Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 4 Aug 2010 16:25:55 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 181842 for review
Message-ID:  <201008041625.o74GPtAB011927@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
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)))



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201008041625.o74GPtAB011927>