From owner-p4-projects@FreeBSD.ORG Wed Aug 11 18:25:49 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 4F3491065672; Wed, 11 Aug 2010 18:25:49 +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 03D8C106564A for ; Wed, 11 Aug 2010 18:25:49 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id E48078FC13 for ; Wed, 11 Aug 2010 18:25:48 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.4/8.14.4) with ESMTP id o7BIPmHB083700 for ; Wed, 11 Aug 2010 18:25:48 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.4/8.14.4/Submit) id o7BIPmqN083697 for perforce@freebsd.org; Wed, 11 Aug 2010 18:25:48 GMT (envelope-from hselasky@FreeBSD.org) Date: Wed, 11 Aug 2010 18:25:48 GMT Message-Id: <201008111825.o7BIPmqN083697@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 182097 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 11 Aug 2010 18:25:49 -0000 X-List-Received-Date: Wed, 11 Aug 2010 18:25:49 -0000 http://p4web.freebsd.org/@@182097?ac=10 Change 182097 by hselasky@hselasky_laptop001 on 2010/08/08 18:42:59 USB core + USB controller (XHCI): - patches related to USB re-enumeration using XHCI chip. - be smarter when reading the USB device descriptor by exploiting information about the device speed. Affected files ... .. //depot/projects/usb/src/sys/dev/usb/controller/xhci.c#19 edit .. //depot/projects/usb/src/sys/dev/usb/usb_device.c#77 edit .. //depot/projects/usb/src/sys/dev/usb/usb_request.c#42 edit .. //depot/projects/usb/src/sys/dev/usb/usb_request.h#14 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb/controller/xhci.c#19 (text+ko) ==== @@ -125,6 +125,7 @@ static usb_error_t xhci_configure_endpoint(struct usb_device *, struct usb_endpoint_descriptor *, uint64_t, uint16_t, uint8_t, uint16_t, uint16_t); static usb_error_t xhci_configure_mask(struct usb_device *, uint32_t, uint8_t); static usb_error_t xhci_cmd_evaluate_ctx(struct xhci_softc *, uint64_t, uint8_t); +static usb_error_t xhci_cmd_reset_dev(struct xhci_softc *, uint8_t); extern struct usb_bus_methods xhci_bus_methods; @@ -624,7 +625,6 @@ if (xfer->flags_int.control_xfr && !xfer->flags_int.control_act) err = xhci_generic_done_sub(xfer); - done: /* transfer is complete */ xhci_device_done(xfer, err); @@ -1072,14 +1072,21 @@ switch (hdev->state) { case XHCI_ST_ADDRESSED: case XHCI_ST_CONFIGURED: - err = 0; - break; + if (udev->address == 0) { + err = xhci_cmd_reset_dev(sc, index); - case XHCI_ST_DEFAULT: - if (address == 0) { + if (err != 0) { + DPRINTF("Device reset failed\n"); + } + } else { err = 0; break; } + + case XHCI_ST_DEFAULT: + + hdev->state = XHCI_ST_ENABLED; + /* FALLTHROUGH */ case XHCI_ST_ENABLED: @@ -1129,7 +1136,8 @@ if (err != 0) { DPRINTF("Could not set address\n"); - break; + if (address != 0) + break; } /* update device address to new value */ @@ -1155,7 +1163,6 @@ } err = xhci_cmd_evaluate_ctx(sc, buf_inp.physaddr, index); - if (err != 0) { DPRINTF("Could not evaluate device context\n"); break; @@ -1286,7 +1293,6 @@ return (xhci_do_command(sc, &trb, 50 /* ms */)); } -#if 0 static usb_error_t xhci_cmd_reset_dev(struct xhci_softc *sc, uint8_t slot_id) { @@ -1304,7 +1310,6 @@ return (xhci_do_command(sc, &trb, 50 /* ms */)); } -#endif /*------------------------------------------------------------------------* * xhci_interrupt - XHCI interrupt handler @@ -3166,6 +3171,10 @@ xfer->flags_int.curr_dma_set = 1; goto alloc_dma_set; } + + /* make sure we catch any set address updates */ + if (parm->buf != NULL) + xhci_set_address(xfer->xroot->udev, NULL, 0); } static usb_error_t ==== //depot/projects/usb/src/sys/dev/usb/usb_device.c#77 (text+ko) ==== @@ -1681,45 +1681,16 @@ } usb_set_device_state(udev, USB_STATE_ADDRESSED); - /* - * Get the first 8 bytes of the device descriptor ! - * - * NOTE: "usbd_do_request" will check the device descriptor - * next time we do a request to see if the maximum packet size - * changed! The 8 first bytes of the device descriptor - * contains the maximum packet size to use on control endpoint - * 0. If this value is different from "USB_MAX_IPACKET" a new - * USB control request will be setup! - */ - err = usbd_req_get_desc(udev, NULL, NULL, &udev->ddesc, - USB_MAX_IPACKET, USB_MAX_IPACKET, 0, UDESC_DEVICE, 0, 0); - if (err) { - DPRINTFN(0, "getting device descriptor " - "at addr %d failed, %s\n", udev->address, - usbd_errstr(err)); + /* setup the device descriptor and the initial "wMaxPacketSize" */ + err = usbd_setup_device_desc(udev, NULL); + + if (err != 0) { /* XXX try to re-enumerate the device */ err = usbd_req_re_enumerate(udev, NULL); - if (err) { + if (err) goto done; - } } - DPRINTF("adding unit addr=%d, rev=%02x, class=%d, " - "subclass=%d, protocol=%d, maxpacket=%d, len=%d, speed=%d\n", - udev->address, UGETW(udev->ddesc.bcdUSB), - udev->ddesc.bDeviceClass, - udev->ddesc.bDeviceSubClass, - udev->ddesc.bDeviceProtocol, - udev->ddesc.bMaxPacketSize, - udev->ddesc.bLength, - udev->speed); - /* get the full device descriptor */ - err = usbd_req_get_device_desc(udev, NULL, &udev->ddesc); - if (err) { - DPRINTF("addr=%d, getting full desc failed\n", - udev->address); - goto done; - } /* * Setup temporary USB attach args so that we can figure out some * basic quirks for this device. ==== //depot/projects/usb/src/sys/dev/usb/usb_request.c#42 (text+ko) ==== @@ -1763,6 +1763,68 @@ } /*------------------------------------------------------------------------* + * usbd_setup_device_desc + *------------------------------------------------------------------------*/ +usb_error_t +usbd_setup_device_desc(struct usb_device *udev, struct mtx *mtx) +{ + usb_error_t err; + + /* + * Get the first 8 bytes of the device descriptor ! + * + * NOTE: "usbd_do_request()" will check the device descriptor + * next time we do a request to see if the maximum packet size + * changed! The 8 first bytes of the device descriptor + * contains the maximum packet size to use on control endpoint + * 0. If this value is different from "USB_MAX_IPACKET" a new + * USB control request will be setup! + */ + switch (udev->speed) { + case USB_SPEED_FULL: + case USB_SPEED_LOW: + err = usbd_req_get_desc(udev, mtx, NULL, &udev->ddesc, + USB_MAX_IPACKET, USB_MAX_IPACKET, 0, UDESC_DEVICE, 0, 0); + if (err != 0) { + DPRINTFN(0, "getting device descriptor " + "at addr %d failed, %s\n", udev->address, + usbd_errstr(err)); + return (err); + } + break; + default: + DPRINTF("Minimum MaxPacketSize is large enough " + "to hold the complete device descriptor\n"); + break; + } + + /* get the full device descriptor */ + err = usbd_req_get_device_desc(udev, mtx, &udev->ddesc); + + /* try one more time, if error */ + if (err) + err = usbd_req_get_device_desc(udev, mtx, &udev->ddesc); + + if (err) { + DPRINTF("addr=%d, getting full desc failed\n", + udev->address); + return (err); + } + + DPRINTF("adding unit addr=%d, rev=%02x, class=%d, " + "subclass=%d, protocol=%d, maxpacket=%d, len=%d, speed=%d\n", + udev->address, UGETW(udev->ddesc.bcdUSB), + udev->ddesc.bDeviceClass, + udev->ddesc.bDeviceSubClass, + udev->ddesc.bDeviceProtocol, + udev->ddesc.bMaxPacketSize, + udev->ddesc.bLength, + udev->speed); + + return (err); +} + +/*------------------------------------------------------------------------* * usbd_req_re_enumerate * * NOTE: After this function returns the hardware is in the @@ -1821,23 +1883,9 @@ if (udev->address == USB_START_ADDR) udev->address = old_addr; - /* get the device descriptor */ - err = usbd_req_get_desc(udev, mtx, NULL, &udev->ddesc, - USB_MAX_IPACKET, USB_MAX_IPACKET, 0, UDESC_DEVICE, 0, 0); - if (err) { - DPRINTFN(0, "getting device descriptor " - "at addr %d failed, %s\n", udev->address, - usbd_errstr(err)); - goto done; - } - /* get the full device descriptor */ - err = usbd_req_get_device_desc(udev, mtx, &udev->ddesc); - if (err) { - DPRINTFN(0, "addr=%d, getting device " - "descriptor failed, %s\n", old_addr, - usbd_errstr(err)); - goto done; - } + /* setup the device descriptor and the initial "wMaxPacketSize" */ + err = usbd_setup_device_desc(udev, mtx); + done: if (err && do_retry) { /* give the USB firmware some time to load */ ==== //depot/projects/usb/src/sys/dev/usb/usb_request.h#14 (text+ko) ==== @@ -71,6 +71,7 @@ uint16_t sel); usb_error_t usbd_req_set_port_feature(struct usb_device *udev, struct mtx *mtx, uint8_t port, uint16_t sel); +usb_error_t usbd_setup_device_desc(struct usb_device *udev, struct mtx *mtx); usb_error_t usbd_req_re_enumerate(struct usb_device *udev, struct mtx *mtx); usb_error_t usbd_req_clear_device_feature(struct usb_device *udev, struct mtx *mtx, uint16_t sel);