Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 2 Aug 2010 18:22:10 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 181738 for review
Message-ID:  <201008021822.o72IMAVd029633@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@181738?ac=10

Change 181738 by hselasky@hselasky_laptop001 on 2010/08/02 18:21:20

	USB controller (XHCI):
		- add code to configure device and endpoint
		- refactor some structures

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb/controller/xhci.c#9 edit
.. //depot/projects/usb/src/sys/dev/usb/controller/xhci.h#11 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb/controller/xhci.c#9 (text+ko) ====

@@ -113,6 +113,7 @@
 static void xhci_device_done(struct usb_xfer *, usb_error_t);
 static void xhci_root_intr(struct xhci_softc *);
 static void xhci_free_device_ext(struct usb_device *udev);
+static struct xhci_endpoint_ext *xhci_get_endpoint_ext(struct usb_xfer *xfer);
 
 extern struct usb_bus_methods xhci_bus_methods;
 
@@ -1162,7 +1163,6 @@
 	xfer->td_transfer_cache = td;
 
 	if (xfer->flags_int.isochronous_xfr) {
-
 		uint8_t shift;
 
 		x = XREAD4(temp.sc, runt, XHCI_MFINDEX);
@@ -1171,17 +1171,19 @@
 		case USB_SPEED_FULL:
 			shift = 3;
 			temp.isoc_delta = 8;	/* 1ms */
+			x += temp.isoc_delta - 1;
+			x &= ~(temp.isoc_delta - 1);
 			break;
 		default:
 			shift = usbd_xfer_get_fps_shift(xfer);
 			temp.isoc_delta = 1U << shift;
+			x += temp.isoc_delta - 1;
+			x &= ~(temp.isoc_delta - 1);
+			/* simple frame load balancing */
+			x += xfer->endpoint->usb_uframe;
 			break;
 		}
 
-		x += temp.isoc_delta - 1;
-		x &= ~(temp.isoc_delta - 1);
-		x += xfer->endpoint->usb_uframe;
-
 		y = XHCI_MFINDEX_GET(x - xfer->endpoint->isoc_next);
 
 		if ((xfer->endpoint->is_synced == 0) ||
@@ -1198,6 +1200,14 @@
 			DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
 		}
 
+		/* compute isochronous completion time */
+
+		y = XHCI_MFINDEX_GET(xfer->endpoint->isoc_next - (x & ~7));
+
+		xfer->isoc_time_complete =
+		    usb_isoc_time_expand(&temp.sc->sc_bus, x / 8) +
+		    (y / 8) + (((xfer->nframes << shift) + 7) / 8);
+
 		x = 0;
 		temp.isoc_frame = xfer->endpoint->isoc_next;
 		temp.trb_type = XHCI_TRB_TYPE_ISOCH;
@@ -1344,232 +1354,338 @@
 	usb_pc_cpu_flush(&sc->sc_hw.ctx_pc);
 }
 
+static uint8_t
+xhci_log2(uint32_t x)
+{
+	uint8_t retval;
+
+	retval = 0;
+	while (1) {
+		if (x == 1)
+			break;
+		x >>= 2;
+		if (x == 0)
+			break;
+		retval++;
+	}
+	return (retval);
+}
+
 static usb_error_t
