version 1.28.2.4, 2014/12/02 09:00:34 |
version 1.28.2.5, 2014/12/03 12:52:07 |
Line 612 xhci_init(struct xhci_softc *sc) |
|
Line 612 xhci_init(struct xhci_softc *sc) |
|
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
|
|
/* XXX Low/Full/High speeds for now */ |
/* XXX Low/Full/High speeds for now */ |
sc->sc_bus.usbrev = USBREV_2_0; |
sc->sc_bus.ub_revision = USBREV_2_0; |
sc->sc_bus.usedma = true; |
sc->sc_bus.ub_usedma = true; |
|
|
cap = xhci_read_4(sc, XHCI_CAPLENGTH); |
cap = xhci_read_4(sc, XHCI_CAPLENGTH); |
caplength = XHCI_CAP_CAPLENGTH(cap); |
caplength = XHCI_CAP_CAPLENGTH(cap); |
Line 812 xhci_init(struct xhci_softc *sc) |
|
Line 812 xhci_init(struct xhci_softc *sc) |
|
usbd_errstr(err), |
usbd_errstr(err), |
(uintmax_t)DMAADDR(&sc->sc_eventst_dma, 0), |
(uintmax_t)DMAADDR(&sc->sc_eventst_dma, 0), |
KERNADDR(&sc->sc_eventst_dma, 0), |
KERNADDR(&sc->sc_eventst_dma, 0), |
sc->sc_eventst_dma.block->size); |
sc->sc_eventst_dma.udma_block->size); |
|
|
dma = &sc->sc_dcbaa_dma; |
dma = &sc->sc_dcbaa_dma; |
size = (1 + sc->sc_maxslots) * sizeof(uint64_t); |
size = (1 + sc->sc_maxslots) * sizeof(uint64_t); |
Line 833 xhci_init(struct xhci_softc *sc) |
|
Line 833 xhci_init(struct xhci_softc *sc) |
|
usbd_errstr(err), |
usbd_errstr(err), |
(uintmax_t)DMAADDR(&sc->sc_dcbaa_dma, 0), |
(uintmax_t)DMAADDR(&sc->sc_dcbaa_dma, 0), |
KERNADDR(&sc->sc_dcbaa_dma, 0), |
KERNADDR(&sc->sc_dcbaa_dma, 0), |
sc->sc_dcbaa_dma.block->size); |
sc->sc_dcbaa_dma.udma_block->size); |
|
|
sc->sc_slots = kmem_zalloc(sizeof(*sc->sc_slots) * sc->sc_maxslots, |
sc->sc_slots = kmem_zalloc(sizeof(*sc->sc_slots) * sc->sc_maxslots, |
KM_SLEEP); |
KM_SLEEP); |
Line 876 xhci_init(struct xhci_softc *sc) |
|
Line 876 xhci_init(struct xhci_softc *sc) |
|
"xhcixfer", NULL, IPL_USB, NULL, NULL, NULL); |
"xhcixfer", NULL, IPL_USB, NULL, NULL, NULL); |
|
|
/* Set up the bus struct. */ |
/* Set up the bus struct. */ |
sc->sc_bus.methods = &xhci_bus_methods; |
sc->sc_bus.ub_methods = &xhci_bus_methods; |
sc->sc_bus.pipe_size = sizeof(struct xhci_pipe); |
sc->sc_bus.ub_pipesize = sizeof(struct xhci_pipe); |
|
|
return USBD_NORMAL_COMPLETION; |
return USBD_NORMAL_COMPLETION; |
} |
} |
Line 899 xhci_intr(void *v) |
|
Line 899 xhci_intr(void *v) |
|
goto done; |
goto done; |
|
|
/* If we get an interrupt while polling, then just ignore it. */ |
/* If we get an interrupt while polling, then just ignore it. */ |
if (sc->sc_bus.use_polling) { |
if (sc->sc_bus.ub_usepolling) { |
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
DPRINTFN(16, "ignored interrupt while polling", 0, 0, 0, 0); |
DPRINTFN(16, "ignored interrupt while polling", 0, 0, 0, 0); |
#endif |
#endif |
Line 951 xhci_intr1(struct xhci_softc * const sc) |
|
Line 951 xhci_intr1(struct xhci_softc * const sc) |
|
static usbd_status |
static usbd_status |
xhci_configure_endpoint(usbd_pipe_handle pipe) |
xhci_configure_endpoint(usbd_pipe_handle pipe) |
{ |
{ |
struct xhci_softc * const sc = pipe->device->bus->hci_private; |
struct xhci_softc * const sc = pipe->up_dev->ud_bus->ub_hcpriv; |
struct xhci_slot * const xs = pipe->device->hci_private; |
struct xhci_slot * const xs = pipe->up_dev->ud_hcpriv; |
const u_int dci = xhci_ep_get_dci(pipe->endpoint->edesc); |
const u_int dci = xhci_ep_get_dci(pipe->up_endpoint->ue_edesc); |
usb_endpoint_descriptor_t * const ed = pipe->endpoint->edesc; |
usb_endpoint_descriptor_t * const ed = pipe->up_endpoint->ue_edesc; |
const uint8_t xfertype = UE_GET_XFERTYPE(ed->bmAttributes); |
const uint8_t xfertype = UE_GET_XFERTYPE(ed->bmAttributes); |
struct xhci_trb trb; |
struct xhci_trb trb; |
usbd_status err; |
usbd_status err; |
Line 986 xhci_configure_endpoint(usbd_pipe_handle |
|
Line 986 xhci_configure_endpoint(usbd_pipe_handle |
|
); |
); |
cp[1] = htole32( |
cp[1] = htole32( |
XHCI_EPCTX_1_CERR_SET(3) | |
XHCI_EPCTX_1_CERR_SET(3) | |
XHCI_EPCTX_1_EPTYPE_SET(xhci_ep_get_type(pipe->endpoint->edesc)) | |
XHCI_EPCTX_1_EPTYPE_SET(xhci_ep_get_type(pipe->up_endpoint->ue_edesc)) | |
XHCI_EPCTX_1_MAXB_SET(0) | |
XHCI_EPCTX_1_MAXB_SET(0) | |
XHCI_EPCTX_1_MAXP_SIZE_SET(8) /* XXX */ |
XHCI_EPCTX_1_MAXP_SIZE_SET(8) /* XXX */ |
); |
); |
Line 997 xhci_configure_endpoint(usbd_pipe_handle |
|
Line 997 xhci_configure_endpoint(usbd_pipe_handle |
|
cp[0] = htole32(0); |
cp[0] = htole32(0); |
cp[1] = htole32( |
cp[1] = htole32( |
XHCI_EPCTX_1_CERR_SET(3) | |
XHCI_EPCTX_1_CERR_SET(3) | |
XHCI_EPCTX_1_EPTYPE_SET(xhci_ep_get_type(pipe->endpoint->edesc)) | |
XHCI_EPCTX_1_EPTYPE_SET(xhci_ep_get_type(pipe->up_endpoint->ue_edesc)) | |
XHCI_EPCTX_1_MAXB_SET(0) | |
XHCI_EPCTX_1_MAXB_SET(0) | |
XHCI_EPCTX_1_MAXP_SIZE_SET(512) /* XXX */ |
XHCI_EPCTX_1_MAXP_SIZE_SET(512) /* XXX */ |
); |
); |
Line 1031 static usbd_status |
|
Line 1031 static usbd_status |
|
xhci_unconfigure_endpoint(usbd_pipe_handle pipe) |
xhci_unconfigure_endpoint(usbd_pipe_handle pipe) |
{ |
{ |
#ifdef USB_DEBUG |
#ifdef USB_DEBUG |
struct xhci_slot * const xs = pipe->device->hci_private; |
struct xhci_slot * const xs = pipe->up_dev->ud_hcpriv; |
#endif |
#endif |
|
|
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
Line 1043 xhci_unconfigure_endpoint(usbd_pipe_hand |
|
Line 1043 xhci_unconfigure_endpoint(usbd_pipe_hand |
|
static usbd_status |
static usbd_status |
xhci_reset_endpoint(usbd_pipe_handle pipe) |
xhci_reset_endpoint(usbd_pipe_handle pipe) |
{ |
{ |
struct xhci_softc * const sc = pipe->device->bus->hci_private; |
struct xhci_softc * const sc = pipe->up_dev->ud_bus->ub_hcpriv; |
struct xhci_slot * const xs = pipe->device->hci_private; |
struct xhci_slot * const xs = pipe->up_dev->ud_hcpriv; |
const u_int dci = xhci_ep_get_dci(pipe->endpoint->edesc); |
const u_int dci = xhci_ep_get_dci(pipe->up_endpoint->ue_edesc); |
struct xhci_trb trb; |
struct xhci_trb trb; |
usbd_status err; |
usbd_status err; |
|
|
Line 1067 xhci_reset_endpoint(usbd_pipe_handle pip |
|
Line 1067 xhci_reset_endpoint(usbd_pipe_handle pip |
|
static usbd_status |
static usbd_status |
xhci_stop_endpoint(usbd_pipe_handle pipe) |
xhci_stop_endpoint(usbd_pipe_handle pipe) |
{ |
{ |
struct xhci_softc * const sc = pipe->device->bus->hci_private; |
struct xhci_softc * const sc = pipe->up_dev->ud_bus->ub_hcpriv; |
struct xhci_slot * const xs = pipe->device->hci_private; |
struct xhci_slot * const xs = pipe->up_dev->ud_hcpriv; |
struct xhci_trb trb; |
struct xhci_trb trb; |
usbd_status err; |
usbd_status err; |
const u_int dci = xhci_ep_get_dci(pipe->endpoint->edesc); |
const u_int dci = xhci_ep_get_dci(pipe->up_endpoint->ue_edesc); |
|
|
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
DPRINTFN(4, "dci %u", dci, 0, 0, 0); |
DPRINTFN(4, "dci %u", dci, 0, 0, 0); |
Line 1091 xhci_stop_endpoint(usbd_pipe_handle pipe |
|
Line 1091 xhci_stop_endpoint(usbd_pipe_handle pipe |
|
static usbd_status |
static usbd_status |
xhci_set_dequeue(usbd_pipe_handle pipe) |
xhci_set_dequeue(usbd_pipe_handle pipe) |
{ |
{ |
struct xhci_softc * const sc = pipe->device->bus->hci_private; |
struct xhci_softc * const sc = pipe->up_dev->ud_bus->ub_hcpriv; |
struct xhci_slot * const xs = pipe->device->hci_private; |
struct xhci_slot * const xs = pipe->up_dev->ud_hcpriv; |
const u_int dci = xhci_ep_get_dci(pipe->endpoint->edesc); |
const u_int dci = xhci_ep_get_dci(pipe->up_endpoint->ue_edesc); |
struct xhci_ring * const xr = &xs->xs_ep[dci].xe_tr; |
struct xhci_ring * const xr = &xs->xs_ep[dci].xe_tr; |
struct xhci_trb trb; |
struct xhci_trb trb; |
usbd_status err; |
usbd_status err; |
Line 1122 xhci_set_dequeue(usbd_pipe_handle pipe) |
|
Line 1122 xhci_set_dequeue(usbd_pipe_handle pipe) |
|
static usbd_status |
static usbd_status |
xhci_open(usbd_pipe_handle pipe) |
xhci_open(usbd_pipe_handle pipe) |
{ |
{ |
usbd_device_handle const dev = pipe->device; |
usbd_device_handle const dev = pipe->up_dev; |
struct xhci_softc * const sc = dev->bus->hci_private; |
struct xhci_softc * const sc = dev->ud_bus->ub_hcpriv; |
usb_endpoint_descriptor_t * const ed = pipe->endpoint->edesc; |
usb_endpoint_descriptor_t * const ed = pipe->up_endpoint->ue_edesc; |
const uint8_t xfertype = UE_GET_XFERTYPE(ed->bmAttributes); |
const uint8_t xfertype = UE_GET_XFERTYPE(ed->bmAttributes); |
|
|
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
DPRINTFN(1, "addr %d depth %d port %d speed %d", |
DPRINTFN(1, "addr %d depth %d port %d speed %d", |
dev->address, dev->depth, dev->powersrc->portno, dev->speed); |
dev->ud_addr, dev->ud_depth, dev->ud_powersrc->up_portno, dev->ud_speed); |
|
|
if (sc->sc_dying) |
if (sc->sc_dying) |
return USBD_IOERROR; |
return USBD_IOERROR; |
|
|
/* Root Hub */ |
/* Root Hub */ |
if (dev->depth == 0 && dev->powersrc->portno == 0 && |
if (dev->ud_depth == 0 && dev->ud_powersrc->up_portno == 0 && |
dev->speed != USB_SPEED_SUPER) { |
dev->ud_speed != USB_SPEED_SUPER) { |
switch (ed->bEndpointAddress) { |
switch (ed->bEndpointAddress) { |
case USB_CONTROL_ENDPOINT: |
case USB_CONTROL_ENDPOINT: |
pipe->methods = &xhci_root_ctrl_methods; |
pipe->up_methods = &xhci_root_ctrl_methods; |
break; |
break; |
case UE_DIR_IN | XHCI_INTR_ENDPT: |
case UE_DIR_IN | XHCI_INTR_ENDPT: |
pipe->methods = &xhci_root_intr_methods; |
pipe->up_methods = &xhci_root_intr_methods; |
break; |
break; |
default: |
default: |
pipe->methods = NULL; |
pipe->up_methods = NULL; |
DPRINTFN(0, "bad bEndpointAddress 0x%02x", |
DPRINTFN(0, "bad bEndpointAddress 0x%02x", |
ed->bEndpointAddress, 0, 0, 0); |
ed->bEndpointAddress, 0, 0, 0); |
return USBD_INVAL; |
return USBD_INVAL; |
Line 1155 xhci_open(usbd_pipe_handle pipe) |
|
Line 1155 xhci_open(usbd_pipe_handle pipe) |
|
|
|
switch (xfertype) { |
switch (xfertype) { |
case UE_CONTROL: |
case UE_CONTROL: |
pipe->methods = &xhci_device_ctrl_methods; |
pipe->up_methods = &xhci_device_ctrl_methods; |
break; |
break; |
case UE_ISOCHRONOUS: |
case UE_ISOCHRONOUS: |
pipe->methods = &xhci_device_isoc_methods; |
pipe->up_methods = &xhci_device_isoc_methods; |
return USBD_INVAL; |
return USBD_INVAL; |
break; |
break; |
case UE_BULK: |
case UE_BULK: |
pipe->methods = &xhci_device_bulk_methods; |
pipe->up_methods = &xhci_device_bulk_methods; |
break; |
break; |
case UE_INTERRUPT: |
case UE_INTERRUPT: |
pipe->methods = &xhci_device_intr_methods; |
pipe->up_methods = &xhci_device_intr_methods; |
break; |
break; |
default: |
default: |
return USBD_IOERROR; |
return USBD_IOERROR; |
Line 1198 xhci_rhpsc(struct xhci_softc * const sc, |
|
Line 1198 xhci_rhpsc(struct xhci_softc * const sc, |
|
port += 1; |
port += 1; |
DPRINTFN(4, "hs port %u status change", port, 0, 0, 0); |
DPRINTFN(4, "hs port %u status change", port, 0, 0, 0); |
|
|
p = xfer->buf; |
p = xfer->ux_buf; |
memset(p, 0, xfer->length); |
memset(p, 0, xfer->ux_length); |
p[port/NBBY] |= 1 << (port%NBBY); |
p[port/NBBY] |= 1 << (port%NBBY); |
xfer->actlen = xfer->length; |
xfer->ux_actlen = xfer->ux_length; |
xfer->status = USBD_NORMAL_COMPLETION; |
xfer->ux_status = USBD_NORMAL_COMPLETION; |
usb_transfer_complete(xfer); |
usb_transfer_complete(xfer); |
} |
} |
|
|
Line 1252 xhci_handle_event(struct xhci_softc * co |
|
Line 1252 xhci_handle_event(struct xhci_softc * co |
|
trb_0, XHCI_TRB_2_REM_GET(trb_2), |
trb_0, XHCI_TRB_2_REM_GET(trb_2), |
XHCI_TRB_2_ERROR_GET(trb_2), 0); |
XHCI_TRB_2_ERROR_GET(trb_2), 0); |
if ((trb_0 & 0x3) == 0x3) { |
if ((trb_0 & 0x3) == 0x3) { |
xfer->actlen = XHCI_TRB_2_REM_GET(trb_2); |
xfer->ux_actlen = XHCI_TRB_2_REM_GET(trb_2); |
} |
} |
} |
} |
|
|
if (XHCI_TRB_2_ERROR_GET(trb_2) == |
if (XHCI_TRB_2_ERROR_GET(trb_2) == |
XHCI_TRB_ERROR_SUCCESS) { |
XHCI_TRB_ERROR_SUCCESS) { |
xfer->actlen = xfer->length - XHCI_TRB_2_REM_GET(trb_2); |
xfer->ux_actlen = xfer->ux_length - XHCI_TRB_2_REM_GET(trb_2); |
err = USBD_NORMAL_COMPLETION; |
err = USBD_NORMAL_COMPLETION; |
} else if (XHCI_TRB_2_ERROR_GET(trb_2) == |
} else if (XHCI_TRB_2_ERROR_GET(trb_2) == |
XHCI_TRB_ERROR_SHORT_PKT) { |
XHCI_TRB_ERROR_SHORT_PKT) { |
xfer->actlen = xfer->length - XHCI_TRB_2_REM_GET(trb_2); |
xfer->ux_actlen = xfer->ux_length - XHCI_TRB_2_REM_GET(trb_2); |
err = USBD_NORMAL_COMPLETION; |
err = USBD_NORMAL_COMPLETION; |
} else if (XHCI_TRB_2_ERROR_GET(trb_2) == |
} else if (XHCI_TRB_2_ERROR_GET(trb_2) == |
XHCI_TRB_ERROR_STALL) { |
XHCI_TRB_ERROR_STALL) { |
Line 1273 xhci_handle_event(struct xhci_softc * co |
|
Line 1273 xhci_handle_event(struct xhci_softc * co |
|
} else { |
} else { |
err = USBD_IOERROR; |
err = USBD_IOERROR; |
} |
} |
xfer->status = err; |
xfer->ux_status = err; |
|
|
//mutex_enter(&sc->sc_lock); /* XXX ??? */ |
//mutex_enter(&sc->sc_lock); /* XXX ??? */ |
if ((trb_3 & XHCI_TRB_3_ED_BIT) != 0) { |
if ((trb_3 & XHCI_TRB_3_ED_BIT) != 0) { |
|
|
xhci_softintr(void *v) |
xhci_softintr(void *v) |
{ |
{ |
struct usbd_bus * const bus = v; |
struct usbd_bus * const bus = v; |
struct xhci_softc * const sc = bus->hci_private; |
struct xhci_softc * const sc = bus->ub_hcpriv; |
struct xhci_ring * const er = &sc->sc_er; |
struct xhci_ring * const er = &sc->sc_er; |
struct xhci_trb *trb; |
struct xhci_trb *trb; |
int i, j, k; |
int i, j, k; |
Line 1361 xhci_softintr(void *v) |
|
Line 1361 xhci_softintr(void *v) |
|
static void |
static void |
xhci_poll(struct usbd_bus *bus) |
xhci_poll(struct usbd_bus *bus) |
{ |
{ |
struct xhci_softc * const sc = bus->hci_private; |
struct xhci_softc * const sc = bus->ub_hcpriv; |
|
|
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
|
|
Line 1375 xhci_poll(struct usbd_bus *bus) |
|
Line 1375 xhci_poll(struct usbd_bus *bus) |
|
static usbd_xfer_handle |
static usbd_xfer_handle |
xhci_allocx(struct usbd_bus *bus) |
xhci_allocx(struct usbd_bus *bus) |
{ |
{ |
struct xhci_softc * const sc = bus->hci_private; |
struct xhci_softc * const sc = bus->ub_hcpriv; |
usbd_xfer_handle xfer; |
usbd_xfer_handle xfer; |
|
|
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
Line 1384 xhci_allocx(struct usbd_bus *bus) |
|
Line 1384 xhci_allocx(struct usbd_bus *bus) |
|
if (xfer != NULL) { |
if (xfer != NULL) { |
memset(xfer, 0, sizeof(struct xhci_xfer)); |
memset(xfer, 0, sizeof(struct xhci_xfer)); |
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
xfer->busy_free = XFER_BUSY; |
xfer->ux_state = XFER_BUSY; |
#endif |
#endif |
} |
} |
|
|
Line 1394 xhci_allocx(struct usbd_bus *bus) |
|
Line 1394 xhci_allocx(struct usbd_bus *bus) |
|
static void |
static void |
xhci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer) |
xhci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer) |
{ |
{ |
struct xhci_softc * const sc = bus->hci_private; |
struct xhci_softc * const sc = bus->ub_hcpriv; |
|
|
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
|
|
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
if (xfer->busy_free != XFER_BUSY) { |
if (xfer->ux_state != XFER_BUSY) { |
DPRINTFN(0, "xfer=%p not busy, 0x%08x", |
DPRINTFN(0, "xfer=%p not busy, 0x%08x", |
xfer, xfer->busy_free, 0, 0); |
xfer, xfer->ux_state, 0, 0); |
} |
} |
xfer->busy_free = XFER_FREE; |
xfer->ux_state = XFER_FREE; |
#endif |
#endif |
pool_cache_put(sc->sc_xferpool, xfer); |
pool_cache_put(sc->sc_xferpool, xfer); |
} |
} |
Line 1411 xhci_freex(struct usbd_bus *bus, usbd_xf |
|
Line 1411 xhci_freex(struct usbd_bus *bus, usbd_xf |
|
static void |
static void |
xhci_get_lock(struct usbd_bus *bus, kmutex_t **lock) |
xhci_get_lock(struct usbd_bus *bus, kmutex_t **lock) |
{ |
{ |
struct xhci_softc * const sc = bus->hci_private; |
struct xhci_softc * const sc = bus->ub_hcpriv; |
|
|
*lock = &sc->sc_lock; |
*lock = &sc->sc_lock; |
} |
} |
Line 1422 static usbd_status |
|
Line 1422 static usbd_status |
|
xhci_new_device(device_t parent, usbd_bus_handle bus, int depth, |
xhci_new_device(device_t parent, usbd_bus_handle bus, int depth, |
int speed, int port, struct usbd_port *up) |
int speed, int port, struct usbd_port *up) |
{ |
{ |
struct xhci_softc * const sc = bus->hci_private; |
struct xhci_softc * const sc = bus->ub_hcpriv; |
usbd_device_handle dev; |
usbd_device_handle dev; |
usbd_status err; |
usbd_status err; |
usb_device_descriptor_t *dd; |
usb_device_descriptor_t *dd; |
Line 1436 xhci_new_device(device_t parent, usbd_bu |
|
Line 1436 xhci_new_device(device_t parent, usbd_bu |
|
|
|
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
DPRINTFN(4, "port=%d depth=%d speed=%d upport %d", |
DPRINTFN(4, "port=%d depth=%d speed=%d upport %d", |
port, depth, speed, up->portno); |
port, depth, speed, up->up_portno); |
|
|
dev = malloc(sizeof *dev, M_USB, M_NOWAIT|M_ZERO); |
dev = malloc(sizeof *dev, M_USB, M_NOWAIT|M_ZERO); |
if (dev == NULL) |
if (dev == NULL) |
return USBD_NOMEM; |
return USBD_NOMEM; |
|
|
dev->bus = bus; |
dev->ud_bus = bus; |
|
|
/* Set up default endpoint handle. */ |
/* Set up default endpoint handle. */ |
dev->def_ep.edesc = &dev->def_ep_desc; |
dev->ud_ep0.ue_edesc = &dev->ud_ep0desc; |
|
|
/* Set up default endpoint descriptor. */ |
/* Set up default endpoint descriptor. */ |
dev->def_ep_desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE; |
dev->ud_ep0desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE; |
dev->def_ep_desc.bDescriptorType = UDESC_ENDPOINT; |
dev->ud_ep0desc.bDescriptorType = UDESC_ENDPOINT; |
dev->def_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT; |
dev->ud_ep0desc.bEndpointAddress = USB_CONTROL_ENDPOINT; |
dev->def_ep_desc.bmAttributes = UE_CONTROL; |
dev->ud_ep0desc.bmAttributes = UE_CONTROL; |
/* XXX */ |
/* XXX */ |
if (speed == USB_SPEED_LOW) |
if (speed == USB_SPEED_LOW) |
USETW(dev->def_ep_desc.wMaxPacketSize, USB_MAX_IPACKET); |
USETW(dev->ud_ep0desc.wMaxPacketSize, USB_MAX_IPACKET); |
else |
else |
USETW(dev->def_ep_desc.wMaxPacketSize, 64); |
USETW(dev->ud_ep0desc.wMaxPacketSize, 64); |
dev->def_ep_desc.bInterval = 0; |
dev->ud_ep0desc.bInterval = 0; |
|
|
/* doesn't matter, just don't let it uninitialized */ |
/* doesn't matter, just don't let it uninitialized */ |
dev->def_ep.datatoggle = 0; |
dev->ud_ep0.ue_toggle = 0; |
|
|
DPRINTFN(4, "up %p portno %d", up, up->portno, 0, 0); |
DPRINTFN(4, "up %p portno %d", up, up->up_portno, 0, 0); |
|
|
dev->quirks = &usbd_no_quirk; |
dev->ud_quirks = &usbd_no_quirk; |
dev->address = 0; |
dev->ud_addr = 0; |
dev->ddesc.bMaxPacketSize = 0; |
dev->ud_ddesc.bMaxPacketSize = 0; |
dev->depth = depth; |
dev->ud_depth = depth; |
dev->powersrc = up; |
dev->ud_powersrc = up; |
dev->myhub = up->parent; |
dev->ud_myhub = up->up_parent; |
|
|
up->device = dev; |
up->up_dev = dev; |
|
|
/* Locate root hub port */ |
/* Locate root hub port */ |
for (adev = dev, hub = dev; |
for (adev = dev, hub = dev; |
hub != NULL; |
hub != NULL; |
adev = hub, hub = hub->myhub) { |
adev = hub, hub = hub->ud_myhub) { |
DPRINTFN(4, "hub %p", hub, 0, 0, 0); |
DPRINTFN(4, "hub %p", hub, 0, 0, 0); |
} |
} |
DPRINTFN(4, "hub %p", hub, 0, 0, 0); |
DPRINTFN(4, "hub %p", hub, 0, 0, 0); |
|
|
if (hub != NULL) { |
if (hub != NULL) { |
for (int p = 0; p < hub->hub->hubdesc.bNbrPorts; p++) { |
for (int p = 0; p < hub->ud_hub->uh_hubdesc.bNbrPorts; p++) { |
if (hub->hub->ports[p].device == adev) { |
if (hub->ud_hub->uh_ports[p].up_dev == adev) { |
rhport = p; |
rhport = p; |
} |
} |
} |
} |
Line 1497 xhci_new_device(device_t parent, usbd_bu |
|
Line 1497 xhci_new_device(device_t parent, usbd_bu |
|
} |
} |
DPRINTFN(4, "rhport %d", rhport, 0, 0, 0); |
DPRINTFN(4, "rhport %d", rhport, 0, 0, 0); |
|
|
dev->speed = speed; |
dev->ud_speed = speed; |
dev->langid = USBD_NOLANG; |
dev->ud_langid = USBD_NOLANG; |
dev->cookie.cookie = ++usb_cookie_no; |
dev->ud_cookie.cookie = ++usb_cookie_no; |
|
|
/* Establish the default pipe. */ |
/* Establish the default pipe. */ |
err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL, |
err = usbd_setup_pipe(dev, 0, &dev->ud_ep0, USBD_DEFAULT_INTERVAL, |
&dev->default_pipe); |
&dev->ud_pipe0); |
if (err) { |
if (err) { |
usbd_remove_device(dev, up); |
usbd_remove_device(dev, up); |
return (err); |
return (err); |
} |
} |
|
|
dd = &dev->ddesc; |
dd = &dev->ud_ddesc; |
|
|
if ((depth == 0) && (port == 0)) { |
if ((depth == 0) && (port == 0)) { |
KASSERT(bus->devices[dev->address] == NULL); |
KASSERT(bus->ub_devices[dev->ud_addr] == NULL); |
bus->devices[dev->address] = dev; |
bus->ub_devices[dev->ud_addr] = dev; |
err = usbd_get_initial_ddesc(dev, dd); |
err = usbd_get_initial_ddesc(dev, dd); |
if (err) |
if (err) |
return err; |
return err; |
Line 1528 xhci_new_device(device_t parent, usbd_bu |
|
Line 1528 xhci_new_device(device_t parent, usbd_bu |
|
if (err) |
if (err) |
return err; |
return err; |
xs = &sc->sc_slots[slot]; |
xs = &sc->sc_slots[slot]; |
dev->hci_private = xs; |
dev->ud_hcpriv = xs; |
cp = xhci_slot_get_dcv(sc, xs, XHCI_DCI_SLOT); |
cp = xhci_slot_get_dcv(sc, xs, XHCI_DCI_SLOT); |
//hexdump("slot context", cp, sc->sc_ctxsz); |
//hexdump("slot context", cp, sc->sc_ctxsz); |
addr = XHCI_SCTX_3_DEV_ADDR_GET(cp[3]); |
addr = XHCI_SCTX_3_DEV_ADDR_GET(cp[3]); |
Line 1536 xhci_new_device(device_t parent, usbd_bu |
|
Line 1536 xhci_new_device(device_t parent, usbd_bu |
|
/* XXX ensure we know when the hardware does something |
/* XXX ensure we know when the hardware does something |
we can't yet cope with */ |
we can't yet cope with */ |
KASSERT(addr >= 1 && addr <= 127); |
KASSERT(addr >= 1 && addr <= 127); |
dev->address = addr; |
dev->ud_addr = addr; |
/* XXX dev->address not necessarily unique on bus */ |
/* XXX dev->ud_addr not necessarily unique on bus */ |
KASSERT(bus->devices[dev->address] == NULL); |
KASSERT(bus->ub_devices[dev->ud_addr] == NULL); |
bus->devices[dev->address] = dev; |
bus->ub_devices[dev->ud_addr] = dev; |
|
|
err = usbd_get_initial_ddesc(dev, dd); |
err = usbd_get_initial_ddesc(dev, dd); |
if (err) |
if (err) |
return err; |
return err; |
/* 4.8.2.1 */ |
/* 4.8.2.1 */ |
if (speed == USB_SPEED_SUPER) |
if (speed == USB_SPEED_SUPER) |
USETW(dev->def_ep_desc.wMaxPacketSize, |
USETW(dev->ud_ep0desc.wMaxPacketSize, |
(1 << dd->bMaxPacketSize)); |
(1 << dd->bMaxPacketSize)); |
else |
else |
USETW(dev->def_ep_desc.wMaxPacketSize, |
USETW(dev->ud_ep0desc.wMaxPacketSize, |
dd->bMaxPacketSize); |
dd->bMaxPacketSize); |
DPRINTFN(4, "bMaxPacketSize %u", dd->bMaxPacketSize, 0, 0, 0); |
DPRINTFN(4, "bMaxPacketSize %u", dd->bMaxPacketSize, 0, 0, 0); |
xhci_update_ep0_mps(sc, xs, |
xhci_update_ep0_mps(sc, xs, |
UGETW(dev->def_ep_desc.wMaxPacketSize)); |
UGETW(dev->ud_ep0desc.wMaxPacketSize)); |
err = usbd_reload_device_desc(dev); |
err = usbd_reload_device_desc(dev); |
if (err) |
if (err) |
return err; |
return err; |
|
|
usbd_kill_pipe(dev->default_pipe); |
usbd_kill_pipe(dev->ud_pipe0); |
err = usbd_setup_pipe(dev, 0, &dev->def_ep, |
err = usbd_setup_pipe(dev, 0, &dev->ud_ep0, |
USBD_DEFAULT_INTERVAL, &dev->default_pipe); |
USBD_DEFAULT_INTERVAL, &dev->ud_pipe0); |
} |
} |
|
|
DPRINTFN(1, "adding unit addr=%d, rev=%02x,", |
DPRINTFN(1, "adding unit addr=%d, rev=%02x,", |
dev->address, UGETW(dd->bcdUSB), 0, 0); |
dev->ud_addr, UGETW(dd->bcdUSB), 0, 0); |
DPRINTFN(1, " class=%d, subclass=%d, protocol=%d,", |
DPRINTFN(1, " class=%d, subclass=%d, protocol=%d,", |
dd->bDeviceClass, dd->bDeviceSubClass, |
dd->bDeviceClass, dd->bDeviceSubClass, |
dd->bDeviceProtocol, 0); |
dd->bDeviceProtocol, 0); |
DPRINTFN(1, " mps=%d, len=%d, noconf=%d, speed=%d", |
DPRINTFN(1, " mps=%d, len=%d, noconf=%d, speed=%d", |
dd->bMaxPacketSize, dd->bLength, dd->bNumConfigurations, |
dd->bMaxPacketSize, dd->bLength, dd->bNumConfigurations, |
dev->speed); |
dev->ud_speed); |
|
|
usbd_add_dev_event(USB_EVENT_DEVICE_ATTACH, dev); |
usbd_add_dev_event(USB_EVENT_DEVICE_ATTACH, dev); |
|
|
if ((depth == 0) && (port == 0)) { |
if ((depth == 0) && (port == 0)) { |
usbd_attach_roothub(parent, dev); |
usbd_attach_roothub(parent, dev); |
DPRINTFN(1, "root_hub %p", bus->root_hub, 0, 0, 0); |
DPRINTFN(1, "root_hub %p", bus->ub_roothub, 0, 0, 0); |
return USBD_NORMAL_COMPLETION; |
return USBD_NORMAL_COMPLETION; |
} |
} |
|
|
|
|
err = usbd_probe_and_attach(parent, dev, port, dev->address); |
err = usbd_probe_and_attach(parent, dev, port, dev->ud_addr); |
if (err) { |
if (err) { |
usbd_remove_device(dev, up); |
usbd_remove_device(dev, up); |
return (err); |
return (err); |
Line 2075 static const usb_hub_descriptor_t xhci_h |
|
Line 2075 static const usb_hub_descriptor_t xhci_h |
|
static usbd_status |
static usbd_status |
xhci_root_ctrl_transfer(usbd_xfer_handle xfer) |
xhci_root_ctrl_transfer(usbd_xfer_handle xfer) |
{ |
{ |
struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; |
struct xhci_softc * const sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv; |
usbd_status err; |
usbd_status err; |
|
|
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
Line 2088 xhci_root_ctrl_transfer(usbd_xfer_handle |
|
Line 2088 xhci_root_ctrl_transfer(usbd_xfer_handle |
|
return err; |
return err; |
|
|
/* Pipe isn't running, start first */ |
/* Pipe isn't running, start first */ |
return (xhci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); |
return (xhci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue))); |
} |
} |
|
|
static usbd_status |
static usbd_status |
xhci_root_ctrl_start(usbd_xfer_handle xfer) |
xhci_root_ctrl_start(usbd_xfer_handle xfer) |
{ |
{ |
struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; |
struct xhci_softc * const sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv; |
usb_port_status_t ps; |
usb_port_status_t ps; |
usb_device_request_t *req; |
usb_device_request_t *req; |
void *buf = NULL; |
void *buf = NULL; |
Line 2110 xhci_root_ctrl_start(usbd_xfer_handle xf |
|
Line 2110 xhci_root_ctrl_start(usbd_xfer_handle xf |
|
if (sc->sc_dying) |
if (sc->sc_dying) |
return USBD_IOERROR; |
return USBD_IOERROR; |
|
|
req = &xfer->request; |
req = &xfer->ux_request; |
|
|
value = UGETW(req->wValue); |
value = UGETW(req->wValue); |
index = UGETW(req->wIndex); |
index = UGETW(req->wIndex); |
len = UGETW(req->wLength); |
len = UGETW(req->wLength); |
|
|
if (len != 0) |
if (len != 0) |
buf = xfer->buf; |
buf = xfer->ux_buf; |
|
|
DPRINTFN(12, "rhreq: %04x %04x %04x %04x", |
DPRINTFN(12, "rhreq: %04x %04x %04x %04x", |
req->bmRequestType | (req->bRequest << 8), value, index, len); |
req->bmRequestType | (req->bRequest << 8), value, index, len); |
Line 2416 xhci_root_ctrl_start(usbd_xfer_handle xf |
|
Line 2416 xhci_root_ctrl_start(usbd_xfer_handle xf |
|
err = USBD_IOERROR; |
err = USBD_IOERROR; |
goto ret; |
goto ret; |
} |
} |
xfer->actlen = totlen; |
xfer->ux_actlen = totlen; |
err = USBD_NORMAL_COMPLETION; |
err = USBD_NORMAL_COMPLETION; |
ret: |
ret: |
xfer->status = err; |
xfer->ux_status = err; |
mutex_enter(&sc->sc_lock); |
mutex_enter(&sc->sc_lock); |
usb_transfer_complete(xfer); |
usb_transfer_complete(xfer); |
mutex_exit(&sc->sc_lock); |
mutex_exit(&sc->sc_lock); |
Line 2447 xhci_root_ctrl_done(usbd_xfer_handle xfe |
|
Line 2447 xhci_root_ctrl_done(usbd_xfer_handle xfe |
|
{ |
{ |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
|
|
xfer->hcpriv = NULL; |
xfer->ux_hcpriv = NULL; |
} |
} |
|
|
/* root hub interrupt */ |
/* root hub interrupt */ |
Line 2455 xhci_root_ctrl_done(usbd_xfer_handle xfe |
|
Line 2455 xhci_root_ctrl_done(usbd_xfer_handle xfe |
|
static usbd_status |
static usbd_status |
xhci_root_intr_transfer(usbd_xfer_handle xfer) |
xhci_root_intr_transfer(usbd_xfer_handle xfer) |
{ |
{ |
struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; |
struct xhci_softc * const sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv; |
usbd_status err; |
usbd_status err; |
|
|
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
Line 2468 xhci_root_intr_transfer(usbd_xfer_handle |
|
Line 2468 xhci_root_intr_transfer(usbd_xfer_handle |
|
return err; |
return err; |
|
|
/* Pipe isn't running, start first */ |
/* Pipe isn't running, start first */ |
return (xhci_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); |
return (xhci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue))); |
} |
} |
|
|
static usbd_status |
static usbd_status |
xhci_root_intr_start(usbd_xfer_handle xfer) |
xhci_root_intr_start(usbd_xfer_handle xfer) |
{ |
{ |
struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; |
struct xhci_softc * const sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv; |
|
|
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
|
|
Line 2491 xhci_root_intr_start(usbd_xfer_handle xf |
|
Line 2491 xhci_root_intr_start(usbd_xfer_handle xf |
|
static void |
static void |
xhci_root_intr_abort(usbd_xfer_handle xfer) |
xhci_root_intr_abort(usbd_xfer_handle xfer) |
{ |
{ |
struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; |
struct xhci_softc * const sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv; |
|
|
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
|
|
KASSERT(mutex_owned(&sc->sc_lock)); |
KASSERT(mutex_owned(&sc->sc_lock)); |
KASSERT(xfer->pipe->intrxfer == xfer); |
KASSERT(xfer->ux_pipe->up_intrxfer == xfer); |
|
|
DPRINTFN(1, "remove", 0, 0, 0, 0); |
DPRINTFN(1, "remove", 0, 0, 0, 0); |
|
|
sc->sc_intrxfer = NULL; |
sc->sc_intrxfer = NULL; |
|
|
xfer->status = USBD_CANCELLED; |
xfer->ux_status = USBD_CANCELLED; |
usb_transfer_complete(xfer); |
usb_transfer_complete(xfer); |
} |
} |
|
|
static void |
static void |
xhci_root_intr_close(usbd_pipe_handle pipe) |
xhci_root_intr_close(usbd_pipe_handle pipe) |
{ |
{ |
struct xhci_softc * const sc = pipe->device->bus->hci_private; |
struct xhci_softc * const sc = pipe->up_dev->ud_bus->ub_hcpriv; |
|
|
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
|
|
Line 2523 xhci_root_intr_done(usbd_xfer_handle xfe |
|
Line 2523 xhci_root_intr_done(usbd_xfer_handle xfe |
|
{ |
{ |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
|
|
xfer->hcpriv = NULL; |
xfer->ux_hcpriv = NULL; |
} |
} |
|
|
/* -------------- */ |
/* -------------- */ |
Line 2532 xhci_root_intr_done(usbd_xfer_handle xfe |
|
Line 2532 xhci_root_intr_done(usbd_xfer_handle xfe |
|
static usbd_status |
static usbd_status |
xhci_device_ctrl_transfer(usbd_xfer_handle xfer) |
xhci_device_ctrl_transfer(usbd_xfer_handle xfer) |
{ |
{ |
struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; |
struct xhci_softc * const sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv; |
usbd_status err; |
usbd_status err; |
|
|
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
Line 2545 xhci_device_ctrl_transfer(usbd_xfer_hand |
|
Line 2545 xhci_device_ctrl_transfer(usbd_xfer_hand |
|
return (err); |
return (err); |
|
|
/* Pipe isn't running, start first */ |
/* Pipe isn't running, start first */ |
return (xhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); |
return (xhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue))); |
} |
} |
|
|
static usbd_status |
static usbd_status |
xhci_device_ctrl_start(usbd_xfer_handle xfer) |
xhci_device_ctrl_start(usbd_xfer_handle xfer) |
{ |
{ |
struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; |
struct xhci_softc * const sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv; |
struct xhci_slot * const xs = xfer->pipe->device->hci_private; |
struct xhci_slot * const xs = xfer->ux_pipe->up_dev->ud_hcpriv; |
const u_int dci = xhci_ep_get_dci(xfer->pipe->endpoint->edesc); |
const u_int dci = xhci_ep_get_dci(xfer->ux_pipe->up_endpoint->ue_edesc); |
struct xhci_ring * const tr = &xs->xs_ep[dci].xe_tr; |
struct xhci_ring * const tr = &xs->xs_ep[dci].xe_tr; |
struct xhci_xfer * const xx = (void *)xfer; |
struct xhci_xfer * const xx = (void *)xfer; |
usb_device_request_t * const req = &xfer->request; |
usb_device_request_t * const req = &xfer->ux_request; |
const bool isread = UT_GET_DIR(req->bmRequestType) == UT_READ; |
const bool isread = UT_GET_DIR(req->bmRequestType) == UT_READ; |
const uint32_t len = UGETW(req->wLength); |
const uint32_t len = UGETW(req->wLength); |
usb_dma_t * const dma = &xfer->dmabuf; |
usb_dma_t * const dma = &xfer->ux_dmabuf; |
uint64_t parameter; |
uint64_t parameter; |
uint32_t status; |
uint32_t status; |
uint32_t control; |
uint32_t control; |
Line 2572 xhci_device_ctrl_start(usbd_xfer_handle |
|
Line 2572 xhci_device_ctrl_start(usbd_xfer_handle |
|
|
|
/* XXX */ |
/* XXX */ |
if (tr->is_halted) { |
if (tr->is_halted) { |
xhci_reset_endpoint(xfer->pipe); |
xhci_reset_endpoint(xfer->ux_pipe); |
tr->is_halted = false; |
tr->is_halted = false; |
xhci_set_dequeue(xfer->pipe); |
xhci_set_dequeue(xfer->ux_pipe); |
} |
} |
|
|
/* we rely on the bottom bits for extra info */ |
/* we rely on the bottom bits for extra info */ |
KASSERT(((uintptr_t)xfer & 0x3) == 0x0); |
KASSERT(((uintptr_t)xfer & 0x3) == 0x0); |
|
|
KASSERT((xfer->rqflags & URQ_REQUEST) != 0); |
KASSERT((xfer->ux_rqflags & URQ_REQUEST) != 0); |
|
|
i = 0; |
i = 0; |
|
|
|
|
|
|
xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci); |
xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci); |
|
|
if (xfer->timeout && !sc->sc_bus.use_polling) { |
if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { |
callout_reset(&xfer->timeout_handle, mstohz(xfer->timeout), |
callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), |
xhci_timeout, xfer); |
xhci_timeout, xfer); |
} |
} |
|
|
if (sc->sc_bus.use_polling) { |
if (sc->sc_bus.ub_usepolling) { |
DPRINTFN(1, "polling", 0, 0, 0, 0); |
DPRINTFN(1, "polling", 0, 0, 0, 0); |
//xhci_waitintr(sc, xfer); |
//xhci_waitintr(sc, xfer); |
} |
} |
Line 2653 xhci_device_ctrl_done(usbd_xfer_handle x |
|
Line 2653 xhci_device_ctrl_done(usbd_xfer_handle x |
|
{ |
{ |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
|
|
callout_stop(&xfer->timeout_handle); /* XXX wrong place */ |
callout_stop(&xfer->ux_callout); /* XXX wrong place */ |
|
|
} |
} |
|
|
Line 2678 xhci_device_ctrl_close(usbd_pipe_handle |
|
Line 2678 xhci_device_ctrl_close(usbd_pipe_handle |
|
static usbd_status |
static usbd_status |
xhci_device_bulk_transfer(usbd_xfer_handle xfer) |
xhci_device_bulk_transfer(usbd_xfer_handle xfer) |
{ |
{ |
struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; |
struct xhci_softc * const sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv; |
usbd_status err; |
usbd_status err; |
|
|
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
Line 2694 xhci_device_bulk_transfer(usbd_xfer_hand |
|
Line 2694 xhci_device_bulk_transfer(usbd_xfer_hand |
|
* Pipe isn't running (otherwise err would be USBD_INPROG), |
* Pipe isn't running (otherwise err would be USBD_INPROG), |
* so start it first. |
* so start it first. |
*/ |
*/ |
return (xhci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); |
return (xhci_device_bulk_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue))); |
} |
} |
|
|
static usbd_status |
static usbd_status |
xhci_device_bulk_start(usbd_xfer_handle xfer) |
xhci_device_bulk_start(usbd_xfer_handle xfer) |
{ |
{ |
struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; |
struct xhci_softc * const sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv; |
struct xhci_slot * const xs = xfer->pipe->device->hci_private; |
struct xhci_slot * const xs = xfer->ux_pipe->up_dev->ud_hcpriv; |
const u_int dci = xhci_ep_get_dci(xfer->pipe->endpoint->edesc); |
const u_int dci = xhci_ep_get_dci(xfer->ux_pipe->up_endpoint->ue_edesc); |
struct xhci_ring * const tr = &xs->xs_ep[dci].xe_tr; |
struct xhci_ring * const tr = &xs->xs_ep[dci].xe_tr; |
struct xhci_xfer * const xx = (void *)xfer; |
struct xhci_xfer * const xx = (void *)xfer; |
const uint32_t len = xfer->length; |
const uint32_t len = xfer->ux_length; |
usb_dma_t * const dma = &xfer->dmabuf; |
usb_dma_t * const dma = &xfer->ux_dmabuf; |
uint64_t parameter; |
uint64_t parameter; |
uint32_t status; |
uint32_t status; |
uint32_t control; |
uint32_t control; |
Line 2719 xhci_device_bulk_start(usbd_xfer_handle |
|
Line 2719 xhci_device_bulk_start(usbd_xfer_handle |
|
if (sc->sc_dying) |
if (sc->sc_dying) |
return USBD_IOERROR; |
return USBD_IOERROR; |
|
|
KASSERT((xfer->rqflags & URQ_REQUEST) == 0); |
KASSERT((xfer->ux_rqflags & URQ_REQUEST) == 0); |
|
|
parameter = DMAADDR(dma, 0); |
parameter = DMAADDR(dma, 0); |
/* |
/* |
Line 2747 xhci_device_bulk_start(usbd_xfer_handle |
|
Line 2747 xhci_device_bulk_start(usbd_xfer_handle |
|
|
|
xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci); |
xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci); |
|
|
if (sc->sc_bus.use_polling) { |
if (sc->sc_bus.ub_usepolling) { |
DPRINTFN(1, "polling", 0, 0, 0, 0); |
DPRINTFN(1, "polling", 0, 0, 0, 0); |
//xhci_waitintr(sc, xfer); |
//xhci_waitintr(sc, xfer); |
} |
} |
|
|
xhci_device_bulk_done(usbd_xfer_handle xfer) |
xhci_device_bulk_done(usbd_xfer_handle xfer) |
{ |
{ |
#ifdef USB_DEBUG |
#ifdef USB_DEBUG |
struct xhci_slot * const xs = xfer->pipe->device->hci_private; |
struct xhci_slot * const xs = xfer->ux_pipe->up_dev->ud_hcpriv; |
const u_int dci = xhci_ep_get_dci(xfer->pipe->endpoint->edesc); |
const u_int dci = xhci_ep_get_dci(xfer->ux_pipe->up_endpoint->ue_edesc); |
#endif |
#endif |
const u_int endpt = xfer->pipe->endpoint->edesc->bEndpointAddress; |
const u_int endpt = xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress; |
const bool isread = UE_GET_DIR(endpt) == UE_DIR_IN; |
const bool isread = UE_GET_DIR(endpt) == UE_DIR_IN; |
|
|
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
|
|
DPRINTFN(15, "%p slot %u dci %u", xfer, xs->xs_idx, dci, 0); |
DPRINTFN(15, "%p slot %u dci %u", xfer, xs->xs_idx, dci, 0); |
|
|
callout_stop(&xfer->timeout_handle); /* XXX wrong place */ |
callout_stop(&xfer->ux_callout); /* XXX wrong place */ |
|
|
usb_syncmem(&xfer->dmabuf, 0, xfer->length, |
usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, |
isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); |
isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); |
|
|
|
|
Line 2795 xhci_device_bulk_close(usbd_pipe_handle |
|
Line 2795 xhci_device_bulk_close(usbd_pipe_handle |
|
static usbd_status |
static usbd_status |
xhci_device_intr_transfer(usbd_xfer_handle xfer) |
xhci_device_intr_transfer(usbd_xfer_handle xfer) |
{ |
{ |
struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; |
struct xhci_softc * const sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv; |
usbd_status err; |
usbd_status err; |
|
|
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
Line 2811 xhci_device_intr_transfer(usbd_xfer_hand |
|
Line 2811 xhci_device_intr_transfer(usbd_xfer_hand |
|
* Pipe isn't running (otherwise err would be USBD_INPROG), |
* Pipe isn't running (otherwise err would be USBD_INPROG), |
* so start it first. |
* so start it first. |
*/ |
*/ |
return (xhci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); |
return (xhci_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue))); |
} |
} |
|
|
static usbd_status |
static usbd_status |
xhci_device_intr_start(usbd_xfer_handle xfer) |
xhci_device_intr_start(usbd_xfer_handle xfer) |
{ |
{ |
struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; |
struct xhci_softc * const sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv; |
struct xhci_slot * const xs = xfer->pipe->device->hci_private; |
struct xhci_slot * const xs = xfer->ux_pipe->up_dev->ud_hcpriv; |
const u_int dci = xhci_ep_get_dci(xfer->pipe->endpoint->edesc); |
const u_int dci = xhci_ep_get_dci(xfer->ux_pipe->up_endpoint->ue_edesc); |
struct xhci_ring * const tr = &xs->xs_ep[dci].xe_tr; |
struct xhci_ring * const tr = &xs->xs_ep[dci].xe_tr; |
struct xhci_xfer * const xx = (void *)xfer; |
struct xhci_xfer * const xx = (void *)xfer; |
const uint32_t len = xfer->length; |
const uint32_t len = xfer->ux_length; |
usb_dma_t * const dma = &xfer->dmabuf; |
usb_dma_t * const dma = &xfer->ux_dmabuf; |
uint64_t parameter; |
uint64_t parameter; |
uint32_t status; |
uint32_t status; |
uint32_t control; |
uint32_t control; |
Line 2836 xhci_device_intr_start(usbd_xfer_handle |
|
Line 2836 xhci_device_intr_start(usbd_xfer_handle |
|
if (sc->sc_dying) |
if (sc->sc_dying) |
return USBD_IOERROR; |
return USBD_IOERROR; |
|
|
KASSERT((xfer->rqflags & URQ_REQUEST) == 0); |
KASSERT((xfer->ux_rqflags & URQ_REQUEST) == 0); |
|
|
parameter = DMAADDR(dma, 0); |
parameter = DMAADDR(dma, 0); |
KASSERT(len <= 0x10000); |
KASSERT(len <= 0x10000); |
Line 2853 xhci_device_intr_start(usbd_xfer_handle |
|
Line 2853 xhci_device_intr_start(usbd_xfer_handle |
|
|
|
xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci); |
xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci); |
|
|
if (sc->sc_bus.use_polling) { |
if (sc->sc_bus.ub_usepolling) { |
DPRINTFN(1, "polling", 0, 0, 0, 0); |
DPRINTFN(1, "polling", 0, 0, 0, 0); |
//xhci_waitintr(sc, xfer); |
//xhci_waitintr(sc, xfer); |
} |
} |
|
|
xhci_device_intr_done(usbd_xfer_handle xfer) |
xhci_device_intr_done(usbd_xfer_handle xfer) |
{ |
{ |
struct xhci_softc * const sc __diagused = |
struct xhci_softc * const sc __diagused = |
xfer->pipe->device->bus->hci_private; |
xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv; |
#ifdef USB_DEBUG |
#ifdef USB_DEBUG |
struct xhci_slot * const xs = xfer->pipe->device->hci_private; |
struct xhci_slot * const xs = xfer->ux_pipe->up_dev->ud_hcpriv; |
const u_int dci = xhci_ep_get_dci(xfer->pipe->endpoint->edesc); |
const u_int dci = xhci_ep_get_dci(xfer->ux_pipe->up_endpoint->ue_edesc); |
#endif |
#endif |
const u_int endpt = xfer->pipe->endpoint->edesc->bEndpointAddress; |
const u_int endpt = xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress; |
const bool isread = UE_GET_DIR(endpt) == UE_DIR_IN; |
const bool isread = UE_GET_DIR(endpt) == UE_DIR_IN; |
|
|
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
|
|
DPRINTFN(15, "%p slot %u dci %u", xfer, xs->xs_idx, dci, 0); |
DPRINTFN(15, "%p slot %u dci %u", xfer, xs->xs_idx, dci, 0); |
|
|
KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); |
KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); |
|
|
usb_syncmem(&xfer->dmabuf, 0, xfer->length, |
usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, |
isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); |
isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); |
|
|
#if 0 |
#if 0 |
device_printf(sc->sc_dev, ""); |
device_printf(sc->sc_dev, ""); |
for (size_t i = 0; i < xfer->length; i++) { |
for (size_t i = 0; i < xfer->ux_length; i++) { |
printf(" %02x", ((uint8_t const *)xfer->buffer)[i]); |
printf(" %02x", ((uint8_t const *)xfer->ux_buffer)[i]); |
} |
} |
printf("\n"); |
printf("\n"); |
#endif |
#endif |
|
|
if (xfer->pipe->repeat) { |
if (xfer->ux_pipe->up_repeat) { |
xfer->status = xhci_device_intr_start(xfer); |
xfer->ux_status = xhci_device_intr_start(xfer); |
} else { |
} else { |
callout_stop(&xfer->timeout_handle); /* XXX */ |
callout_stop(&xfer->ux_callout); /* XXX */ |
} |
} |
|
|
} |
} |
|
|
xhci_device_intr_abort(usbd_xfer_handle xfer) |
xhci_device_intr_abort(usbd_xfer_handle xfer) |
{ |
{ |
struct xhci_softc * const sc __diagused = |
struct xhci_softc * const sc __diagused = |
xfer->pipe->device->bus->hci_private; |
xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv; |
|
|
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
|
|
KASSERT(mutex_owned(&sc->sc_lock)); |
KASSERT(mutex_owned(&sc->sc_lock)); |
DPRINTFN(15, "%p", xfer, 0, 0, 0); |
DPRINTFN(15, "%p", xfer, 0, 0, 0); |
KASSERT(xfer->pipe->intrxfer == xfer); |
KASSERT(xfer->ux_pipe->up_intrxfer == xfer); |
xfer->status = USBD_CANCELLED; |
xfer->ux_status = USBD_CANCELLED; |
usb_transfer_complete(xfer); |
usb_transfer_complete(xfer); |
} |
} |
|
|
static void |
static void |
xhci_device_intr_close(usbd_pipe_handle pipe) |
xhci_device_intr_close(usbd_pipe_handle pipe) |
{ |
{ |
//struct xhci_softc * const sc = pipe->device->bus->hci_private; |
//struct xhci_softc * const sc = pipe->up_dev->ud_bus->ub_hcpriv; |
|
|
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
DPRINTFN(15, "%p", pipe, 0, 0, 0); |
DPRINTFN(15, "%p", pipe, 0, 0, 0); |
Line 2931 xhci_timeout(void *addr) |
|
Line 2931 xhci_timeout(void *addr) |
|
{ |
{ |
struct xhci_xfer * const xx = addr; |
struct xhci_xfer * const xx = addr; |
usbd_xfer_handle const xfer = &xx->xx_xfer; |
usbd_xfer_handle const xfer = &xx->xx_xfer; |
struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; |
struct xhci_softc * const sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv; |
|
|
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
|
|
Line 2941 xhci_timeout(void *addr) |
|
Line 2941 xhci_timeout(void *addr) |
|
|
|
usb_init_task(&xx->xx_abort_task, xhci_timeout_task, addr, |
usb_init_task(&xx->xx_abort_task, xhci_timeout_task, addr, |
USB_TASKQ_MPSAFE); |
USB_TASKQ_MPSAFE); |
usb_add_task(xx->xx_xfer.pipe->device, &xx->xx_abort_task, |
usb_add_task(xx->xx_xfer.ux_pipe->up_dev, &xx->xx_abort_task, |
USB_TASKQ_HC); |
USB_TASKQ_HC); |
} |
} |
|
|
|
|
xhci_timeout_task(void *addr) |
xhci_timeout_task(void *addr) |
{ |
{ |
usbd_xfer_handle const xfer = addr; |
usbd_xfer_handle const xfer = addr; |
struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; |
struct xhci_softc * const sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv; |
|
|
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
XHCIHIST_FUNC(); XHCIHIST_CALLED(); |
|
|
Line 2957 xhci_timeout_task(void *addr) |
|
Line 2957 xhci_timeout_task(void *addr) |
|
#if 0 |
#if 0 |
xhci_abort_xfer(xfer, USBD_TIMEOUT); |
xhci_abort_xfer(xfer, USBD_TIMEOUT); |
#else |
#else |
xfer->status = USBD_TIMEOUT; |
xfer->ux_status = USBD_TIMEOUT; |
usb_transfer_complete(xfer); |
usb_transfer_complete(xfer); |
#endif |
#endif |
mutex_exit(&sc->sc_lock); |
mutex_exit(&sc->sc_lock); |