Beispiel #1
0
static void tx_urb_complete(struct urb *urb)
{
    int r;

    switch (urb->status) {
    case 0:
        break;
    case -ESHUTDOWN:
    case -EINVAL:
    case -ENODEV:
    case -ENOENT:
    case -ECONNRESET:
    case -EPIPE:
        dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status);
        break;
    default:
        dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status);
        goto resubmit;
    }
free_urb:
    usb_buffer_free(urb->dev, urb->transfer_buffer_length,
                    urb->transfer_buffer, urb->transfer_dma);
    usb_free_urb(urb);
    return;
resubmit:
    r = usb_submit_urb(urb, GFP_ATOMIC);
    if (r) {
        dev_dbg_f(urb_dev(urb), "error resubmit urb %p %d\n", urb, r);
        goto free_urb;
    }
}
Beispiel #2
0
static void rx_urb_complete(struct urb *urb)
{
    struct zd_usb *usb;
    struct zd_usb_rx *rx;
    const u8 *buffer;
    unsigned int length;

    switch (urb->status) {
    case 0:
        break;
    case -ESHUTDOWN:
    case -EINVAL:
    case -ENODEV:
    case -ENOENT:
    case -ECONNRESET:
    case -EPIPE:
        return;
    default:
        dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status);
        goto resubmit;
    }

    buffer = urb->transfer_buffer;
    length = urb->actual_length;
    usb = urb->context;
    rx = &usb->rx;

    if (length%rx->usb_packet_size > rx->usb_packet_size-4) {
        /* If there is an old first fragment, we don't care. */
        dev_dbg_f(urb_dev(urb), "*** first fragment ***\n");
        ZD_ASSERT(length <= ARRAY_SIZE(rx->fragment));
        spin_lock(&rx->lock);
        memcpy(rx->fragment, buffer, length);
        rx->fragment_length = length;
        spin_unlock(&rx->lock);
        goto resubmit;
    }

    spin_lock(&rx->lock);
    if (rx->fragment_length > 0) {
        /* We are on a second fragment, we believe */
        ZD_ASSERT(length + rx->fragment_length <=
                  ARRAY_SIZE(rx->fragment));
        dev_dbg_f(urb_dev(urb), "*** second fragment ***\n");
        memcpy(rx->fragment+rx->fragment_length, buffer, length);
        handle_rx_packet(usb, rx->fragment,
                         rx->fragment_length + length);
        rx->fragment_length = 0;
        spin_unlock(&rx->lock);
    } else {
        spin_unlock(&rx->lock);
        handle_rx_packet(usb, buffer, length);
    }

resubmit:
    usb_submit_urb(urb, GFP_ATOMIC);
}
Beispiel #3
0
static void int_urb_complete(struct urb *urb)
{
    int r;
    struct usb_int_header *hdr;

    switch (urb->status) {
    case 0:
        break;
    case -ESHUTDOWN:
    case -EINVAL:
    case -ENODEV:
    case -ENOENT:
    case -ECONNRESET:
    case -EPIPE:
        goto kfree;
    default:
        goto resubmit;
    }

    if (urb->actual_length < sizeof(hdr)) {
        dev_dbg_f(urb_dev(urb), "error: urb %p to small\n", urb);
        goto resubmit;
    }

    hdr = urb->transfer_buffer;
    if (hdr->type != USB_INT_TYPE) {
        dev_dbg_f(urb_dev(urb), "error: urb %p wrong type\n", urb);
        goto resubmit;
    }

    switch (hdr->id) {
    case USB_INT_ID_REGS:
        handle_regs_int(urb);
        break;
    case USB_INT_ID_RETRY_FAILED:
        handle_retry_failed_int(urb);
        break;
    default:
        dev_dbg_f(urb_dev(urb), "error: urb %p unknown id %x\n", urb,
                  (unsigned int)hdr->id);
        goto resubmit;
    }

resubmit:
    r = usb_submit_urb(urb, GFP_ATOMIC);
    if (r) {
        dev_dbg_f(urb_dev(urb), "resubmit urb %p\n", urb);
        goto kfree;
    }
    return;
kfree:
    kfree(urb->transfer_buffer);
}
Beispiel #4
0
/**
 * tx_urb_complete - completes the execution of an URB
 * @urb: a URB
 *
 * This function is called if the URB has been transferred to a device or an
 * error has happened.
 */
static void tx_urb_complete(struct urb *urb)
{
	int r;
	struct sk_buff *skb;
	struct ieee80211_tx_info *info;
	struct zd_usb *usb;
	struct zd_usb_tx *tx;

	skb = (struct sk_buff *)urb->context;
	info = IEEE80211_SKB_CB(skb);
	/*
	 * grab 'usb' pointer before handing off the skb (since
	 * it might be freed by zd_mac_tx_to_dev or mac80211)
	 */
	usb = &zd_hw_mac(info->rate_driver_data[0])->chip.usb;
	tx = &usb->tx;

	switch (urb->status) {
	case 0:
		break;
	case -ESHUTDOWN:
	case -EINVAL:
	case -ENODEV:
	case -ENOENT:
	case -ECONNRESET:
	case -EPIPE:
		dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status);
		break;
	default:
		dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status);
		goto resubmit;
	}
free_urb:
	skb_unlink(skb, &usb->tx.submitted_skbs);
	zd_mac_tx_to_dev(skb, urb->status);
	usb_free_urb(urb);
	tx_dec_submitted_urbs(usb);
	return;
resubmit:
	usb_anchor_urb(urb, &tx->submitted);
	r = usb_submit_urb(urb, GFP_ATOMIC);
	if (r) {
		usb_unanchor_urb(urb);
		dev_dbg_f(urb_dev(urb), "error resubmit urb %p %d\n", urb, r);
		goto free_urb;
	}
}
Beispiel #5
0
static inline void handle_retry_failed_int(struct urb *urb)
{
    struct zd_usb *usb = urb->context;
    struct zd_mac *mac = zd_usb_to_mac(usb);
    struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);

    ieee->stats.tx_errors++;
    ieee->ieee_stats.tx_retry_limit_exceeded++;
    dev_dbg_f(urb_dev(urb), "retry failed interrupt\n");
}
Beispiel #6
0
static inline void handle_regs_int(struct urb *urb)
{
    struct zd_usb *usb = urb->context;
    struct zd_usb_interrupt *intr = &usb->intr;
    int len;

    ZD_ASSERT(in_interrupt());
    spin_lock(&intr->lock);

    if (intr->read_regs_enabled) {
        intr->read_regs.length = len = urb->actual_length;

        if (len > sizeof(intr->read_regs.buffer))
            len = sizeof(intr->read_regs.buffer);
        memcpy(intr->read_regs.buffer, urb->transfer_buffer, len);
        intr->read_regs_enabled = 0;
        complete(&intr->read_regs.completion);
        goto out;
    }

    dev_dbg_f(urb_dev(urb), "regs interrupt ignored\n");
out:
    spin_unlock(&intr->lock);
}