Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 2 Aug 2010 17:44:28 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 181733 for review
Message-ID:  <201008021744.o72HiSVK025888@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@181733?ac=10

Change 181733 by hselasky@hselasky_laptop001 on 2010/08/02 17:44:09

	USB core:
		- add missing code regarding SuperSpeed endpoint
		companion descriptor handling.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb/usb_device.c#71 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_device.h#38 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_parse.c#10 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_transfer.c#179 edit
.. //depot/projects/usb/src/sys/dev/usb/usbdi.h#19 edit
.. //depot/projects/usb/src/sys/dev/usb/usbdi_util.h#6 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb/usb_device.c#71 (text+ko) ====

@@ -83,7 +83,9 @@
 /* function prototypes  */
 
 static void	usb_init_endpoint(struct usb_device *, uint8_t,
-		    struct usb_endpoint_descriptor *, struct usb_endpoint *);
+		    struct usb_endpoint_descriptor *,
+		    struct usb_endpoint_ss_comp_descriptor *,
+		    struct usb_endpoint *);
 static void	usb_unconfigure(struct usb_device *, uint8_t);
 static void	usb_detach_device_sub(struct usb_device *, device_t *,
 		    uint8_t);
@@ -346,7 +348,9 @@
  *------------------------------------------------------------------------*/
 static void
 usb_init_endpoint(struct usb_device *udev, uint8_t iface_index,
-    struct usb_endpoint_descriptor *edesc, struct usb_endpoint *ep)
+    struct usb_endpoint_descriptor *edesc,
+    struct usb_endpoint_ss_comp_descriptor *ecomp,
+    struct usb_endpoint *ep)
 {
 	struct usb_bus_methods *methods;
 
@@ -356,6 +360,7 @@
 
 	/* initialise USB endpoint structure */
 	ep->edesc = edesc;
+	ep->ecomp = ecomp;
 	ep->iface_index = iface_index;
 	TAILQ_INIT(&ep->endpoint_q.head);
 	ep->endpoint_q.command = &usbd_pipe_start;
@@ -749,8 +754,14 @@
 			ep = udev->endpoints + temp;
 
 			if (do_init) {
+				void *ecomp;
+
+				ecomp = usb_ed_comp_foreach(udev->cdesc, (void *)ed);
+				if (ecomp != NULL)
+					DPRINTFN(5, "Found endpoint companion descriptor\n");
+
 				usb_init_endpoint(udev, 
-				    ips.iface_index, ed, ep);
+				    ips.iface_index, ed, ecomp, ep);
 			}
 
 			temp ++;
@@ -1541,6 +1552,11 @@
 	udev->ctrl_ep_desc.wMaxPacketSize[0] = USB_MAX_IPACKET;
 	udev->ctrl_ep_desc.wMaxPacketSize[1] = 0;
 	udev->ctrl_ep_desc.bInterval = 0;
+
+	/* set up default endpoint companion descriptor */
+	udev->ctrl_ep_comp_desc.bLength = sizeof(udev->ctrl_ep_comp_desc);
+	udev->ctrl_ep_comp_desc.bDescriptorType = UDESC_ENDPOINT_SS_COMP;
+
 	udev->ddesc.bMaxPacketSize = USB_MAX_IPACKET;
 
 	udev->speed = speed;
@@ -1565,6 +1581,7 @@
 	/* init the default endpoint */
 	usb_init_endpoint(udev, 0,
 	    &udev->ctrl_ep_desc,
+	    &udev->ctrl_ep_comp_desc,
 	    &udev->ctrl_ep);
 
 	/* set device index */

==== //depot/projects/usb/src/sys/dev/usb/usb_device.h#38 (text+ko) ====

@@ -169,6 +169,7 @@
 	struct usb_device_flags flags;
 
 	struct usb_endpoint_descriptor ctrl_ep_desc;	/* for endpoint 0 */
+	struct usb_endpoint_ss_comp_descriptor ctrl_ep_comp_desc;	/* for endpoint 0 */
 	struct usb_device_descriptor ddesc;	/* device descriptor */
 
 	char	*serial;		/* serial number */

==== //depot/projects/usb/src/sys/dev/usb/usb_parse.c#10 (text+ko) ====

@@ -180,7 +180,7 @@
 		}
 		if (desc->bDescriptorType == UDESC_ENDPOINT) {
 			if (desc->bLength < sizeof(*ped)) {
-				/* endpoint index is invalid */
+				/* endpoint descriptor is invalid */
 				break;
 			}
 			return ((struct usb_endpoint_descriptor *)desc);
@@ -190,6 +190,42 @@
 }
 
 /*------------------------------------------------------------------------*
+ *	usb_ed_comp_foreach
+ *
+ * This function will iterate all the endpoint companion descriptors
+ * within an endpoint descriptor in an interface descriptor. Starting
+ * value for the "ped" argument should be a valid endpoint companion
+ * descriptor.
+ *
+ * Return values:
+ *   NULL: End of descriptors
+ *   Else: A valid endpoint companion descriptor
+ *------------------------------------------------------------------------*/
+struct usb_endpoint_ss_comp_descriptor *
+usb_ed_comp_foreach(struct usb_config_descriptor *cd,
+    struct usb_endpoint_ss_comp_descriptor *ped)
+{
+	struct usb_descriptor *desc;
+
+	desc = ((struct usb_descriptor *)ped);
+
+	while ((desc = usb_desc_foreach(cd, desc))) {
+		if (desc->bDescriptorType == UDESC_INTERFACE)
+			break;
+		if (desc->bDescriptorType == UDESC_ENDPOINT)
+			break;
+		if (desc->bDescriptorType == UDESC_ENDPOINT_SS_COMP) {
+			if (desc->bLength < sizeof(*ped)) {
+				/* endpoint companion descriptor is invalid */
+				break;
+			}
+			return ((struct usb_endpoint_ss_comp_descriptor *)desc);
+		}
+	}
+	return (NULL);
+}
+
+/*------------------------------------------------------------------------*
  *	usbd_get_no_descriptors
  *
  * This function will count the total number of descriptors in the

==== //depot/projects/usb/src/sys/dev/usb/usb_transfer.c#179 (text+ko) ====

@@ -137,14 +137,10 @@
 usbd_update_max_frame_size(struct usb_xfer *xfer)
 {
 	/* compute maximum frame size */
+	/* this computation should not overflow 16-bit */
+	/* max = 15 * 1024 */
 
-	if (xfer->max_packet_count == 2) {
-		xfer->max_frame_size = 2 * xfer->max_packet_size;
-	} else if (xfer->max_packet_count == 3) {
-		xfer->max_frame_size = 3 * xfer->max_packet_size;
-	} else {
-		xfer->max_frame_size = xfer->max_packet_size;
-	}
+	xfer->max_frame_size = xfer->max_packet_size * xfer->max_packet_count;
 }
 
 /*------------------------------------------------------------------------*
@@ -355,9 +351,23 @@
 
 	parm->bufsize = setup->bufsize;
 
-	if (parm->speed == USB_SPEED_HIGH) {
+	switch (parm->speed) {
+	case USB_SPEED_HIGH:
 		xfer->max_packet_count += (xfer->max_packet_size >> 11) & 3;
+		/* check for invalid max packet count */
+		if (xfer->max_packet_count > 3)
+			xfer->max_packet_count = 3;
 		xfer->max_packet_size &= 0x7FF;
+		break;
+	case USB_SPEED_SUPER:
+		if (xfer->endpoint->ecomp != NULL)
+			xfer->max_packet_count += xfer->endpoint->ecomp->bMaxBurst;
+		/* check for invalid max packet count */
+		if (xfer->max_packet_count > 15)
+			xfer->max_packet_count = 15;
+		break;
+	default:
+		break;
 	}
 	/* range check "max_packet_count" */
 

==== //depot/projects/usb/src/sys/dev/usb/usbdi.h#19 (text+ko) ====

@@ -135,6 +135,7 @@
 	struct usb_xfer_queue endpoint_q;	/* queue of USB transfers */
 
 	struct usb_endpoint_descriptor *edesc;
+	struct usb_endpoint_ss_comp_descriptor *ecomp;
 	struct usb_pipe_methods *methods;	/* set by HC driver */
 
 	uint16_t isoc_next;

==== //depot/projects/usb/src/sys/dev/usb/usbdi_util.h#6 (text+ko) ====

@@ -51,6 +51,9 @@
 struct usb_endpoint_descriptor *usb_edesc_foreach(
 	    struct usb_config_descriptor *cd,
 	    struct usb_endpoint_descriptor *ped);
+struct usb_endpoint_ss_comp_descriptor *usb_ed_comp_foreach(
+	    struct usb_config_descriptor *cd,
+	    struct usb_endpoint_ss_comp_descriptor *ped);
 uint8_t usbd_get_no_descriptors(struct usb_config_descriptor *cd,
 	    uint8_t type);
 uint8_t usbd_get_no_alts(struct usb_config_descriptor *cd,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201008021744.o72HiSVK025888>