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