Exemple #1
0
static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
{
	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
	struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
	struct queue_entry_priv_usb *entry_priv = entry->priv_data;
	u32 length;

	if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags))
		return;

	/*
	 * USB devices cannot blindly pass the skb->len as the
	 * length of the data to usb_fill_bulk_urb. Pass the skb
	 * to the driver to determine what the length should be.
	 */
	length = rt2x00dev->ops->lib->get_tx_data_len(entry);

	usb_fill_bulk_urb(entry_priv->urb, usb_dev,
			  usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint),
			  entry->skb->data, length,
			  rt2x00usb_interrupt_txdone, entry);

	if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) {
		set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
		rt2x00lib_dmadone(entry);
	}
}
Exemple #2
0
static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry, void *data)
{
    struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
    struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
    struct queue_entry_priv_usb *entry_priv = entry->priv_data;
    int status;

    if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
            test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
        return false;

    rt2x00lib_dmastart(entry);

    usb_fill_bulk_urb(entry_priv->urb, usb_dev,
                      usb_rcvbulkpipe(usb_dev, entry->queue->usb_endpoint),
                      entry->skb->data, entry->skb->len,
                      rt2x00usb_interrupt_rxdone, entry);

    status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
    if (status) {
        if (status == -ENODEV)
            clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
        set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
        rt2x00lib_dmadone(entry);
    }

    return false;
}
Exemple #3
0
void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev,
                                   const unsigned int offset,
                                   bool (*callback)(struct rt2x00_dev*, int, u32))
{
    struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
    struct urb *urb;
    struct rt2x00_async_read_data *rd;

    rd = kmalloc(sizeof(*rd), GFP_ATOMIC);
    if (!rd)
        return;

    urb = usb_alloc_urb(0, GFP_ATOMIC);
    if (!urb) {
        kfree(rd);
        return;
    }

    rd->rt2x00dev = rt2x00dev;
    rd->callback = callback;
    rd->cr.bRequestType = USB_VENDOR_REQUEST_IN;
    rd->cr.bRequest = USB_MULTI_READ;
    rd->cr.wValue = 0;
    rd->cr.wIndex = cpu_to_le16(offset);
    rd->cr.wLength = cpu_to_le16(sizeof(u32));

    usb_fill_control_urb(urb, usb_dev, usb_rcvctrlpipe(usb_dev, 0),
                         (unsigned char *)(&rd->cr), &rd->reg, sizeof(rd->reg),
                         rt2x00usb_register_read_async_cb, rd);
    if (usb_submit_urb(urb, GFP_ATOMIC) < 0)
        kfree(rd);
    usb_free_urb(urb);
}
Exemple #4
0
int rt2x00usb_write_tx_data(struct queue_entry *entry,
			    struct txentry_desc *txdesc)
{
	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
	struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
	struct queue_entry_priv_usb *entry_priv = entry->priv_data;
	u32 length;

	/*
	 * Add the descriptor in front of the skb.
	 */
	skb_push(entry->skb, entry->queue->desc_size);
	memset(entry->skb->data, 0, entry->queue->desc_size);

	/*
	 * USB devices cannot blindly pass the skb->len as the
	 * length of the data to usb_fill_bulk_urb. Pass the skb
	 * to the driver to determine what the length should be.
	 */
	length = rt2x00dev->ops->lib->get_tx_data_len(entry);

	usb_fill_bulk_urb(entry_priv->urb, usb_dev,
			  usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint),
			  entry->skb->data, length,
			  rt2x00usb_interrupt_txdone, entry);

	/*
	 * Make sure the skb->data pointer points to the frame, not the
	 * descriptor.
	 */
	skb_pull(entry->skb, entry->queue->desc_size);

	return 0;
}
Exemple #5
0
int rt2x00usb_write_tx_data(struct queue_entry *entry)
{
	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
	struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
	struct queue_entry_priv_usb *entry_priv = entry->priv_data;
	struct skb_frame_desc *skbdesc;
	u32 length;

	
	skb_push(entry->skb, entry->queue->desc_size);
	memset(entry->skb->data, 0, entry->queue->desc_size);

	
	skbdesc = get_skb_frame_desc(entry->skb);
	skbdesc->desc = entry->skb->data;
	skbdesc->desc_len = entry->queue->desc_size;

	
	length = rt2x00dev->ops->lib->get_tx_data_len(entry);

	usb_fill_bulk_urb(entry_priv->urb, usb_dev,
			  usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint),
			  entry->skb->data, length,
			  rt2x00usb_interrupt_txdone, entry);

	
	skb_pull(entry->skb, entry->queue->desc_size);

	return 0;
}
Exemple #6
0
static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void *data)
{
	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
	struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
	struct queue_entry_priv_usb *entry_priv = entry->priv_data;
	u32 length;
	int status;

	if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags) ||
	    test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
		return false;

	/*
	 * USB devices require certain padding at the end of each frame
	 * and urb. Those paddings are not included in skbs. Pass entry
	 * to the driver to determine what the overall length should be.
	 */
	length = rt2x00dev->ops->lib->get_tx_data_len(entry);

	status = skb_padto(entry->skb, length);
	if (unlikely(status)) {
		/* TODO: report something more appropriate than IO_FAILED. */
		rt2x00_warn(rt2x00dev, "TX SKB padding error, out of memory\n");
		set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
		rt2x00lib_dmadone(entry);

		return false;
	}

	usb_fill_bulk_urb(entry_priv->urb, usb_dev,
			  usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint),
			  entry->skb->data, length,
			  rt2x00usb_interrupt_txdone, entry);

	usb_anchor_urb(entry_priv->urb, rt2x00dev->anchor);
	status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
	if (status) {
		usb_unanchor_urb(entry_priv->urb);
		if (status == -ENODEV)
			clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
		set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
		rt2x00lib_dmadone(entry);
	}

	return false;
}
Exemple #7
0
static void rt2x00usb_assign_endpoint(struct data_queue *queue,
                                      struct usb_endpoint_descriptor *ep_desc)
{
    struct usb_device *usb_dev = to_usb_device_intf(queue->rt2x00dev->dev);
    int pipe;

