mirror of https://github.com/ipxe/ipxe.git
[usb] Use generic refill framework for USB hub interrupt endpoints
Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/34/head
parent
17fc79425e
commit
ebe433e795
|
@ -40,27 +40,14 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||||
* @v hubdev Hub device
|
* @v hubdev Hub device
|
||||||
*/
|
*/
|
||||||
static void hub_refill ( struct usb_hub_device *hubdev ) {
|
static void hub_refill ( struct usb_hub_device *hubdev ) {
|
||||||
struct io_buffer *iobuf;
|
|
||||||
size_t mtu = hubdev->intr.mtu;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Enqueue any available I/O buffers */
|
/* Refill interrupt endpoint */
|
||||||
while ( ( iobuf = list_first_entry ( &hubdev->intrs, struct io_buffer,
|
if ( ( rc = usb_refill ( &hubdev->intr ) ) != 0 ) {
|
||||||
list ) ) ) {
|
DBGC ( hubdev, "HUB %s could not refill interrupt: %s\n",
|
||||||
|
hubdev->name, strerror ( rc ) );
|
||||||
/* Reset size */
|
/* Continue attempting to refill */
|
||||||
iob_put ( iobuf, ( mtu - iob_len ( iobuf ) ) );
|
return;
|
||||||
|
|
||||||
/* Enqueue I/O buffer */
|
|
||||||
if ( ( rc = usb_stream ( &hubdev->intr, iobuf, 0 ) ) != 0 ) {
|
|
||||||
DBGC ( hubdev, "HUB %s could not enqueue interrupt: "
|
|
||||||
"%s\n", hubdev->name, strerror ( rc ) );
|
|
||||||
/* Leave in available list and wait for next refill */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove from available list */
|
|
||||||
list_del ( &iobuf->list );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stop refill process */
|
/* Stop refill process */
|
||||||
|
@ -119,9 +106,6 @@ static void hub_complete ( struct usb_endpoint *ep,
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
/* Return I/O buffer to available list */
|
|
||||||
list_add_tail ( &iobuf->list, &hubdev->intrs );
|
|
||||||
|
|
||||||
/* Start refill process */
|
/* Start refill process */
|
||||||
process_add ( &hubdev->refill );
|
process_add ( &hubdev->refill );
|
||||||
}
|
}
|
||||||
|
@ -140,8 +124,6 @@ static struct usb_endpoint_driver_operations usb_hub_intr_operations = {
|
||||||
static int hub_open ( struct usb_hub *hub ) {
|
static int hub_open ( struct usb_hub *hub ) {
|
||||||
struct usb_hub_device *hubdev = usb_hub_get_drvdata ( hub );
|
struct usb_hub_device *hubdev = usb_hub_get_drvdata ( hub );
|
||||||
struct usb_device *usb = hubdev->usb;
|
struct usb_device *usb = hubdev->usb;
|
||||||
struct io_buffer *iobuf;
|
|
||||||
struct io_buffer *tmp;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -156,16 +138,6 @@ static int hub_open ( struct usb_hub *hub ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate I/O buffers */
|
|
||||||
for ( i = 0 ; i < USB_HUB_INTR_FILL ; i++ ) {
|
|
||||||
iobuf = alloc_iob ( hubdev->intr.mtu );
|
|
||||||
if ( ! iobuf ) {
|
|
||||||
rc = -ENOMEM;
|
|
||||||
goto err_alloc_iob;
|
|
||||||
}
|
|
||||||
list_add ( &iobuf->list, &hubdev->intrs );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open interrupt endpoint */
|
/* Open interrupt endpoint */
|
||||||
if ( ( rc = usb_endpoint_open ( &hubdev->intr ) ) != 0 ) {
|
if ( ( rc = usb_endpoint_open ( &hubdev->intr ) ) != 0 ) {
|
||||||
DBGC ( hubdev, "HUB %s could not register interrupt: %s\n",
|
DBGC ( hubdev, "HUB %s could not register interrupt: %s\n",
|
||||||
|
@ -183,11 +155,6 @@ static int hub_open ( struct usb_hub *hub ) {
|
||||||
|
|
||||||
usb_endpoint_close ( &hubdev->intr );
|
usb_endpoint_close ( &hubdev->intr );
|
||||||
err_open:
|
err_open:
|
||||||
err_alloc_iob:
|
|
||||||
list_for_each_entry_safe ( iobuf, tmp, &hubdev->intrs, list ) {
|
|
||||||
list_del ( &iobuf->list );
|
|
||||||
free_iob ( iobuf );
|
|
||||||
}
|
|
||||||
err_power:
|
err_power:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -199,20 +166,12 @@ static int hub_open ( struct usb_hub *hub ) {
|
||||||
*/
|
*/
|
||||||
static void hub_close ( struct usb_hub *hub ) {
|
static void hub_close ( struct usb_hub *hub ) {
|
||||||
struct usb_hub_device *hubdev = usb_hub_get_drvdata ( hub );
|
struct usb_hub_device *hubdev = usb_hub_get_drvdata ( hub );
|
||||||
struct io_buffer *iobuf;
|
|
||||||
struct io_buffer *tmp;
|
|
||||||
|
|
||||||
/* Close interrupt endpoint */
|
/* Close interrupt endpoint */
|
||||||
usb_endpoint_close ( &hubdev->intr );
|
usb_endpoint_close ( &hubdev->intr );
|
||||||
|
|
||||||
/* Stop refill process */
|
/* Stop refill process */
|
||||||
process_del ( &hubdev->refill );
|
process_del ( &hubdev->refill );
|
||||||
|
|
||||||
/* Free I/O buffers */
|
|
||||||
list_for_each_entry_safe ( iobuf, tmp, &hubdev->intrs, list ) {
|
|
||||||
list_del ( &iobuf->list );
|
|
||||||
free_iob ( iobuf );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -415,7 +374,7 @@ static int hub_probe ( struct usb_function *func,
|
||||||
hubdev->features =
|
hubdev->features =
|
||||||
( enhanced ? USB_HUB_FEATURES_ENHANCED : USB_HUB_FEATURES );
|
( enhanced ? USB_HUB_FEATURES_ENHANCED : USB_HUB_FEATURES );
|
||||||
usb_endpoint_init ( &hubdev->intr, usb, &usb_hub_intr_operations );
|
usb_endpoint_init ( &hubdev->intr, usb, &usb_hub_intr_operations );
|
||||||
INIT_LIST_HEAD ( &hubdev->intrs );
|
usb_refill_init ( &hubdev->intr, 0, USB_HUB_INTR_FILL );
|
||||||
process_init_stopped ( &hubdev->refill, &hub_refill_desc, NULL );
|
process_init_stopped ( &hubdev->refill, &hub_refill_desc, NULL );
|
||||||
|
|
||||||
/* Locate hub interface descriptor */
|
/* Locate hub interface descriptor */
|
||||||
|
@ -510,7 +469,6 @@ static void hub_remove ( struct usb_function *func ) {
|
||||||
/* Unregister hub */
|
/* Unregister hub */
|
||||||
unregister_usb_hub ( hubdev->hub );
|
unregister_usb_hub ( hubdev->hub );
|
||||||
assert ( ! process_running ( &hubdev->refill ) );
|
assert ( ! process_running ( &hubdev->refill ) );
|
||||||
assert ( list_empty ( &hubdev->intrs ) );
|
|
||||||
|
|
||||||
/* Free hub */
|
/* Free hub */
|
||||||
free_usb_hub ( hubdev->hub );
|
free_usb_hub ( hubdev->hub );
|
||||||
|
|
|
@ -227,8 +227,6 @@ struct usb_hub_device {
|
||||||
|
|
||||||
/** Interrupt endpoint */
|
/** Interrupt endpoint */
|
||||||
struct usb_endpoint intr;
|
struct usb_endpoint intr;
|
||||||
/** Recycled interrupt I/O buffers */
|
|
||||||
struct list_head intrs;
|
|
||||||
/** Interrupt endpoint refill process */
|
/** Interrupt endpoint refill process */
|
||||||
struct process refill;
|
struct process refill;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue