PERFORCE change 131960 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sat Dec 29 04:36:37 PST 2007
http://perforce.freebsd.org/chv.cgi?CH=131960
Change 131960 by hselasky at hselasky_laptop001 on 2007/12/29 12:36:07
High Speed USB requires some more descriptors to
be fully USB specification compliant in USB Device
Side mode. This mostly is related to the other speed
descriptors.
Simplify the way we lookup the device descriptor
by introducing a new structure called "struct usb_temp_data".
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/usb_subr.h#89 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_template.c#11 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_template.h#7 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/usb_subr.h#89 (text+ko) ====
@@ -108,6 +108,7 @@
struct usbd_temp_setup;
struct usb_callout;
struct usb_temp_device_desc;
+struct usb_temp_data;
struct module;
struct malloc_type;
struct proc;
@@ -440,7 +441,7 @@
device_t global_dev;
struct usb_device *linux_dev;
struct usbd_xfer *default_xfer[1];
- void *usb_template_ptr;
+ struct usb_temp_data *usb_template_ptr;
uint16_t refcount;
#define USB_DEV_REFCOUNT_MAX 0xffff
==== //depot/projects/usb/src/sys/dev/usb/usb_template.c#11 (text+ko) ====
@@ -294,22 +294,14 @@
usbd_make_device_desc(struct usbd_temp_setup *temp,
const struct usb_temp_device_desc *tdd)
{
- usb_device_descriptor_t *dd;
- const void **pp;
+ struct usb_temp_data *utd;
const struct usb_temp_config_desc **tcd;
uint16_t old_size;
- /* Store a pointer to our template device descriptor */
- if (temp->buf) {
- pp = USBD_ADD_BYTES(temp->buf, temp->size);
- *pp = tdd;
- }
- temp->size += sizeof(void *);
-
/* Reserve memory */
old_size = temp->size;
- temp->size += sizeof(*dd);
+ temp->size += sizeof(*utd);
/* Scan all the USB configs */
@@ -328,36 +320,57 @@
*/
if (temp->buf) {
- dd = USBD_ADD_BYTES(temp->buf, old_size);
- dd->bLength = sizeof(*dd);
- dd->bDescriptorType = UDESC_DEVICE;
- dd->bDeviceClass = tdd->bDeviceClass;
- dd->bDeviceSubClass = tdd->bDeviceSubClass;
- dd->bDeviceProtocol = tdd->bDeviceProtocol;
- USETW(dd->idVendor, tdd->idVendor);
- USETW(dd->idProduct, tdd->idProduct);
- USETW(dd->bcdDevice, tdd->bcdDevice);
- dd->iManufacturer = tdd->iManufacturer;
- dd->iProduct = tdd->iProduct;
- dd->iSerialNumber = tdd->iSerialNumber;
- dd->bNumConfigurations = temp->bConfigurationValue - 1;
+ utd = USBD_ADD_BYTES(temp->buf, old_size);
+
+ /* Store a pointer to our template device descriptor */
+ utd->tdd = tdd;
+
+ /* Fill out USB device descriptor */
+ utd->udd.bLength = sizeof(utd->udd);
+ utd->udd.bDescriptorType = UDESC_DEVICE;
+ utd->udd.bDeviceClass = tdd->bDeviceClass;
+ utd->udd.bDeviceSubClass = tdd->bDeviceSubClass;
+ utd->udd.bDeviceProtocol = tdd->bDeviceProtocol;
+ USETW(utd->udd.idVendor, tdd->idVendor);
+ USETW(utd->udd.idProduct, tdd->idProduct);
+ USETW(utd->udd.bcdDevice, tdd->bcdDevice);
+ utd->udd.iManufacturer = tdd->iManufacturer;
+ utd->udd.iProduct = tdd->iProduct;
+ utd->udd.iSerialNumber = tdd->iSerialNumber;
+ utd->udd.bNumConfigurations = temp->bConfigurationValue - 1;
+
+ /*
+ * Fill out the USB device qualifier. Pretend that we
+ * don't support any other speeds by setting
+ * "bNumConfigurations" equal to zero. That saves us
+ * generating an extra set of configuration
+ * descriptors.
+ */
+ utd->udq.bLength = sizeof(utd->udq);
+ utd->udq.bDescriptorType = UDESC_DEVICE_QUALIFIER;
+ utd->udq.bDeviceClass = tdd->bDeviceClass;
+ utd->udq.bDeviceSubClass = tdd->bDeviceSubClass;
+ utd->udq.bDeviceProtocol = tdd->bDeviceProtocol;
+ utd->udq.bNumConfigurations = 0;
+ USETW(utd->udq.bcdUSB, 0x0200);
+ utd->udq.bMaxPacketSize0 = 0;
switch (temp->usb_speed) {
case USB_SPEED_LOW:
- USETW(dd->bcdUSB, 0x0101);
- dd->bMaxPacketSize = 8;
+ USETW(utd->udd.bcdUSB, 0x0101);
+ utd->udd.bMaxPacketSize = 8;
break;
case USB_SPEED_FULL:
- USETW(dd->bcdUSB, 0x0101);
- dd->bMaxPacketSize = 32;
+ USETW(utd->udd.bcdUSB, 0x0101);
+ utd->udd.bMaxPacketSize = 32;
break;
case USB_SPEED_HIGH:
- USETW(dd->bcdUSB, 0x0200);
- dd->bMaxPacketSize = 64;
+ USETW(utd->udd.bcdUSB, 0x0200);
+ utd->udd.bMaxPacketSize = 64;
break;
case USB_SPEED_VARIABLE:
- USETW(dd->bcdUSB, 0x0250);
- dd->bMaxPacketSize = 255; /* 512 bytes */
+ USETW(utd->udd.bcdUSB, 0x0250);
+ utd->udd.bMaxPacketSize = 255; /* 512 bytes */
break;
default:
temp->err = USBD_INVAL;
@@ -780,13 +793,10 @@
static const struct usb_temp_device_desc *
usbd_temp_get_tdd(struct usbd_device *udev)
{
- const void **pp;
-
- pp = udev->usb_template_ptr;
- if (pp == NULL) {
+ if (udev->usb_template_ptr == NULL) {
return (NULL);
}
- return (*pp);
+ return (udev->usb_template_ptr->tdd);
}
/*------------------------------------------------------------------------*
@@ -801,11 +811,10 @@
{
usb_device_descriptor_t *dd;
- dd = udev->usb_template_ptr;
- if (dd == NULL) {
+ if (udev->usb_template_ptr == NULL) {
return (NULL);
}
- dd = USBD_ADD_BYTES(dd, sizeof(void *));
+ dd = &(udev->usb_template_ptr->udd);
if (dd->bDescriptorType != UDESC_DEVICE) {
/* sanity check failed */
return (NULL);
@@ -814,6 +823,29 @@
}
/*------------------------------------------------------------------------*
+ * usbd_temp_get_qualifier_desc
+ *
+ * Returns:
+ * NULL: No USB device_qualifier descriptor found.
+ * Else: Pointer to USB device_qualifier descriptor.
+ *------------------------------------------------------------------------*/
+static void *
+usbd_temp_get_qualifier_desc(struct usbd_device *udev)
+{
+ usb_device_qualifier_t *dq;
+
+ if (udev->usb_template_ptr == NULL) {
+ return (NULL);
+ }
+ dq = &(udev->usb_template_ptr->udq);
+ if (dq->bDescriptorType != UDESC_DEVICE_QUALIFIER) {
+ /* sanity check failed */
+ return (NULL);
+ }
+ return (dq);
+}
+
+/*------------------------------------------------------------------------*
* usbd_temp_get_config_desc
*
* Returns:
@@ -828,16 +860,16 @@
usb_config_descriptor_t *cd;
uint16_t temp;
- dd = usbd_temp_get_device_desc(udev);
- if (dd == NULL) {
+ if (udev->usb_template_ptr == NULL) {
return (NULL);
}
+ dd = &(udev->usb_template_ptr->udd);
+ cd = (void *)(udev->usb_template_ptr + 1);
+
if (index >= dd->bNumConfigurations) {
/* out of range */
return (NULL);
}
- cd = USBD_ADD_BYTES(dd, dd->bLength);
-
while (index--) {
if (cd->bDescriptorType != UDESC_CONFIG) {
/* sanity check failed */
@@ -928,11 +960,24 @@
tr_handle_get_descriptor:
switch (req->wValue[1]) {
case UDESC_DEVICE:
- if (req->wValue[0] & 0xff) {
+ if (req->wValue[0]) {
goto tr_stalled;
}
buf = usbd_temp_get_device_desc(udev);
goto tr_valid;
+ case UDESC_DEVICE_QUALIFIER:
+ if (udev->speed != USB_SPEED_HIGH) {
+ goto tr_stalled;
+ }
+ if (req->wValue[0]) {
+ goto tr_stalled;
+ }
+ buf = usbd_temp_get_qualifier_desc(udev);
+ goto tr_valid;
+ case UDESC_OTHER_SPEED_CONFIGURATION:
+ if (udev->speed != USB_SPEED_HIGH) {
+ goto tr_stalled;
+ }
case UDESC_CONFIG:
buf = usbd_temp_get_config_desc(udev,
&len, req->wValue[0]);
@@ -947,7 +992,7 @@
goto tr_stalled;
tr_handle_get_class_descriptor:
- if (req->wValue[0] & 0xFF) {
+ if (req->wValue[0]) {
goto tr_stalled;
}
buf = usbd_temp_get_hub_desc(udev);
==== //depot/projects/usb/src/sys/dev/usb/usb_template.h#7 (text+ko) ====
@@ -80,6 +80,12 @@
uint8_t iSerialNumber;
};
+struct usb_temp_data {
+ const struct usb_temp_device_desc *tdd;
+ usb_device_descriptor_t udd; /* device descriptor */
+ usb_device_qualifier_t udq; /* device qualifier */
+};
+
/* prototypes */
extern const struct usb_temp_device_desc usb_template_cdce;
More information about the p4-projects
mailing list