From owner-p4-projects@FreeBSD.ORG Wed Aug 4 16:25:55 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 84C72106567E; Wed, 4 Aug 2010 16:25:55 +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 4798C106567B for ; Wed, 4 Aug 2010 16:25:55 +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 33AAA8FC18 for ; Wed, 4 Aug 2010 16:25:55 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.4/8.14.4) with ESMTP id o74GPtLv011929 for ; Wed, 4 Aug 2010 16:25:55 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.4/8.14.4/Submit) id o74GPtAB011927 for perforce@freebsd.org; Wed, 4 Aug 2010 16:25:55 GMT (envelope-from hselasky@FreeBSD.org) Date: Wed, 4 Aug 2010 16:25:55 GMT Message-Id: <201008041625.o74GPtAB011927@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 Precedence: bulk Cc: Subject: PERFORCE change 181842 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, 04 Aug 2010 16:25:55 -0000 http://p4web.freebsd.org/@@181842?ac=10 Change 181842 by hselasky@hselasky_laptop001 on 2010/08/04 16:25:11 USB controller (XHCI): - the CAPLENGTH register is only 8-bits - correct / rename some registers - add more debug prints. - factor more code into xhci_init(). - at this point the XHCI driver is showing the root-HUB and detect devices. No data traffic is working yet. Affected files ... .. //depot/projects/usb/src/sys/dev/usb/controller/xhci.c#13 edit .. //depot/projects/usb/src/sys/dev/usb/controller/xhci.h#14 edit .. //depot/projects/usb/src/sys/dev/usb/controller/xhci_pci.c#6 edit .. //depot/projects/usb/src/sys/dev/usb/controller/xhcireg.h#13 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb/controller/xhci.c#13 (text+ko) ==== @@ -79,7 +79,7 @@ ((uint8_t *)&(((struct xhci_softc *)0)->sc_bus)))) #ifdef USB_DEBUG -static int xhcidebug = 0; +static int xhcidebug = 15; SYSCTL_NODE(_hw_usb, OID_AUTO, xhci, CTLFLAG_RW, 0, "USB XHCI"); SYSCTL_INT(_hw_usb_xhci, OID_AUTO, debug, CTLFLAG_RW, @@ -144,10 +144,12 @@ DPRINTF("\n"); sc->sc_capa_off = 0; - sc->sc_oper_off = XREAD4(sc, capa, XHCI_CAPLENGTH); + sc->sc_oper_off = XREAD1(sc, capa, XHCI_CAPLENGTH); sc->sc_runt_off = XREAD4(sc, capa, XHCI_RTSOFF) & ~0xF; sc->sc_door_off = XREAD4(sc, capa, XHCI_DBOFF) & ~0x3; + DPRINTF("CAPLENGTH=0x%x\n", sc->sc_oper_off); + sc->sc_event_ccs = 1; sc->sc_event_idx = 0; sc->sc_command_ccs = 1; @@ -191,6 +193,12 @@ if (sc->sc_noslot > XHCI_MAX_DEVICES) sc->sc_noslot = XHCI_MAX_DEVICES; + /* setup number of device slots */ + + XWRITE4(sc, oper, XHCI_CONFIG, sc->sc_noslot); + + DPRINTF("Max slots: %u\n", sc->sc_noslot); + temp = XREAD4(sc, capa, XHCI_HCSPARAMS2); sc->sc_noscratch = XHCI_HCS2_SPB_MAX(temp); @@ -201,6 +209,8 @@ return (USB_ERR_NOMEM); } + DPRINTF("Max scratch: %u\n", sc->sc_noscratch); + temp = XREAD4(sc, capa, XHCI_HCSPARAMS3); sc->sc_exit_lat_max = XHCI_HCS3_U1_DEL(temp) + @@ -226,10 +236,6 @@ XWRITE4(sc, oper, XHCI_DCBAAP_LO, (uint32_t)addr); XWRITE4(sc, oper, XHCI_DCBAAP_HI, (uint32_t)(addr >> 32)); - /* setup number of device slots */ - - XWRITE4(sc, oper, XHCI_CONFIG, sc->sc_noslot); - /* Setup interrupter registers */ temp = XREAD4(sc, runt, XHCI_IMAN(0)); @@ -256,7 +262,7 @@ temp = XREAD4(sc, capa, XHCI_HCSPARAMS2); - DPRINTF("hcsparams2=0x%08x\n", temp); + DPRINTF("HCS2=0x%08x\n", temp); temp = XHCI_HCS2_ERST_MAX(temp); temp = 1U << temp; @@ -267,31 +273,38 @@ XWRITE4(sc, runt, XHCI_ERSTS_SET(0), temp); - XWRITE4(sc, oper, XHCI_ERSTDP_LO(0), (uint32_t)addr); - XWRITE4(sc, oper, XHCI_ERSTDP_HI(0), (uint32_t)(addr >> 32)); + DPRINTF("ERDP(0)=0x%016llx\n", (unsigned long long)addr); + + XWRITE4(sc, runt, XHCI_ERDP_LO(0), (uint32_t)addr); + XWRITE4(sc, runt, XHCI_ERDP_HI(0), (uint32_t)(addr >> 32)); addr = (uint64_t)buf_res.physaddr; - XWRITE4(sc, oper, XHCI_ERSTBA_LO(0), (uint32_t)addr); - XWRITE4(sc, oper, XHCI_ERSTBA_HI(0), (uint32_t)(addr >> 32)); + DPRINTF("ERSTBA(0)=0x%016llx\n", (unsigned long long)addr); + + XWRITE4(sc, runt, XHCI_ERSTBA_LO(0), (uint32_t)addr); + XWRITE4(sc, runt, XHCI_ERSTBA_HI(0), (uint32_t)(addr >> 32)); /* setup command ring control base address */ addr = (uint64_t)buf_res.physaddr + (uintptr_t)&((struct xhci_hw_root *)0)->hwr_commands[0]; + DPRINTF("CRCR=0x%016llx\n", (unsigned long long)addr); + XWRITE4(sc, oper, XHCI_CRCR_LO, ((uint32_t)addr) | XHCI_CRCR_LO_RCS); XWRITE4(sc, oper, XHCI_CRCR_HI, (uint32_t)(addr >> 32)); phwr->hwr_commands[XHCI_MAX_COMMANDS - 1].qwTrb0 = htole64(addr); phwr->hwr_commands[XHCI_MAX_COMMANDS - 1].dwTrb2 = htole32(0); phwr->hwr_commands[XHCI_MAX_COMMANDS - 1].dwTrb3 = htole32( - XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_LINK) | - XHCI_TRB_3_IOC_BIT | XHCI_TRB_3_TC_BIT); + XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_LINK) | + XHCI_TRB_3_IOC_BIT | XHCI_TRB_3_TC_BIT); usb_bus_mem_flush_all(&sc->sc_bus, &xhci_iterate_hw_softc); /* Go! */ - XWRITE4(sc, oper, XHCI_USBCMD, XHCI_CMD_RS | XHCI_CMD_INTE | XHCI_CMD_HSEE); + XWRITE4(sc, oper, XHCI_USBCMD, XHCI_CMD_RS | + XHCI_CMD_INTE | XHCI_CMD_HSEE); for (i = 0; i != 100; i++) { usb_pause_mtx(NULL, hz / 1000); @@ -319,6 +332,11 @@ DPRINTF("\n"); + sc->sc_capa_off = 0; + sc->sc_oper_off = XREAD1(sc, capa, XHCI_CAPLENGTH); + sc->sc_runt_off = XREAD4(sc, capa, XHCI_RTSOFF) & ~0xF; + sc->sc_door_off = XREAD4(sc, capa, XHCI_DBOFF) & ~0x3; + /* Halt controller */ XWRITE4(sc, oper, XHCI_USBCMD, 0); @@ -339,6 +357,9 @@ usb_error_t xhci_init(struct xhci_softc *sc, device_t self) { + /* initialise some bus fields */ + sc->sc_bus.parent = self; + /* set the bus revision */ sc->sc_bus.usbrev = USB_REV_3_0; @@ -628,6 +649,7 @@ xhci_check_command(struct xhci_softc *sc, struct xhci_trb *trb) { if (sc->sc_cmd_addr == trb->qwTrb0) { + DPRINTF("Received command event\n"); sc->sc_cmd_result[0] = trb->dwTrb2; sc->sc_cmd_result[1] = trb->dwTrb2; cv_signal(&sc->sc_cmd_cv); @@ -698,7 +720,7 @@ /* we are within a PAGE - no need to update the high bits */ - XWRITE4(sc, oper, XHCI_ERSTDP_LO(0), temp); + XWRITE4(sc, runt, XHCI_ERDP_LO(0), temp); sc->sc_event_idx = i; sc->sc_event_ccs = j; ==== //depot/projects/usb/src/sys/dev/usb/controller/xhci.h#14 (text+ko) ==== @@ -337,7 +337,9 @@ struct xhci_hw_root { struct xhci_event_ring_seg hwr_ring_seg[XHCI_MAX_RSEG]; - volatile uint64_t hwr_padding[2]; + struct { + volatile uint64_t dummy; + } __aligned(64) padding; struct xhci_trb hwr_events[XHCI_MAX_EVENTS]; struct xhci_trb hwr_commands[XHCI_MAX_COMMANDS]; }; ==== //depot/projects/usb/src/sys/dev/usb/controller/xhci_pci.c#6 (text+ko) ==== @@ -164,9 +164,6 @@ int err; int rid; - /* initialise some bus fields */ - sc->sc_bus.parent = self; - /* XXX check for 64-bit capability */ if (xhci_init(sc, self)) { @@ -195,7 +192,7 @@ goto error; } sc->sc_bus.bdev = device_add_child(self, "usbus", -1); - if (!sc->sc_bus.bdev) { + if (sc->sc_bus.bdev == NULL) { device_printf(self, "Could not add USB device\n"); goto error; } @@ -219,14 +216,14 @@ err = xhci_halt_controller(sc); - if (!err) + if (err == 0) err = xhci_start_controller(sc); - if (!err) { + if (err == 0) err = device_probe_and_attach(sc->sc_bus.bdev); - } + if (err) { - device_printf(self, "XHCI start failed err=%d\n", err); + device_printf(self, "XHCI halt/start/probe failed err=%d\n", err); goto error; } return (0); ==== //depot/projects/usb/src/sys/dev/usb/controller/xhcireg.h#13 (text+ko) ==== @@ -170,10 +170,10 @@ #define XHCI_ERSTS_SET(x) ((x) & 0xFFFF) #define XHCI_ERSTBA_LO(n) (0x0030 + (0x20 * (n))) /* XHCI event ring segment table BA */ #define XHCI_ERSTBA_HI(n) (0x0034 + (0x20 * (n))) /* XHCI event ring segment table BA */ -#define XHCI_ERSTDP_LO(n) (0x0038 + (0x20 * (n))) /* XHCI event ring dequeue pointer */ -#define XHCI_ERSTDP_LO_SIGET(x) ((x) & 0x7) /* RO - dequeue segment index */ -#define XHCI_ERSTDP_LO_BUSY 0x00000008 /* RW - event handler busy */ -#define XHCI_ERSTDP_HI(n) (0x003C + (0x20 * (n))) /* XHCI event ring dequeue pointer */ +#define XHCI_ERDP_LO(n) (0x0038 + (0x20 * (n))) /* XHCI event ring dequeue pointer */ +#define XHCI_ERDP_LO_SIGET(x) ((x) & 0x7) /* RO - dequeue segment index */ +#define XHCI_ERDP_LO_BUSY 0x00000008 /* RW - event handler busy */ +#define XHCI_ERDP_HI(n) (0x003C + (0x20 * (n))) /* XHCI event ring dequeue pointer */ /* XHCI doorbell registers. Offset given by XHCI_CAPLENGTH + XHCI_DBOFF registers */ #define XHCI_DOORBELL(n) (0x0000 + (4 * (n)))