svn commit: r245731 - stable/9/sys/dev/usb/controller

Hans Petter Selasky hselasky at FreeBSD.org
Mon Jan 21 07:22:46 UTC 2013


Author: hselasky
Date: Mon Jan 21 07:22:45 2013
New Revision: 245731
URL: http://svnweb.freebsd.org/changeset/base/245731

Log:
  MFC r243780:
  - Add support for Etron EJ168 USB 3.0 Host Controllers.
  This brand of controllers expects that the number of
  contexts specified in the input slot context points
  to an active endpoint context, else it refuses to
  operate.
  
  - Wrap one or two long lines.
  
  Tested by:	Markus Pfeiffer (DragonFlyBSD)

Modified:
  stable/9/sys/dev/usb/controller/xhci.c
  stable/9/sys/dev/usb/controller/xhci.h
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/dev/   (props changed)

Modified: stable/9/sys/dev/usb/controller/xhci.c
==============================================================================
--- stable/9/sys/dev/usb/controller/xhci.c	Mon Jan 21 07:19:02 2013	(r245730)
+++ stable/9/sys/dev/usb/controller/xhci.c	Mon Jan 21 07:22:45 2013	(r245731)
@@ -2044,7 +2044,9 @@ xhci_configure_mask(struct usb_device *u
 	struct xhci_softc *sc = XHCI_BUS2SC(udev->bus);
 	struct usb_page_search buf_inp;
 	struct xhci_input_dev_ctx *pinp;
+	uint32_t temp;
 	uint8_t index;
+	uint8_t x;
 
 	index = udev->controller_slot_id;
 
@@ -2059,6 +2061,24 @@ xhci_configure_mask(struct usb_device *u
 	} else {
 		xhci_ctx_set_le32(sc, &pinp->ctx_input.dwInCtx0, 0);
 		xhci_ctx_set_le32(sc, &pinp->ctx_input.dwInCtx1, mask);
+
+		/* find most significant set bit */
+		for (x = 31; x != 1; x--) {
+			if (mask & (1 << x))
+				break;
+		}
+
+		/* adjust */
+		x--;
+
+		/* figure out maximum */
+		if (x > sc->sc_hw.devs[index].context_num) {
+			sc->sc_hw.devs[index].context_num = x;
+			temp = xhci_ctx_get_le32(sc, &pinp->ctx_slot.dwSctx0);
+			temp &= ~XHCI_SCTX_0_CTX_NUM_SET(31);
+			temp |= XHCI_SCTX_0_CTX_NUM_SET(x + 1);
+			xhci_ctx_set_le32(sc, &pinp->ctx_slot.dwSctx0, temp);
+		}
 	}
 	return (0);
 }
