? nb7-axe-usb.diff ? pullup.msg Index: usb_subr.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/usb_subr.c,v retrieving revision 1.196.4.5 diff -p -u -r1.196.4.5 usb_subr.c --- usb_subr.c 8 Aug 2018 10:17:11 -0000 1.196.4.5 +++ usb_subr.c 16 Nov 2019 11:55:31 -0000 @@ -157,13 +157,20 @@ usbd_get_string_desc(struct usbd_device usbd_status err; int actlen; + /* + * Pass a full-sized buffer to usbd_do_request_len(). At least + * one device has been seen returning additional data beyond the + * provided buffers (2-bytes written shortly after the request + * claims to have completed and returned the 2 byte header, + * corrupting other memory.) + */ req.bmRequestType = UT_READ_DEVICE; req.bRequest = UR_GET_DESCRIPTOR; USETW2(req.wValue, UDESC_STRING, sindex); USETW(req.wIndex, langid); USETW(req.wLength, 2); /* only size byte first */ - err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK, - &actlen, USBD_DEFAULT_TIMEOUT); + err = usbd_do_request_len(dev, &req, sizeof(*sdesc), sdesc, + USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT); if (err) return err; @@ -171,8 +178,8 @@ usbd_get_string_desc(struct usbd_device return USBD_SHORT_XFER; USETW(req.wLength, sdesc->bLength); /* the whole string */ - err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK, - &actlen, USBD_DEFAULT_TIMEOUT); + err = usbd_do_request_len(dev, &req, sizeof(*sdesc), sdesc, + USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT); if (err) return err; @@ -1192,7 +1199,7 @@ usbd_get_initial_ddesc(struct usbd_devic req.bRequest = UR_GET_DESCRIPTOR; USETW2(req.wValue, UDESC_DEVICE, 0); USETW(req.wIndex, 0); - USETW(req.wLength, 64); + USETW(req.wLength, 8); res = usbd_do_request_flags(dev, &req, buf, USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT); if (res) Index: usbdi.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/usbdi.c,v retrieving revision 1.161.2.4 diff -p -u -r1.161.2.4 usbdi.c --- usbdi.c 11 Jan 2019 15:58:23 -0000 1.161.2.4 +++ usbdi.c 16 Nov 2019 11:55:31 -0000 @@ -331,6 +331,8 @@ usbd_transfer(struct usbd_xfer *xfer) * accepted by the HCD for some reason. It needs removing * from the pipe queue. */ + USBHIST_LOG(usbdebug, "xfer failed: %s, reinserting", + err, 0, 0, 0); usbd_lock_pipe(pipe); SIMPLEQ_REMOVE_HEAD(&pipe->up_queue, ux_next); if (pipe->up_serialise) @@ -1072,13 +1074,23 @@ usbd_status usbd_do_request_flags(struct usbd_device *dev, usb_device_request_t *req, void *data, uint16_t flags, int *actlen, uint32_t timeout) { + size_t len = UGETW(req->wLength); + + return usbd_do_request_len(dev, req, len, data, flags, actlen, timeout); +} + +usbd_status +usbd_do_request_len(struct usbd_device *dev, usb_device_request_t *req, + size_t len, void *data, uint16_t flags, int *actlen, uint32_t timeout) +{ USBHIST_FUNC(); USBHIST_CALLED(usbdebug); struct usbd_xfer *xfer; usbd_status err; + KASSERT(len >= UGETW(req->wLength)); + ASSERT_SLEEPABLE(); - size_t len = UGETW(req->wLength); int error = usbd_create_xfer(dev->ud_pipe0, len, 0, 0, &xfer); if (error) return error; Index: usbdi.h =================================================================== RCS file: /cvsroot/src/sys/dev/usb/usbdi.h,v retrieving revision 1.90.2.2 diff -p -u -r1.90.2.2 usbdi.h --- usbdi.h 8 Aug 2018 10:17:11 -0000 1.90.2.2 +++ usbdi.h 16 Nov 2019 11:55:31 -0000 @@ -141,6 +141,9 @@ usbd_status usbd_sync_transfer_sig(struc usbd_status usbd_do_request(struct usbd_device *, usb_device_request_t *, void *); usbd_status usbd_do_request_flags(struct usbd_device *, usb_device_request_t *, void *, uint16_t, int *, uint32_t); +usbd_status usbd_do_request_len(struct usbd_device *dev, + usb_device_request_t *req, size_t len, void *data, uint16_t flags, + int *actlen, uint32_t timeout); usb_interface_descriptor_t * usbd_get_interface_descriptor(struct usbd_interface *);