Browse Source

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

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 7 years ago
parent
commit
63113f591f
2 changed files with 34 additions and 14 deletions
  1. 21
    13
      src/drivers/usb/usbnet.c
  2. 13
    1
      src/include/ipxe/usbnet.h

+ 21
- 13
src/drivers/usb/usbnet.c View File

@@ -35,11 +35,11 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
35 35
  * USB network devices use a variety of packet formats and interface
36 36
  * descriptors, but tend to have several features in common:
37 37
  *
38
- *  - a single interrupt endpoint using the generic refill mechanism
38
+ *  - a single bulk OUT endpoint
39 39
  *
40 40
  *  - a single bulk IN endpoint using the generic refill mechanism
41 41
  *
42
- *  - a single bulk OUT endpoint
42
+ *  - an optional interrupt endpoint using the generic refill mechanism
43 43
  *
44 44
  *  - optional use of an alternate setting to enable the data interface
45 45
  *
@@ -55,15 +55,17 @@ int usbnet_open ( struct usbnet_device *usbnet ) {
55 55
 	struct usb_device *usb = usbnet->func->usb;
56 56
 	int rc;
57 57
 
58
-	/* Open interrupt endpoint */
59
-	if ( ( rc = usb_endpoint_open ( &usbnet->intr ) ) != 0 ) {
58
+	/* Open interrupt endpoint, if applicable */
59
+	if ( usbnet_has_intr ( usbnet ) &&
60
+	     ( rc = usb_endpoint_open ( &usbnet->intr ) ) != 0 ) {
60 61
 		DBGC ( usbnet, "USBNET %s could not open interrupt: %s\n",
61 62
 		       usbnet->func->name, strerror ( rc ) );
62 63
 		goto err_open_intr;
63 64
 	}
64 65
 
65
-	/* Refill interrupt endpoint */
66
-	if ( ( rc = usb_refill ( &usbnet->intr ) ) != 0 ) {
66
+	/* Refill interrupt endpoint, if applicable */
67
+	if ( usbnet_has_intr ( usbnet ) &&
68
+	     ( rc = usb_refill ( &usbnet->intr ) ) != 0 ) {
67 69
 		DBGC ( usbnet, "USBNET %s could not refill interrupt: %s\n",
68 70
 		       usbnet->func->name, strerror ( rc ) );
69 71
 		goto err_refill_intr;
@@ -111,7 +113,8 @@ int usbnet_open ( struct usbnet_device *usbnet ) {
111 113
 		usb_set_interface ( usb, usbnet->data, 0 );
112 114
  err_set_interface:
113 115
  err_refill_intr:
114
-	usb_endpoint_close ( &usbnet->intr );
116
+	if ( usbnet_has_intr ( usbnet ) )
117
+		usb_endpoint_close ( &usbnet->intr );
115 118
  err_open_intr:
116 119
 	return rc;
117 120
 }
@@ -134,8 +137,9 @@ void usbnet_close ( struct usbnet_device *usbnet ) {
134 137
 	if ( usbnet->alternate )
135 138
 		usb_set_interface ( usb, usbnet->data, 0 );
136 139
 
137
-	/* Close interrupt endpoint */
138
-	usb_endpoint_close ( &usbnet->intr );
140
+	/* Close interrupt endpoint, if applicable */
141
+	if ( usbnet_has_intr ( usbnet ) )
142
+		usb_endpoint_close ( &usbnet->intr );
139 143
 }
140 144
 
141 145
 /**
@@ -151,9 +155,11 @@ int usbnet_refill ( struct usbnet_device *usbnet ) {
151 155
 	if ( ( rc = usb_refill ( &usbnet->in ) ) != 0 )
152 156
 		return rc;
153 157
 
154
-	/* Refill interrupt endpoint */
155
-	if ( ( rc = usb_refill ( &usbnet->intr ) ) != 0 )
158
+	/* Refill interrupt endpoint, if applicable */
159
+	if ( usbnet_has_intr ( usbnet ) &&
160
+	     ( rc = usb_refill ( &usbnet->intr ) ) != 0 ) {
156 161
 		return rc;
162
+	}
157 163
 
158 164
 	return 0;
159 165
 }
@@ -272,9 +278,11 @@ int usbnet_describe ( struct usbnet_device *usbnet,
272 278
 		      struct usb_configuration_descriptor *config ) {
273 279
 	int rc;
274 280
 
275
-	/* Describe communications interface */
276
-	if ( ( rc = usbnet_comms_describe ( usbnet, config ) ) != 0 )
281
+	/* Describe communications interface, if applicable */
282
+	if ( usbnet_has_intr ( usbnet ) &&
283
+	     ( rc = usbnet_comms_describe ( usbnet, config ) ) != 0 ) {
277 284
 		return rc;
285
+	}
278 286
 
279 287
 	/* Describe data interface */
280 288
 	if ( ( rc = usbnet_data_describe ( usbnet, config ) ) != 0 )

+ 13
- 1
src/include/ipxe/usbnet.h View File

@@ -36,7 +36,7 @@ struct usbnet_device {
36 36
  *
37 37
  * @v usbnet		USB network device
38 38
  * @v func		USB function
39
- * @v intr		Interrupt endpoint operations
39
+ * @v intr		Interrupt endpoint operations, or NULL
40 40
  * @v in		Bulk IN endpoint operations
41 41
  * @v out		Bulk OUT endpoint operations
42 42
  */
@@ -53,6 +53,18 @@ usbnet_init ( struct usbnet_device *usbnet, struct usb_function *func,
53 53
 	usb_endpoint_init ( &usbnet->out, usb, out );
54 54
 }
55 55
 
56
+/**
57
+ * Check if USB network device has an interrupt endpoint
58
+ *
59
+ * @v usbnet		USB network device
60
+ * @ret has_intr	Device has an interrupt endpoint
61
+ */
62
+static inline __attribute__ (( always_inline )) int
63
+usbnet_has_intr ( struct usbnet_device *usbnet ) {
64
+
65
+	return ( usbnet->intr.driver != NULL );
66
+}
67
+
56 68
 extern int usbnet_open ( struct usbnet_device *usbnet );
57 69
 extern void usbnet_close ( struct usbnet_device *usbnet );
58 70
 extern int usbnet_refill ( struct usbnet_device *usbnet );

Loading…
Cancel
Save