Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/nick-nhusb]: src/sys/dev/usb Sync with HEAD



details:   https://anonhg.NetBSD.org/src/rev/71b66d21835a
branches:  nick-nhusb
changeset: 334515:71b66d21835a
user:      skrll <skrll%NetBSD.org@localhost>
date:      Sun Jun 05 10:50:36 2016 +0000

description:
Sync with HEAD

diffstat:

 sys/dev/usb/xhci.c |  1019 +++++++++++++++++++++++++++++----------------------
 1 files changed, 569 insertions(+), 450 deletions(-)

diffs (truncated from 1346 to 300 lines):

diff -r c72c9ff57c74 -r 71b66d21835a sys/dev/usb/xhci.c
--- a/sys/dev/usb/xhci.c        Mon May 30 06:54:17 2016 +0000
+++ b/sys/dev/usb/xhci.c        Sun Jun 05 10:50:36 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: xhci.c,v 1.28.2.70 2016/05/30 06:48:46 skrll Exp $     */
+/*     $NetBSD: xhci.c,v 1.28.2.71 2016/06/05 10:50:36 skrll Exp $     */
 
 /*
  * Copyright (c) 2013 Jonathan A. Kollasch
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.28.2.70 2016/05/30 06:48:46 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.28.2.71 2016/06/05 10:50:36 skrll Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -142,13 +142,16 @@
 static usbd_status xhci_reset_endpoint(struct usbd_pipe *);
 static usbd_status xhci_stop_endpoint(struct usbd_pipe *);
 
+static void xhci_host_dequeue(struct xhci_ring * const);
 static usbd_status xhci_set_dequeue(struct usbd_pipe *);
 
 static usbd_status xhci_do_command(struct xhci_softc * const,
     struct xhci_trb * const, int);
 static usbd_status xhci_do_command_locked(struct xhci_softc * const,
     struct xhci_trb * const, int);
-static usbd_status xhci_init_slot(struct usbd_device *, uint32_t, uint32_t, int);
+static usbd_status xhci_init_slot(struct usbd_device *, uint32_t);
+static void xhci_free_slot(struct xhci_softc *, struct xhci_slot *, int, int);
+static usbd_status xhci_set_address(struct usbd_device *, uint32_t, bool);
 static usbd_status xhci_enable_slot(struct xhci_softc * const,
     uint8_t * const);
 static usbd_status xhci_disable_slot(struct xhci_softc * const, uint8_t);
@@ -161,6 +164,12 @@
     struct xhci_ring * const, size_t, size_t);
 static void xhci_ring_free(struct xhci_softc * const, struct xhci_ring * const);
 
+static void xhci_setup_ctx(struct usbd_pipe *);
+static void xhci_setup_route(struct usbd_pipe *, uint32_t *);
+static void xhci_setup_tthub(struct usbd_pipe *, uint32_t *);
+static void xhci_setup_maxburst(struct usbd_pipe *, uint32_t *);
+static uint32_t xhci_bival2ival(uint32_t, uint32_t);
+
 static void xhci_noop(struct usbd_pipe *);
 
 static usbd_status xhci_root_intr_transfer(struct usbd_xfer *);
@@ -559,7 +568,6 @@
 
        mutex_destroy(&sc->sc_lock);
        mutex_destroy(&sc->sc_intr_lock);
-       cv_destroy(&sc->sc_softwake_cv);
 
        pool_cache_destroy(sc->sc_xferpool);
 
@@ -1020,7 +1028,6 @@
        cv_init(&sc->sc_cmdbusy_cv, "xhcicmdq");
        mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
        mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB);
-       cv_init(&sc->sc_softwake_cv, "xhciab");
 
        /* Set up the bus struct. */
        sc->sc_bus.ub_methods = &xhci_bus_methods;
@@ -1029,7 +1036,7 @@
        struct xhci_erste *erst;
        erst = KERNADDR(&sc->sc_eventst_dma, 0);
        erst[0].erste_0 = htole64(xhci_ring_trbp(&sc->sc_er, 0));
-       erst[0].erste_2 = htole32(XHCI_EVENT_RING_TRBS);
+       erst[0].erste_2 = htole32(sc->sc_er.xr_ntrb);
        erst[0].erste_3 = htole32(0);
        usb_syncmem(&sc->sc_eventst_dma, 0,
            XHCI_ERSTE_SIZE * XHCI_EVENT_RING_SEGMENTS, BUS_DMASYNC_PREWRITE);
@@ -1053,7 +1060,7 @@
                xhci_rt_write_4(sc, XHCI_IMOD(0), XHCI_IMOD_DEFAULT_LP);
        else
                xhci_rt_write_4(sc, XHCI_IMOD(0), 0);
-       aprint_debug_dev(sc->sc_dev, "setting IMOD %u\n",
+       aprint_debug_dev(sc->sc_dev, "current IMOD %u\n",
            xhci_rt_read_4(sc, XHCI_IMOD(0)));
 
        xhci_op_write_4(sc, XHCI_USBCMD, XHCI_CMD_INTE|XHCI_CMD_RS); /* Go! */
@@ -1216,269 +1223,8 @@
        }
 }
 
