PERFORCE change 181842 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Wed Aug 4 16:25:55 UTC 2010
http://p4web.freebsd.org/@@181842?ac=10
Change 181842 by hselasky at 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)))
More information about the p4-projects
mailing list