int __carl9170_exec_cmd(struct ar9170 *ar, struct carl9170_cmd *cmd, const bool free_buf) { struct urb *urb; int err = 0; if (!IS_INITIALIZED(ar)) { err = -EPERM; goto err_free; } if (WARN_ON(cmd->hdr.len > CARL9170_MAX_CMD_LEN - 4)) { err = -EINVAL; goto err_free; } urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { err = -ENOMEM; goto err_free; } if (ar->usb_ep_cmd_is_bulk) usb_fill_bulk_urb(urb, ar->udev, usb_sndbulkpipe(ar->udev, AR9170_USB_EP_CMD), cmd, cmd->hdr.len + 4, carl9170_usb_cmd_complete, ar); else usb_fill_int_urb(urb, ar->udev, usb_sndintpipe(ar->udev, AR9170_USB_EP_CMD), cmd, cmd->hdr.len + 4, carl9170_usb_cmd_complete, ar, 1); if (free_buf) urb->transfer_flags |= URB_FREE_BUFFER; usb_anchor_urb(urb, &ar->tx_cmd); usb_free_urb(urb); return carl9170_usb_submit_cmd_urb(ar); err_free: if (free_buf) kfree(cmd); return err; }
static void carl9170_usb_cmd_complete(struct urb *urb) { struct ar9170 *ar = urb->context; int err = 0; if (WARN_ON_ONCE(!ar)) return; atomic_dec(&ar->tx_cmd_urbs); switch (urb->status) { /* everything is fine */ case 0: break; /* disconnect */ case -ENOENT: case -ECONNRESET: case -ENODEV: case -ESHUTDOWN: return; default: err = urb->status; break; } if (!IS_INITIALIZED(ar)) return; if (err) dev_err(&ar->udev->dev, "submit cmd cb failed (%d).\n", err); err = carl9170_usb_submit_cmd_urb(ar); if (err) dev_err(&ar->udev->dev, "submit cmd failed (%d).\n", err); }
/* * Send a command to the firmware. */ int otus_send_cmd(struct ar9170 *ar, struct carl9170_cmd *cmd) { if (cmd->hdr.len > CARL9170_MAX_CMD_LEN - 4) { return (EINVAL); } /* * Commands are sent on the CMD endpoint. */ usb_fill_int_urb(urb, ar->udev, usb_sndintpipe(ar->udev, AR9170_USB_EP_CMD), cmd, cmd->hdr.len + 4, carl9170_usb_cmd_complete, ar, 1); if (free_buf) urb->transfer_flags |= URB_FREE_BUFFER; usb_anchor_urb(urb, &ar->tx_cmd); usb_free_urb(urb); return carl9170_usb_submit_cmd_urb(ar); }