mirror of https://github.com/ipxe/ipxe.git
[usb] Allow for USB network devices with no interrupt endpoint
Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/64/head
parent
84e25513b1
commit
63113f591f
|
@ -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 )
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
Loading…
Reference in New Issue