mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 18:22:00 -04:00
wifi: libertas: use USB anchors for tracking in-flight URBs
The libertas driver currently handles URB lifecycles manually, which makes it non-trivial to check if specific URBs are pending or not. Add anchors for TX/RX URBs, and use those to track in-flight requests. Signed-off-by: Heitor Alves de Siqueira <halves@igalia.com> Link: https://patch.msgid.link/20260313-libertas-usb-anchors-v1-1-915afbe988d7@igalia.com Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
committed by
Johannes Berg
parent
f10ebd136d
commit
a57f35fc19
@@ -114,8 +114,8 @@ static void if_usb_write_bulk_callback(struct urb *urb)
|
||||
static void if_usb_free(struct if_usb_card *cardp)
|
||||
{
|
||||
/* Unlink tx & rx urb */
|
||||
usb_kill_urb(cardp->tx_urb);
|
||||
usb_kill_urb(cardp->rx_urb);
|
||||
usb_kill_anchored_urbs(&cardp->tx_submitted);
|
||||
usb_kill_anchored_urbs(&cardp->rx_submitted);
|
||||
|
||||
usb_free_urb(cardp->tx_urb);
|
||||
cardp->tx_urb = NULL;
|
||||
@@ -221,6 +221,9 @@ static int if_usb_probe(struct usb_interface *intf,
|
||||
udev->descriptor.bDeviceSubClass,
|
||||
udev->descriptor.bDeviceProtocol);
|
||||
|
||||
init_usb_anchor(&cardp->rx_submitted);
|
||||
init_usb_anchor(&cardp->tx_submitted);
|
||||
|
||||
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
|
||||
endpoint = &iface_desc->endpoint[i].desc;
|
||||
if (usb_endpoint_is_bulk_in(endpoint)) {
|
||||
@@ -423,7 +426,7 @@ static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb
|
||||
goto tx_ret;
|
||||
}
|
||||
|
||||
usb_kill_urb(cardp->tx_urb);
|
||||
usb_kill_anchored_urbs(&cardp->tx_submitted);
|
||||
|
||||
usb_fill_bulk_urb(cardp->tx_urb, cardp->udev,
|
||||
usb_sndbulkpipe(cardp->udev,
|
||||
@@ -432,8 +435,10 @@ static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb
|
||||
|
||||
cardp->tx_urb->transfer_flags |= URB_ZERO_PACKET;
|
||||
|
||||
usb_anchor_urb(cardp->tx_urb, &cardp->tx_submitted);
|
||||
if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) {
|
||||
lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret);
|
||||
usb_unanchor_urb(cardp->tx_urb);
|
||||
} else {
|
||||
lbs_deb_usb2(&cardp->udev->dev, "usb_submit_urb success\n");
|
||||
ret = 0;
|
||||
@@ -464,8 +469,10 @@ static int __if_usb_submit_rx_urb(struct if_usb_card *cardp,
|
||||
cardp);
|
||||
|
||||
lbs_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb);
|
||||
usb_anchor_urb(cardp->rx_urb, &cardp->rx_submitted);
|
||||
if ((ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC))) {
|
||||
lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed: %d\n", ret);
|
||||
usb_unanchor_urb(cardp->rx_urb);
|
||||
kfree_skb(skb);
|
||||
cardp->rx_skb = NULL;
|
||||
ret = -1;
|
||||
@@ -835,8 +842,8 @@ static void if_usb_prog_firmware(struct lbs_private *priv, int ret,
|
||||
}
|
||||
|
||||
/* Cancel any pending usb business */
|
||||
usb_kill_urb(cardp->rx_urb);
|
||||
usb_kill_urb(cardp->tx_urb);
|
||||
usb_kill_anchored_urbs(&cardp->rx_submitted);
|
||||
usb_kill_anchored_urbs(&cardp->tx_submitted);
|
||||
|
||||
cardp->fwlastblksent = 0;
|
||||
cardp->fwdnldover = 0;
|
||||
@@ -866,8 +873,8 @@ static void if_usb_prog_firmware(struct lbs_private *priv, int ret,
|
||||
if (cardp->bootcmdresp == BOOT_CMD_RESP_NOT_SUPPORTED) {
|
||||
/* Return to normal operation */
|
||||
ret = -EOPNOTSUPP;
|
||||
usb_kill_urb(cardp->rx_urb);
|
||||
usb_kill_urb(cardp->tx_urb);
|
||||
usb_kill_anchored_urbs(&cardp->rx_submitted);
|
||||
usb_kill_anchored_urbs(&cardp->tx_submitted);
|
||||
if (if_usb_submit_rx_urb(cardp) < 0)
|
||||
ret = -EIO;
|
||||
goto done;
|
||||
@@ -897,7 +904,7 @@ static void if_usb_prog_firmware(struct lbs_private *priv, int ret,
|
||||
wait_event_interruptible(cardp->fw_wq, cardp->surprise_removed || cardp->fwdnldover);
|
||||
|
||||
timer_delete_sync(&cardp->fw_timeout);
|
||||
usb_kill_urb(cardp->rx_urb);
|
||||
usb_kill_anchored_urbs(&cardp->rx_submitted);
|
||||
|
||||
if (!cardp->fwdnldover) {
|
||||
pr_info("failed to load fw, resetting device!\n");
|
||||
@@ -957,8 +964,8 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
|
||||
goto out;
|
||||
|
||||
/* Unlink tx & rx urb */
|
||||
usb_kill_urb(cardp->tx_urb);
|
||||
usb_kill_urb(cardp->rx_urb);
|
||||
usb_kill_anchored_urbs(&cardp->tx_submitted);
|
||||
usb_kill_anchored_urbs(&cardp->rx_submitted);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
|
||||
@@ -48,6 +48,9 @@ struct if_usb_card {
|
||||
struct urb *rx_urb, *tx_urb;
|
||||
struct lbs_private *priv;
|
||||
|
||||
struct usb_anchor rx_submitted;
|
||||
struct usb_anchor tx_submitted;
|
||||
|
||||
struct sk_buff *rx_skb;
|
||||
|
||||
uint8_t ep_in;
|
||||
|
||||
Reference in New Issue
Block a user