Browse Source

[usb] Parse endpoint descriptor bInterval field

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
17aceb34da
4 changed files with 46 additions and 5 deletions
  1. 23
    4
      src/drivers/bus/usb.c
  2. 10
    0
      src/drivers/usb/xhci.c
  3. 5
    0
      src/drivers/usb/xhci.h
  4. 8
    1
      src/include/ipxe/usb.h

+ 23
- 4
src/drivers/bus/usb.c View File

@@ -227,10 +227,13 @@ int usb_endpoint_described ( struct usb_endpoint *ep,
227 227
 			     struct usb_configuration_descriptor *config,
228 228
 			     struct usb_interface_descriptor *interface,
229 229
 			     unsigned int type, unsigned int index ) {
230
+	struct usb_device *usb = ep->usb;
231
+	struct usb_port *port = usb->port;
230 232
 	struct usb_endpoint_descriptor *desc;
231 233
 	struct usb_endpoint_companion_descriptor *descx;
232 234
 	unsigned int sizes;
233 235
 	unsigned int burst;
236
+	unsigned int interval;
234 237
 	size_t mtu;
235 238
 
236 239
 	/* Locate endpoint descriptor */
@@ -246,9 +249,23 @@ int usb_endpoint_described ( struct usb_endpoint *ep,
246 249
 	mtu = USB_ENDPOINT_MTU ( sizes );
247 250
 	burst = ( descx ? descx->burst : USB_ENDPOINT_BURST ( sizes ) );
248 251
 
252
+	/* Calculate interval */
253
+	if ( type == USB_INTERRUPT ) {
254
+		if ( port->speed >= USB_SPEED_HIGH ) {
255
+			/* 2^(desc->interval-1) is a microframe count */
256
+			interval = ( 1 << ( desc->interval - 1 ) );
257
+		} else {
258
+			/* desc->interval is a (whole) frame count */
259
+			interval = ( desc->interval << 3 );
260
+		}
261
+	} else {
262
+		/* desc->interval is a microframe count */
263
+		interval = desc->interval;
264
+	}
265
+
249 266
 	/* Describe endpoint */
250 267
 	usb_endpoint_describe ( ep, desc->endpoint, desc->attributes,
251
-				mtu, burst );
268
+				mtu, burst, interval );
252 269
 	return 0;
253 270
 }
254 271
 
@@ -286,8 +303,9 @@ int usb_endpoint_open ( struct usb_endpoint *ep ) {
286 303
 	}
287 304
 	ep->open = 1;
288 305
 
289
-	DBGC2 ( usb, "USB %s %s opened with MTU %zd (burst %d)\n", usb->name,
290
-		usb_endpoint_name ( ep->address ), ep->mtu, ep->burst );
306
+	DBGC2 ( usb, "USB %s %s opened with MTU %zd, burst %d, interval %d\n",
307
+		usb->name, usb_endpoint_name ( ep->address ), ep->mtu,
308
+		ep->burst, ep->interval );
291 309
 	return 0;
292 310
 
293 311
 	ep->open = 0;
@@ -1147,7 +1165,8 @@ static int register_usb ( struct usb_device *usb ) {
1147 1165
 	/* Describe control endpoint */
1148 1166
 	mtu = USB_EP0_DEFAULT_MTU ( port->speed );
1149 1167
 	usb_endpoint_describe ( &usb->control, USB_EP0_ADDRESS,
1150
-				USB_EP0_ATTRIBUTES, mtu, USB_EP0_BURST );
1168
+				USB_EP0_ATTRIBUTES, mtu, USB_EP0_BURST,
1169
+				USB_EP0_INTERVAL );
1151 1170
 
1152 1171
 	/* Open control endpoint */
1153 1172
 	if ( ( rc = usb_endpoint_open ( &usb->control ) ) != 0 )

+ 10
- 0
src/drivers/usb/xhci.c View File

