Module Name:    src
Committed By:   skrll
Date:           Mon Aug 31 08:33:03 UTC 2015

Modified Files:
        src/sys/dev/pci [nick-nhusb]: xhci_pci.c
        src/sys/dev/usb [nick-nhusb]: xhci.c xhcivar.h

Log Message:
Various improvements from t-hash (very very slightly tweaked by me)

    + Use usbd_xfer_isread().
    + Change mutex to be initialized at IPL_USB.
    + Add vendor init/portsc hook.
    + Modify xhci_trb_put() to take host byte order arguments and
      convert them to little endian byte order.
    + Return PCI vendor ID of xhci instead of NetBSD(0x0) as a root hub
      vendor ID like other HCs do.
    + Move sc_ih in struct xhci_softc to struct xhci_pci_softc.
    + Improve debug message.


To generate a diff of this commit:
cvs rdiff -u -r1.4.2.3 -r1.4.2.4 src/sys/dev/pci/xhci_pci.c
cvs rdiff -u -r1.28.2.33 -r1.28.2.34 src/sys/dev/usb/xhci.c
cvs rdiff -u -r1.4.12.4 -r1.4.12.5 src/sys/dev/usb/xhcivar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/xhci_pci.c
diff -u src/sys/dev/pci/xhci_pci.c:1.4.2.3 src/sys/dev/pci/xhci_pci.c:1.4.2.4
--- src/sys/dev/pci/xhci_pci.c:1.4.2.3	Wed May 27 07:22:51 2015
+++ src/sys/dev/pci/xhci_pci.c	Mon Aug 31 08:33:03 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: xhci_pci.c,v 1.4.2.3 2015/05/27 07:22:51 skrll Exp $	*/
+/*	$NetBSD: xhci_pci.c,v 1.4.2.4 2015/08/31 08:33:03 skrll Exp $	*/
 /*	OpenBSD: xhci_pci.c,v 1.4 2014/07/12 17:38:51 yuo Exp	*/
 
 /*
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xhci_pci.c,v 1.4.2.3 2015/05/27 07:22:51 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xhci_pci.c,v 1.4.2.4 2015/08/31 08:33:03 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -69,6 +69,7 @@ struct xhci_pci_softc {
 	struct xhci_softc	sc_xhci;
 	pci_chipset_tag_t	sc_pc;
 	pcitag_t		sc_tag;
+	void			*sc_ih;
 };
 
 static int
@@ -144,7 +145,6 @@ xhci_pci_attach(device_t parent, device_
 	pci_intr_handle_t ih;
 	pcireg_t csr, memtype;
 	int err;
-	//const char *vendor;
 	uint32_t hccparams;
 	char intrbuf[PCI_INTRSTR_LEN];
 
@@ -160,7 +160,7 @@ xhci_pci_attach(device_t parent, device_
 	/* check if memory space access is enabled */
 	csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
 #ifdef DEBUG
-	printf("csr: %08x\n", csr);
+	printf("%s: csr: %08x\n", __func__, csr);
 #endif
 	if ((csr & PCI_COMMAND_MEM_ENABLE) == 0) {
 		aprint_error_dev(self, "memory access is disabled\n");
@@ -208,8 +208,8 @@ xhci_pci_attach(device_t parent, device_
 	 * Allocate IRQ
 	 */
 	intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf));