-/* construct slot context */
-static void
-xhci_setup_sctx(struct usbd_device *dev, uint32_t *cp)
-{
-       usb_device_descriptor_t * const dd = &dev->ud_ddesc;
-       int speed = dev->ud_speed;
-       int tthubslot, ttportnum;
-       bool ishub;
-       bool usemtt;
-
-       XHCIHIST_FUNC(); XHCIHIST_CALLED();
-
-       /*
-        * 6.2.2, Table 57-60, 6.2.2.1, 6.2.2.2
-        * tthubslot:
-        *   This is the slot ID of parent HS hub
-        *   if LS/FS device is connected && connected through HS hub.
-        *   This is 0 if device is not LS/FS device ||
-        *   parent hub is not HS hub ||
-        *   attached to root hub.
-        * ttportnum:
-        *   This is the downstream facing port of parent HS hub
-        *   if LS/FS device is connected.
-        *   This is 0 if device is not LS/FS device ||
-        *   parent hub is not HS hub ||
-        *   attached to root hub.
-        */
-       if (dev->ud_myhsport != NULL &&
-           dev->ud_myhub != NULL && dev->ud_myhub->ud_depth != 0 &&
-           (dev->ud_myhub != NULL &&
-            dev->ud_myhub->ud_speed == USB_SPEED_HIGH) &&
-           (speed == USB_SPEED_LOW || speed == USB_SPEED_FULL)) {
-               ttportnum = dev->ud_myhsport->up_portno;
-               tthubslot = dev->ud_myhsport->up_parent->ud_addr;
-       } else {
-               ttportnum = 0;
-               tthubslot = 0;
-       }
-       DPRINTFN(4, "myhsport %p ttportnum=%d tthubslot=%d",
-           dev->ud_myhsport, ttportnum, tthubslot, 0);
-
-       /* ishub is valid after reading UDESC_DEVICE */
-       ishub = (dd->bDeviceClass == UDCLASS_HUB);
-
-       /* dev->ud_hub is valid after reading UDESC_HUB */
-       if (ishub && dev->ud_hub) {
-               usb_hub_descriptor_t *hd = &dev->ud_hub->uh_hubdesc;
-
-               cp[1] |= htole32(XHCI_SCTX_1_NUM_PORTS_SET(hd->bNbrPorts));
-               cp[2] |= htole32(XHCI_SCTX_2_TT_THINK_TIME_SET(
-                   __SHIFTOUT(UGETW(hd->wHubCharacteristics), UHD_TT_THINK)));
-               DPRINTFN(4, "nports=%d ttt=%d",
-                   hd->bNbrPorts, XHCI_SCTX_2_TT_THINK_TIME_GET(cp[2]), 0, 0);
-       }
-
-#define IS_TTHUB(dd) \
-    ((dd)->bDeviceProtocol == UDPROTO_HSHUBSTT || \
-     (dd)->bDeviceProtocol == UDPROTO_HSHUBMTT)
-
-       /*
-        * MTT flag is set if
-        * 1. this is HS hub && MTT is enabled
-        *  or
-        * 2. this is not hub && this is LS or FS device &&
-        *    MTT of parent HS hub (and its parent, too) is enabled
-        */
-       if (ishub && speed == USB_SPEED_HIGH && IS_TTHUB(dd))
-               usemtt = true;
-       else if (!ishub &&
-            (speed == USB_SPEED_LOW || speed == USB_SPEED_FULL) &&
-            dev->ud_myhub != NULL && dev->ud_myhub->ud_depth != 0 &&
-            (dev->ud_myhub != NULL &&
-             dev->ud_myhub->ud_speed == USB_SPEED_HIGH) &&
-            dev->ud_myhsport != NULL &&
-            IS_TTHUB(&dev->ud_myhsport->up_parent->ud_ddesc))
-               usemtt = true;
-       else
-               usemtt = false;
-       DPRINTFN(4, "class %u proto %u ishub %d usemtt %d",
-           dd->bDeviceClass, dd->bDeviceProtocol, ishub, usemtt);
-
-       cp[0] |= htole32(
-           XHCI_SCTX_0_SPEED_SET(xhci_speed2xspeed(speed)) |
-           XHCI_SCTX_0_HUB_SET(ishub ? 1 : 0) |
-           XHCI_SCTX_0_MTT_SET(usemtt ? 1 : 0)
-           );
-       cp[1] |= htole32(0);
-       cp[2] |= htole32(
-           XHCI_SCTX_2_IRQ_TARGET_SET(0) |
-           XHCI_SCTX_2_TT_HUB_SID_SET(tthubslot) |
-           XHCI_SCTX_2_TT_PORT_NUM_SET(ttportnum)
-           );
-       cp[3] |= htole32(0);
-}
-
-static uint32_t
-xhci_get_maxburst(struct usbd_pipe *pipe)
-{
-       usb_endpoint_descriptor_t * const ed = pipe->up_endpoint->ue_edesc;
-       usbd_desc_iter_t iter;
-       const usb_cdc_descriptor_t *cdcd;
-       const usb_endpoint_ss_comp_descriptor_t * esscd = NULL;
-       uint32_t maxb = 0;
-       uint8_t ep;
-
-       cdcd = (const usb_cdc_descriptor_t *)usb_find_desc(
-           pipe->up_dev, UDESC_INTERFACE, USBD_CDCSUBTYPE_ANY);
-       usb_desc_iter_init(pipe->up_dev, &iter);
-       iter.cur = (const void *)cdcd;
-
-       /* find endpoint_ss_comp desc for ep of this pipe */
-       for (ep = 0;;) {
-               cdcd = (const usb_cdc_descriptor_t *)usb_desc_iter_next(&iter);
-               if (cdcd == NULL)
-                       break;
-               if (ep == 0 && cdcd->bDescriptorType == UDESC_ENDPOINT) {
-                       ep = ((const usb_endpoint_descriptor_t *)cdcd)->
-                           bEndpointAddress;
-                       if (UE_GET_ADDR(ep) ==
-                           UE_GET_ADDR(ed->bEndpointAddress)) {
-                               cdcd = (const usb_cdc_descriptor_t *)
-                                   usb_desc_iter_next(&iter);
-                               break;
-                       }
-                       ep = 0;
-               }
-       }
-       if (cdcd != NULL && cdcd->bDescriptorType == UDESC_ENDPOINT_SS_COMP) {
-               esscd = (const usb_endpoint_ss_comp_descriptor_t *)cdcd;
-               maxb = esscd->bMaxBurst;
-       }
-
-       return maxb;
-}
-
 /*
- * Convert endpoint bInterval value to endpoint context interval value
- * for Interrupt pipe.
- * xHCI 6.2.3.6 Table 65, USB 2.0 9.6.6
- */
-static uint32_t
-xhci_bival2ival(uint32_t ival, int speed)
-{
-       if (speed == USB_SPEED_LOW || speed == USB_SPEED_FULL) {
-               int i;
-
-               /*
-                * round ival down to "the nearest base 2 multiple of
-                * bInterval * 8".
-                * bInterval is at most 255 as its type is uByte.
-                * 255(ms) = 2040(x 125us) < 2^11, so start with 10.
-                */
-               for (i = 10; i > 0; i--) {
-                       if ((ival * 8) >= (1 << i))
-                               break;
-               }
-               ival = i;
-       } else {
-               /* Interval = bInterval-1 for SS/HS */
-               ival--;
-       }
-
-       return ival;
-}
-
-/*
- * 4.8.2, 6.2.3.2
- * construct common endpoint parameters
- */
-static void
-xhci_setup_endp_ctx(struct usbd_pipe *pipe, uint32_t *cp)
-{
-       struct xhci_slot * const xs = pipe->up_dev->ud_hcpriv;
-       usb_endpoint_descriptor_t * const ed = pipe->up_endpoint->ue_edesc;
-       const u_int dci = xhci_ep_get_dci(ed);
-       const uint8_t xfertype = UE_GET_XFERTYPE(ed->bmAttributes);
-       uint32_t mps = UGETW(ed->wMaxPacketSize);
-       uint32_t maxb = 0;
-       int speed = pipe->up_dev->ud_speed;
-       uint32_t ival = ed->bInterval;
-
-       cp[0] = htole32(
-           XHCI_EPCTX_0_EPSTATE_SET(0) |
-           XHCI_EPCTX_0_MULT_SET(0) |  /* always 0 except SS iscoh */
-           XHCI_EPCTX_0_MAXP_STREAMS_SET(0) |
-           XHCI_EPCTX_0_LSA_SET(0) |
-           XHCI_EPCTX_0_MAX_ESIT_PAYLOAD_HI_SET(0)
-           );
-       cp[1] = htole32(
-           XHCI_EPCTX_1_EPTYPE_SET(xhci_ep_get_type(ed)) |
-           XHCI_EPCTX_1_HID_SET(0) |
-           XHCI_EPCTX_1_MAXB_SET(0)
-           );
-       if (xfertype != UE_ISOCHRONOUS)
-               cp[1] |= htole32(XHCI_EPCTX_1_CERR_SET(3));
-
-       /* 6.2.3.4,  4.8.2.4 */
-       if (USB_IS_SS(speed)) {
-               /* UBS 3.1  9.6.6 */
-               cp[1] |= htole32(XHCI_EPCTX_1_MAXP_SIZE_SET(mps));
-               /* UBS 3.1  9.6.7 */
-               maxb = xhci_get_maxburst(pipe);
-               cp[1] |= htole32(XHCI_EPCTX_1_MAXB_SET(maxb));
-       } else {
-               /* UBS 2.0  9.6.6 */
-               cp[1] |= htole32(XHCI_EPCTX_1_MAXP_SIZE_SET(UE_GET_SIZE(mps)));
-
-               /* 6.2.3.4 */
-               if (speed == USB_SPEED_HIGH &&
-                  (xfertype == UE_ISOCHRONOUS || xfertype == UE_INTERRUPT)) {
-                       maxb = UE_GET_TRANS(mps);
-               } else {
-                       /* LS/FS or HS CTRL or HS BULK */



Home | Main Index | Thread Index | Old Index