david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[usb] Allow for USB network devices with no interrupt endpoint

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown 2017-05-18 15:18:25 +01:00
parent 84e25513b1
commit 63113f591f
2 changed files with 34 additions and 14 deletions

View File

@ -35,11 +35,11 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
* USB network devices use a variety of packet formats and interface * USB network devices use a variety of packet formats and interface
* descriptors, but tend to have several features in common: * descriptors, but tend to have several features in common:
* *
* - a single interrupt endpoint using the generic refill mechanism * - a single bulk OUT endpoint
* *
* - a single bulk IN endpoint using the generic refill mechanism * - a single bulk IN endpoint using the generic refill mechanism
* *
* - a single bulk OUT endpoint * - an optional interrupt endpoint using the generic refill mechanism
* *
* - optional use of an alternate setting to enable the data interface * - optional use of an alternate setting to enable the data interface
* *
@ -55,15 +55,17 @@ int usbnet_open ( struct usbnet_device *usbnet ) {
struct usb_device *usb = usbnet->func->usb; struct usb_device *usb = usbnet->func->usb;
int rc; int rc;
/* Open interrupt endpoint */ /* Open interrupt endpoint, if applicable */
if ( ( rc = usb_endpoint_open ( &usbnet->intr ) ) != 0 ) { if ( usbnet_has_intr ( usbnet ) &&
( rc = usb_endpoint_open ( &usbnet->intr ) ) != 0 ) {
DBGC ( usbnet, "USBNET %s could not open interrupt: %s\n", DBGC ( usbnet, "USBNET %s could not open interrupt: %s\n",
usbnet->func->name, strerror ( rc ) ); usbnet->func->name, strerror ( rc ) );
goto err_open_intr; goto err_open_intr;
} }
/* Refill interrupt endpoint */ /* Refill interrupt endpoint, if applicable */
if ( ( rc = usb_refill ( &usbnet->intr ) ) != 0 ) { if ( usbnet_has_intr ( usbnet ) &&
( rc = usb_refill ( &usbnet->intr ) ) != 0 ) {
DBGC ( usbnet, "USBNET %s could not refill interrupt: %s\n", DBGC ( usbnet, "USBNET %s could not refill interrupt: %s\n",
usbnet->func->name, strerror ( rc ) ); usbnet->func->name, strerror ( rc ) );
goto err_refill_intr; goto err_refill_intr;
@ -111,7 +113,8 @@ int usbnet_open ( struct usbnet_device *usbnet ) {
usb_set_interface ( usb, usbnet->data, 0 ); usb_set_interface ( usb, usbnet->data, 0 );
err_set_interface: err_set_interface:
err_refill_intr: err_refill_intr:
usb_endpoint_close ( &usbnet->intr ); if ( usbnet_has_intr ( usbnet ) )
usb_endpoint_close ( &usbnet->intr );
err_open_intr: err_open_intr:
return rc; return rc;
} }
@ -134,8 +137,9 @@ void usbnet_close ( struct usbnet_device *usbnet ) {
if ( usbnet->alternate ) if ( usbnet->alternate )
usb_set_interface ( usb, usbnet->data, 0 ); usb_set_interface ( usb, usbnet->data, 0 );
/* Close interrupt endpoint */ /* Close interrupt endpoint, if applicable */
usb_endpoint_close ( &usbnet->intr ); if ( usbnet_has_intr ( usbnet ) )
usb_endpoint_close ( &usbnet->intr );
} }
/** /**
@ -151,9 +155,11 @@ int usbnet_refill ( struct usbnet_device *usbnet ) {
if ( ( rc = usb_refill ( &usbnet->in ) ) != 0 ) if ( ( rc = usb_refill ( &usbnet->in ) ) != 0 )
return rc; return rc;
/* Refill interrupt endpoint */ /* Refill interrupt endpoint, if applicable */
if ( ( rc = usb_refill ( &usbnet->intr ) ) != 0 ) if ( usbnet_has_intr ( usbnet ) &&
( rc = usb_refill ( &usbnet->intr ) ) != 0 ) {
return rc; return rc;
}
return 0; return 0;
} }
@ -272,9 +278,11 @@ int usbnet_describe ( struct usbnet_device *usbnet,
struct usb_configuration_descriptor *config ) { struct usb_configuration_descriptor *config ) {
int rc; int rc;
/* Describe communications interface */ /* Describe communications interface, if applicable */
if ( ( rc = usbnet_comms_describe ( usbnet, config ) ) != 0 ) if ( usbnet_has_intr ( usbnet ) &&
( rc = usbnet_comms_describe ( usbnet, config ) ) != 0 ) {
return rc; return rc;
}
/* Describe data interface */ /* Describe data interface */
if ( ( rc = usbnet_data_describe ( usbnet, config ) ) != 0 ) if ( ( rc = usbnet_data_describe ( usbnet, config ) ) != 0 )

View File

@ -36,7 +36,7 @@ struct usbnet_device {
* *
* @v usbnet USB network device * @v usbnet USB network device
* @v func USB function * @v func USB function
* @v intr Interrupt endpoint operations * @v intr Interrupt endpoint operations, or NULL
* @v in Bulk IN endpoint operations * @v in Bulk IN endpoint operations
* @v out Bulk OUT endpoint operations * @v out Bulk OUT endpoint operations
*/ */
@ -53,6 +53,18 @@ usbnet_init ( struct usbnet_device *usbnet, struct usb_function *func,
usb_endpoint_init ( &usbnet->out, usb, out ); usb_endpoint_init ( &usbnet->out, usb, out );
} }
/**
* Check if USB network device has an interrupt endpoint
*
* @v usbnet USB network device
* @ret has_intr Device has an interrupt endpoint
*/
static inline __attribute__ (( always_inline )) int
usbnet_has_intr ( struct usbnet_device *usbnet ) {
return ( usbnet->intr.driver != NULL );
}
extern int usbnet_open ( struct usbnet_device *usbnet ); extern int usbnet_open ( struct usbnet_device *usbnet );
extern void usbnet_close ( struct usbnet_device *usbnet ); extern void usbnet_close ( struct usbnet_device *usbnet );
extern int usbnet_refill ( struct usbnet_device *usbnet ); extern int usbnet_refill ( struct usbnet_device *usbnet );