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
  * USB network devices use a variety of packet formats and interface
35
  * USB network devices use a variety of packet formats and interface
36
  * descriptors, but tend to have several features in common:
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
  *  - a single bulk IN endpoint using the generic refill mechanism
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
  *  - optional use of an alternate setting to enable the data interface
44
  *  - optional use of an alternate setting to enable the data interface
45
  *
45
  *
55
 	struct usb_device *usb = usbnet->func->usb;
55
 	struct usb_device *usb = usbnet->func->usb;
56
 	int rc;
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
 		DBGC ( usbnet, "USBNET %s could not open interrupt: %s\n",
61
 		DBGC ( usbnet, "USBNET %s could not open interrupt: %s\n",
61
 		       usbnet->func->name, strerror ( rc ) );
62
 		       usbnet->func->name, strerror ( rc ) );
62
 		goto err_open_intr;
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
 		DBGC ( usbnet, "USBNET %s could not refill interrupt: %s\n",
69
 		DBGC ( usbnet, "USBNET %s could not refill interrupt: %s\n",
68
 		       usbnet->func->name, strerror ( rc ) );
70
 		       usbnet->func->name, strerror ( rc ) );
69
 		goto err_refill_intr;
71
 		goto err_refill_intr;
111
 		usb_set_interface ( usb, usbnet->data, 0 );
113
 		usb_set_interface ( usb, usbnet->data, 0 );
112
  err_set_interface:
114
  err_set_interface:
113
  err_refill_intr:
115
  err_refill_intr:
114
-	usb_endpoint_close ( &usbnet->intr );
116
+	if ( usbnet_has_intr ( usbnet ) )
117
+		usb_endpoint_close ( &usbnet->intr );
115
  err_open_intr:
118
  err_open_intr:
116
 	return rc;
119
 	return rc;
117
 }
120
 }
134
 	if ( usbnet->alternate )
137
 	if ( usbnet->alternate )
135
 		usb_set_interface ( usb, usbnet->data, 0 );
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
 	if ( ( rc = usb_refill ( &usbnet->in ) ) != 0 )
155
 	if ( ( rc = usb_refill ( &usbnet->in ) ) != 0 )
152
 		return rc;
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
 		return rc;
161
 		return rc;
162
+	}
157
 
163
 
158
 	return 0;
164
 	return 0;
159
 }
165
 }
272
 		      struct usb_configuration_descriptor *config ) {
278
 		      struct usb_configuration_descriptor *config ) {
273
 	int rc;
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
 		return rc;
284
 		return rc;
285
+	}
278
 
286
 
279
 	/* Describe data interface */
287
 	/* Describe data interface */
280
 	if ( ( rc = usbnet_data_describe ( usbnet, config ) ) != 0 )
288
 	if ( ( rc = usbnet_data_describe ( usbnet, config ) ) != 0 )

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

36
  *
36
  *
37
  * @v usbnet		USB network device
37
  * @v usbnet		USB network device
38
  * @v func		USB function
38
  * @v func		USB function
39
- * @v intr		Interrupt endpoint operations
39
+ * @v intr		Interrupt endpoint operations, or NULL
40
  * @v in		Bulk IN endpoint operations
40
  * @v in		Bulk IN endpoint operations
41
  * @v out		Bulk OUT endpoint operations
41
  * @v out		Bulk OUT endpoint operations
42
  */
42
  */
53
 	usb_endpoint_init ( &usbnet->out, usb, out );
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
 extern int usbnet_open ( struct usbnet_device *usbnet );
68
 extern int usbnet_open ( struct usbnet_device *usbnet );
57
 extern void usbnet_close ( struct usbnet_device *usbnet );
69
 extern void usbnet_close ( struct usbnet_device *usbnet );
58
 extern int usbnet_refill ( struct usbnet_device *usbnet );
70
 extern int usbnet_refill ( struct usbnet_device *usbnet );

Loading…
Cancel
Save