From owner-p4-projects@FreeBSD.ORG Sat Dec 29 12:36:37 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 9DE2A16A41B; Sat, 29 Dec 2007 12:36:37 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4AF5F16A419 for ; Sat, 29 Dec 2007 12:36:37 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 3EF6913C442 for ; Sat, 29 Dec 2007 12:36:37 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id lBTCabpO095313 for ; Sat, 29 Dec 2007 12:36:37 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id lBTCaaPq095310 for perforce@freebsd.org; Sat, 29 Dec 2007 12:36:36 GMT (envelope-from hselasky@FreeBSD.org) Date: Sat, 29 Dec 2007 12:36:36 GMT Message-Id: <200712291236.lBTCaaPq095310@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 131960 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 29 Dec 2007 12:36:37 -0000 http://perforce.freebsd.org/chv.cgi?CH=131960 Change 131960 by hselasky@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;