/** * zd_mac_tx_to_dev - callback for USB layer * @skb: a &sk_buff pointer * @error: error value, 0 if transmission successful * * Informs the MAC layer that the frame has successfully transferred to the * device. If an ACK is required and the transfer to the device has been * successful, the packets are put on the @ack_wait_queue with * the control set removed. */ void zd_mac_tx_to_dev(struct sk_buff *skb, int error) { struct zd_tx_skb_control_block *cb = (struct zd_tx_skb_control_block *)skb->cb; struct ieee80211_hw *hw = cb->hw; if (likely(cb->control)) { skb_pull(skb, sizeof(struct zd_ctrlset)); if (unlikely(error || (cb->control->flags & IEEE80211_TXCTL_NO_ACK))) { struct ieee80211_tx_status status; memset(&status, 0, sizeof(status)); tx_status(hw, skb, &status, !error); } else { struct sk_buff_head *q = &zd_hw_mac(hw)->ack_wait_queue; skb_queue_tail(q, skb); while (skb_queue_len(q) > ZD_MAC_MAX_ACK_WAITERS) zd_mac_tx_failed(hw); } } else { kfree_tx_skb(skb); } }
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: dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status); return; default: dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status); 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: zd_mac_tx_failed(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), "error: resubmit urb %p err code %d\n", urb, r); /* TODO: add worker to reset intr->urb */ } return; }