    queue->usb_endpoint = usb_endpoint_num(ep_desc);

    if (queue->qid == QID_RX) {
        pipe = usb_rcvbulkpipe(usb_dev, queue->usb_endpoint);
        queue->usb_maxpacket = usb_maxpacket(usb_dev, pipe, 0);
    } else {
        pipe = usb_sndbulkpipe(usb_dev, queue->usb_endpoint);
        queue->usb_maxpacket = usb_maxpacket(usb_dev, pipe, 1);
    }

    if (!queue->usb_maxpacket)
        queue->usb_maxpacket = 1;
}
Exemple #8
0
/*
 * Device initialization handlers.
 */
void rt2x00usb_clear_entry(struct queue_entry *entry)
{
	struct usb_device *usb_dev =
	    to_usb_device_intf(entry->queue->rt2x00dev->dev);
	struct queue_entry_priv_usb *entry_priv = entry->priv_data;
	int pipe;

	if (entry->queue->qid == QID_RX) {
		pipe = usb_rcvbulkpipe(usb_dev, entry->queue->usb_endpoint);
		usb_fill_bulk_urb(entry_priv->urb, usb_dev, pipe,
				entry->skb->data, entry->skb->len,
				rt2x00usb_interrupt_rxdone, entry);

		set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
		usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
	} else {
		entry->flags = 0;
	}
}
Exemple #9
0
/*
 * Interfacing with the HW.
 */
int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev,
                             const u8 request, const u8 requesttype,
                             const u16 offset, const u16 value,
                             void *buffer, const u16 buffer_length,
                             const int timeout)
{
    struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
    int status;
    unsigned int i;
    unsigned int pipe =
        (requesttype == USB_VENDOR_REQUEST_IN) ?
        usb_rcvctrlpipe(usb_dev, 0) : usb_sndctrlpipe(usb_dev, 0);

    if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
        return -ENODEV;

    for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
        status = usb_control_msg(usb_dev, pipe, request, requesttype,
                                 value, offset, buffer, buffer_length,
                                 timeout);
        if (status >= 0)
            return 0;

        /*
         * Check for errors
         * -ENODEV: Device has disappeared, no point continuing.
         * All other errors: Try again.
         */
        else if (status == -ENODEV) {
            clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
            break;
        }
    }

    rt2x00_err(rt2x00dev,
               "Vendor Request 0x%02x failed for offset 0x%04x with error %d\n",
               request, offset, status);

    return status;
}
Exemple #10
0
/*
 * Interfacing with the HW.
 */
int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev,
			     const u8 request, const u8 requesttype,
			     const u16 offset, const u16 value,
			     void *buffer, const u16 buffer_length,
			     const int timeout)
{
	struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
	int status;
	unsigned int pipe =
	    (requesttype == USB_VENDOR_REQUEST_IN) ?
	    usb_rcvctrlpipe(usb_dev, 0) : usb_sndctrlpipe(usb_dev, 0);
	unsigned long expire = jiffies + msecs_to_jiffies(timeout);

	if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
		return -ENODEV;

	do {
		status = usb_control_msg(usb_dev, pipe, request, requesttype,
					 value, offset, buffer, buffer_length,
					 timeout / 2);
		if (status >= 0)
			return 0;

		if (status == -ENODEV) {
			/* Device has disappeared. */
			clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
			break;
		}
	} while (time_before(jiffies, expire));

	rt2x00_err(rt2x00dev,
		   "Vendor Request 0x%02x failed for offset 0x%04x with error %d\n",
		   request, offset, status);

	return status;
}