From owner-p4-projects@FreeBSD.ORG Mon Dec 17 15:56:10 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id DBF3A16A473; Mon, 17 Dec 2007 15:56:09 +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 5EDDF16A418 for ; Mon, 17 Dec 2007 15:56:09 +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 5740013C459 for ; Mon, 17 Dec 2007 15:56:09 +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 lBHFu9vD077138 for ; Mon, 17 Dec 2007 15:56:09 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id lBHFu9MD077133 for perforce@freebsd.org; Mon, 17 Dec 2007 15:56:09 GMT (envelope-from hselasky@FreeBSD.org) Date: Mon, 17 Dec 2007 15:56:09 GMT Message-Id: <200712171556.lBHFu9MD077133@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 131103 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: Mon, 17 Dec 2007 15:56:10 -0000 http://perforce.freebsd.org/chv.cgi?CH=131103 Change 131103 by hselasky@hselasky_laptop001 on 2007/12/17 15:55:39 This change is device side related. Please see change 131102 for a detailed description. TODO: Add more comments. Affected files ... .. //depot/projects/usb/src/sys/dev/usb/usb_template.c#3 edit .. //depot/projects/usb/src/sys/dev/usb/usb_template.h#4 edit .. //depot/projects/usb/src/sys/dev/usb/usb_transfer.c#75 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb/usb_template.c#3 (text+ko) ==== @@ -70,8 +70,6 @@ { usb_endpoint_descriptor_t *ed; const void **rd; - uint8_t *pEp; - uint8_t *pEpEnd; uint16_t old_size; uint16_t mps; uint8_t ea = 0; /* Endpoint Address */ @@ -104,57 +102,7 @@ /* escape for Zero Max Packet Size */ mps = 0; } - if (ted->endpoint == 0) { - /* not initialized */ - temp->err = USBD_NO_PIPE; - return; - } else if (ted->endpoint == UE_ADDR_ANY) { - if (temp->buf) { - - /* search for a free endpoint */ - - pEp = temp->bEpToIface + - ((ted->direction & (UE_DIR_IN | - UE_DIR_OUT)) ? 1 : 0); - pEpEnd = pEp + USB_MAX_ENDPOINTS; - pEp += 2; /* skip control endpoint */ - while (1) { - - if (pEp == pEpEnd) { - temp->err = USBD_NO_PIPE; - return; - } - if (*pEp == 0) { - /* found one */ - *pEp = 1; /* dummy value */ - ea = (pEp - temp->bEpToIface) / 2; - break; - } - pEp += 2; - } - - } - } else { - ea = (ted->endpoint & UE_ADDR); - pEp = temp->bEpToIface + (ea << 1) + - ((ted->direction & (UE_DIR_IN | - UE_DIR_OUT)) ? 1 : 0); - - if (temp->buf) { - if (*pEp != temp->bInterfaceNumber) { - /* - * An endpoint is being used in multiple USB - * interfaces ! - */ - temp->err = USBD_INVAL; - return; - } - } else { - *pEp = temp->bInterfaceNumber; - } - } - - ea |= (ted->direction & (UE_DIR_IN | UE_DIR_OUT)); + ea = (ted->direction & (UE_DIR_IN | UE_DIR_OUT)); et = (ted->bmAttributes & UE_XFERTYPE); /* @@ -320,9 +268,17 @@ const struct usb_temp_device_desc *tdd) { usb_device_descriptor_t *dd; + const void **pp; 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; @@ -374,7 +330,7 @@ break; case USB_SPEED_VARIABLE: USETW(dd->bcdUSB, 0x0250); - dd->bMaxPacketSize = 255; + dd->bMaxPacketSize = 255; /* 512 bytes */ break; default: temp->err = USBD_INVAL; @@ -384,15 +340,441 @@ return; } -const void * +static uint8_t +usbd_hw_ep_match(const struct usbd_hw_ep_profile *pf, + uint8_t ep_type, uint8_t ep_dir_in) +{ + if (ep_type == UE_CONTROL) { + /* special */ + return (pf->support_control); + } + if ((pf->support_in && ep_dir_in) || + (pf->support_out && !ep_dir_in)) { + if ((pf->support_interrupt && (ep_type == UE_INTERRUPT)) || + (pf->support_isochronous && (ep_type == UE_ISOCHRONOUS)) || + (pf->support_bulk && (ep_type == UE_BULK))) { + return (1); + } + } + return (0); +} + +static uint8_t +usbd_hw_ep_find_match(struct usbd_hw_ep_scratch *ues, + struct usbd_sw_ep_scratch *ep, uint8_t is_simplex) +{ + const struct usbd_hw_ep_profile *pf; + uint16_t distance; + uint16_t temp; + uint8_t n; + uint8_t best_n; + uint8_t dir_in; + uint8_t dir_out; + + distance = 0xFFFF; + best_n = 0; + + if (ep->needs_ep_type == UE_CONTROL) { + dir_in = 1; + dir_out = 1; + } else { + if (ep->needs_in) { + ep->needs_in = 0; + dir_in = 1; + dir_out = 0; + } else { + ep->needs_out = 0; + dir_in = 0; + dir_out = 1; + } + } + + for (n = 1; n != (USB_MAX_ENDPOINTS / 2); n++) { + + /* check if IN-endpoint is reserved */ + if (dir_in) { + if (ues->bmInAlloc[n / 8] & (1 << (n % 8))) { + /* mismatch */ + continue; + } + } + /* check if OUT-endpoint is reserved */ + if (dir_out) { + if (ues->bmOutAlloc[n / 8] & (1 << (n % 8))) { + /* mismatch */ + continue; + } + } + /* get HW endpoint profile */ + pf = (ues->get_hw_ep_profile) (ues->udev, n); + if (pf == NULL) { + /* end of profiles */ + break; + } + /* check simplex */ + if (pf->is_simplex == is_simplex) { + /* mismatch */ + continue; + } + /* check if HW endpoint matches */ + if (!usbd_hw_ep_match(pf, ep->needs_ep_type, dir_in)) { + /* mismatch */ + continue; + } + if (pf->max_frame_size >= ep->max_frame_size) { + temp = (pf->max_frame_size - ep->max_frame_size); + if (distance > temp) { + distance = temp; + best_n = n; + ep->pf = pf; + } + } else if ((ep->needs_ep_type == UE_BULK) || + (ep->needs_ep_type == UE_CONTROL)) { + /* frame size is not so important */ + temp = (ep->max_frame_size - pf->max_frame_size); + if (distance > temp) { + distance = temp; + best_n = n; + ep->pf = pf; + } + } + } + + /* see if we got a match */ + if (best_n != 0) { + /* get the correct profile */ + pf = ep->pf; + + /* reserve IN-endpoint */ + if (dir_in || pf->is_simplex) { + ues->bmInAlloc[best_n / 8] |= + (1 << (best_n % 8)); + ep->hw_endpoint_in = best_n | UE_DIR_IN; + } + /* reserve OUT-endpoint */ + if (dir_out || pf->is_simplex) { + ues->bmOutAlloc[best_n / 8] |= + (1 << (best_n % 8)); + ep->hw_endpoint_out = best_n | UE_DIR_OUT; + } + /* + * In case we choose an endpoint having a smaller Maximum + * Frame Size than we wanted, we need to update the Maximum + * Frame Size ! + */ + if (ep->max_frame_size > pf->max_frame_size) { + ep->max_frame_size = pf->max_frame_size; + } + return (0); /* got a match */ + } + return (1); /* failure */ +} + +static uint8_t +usbd_hw_ep_get_needs(struct usbd_hw_ep_scratch *ues, + uint8_t ep_type, uint8_t is_complete) +{ + struct usbd_sw_ep_scratch *ep_iface; + struct usbd_sw_ep_scratch *ep_curr; + struct usbd_sw_ep_scratch *ep_max; + struct usbd_sw_ep_scratch *ep_end; + usb_descriptor_t *desc; + usb_interface_descriptor_t *id; + usb_endpoint_descriptor_t *ed; + uint16_t wMaxPacketSize; + uint16_t temp; + uint8_t allow_override; + uint8_t speed; + + ep_iface = ues->ep_max; + ep_curr = ues->ep_max; + ep_end = ues->ep + USB_MAX_ENDPOINTS; + ep_max = ues->ep_max; + desc = NULL; + speed = ues->udev->speed; + +repeat: + + while ((desc = usbd_desc_foreach(ues->cd, desc))) { + + if ((desc->bDescriptorType == UDESC_INTERFACE) && + (desc->bLength >= sizeof(*id))) { + + id = (void *)desc; + + if (id->bAlternateSetting == 0) { + /* going forward */ + ep_iface = ep_max; + } else { + /* reset */ + ep_curr = ep_iface; + } + } + if ((desc->bDescriptorType == UDESC_ENDPOINT) && + (desc->bLength >= sizeof(*ed))) { + + ed = (void *)desc; + + goto handle_endpoint_desc; + } + } + ues->ep_max = ep_max; + return (0); + +handle_endpoint_desc: + temp = (ed->bmAttributes & UE_XFERTYPE); + + if (temp == ep_type) { + + if (ep_curr == ep_end) { + /* too many endpoints */ + return (1); /* failure */ + } + wMaxPacketSize = UGETW(ed->wMaxPacketSize); + if ((wMaxPacketSize & 0xF800) && + (speed == USB_SPEED_HIGH)) { + /* handle frame multiplier */ + temp = (wMaxPacketSize >> 11) & 3; + wMaxPacketSize &= 0x7FF; + if (temp == 2) { + wMaxPacketSize *= 2; + } else { + wMaxPacketSize *= 3; + } + allow_override = 0; + } else { + if ((ep_type == UE_BULK) || + (ep_type == UE_CONTROL)) { + allow_override = 1; + } else { + allow_override = 0; + } + } + + if (is_complete) { + + /* + * We assume that + * "ep_curr->max_frame_size" + * is correct according to the + * speed we are connected at ! + */ + while (1) { + + if (wMaxPacketSize <= + ep_curr->max_frame_size) { + break; + } + if (wMaxPacketSize < 8) { + return (1); /* failure */ + } + if (!allow_override) { + return (1); /* failure */ + } + /* + * We have a BULK or CONTROL + * endpoint having a packet + * size that the hardware + * cannot handle ! Try to + * work it around! + */ + wMaxPacketSize /= 2; + USETW(ed->wMaxPacketSize, + wMaxPacketSize); + } + + if (ed->bEndpointAddress & UE_DIR_IN) { + ed->bEndpointAddress = + ep_curr->hw_endpoint_in; + } else { + ed->bEndpointAddress = + ep_curr->hw_endpoint_out; + } + + } else { + + /* compute the maximum frame size */ + if (ep_curr->max_frame_size < wMaxPacketSize) { + ep_curr->max_frame_size = wMaxPacketSize; + } + if (temp == UE_CONTROL) { + ep_curr->needs_in = 1; + ep_curr->needs_out = 1; + } else { + if (ed->bEndpointAddress & UE_DIR_IN) { + ep_curr->needs_in = 1; + } else { + ep_curr->needs_out = 1; + } + } + ep_curr->needs_ep_type = ep_type; + } + + ep_curr++; + if (ep_max < ep_curr) { + ep_max = ep_curr; + } + } + goto repeat; +} + +static usbd_status_t +usbd_hw_ep_resolve(struct usbd_device *udev, + usb_descriptor_t *desc) +{ + struct usbd_hw_ep_scratch *ues; + struct usbd_sw_ep_scratch *ep; + struct usbd_hw_ep_profile *pf; + struct usbd_bus *bus; + usb_device_descriptor_t *dd; + uint16_t mps; + + if (desc == NULL) { + return (USBD_INVAL); + } + /* get bus structure */ + bus = udev->bus; + + if (bus->methods->get_hw_ep_profile == NULL) { + return (USBD_INVAL); + } + if (desc->bDescriptorType == UDESC_DEVICE) { + + if (desc->bLength < sizeof(*dd)) { + return (USBD_INVAL); + } + dd = (void *)desc; + + /* get HW control endpoint 0 profile */ + pf = (bus->methods->get_hw_ep_profile) (ues->udev, 0); + if (pf == NULL) { + return (USBD_INVAL); + } + if (!usbd_hw_ep_match(pf, UE_CONTROL, 0)) { + PRINTFN(-1, ("Endpoint 0 does not " + "support control\n")); + return (USBD_INVAL); + } + mps = dd->bMaxPacketSize; + + if (udev->speed == USB_SPEED_FULL) { + /* + * We can optionally choose another packet size ! + */ + while (1) { + /* check if "mps" is ok */ + if (pf->max_frame_size >= mps) { + break; + } + /* reduce maximum packet size */ + mps /= 2; + + /* check if "mps" is too small */ + if (mps < 8) { + return (USBD_INVAL); + } + } + + dd->bMaxPacketSize = mps; + + } else { + /* We only have one choice */ + if (mps == 255) { + mps = 512; + } + /* Check if we support the specified wMaxPacketSize */ + if (pf->max_frame_size < mps) { + return (USBD_INVAL); + } + } + } + if (desc->bDescriptorType != UDESC_CONFIG) { + return (USBD_INVAL); + } + if (desc->bLength < sizeof(*(ues->cd))) { + return (USBD_INVAL); + } + ues = udev->scratch[0].hw_ep_scratch; + + bzero(ues, sizeof(*ues)); + + ues->ep_max = ues->ep; + ues->cd = (void *)desc; + ues->get_hw_ep_profile = bus->methods->get_hw_ep_profile; + ues->udev = udev; + + /* Get all the endpoints we need */ + + if (usbd_hw_ep_get_needs(ues, UE_ISOCHRONOUS, 0) || + usbd_hw_ep_get_needs(ues, UE_INTERRUPT, 0) || + usbd_hw_ep_get_needs(ues, UE_CONTROL, 0) || + usbd_hw_ep_get_needs(ues, UE_BULK, 0)) { + return (USBD_INVAL); + } + for (ep = ues->ep; ep != ues->ep_max; ep++) { + + while (ep->needs_in || ep->needs_out) { + + /* + * First try to use a simplex endpoint. + * Then try to use a duplex endpoint. + */ + if (usbd_hw_ep_find_match(ues, ep, 1) && + usbd_hw_ep_find_match(ues, ep, 0)) { + return (USBD_INVAL); + } + } + } + + ues->ep_max = ues->ep; + + /* Update all endpoint addresses */ + + if (usbd_hw_ep_get_needs(ues, UE_ISOCHRONOUS, 1) || + usbd_hw_ep_get_needs(ues, UE_INTERRUPT, 1) || + usbd_hw_ep_get_needs(ues, UE_CONTROL, 1) || + usbd_hw_ep_get_needs(ues, UE_BULK, 1)) { + return (USBD_INVAL); + } + return (0); /* success */ +} + +/*------------------------------------------------------------------------* + * usbd_temp_get_tdd + * + * Returns: + * NULL: No USB template device descriptor found. + * Else: Pointer to the USB template device descriptor. + *------------------------------------------------------------------------*/ +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) { + return (NULL); + } + return (*pp); +} + +/*------------------------------------------------------------------------* + * usbd_temp_get_device_desc + * + * Returns: + * NULL: No USB device descriptor found. + * Else: Pointer to USB device descriptor. + *------------------------------------------------------------------------*/ +static void * usbd_temp_get_device_desc(struct usbd_device *udev) { - const usb_device_descriptor_t *dd; + usb_device_descriptor_t *dd; dd = udev->usb_template_ptr; if (dd == NULL) { return (NULL); } + dd = USBD_ADD_BYTES(dd, sizeof(void *)); if (dd->bDescriptorType != UDESC_DEVICE) { /* sanity check failed */ return (NULL); @@ -400,11 +782,19 @@ return (dd); } -const void * -usbd_temp_get_config_desc(struct usbd_device *udev, uint8_t index) +/*------------------------------------------------------------------------* + * usbd_temp_get_config_desc + * + * Returns: + * NULL: No USB config descriptor found. + * Else: Pointer to USB config descriptor having index "index". + *------------------------------------------------------------------------*/ +static void * +usbd_temp_get_config_desc(struct usbd_device *udev, + uint16_t *pLength, uint8_t index) { - const usb_device_descriptor_t *dd; - const usb_config_descriptor_t *cd; + usb_device_descriptor_t *dd; + usb_config_descriptor_t *cd; uint16_t temp; dd = usbd_temp_get_device_desc(udev); @@ -425,14 +815,136 @@ temp = UGETW(cd->wTotalLength); cd = USBD_ADD_BYTES(cd, temp); } + + if (pLength) { + *pLength = UGETW(cd->wTotalLength); + } return (cd); } /*------------------------------------------------------------------------* + * usbd_temp_get_string_desc + * + * Returns: + * NULL: No string descriptor found. + * Else: Pointer to a string descriptor. + *------------------------------------------------------------------------*/ +static const void * +usbd_temp_get_string_desc(struct usbd_device *udev, + uint16_t lang_id, uint8_t string_index) +{ + const struct usb_temp_device_desc *tdd; + + tdd = usbd_temp_get_tdd(udev); + if (tdd == NULL) { + return (NULL); + } + if (tdd->getStringDesc == NULL) { + return (NULL); + } + return ((tdd->getStringDesc) (lang_id, string_index)); +} + +/*------------------------------------------------------------------------* + * usbd_temp_get_hub_desc + * + * Returns: + * NULL: No USB HUB descriptor found. + * Else: Pointer to a USB HUB descriptor. + *------------------------------------------------------------------------*/ +static const void * +usbd_temp_get_hub_desc(struct usbd_device *udev) +{ + return (NULL); /* needs to be implemented */ +} + +/*------------------------------------------------------------------------* + * usbd_temp_get_desc + * + * This function is a demultiplexer for USB device requests. + *------------------------------------------------------------------------*/ +void +usbd_temp_get_desc(struct usbd_device *udev, usb_device_request_t *req, + const void **pPtr, uint16_t *pLength) +{ + const uint8_t *buf; + uint16_t len; + + buf = NULL; + len = 0; + + switch (req->bmRequestType) { + case UT_READ_DEVICE: + switch (req->bRequest) { + case UR_GET_DESCRIPTOR: + goto tr_handle_get_descriptor; + default: + goto tr_stalled; + } + break; + case UT_READ_CLASS_DEVICE: + switch (req->bRequest) { + case UR_GET_DESCRIPTOR: + goto tr_handle_get_class_descriptor; + default: + goto tr_stalled; + } + break; + default: + goto tr_stalled; + } + +tr_handle_get_descriptor: + switch (req->wValue[1]) { + case UDESC_DEVICE: + if (req->wValue[0] & 0xff) { + goto tr_stalled; + } + buf = usbd_temp_get_device_desc(udev); + goto tr_valid; + case UDESC_CONFIG: + buf = usbd_temp_get_config_desc(udev, + &len, req->wValue[0]); + goto tr_valid; + case UDESC_STRING: + buf = usbd_temp_get_string_desc(udev, + UGETW(req->wIndex), req->wValue[0]); + goto tr_valid; + default: + goto tr_stalled; + } + goto tr_stalled; + +tr_handle_get_class_descriptor: + if (req->wValue[0] & 0xFF) { + goto tr_stalled; + } + buf = usbd_temp_get_hub_desc(udev); + goto tr_valid; + +tr_valid: + if (buf == NULL) { + goto tr_stalled; + } + if (len == 0) { + len = buf[0]; + } + *pPtr = buf; + *pLength = len; + return; + +tr_stalled: + *pPtr = NULL; + *pLength = 0; + return; +} + +/*------------------------------------------------------------------------* * usbd_temp_setup * - * This function generates USB descriptors according to - * the given USB template device descriptor. + * This function generates USB descriptors according to the given USB + * template device descriptor. It will also try to figure out the best + * matching endpoint addresses using the hardware endpoint profiles. * * Returns: * 0: Success @@ -443,15 +955,13 @@ const struct usb_temp_device_desc *tdd) { struct usbd_temp_setup *uts; + void *buf; + uint8_t n; if (tdd == NULL) { /* be NULL safe */ return (0); } - if (tdd->pGetDescFn == NULL) { - /* not initialized properly */ - return (USBD_INVAL); - } uts = udev->scratch[0].temp_setup; bzero(uts, sizeof(*uts)); @@ -480,14 +990,42 @@ usbd_make_device_desc(uts, tdd); + /* + * Store a pointer to our descriptors: + */ + udev->usb_template_ptr = uts->buf; + if (uts->err) { /* some error happened during second pass */ - free(uts->buf, M_USB); - return (uts->err); + goto error; + } + /* + * Resolve all endpoint addresses ! + */ + buf = usbd_temp_get_device_desc(udev); + uts->err = usbd_hw_ep_resolve(udev, buf); + if (uts->err) { + PRINTFN(-1, ("Could not resolve endpoints for " + "Device Descriptor\n")); + goto error; + } + for (n = 0;; n++) { + + buf = usbd_temp_get_config_desc(udev, NULL, n); + uts->err = usbd_hw_ep_resolve(udev, buf); + if (uts->err) { + if (buf == NULL) { + break; + } + PRINTFN(-1, ("Could not resolve endpoints for " + "Config Descriptor %u\n", n)); + goto error; + } } - udev->usb_template_ptr = uts->buf; - udev->usb_temp_get_desc = tdd->pGetDescFn; + return (uts->err); +error: + usbd_temp_unsetup(udev); return (uts->err); } @@ -505,7 +1043,6 @@ free(udev->usb_template_ptr, M_USB); udev->usb_template_ptr = NULL; - udev->usb_temp_get_desc = NULL; } return; } ==== //depot/projects/usb/src/sys/dev/usb/usb_template.h#4 (text+ko) ==== @@ -31,6 +31,8 @@ #ifndef _USB_TEMPLATE_H_ #define _USB_TEMPLATE_H_ +typedef const void *(usbd_temp_get_string_desc_t)(uint16_t lang_id, uint8_t string_index); + struct usb_temp_packet_size { uint16_t mps[USB_SPEED_MAX]; }; @@ -39,7 +41,6 @@ const void **ppRawDesc; const struct usb_temp_packet_size *pPacketSize; uint8_t direction; /* UE_DIR_IN or UE_DIR_OUT */ - uint8_t endpoint; /* endpoint address */ uint8_t bmAttributes; }; @@ -61,7 +62,7 @@ }; struct usb_temp_device_desc { - usbd_temp_get_desc_t *pGetDescFn; + usbd_temp_get_string_desc_t *getStringDesc; const struct usb_temp_config_desc **ppConfigDesc; uint16_t idVendor; uint16_t idProduct; ==== //depot/projects/usb/src/sys/dev/usb/usb_transfer.c#75 (text+ko) ==== @@ -3079,8 +3079,7 @@ goto tr_valid; tr_handle_get_descriptor: - (udev->usb_temp_get_desc) ( - udev, xfer->priv_mtx, &req, &ptr, &max_len); + usbd_temp_get_desc(udev, &req, &ptr, &max_len); if (ptr == NULL) { goto tr_stalled; } @@ -3362,17 +3361,7 @@ } if (udev->flags.usb_mode == USB_MODE_DEVICE) { PRINTFN(0, ("USB device mode\n")); - if ((req->bmRequestType == UT_READ_DEVICE) && - (req->bRequest == UR_GET_DESCRIPTOR)) { - (udev->usb_temp_get_desc) ( - udev, mtx, req, &desc, &temp); - if (desc == NULL) { - return (USBD_INVAL); - } - } else { - /* the rest we don't care about */ - temp = 0; - } + usbd_temp_get_desc(udev, req, &desc, &temp); if (length > temp) { if (!(flags & USBD_SHORT_XFER_OK)) { return (USBD_SHORT_XFER);