]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[usb] Allow USB endpoints to specify a reserved header length for refills
authorMichael Brown <mcb30@ipxe.org>
Tue, 19 Jan 2016 00:01:11 +0000 (00:01 +0000)
committerMichael Brown <mcb30@ipxe.org>
Tue, 19 Jan 2016 00:01:11 +0000 (00:01 +0000)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/drivers/bus/usb.c
src/drivers/net/acm.c
src/drivers/net/dm96xx.c
src/drivers/net/ecm.c
src/drivers/net/ncm.c
src/drivers/net/smsc75xx.c
src/drivers/net/smsc95xx.c
src/drivers/usb/usbhub.c
src/drivers/usb/usbkbd.c
src/include/ipxe/usb.h
src/interface/efi/efi_usb.c

index b1fa4efb524362701bcec08306e7f548e5899031..880e3f08c2133033bf4ebab147ff80e26529eaca 100644 (file)
@@ -601,6 +601,7 @@ void usb_complete_err ( struct usb_endpoint *ep, struct io_buffer *iobuf,
  */
 int usb_prefill ( struct usb_endpoint *ep ) {
        struct io_buffer *iobuf;
+       size_t reserve = ep->reserve;
        size_t len = ( ep->len ? ep->len : ep->mtu );
        unsigned int fill;
        int rc;
@@ -614,11 +615,12 @@ int usb_prefill ( struct usb_endpoint *ep ) {
        for ( fill = 0 ; fill < ep->max ; fill++ ) {
 
                /* Allocate I/O buffer */
-               iobuf = alloc_iob ( len );
+               iobuf = alloc_iob ( reserve + len );
                if ( ! iobuf ) {
                        rc = -ENOMEM;
                        goto err_alloc;
                }
+               iob_reserve ( iobuf, reserve );
 
                /* Add to recycled buffer list */
                list_add_tail ( &iobuf->list, &ep->recycled );
@@ -639,6 +641,7 @@ int usb_prefill ( struct usb_endpoint *ep ) {
  */
 int usb_refill ( struct usb_endpoint *ep ) {
        struct io_buffer *iobuf;
+       size_t reserve = ep->reserve;
        size_t len = ( ep->len ? ep->len : ep->mtu );
        int rc;
 
@@ -652,9 +655,10 @@ int usb_refill ( struct usb_endpoint *ep ) {
                /* Get or allocate buffer */
                if ( list_empty ( &ep->recycled ) ) {
                        /* Recycled buffer list is empty; allocate new buffer */
-                       iobuf = alloc_iob ( len );
+                       iobuf = alloc_iob ( reserve + len );
                        if ( ! iobuf )
                                return -ENOMEM;
+                       iob_reserve ( iobuf, reserve );
                } else {
                        /* Get buffer from recycled buffer list */
                        iobuf = list_first_entry ( &ep->recycled,
index 955ad4ab4b83d5873b527bedba3c550b35fcdcc8..16dab4be8cc7a74abab9ab7adcc59e9a7ff04876 100644 (file)
@@ -447,8 +447,8 @@ static int acm_probe ( struct usb_function *func,
        acm->rndis = rndis;
        usbnet_init ( &acm->usbnet, func, &acm_intr_operations,
                      &acm_in_operations, &acm_out_operations );
-       usb_refill_init ( &acm->usbnet.intr, 0, ACM_INTR_MAX_FILL );
-       usb_refill_init ( &acm->usbnet.in, ACM_IN_MTU, ACM_IN_MAX_FILL );
+       usb_refill_init ( &acm->usbnet.intr, 0, 0, ACM_INTR_MAX_FILL );
+       usb_refill_init ( &acm->usbnet.in, 0, ACM_IN_MTU, ACM_IN_MAX_FILL );
 
        /* Describe USB network device */
        if ( ( rc = usbnet_describe ( &acm->usbnet, config ) ) != 0 ) {
index 817a84a29fa5965612ab7af3998cd7dc6ef8b7a5..61b957be9fcdb9414077e2631574a3a37efd2eb9 100644 (file)
@@ -532,8 +532,8 @@ static int dm96xx_probe ( struct usb_function *func,
        dm96xx->netdev = netdev;
        usbnet_init ( &dm96xx->usbnet, func, &dm96xx_intr_operations,
                      &dm96xx_in_operations, &dm96xx_out_operations );
-       usb_refill_init ( &dm96xx->usbnet.intr, 0, DM96XX_INTR_MAX_FILL );
-       usb_refill_init ( &dm96xx->usbnet.in, DM96XX_IN_MTU,
+       usb_refill_init ( &dm96xx->usbnet.intr, 0, 0, DM96XX_INTR_MAX_FILL );
+       usb_refill_init ( &dm96xx->usbnet.in, 0, DM96XX_IN_MTU,
                          DM96XX_IN_MAX_FILL );
        DBGC ( dm96xx, "DM96XX %p on %s\n", dm96xx, func->name );
 
index 371611d54ea9de3e71004d3abb37e31d7fe88d7c..f2d9161c1abece140ee5bfb6a31aa4edde24da62 100644 (file)
@@ -437,8 +437,8 @@ static int ecm_probe ( struct usb_function *func,
        ecm->netdev = netdev;
        usbnet_init ( &ecm->usbnet, func, &ecm_intr_operations,
                      &ecm_in_operations, &ecm_out_operations );
-       usb_refill_init ( &ecm->usbnet.intr, 0, ECM_INTR_MAX_FILL );
-       usb_refill_init ( &ecm->usbnet.in, ECM_IN_MTU, ECM_IN_MAX_FILL );
+       usb_refill_init ( &ecm->usbnet.intr, 0, 0, ECM_INTR_MAX_FILL );
+       usb_refill_init ( &ecm->usbnet.in, 0, ECM_IN_MTU, ECM_IN_MAX_FILL );
        DBGC ( ecm, "ECM %p on %s\n", ecm, func->name );
 
        /* Describe USB network device */
index fed77a00f4f4e950c54ab7745bcbe5fb00fb9329..1837291f7df79173ca90b68028a564264198ac0e 100644 (file)
@@ -186,7 +186,7 @@ static int ncm_in_prefill ( struct ncm_device *ncm ) {
                        count = NCM_IN_MIN_COUNT;
                if ( ( count * mtu ) > NCM_IN_MAX_SIZE )
                        continue;
-               usb_refill_init ( &ncm->usbnet.in, mtu, count );
+               usb_refill_init ( &ncm->usbnet.in, 0, mtu, count );
                if ( ( rc = usb_prefill ( &ncm->usbnet.in ) ) != 0 ) {
                        DBGC ( ncm, "NCM %p could not prefill %dx %zd-byte "
                               "buffers for bulk IN\n", ncm, count, mtu );
@@ -575,7 +575,7 @@ static int ncm_probe ( struct usb_function *func,
        ncm->netdev = netdev;
        usbnet_init ( &ncm->usbnet, func, &ncm_intr_operations,
                      &ncm_in_operations, &ncm_out_operations );
-       usb_refill_init ( &ncm->usbnet.intr, 0, NCM_INTR_COUNT );
+       usb_refill_init ( &ncm->usbnet.intr, 0, 0, NCM_INTR_COUNT );
        DBGC ( ncm, "NCM %p on %s\n", ncm, func->name );
 
        /* Describe USB network device */
index 5e4e0e12b8652ca59a485e9ead286509a203eaac..9a96346004ea3794774912864d38ed6551bc7bbd 100644 (file)
@@ -979,8 +979,9 @@ static int smsc75xx_probe ( struct usb_function *func,
        smsc75xx->netdev = netdev;
        usbnet_init ( &smsc75xx->usbnet, func, &smsc75xx_intr_operations,
                      &smsc75xx_in_operations, &smsc75xx_out_operations );
-       usb_refill_init ( &smsc75xx->usbnet.intr, 0, SMSC75XX_INTR_MAX_FILL );
-       usb_refill_init ( &smsc75xx->usbnet.in, SMSC75XX_IN_MTU,
+       usb_refill_init ( &smsc75xx->usbnet.intr, 0, 0,
+                         SMSC75XX_INTR_MAX_FILL );
+       usb_refill_init ( &smsc75xx->usbnet.in, 0, SMSC75XX_IN_MTU,
                          SMSC75XX_IN_MAX_FILL );
        mii_init ( &smsc75xx->mii, &smsc75xx_mii_operations );
        DBGC ( smsc75xx, "SMSC75XX %p on %s\n", smsc75xx, func->name );
index 21e89a44d9a10e02f3a1ea58946e14514c9cae5d..1e237d01ae0dbc48c200d04e9afaada4a7134c0b 100644 (file)
@@ -1140,8 +1140,9 @@ static int smsc95xx_probe ( struct usb_function *func,
        smsc95xx->netdev = netdev;
        usbnet_init ( &smsc95xx->usbnet, func, &smsc95xx_intr_operations,
                      &smsc95xx_in_operations, &smsc95xx_out_operations );
-       usb_refill_init ( &smsc95xx->usbnet.intr, 0, SMSC95XX_INTR_MAX_FILL );
-       usb_refill_init ( &smsc95xx->usbnet.in, SMSC95XX_IN_MTU,
+       usb_refill_init ( &smsc95xx->usbnet.intr, 0, 0,
+                         SMSC95XX_INTR_MAX_FILL );
+       usb_refill_init ( &smsc95xx->usbnet.in, 0, SMSC95XX_IN_MTU,
                          SMSC95XX_IN_MAX_FILL );
        mii_init ( &smsc95xx->mii, &smsc95xx_mii_operations );
        DBGC ( smsc95xx, "SMSC95XX %p on %s\n", smsc95xx, func->name );
index 7095fc31b60165fc18c7dac3660cb4910261e806..47914bcdbf20e62278081a3f74837f7bbf577122 100644 (file)
@@ -416,7 +416,7 @@ static int hub_probe ( struct usb_function *func,
                ( enhanced ? USB_HUB_FEATURES_ENHANCED : USB_HUB_FEATURES );
        hubdev->flags = func->id->driver_data;
        usb_endpoint_init ( &hubdev->intr, usb, &usb_hub_intr_operations );
-       usb_refill_init ( &hubdev->intr, 0, USB_HUB_INTR_FILL );
+       usb_refill_init ( &hubdev->intr, 0, 0, USB_HUB_INTR_FILL );
        process_init_stopped ( &hubdev->refill, &hub_refill_desc, NULL );
 
        /* Locate hub interface descriptor */
index 76db5771ffe5b246c9ec9a1efe8e079dd4e3a521..a8ab6ab76bd83ce59c954b1f079e236ad835f293 100644 (file)
@@ -425,7 +425,7 @@ static int usbkbd_probe ( struct usb_function *func,
        kbd->name = func->name;
        kbd->bus = usb->port->hub->bus;
        usbhid_init ( &kbd->hid, func, &usbkbd_operations, NULL );
-       usb_refill_init ( &kbd->hid.in, sizeof ( kbd->report ),
+       usb_refill_init ( &kbd->hid.in, 0, sizeof ( kbd->report ),
                          USBKBD_INTR_MAX_FILL );
 
        /* Describe USB human interface device */
index 37b6d94edd5f3a52dd8c2bb207b6457082b9f705..e7909d300aad2567ccd8669445672eaf1c2ebef9 100644 (file)
@@ -414,7 +414,9 @@ struct usb_endpoint {
 
        /** Recycled I/O buffer list */
        struct list_head recycled;
-       /** Refill buffer length */
+       /** Refill buffer reserved header length */
+       size_t reserve;
+       /** Refill buffer payload length */
        size_t len;
        /** Maximum fill level */
        unsigned int max;
@@ -588,13 +590,16 @@ extern void usb_complete_err ( struct usb_endpoint *ep,
  * Initialise USB endpoint refill
  *
  * @v ep               USB endpoint
- * @v len              Refill buffer length (or zero to use endpoint's MTU)
+ * @v reserve          Refill buffer reserved header length
+ * @v len              Refill buffer payload length (zero for endpoint's MTU)
  * @v max              Maximum fill level
  */
 static inline __attribute__ (( always_inline )) void
-usb_refill_init ( struct usb_endpoint *ep, size_t len, unsigned int max ) {
+usb_refill_init ( struct usb_endpoint *ep, size_t reserve, size_t len,
+                 unsigned int max ) {
 
        INIT_LIST_HEAD ( &ep->recycled );
+       ep->reserve = reserve;
        ep->len = len;
        ep->max = max;
 }
index 94f216104bf57204cd9a9ff823a09c13171c1ecf..db8c3d348ca5101d71ec790751668e702b3ac26e 100644 (file)
@@ -472,7 +472,7 @@ static int efi_usb_async_start ( struct efi_usb_interface *usbintf,
        usbep->context = context;
 
        /* Prefill endpoint */
-       usb_refill_init ( &usbep->ep, len, EFI_USB_ASYNC_FILL );
+       usb_refill_init ( &usbep->ep, 0, len, EFI_USB_ASYNC_FILL );
        if ( ( rc = usb_prefill ( &usbep->ep ) ) != 0 ) {
                DBGC ( usbdev, "USBDEV %s %s could not prefill: %s\n",
                       usbintf->name, usb_endpoint_name ( &usbep->ep ),