version 1.234.2.68, 2015/12/08 12:40:12 |
version 1.234.2.69, 2015/12/08 12:48:55 |
Line 233 Static usbd_status ehci_alloc_sqtd_chain |
|
Line 233 Static usbd_status ehci_alloc_sqtd_chain |
|
Static void ehci_free_sqtds(ehci_softc_t *, struct ehci_xfer *); |
Static void ehci_free_sqtds(ehci_softc_t *, struct ehci_xfer *); |
|
|
Static void ehci_reset_sqtd_chain(ehci_softc_t *, struct usbd_xfer *, |
Static void ehci_reset_sqtd_chain(ehci_softc_t *, struct usbd_xfer *, |
int, int, int *, ehci_soft_qtd_t *, ehci_soft_qtd_t **); |
int, int, int *, ehci_soft_qtd_t **); |
|
|
Static ehci_soft_itd_t *ehci_alloc_itd(ehci_softc_t *); |
Static ehci_soft_itd_t *ehci_alloc_itd(ehci_softc_t *); |
Static ehci_soft_sitd_t * |
Static ehci_soft_sitd_t * |
Line 2852 ehci_alloc_sqtd_chain(ehci_softc_t *sc, |
|
Line 2852 ehci_alloc_sqtd_chain(ehci_softc_t *sc, |
|
|
|
size_t nsqtd = (flags & USBD_FORCE_SHORT_XFER) ? 1 : 0; |
size_t nsqtd = (flags & USBD_FORCE_SHORT_XFER) ? 1 : 0; |
nsqtd += ((len + EHCI_QTD_MAXTRANSFER - 1) / EHCI_QTD_MAXTRANSFER); |
nsqtd += ((len + EHCI_QTD_MAXTRANSFER - 1) / EHCI_QTD_MAXTRANSFER); |
exfer->ex_sqtds = kmem_alloc(sizeof(ehci_soft_qtd_t *) * nsqtd, |
exfer->ex_sqtds = kmem_zalloc(sizeof(ehci_soft_qtd_t *) * nsqtd, |
KM_SLEEP); |
KM_SLEEP); |
exfer->ex_nsqtd = nsqtd; |
exfer->ex_nsqtd = nsqtd; |
|
|
Line 2964 ehci_free_sqtds(ehci_softc_t *sc, struct |
|
Line 2964 ehci_free_sqtds(ehci_softc_t *sc, struct |
|
|
|
mutex_enter(&sc->sc_lock); |
mutex_enter(&sc->sc_lock); |
for (size_t i = 0; i < exfer->ex_nsqtd; i++) { |
for (size_t i = 0; i < exfer->ex_nsqtd; i++) { |
exfer->ex_sqtds[i]->nextqtd = sc->sc_freeqtds; |
ehci_soft_qtd_t *sqtd = exfer->ex_sqtds[i]; |
sc->sc_freeqtds = exfer->ex_sqtds[i]->nextqtd; |
|
|
if (sqtd == NULL) |
|
break; |
|
|
|
sqtd->nextqtd = sc->sc_freeqtds; |
|
sc->sc_freeqtds = sqtd->nextqtd; |
} |
} |
mutex_exit(&sc->sc_lock); |
mutex_exit(&sc->sc_lock); |
} |
} |
|
|
Static void |
Static void |
ehci_reset_sqtd_chain(ehci_softc_t *sc, struct usbd_xfer *xfer, |
ehci_reset_sqtd_chain(ehci_softc_t *sc, struct usbd_xfer *xfer, |
int length, int isread, int *toggle, |
int length, int isread, int *toggle, ehci_soft_qtd_t **lsqtd) |
ehci_soft_qtd_t *fsqtd, ehci_soft_qtd_t **lsqtd) |
|
{ |
{ |
struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); |
struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); |
ehci_soft_qtd_t *sqtd, *prev; |
ehci_soft_qtd_t *sqtd, *prev; |
Line 3691 ehci_device_ctrl_start(struct usbd_xfer |
|
Line 3695 ehci_device_ctrl_start(struct usbd_xfer |
|
int toggle = 1; |
int toggle = 1; |
next = exfer->ex_data; |
next = exfer->ex_data; |
KASSERTMSG(next != NULL, "Failed memory allocation"); |
KASSERTMSG(next != NULL, "Failed memory allocation"); |
ehci_reset_sqtd_chain(sc, xfer, len, isread, &toggle, |
ehci_reset_sqtd_chain(sc, xfer, len, isread, &toggle, &end); |
next, &end); |
|
end->nextqtd = status; |
end->nextqtd = status; |
end->qtd.qtd_next = end->qtd.qtd_altnext = |
end->qtd.qtd_next = end->qtd.qtd_altnext = |
htole32(status->physaddr); |
htole32(status->physaddr); |
Line 3912 ehci_device_bulk_start(struct usbd_xfer |
|
Line 3915 ehci_device_bulk_start(struct usbd_xfer |
|
/* Take lock here to protect nexttoggle */ |
/* Take lock here to protect nexttoggle */ |
mutex_enter(&sc->sc_lock); |
mutex_enter(&sc->sc_lock); |
|
|
ehci_reset_sqtd_chain(sc, xfer, len, isread, &epipe->nexttoggle, |
ehci_reset_sqtd_chain(sc, xfer, len, isread, &epipe->nexttoggle, &end); |
exfer->ex_sqtdstart, &end); |
|
|
|
exfer->ex_sqtdend = end; |
exfer->ex_sqtdend = end; |
end->qtd.qtd_status |= htole32(EHCI_QTD_IOC); |
end->qtd.qtd_status |= htole32(EHCI_QTD_IOC); |
Line 4108 ehci_device_intr_start(struct usbd_xfer |
|
Line 4110 ehci_device_intr_start(struct usbd_xfer |
|
struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); |
struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); |
struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); |
struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); |
ehci_softc_t *sc = EHCI_XFER2SC(xfer); |
ehci_softc_t *sc = EHCI_XFER2SC(xfer); |
ehci_soft_qtd_t *data, *end; |
ehci_soft_qtd_t *end; |
ehci_soft_qh_t *sqh; |
ehci_soft_qh_t *sqh; |
int len, isread, endpt; |
int len, isread, endpt; |
|
|
Line 4128 ehci_device_intr_start(struct usbd_xfer |
|
Line 4130 ehci_device_intr_start(struct usbd_xfer |
|
isread = UE_GET_DIR(endpt) == UE_DIR_IN; |
isread = UE_GET_DIR(endpt) == UE_DIR_IN; |
sqh = epipe->sqh; |
sqh = epipe->sqh; |
|
|
data = exfer->ex_sqtdstart; |
|
|
|
KASSERT(exfer->ex_isdone); |
KASSERT(exfer->ex_isdone); |
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
exfer->ex_isdone = false; |
exfer->ex_isdone = false; |
Line 4137 ehci_device_intr_start(struct usbd_xfer |
|
Line 4137 ehci_device_intr_start(struct usbd_xfer |
|
|
|
/* Take lock to protect nexttoggle */ |
/* Take lock to protect nexttoggle */ |
mutex_enter(&sc->sc_lock); |
mutex_enter(&sc->sc_lock); |
ehci_reset_sqtd_chain(sc, xfer, len, isread, &epipe->nexttoggle, |
ehci_reset_sqtd_chain(sc, xfer, len, isread, &epipe->nexttoggle, &end); |
data, &end); |
|
|
|
end->qtd.qtd_status |= htole32(EHCI_QTD_IOC); |
end->qtd.qtd_status |= htole32(EHCI_QTD_IOC); |
usb_syncmem(&end->dma, end->offs, sizeof(end->qtd), |
usb_syncmem(&end->dma, end->offs, sizeof(end->qtd), |
Line 4156 ehci_device_intr_start(struct usbd_xfer |
|
Line 4155 ehci_device_intr_start(struct usbd_xfer |
|
isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); |
isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); |
|
|
/* also does usb_syncmem(sqh) */ |
/* also does usb_syncmem(sqh) */ |
ehci_set_qh_qtd(sqh, data); |
ehci_set_qh_qtd(sqh, exfer->ex_sqtdstart); |
if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { |
if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { |
callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), |
callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), |
ehci_timeout, xfer); |
ehci_timeout, xfer); |
Line 4173 ehci_device_intr_start(struct usbd_xfer |
|
Line 4172 ehci_device_intr_start(struct usbd_xfer |
|
ehci_dump_regs(sc); |
ehci_dump_regs(sc); |
USBHIST_LOGN(ehcidebug, 5, "sqh:", 0, 0, 0, 0); |
USBHIST_LOGN(ehcidebug, 5, "sqh:", 0, 0, 0, 0); |
ehci_dump_sqh(sqh); |
ehci_dump_sqh(sqh); |
ehci_dump_sqtds(data); |
ehci_dump_sqtds(exfer->ex_sqtdstart); |
#endif |
#endif |
#endif |
#endif |
|
|
Line 4218 ehci_device_intr_done(struct usbd_xfer * |
|
Line 4217 ehci_device_intr_done(struct usbd_xfer * |
|
ehci_softc_t *sc = EHCI_XFER2SC(xfer); |
ehci_softc_t *sc = EHCI_XFER2SC(xfer); |
struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); |
struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); |
struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); |
struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); |
ehci_soft_qtd_t *data; |
|
ehci_soft_qh_t *sqh; |
ehci_soft_qh_t *sqh; |
int len, isread, endpt; |
int len, isread, endpt; |
|
|
Line 4245 ehci_device_intr_done(struct usbd_xfer * |
|
Line 4243 ehci_device_intr_done(struct usbd_xfer * |
|
|
|
ehci_soft_qtd_t *end; |
ehci_soft_qtd_t *end; |
ehci_reset_sqtd_chain(sc, xfer, len, isread, |
ehci_reset_sqtd_chain(sc, xfer, len, isread, |
&epipe->nexttoggle, exfer->ex_sqtdstart, &end); |
&epipe->nexttoggle, &end); |
end->qtd.qtd_status |= htole32(EHCI_QTD_IOC); |
end->qtd.qtd_status |= htole32(EHCI_QTD_IOC); |
usb_syncmem(&end->dma, end->offs, sizeof(end->qtd), |
usb_syncmem(&end->dma, end->offs, sizeof(end->qtd), |
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); |
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); |
|
|
exfer->ex_sqtdend = end; |
exfer->ex_sqtdend = end; |
|
|
data = exfer->ex_sqtdstart; |
|
|
|
/* also does usb_syncmem(sqh) */ |
/* also does usb_syncmem(sqh) */ |
ehci_set_qh_qtd(sqh, data); |
ehci_set_qh_qtd(sqh, exfer->ex_sqtdstart); |
if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { |
if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { |
callout_reset(&xfer->ux_callout, |
callout_reset(&xfer->ux_callout, |
mstohz(xfer->ux_timeout), ehci_timeout, xfer); |
mstohz(xfer->ux_timeout), ehci_timeout, xfer); |