Add a flag, USBD_FORCE_SHORT_XFER, to transfers. Using this flag will
force the last packet of a transfer to be smaller than the maximum packet size. The only time this matters is if the transfer size is a multiple of the maximum packet size, in which case a 0 length packet is sent last. Some weird devices require this behaviour to determine the end of a transfer.
This commit is contained in:
parent
d837d7a740
commit
537c04e5ee
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: ohci.c,v 1.60 2000/01/16 10:35:24 augustss Exp $ */
|
/* $NetBSD: ohci.c,v 1.61 2000/01/16 13:12:06 augustss Exp $ */
|
||||||
/* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */
|
/* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -123,7 +123,7 @@ static void ohci_free_std_chain __P((ohci_softc_t *,
|
|||||||
ohci_soft_td_t *, ohci_soft_td_t *));
|
ohci_soft_td_t *, ohci_soft_td_t *));
|
||||||
#endif
|
#endif
|
||||||
static usbd_status ohci_alloc_std_chain __P((struct ohci_pipe *,
|
static usbd_status ohci_alloc_std_chain __P((struct ohci_pipe *,
|
||||||
ohci_softc_t *, int, int, int, usb_dma_t *,
|
ohci_softc_t *, int, int, u_int16_t, usb_dma_t *,
|
||||||
ohci_soft_td_t *, ohci_soft_td_t **));
|
ohci_soft_td_t *, ohci_soft_td_t **));
|
||||||
|
|
||||||
static void ohci_shutdown __P((void *v));
|
static void ohci_shutdown __P((void *v));
|
||||||
@ -441,28 +441,32 @@ ohci_free_std(sc, std)
|
|||||||
}
|
}
|
||||||
|
|
||||||
usbd_status
|
usbd_status
|
||||||
ohci_alloc_std_chain(upipe, sc, len, rd, shortok, dma, sp, ep)
|
ohci_alloc_std_chain(opipe, sc, len, rd, flags, dma, sp, ep)
|
||||||
struct ohci_pipe *upipe;
|
struct ohci_pipe *opipe;
|
||||||
ohci_softc_t *sc;
|
ohci_softc_t *sc;
|
||||||
int len, rd, shortok;
|
int len, rd;
|
||||||
|
u_int16_t flags;
|
||||||
usb_dma_t *dma;
|
usb_dma_t *dma;
|
||||||
ohci_soft_td_t *sp, **ep;
|
ohci_soft_td_t *sp, **ep;
|
||||||
{
|
{
|
||||||
ohci_soft_td_t *next, *cur;
|
ohci_soft_td_t *next, *cur;
|
||||||
ohci_physaddr_t dataphys, dataphysend;
|
ohci_physaddr_t dataphys, dataphysend;
|
||||||
u_int32_t intr;
|
u_int32_t intr, tdflags;
|
||||||
int curlen;
|
int curlen;
|
||||||
|
|
||||||
DPRINTFN(len < 4096,("ohci_alloc_std_chain: start len=%d\n", len));
|
DPRINTFN(len < 4096,("ohci_alloc_std_chain: start len=%d\n", len));
|
||||||
cur = sp;
|
cur = sp;
|
||||||
dataphys = DMAADDR(dma);
|
dataphys = DMAADDR(dma);
|
||||||
dataphysend = OHCI_PAGE(dataphys + len - 1);
|
dataphysend = OHCI_PAGE(dataphys + len - 1);
|
||||||
|
tdflags =
|
||||||
|
(rd ? OHCI_TD_IN : OHCI_TD_OUT) |
|
||||||
|
OHCI_TD_NOCC | OHCI_TD_TOGGLE_CARRY |
|
||||||
|
(flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
next = ohci_alloc_std(sc);
|
next = ohci_alloc_std(sc);
|
||||||
if (next == 0) {
|
if (next == 0)
|
||||||
/* XXX free chain */
|
goto nomem;
|
||||||
return (USBD_NOMEM);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The OHCI hardware can handle at most one page crossing. */
|
/* The OHCI hardware can handle at most one page crossing. */
|
||||||
if (OHCI_PAGE(dataphys) == dataphysend ||
|
if (OHCI_PAGE(dataphys) == dataphysend ||
|
||||||
@ -481,10 +485,7 @@ ohci_alloc_std_chain(upipe, sc, len, rd, shortok, dma, sp, ep)
|
|||||||
len -= curlen;
|
len -= curlen;
|
||||||
|
|
||||||
intr = len == 0 ? OHCI_TD_SET_DI(1) : OHCI_TD_NOINTR;
|
intr = len == 0 ? OHCI_TD_SET_DI(1) : OHCI_TD_NOINTR;
|
||||||
cur->td.td_flags = LE(
|
cur->td.td_flags = LE(tdflags | intr);
|
||||||
(rd ? OHCI_TD_IN : OHCI_TD_OUT) | OHCI_TD_NOCC |
|
|
||||||
intr | OHCI_TD_TOGGLE_CARRY |
|
|
||||||
(shortok ? OHCI_TD_R : 0));
|
|
||||||
cur->td.td_cbp = LE(dataphys);
|
cur->td.td_cbp = LE(dataphys);
|
||||||
cur->nexttd = next;
|
cur->nexttd = next;
|
||||||
cur->td.td_nexttd = LE(next->physaddr);
|
cur->td.td_nexttd = LE(next->physaddr);
|
||||||
@ -499,10 +500,31 @@ ohci_alloc_std_chain(upipe, sc, len, rd, shortok, dma, sp, ep)
|
|||||||
dataphys += curlen;
|
dataphys += curlen;
|
||||||
cur = next;
|
cur = next;
|
||||||
}
|
}
|
||||||
|
if ((flags & USBD_FORCE_SHORT_XFER) &&
|
||||||
|
len % UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize) == 0) {
|
||||||
|
/* Force a 0 length transfer at the end. */
|
||||||
|
next = ohci_alloc_std(sc);
|
||||||
|
if (next == 0)
|
||||||
|
goto nomem;
|
||||||
|
|
||||||
|
cur->td.td_flags = LE(tdflags | OHCI_TD_SET_DI(1));
|
||||||
|
cur->td.td_cbp = 0; /* indicate 0 length packet */
|
||||||
|
cur->nexttd = next;
|
||||||
|
cur->td.td_nexttd = LE(next->physaddr);
|
||||||
|
cur->td.td_be = LE(dataphys - 1);
|
||||||
|
cur->len = 0;
|
||||||
|
cur->flags = 0;
|
||||||
|
cur = next;
|
||||||
|
DPRINTFN(2,("ohci_alloc_std_chain: add 0 xfer\n"));
|
||||||
|
}
|
||||||
cur->flags = OHCI_CALL_DONE | OHCI_ADD_LEN;
|
cur->flags = OHCI_CALL_DONE | OHCI_ADD_LEN;
|
||||||
*ep = next;
|
*ep = next;
|
||||||
|
|
||||||
return (USBD_NORMAL_COMPLETION);
|
return (USBD_NORMAL_COMPLETION);
|
||||||
|
|
||||||
|
nomem:
|
||||||
|
/* XXX free chain */
|
||||||
|
return (USBD_NOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -1706,6 +1728,7 @@ ohci_abort_xfer(xfer, status)
|
|||||||
DPRINTFN(1,("ohci_abort_xfer: stop ed=%p\n", sed));
|
DPRINTFN(1,("ohci_abort_xfer: stop ed=%p\n", sed));
|
||||||
sed->ed.ed_flags |= LE(OHCI_ED_SKIP); /* force hardware skip */
|
sed->ed.ed_flags |= LE(OHCI_ED_SKIP); /* force hardware skip */
|
||||||
|
|
||||||
|
#if 1
|
||||||
if (xfer->device->bus->intr_context) {
|
if (xfer->device->bus->intr_context) {
|
||||||
/* We have no process context, so we can't use tsleep(). */
|
/* We have no process context, so we can't use tsleep(). */
|
||||||
timeout(ohci_abort_xfer_end, xfer, hz / USB_FRAMES_PER_SECOND);
|
timeout(ohci_abort_xfer_end, xfer, hz / USB_FRAMES_PER_SECOND);
|
||||||
@ -1717,6 +1740,10 @@ ohci_abort_xfer(xfer, status)
|
|||||||
usb_delay_ms(opipe->pipe.device->bus, 1);
|
usb_delay_ms(opipe->pipe.device->bus, 1);
|
||||||
ohci_abort_xfer_end(xfer);
|
ohci_abort_xfer_end(xfer);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
delay(1000);
|
||||||
|
ohci_abort_xfer_end(xfer);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2361,8 +2388,7 @@ ohci_device_bulk_start(xfer)
|
|||||||
|
|
||||||
/* Allocate a chain of new TDs (including a new tail). */
|
/* Allocate a chain of new TDs (including a new tail). */
|
||||||
data = opipe->tail.td;
|
data = opipe->tail.td;
|
||||||
err = ohci_alloc_std_chain(opipe, sc, len, isread,
|
err = ohci_alloc_std_chain(opipe, sc, len, isread, xfer->flags,
|
||||||
xfer->flags & USBD_SHORT_XFER_OK,
|
|
||||||
&xfer->dmabuf, data, &tail);
|
&xfer->dmabuf, data, &tail);
|
||||||
if (err)
|
if (err)
|
||||||
return (err);
|
return (err);
|
||||||
@ -2678,7 +2704,71 @@ void
|
|||||||
ohci_device_isoc_enter(xfer)
|
ohci_device_isoc_enter(xfer)
|
||||||
usbd_xfer_handle xfer;
|
usbd_xfer_handle xfer;
|
||||||
{
|
{
|
||||||
printf("ohci_device_isoc_enter: not implemented\n");
|
struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
|
||||||
|
usbd_device_handle dev = opipe->pipe.device;
|
||||||
|
ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
|
||||||
|
ohci_soft_ed_t *sed = opipe->sed;
|
||||||
|
struct iso *iso = &opipe->u.iso;
|
||||||
|
ohci_soft_itd_t *sitd, *nsitd;
|
||||||
|
ohci_physaddr_t buf, offs;
|
||||||
|
int i, ncur, nframes;
|
||||||
|
int ncross;
|
||||||
|
int s;
|
||||||
|
|
||||||
|
s = splusb();
|
||||||
|
sitd = opipe->tail.itd;
|
||||||
|
buf = DMAADDR(&xfer->dmabuf);
|
||||||
|
sitd->itd.itd_bp0 = LE(buf & OHCI_ITD_PAGE_MASK);
|
||||||
|
nframes = xfer->nframes;
|
||||||
|
offs = buf & OHCI_ITD_OFFSET_MASK;
|
||||||
|
for (i = ncur = 0; i < nframes; i++, ncur++) {
|
||||||
|
if (ncur == OHCI_ITD_NOFFSET || /* all offsets used */
|
||||||
|
ncross > 1) { /* too many page crossings */
|
||||||
|
|
||||||
|
nsitd = ohci_alloc_sitd(sc);
|
||||||
|
if (nsitd == NULL) {
|
||||||
|
/* XXX what now? */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sitd->nextitd = nsitd;
|
||||||
|
sitd->itd.itd_nextitd = LE(nsitd->physaddr);
|
||||||
|
sitd->itd.itd_flags = LE(
|
||||||
|
OHCI_ITD_NOCC |
|
||||||
|
OHCI_ITD_SET_SF(iso->next) |
|
||||||
|
OHCI_ITD_NOINTR |
|
||||||
|
OHCI_ITD_SET_FC(OHCI_ITD_NOFFSET));
|
||||||
|
sitd->itd.itd_be = LE(LE(sitd->itd.itd_bp0) + offs - 1);
|
||||||
|
nsitd->itd.itd_bp0 = LE((buf + offs) & OHCI_ITD_PAGE_MASK);
|
||||||
|
sitd = nsitd;
|
||||||
|
iso->next = iso->next + ncur;
|
||||||
|
ncur = 0;
|
||||||
|
ncross = 0;
|
||||||
|
}
|
||||||
|
/* XXX byte order */
|
||||||
|
sitd->itd.itd_offset[i] =
|
||||||
|
offs | (ncross == 1 ? OHCI_ITD_PAGE_SELECT : 0);
|
||||||
|
offs += xfer->frlengths[i];
|
||||||
|
/* XXX update ncross */
|
||||||
|
}
|
||||||
|
nsitd = ohci_alloc_sitd(sc);
|
||||||
|
if (nsitd == NULL) {
|
||||||
|
/* XXX what now? */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sitd->nextitd = nsitd;
|
||||||
|
sitd->itd.itd_nextitd = LE(nsitd->physaddr);
|
||||||
|
sitd->itd.itd_flags = LE(
|
||||||
|
OHCI_ITD_NOCC |
|
||||||
|
OHCI_ITD_SET_SF(iso->next) |
|
||||||
|
OHCI_ITD_SET_DI(0) |
|
||||||
|
OHCI_ITD_SET_FC(ncur));
|
||||||
|
sitd->itd.itd_be = LE(LE(sitd->itd.itd_bp0) + offs - 1);
|
||||||
|
iso->next = iso->next + ncur;
|
||||||
|
|
||||||
|
opipe->tail.itd = nsitd;
|
||||||
|
sed->ed.ed_tailp = LE(nsitd->physaddr);
|
||||||
|
/* XXX update ED */
|
||||||
|
splx(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
usbd_status
|
usbd_status
|
||||||
@ -2693,7 +2783,6 @@ void
|
|||||||
ohci_device_isoc_abort(xfer)
|
ohci_device_isoc_abort(xfer)
|
||||||
usbd_xfer_handle xfer;
|
usbd_xfer_handle xfer;
|
||||||
{
|
{
|
||||||
printf("ohci_device_isoc_abort: not implemented\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: uhci.c,v 1.72 2000/01/16 10:27:51 augustss Exp $ */
|
/* $NetBSD: uhci.c,v 1.73 2000/01/16 13:12:05 augustss Exp $ */
|
||||||
/* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */
|
/* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -168,7 +168,7 @@ static void uhci_exit_ctl_q __P((uhci_softc_t *, uhci_soft_qh_t *));
|
|||||||
static void uhci_free_std_chain __P((uhci_softc_t *,
|
static void uhci_free_std_chain __P((uhci_softc_t *,
|
||||||
uhci_soft_td_t *, uhci_soft_td_t *));
|
uhci_soft_td_t *, uhci_soft_td_t *));
|
||||||
static usbd_status uhci_alloc_std_chain __P((struct uhci_pipe *,
|
static usbd_status uhci_alloc_std_chain __P((struct uhci_pipe *,
|
||||||
uhci_softc_t *, int, int, int, usb_dma_t *,
|
uhci_softc_t *, int, int, u_int16_t, usb_dma_t *,
|
||||||
uhci_soft_td_t **, uhci_soft_td_t **));
|
uhci_soft_td_t **, uhci_soft_td_t **));
|
||||||
static void uhci_timo __P((void *));
|
static void uhci_timo __P((void *));
|
||||||
static void uhci_waitintr __P((uhci_softc_t *,
|
static void uhci_waitintr __P((uhci_softc_t *,
|
||||||
@ -1375,10 +1375,11 @@ uhci_free_std_chain(sc, std, stdend)
|
|||||||
}
|
}
|
||||||
|
|
||||||
usbd_status
|
usbd_status
|
||||||
uhci_alloc_std_chain(upipe, sc, len, rd, shortok, dma, sp, ep)
|
uhci_alloc_std_chain(upipe, sc, len, rd, flags, dma, sp, ep)
|
||||||
struct uhci_pipe *upipe;
|
struct uhci_pipe *upipe;
|
||||||
uhci_softc_t *sc;
|
uhci_softc_t *sc;
|
||||||
int len, rd, shortok;
|
int len, rd;
|
||||||
|
u_int16_t flags;
|
||||||
usb_dma_t *dma;
|
usb_dma_t *dma;
|
||||||
uhci_soft_td_t **sp, **ep;
|
uhci_soft_td_t **sp, **ep;
|
||||||
{
|
{
|
||||||
@ -1390,20 +1391,22 @@ uhci_alloc_std_chain(upipe, sc, len, rd, shortok, dma, sp, ep)
|
|||||||
int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
|
int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
|
||||||
|
|
||||||
DPRINTFN(8, ("uhci_alloc_std_chain: addr=%d endpt=%d len=%d ls=%d "
|
DPRINTFN(8, ("uhci_alloc_std_chain: addr=%d endpt=%d len=%d ls=%d "
|
||||||
"shortok=%d\n", addr, UE_GET_ADDR(endpt), len,
|
"flags=0x%x\n", addr, UE_GET_ADDR(endpt), len,
|
||||||
upipe->pipe.device->lowspeed, shortok));
|
upipe->pipe.device->lowspeed, flags));
|
||||||
if (len == 0) {
|
|
||||||
*sp = *ep = 0;
|
|
||||||
DPRINTFN(-1,("uhci_alloc_std_chain: len=0\n"));
|
|
||||||
return (USBD_NORMAL_COMPLETION);
|
|
||||||
}
|
|
||||||
maxp = UGETW(upipe->pipe.endpoint->edesc->wMaxPacketSize);
|
maxp = UGETW(upipe->pipe.endpoint->edesc->wMaxPacketSize);
|
||||||
if (maxp == 0) {
|
if (maxp == 0) {
|
||||||
printf("uhci_alloc_std_chain: maxp=0\n");
|
printf("uhci_alloc_std_chain: maxp=0\n");
|
||||||
return (USBD_INVAL);
|
return (USBD_INVAL);
|
||||||
}
|
}
|
||||||
ntd = (len + maxp - 1) / maxp;
|
ntd = (len + maxp - 1) / maxp;
|
||||||
|
if ((flags & USBD_FORCE_SHORT_XFER) && len % maxp == 0)
|
||||||
|
ntd++;
|
||||||
DPRINTFN(10, ("uhci_alloc_std_chain: maxp=%d ntd=%d\n", maxp, ntd));
|
DPRINTFN(10, ("uhci_alloc_std_chain: maxp=%d ntd=%d\n", maxp, ntd));
|
||||||
|
if (ntd == 0) {
|
||||||
|
*sp = *ep = 0;
|
||||||
|
DPRINTFN(-1,("uhci_alloc_std_chain: ntd=0\n"));
|
||||||
|
return (USBD_NORMAL_COMPLETION);
|
||||||
|
}
|
||||||
tog = upipe->nexttoggle;
|
tog = upipe->nexttoggle;
|
||||||
if (ntd % 2 == 0)
|
if (ntd % 2 == 0)
|
||||||
tog ^= 1;
|
tog ^= 1;
|
||||||
@ -1414,7 +1417,7 @@ uhci_alloc_std_chain(upipe, sc, len, rd, shortok, dma, sp, ep)
|
|||||||
status = UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(3) | UHCI_TD_ACTIVE);
|
status = UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(3) | UHCI_TD_ACTIVE);
|
||||||
if (upipe->pipe.device->lowspeed)
|
if (upipe->pipe.device->lowspeed)
|
||||||
status |= UHCI_TD_LS;
|
status |= UHCI_TD_LS;
|
||||||
if (shortok)
|
if (flags & USBD_SHORT_XFER_OK)
|
||||||
status |= UHCI_TD_SPD;
|
status |= UHCI_TD_SPD;
|
||||||
for (i = ntd; i >= 0; i--) {
|
for (i = ntd; i >= 0; i--) {
|
||||||
p = uhci_alloc_std(sc);
|
p = uhci_alloc_std(sc);
|
||||||
@ -1433,7 +1436,8 @@ uhci_alloc_std_chain(upipe, sc, len, rd, shortok, dma, sp, ep)
|
|||||||
if (i == ntd) {
|
if (i == ntd) {
|
||||||
/* last TD */
|
/* last TD */
|
||||||
l = len % maxp;
|
l = len % maxp;
|
||||||
if (l == 0) l = maxp;
|
if (l == 0 && !(flags & USBD_FORCE_SHORT_XFER))
|
||||||
|
l = maxp;
|
||||||
*ep = p;
|
*ep = p;
|
||||||
} else
|
} else
|
||||||
l = maxp;
|
l = maxp;
|
||||||
@ -1510,9 +1514,8 @@ uhci_device_bulk_start(xfer)
|
|||||||
upipe->u.bulk.isread = isread;
|
upipe->u.bulk.isread = isread;
|
||||||
upipe->u.bulk.length = len;
|
upipe->u.bulk.length = len;
|
||||||
|
|
||||||
err = uhci_alloc_std_chain(upipe, sc, len, isread,
|
err = uhci_alloc_std_chain(upipe, sc, len, isread, xfer->flags,
|
||||||
xfer->flags & USBD_SHORT_XFER_OK,
|
&xfer->dmabuf, &data, &dataend);
|
||||||
&xfer->dmabuf, &data, &dataend);
|
|
||||||
if (err)
|
if (err)
|
||||||
return (err);
|
return (err);
|
||||||
dataend->td.td_status |= LE(UHCI_TD_IOC);
|
dataend->td.td_status |= LE(UHCI_TD_IOC);
|
||||||
@ -1597,7 +1600,7 @@ uhci_abort_xfer(xfer, status)
|
|||||||
|
|
||||||
xfer->hcpriv = ii;
|
xfer->hcpriv = ii;
|
||||||
|
|
||||||
#if 1
|
#if 0
|
||||||
/* Make sure hardware has completed. */
|
/* Make sure hardware has completed. */
|
||||||
if (xfer->device->bus->intr_context) {
|
if (xfer->device->bus->intr_context) {
|
||||||
/* We have no process context, so we can't use tsleep(). */
|
/* We have no process context, so we can't use tsleep(). */
|
||||||
@ -1719,9 +1722,8 @@ uhci_device_intr_start(xfer)
|
|||||||
panic("uhci_device_intr_transfer: a request\n");
|
panic("uhci_device_intr_transfer: a request\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
err = uhci_alloc_std_chain(upipe, sc, xfer->length, 1,
|
err = uhci_alloc_std_chain(upipe, sc, xfer->length, 1, xfer->flags,
|
||||||
xfer->flags & USBD_SHORT_XFER_OK,
|
&xfer->dmabuf, &data, &dataend);
|
||||||
&xfer->dmabuf, &data, &dataend);
|
|
||||||
if (err)
|
if (err)
|
||||||
return (err);
|
return (err);
|
||||||
dataend->td.td_status |= LE(UHCI_TD_IOC);
|
dataend->td.td_status |= LE(UHCI_TD_IOC);
|
||||||
@ -1875,9 +1877,8 @@ uhci_device_request(xfer)
|
|||||||
/* Set up data transaction */
|
/* Set up data transaction */
|
||||||
if (len != 0) {
|
if (len != 0) {
|
||||||
upipe->nexttoggle = 1;
|
upipe->nexttoggle = 1;
|
||||||
err = uhci_alloc_std_chain(upipe, sc, len, isread,
|
err = uhci_alloc_std_chain(upipe, sc, len, isread, xfer->flags,
|
||||||
xfer->flags & USBD_SHORT_XFER_OK,
|
&xfer->dmabuf, &data, &dataend);
|
||||||
&xfer->dmabuf, &data, &dataend);
|
|
||||||
if (err)
|
if (err)
|
||||||
return (err);
|
return (err);
|
||||||
next = data;
|
next = data;
|
||||||
@ -2282,8 +2283,7 @@ uhci_device_intr_done(xfer)
|
|||||||
uhci_soft_td_t *data, *dataend;
|
uhci_soft_td_t *data, *dataend;
|
||||||
|
|
||||||
/* This alloc cannot fail since we freed the chain above. */
|
/* This alloc cannot fail since we freed the chain above. */
|
||||||
uhci_alloc_std_chain(upipe, sc, xfer->length, 1,
|
uhci_alloc_std_chain(upipe, sc, xfer->length, 1, xfer->flags,
|
||||||
xfer->flags & USBD_SHORT_XFER_OK,
|
|
||||||
&xfer->dmabuf, &data, &dataend);
|
&xfer->dmabuf, &data, &dataend);
|
||||||
dataend->td.td_status |= LE(UHCI_TD_IOC);
|
dataend->td.td_status |= LE(UHCI_TD_IOC);
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: usbdi.h,v 1.36 2000/01/16 11:19:05 augustss Exp $ */
|
/* $NetBSD: usbdi.h,v 1.37 2000/01/16 13:12:05 augustss Exp $ */
|
||||||
/* $FreeBSD: src/sys/dev/usb/usbdi.h,v 1.18 1999/11/17 22:33:49 n_hibma Exp $ */
|
/* $FreeBSD: src/sys/dev/usb/usbdi.h,v 1.18 1999/11/17 22:33:49 n_hibma Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -80,6 +80,10 @@ typedef void (*usbd_callback) __P((usbd_xfer_handle, usbd_private_handle,
|
|||||||
#define USBD_NO_COPY 0x01 /* do not copy data to DMA buffer */
|
#define USBD_NO_COPY 0x01 /* do not copy data to DMA buffer */
|
||||||
#define USBD_SYNCHRONOUS 0x02 /* wait for completion */
|
#define USBD_SYNCHRONOUS 0x02 /* wait for completion */
|
||||||
/* in usb.h #define USBD_SHORT_XFER_OK 0x04*/ /* allow short reads */
|
/* in usb.h #define USBD_SHORT_XFER_OK 0x04*/ /* allow short reads */
|
||||||
|
#define USBD_FORCE_SHORT_XFER 0x08 /* force last short packet on write */
|
||||||
|
|
||||||
|
/* XXX Temporary hack XXX */
|
||||||
|
#define USBD_NO_TSLEEP 0x80 /* XXX use busy wait */
|
||||||
|
|
||||||
#define USBD_NO_TIMEOUT 0
|
#define USBD_NO_TIMEOUT 0
|
||||||
#define USBD_DEFAULT_TIMEOUT 5000 /* ms = 5 s */
|
#define USBD_DEFAULT_TIMEOUT 5000 /* ms = 5 s */
|
||||||
|
Loading…
Reference in New Issue
Block a user