Skip to content

Commit

Permalink
[usb] Allow USB endpoints to specify a reserved header length for ref…
Browse files Browse the repository at this point in the history
…ills

Signed-off-by: Michael Brown <mcb30@ipxe.org>
  • Loading branch information
mcb30 committed Jan 19, 2016
1 parent 8dc23d9 commit 71b83a6
Show file tree
Hide file tree
Showing 11 changed files with 31 additions and 20 deletions.
8 changes: 6 additions & 2 deletions src/drivers/bus/usb.c
Expand Up @@ -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;
Expand All @@ -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 );
Expand All @@ -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;

Expand All @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions src/drivers/net/acm.c
Expand Up @@ -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 ) {
Expand Down
4 changes: 2 additions & 2 deletions src/drivers/net/dm96xx.c
Expand Up @@ -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 );

Expand Down
4 changes: 2 additions & 2 deletions src/drivers/net/ecm.c
Expand Up @@ -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 */
Expand Down
4 changes: 2 additions & 2 deletions src/drivers/net/ncm.c
Expand Up @@ -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 );
Expand Down Expand Up @@ -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 */
Expand Down
5 changes: 3 additions & 2 deletions src/drivers/net/smsc75xx.c
Expand Up @@ -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 );
Expand Down
5 changes: 3 additions & 2 deletions src/drivers/net/smsc95xx.c
Expand Up @@ -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 );
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/usb/usbhub.c
Expand Up @@ -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 */
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/usb/usbkbd.c
Expand Up @@ -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 */
Expand Down
11 changes: 8 additions & 3 deletions src/include/ipxe/usb.h
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion src/interface/efi/efi_usb.c
Expand Up @@ -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 ),
Expand Down

0 comments on commit 71b83a6

Please sign in to comment.