PERFORCE change 181738 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Mon Aug 2 18:22:10 UTC 2010
http://p4web.freebsd.org/@@181738?ac=10
Change 181738 by hselasky at 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 {
More information about the p4-projects
mailing list