diff options
author | Michael Brown <mcb30@ipxe.org> | 2016-01-19 00:01:11 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2016-01-19 00:01:11 +0000 |
commit | 71b83a6d00caedb62cc62a5810f99a7a1478f2ae (patch) | |
tree | 8e1224923a381d42a60f4bac985868e5294dad66 | |
parent | 8dc23d9b83027ea93e5e8689316f8448ff964647 (diff) | |
download | ipxe-71b83a6d00caedb62cc62a5810f99a7a1478f2ae.zip ipxe-71b83a6d00caedb62cc62a5810f99a7a1478f2ae.tar.gz ipxe-71b83a6d00caedb62cc62a5810f99a7a1478f2ae.tar.bz2 |
[usb] Allow USB endpoints to specify a reserved header length for refills
Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r-- | src/drivers/bus/usb.c | 8 | ||||
-rw-r--r-- | src/drivers/net/acm.c | 4 | ||||
-rw-r--r-- | src/drivers/net/dm96xx.c | 4 | ||||
-rw-r--r-- | src/drivers/net/ecm.c | 4 | ||||
-rw-r--r-- | src/drivers/net/ncm.c | 4 | ||||
-rw-r--r-- | src/drivers/net/smsc75xx.c | 5 | ||||
-rw-r--r-- | src/drivers/net/smsc95xx.c | 5 | ||||
-rw-r--r-- | src/drivers/usb/usbhub.c | 2 | ||||
-rw-r--r-- | src/drivers/usb/usbkbd.c | 2 | ||||
-rw-r--r-- | src/include/ipxe/usb.h | 11 | ||||
-rw-r--r-- | src/interface/efi/efi_usb.c | 2 |
11 files changed, 31 insertions, 20 deletions
diff --git a/src/drivers/bus/usb.c b/src/drivers/bus/usb.c index b1fa4ef..880e3f0 100644 --- a/src/drivers/bus/usb.c +++ b/src/drivers/bus/usb.c @@ -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, diff --git a/src/drivers/net/acm.c b/src/drivers/net/acm.c index 955ad4a..16dab4b 100644 --- a/src/drivers/net/acm.c +++ b/src/drivers/net/acm.c @@ -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 ) { diff --git a/src/drivers/net/dm96xx.c b/src/drivers/net/dm96xx.c index 817a84a..61b957b 100644 --- a/src/drivers/net/dm96xx.c +++ b/src/drivers/net/dm96xx.c @@ -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 ); diff --git a/src/drivers/net/ecm.c b/src/drivers/net/ecm.c index 371611d..f2d9161 100644 --- a/src/drivers/net/ecm.c +++ b/src/drivers/net/ecm.c @@ -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 */ diff --git a/src/drivers/net/ncm.c b/src/drivers/net/ncm.c index fed77a0..1837291 100644 --- a/src/drivers/net/ncm.c +++ b/src/drivers/net/ncm.c @@ -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 */ diff --git a/src/drivers/net/smsc75xx.c b/src/drivers/net/smsc75xx.c index 5e4e0e1..9a96346 100644 --- a/src/drivers/net/smsc75xx.c +++ b/src/drivers/net/smsc75xx.c @@ -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 ); diff --git a/src/drivers/net/smsc95xx.c b/src/drivers/net/smsc95xx.c index 21e89a4..1e237d0 100644 --- a/src/drivers/net/smsc95xx.c +++ b/src/drivers/net/smsc95xx.c @@ -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 ); diff --git a/src/drivers/usb/usbhub.c b/src/drivers/usb/usbhub.c index 7095fc3..47914bc 100644 --- a/src/drivers/usb/usbhub.c +++ b/src/drivers/usb/usbhub.c @@ -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 */ diff --git a/src/drivers/usb/usbkbd.c b/src/drivers/usb/usbkbd.c index 76db577..a8ab6ab 100644 --- a/src/drivers/usb/usbkbd.c +++ b/src/drivers/usb/usbkbd.c @@ -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 */ diff --git a/src/include/ipxe/usb.h b/src/include/ipxe/usb.h index 37b6d94..e7909d3 100644 --- a/src/include/ipxe/usb.h +++ b/src/include/ipxe/usb.h @@ -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; } diff --git a/src/interface/efi/efi_usb.c b/src/interface/efi/efi_usb.c index 94f2161..db8c3d3 100644 --- a/src/interface/efi/efi_usb.c +++ b/src/interface/efi/efi_usb.c @@ -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 ), |