diff options
author | Hector Martin <marcan@marcan.st> | 2023-10-29 15:37:38 +0900 |
---|---|---|
committer | Marek Vasut <marex@denx.de> | 2023-12-01 14:06:04 +0100 |
commit | 8d1e03f984c7467d7c8883f15dea14b2f8b4c0e2 (patch) | |
tree | 2cb1fb2b67b4045902e79d5459299f78e17700d8 /drivers/usb/host/xhci-ring.c | |
parent | 43f2873fa98b1da6eb56d756315c7bd7db63db27 (diff) | |
download | u-boot-8d1e03f984c7467d7c8883f15dea14b2f8b4c0e2.tar.gz u-boot-8d1e03f984c7467d7c8883f15dea14b2f8b4c0e2.tar.bz2 u-boot-8d1e03f984c7467d7c8883f15dea14b2f8b4c0e2.zip |
usb: xhci: Guard all calls to xhci_wait_for_event
xhci_wait_for_event returns NULL on timeout, so the caller always has to
check for that. This addresses immediate explosions in this part
of the code when timeouts happen, but not the root cause for the
timeout.
Signed-off-by: Hector Martin <marcan@marcan.st>
Reviewed-by: Marek Vasut <marex@denx.de>
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index c8260cbdf9..d0960812a4 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -511,6 +511,9 @@ static void reset_ep(struct usb_device *udev, int ep_index) printf("Resetting EP %d...\n", ep_index); xhci_queue_command(ctrl, 0, udev->slot_id, ep_index, TRB_RESET_EP); event = xhci_wait_for_event(ctrl, TRB_COMPLETION); + if (!event) + return; + field = le32_to_cpu(event->trans_event.flags); BUG_ON(TRB_TO_SLOT_ID(field) != udev->slot_id); xhci_acknowledge_event(ctrl); @@ -519,6 +522,9 @@ static void reset_ep(struct usb_device *udev, int ep_index) (void *)((uintptr_t)ring->enqueue | ring->cycle_state)); xhci_queue_command(ctrl, addr, udev->slot_id, ep_index, TRB_SET_DEQ); event = xhci_wait_for_event(ctrl, TRB_COMPLETION); + if (!event) + return; + BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) != udev->slot_id || GET_COMP_CODE(le32_to_cpu( event->event_cmd.status)) != COMP_SUCCESS); @@ -544,6 +550,9 @@ static void abort_td(struct usb_device *udev, int ep_index) xhci_queue_command(ctrl, 0, udev->slot_id, ep_index, TRB_STOP_RING); event = xhci_wait_for_event(ctrl, TRB_TRANSFER); + if (!event) + return; + field = le32_to_cpu(event->trans_event.flags); BUG_ON(TRB_TO_SLOT_ID(field) != udev->slot_id); BUG_ON(TRB_TO_EP_INDEX(field) != ep_index); @@ -552,6 +561,9 @@ static void abort_td(struct usb_device *udev, int ep_index) xhci_acknowledge_event(ctrl); event = xhci_wait_for_event(ctrl, TRB_COMPLETION); + if (!event) + return; + BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) != udev->slot_id || GET_COMP_CODE(le32_to_cpu( event->event_cmd.status)) != COMP_SUCCESS); @@ -561,6 +573,9 @@ static void abort_td(struct usb_device *udev, int ep_index) (void *)((uintptr_t)ring->enqueue | ring->cycle_state)); xhci_queue_command(ctrl, addr, udev->slot_id, ep_index, TRB_SET_DEQ); event = xhci_wait_for_event(ctrl, TRB_COMPLETION); + if (!event) + return; + BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) != udev->slot_id || GET_COMP_CODE(le32_to_cpu( event->event_cmd.status)) != COMP_SUCCESS); |