-xhci_alloc_device_ext(struct usb_device *udev)
+xhci_configure_endpoint(struct usb_xfer *xfer)
 {
-	struct xhci_softc *sc = XHCI_BUS2SC(udev->bus);
-	struct usb_page_search buf_scp;
-	struct usb_page_search buf_dev;
-	struct usb_page_cache *pcd;
-	struct usb_page *pgd;
-	struct usb_page_cache *pcs;
-	struct usb_page *pgs;
-	struct xhci_dev_ctx *pdctx;
-	struct usb_device *hubdev;
+	struct usb_page_search buf_inp;
+	struct usb_page_search buf_ep;
+	struct xhci_softc *sc = XHCI_BUS2SC(xfer->xroot->bus);
+	struct xhci_input_dev_ctx *pinp;
+	struct usb_endpoint_descriptor *edesc;
+	struct xhci_endpoint_ext *pepext;
+	struct usb_device *udev;
 	uint64_t addr;
 	uint32_t temp;
 	uint8_t index;
-	uint8_t failure;
-	uint8_t i;
-	uint8_t rh_port;
+	uint8_t epno;
+	uint8_t k;
+
+	usbd_get_page(&sc->sc_hw.devs[index].input_pc, 0, &buf_inp);
+	usbd_get_page(&sc->sc_hw.devs[index].endpoint_pc, 0, &buf_ep);
+
+	pepext = xhci_get_endpoint_ext(xfer);
+
+	udev = xfer->xroot->udev;
 
 	index = udev->device_index;
-	failure = 0;
+
+	edesc = xfer->endpoint->edesc;
+
+	epno = edesc->bEndpointAddress;
+
+	if ((edesc->bmAttributes & UE_XFERTYPE) == UE_CONTROL)
+		epno |= UE_DIR_IN;
+
+	epno = XHCI_EPNO2EPID(epno);
+
+ 	if (epno == 0)
+		return (USB_ERR_INVAL);		/* invalid */
+
+	pinp = buf_inp.buffer;
+
+	XXX;
+	pinp->ctx_input.dwInCtx0 |= htole32(0xFFFFFFFC);
+	pinp->ctx_input.dwInCtx1 &= htole32(0x1);
 
-	pcd = &sc->sc_hw.devs[index].device_pc;
-	pgd = &sc->sc_hw.devs[index].device_pg;
+	temp = XHCI_EPCTX_0_EPSTATE_SET(0) |
+	    XHCI_EPCTX_0_MAXP_STREAMS_SET(0) |
+	    XHCI_EPCTX_0_LSA_SET(0);
 
-	/* need to initialize the page cache */
-	pcd->tag_parent = sc->sc_bus.dma_parent_tag;
+	switch (edesc->bmAttributes & UE_XFERTYPE) {
+	case UE_INTERRUPT:
+		k = xhci_log2(xfer->interval) + 3;
+		temp |= XHCI_EPCTX_0_IVAL_SET(k);
+		break;
+	case UE_ISOCHRONOUS:
+		if (udev->speed == USB_SPEED_SUPER)
+			temp |= XHCI_EPCTX_0_MULT_SET(xfer->max_packet_count);
+		break;
+	default:
+		break;
+	}
 
-	if (usb_pc_alloc_mem(pcd, pgd, sizeof(*pdctx), XHCI_PAGE_SIZE))
-		failure = 1;
+	pinp->ctx_ep[epno - 1].dwEpCtx0 = htole32(temp);
 
-	if (failure == 0) {
+	temp =
+	    XHCI_EPCTX_1_HID_SET(0) |
+	    XHCI_EPCTX_1_MAXB_SET(xfer->max_packet_count) |
+	    XHCI_EPCTX_1_MAXP_SIZE_SET(xfer->max_packet_size);
 
-		usbd_get_page(pcd, 0, &buf_dev);
+	if ((udev->parent_hs_hub != NULL) || (udev->address != 0))
+		temp |= XHCI_EPCTX_1_CERR_SET(3);
 
-		pdctx = buf_dev.buffer;
-		addr = buf_dev.physaddr;
+	switch (edesc->bmAttributes & UE_XFERTYPE) {
+	case UE_CONTROL:
+		temp |= XHCI_EPCTX_1_EPTYPE_SET(4);
+		break;
+	case UE_ISOCHRONOUS:
+		temp |= XHCI_EPCTX_1_EPTYPE_SET(1);
+		break;
+	case UE_BULK:
+		temp |= XHCI_EPCTX_1_EPTYPE_SET(2);
+		break;
+	default:
+		temp |= XHCI_EPCTX_1_EPTYPE_SET(3);
+		break;
+	}
 
-		hubdev = udev;
-		temp = XHCI_SCTX_0_CTX_NUM_SET(XHCI_MAX_ENDPOINTS - 1);
+	if (edesc->bmAttributes & UE_DIR_IN)
+		temp |= XHCI_EPCTX_1_EPTYPE_SET(4);
 
-		while (hubdev->parent_hub != NULL) {
-			temp |= (hubdev->port_no & 0xF) << ((hubdev->depth - 1) * 4);
-			hubdev = hubdev->parent_hub;
-		}
+	pinp->ctx_ep[epno - 1].dwEpCtx1 = htole32(temp);
 
-		rh_port = hubdev->port_no;
+	pepext->trb_ccs = 1;
+	pepext->trb_index = 0;
+	pepext->trb_halted = 0;
 
-		switch (udev->speed) {
-		case USB_SPEED_LOW:
-			temp |= XHCI_SCTX_0_SPEED_SET(2);
-			break;
-		case USB_SPEED_HIGH:
-			temp |= XHCI_SCTX_0_SPEED_SET(3);
-			break;
-		case USB_SPEED_FULL:
-			temp |= XHCI_SCTX_0_SPEED_SET(1);
-			break;
-		default:
-			temp |= XHCI_SCTX_0_SPEED_SET(4);
-			break;
-		}
+	for (k = 0; k != XHCI_MAX_TRANSFERS; k++)
+		pepext->trb[k].dwTrb3 = 0;
 
-		if (udev->hub != NULL)
-			temp |= XHCI_SCTX_0_HUB_SET(1);
+	usb_pc_cpu_flush(pepext->page_cache);
 
-		pdctx->ctx_slot.dwSctx0 = htole32(temp);
+	addr = XHCI_EPCTX_2_DCS_SET(1) |
+	    (buf_ep.physaddr + (uintptr_t)&((struct xhci_dev_endpoint_trbs *)0)->trb[epno][0]);
 
-		temp = XHCI_SCTX_1_RH_PORT_SET(rh_port);
+	pinp->ctx_ep[epno - 1].qwEpCtx2 = htole64(addr);
 
-		if (udev->hub != NULL)
-			temp |= XHCI_SCTX_1_NUM_PORTS_SET(udev->hub->nports);
+	temp = XHCI_EPCTX_4_AVG_TRB_LEN_SET() |
+	    XHCI_EPCTX_4_MAX_ESIT_PAYLOAD_SET();
 
-		switch (udev->speed) {
-		case USB_SPEED_LOW:
-		case USB_SPEED_HIGH:
-		case USB_SPEED_FULL:
-		default:
-			temp |= XHCI_SCTX_1_MAX_EL_SET(sc->sc_exit_lat_max);
-			break;
-		}
+	pinp->ctx_ep[epno - 1].dwEpCtx4 = htole32(temp);
 
-		pdctx->ctx_slot.dwSctx1 = htole32(temp);
+	usb_pc_cpu_flush(&sc->sc_hw.devs[index].input_pc);
+}
 
-		temp = XHCI_SCTX_2_IRQ_TARGET_SET(0);
+static usb_error_t
+xhci_configure_device(struct usb_device *udev)
+{
+	struct xhci_softc *sc = XHCI_BUS2SC(udev->bus);
+	struct usb_page_search buf_scp;
+	struct usb_page_search buf_dev;
+	struct usb_page_search buf_inp;
+	struct usb_page_cache *pcdev;
+	struct usb_page_cache *pcinp;
+	struct usb_page_cache *pc;
+	struct xhci_input_dev_ctx *pinp;
+	struct usb_device *hubdev;
+	uint32_t temp;
+	uint8_t index;
+	uint8_t rh_port;
+	uint8_t i;
 
-		if ((udev->hub != NULL) &&
-		    (udev->speed == USB_SPEED_HIGH))
-			temp |= XHCI_SCTX_2_TT_THINK_TIME_SET(3);
+	pcdev = &sc->sc_hw.devs[index].device_pc;
+	pcinp = &sc->sc_hw.devs[index].input_pc;
 
-		hubdev = udev->parent_hs_hub;
+	usbd_get_page(pcdev, 0, &buf_dev);
+	usbd_get_page(pcinp, 0, &buf_inp);
 
-		if (hubdev != NULL) {
-			temp |= XHCI_SCTX_2_TT_HUB_SID_SET(hubdev->device_index);
-			temp |= XHCI_SCTX_2_TT_PORT_NUM_SET(hubdev->port_no);
-		}
+	pinp = buf_inp.buffer;
 
-		pdctx->ctx_slot.dwSctx2 = htole32(temp);
+	hubdev = udev;
+	temp = XHCI_SCTX_0_CTX_NUM_SET(XHCI_MAX_ENDPOINTS - 1);
 
-		temp = XHCI_SCTX_3_DEV_ADDR_SET(udev->address) |
-		    XHCI_SCTX_3_SLOT_STATE_SET(3);
+	while (hubdev->parent_hub != NULL) {
+		temp |= ((uint32_t)(hubdev->port_no & 0xF)) << ((hubdev->depth - 1) * 4);
+		hubdev = hubdev->parent_hub;
+	}
 
-		pdctx->ctx_slot.dwSctx3 = htole32(temp);
+	rh_port = hubdev->port_no;
 
-	} else {
-		pdctx = NULL;
+	switch (udev->speed) {
+	case USB_SPEED_LOW:
+		temp |= XHCI_SCTX_0_SPEED_SET(2);
+		break;
+	case USB_SPEED_HIGH:
+		temp |= XHCI_SCTX_0_SPEED_SET(3);
+		break;
+	case USB_SPEED_FULL:
+		temp |= XHCI_SCTX_0_SPEED_SET(1);
+		break;
+	default:
+		temp |= XHCI_SCTX_0_SPEED_SET(4);
+		break;
 	}
 
-	for (i = 0; i != sc->sc_noscratch; i++) {
+	if (udev->hub != NULL)
+		temp |= XHCI_SCTX_0_HUB_SET(1);
 
-		pcs = &sc->sc_hw.devs[index].scratch_pc[i];
-		pgs = &sc->sc_hw.devs[index].scratch_pg[i];
+	pinp->ctx_slot.dwSctx0 = htole32(temp);
 
-		/* need to initialize the page cache */
-		pcs->tag_parent = sc->sc_bus.dma_parent_tag;
+	temp = XHCI_SCTX_1_RH_PORT_SET(rh_port);
 
-		if (usb_pc_alloc_mem(pcs, pgs, XHCI_PAGE_SIZE, XHCI_PAGE_SIZE))
-			failure = 1;
+	if (udev->hub != NULL)
+		temp |= XHCI_SCTX_1_NUM_PORTS_SET(udev->hub->nports);
 
-		if (failure == 0) {
-			usbd_get_page(pcs, 0, &buf_scp);
-			pdctx->ctx_sp_buf_ptr[i] = htole64((uint64_t)buf_scp.physaddr);
-		}
+	switch (udev->speed) {
+	case USB_SPEED_LOW:
+	case USB_SPEED_HIGH:
+	case USB_SPEED_FULL:
+	default:
+		temp |= XHCI_SCTX_1_MAX_EL_SET(sc->sc_exit_lat_max);
+		break;
 	}
-	if (failure)
-		goto error;
+
+	pinp->ctx_slot.dwSctx1 = htole32(temp);
 
-	usb_pc_cpu_flush(pcd);
+	temp = XHCI_SCTX_2_IRQ_TARGET_SET(0);
 
-	xhci_set_slot_scratch(sc, udev->device_index, addr,
-	    addr + (uintptr_t)&((struct xhci_dev_ctx *)0)->ctx_sp_buf_ptr[0]);
+	if ((udev->hub != NULL) &&
+	    (udev->speed == USB_SPEED_HIGH))
+		temp |= XHCI_SCTX_2_TT_THINK_TIME_SET(3);
 
-	return (0);
+	hubdev = udev->parent_hs_hub;
 
-error:
-	xhci_free_device_ext(udev);
+	if (hubdev != NULL) {
+		temp |= XHCI_SCTX_2_TT_HUB_SID_SET(hubdev->device_index);
+		temp |= XHCI_SCTX_2_TT_PORT_NUM_SET(hubdev->port_no);
+	}
 
-	return (USB_ERR_NOMEM);
-}
+	pinp->ctx_slot.dwSctx2 = htole32(temp);
 
-static void
-xhci_free_device_ext(struct usb_device *udev)
-{
-	struct xhci_softc *sc = XHCI_BUS2SC(udev->bus);
-	struct usb_page_cache *pcd;
-	struct usb_page_cache *pcs;
-	uint8_t index;
-	uint8_t i;
+	temp = XHCI_SCTX_3_DEV_ADDR_SET(udev->address) |
+	    XHCI_SCTX_3_SLOT_STATE_SET(3);
 
-	index = udev->device_index;
+	pinp->ctx_slot.dwSctx3 = htole32(temp);
 
-	pcd = &sc->sc_hw.devs[index].device_pc;
+	for (i = 0; i != sc->sc_noscratch; i++) {
 
-	usb_pc_free_mem(pcd);
+		pc = &sc->sc_hw.devs[index].scratch_pc[i];
 
-	for (i = 0; i != sc->sc_noscratch; i++) {
-		pcs = &sc->sc_hw.devs[index].scratch_pc[i];
+		usbd_get_page(pc, 0, &buf_scp);
 
-		usb_pc_free_mem(pcs);
+		pinp->ctx_sp_buf_ptr[i] = htole64((uint64_t)buf_scp.physaddr);
 	}
 
-	xhci_set_slot_scratch(sc, udev->device_index, 0, 0);
+	usb_pc_cpu_flush(pcinp);
+
+	xhci_set_slot_scratch(sc, udev->device_index, buf_dev.physaddr,
+	    buf_inp.physaddr + (uintptr_t)&((struct xhci_input_dev_ctx *)0)->ctx_sp_buf_ptr[0]);
+
+	XXX_cmd_config();
 }
 
 static usb_error_t
-xhci_alloc_endpoint_ext(struct xhci_softc *sc, uint8_t index, 
-    struct usb_endpoint_descriptor *edesc)
+xhci_alloc_device_ext(struct usb_device *udev)
 {
-	struct usb_page_search buf_res;
-	struct xhci_endpoint_ext *pepext;
+	struct xhci_softc *sc = XHCI_BUS2SC(udev->bus);
 	struct usb_page_cache *pc;
 	struct usb_page *pg;
-	uint8_t epno;
+	uint8_t i;
+	uint8_t index;
+
+	index = udev->device_index;
+
+	pc = &sc->sc_hw.devs[index].device_pc;
+	pg = &sc->sc_hw.devs[index].device_pg;
 
-	epno = edesc->bEndpointAddress;
+	/* need to initialize the page cache */
+	pc->tag_parent = sc->sc_bus.dma_parent_tag;
 
-	if ((edesc->bmAttributes & UE_XFERTYPE) == UE_CONTROL)
-		epno |= UE_DIR_IN;
+	if (usb_pc_alloc_mem(pc, pg, sizeof(struct xhci_dev_ctx), XHCI_PAGE_SIZE))
+		goto error;
 
-	epno = XHCI_EPNO2EPID(epno);
-	pc = &sc->sc_hw.devs[index].endpoint_pc[epno];
-	pg = &sc->sc_hw.devs[index].endpoint_pg[epno];
+	pc = &sc->sc_hw.devs[index].input_pc;
+	pg = &sc->sc_hw.devs[index].input_pg;
 
 	/* need to initialize the page cache */
 	pc->tag_parent = sc->sc_bus.dma_parent_tag;
 
-	if (usb_pc_alloc_mem(pc, pg, sizeof(*pepext), XHCI_TRB_ALIGN)) {
-		return (USB_ERR_NOMEM);     /* failure */
-	}
+	if (usb_pc_alloc_mem(pc, pg, 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;
 
-	/* the allocated memory is zeroed */
+	/* need to initialize the page cache */
+	pc->tag_parent = sc->sc_bus.dma_parent_tag;
 
-	usbd_get_page(pc, 0, &buf_res);
+	if (usb_pc_alloc_mem(pc, pg, sizeof(struct xhci_dev_endpoint_trbs), XHCI_PAGE_SIZE))
+		goto error;
 
-	pepext = buf_res.buffer;
+	for (i = 0; i != sc->sc_noscratch; i++) {
 
-	pepext->page_cache = pc;
-	pepext->trb_ccs = 1;
+		pc = &sc->sc_hw.devs[index].scratch_pc[i];
+		pg = &sc->sc_hw.devs[index].scratch_pg[i];
 
-	usb_pc_cpu_flush(pepext->page_cache);
+		/* need to initialize the page cache */
+		pc->tag_parent = sc->sc_bus.dma_parent_tag;
 
+		if (usb_pc_alloc_mem(pc, pg, XHCI_PAGE_SIZE, XHCI_PAGE_SIZE))
+			goto error;
+	}
 	return (0);
+
+error:
+	xhci_free_device_ext(udev);
+
+	return (USB_ERR_NOMEM);
 }
 
 static void
-xhci_free_endpoint_ext(struct xhci_softc *sc, uint8_t index, 
-    struct usb_endpoint_descriptor *edesc)
+xhci_free_device_ext(struct usb_device *udev)
 {
+	struct xhci_softc *sc = XHCI_BUS2SC(udev->bus);
 	struct usb_page_cache *pc;
-	uint8_t epno;
+	uint8_t index;
+	uint8_t i;
+
+	index = udev->device_index;
+
+	xhci_set_slot_scratch(sc, index, 0, 0);
+
+	pc = &sc->sc_hw.devs[index].device_pc;
+
+	usb_pc_free_mem(pc);
 
-	epno = edesc->bEndpointAddress;
+	pc = &sc->sc_hw.devs[index].input_pc;
 
-	if ((edesc->bmAttributes & UE_XFERTYPE) == UE_CONTROL)
-		epno |= UE_DIR_IN;
+	usb_pc_free_mem(pc);
 
-	epno = XHCI_EPNO2EPID(epno);
-	pc = &sc->sc_hw.devs[index].endpoint_pc[epno];
+	pc = &sc->sc_hw.devs[index].endpoint_pc;
 
 	usb_pc_free_mem(pc);
+
+	for (i = 0; i != sc->sc_noscratch; i++) {
+		pc = &sc->sc_hw.devs[index].scratch_pc[i];
+
+		usb_pc_free_mem(pc);
+	}
 }
 
-static void
-xhci_get_endpoint_ext(struct usb_xfer *xfer, struct usb_page_search *buf)
+static struct xhci_endpoint_ext *
+xhci_get_endpoint_ext(struct usb_xfer *xfer)
 {
 	struct xhci_softc *sc = XHCI_BUS2SC(xfer->xroot->bus);
+	struct xhci_endpoint_ext *pepext;
+	struct usb_page_cache *pc;
+	struct usb_page_search buf_res;
 	uint8_t epno;
 	uint8_t index;
 
@@ -1580,7 +1696,16 @@
 	epno = XHCI_EPNO2EPID(epno);
 	index = xfer->xroot->udev->device_index;
 
-	usbd_get_page(&sc->sc_hw.devs[index].endpoint_pc[epno], 0, buf);
+	pc = &sc->sc_hw.devs[index].endpoint_pc;
+
+	usbd_get_page(pc, (XHCI_MAX_TRANSFERS * sizeof(struct xhci_trb)) * epno, &buf_res);
+
+	pepext = &sc->sc_hw.devs[index].endp[epno];
+	pepext->page_cache = pc;
+	pepext->trb = buf_res.buffer;
+	pepext->physaddr = buf_res.physaddr;
+
+	return (pepext);
 }
 
 static void
@@ -1603,20 +1728,15 @@
 static void
 xhci_transfer_remove(struct usb_xfer *xfer, usb_error_t error)
 {
-	struct usb_page_search buf_res;
 	struct xhci_endpoint_ext *pepext;
 
 	if (xfer->flags_int.bandwidth_reclaimed) {
 		xfer->flags_int.bandwidth_reclaimed = 0;
 
-		xhci_get_endpoint_ext(xfer, &buf_res);
-
-		pepext = buf_res.buffer;
+		pepext = xhci_get_endpoint_ext(xfer);
 
 		pepext->trb_used--;
 
-		usb_pc_cpu_flush(pepext->page_cache);
-
 		if (error)
 			xhci_transfer_stop_endpoint(xfer);
 	}
@@ -1625,7 +1745,6 @@
 static usb_error_t
 xhci_transfer_insert(struct usb_xfer *xfer)
 {
-	struct usb_page_search buf_res;
 	struct xhci_td *td_first;
 	struct xhci_td *td_last;
 	struct xhci_endpoint_ext *pepext;
@@ -1638,12 +1757,11 @@
 	if (xfer->flags_int.bandwidth_reclaimed)
 		return (0);
 
-	xhci_get_endpoint_ext(xfer, &buf_res);
+	pepext = xhci_get_endpoint_ext(xfer);
 
 	td_first = xfer->td_transfer_first;
 	td_last = xfer->td_transfer_last;
-	pepext = buf_res.buffer;
-	addr = buf_res.physaddr;
+	addr = pepext->physaddr;
 
 	if (pepext->trb_used >= (XHCI_MAX_TRANSFERS - 1))
 		return (USB_ERR_NOMEM);
@@ -1694,7 +1812,7 @@
 
 	if (i == (XHCI_MAX_TRANSFERS - 1)) {
 
-		addr = buf_res.physaddr;
+		addr = pepext->physaddr;
 
 		/* update next pointer of link TRB */
 

==== //depot/projects/usb/src/sys/dev/usb/controller/xhci.h#11 (text+ko) ====

@@ -147,13 +147,22 @@
 	volatile uint32_t	dwInCtx7;
 };
 
+struct xhci_input_dev_ctx {
+	struct xhci_input_ctx	ctx_input;
+	struct xhci_slot_ctx	ctx_slot;
+	struct xhci_endp_ctx	ctx_ep[XHCI_MAX_ENDPOINTS - 1];
+	volatile uint64_t	ctx_sp_buf_ptr[XHCI_MAX_SCRATCHPADS];
+};
+
 struct xhci_dev_ctx {
 	struct xhci_slot_ctx	ctx_slot;
-	struct xhci_endp_ctx	ctx_ep0;
-	struct xhci_endp_ctx	ctx_epN[XHCI_MAX_ENDPOINTS - 2];
-	volatile uint64_t	ctx_sp_buf_ptr[XHCI_MAX_SCRATCHPADS];
+	struct xhci_endp_ctx	ctx_epN[XHCI_MAX_ENDPOINTS - 1];
 } __aligned(XHCI_DEV_CTX_ALIGN);
 
+struct xhci_dev_endpoint_trbs {
+	struct xhci_trb	trb[XHCI_MAX_ENDPOINTS][XHCI_MAX_TRANSFERS];
+};
+
 struct xhci_stream_ctx {
 	volatile uint64_t	qwSctx0;
 #define	XHCI_SCTX_0_DCS_GET(x)		((x) & 0x1)
@@ -333,28 +342,29 @@
 };
 
 struct xhci_endpoint_ext {
-
-	struct xhci_trb	trb[XHCI_MAX_TRANSFERS];
-
 	struct xhci_command ep_stop_cmd;
-
+	struct xhci_command ep_config_cmd;
+	struct xhci_trb *trb;
 	struct usb_page_cache *page_cache;
-
+	uint64_t physaddr;
 	uint8_t trb_used;
 	uint8_t trb_ccs;
 	uint8_t trb_index;
+	uint8_t trb_halted;
 };
 
 struct xhci_hw_dev {
 	struct usb_page_cache device_pc;
-	struct usb_page_cache endpoint_pc[XHCI_MAX_ENDPOINTS];
 	struct usb_page_cache input_pc;
+	struct usb_page_cache endpoint_pc;
 	struct usb_page_cache scratch_pc[XHCI_MAX_SCRATCHPADS];
 
 	struct usb_page device_pg;
-	struct usb_page endpoint_pg[XHCI_MAX_ENDPOINTS];
 	struct usb_page input_pg;
+	struct usb_page endpoint_pg;
 	struct usb_page scratch_pg[XHCI_MAX_SCRATCHPADS];
+
+	struct xhci_endpoint_ext endp[XHCI_MAX_ENDPOINTS];
 };
 
 struct xhci_hw_softc {



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