arch/sim: Optimize sim usbhost isoc endpoint transmission

The USB driver framework only implements a single ISOC transfer.
If multiple transfers are needed, the class driver can initiate
multiple urbs to meet the real-time requirements of the ISOC
 endpoint. The class driver's urb record the buf address, length,
and number of packets sent. The callback function calculates the
data location in the buf based on the callback number and length
returned.

Signed-off-by: yangsong8 <yangsong8@xiaomi.com>
This commit is contained in:
yangsong8
2025-10-14 22:49:56 +08:00
committed by Xiang Xiao
parent 199290c0ee
commit bc2daa48cc
4 changed files with 33 additions and 15 deletions
+19 -12
View File
@@ -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)
+5 -3
View File
@@ -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;
+1
View File
@@ -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;
+8
View File
@@ -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 */