-/* $OpenBSD: ehci.c,v 1.150 2014/05/04 14:31:50 mpi Exp $ */
+/* $OpenBSD: ehci.c,v 1.151 2014/05/04 14:42:36 mpi Exp $ */
/* $NetBSD: ehci.c,v 1.66 2004/06/30 03:11:56 mycroft Exp $ */
/*
struct ehci_soft_qtd *ehci_alloc_sqtd(struct ehci_softc *);
void ehci_free_sqtd(struct ehci_softc *, struct ehci_soft_qtd *);
-usbd_status ehci_alloc_sqtd_chain(struct ehci_pipe *,
- struct ehci_softc *, u_int, int, struct usbd_xfer *,
- struct ehci_soft_qtd **, struct ehci_soft_qtd **);
+usbd_status ehci_alloc_sqtd_chain(struct ehci_softc *, u_int,
+ struct usbd_xfer *, struct ehci_soft_qtd **, struct ehci_soft_qtd **);
void ehci_free_sqtd_chain(struct ehci_softc *, struct ehci_xfer *);
struct ehci_soft_itd *ehci_alloc_itd(struct ehci_softc *sc);
}
usbd_status
-ehci_alloc_sqtd_chain(struct ehci_pipe *epipe, struct ehci_softc *sc,
- u_int alen, int rd, struct usbd_xfer *xfer, struct ehci_soft_qtd **sp,
- struct ehci_soft_qtd **ep)
+ehci_alloc_sqtd_chain(struct ehci_softc *sc, u_int alen, struct usbd_xfer *xfer,
+ struct ehci_soft_qtd **sp, struct ehci_soft_qtd **ep)
{
struct ehci_soft_qtd *next, *cur;
ehci_physaddr_t dataphys, dataphyspage, dataphyslastpage, nextphys;
u_int32_t qtdstatus;
u_int len, curlen;
int mps, i, iscontrol, forceshort;
+ int rd = usbd_xfer_isread(xfer);
struct usb_dma *dma = &xfer->dmabuf;
DPRINTFN(alen<4*4096,("ehci_alloc_sqtd_chain: start len=%d\n", alen));
usb_device_request_t *req = &xfer->request;
struct ehci_soft_qtd *setup, *stat, *next;
struct ehci_soft_qh *sqh;
- int isread;
- u_int len;
+ u_int len = UGETW(req->wLength);
usbd_status err;
int s;
- isread = req->bmRequestType & UT_READ;
- len = UGETW(req->wLength);
-
DPRINTFN(3,("ehci_device_request: type=0x%02x, request=0x%02x, "
"wValue=0x%04x, wIndex=0x%04x len=%u, addr=%d, endpt=%d\n",
req->bmRequestType, req->bRequest, UGETW(req->wValue),
- UGETW(req->wIndex), len, xfer->device->address,
+ UGETW(req->wIndex), UGETW(req->wLength), xfer->device->address,
xfer->pipe->endpoint->edesc->bEndpointAddress));
setup = ehci_alloc_sqtd(sc);
if (len != 0) {
struct ehci_soft_qtd *end;
- err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer,
- &next, &end);
+ err = ehci_alloc_sqtd_chain(sc, len, xfer, &next, &end);
if (err)
goto bad3;
end->qtd.qtd_status &= htole32(~EHCI_QTD_IOC);
stat->qtd.qtd_status = htole32(
EHCI_QTD_ACTIVE |
- EHCI_QTD_SET_PID(isread ? EHCI_QTD_PID_OUT : EHCI_QTD_PID_IN) |
+ EHCI_QTD_SET_PID(usbd_xfer_isread(xfer) ?
+ EHCI_QTD_PID_OUT : EHCI_QTD_PID_IN) |
EHCI_QTD_SET_CERR(3) |
EHCI_QTD_SET_TOGGLE(1) |
EHCI_QTD_IOC);
struct ehci_soft_qtd *data, *dataend;
struct ehci_soft_qh *sqh;
usbd_status err;
- u_int len;
- int isread, endpt;
int s;
DPRINTFN(2, ("ehci_device_bulk_start: xfer=%p len=%u flags=%d\n",
panic("ehci_device_bulk_start: a request");
#endif
- len = xfer->length;
- endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
- isread = UE_GET_DIR(endpt) == UE_DIR_IN;
sqh = epipe->sqh;
- epipe->u.bulk.length = len;
+ epipe->u.bulk.length = xfer->length;
- err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer, &data,
- &dataend);
+ err = ehci_alloc_sqtd_chain(sc, xfer->length, xfer, &data, &dataend);
if (err) {
DPRINTFN(-1,("ehci_device_bulk_start: no memory\n"));
xfer->status = err;
{
struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
- int endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
- int rd = UE_GET_DIR(endpt) == UE_DIR_IN;
DPRINTFN(10,("ehci_bulk_done: xfer=%p, actlen=%d\n",
xfer, xfer->actlen));
ehci_del_intr_list(sc, ex); /* remove from active list */
ehci_free_sqtd_chain(sc, ex);
usb_syncmem(&xfer->dmabuf, 0, xfer->length,
- rd ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
}
DPRINTFN(5, ("ehci_bulk_done: length=%d\n", xfer->actlen));
struct ehci_soft_qtd *data, *dataend;
struct ehci_soft_qh *sqh;
usbd_status err;
- u_int len;
- int isread, endpt;
int s;
DPRINTFN(2, ("ehci_device_intr_start: xfer=%p len=%u flags=%d\n",
panic("ehci_device_intr_start: a request");
#endif
- len = xfer->length;
- endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
- isread = UE_GET_DIR(endpt) == UE_DIR_IN;
sqh = epipe->sqh;
- epipe->u.intr.length = len;
+ epipe->u.intr.length = xfer->length;
- err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer, &data,
- &dataend);
+ err = ehci_alloc_sqtd_chain(sc, xfer->length, xfer, &data, &dataend);
if (err) {
DPRINTFN(-1, ("ehci_device_intr_start: no memory\n"));
xfer->status = err;
struct ehci_soft_qtd *data, *dataend;
struct ehci_soft_qh *sqh;
usbd_status err;
- u_int len;
- int isread, endpt, s;
+ int s;
DPRINTFN(10, ("ehci_device_intr_done: xfer=%p, actlen=%d\n",
xfer, xfer->actlen));
if (xfer->pipe->repeat) {
ehci_free_sqtd_chain(sc, ex);
- len = epipe->u.intr.length;
- xfer->length = len;
- endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
- isread = UE_GET_DIR(endpt) == UE_DIR_IN;
- usb_syncmem(&xfer->dmabuf, 0, len,
- isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
+ xfer->length = epipe->u.intr.length;
+ usb_syncmem(&xfer->dmabuf, 0, xfer->length,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
sqh = epipe->sqh;
- err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer,
- &data, &dataend);
+ err = ehci_alloc_sqtd_chain(sc, xfer->length, xfer, &data, &dataend);
if (err) {
DPRINTFN(-1, ("ehci_device_intr_done: no memory\n"));
xfer->status = err;
} else if (xfer->status != USBD_NOMEM && ehci_active_intr_list(ex)) {
ehci_del_intr_list(sc, ex); /* remove from active list */
ehci_free_sqtd_chain(sc, ex);
- endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
- isread = UE_GET_DIR(endpt) == UE_DIR_IN;
usb_syncmem(&xfer->dmabuf, 0, xfer->length,
- isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
}
}
-/* $OpenBSD: ohci.c,v 1.127 2014/04/29 21:51:18 mpi Exp $ */
+/* $OpenBSD: ohci.c,v 1.128 2014/05/04 14:42:36 mpi Exp $ */
/* $NetBSD: ohci.c,v 1.139 2003/02/22 05:24:16 tsutsui Exp $ */
/* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */
void ohci_free_std_chain(struct ohci_softc *, struct ohci_soft_td *,
struct ohci_soft_td *);
#endif
-usbd_status ohci_alloc_std_chain(struct ohci_pipe *,
- struct ohci_softc *, u_int, int, struct usbd_xfer *,
- struct ohci_soft_td *, struct ohci_soft_td **);
+usbd_status ohci_alloc_std_chain(struct ohci_softc *, u_int,
+ struct usbd_xfer *, struct ohci_soft_td *,
+ struct ohci_soft_td **);
usbd_status ohci_open(struct usbd_pipe *);
void ohci_poll(struct usbd_bus *);
}
usbd_status
-ohci_alloc_std_chain(struct ohci_pipe *opipe, struct ohci_softc *sc,
- u_int alen, int rd, struct usbd_xfer *xfer,
+ohci_alloc_std_chain(struct ohci_softc *sc, u_int alen, struct usbd_xfer *xfer,
struct ohci_soft_td *sp, struct ohci_soft_td **ep)
{
struct ohci_soft_td *next, *cur, *end;
ohci_physaddr_t dataphys, dataphysend;
u_int32_t tdflags;
u_int len, curlen;
+ int mps;
+ int rd = usbd_xfer_isread(xfer);
struct usb_dma *dma = &xfer->dmabuf;
u_int16_t flags = xfer->flags;
(rd ? OHCI_TD_IN : OHCI_TD_OUT) |
(flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0) |
OHCI_TD_NOCC | OHCI_TD_TOGGLE_CARRY | OHCI_TD_NOINTR);
+ mps = UGETW(xfer->pipe->endpoint->edesc->wMaxPacketSize);
while (len > 0) {
next = ohci_alloc_std(sc);
curlen = 2 * OHCI_PAGE_SIZE -
(dataphys & (OHCI_PAGE_SIZE-1));
/* the length must be a multiple of the max size */
- curlen -= curlen % UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize);
+ curlen -= curlen % mps;
#ifdef DIAGNOSTIC
if (curlen == 0)
panic("ohci_alloc_std: curlen == 0");
cur = next;
}
if (!rd && ((flags & USBD_FORCE_SHORT_XFER) || alen == 0) &&
- alen % UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize) == 0) {
+ alen % mps == 0) {
/* Force a 0 length transfer at the end. */
next = ohci_alloc_std(sc);
usb_device_request_t *req = &xfer->request;
struct ohci_soft_td *setup, *stat, *next, *tail;
struct ohci_soft_ed *sed;
- int isread;
u_int len;
usbd_status err;
int s;
- isread = req->bmRequestType & UT_READ;
len = UGETW(req->wLength);
DPRINTFN(3,("ohci_device_control type=0x%02x, request=0x%02x, "
if (len != 0) {
struct ohci_soft_td *std = stat;
- err = ohci_alloc_std_chain(opipe, sc, len, isread, xfer,
- std, &stat);
+ err = ohci_alloc_std_chain(sc, len, xfer, std, &stat);
stat = stat->nexttd; /* point at free TD */
if (err)
goto bad3;
xfer->hcpriv = setup;
stat->td.td_flags = htole32(
- (isread ? OHCI_TD_OUT : OHCI_TD_IN) |
+ (usbd_xfer_isread(xfer) ? OHCI_TD_OUT : OHCI_TD_IN) |
OHCI_TD_NOCC | OHCI_TD_TOGGLE_1 | OHCI_TD_SET_DI(1));
stat->td.td_cbp = 0;
stat->nexttd = tail;
struct ohci_soft_td *data, *tail, *tdp;
struct ohci_soft_ed *sed;
u_int len;
- int s, isread, endpt;
+ int s, endpt;
usbd_status err;
if (sc->sc_bus.dying)
len = xfer->length;
endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
- isread = UE_GET_DIR(endpt) == UE_DIR_IN;
sed = opipe->sed;
- DPRINTFN(4,("ohci_device_bulk_start: xfer=%p len=%u isread=%d "
- "flags=%d endpt=%d\n", xfer, len, isread, xfer->flags,
- endpt));
+ DPRINTFN(4,("ohci_device_bulk_start: xfer=%p len=%u "
+ "flags=%d endpt=%d\n", xfer, len, xfer->flags, endpt));
- opipe->u.bulk.isread = isread;
+ opipe->u.bulk.isread = usbd_xfer_isread(xfer);
opipe->u.bulk.length = len;
/* Update device address */
/* Allocate a chain of new TDs (including a new tail). */
data = opipe->tail.td;
- err = ohci_alloc_std_chain(opipe, sc, len, isread, xfer,
- data, &tail);
+ err = ohci_alloc_std_chain(sc, len, xfer, data, &tail);
/* We want interrupt at the end of the transfer. */
tail->td.td_flags &= htole32(~OHCI_TD_INTR_MASK);
tail->td.td_flags |= htole32(OHCI_TD_SET_DI(1));
struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
struct ohci_soft_ed *sed = opipe->sed;
struct ohci_soft_td *data, *tail;
- int s, len, isread, endpt;
+ int s, len, endpt;
if (sc->sc_bus.dying)
return (USBD_IOERROR);
len = xfer->length;
endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
- isread = UE_GET_DIR(endpt) == UE_DIR_IN;
data = opipe->tail.td;
tail = ohci_alloc_std(sc);
tail->xfer = NULL;
data->td.td_flags = htole32(
- isread ? OHCI_TD_IN : OHCI_TD_OUT |
+ usbd_xfer_isread(xfer) ? OHCI_TD_IN : OHCI_TD_OUT |
OHCI_TD_NOCC |
OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY);
if (xfer->flags & USBD_SHORT_XFER_OK)
-/* $OpenBSD: uhci.c,v 1.113 2014/04/29 21:51:18 mpi Exp $ */
+/* $OpenBSD: uhci.c,v 1.114 2014/05/04 14:42:36 mpi Exp $ */
/* $NetBSD: uhci.c,v 1.172 2003/02/23 04:19:26 simonb Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */
void uhci_free_std_chain(struct uhci_softc *,
struct uhci_soft_td *, struct uhci_soft_td *);
-usbd_status uhci_alloc_std_chain(struct uhci_pipe *,
- struct uhci_softc *, u_int, int, u_int16_t,
- struct usb_dma *, struct uhci_soft_td **,
+usbd_status uhci_alloc_std_chain(struct uhci_softc *, u_int,
+ struct usbd_xfer *, struct uhci_soft_td **,
struct uhci_soft_td **);
void uhci_poll_hub(void *);
void uhci_waitintr(struct uhci_softc *, struct usbd_xfer *);
}
usbd_status
-uhci_alloc_std_chain(struct uhci_pipe *upipe, struct uhci_softc *sc, u_int len,
- int rd, u_int16_t flags, struct usb_dma *dma,
+uhci_alloc_std_chain(struct uhci_softc *sc, u_int len, struct usbd_xfer *xfer,
struct uhci_soft_td **sp, struct uhci_soft_td **ep)
{
+ struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
struct uhci_soft_td *p, *lastp;
uhci_physaddr_t lastlink;
- int i, ntd, l, tog, maxp;
+ int i, ntd, l, tog, mps;
u_int32_t status;
- int addr = upipe->pipe.device->address;
- int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
-
- DPRINTFN(8, ("uhci_alloc_std_chain: addr=%d endpt=%d len=%u speed=%d "
- "flags=0x%x\n", addr, UE_GET_ADDR(endpt), len,
- upipe->pipe.device->speed, flags));
- maxp = UGETW(upipe->pipe.endpoint->edesc->wMaxPacketSize);
- if (maxp == 0) {
- printf("uhci_alloc_std_chain: maxp=0\n");
+ u_int16_t flags = xfer->flags;
+ int rd = usbd_xfer_isread(xfer);
+ struct usb_dma *dma = &xfer->dmabuf;
+ int addr = xfer->device->address;
+ int endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
+
+ DPRINTFN(8, ("%s: addr=%d endpt=%d len=%u speed=%d flags=0x%x\n",
+ __func__, addr, UE_GET_ADDR(endpt), len, xfer->device->speed,
+ flags));
+
+ mps = UGETW(xfer->pipe->endpoint->edesc->wMaxPacketSize);
+ if (mps == 0) {
+ printf("uhci_alloc_std_chain: mps=0\n");
return (USBD_INVAL);
}
- ntd = (len + maxp - 1) / maxp;
+ ntd = (len + mps - 1) / mps;
if (len == 0)
flags |= USBD_FORCE_SHORT_XFER;
- if ((flags & USBD_FORCE_SHORT_XFER) && len % maxp == 0)
+ if ((flags & USBD_FORCE_SHORT_XFER) && len % mps == 0)
ntd++;
- DPRINTFN(10, ("uhci_alloc_std_chain: maxp=%d ntd=%d\n", maxp, ntd));
+ DPRINTFN(10, ("%s: mps=%d ntd=%d\n", __func__, mps, ntd));
tog = upipe->nexttoggle;
if (ntd % 2 == 0)
tog ^= 1;
lastlink = UHCI_PTR_T;
ntd--;
status = UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(3) | UHCI_TD_ACTIVE);
- if (upipe->pipe.device->speed == USB_SPEED_LOW)
+ if (xfer->pipe->device->speed == USB_SPEED_LOW)
status |= UHCI_TD_LS;
if (flags & USBD_SHORT_XFER_OK)
status |= UHCI_TD_SPD;
p->td.td_status = htole32(status);
if (i == ntd) {
/* last TD */
- l = len % maxp;
+ l = len % mps;
if (l == 0 && !(flags & USBD_FORCE_SHORT_XFER))
- l = maxp;
+ l = mps;
*ep = p;
} else
- l = maxp;
+ l = mps;
p->td.td_token =
htole32(rd ? UHCI_TD_IN (l, endpt, addr, tog) :
UHCI_TD_OUT(l, endpt, addr, tog));
- p->td.td_buffer = htole32(DMAADDR(dma, i * maxp));
+ p->td.td_buffer = htole32(DMAADDR(dma, i * mps));
tog ^= 1;
}
*sp = lastp;
- DPRINTFN(10, ("uhci_alloc_std_chain: nexttog=%d\n",
- upipe->nexttoggle));
+ DPRINTFN(10, ("%s: nexttog=%d\n", __func__, upipe->nexttoggle));
return (USBD_NORMAL_COMPLETION);
}
struct uhci_soft_qh *sqh;
usbd_status err;
u_int len;
- int isread, endpt;
+ int endpt;
int s;
DPRINTFN(3, ("uhci_device_bulk_start: xfer=%p len=%u flags=%d ux=%p\n",
len = xfer->length;
endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
- isread = UE_GET_DIR(endpt) == UE_DIR_IN;
sqh = upipe->u.bulk.sqh;
- upipe->u.bulk.isread = isread;
+ upipe->u.bulk.isread = usbd_xfer_isread(xfer);
upipe->u.bulk.length = len;
- err = uhci_alloc_std_chain(upipe, sc, len, isread, xfer->flags,
- &xfer->dmabuf, &data, &dataend);
+ err = uhci_alloc_std_chain(sc, len, xfer, &data, &dataend);
if (err)
return (err);
dataend->td.td_status |= htole32(UHCI_TD_IOC);
struct uhci_soft_td *data, *dataend;
struct uhci_soft_qh *sqh;
usbd_status err;
- int isread, endpt;
+ int endpt;
int i, s;
if (sc->sc_bus.dying)
#endif
endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
- isread = UE_GET_DIR(endpt) == UE_DIR_IN;
- upipe->u.intr.isread = isread;
+ upipe->u.intr.isread = usbd_xfer_isread(xfer);
- err = uhci_alloc_std_chain(upipe, sc, xfer->length, isread,
- xfer->flags, &xfer->dmabuf, &data,
- &dataend);
+ err = uhci_alloc_std_chain(sc, xfer->length, xfer, &data, &dataend);
if (err)
return (err);
u_int len;
u_int32_t ls;
usbd_status err;
- int isread;
int s;
DPRINTFN(3,("uhci_device_request type=0x%02x, request=0x%02x, "
addr, endpt));
ls = xfer->device->speed == USB_SPEED_LOW ? UHCI_TD_LS : 0;
- isread = req->bmRequestType & UT_READ;
len = UGETW(req->wLength);
setup = upipe->u.ctl.setup;
/* Set up data transaction */
if (len != 0) {
upipe->nexttoggle = 1;
- err = uhci_alloc_std_chain(upipe, sc, len, isread, xfer->flags,
- &xfer->dmabuf, &data, &dataend);
+ err = uhci_alloc_std_chain(sc, len, xfer, &data, &dataend);
if (err)
return (err);
next = data;
stat->td.td_link = htole32(UHCI_PTR_T);
stat->td.td_status = htole32(UHCI_TD_SET_ERRCNT(3) | ls |
UHCI_TD_ACTIVE | UHCI_TD_IOC);
- stat->td.td_token =
- htole32(isread ? UHCI_TD_OUT(0, endpt, addr, 1) :
- UHCI_TD_IN (0, endpt, addr, 1));
+ stat->td.td_token = htole32(usbd_xfer_isread(xfer) ?
+ UHCI_TD_OUT(0, endpt, addr, 1) : UHCI_TD_IN (0, endpt, addr, 1));
stat->td.td_buffer = htole32(0);
#ifdef UHCI_DEBUG
DPRINTFN(5,("uhci_device_intr_done: requeuing\n"));
/* This alloc cannot fail since we freed the chain above. */
- uhci_alloc_std_chain(upipe, sc, xfer->length,
- upipe->u.intr.isread, xfer->flags,
- &xfer->dmabuf, &data, &dataend);
+ uhci_alloc_std_chain(sc, xfer->length, xfer, &data, &dataend);
dataend->td.td_status |= htole32(UHCI_TD_IOC);
#ifdef UHCI_DEBUG