Browse Source

[usb] Allow USB endpoints to specify a reserved header length for refills

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
71b83a6d00

+ 6
- 2
src/drivers/bus/usb.c View File

@@ -601,6 +601,7 @@ void usb_complete_err ( struct usb_endpoint *ep, struct io_buffer *iobuf,
601 601
  */
602 602
 int usb_prefill ( struct usb_endpoint *ep ) {
603 603
 	struct io_buffer *iobuf;
604
+	size_t reserve = ep->reserve;
604 605
 	size_t len = ( ep->len ? ep->len : ep->mtu );
605 606
 	unsigned int fill;
606 607
 	int rc;
@@ -614,11 +615,12 @@ int usb_prefill ( struct usb_endpoint *ep ) {
614 615
 	for ( fill = 0 ; fill < ep->max ; fill++ ) {
615 616
 
616 617
 		/* Allocate I/O buffer */
617
-		iobuf = alloc_iob ( len );
618
+		iobuf = alloc_iob ( reserve + len );
618 619
 		if ( ! iobuf ) {
619 620
 			rc = -ENOMEM;
620 621
 			goto err_alloc;
621 622
 		}
623
+		iob_reserve ( iobuf, reserve );
622 624
 
623 625
 		/* Add to recycled buffer list */
624 626
 		list_add_tail ( &iobuf->list, &ep->recycled );
@@ -639,6 +641,7 @@ int usb_prefill ( struct usb_endpoint *ep ) {
639 641
  */
640 642
 int usb_refill ( struct usb_endpoint *ep ) {
641 643
 	struct io_buffer *iobuf;
644
+	size_t reserve = ep->reserve;
642 645
 	size_t len = ( ep->len ? ep->len : ep->mtu );
643 646
 	int rc;
644 647
 
@@ -652,9 +655,10 @@ int usb_refill ( struct usb_endpoint *ep ) {
652 655
 		/* Get or allocate buffer */
653 656
 		if ( list_empty ( &ep->recycled ) ) {
654 657
 			/* Recycled buffer list is empty; allocate new buffer */
655
-			iobuf = alloc_iob ( len );
658
+			iobuf = alloc_iob ( reserve + len );
656 659
 			if ( ! iobuf )
657 660
 				return -ENOMEM;
661
+			iob_reserve ( iobuf, reserve );
658 662
 		} else {
659 663
 			/* Get buffer from recycled buffer list */
660 664
 			iobuf = list_first_entry ( &ep->recycled,

+ 2
- 2
src/drivers/net/acm.c View File

@@ -447,8 +447,8 @@ static int acm_probe ( struct usb_function *func,
447 447
 	acm->rndis = rndis;
448 448
 	usbnet_init ( &acm->usbnet, func, &acm_intr_operations,
449 449
 		      &acm_in_operations, &acm_out_operations );
450
-	usb_refill_init ( &acm->usbnet.intr, 0, ACM_INTR_MAX_FILL );
451
-	usb_refill_init ( &acm->usbnet.in, ACM_IN_MTU, ACM_IN_MAX_FILL );
450
+	usb_refill_init ( &acm->usbnet.intr, 0, 0, ACM_INTR_MAX_FILL );
451
+	usb_refill_init ( &acm->usbnet.in, 0, ACM_IN_MTU, ACM_IN_MAX_FILL );
452 452
 
453 453
 	/* Describe USB network device */
454 454
 	if ( ( rc = usbnet_describe ( &acm->usbnet, config ) ) != 0 ) {

+ 2
- 2
src/drivers/net/dm96xx.c View File

@@ -532,8 +532,8 @@ static int dm96xx_probe ( struct usb_function *func,
532 532
 	dm96xx->netdev = netdev;
533 533
 	usbnet_init ( &dm96xx->usbnet, func, &dm96xx_intr_operations,
534 534
 		      &dm96xx_in_operations, &dm96xx_out_operations );
535
-	usb_refill_init ( &dm96xx->usbnet.intr, 0, DM96XX_INTR_MAX_FILL );
536
-	usb_refill_init ( &dm96xx->usbnet.in, DM96XX_IN_MTU,
535
+	usb_refill_init ( &dm96xx->usbnet.intr, 0, 0, DM96XX_INTR_MAX_FILL );
536
+	usb_refill_init ( &dm96xx->usbnet.in, 0, DM96XX_IN_MTU,
537 537
 			  DM96XX_IN_MAX_FILL );
538 538
 	DBGC ( dm96xx, "DM96XX %p on %s\n", dm96xx, func->name );
539 539
 

+ 2
- 2
src/drivers/net/ecm.c View File

@@ -437,8 +437,8 @@ static int ecm_probe ( struct usb_function *func,
437 437
 	ecm->netdev = netdev;
438 438
 	usbnet_init ( &ecm->usbnet, func, &ecm_intr_operations,
439 439
 		      &ecm_in_operations, &ecm_out_operations );
440
-	usb_refill_init ( &ecm->usbnet.intr, 0, ECM_INTR_MAX_FILL );
441
-	usb_refill_init ( &ecm->usbnet.in, ECM_IN_MTU, ECM_IN_MAX_FILL );
440
+	usb_refill_init ( &ecm->usbnet.intr, 0, 0, ECM_INTR_MAX_FILL );
441
+	usb_refill_init ( &ecm->usbnet.in, 0, ECM_IN_MTU, ECM_IN_MAX_FILL );
442 442
 	DBGC ( ecm, "ECM %p on %s\n", ecm, func->name );
443 443
 
444 444
 	/* Describe USB network device */

+ 2
- 2
src/drivers/net/ncm.c View File

@@ -186,7 +186,7 @@ static int ncm_in_prefill ( struct ncm_device *ncm ) {
186 186
 			count = NCM_IN_MIN_COUNT;
187 187
 		if ( ( count * mtu ) > NCM_IN_MAX_SIZE )
188 188
 			continue;
189
-		usb_refill_init ( &ncm->usbnet.in, mtu, count );
189
+		usb_refill_init ( &ncm->usbnet.in, 0, mtu, count );
190 190
 		if ( ( rc = usb_prefill ( &ncm->usbnet.in ) ) != 0 ) {
191 191
 			DBGC ( ncm, "NCM %p could not prefill %dx %zd-byte "
192 192
 			       "buffers for bulk IN\n", ncm, count, mtu );
@@ -575,7 +575,7 @@ static int ncm_probe ( struct usb_function *func,
575 575
 	ncm->netdev = netdev;
576 576
 	usbnet_init ( &ncm->usbnet, func, &ncm_intr_operations,
577 577
 		      &ncm_in_operations, &ncm_out_operations );
578
-	usb_refill_init ( &ncm->usbnet.intr, 0, NCM_INTR_COUNT );
578
+	usb_refill_init ( &ncm->usbnet.intr, 0, 0, NCM_INTR_COUNT );
579 579
 	DBGC ( ncm, "NCM %p on %s\n", ncm, func->name );
580 580
 
581 581
 	/* Describe USB network device */

+ 3
- 2
src/drivers/net/smsc75xx.c View File

@@ -979,8 +979,9 @@ static int smsc75xx_probe ( struct usb_function *func,
979 979
 	smsc75xx->netdev = netdev;
980 980
 	usbnet_init ( &smsc75xx->usbnet, func, &smsc75xx_intr_operations,
981 981
 		      &smsc75xx_in_operations, &smsc75xx_out_operations );
982
-	usb_refill_init ( &smsc75xx->usbnet.intr, 0, SMSC75XX_INTR_MAX_FILL );
983
-	usb_refill_init ( &smsc75xx->usbnet.in, SMSC75XX_IN_MTU,
982
+	usb_refill_init ( &smsc75xx->usbnet.intr, 0, 0,
983
+			  SMSC75XX_INTR_MAX_FILL );
984
+	usb_refill_init ( &smsc75xx->usbnet.in, 0, SMSC75XX_IN_MTU,
984 985
 			  SMSC75XX_IN_MAX_FILL );
985 986
 	mii_init ( &smsc75xx->mii, &smsc75xx_mii_operations );
986 987
 	DBGC ( smsc75xx, "SMSC75XX %p on %s\n", smsc75xx, func->name );

+ 3
- 2
src/drivers/net/smsc95xx.c View File

@@ -1140,8 +1140,9 @@ static int smsc95xx_probe ( struct usb_function *func,
1140 1140
 	smsc95xx->netdev = netdev;
1141 1141
 	usbnet_init ( &smsc95xx->usbnet, func, &smsc95xx_intr_operations,
1142 1142
 		      &smsc95xx_in_operations, &smsc95xx_out_operations );
1143
-	usb_refill_init ( &smsc95xx->usbnet.intr, 0, SMSC95XX_INTR_MAX_FILL );
1144
-	usb_refill_init ( &smsc95xx->usbnet.in, SMSC95XX_IN_MTU,
1143
+	usb_refill_init ( &smsc95xx->usbnet.intr, 0, 0,
1144
+			  SMSC95XX_INTR_MAX_FILL );
1145
+	usb_refill_init ( &smsc95xx->usbnet.in, 0, SMSC95XX_IN_MTU,
1145 1146
 			  SMSC95XX_IN_MAX_FILL );
1146 1147
 	mii_init ( &smsc95xx->mii, &smsc95xx_mii_operations );
1147 1148
 	DBGC ( smsc95xx, "SMSC95XX %p on %s\n", smsc95xx, func->name );

+ 1
- 1
src/drivers/usb/usbhub.c View File

@@ -416,7 +416,7 @@ static int hub_probe ( struct usb_function *func,
416 416
 		( enhanced ? USB_HUB_FEATURES_ENHANCED : USB_HUB_FEATURES );
417 417
 	hubdev->flags = func->id->driver_data;
418 418
 	usb_endpoint_init ( &hubdev->intr, usb, &usb_hub_intr_operations );
419
-	usb_refill_init ( &hubdev->intr, 0, USB_HUB_INTR_FILL );
419
+	usb_refill_init ( &hubdev->intr, 0, 0, USB_HUB_INTR_FILL );
420 420
 	process_init_stopped ( &hubdev->refill, &hub_refill_desc, NULL );
421 421
 
422 422
 	/* Locate hub interface descriptor */

+ 1
- 1
src/drivers/usb/usbkbd.c View File

@@ -425,7 +425,7 @@ static int usbkbd_probe ( struct usb_function *func,
425 425
 	kbd->name = func->name;
426 426
 	kbd->bus = usb->port->hub->bus;
427 427
 	usbhid_init ( &kbd->hid, func, &usbkbd_operations, NULL );
428
-	usb_refill_init ( &kbd->hid.in, sizeof ( kbd->report ),
428
+	usb_refill_init ( &kbd->hid.in, 0, sizeof ( kbd->report ),
429 429
 			  USBKBD_INTR_MAX_FILL );
430 430
 
431 431
 	/* Describe USB human interface device */

+ 8
- 3
src/include/ipxe/usb.h View File

@@ -414,7 +414,9 @@ struct usb_endpoint {
414 414
 
415 415
 	/** Recycled I/O buffer list */
416 416
 	struct list_head recycled;
417
-	/** Refill buffer length */
417
+	/** Refill buffer reserved header length */
418
+	size_t reserve;
419
+	/** Refill buffer payload length */
418 420
 	size_t len;
419 421
 	/** Maximum fill level */
420 422
 	unsigned int max;
@@ -588,13 +590,16 @@ extern void usb_complete_err ( struct usb_endpoint *ep,
588 590
  * Initialise USB endpoint refill
589 591
  *
590 592
  * @v ep		USB endpoint
591
- * @v len		Refill buffer length (or zero to use endpoint's MTU)
593
+ * @v reserve		Refill buffer reserved header length
594
+ * @v len		Refill buffer payload length (zero for endpoint's MTU)
592 595
  * @v max		Maximum fill level
593 596
  */
594 597
 static inline __attribute__ (( always_inline )) void
595
-usb_refill_init ( struct usb_endpoint *ep, size_t len, unsigned int max ) {
598
+usb_refill_init ( struct usb_endpoint *ep, size_t reserve, size_t len,
599
+		  unsigned int max ) {
596 600
 
597 601
 	INIT_LIST_HEAD ( &ep->recycled );
602
+	ep->reserve = reserve;
598 603
 	ep->len = len;
599 604
 	ep->max = max;
600 605
 }

+ 1
- 1
src/interface/efi/efi_usb.c View File

@@ -472,7 +472,7 @@ static int efi_usb_async_start ( struct efi_usb_interface *usbintf,
472 472
 	usbep->context = context;
473 473
 
474 474
 	/* Prefill endpoint */
475
-	usb_refill_init ( &usbep->ep, len, EFI_USB_ASYNC_FILL );
475
+	usb_refill_init ( &usbep->ep, 0, len, EFI_USB_ASYNC_FILL );
476 476
 	if ( ( rc = usb_prefill ( &usbep->ep ) ) != 0 ) {
477 477
 		DBGC ( usbdev, "USBDEV %s %s could not prefill: %s\n",
478 478
 		       usbintf->name, usb_endpoint_name ( &usbep->ep ),

Loading…
Cancel
Save