diff --git a/arch/sim/src/sim/posix/sim_libusb.c b/arch/sim/src/sim/posix/sim_libusb.c index bf745c499c0..d99021248c1 100644 --- a/arch/sim/src/sim/posix/sim_libusb.c +++ b/arch/sim/src/sim/posix/sim_libusb.c @@ -286,8 +286,11 @@ static void host_libusb_inttransfer_cb(struct libusb_transfer *transfer) #ifndef CONFIG_USBHOST_ISOC_DISABLE static void host_libusb_isotransfer_cb(struct libusb_transfer *transfer) { - struct host_libusb_hostdev_s *dev = &g_libusb_dev; + struct libusb_iso_packet_descriptor *packet; struct host_usb_datareq_s *datareq; + usbhost_asynch_t callback; + size_t length; + int i; if (!transfer) { @@ -298,18 +301,24 @@ static void host_libusb_isotransfer_cb(struct libusb_transfer *transfer) } datareq = (struct host_usb_datareq_s *)transfer->user_data; + callback = datareq->callback; - if (transfer->status == LIBUSB_TRANSFER_COMPLETED) + for (i = 0; i < transfer->num_iso_packets; i++) { - datareq->success = true; - datareq->xfer += transfer->actual_length; - } - else - { - datareq->success = false; + packet = &transfer->iso_packet_desc[i]; + length = packet->status == LIBUSB_TRANSFER_COMPLETED ? + packet->actual_length : 0; + + /* If there are multiple isoc packages, only the actual length + * of the data in each package is returned here. Because each + * package has the same size, the number of packages returned + * needs to be recorded in class driver. + */ + + callback(datareq->priv, length); } - host_libusb_fifopush(&dev->completed, datareq); + free(datareq); host_uninterruptible_no_return(libusb_free_transfer, transfer); } #endif @@ -486,9 +495,7 @@ host_libusb_isotransfer(struct host_libusb_hostdev_s *dev, uint8_t addr, int num_iso_pack; int ret; - max_packet_size = host_uninterruptible(libusb_get_max_iso_packet_size, - dev->priv, - addr); + max_packet_size = datareq->maxpacketsize; num_iso_pack = (datareq->len + max_packet_size - 1) / max_packet_size; transfer = host_uninterruptible(libusb_alloc_transfer, num_iso_pack); if (!transfer) diff --git a/arch/sim/src/sim/sim_usbhost.c b/arch/sim/src/sim/sim_usbhost.c index 65931cd7632..8c559fcd03e 100644 --- a/arch/sim/src/sim/sim_usbhost.c +++ b/arch/sim/src/sim/sim_usbhost.c @@ -77,9 +77,9 @@ struct sim_epinfo_s uint8_t toggle:1; /* Next data toggle */ uint8_t interval; /* Polling interval */ uint8_t status; /* Retained token status bits (for debug purposes) */ - uint16_t maxpacket:11; /* Maximum packet size */ + uint16_t maxpacket:14; /* Maximum packet size */ uint16_t xfrtype:2; /* See USB_EP_ATTR_XFER_* definitions in usb.h */ - uint16_t speed:2; /* See USB_*_SPEED definitions */ + uint8_t speed; /* See USB_*_SPEED definitions */ int result; /* The result of the transfer */ ssize_t xfrd; /* On completion, will hold the number of bytes transferred */ sem_t iocsem; /* Semaphore used to wait for transfer completion */ @@ -406,7 +406,8 @@ static int sim_usbhost_epalloc(struct usbhost_driver_s *drvr, epinfo->dirin = epdesc->in; epinfo->devaddr = hport->funcaddr; epinfo->interval = epdesc->interval; - epinfo->maxpacket = epdesc->mxpacketsize; + epinfo->maxpacket = (epdesc->mxpacketsize & USB_EP_MAXP_MASK) * + (USB_EP_MAX_PACKET_MULT(epdesc->mxpacketsize) + 1); epinfo->xfrtype = epdesc->xfrtype; epinfo->speed = hport->speed; nxsem_init(&epinfo->iocsem, 0, 0); @@ -610,6 +611,7 @@ static int sim_usbhost_asynch(struct usbhost_driver_s *drvr, datareq->addr = (epinfo->dirin << 7) + epinfo->epno; datareq->len = buflen; datareq->xfrtype = epinfo->xfrtype; + datareq->maxpacketsize = epinfo->maxpacket; datareq->callback = callback; datareq->data = buffer; datareq->priv = arg; diff --git a/arch/sim/src/sim/sim_usbhost.h b/arch/sim/src/sim/sim_usbhost.h index 9db8c583954..b559a6debe0 100644 --- a/arch/sim/src/sim/sim_usbhost.h +++ b/arch/sim/src/sim/sim_usbhost.h @@ -78,6 +78,7 @@ struct host_usb_datareq_s struct host_usb_datareq_s *flink; uint8_t addr; uint8_t xfrtype; + uint16_t maxpacketsize; uint8_t *data; uint16_t len; uint16_t xfer; diff --git a/include/nuttx/usb/usb.h b/include/nuttx/usb/usb.h index d9bffad3ce6..9bc96ca2314 100644 --- a/include/nuttx/usb/usb.h +++ b/include/nuttx/usb/usb.h @@ -256,6 +256,14 @@ # define USB_EP_ATTR_USAGE_IMPLICIT (2 << USB_EP_ATTR_USAGE_SHIFT) #define USB_EP_ATTR_MAX_ADJUSTABLE (1 << 7) +/* Endpoint descriptor max packet size */ + +#define USB_EP_MAX_PACKET_MASK (0x07ff) +#define USB_EP_MAX_PACKET_MULT_SHIFT (11) +#define USB_EP_MAX_PACKET_MULT_MASK (3 << USB_EP_MAX_PACKET_MULT_SHIFT) +#define USB_EP_MAX_PACKET_MULT(m) (((m) & USB_EP_MAX_PACKET_MULT_MASK) >> \ + USB_EP_MAX_PACKET_MULT_SHIFT) + /* OTG Definitions */ /* OTG SET FEATURE Constants */