-	sc->sc_ih = pci_intr_establish(pc, ih, IPL_USB, xhci_intr, sc);
-	if (sc->sc_ih == NULL) {
+	psc->sc_ih = pci_intr_establish(pc, ih, IPL_USB, xhci_intr, sc);
+	if (psc->sc_ih == NULL) {
 		aprint_error_dev(self, "couldn't establish interrupt");
 		if (intrstr != NULL)
 			aprint_error(" at %s", intrstr);
@@ -218,12 +218,10 @@ xhci_pci_attach(device_t parent, device_
 	}
 	aprint_normal_dev(self, "interrupting at %s\n", intrstr);
 
-#if 0
 	/* Figure out vendor for root hub descriptor. */
 	sc->sc_id_vendor = PCI_VENDOR(pa->pa_id);
 	pci_findvendor(sc->sc_vendor, sizeof(sc->sc_vendor),
 	    sc->sc_id_vendor);
-#endif
 
 	/* Intel chipset requires SuperSpeed enable and USB2 port routing */
 	switch (PCI_VENDOR(pa->pa_id)) {
@@ -252,9 +250,9 @@ xhci_pci_attach(device_t parent, device_
 	return;
 
 fail:
-	if (sc->sc_ih) {
-		pci_intr_disestablish(psc->sc_pc, sc->sc_ih);
-		sc->sc_ih = NULL;
+	if (psc->sc_ih) {
+		pci_intr_disestablish(psc->sc_pc, psc->sc_ih);
+		psc->sc_ih = NULL;
 	}
 	if (sc->sc_ios) {
 		bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
@@ -286,9 +284,9 @@ xhci_pci_detach(device_t self, int flags
 #endif
 	}
 
-	if (sc->sc_ih != NULL) {
-		pci_intr_disestablish(psc->sc_pc, sc->sc_ih);
-		sc->sc_ih = NULL;
+	if (psc->sc_ih != NULL) {
+		pci_intr_disestablish(psc->sc_pc, psc->sc_ih);
+		psc->sc_ih = NULL;
 	}
 	if (sc->sc_ios) {
 		bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);

Index: src/sys/dev/usb/xhci.c
diff -u src/sys/dev/usb/xhci.c:1.28.2.33 src/sys/dev/usb/xhci.c:1.28.2.34
--- src/sys/dev/usb/xhci.c:1.28.2.33	Fri Jun 26 15:51:05 2015
+++ src/sys/dev/usb/xhci.c	Mon Aug 31 08:33:03 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: xhci.c,v 1.28.2.33 2015/06/26 15:51:05 skrll Exp $	*/
+/*	$NetBSD: xhci.c,v 1.28.2.34 2015/08/31 08:33:03 skrll Exp $	*/
 
 /*
  * Copyright (c) 2013 Jonathan A. Kollasch
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.28.2.33 2015/06/26 15:51:05 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.28.2.34 2015/08/31 08:33:03 skrll Exp $");
 
 #include "opt_usb.h"
 
@@ -493,9 +493,9 @@ static inline void
 xhci_trb_put(struct xhci_trb * const trb, uint64_t parameter, uint32_t status,
     uint32_t control)
 {
-	trb->trb_0 = parameter;
-	trb->trb_2 = status;
-	trb->trb_3 = control;
+	trb->trb_0 = htole64(parameter);
+	trb->trb_2 = htole32(status);
+	trb->trb_3 = htole32(control);
 }
 
 /* --- */
@@ -775,6 +775,9 @@ xhci_init(struct xhci_softc *sc)
 	if (i >= 100)
 		return EIO;
 
+	if (sc->sc_vendor_init)
+		sc->sc_vendor_init(sc);
+
 	pagesize = xhci_op_read_4(sc, XHCI_PAGESIZE);
 	aprint_debug_dev(sc->sc_dev, "PAGESIZE 0x%08x\n", pagesize);
 	pagesize = ffs(pagesize);
@@ -879,7 +882,7 @@ xhci_init(struct xhci_softc *sc)
 
 	cv_init(&sc->sc_command_cv, "xhcicmd");
 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
-	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
+	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB);
 	cv_init(&sc->sc_softwake_cv, "xhciab");
 
 	sc->sc_xferpool = pool_cache_init(sizeof(struct xhci_xfer), 0, 0, 0,
@@ -979,6 +982,7 @@ xhci_intr1(struct xhci_softc * const sc)
 	iman = xhci_rt_read_4(sc, XHCI_IMAN(0));
 	DPRINTFN(16, "IMAN0 %08x", iman, 0, 0, 0);
 
+	/* XXX 4.17.5 IP may be 0 if MSI/MSI-X is used */
 	if (!(sc->sc_quirks & XHCI_QUIRK_FORCE_INTR)) {
 		if ((iman & XHCI_IMAN_INTR_PEND) == 0) {
 			return 0;
@@ -2298,8 +2302,7 @@ xhci_ring_put(struct xhci_softc * const 
 		status = 0;
 		control = XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_LINK) |
 		    XHCI_TRB_3_TC_BIT | (cs ? XHCI_TRB_3_CYCLE_BIT : 0);
-		xhci_trb_put(&xr->xr_trb[ri], htole64(parameter),
-		    htole32(status), htole32(control));
+		xhci_trb_put(&xr->xr_trb[ri], parameter, status, control);
 		usb_syncmem(&xr->xr_dma, XHCI_TRB_SIZE * ri, XHCI_TRB_SIZE * 1,
 		    BUS_DMASYNC_PREWRITE);
 		xr->xr_cookies[ri] = NULL;
@@ -2323,8 +2326,7 @@ xhci_ring_put(struct xhci_softc * const 
 			control &= ~XHCI_TRB_3_CYCLE_BIT;
 		}
 
-		xhci_trb_put(&xr->xr_trb[ri], htole64(parameter),
-		    htole32(status), htole32(control));
+		xhci_trb_put(&xr->xr_trb[ri], parameter, status, control);
 		usb_syncmem(&xr->xr_dma, XHCI_TRB_SIZE * ri, XHCI_TRB_SIZE * 1,
 		    BUS_DMASYNC_PREWRITE);
 		xr->xr_cookies[ri] = cookie;
@@ -2343,8 +2345,7 @@ xhci_ring_put(struct xhci_softc * const 
 		control &= ~XHCI_TRB_3_CYCLE_BIT;
 	}
 
-	xhci_trb_put(&xr->xr_trb[xr->xr_ep], htole64(parameter),
-	    htole32(status), htole32(control));
+	xhci_trb_put(&xr->xr_trb[xr->xr_ep], parameter, status, control);
 	usb_syncmem(&xr->xr_dma, XHCI_TRB_SIZE * ri, XHCI_TRB_SIZE * 1,
 	    BUS_DMASYNC_PREWRITE);
 	xr->xr_cookies[xr->xr_ep] = cookie;
@@ -2716,7 +2717,19 @@ xhci_roothub_ctrl(struct usbd_bus *bus, 
 		if (len == 0)
 			break;
 		switch (value) {
+		case C(0, UDESC_DEVICE): {
+			usb_device_descriptor_t devd;
+			totlen = min(buflen, sizeof(devd));
+			memcpy(&devd, buf, totlen);
+			USETW(devd.idVendor, sc->sc_id_vendor);
+			memcpy(buf, &devd, totlen);
+			break;
+		}
 #define sd ((usb_string_descriptor_t *)buf)
+		case C(1, UDESC_STRING):
+			/* Vendor */
+			totlen = usb_makestrdesc(sd, len, sc->sc_vendor);
+			break;
 		case C(2, UDESC_STRING):
 			/* Product */
 			totlen = usb_makestrdesc(sd, len, "xHCI Root Hub");
@@ -2825,6 +2838,8 @@ xhci_roothub_ctrl(struct usbd_bus *bus, 
 		}
 		if (i & UPS_OTHER_SPEED)
 			i |= UPS_PORT_LS_SET(XHCI_PS_PLS_GET(v));
+		if (sc->sc_vendor_port_status)
+			i = sc->sc_vendor_port_status(sc, v, i);
 		USETW(ps.wPortStatus, i);
 		i = 0;
 		if (v & XHCI_PS_CSC)    i |= UPS_C_CONNECT_STATUS;
@@ -3027,7 +3042,7 @@ xhci_device_ctrl_start(struct usbd_xfer 
 	struct xhci_ring * const tr = &xs->xs_ep[dci].xe_tr;
 	struct xhci_xfer * const xx = (void *)xfer;
 	usb_device_request_t * const req = &xfer->ux_request;
-	const bool isread = UT_GET_DIR(req->bmRequestType) == UT_READ;
+	const int isread = usbd_xfer_isread(xfer);
 	const uint32_t len = UGETW(req->wLength);
 	usb_dma_t * const dma = &xfer->ux_dmabuf;
 	uint64_t parameter;
@@ -3058,7 +3073,6 @@ xhci_device_ctrl_start(struct usbd_xfer 
 
 	/* setup phase */
 	memcpy(&parameter, req, sizeof(*req));
-	parameter = le64toh(parameter);
 	status = XHCI_TRB_2_IRQ_SET(0) | XHCI_TRB_2_BYTES_SET(sizeof(*req));
 	control = ((len == 0) ? XHCI_TRB_3_TRT_NONE :
 	     (isread ? XHCI_TRB_3_TRT_IN : XHCI_TRB_3_TRT_OUT)) |
@@ -3238,8 +3252,7 @@ xhci_device_bulk_done(struct usbd_xfer *
 	struct xhci_slot * const xs = xfer->ux_pipe->up_dev->ud_hcpriv;
 	const u_int dci = xhci_ep_get_dci(xfer->ux_pipe->up_endpoint->ue_edesc);
 #endif
-	const u_int endpt = xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress;
-	const bool isread = UE_GET_DIR(endpt) == UE_DIR_IN;
+	const int isread = usbd_xfer_isread(xfer);
 
 	XHCIHIST_FUNC(); XHCIHIST_CALLED();
 
@@ -3348,8 +3361,7 @@ xhci_device_intr_done(struct usbd_xfer *
 	struct xhci_slot * const xs = xfer->ux_pipe->up_dev->ud_hcpriv;
 	const u_int dci = xhci_ep_get_dci(xfer->ux_pipe->up_endpoint->ue_edesc);
 #endif
-	const u_int endpt = xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress;
-	const bool isread = UE_GET_DIR(endpt) == UE_DIR_IN;
+	const int isread = usbd_xfer_isread(xfer);
 
 	XHCIHIST_FUNC(); XHCIHIST_CALLED();
 

Index: src/sys/dev/usb/xhcivar.h
diff -u src/sys/dev/usb/xhcivar.h:1.4.12.4 src/sys/dev/usb/xhcivar.h:1.4.12.5
--- src/sys/dev/usb/xhcivar.h:1.4.12.4	Tue Apr  7 07:11:58 2015
+++ src/sys/dev/usb/xhcivar.h	Mon Aug 31 08:33:03 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: xhcivar.h,v 1.4.12.4 2015/04/07 07:11:58 skrll Exp $	*/
+/*	$NetBSD: xhcivar.h,v 1.4.12.5 2015/08/31 08:33:03 skrll Exp $	*/
 
 /*
  * Copyright (c) 2013 Jonathan A. Kollasch
@@ -31,10 +31,12 @@
 
 #include <sys/pool.h>
 
+#define XHCI_XFER_NTRB	20
+
 struct xhci_xfer {
 	struct usbd_xfer xx_xfer;
 	struct usb_task xx_abort_task;
-	struct xhci_trb xx_trb[20];
+	struct xhci_trb xx_trb[XHCI_XFER_NTRB];
 };
 
 struct xhci_ring {
@@ -62,7 +64,6 @@ struct xhci_slot {
 struct xhci_softc {
 	device_t sc_dev;
 	device_t sc_child;
-	void *sc_ih;
 	bus_size_t sc_ios;
 	bus_space_tag_t sc_iot;
 	bus_space_handle_t sc_ioh;	/* Base */
@@ -76,6 +77,9 @@ struct xhci_softc {
 	kmutex_t sc_intr_lock;
 	kcondvar_t sc_softwake_cv;
 
+	char sc_vendor[32];		/* vendor string for root hub */
+	int sc_id_vendor;		/* vendor ID for root hub */
+
 	struct usbd_xfer *sc_intrxfer;
 
 	pool_cache_t sc_xferpool;
@@ -110,6 +114,9 @@ struct xhci_softc {
 	bool sc_ac64;
 	bool sc_dying;
 
+	void (*sc_vendor_init)(struct xhci_softc *);
+	int (*sc_vendor_port_status)(struct xhci_softc *, uint32_t, int);
+
 	int sc_quirks;
 #define XHCI_QUIRK_FORCE_INTR	__BIT(0) /* force interrupt reading */
 #define XHCI_QUIRK_INTEL	__BIT(1) /* Intel xhci chip */

Reply via email to