@@ -1986,6 +1986,7 @@ static void xhci_configure_endpoint_input ( struct xhci_device *xhci,
1986 1986
 
1987 1987
 	/* Populate endpoint context */
1988 1988
 	ep_ctx = ( input + xhci_input_context_offset ( xhci, endpoint->ctx ) );
1989
+	ep_ctx->interval = endpoint->interval;
1989 1990
 	ep_ctx->type = endpoint->type;
1990 1991
 	ep_ctx->burst = endpoint->ep->burst;
1991 1992
 	ep_ctx->mtu = cpu_to_le16 ( endpoint->ep->mtu );
@@ -2252,6 +2253,7 @@ static int xhci_endpoint_open ( struct usb_endpoint *ep ) {
2252 2253
 	struct xhci_endpoint *endpoint;
2253 2254
 	unsigned int ctx;
2254 2255
 	unsigned int type;
2256
+	unsigned int interval;
2255 2257
 	int rc;
2256 2258
 
2257 2259
 	/* Calculate context index */
@@ -2265,6 +2267,13 @@ static int xhci_endpoint_open ( struct usb_endpoint *ep ) {
2265 2267
 	if ( ep->address & USB_DIR_IN )
2266 2268
 		type |= XHCI_EP_TYPE_IN;
2267 2269
 
2270
+	/* Calculate interval */
2271
+	if ( type & XHCI_EP_TYPE_PERIODIC ) {
2272
+		interval = ( fls ( ep->interval ) - 1 );
2273
+	} else {
2274
+		interval = ep->interval;
2275
+	}
2276
+
2268 2277
 	/* Allocate and initialise structure */
2269 2278
 	endpoint = zalloc ( sizeof ( *endpoint ) );
2270 2279
 	if ( ! endpoint ) {
@@ -2278,6 +2287,7 @@ static int xhci_endpoint_open ( struct usb_endpoint *ep ) {
2278 2287
 	endpoint->ep = ep;
2279 2288
 	endpoint->ctx = ctx;
2280 2289
 	endpoint->type = type;
2290
+	endpoint->interval = interval;
2281 2291
 	endpoint->context = ( ( ( void * ) slot->context ) +
2282 2292
 			      xhci_device_context_offset ( xhci, ctx ) );
2283 2293
 

+ 5
- 0
src/drivers/usb/xhci.h View File

@@ -806,6 +806,9 @@ enum xhci_endpoint_state {
806 806
 /** Input endpoint type */
807 807
 #define XHCI_EP_TYPE_IN XHCI_EP_TYPE ( 4 )
808 808
 
809
+/** Periodic endpoint type */
810
+#define XHCI_EP_TYPE_PERIODIC XHCI_EP_TYPE ( 1 )
811
+
809 812
 /** Endpoint dequeue cycle state */
810 813
 #define XHCI_EP_DCS 0x00000001UL
811 814
 
@@ -1078,6 +1081,8 @@ struct xhci_endpoint {
1078 1081
 	unsigned int ctx;
1079 1082
 	/** Endpoint type */
1080 1083
 	unsigned int type;
1084
+	/** Endpoint interval */
1085
+	unsigned int interval;
1081 1086
 	/** Endpoint context */
1082 1087
 	struct xhci_endpoint_context *context;
1083 1088
 	/** Transfer ring */

+ 8
- 1
src/include/ipxe/usb.h View File

@@ -372,6 +372,8 @@ struct usb_endpoint {
372 372
 	size_t mtu;
373 373
 	/** Maximum burst size */
374 374
 	unsigned int burst;
375
+	/** Interval (in microframes) */
376
+	unsigned int interval;
375 377
 
376 378
 	/** Endpoint is open */
377 379
 	int open;
@@ -462,6 +464,9 @@ struct usb_endpoint_driver_operations {
462 464
 /** Control endpoint maximum burst size */
463 465
 #define USB_EP0_BURST 0
464 466
 
467
+/** Control endpoint interval */
468
+#define USB_EP0_INTERVAL 0
469
+
465 470
 /** Maximum endpoint number */
466 471
 #define USB_ENDPOINT_MAX 0x0f
467 472
 
@@ -496,16 +501,18 @@ usb_endpoint_init ( struct usb_endpoint *ep, struct usb_device *usb,
496 501
  * @v attributes	Attributes
497 502
  * @v mtu		Maximum packet size
498 503
  * @v burst		Maximum burst size
504
+ * @v interval		Interval (in microframes)
499 505
  */
500 506
 static inline __attribute__ (( always_inline )) void
501 507
 usb_endpoint_describe ( struct usb_endpoint *ep, unsigned int address,
502 508
 			unsigned int attributes, size_t mtu,
503
-			unsigned int burst ) {
509
+			unsigned int burst, unsigned int interval ) {
504 510
 
505 511
 	ep->address = address;
506 512
 	ep->attributes = attributes;
507 513
 	ep->mtu = mtu;
508 514
 	ep->burst = burst;
515
+	ep->interval = interval;
509 516
 }
510 517
 
511 518
 /**

Loading…
Cancel
Save