Index: sys/conf/files =================================================================== --- sys/conf/files +++ sys/conf/files @@ -3023,6 +3023,7 @@ dev/usb/controller/uhci_pci.c optional uhci pci dev/usb/controller/xhci.c optional xhci dev/usb/controller/xhci_pci.c optional xhci pci +dev/usb/controller/xhci_dbc.c optional xhci pci dev/usb/controller/saf1761_otg.c optional saf1761otg dev/usb/controller/saf1761_otg_fdt.c optional saf1761otg fdt dev/usb/controller/uss820dci.c optional uss820dci Index: sys/dev/usb/controller/xhci.h =================================================================== --- sys/dev/usb/controller/xhci.h +++ sys/dev/usb/controller/xhci.h @@ -515,6 +515,9 @@ /* vendor string for root HUB */ char sc_vendor[16]; + + /* offset to debug port registers */ + uint32_t sc_dbc_off; }; #define XHCI_CMD_LOCK(sc) sx_xlock(&(sc)->sc_cmd_sx) Index: sys/dev/usb/controller/xhci.c =================================================================== --- sys/dev/usb/controller/xhci.c +++ sys/dev/usb/controller/xhci.c @@ -94,7 +94,7 @@ &xhcistreams, 0, "Set to enable streams mode support"); #ifdef USB_DEBUG -static int xhcidebug; +int xhcidebug; static int xhciroute; static int xhcipolling; static int xhcidma32; Index: sys/dev/usb/controller/xhci_dbc.h =================================================================== --- /dev/null +++ sys/dev/usb/controller/xhci_dbc.h @@ -0,0 +1,120 @@ +/* $FreeBSD$ */ + +/*- + * Copyright (c) 2015-2017 Bruce Simpson. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#ifndef _XHCI_DBC_H_ +#define _XHCI_DBC_H_ + +int xhci_dbc_detect(device_t dev); + +/* + * xHCI Debug Capability Context [Sec. 7.6.9.1] + */ + +enum xhci_dbcic_desc { + DBCIC_STR0_DESC = 0, + DBCIC_VENDOR_DESC, + DBCIC_PRODUCT_DESC, + DBCIC_SERIAL_DESC +}; +#define DBCIC_MAX_DESCS 4 /* number of descriptors in DbC IC */ +#define DBCIC_DESC_SIZE_MAX 256 /* maximum size of each descriptor */ + +/* + * Controller-visible structures. + */ + +/* + * Event ring. TRB slots are allocated in the same page, as existing code. + * Alias for xhci_hw_root{} in xhci.h to avoid confusion. + */ +typedef struct xhci_hw_root xhci_dbc_erst_t; + +/* + * DbC IC string descriptor table. + */ +struct xhci_dbc_ic { + uint64_t aqwDesc[DBCIC_MAX_DESCS]; + uint8_t abyStrlen[DBCIC_MAX_DESCS]; + uint32_t dwReserved[7]; +} __packed; + +/* Endpoint context indices */ +#define DBC_EP_OUT 0 +#define DBC_EP_IN 1 +#define DBC_EP_MAX 2 + +#define DBC_EP_MAXP_SIZE 1024 /* Fixed packet size for DbC EPs */ + +/* + * DbC Information Context (IC). + */ +struct xhci_hw_dbcc { + struct xhci_dbc_ic dbcc_ic; /* 'personality' */ + struct { + struct xhci_endp_ctx ctx; /* [Sec. 6.2.3] */ + uint32_t reserved[8]; /* Pad to 64 bytes */ + } dbcc_endps[DBC_EP_MAX] __packed; +} __packed; +#define DBCC_EP_CTX(x, idx) (&((x)->dbcc_endps[(idx)].ctx)) + +/* + * Driver-visible structures. + */ + +/* 'usb/' + 'xhci' + 'NNNNNN' + '-dbc' + '\0' + 2*pad := 80 bytes */ +#define DBC_PROCNAMELEN (4 + SPECNAMELEN + 6 + 4 + 1 + 2) + +struct xhci_dbc { + struct usb_page_cache dbc_ctx_pc; /* DbCC */ + struct usb_page_cache dbc_erst_pc; /* ERST */ + struct usb_page_cache dbc_ring_pcs[DBC_EP_MAX]; /* EPs */ + + struct usb_page dbc_ctx_pg; + struct usb_page dbc_erst_pg; + struct usb_page dbc_ring_pgs[DBC_EP_MAX]; + + struct usb_process dbc_proc; + struct mtx dbc_mtx; + + struct xhci_softc *dbc_sc; /* backptr to xHCI softc */ + + /* chip specific */ + uint16_t dbc_erst_max; /* event ring segment limit */ + uint8_t dbc_bst_max; /* packet burst limit */ + uint8_t dbc_pad00; + + /* thread naming */ + char dbc_procname[DBC_PROCNAMELEN]; +}; +#define DBC_EP_PC(x, idx) (&((x)->dbc_ring_pcs[(idx)])) +#define DBC_EP_PG(x, idx) (&((x)->dbc_ring_pgs[(idx)])) + +/* + * There are no user-visible structures. + */ + +#endif /* _XHCI_DBC_H_ */ Index: sys/dev/usb/controller/xhci_dbc.c =================================================================== --- /dev/null +++ sys/dev/usb/controller/xhci_dbc.c @@ -0,0 +1,107 @@ +/* $FreeBSD$ */ + +/*- + * Copyright (c) 2015-2017 Bruce Simpson. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define USB_DEBUG_VAR xhcidebug + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +extern int xhcidebug; + +int +xhci_dbc_detect(device_t self) +{ + struct xhci_softc *sc; + uint32_t temp, eecp, noff; + + sc = device_get_softc(self); + + sc->sc_dbc_off = noff = -1U; + temp = XREAD4(sc, capa, XHCI_HCSPARAMS0); + eecp = XHCI_HCS0_XECP(temp) << 2; + while (eecp != 0) { + temp = XREAD4(sc, capa, eecp); + if (XHCI_XECP_ID(temp) == XHCI_ID_DBC) { + sc->sc_dbc_off = eecp; + break; + } + noff = XHCI_XECP_NEXT(temp) << 2; + if (noff == 0) + break; + eecp += noff; + } + + DPRINTF("DBCOFF=0x08%x\n", sc->sc_dbc_off); + if (sc->sc_dbc_off == -1U) + return (0); + + /* Probe status register to see if DbC capability exists (and mapped) */ + temp = XREAD4(sc, dbc, XHCI_DCST); + DPRINTF("DCST=0x08%x\n", temp); + if (temp == -1U) + return (USB_ERR_NO_PIPE); /* not responding */ + + device_printf(self, "Debug Capability detected\n"); + + return (0); +} Index: sys/dev/usb/controller/xhci_pci.c =================================================================== --- sys/dev/usb/controller/xhci_pci.c +++ sys/dev/usb/controller/xhci_pci.c @@ -58,6 +58,7 @@ #include #include #include +#include #include "usb_if.h" static device_probe_t xhci_pci_probe; @@ -100,6 +101,8 @@ case 0x01941033: return ("NEC uPD720200 USB 3.0 controller"); + case 0x00151912: + return ("NEC uPD720202 USB 3.0 controller"); case 0x10001b73: return ("Fresco Logic FL1000G USB 3.0 controller"); @@ -319,6 +322,8 @@ xhci_pci_take_controller(self); + err = xhci_dbc_detect(self); + err = xhci_halt_controller(sc); if (err == 0) Index: sys/dev/usb/controller/xhcireg.h =================================================================== --- sys/dev/usb/controller/xhcireg.h +++ sys/dev/usb/controller/xhcireg.h @@ -187,6 +187,50 @@ #define XHCI_DB_SID_GET(x) (((x) >> 16) & 0xFFFF) /* RW - doorbell stream ID */ #define XHCI_DB_SID_SET(x) (((x) & 0xFFFF) << 16) /* RW - doorbell stream ID */ +/* + * XHCI Debug Capability (DbC) registers. + * Offset given by XHCI_ID_USB_DEBUG extended capability pointer. + * See also: Sec. 7.6.8 of Intel xHCI specification v1.1. + */ +#define XHCI_DCID 0x00 /* Capability ID */ +#define XHCI_DCID_ERST_MAX(x) (((x) >> 16) & 0xF) +#define XHCI_DCDB 0x04 /* Doorbell */ +#define XHCI_DCDB_TARGET_SET(x) (((x) & 0x01) << 8) +#define DCDB_TARGET_OUT 0 +#define DCDB_TARGET_IN 1 +#define XHCI_DCERSTSZ 0x08 /* Event Ring Segment Table Size */ +#define XHCI_DCERSTBA 0x10 /* Event Ring Base Address */ +#define XHCI_DCERDP 0x18 /* Event Ring Dequeue Pointer */ +#define XHCI_DCERDP_SINDEX(x) XHCI_ERDP_LO_SINDEX(x) +#define XHCI_DCCTRL 0x20 /* DbC Control Register */ +#define XHCI_DCCTRL_DCR 0x00000001 /* DbC Run (RO) */ +#define XHCI_DCCTRL_LSE 0x00000002 /* Link Status Event Enable */ +#define XHCI_DCCTRL_HOT 0x00000004 /* Halt OUT TR */ +#define XHCI_DCCTRL_HIT 0x00000008 /* Halt IN TR */ +#define XHCI_DCCTRL_DRC 0x00000010 /* DbC Run Change */ +#define XHCI_DCCTRL_BST_MAX(x) (((x) >> 16) & 0xFF) /* Burst size */ +#define XHCI_DCCTRL_ADDR_GET(x) (((x) >> 24) & 0x7F) /* USB address */ +#define XHCI_DCCTRL_DCE 0x80000000 +#define XHCI_DCST 0x24 /* DbC Status Register */ +#define XHCI_DCST_ER 0x00000001 /* Event Ring not empty (RO) */ +#define XHCI_DCST_SBR 0x00000002 /* System Bus will Reset (RO) */ +#define XHCI_DCST_DPORT(x) (((x) >> 24) & 0xFF) +#define XHCI_DCPORTSC 0x28 /* DbC Port Status/Control Register */ +#define XHCI_DCPORTSC_CCS 0x00000001 /* Current Connect Status (RO) */ +#define XHCI_DCPORTSC_PED 0x00000002 /* Port Enable/Disable */ +#define XHCI_DCPORTSC_PR 0x00000010 /* Port in Reset (RO) */ +#define XHCI_DCPORTSC_PLS(x) ((x) >> 5) & 0x0F) /* Port Link Status */ +#define XHCI_DCPORTSC_SPEED(x) ((x) >> 13) & 0x0F) /* Port Speed */ +#define XHCI_DCPORTSC_CSC 0x00020000 /* Connect Status Change */ +#define XHCI_DCPORTSC_PRC 0x00200000 /* Port Reset Change */ +#define XHCI_DCPORTSC_PLC 0x00400000 /* Port Link Status Change */ +#define XHCI_DCPORTSC_CEC 0x00800000 /* Port Config Error Change */ +#define XHCI_DCCP 0x30 /* DbC Context Pointer */ +#define XHCI_DCDDI1 0x38 /* DbC Device Descriptor Info 1 */ +#define XHCI_DBC_PROTO_VENDOR 0 /* Vendor-specific protocol */ +#define XHCI_DBC_PROTO_GNU 1 /* GDB Remote Serial protocol */ +#define XHCI_DCDDI2 0x3C /* DbC Device Descriptor Info 2 */ + /* XHCI legacy support */ #define XHCI_XECP_ID(x) ((x) & 0xFF) #define XHCI_XECP_NEXT(x) (((x) >> 8) & 0xFF) @@ -200,6 +244,7 @@ #define XHCI_ID_VIRTUALIZATION 0x0004 #define XHCI_ID_MSG_IRQ 0x0005 #define XHCI_ID_USB_LOCAL_MEM 0x0006 +#define XHCI_ID_DBC 0x000a /* XHCI register R/W wrappers */ #define XREAD1(sc, what, a) \