This commit is contained in:
Tom Rini 2024-07-08 08:44:26 -06:00
commit 97d638e77a
2 changed files with 37 additions and 18 deletions

View file

@ -214,8 +214,9 @@ int usb_int_msg(struct usb_device *dev, unsigned long pipe,
* clear keyboards LEDs). For data transfers, (storage transfers) we don't * clear keyboards LEDs). For data transfers, (storage transfers) we don't
* allow control messages with 0 timeout, by previousely resetting the flag * allow control messages with 0 timeout, by previousely resetting the flag
* asynch_allowed (usb_disable_asynch(1)). * asynch_allowed (usb_disable_asynch(1)).
* returns the transferred length if OK or -1 if error. The transferred length * returns the transferred length if OK, otherwise a negative error code. The
* and the current status are stored in the dev->act_len and dev->status. * transferred length and the current status are stored in the dev->act_len and
* dev->status.
*/ */
int usb_control_msg(struct usb_device *dev, unsigned int pipe, int usb_control_msg(struct usb_device *dev, unsigned int pipe,
unsigned char request, unsigned char requesttype, unsigned char request, unsigned char requesttype,
@ -257,11 +258,14 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
break; break;
mdelay(1); mdelay(1);
} }
if (timeout == 0)
return -ETIMEDOUT;
if (dev->status) if (dev->status)
return -1; return -1;
return dev->act_len; return dev->act_len;
} }
/*------------------------------------------------------------------- /*-------------------------------------------------------------------
@ -562,10 +566,29 @@ int usb_clear_halt(struct usb_device *dev, int pipe)
static int usb_get_descriptor(struct usb_device *dev, unsigned char type, static int usb_get_descriptor(struct usb_device *dev, unsigned char type,
unsigned char index, void *buf, int size) unsigned char index, void *buf, int size)
{ {
return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), int i;
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, int result;
(type << 8) + index, 0, buf, size,
USB_CNTL_TIMEOUT); if (size <= 0) /* No point in asking for no data */
return -EINVAL;
memset(buf, 0, size); /* Make sure we parse really received data */
for (i = 0; i < 3; ++i) {
/* retry on length 0 or error; some devices are flakey */
result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
(type << 8) + index, 0, buf, size,
USB_CNTL_TIMEOUT);
if (result <= 0 && result != -ETIMEDOUT)
continue;
if (result > 1 && ((u8 *)buf)[1] != type) {
result = -ENODATA;
continue;
}
break;
}
return result;
} }
/********************************************************************** /**********************************************************************

View file

@ -530,9 +530,8 @@ static void reset_ep(struct usb_device *udev, int ep_index)
if (!event) if (!event)
return; return;
BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) != udev->slot_id ||
!= udev->slot_id || GET_COMP_CODE(le32_to_cpu( GET_COMP_CODE(le32_to_cpu(event->event_cmd.status)) != COMP_SUCCESS);
event->event_cmd.status)) != COMP_SUCCESS);
xhci_acknowledge_event(ctrl); xhci_acknowledge_event(ctrl);
} }
@ -565,8 +564,7 @@ static void abort_td(struct usb_device *udev, int ep_index)
field = le32_to_cpu(event->trans_event.flags); field = le32_to_cpu(event->trans_event.flags);
BUG_ON(TRB_TO_SLOT_ID(field) != udev->slot_id); BUG_ON(TRB_TO_SLOT_ID(field) != udev->slot_id);
BUG_ON(TRB_TO_EP_INDEX(field) != ep_index); BUG_ON(TRB_TO_EP_INDEX(field) != ep_index);
BUG_ON(GET_COMP_CODE(le32_to_cpu(event->trans_event.transfer_len BUG_ON(GET_COMP_CODE(le32_to_cpu(event->trans_event.transfer_len != COMP_STOP)));
!= COMP_STOP)));
xhci_acknowledge_event(ctrl); xhci_acknowledge_event(ctrl);
event = xhci_wait_for_event(ctrl, TRB_COMPLETION); event = xhci_wait_for_event(ctrl, TRB_COMPLETION);
@ -580,9 +578,8 @@ static void abort_td(struct usb_device *udev, int ep_index)
comp = GET_COMP_CODE(le32_to_cpu(event->event_cmd.status)); comp = GET_COMP_CODE(le32_to_cpu(event->event_cmd.status));
BUG_ON(type != TRB_COMPLETION || BUG_ON(type != TRB_COMPLETION ||
TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) != udev->slot_id ||
!= udev->slot_id || (comp != COMP_SUCCESS && comp (comp != COMP_SUCCESS && comp != COMP_CTX_STATE));
!= COMP_CTX_STATE));
xhci_acknowledge_event(ctrl); xhci_acknowledge_event(ctrl);
addr = xhci_trb_virt_to_dma(ring->enq_seg, addr = xhci_trb_virt_to_dma(ring->enq_seg,
@ -592,9 +589,8 @@ static void abort_td(struct usb_device *udev, int ep_index)
if (!event) if (!event)
return; return;
BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) != udev->slot_id ||
!= udev->slot_id || GET_COMP_CODE(le32_to_cpu( GET_COMP_CODE(le32_to_cpu(event->event_cmd.status)) != COMP_SUCCESS);
event->event_cmd.status)) != COMP_SUCCESS);
xhci_acknowledge_event(ctrl); xhci_acknowledge_event(ctrl);
} }