@@ -2280,16 +2300,9 @@ xhci_configure_device(struct usb_device 
 
 	DPRINTF("Route=0x%08x\n", route);
 
-	temp = XHCI_SCTX_0_ROUTE_SET(route);
-
-	switch (sc->sc_hw.devs[index].state) {
-	case XHCI_ST_CONFIGURED:
-		temp |= XHCI_SCTX_0_CTX_NUM_SET(XHCI_MAX_ENDPOINTS - 1);
-		break;
-	default:
-		temp |= XHCI_SCTX_0_CTX_NUM_SET(1);
-		break;
-	}
+	temp = XHCI_SCTX_0_ROUTE_SET(route) |
+	    XHCI_SCTX_0_CTX_NUM_SET(
+	    sc->sc_hw.devs[index].context_num + 1);
 
 	switch (udev->speed) {
 	case USB_SPEED_LOW:
@@ -2433,8 +2446,9 @@ xhci_alloc_device_ext(struct usb_device 
 
 	if (usb_pc_alloc_mem(pc, pg, sc->sc_ctx_is_64_byte ?
 	    (2 * sizeof(struct xhci_input_dev_ctx)) :
-	     sizeof(struct xhci_input_dev_ctx), XHCI_PAGE_SIZE))
+	    sizeof(struct xhci_input_dev_ctx), XHCI_PAGE_SIZE)) {
 		goto error;
+	}
 
 	pc = &sc->sc_hw.devs[index].endpoint_pc;
 	pg = &sc->sc_hw.devs[index].endpoint_pg;
@@ -2442,15 +2456,18 @@ xhci_alloc_device_ext(struct usb_device 
 	/* need to initialize the page cache */
 	pc->tag_parent = sc->sc_bus.dma_parent_tag;
 
-	if (usb_pc_alloc_mem(pc, pg, sizeof(struct xhci_dev_endpoint_trbs), XHCI_PAGE_SIZE))
+	if (usb_pc_alloc_mem(pc, pg,
+	    sizeof(struct xhci_dev_endpoint_trbs), XHCI_PAGE_SIZE)) {
 		goto error;
+	}
 
 	/* initialise all endpoint LINK TRBs */
 
 	for (i = 0; i != XHCI_MAX_ENDPOINTS; i++) {
 
 		/* lookup endpoint TRB ring */
-		usbd_get_page(pc, (uintptr_t)&((struct xhci_dev_endpoint_trbs *)0)->trb[i][0], &buf_ep);
+		usbd_get_page(pc, (uintptr_t)&
+		    ((struct xhci_dev_endpoint_trbs *)0)->trb[i][0], &buf_ep);
 
 		/* get TRB pointer */
 		trb = buf_ep.buffer;
@@ -2536,8 +2553,10 @@ xhci_endpoint_doorbell(struct usb_xfer *
 	epno = XHCI_EPNO2EPID(epno);
 	index = xfer->xroot->udev->controller_slot_id;
 
-	if (xfer->xroot->udev->flags.self_suspended == 0)
-		XWRITE4(sc, door, XHCI_DOORBELL(index), epno | XHCI_DB_SID_SET(0));
+	if (xfer->xroot->udev->flags.self_suspended == 0) {
+		XWRITE4(sc, door, XHCI_DOORBELL(index),
+		    epno | XHCI_DB_SID_SET(/*xfer->stream_id*/ 0));
+	}
 }
 
 static void
@@ -3539,7 +3558,7 @@ xhci_configure_reset_endpoint(struct usb
 	 * endpoint context state diagram in the XHCI specification:
 	 */
 
-	xhci_configure_mask(udev, 1U << epno, 0);
+	xhci_configure_mask(udev, (1U << epno) | 1U, 0);
 
 	err = xhci_cmd_evaluate_ctx(sc, buf_inp.physaddr, index);
 
@@ -3815,6 +3834,7 @@ xhci_device_resume(struct usb_device *ud
 	struct xhci_softc *sc = XHCI_BUS2SC(udev->bus);
 	uint8_t index;
 	uint8_t n;
+	uint8_t p;
 
 	DPRINTF("\n");
 
@@ -3830,8 +3850,12 @@ xhci_device_resume(struct usb_device *ud
 
 	USB_BUS_LOCK(udev->bus);
 
-	for (n = 1; n != XHCI_MAX_ENDPOINTS; n++)
-		XWRITE4(sc, door, XHCI_DOORBELL(index), n | XHCI_DB_SID_SET(0));
+	for (n = 1; n != XHCI_MAX_ENDPOINTS; n++) {
+		for (p = 0; p != 1 /*XHCI_MAX_STREAMS*/; p++) {
+			XWRITE4(sc, door, XHCI_DOORBELL(index),
+			    n | XHCI_DB_SID_SET(p));
+		}
+	}
 
 	USB_BUS_UNLOCK(udev->bus);
 
@@ -3905,8 +3929,12 @@ xhci_device_state_change(struct usb_devi
 		if (sc->sc_hw.devs[index].state == XHCI_ST_DEFAULT)
 			break;
 
+		/* set default state */
 		sc->sc_hw.devs[index].state = XHCI_ST_DEFAULT;
 
+		/* reset number of contexts */
+		sc->sc_hw.devs[index].context_num = 0;
+
 		err = xhci_cmd_reset_dev(sc, index);
 
 		if (err != 0) {
@@ -3933,11 +3961,15 @@ xhci_device_state_change(struct usb_devi
 		if (sc->sc_hw.devs[index].state == XHCI_ST_CONFIGURED)
 			break;
 
+		/* set configured state */
 		sc->sc_hw.devs[index].state = XHCI_ST_CONFIGURED;
 
+		/* reset number of contexts */
+		sc->sc_hw.devs[index].context_num = 0;
+
 		usbd_get_page(&sc->sc_hw.devs[index].input_pc, 0, &buf_inp);
 
-		xhci_configure_mask(udev, 1, 0);
+		xhci_configure_mask(udev, 3, 0);
 
 		err = xhci_configure_device(udev);
 		if (err != 0) {

Modified: stable/9/sys/dev/usb/controller/xhci.h
==============================================================================
--- stable/9/sys/dev/usb/controller/xhci.h	Mon Jan 21 07:19:02 2013	(r245730)
+++ stable/9/sys/dev/usb/controller/xhci.h	Mon Jan 21 07:22:45 2013	(r245731)
@@ -385,7 +385,7 @@ struct xhci_hw_dev {
 	uint8_t			state;
 	uint8_t			nports;
 	uint8_t			tt;
-	uint8_t			reserved;
+	uint8_t			context_num;
 };
 
 struct xhci_hw_softc {


More information about the svn-src-stable-9 mailing list