PERFORCE change 163516 for review
Andrew Thompson
thompsa at FreeBSD.org
Thu Jun 4 19:47:25 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=163516
Change 163516 by thompsa at thompsa_burger on 2009/06/04 19:47:02
Checkpoint buffer WIP. Basic operation works, many things broken.
Affected files ...
.. //depot/projects/usb_buf/src/sys/dev/usb/controller/ehci.c#8 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/input/uhid.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/input/ukbd.c#7 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/input/ums.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/misc/udbp.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/net/if_aue.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/net/if_axe.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/net/if_cdce.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/net/if_cue.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/net/if_kue.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/net/if_rue.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/net/if_udav.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/u3g.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/uark.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/ubsa.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/ubser.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/uchcom.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/ucycom.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/ufoma.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/uftdi.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/ugensa.c#7 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/uipaq.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/ulpt.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/umct.c#7 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/umodem.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/umoscom.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/uplcom.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/uslcom.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/uvisor.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/uvscom.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/storage/umass.c#7 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/storage/urio.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/storage/ustorage_fs.c#7 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_busdma.c#7 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_compat_linux.c#7 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_controller.h#7 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_core.h#8 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_debug.c#7 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_debug.h#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_device.c#9 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_device.h#8 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_generic.c#8 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_handle_request.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_hub.c#8 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_msctest.c#5 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_request.c#10 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_transfer.c#8 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_transfer.h#7 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/wlan/if_rum.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/wlan/if_uath.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/wlan/if_upgt.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/wlan/if_ural.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/wlan/if_urtw.c#3 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/wlan/if_zyd.c#7 edit
Differences ...
==== //depot/projects/usb_buf/src/sys/dev/usb/controller/ehci.c#8 (text+ko) ====
@@ -70,7 +70,7 @@
((uint8_t *)&(((ehci_softc_t *)0)->sc_bus))))
#if USB_DEBUG
-static int ehcidebug = 100;
+static int ehcidebug = 0;
static int ehcinohighspeed = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, ehci, CTLFLAG_RW, 0, "USB ehci");
@@ -956,6 +956,10 @@
{
struct usb_pipe *pipe = urb->ub_pipe;
+ USB_BUS_LOCK_ASSERT(pipe->bus, MA_OWNED);
+
+ pipe->urb_curr = urb;
+
/* check for early completion */
if (ehci_check_transfer(urb)) {
return;
@@ -1132,7 +1136,7 @@
uint32_t status;
uint16_t len;
- td = urb->td_transfer_cache;
+ td = pipe->td_transfer_cache;
td_alt_next = td->alt_next;
if (urb->aframes != urb->nframes) {
@@ -1158,7 +1162,7 @@
urb->frlengths[urb->aframes] += td->len - len;
}
/* Check for last transfer */
- if (((void *)td) == urb->td_transfer_last) {
+ if (((void *)td) == pipe->td_transfer_last) {
td = NULL;
break;
}
@@ -1170,7 +1174,7 @@
}
/* Check for short transfer */
if (len > 0) {
- if (urb->flags_int.short_frames_ok) {
+ if (pipe->flags_int.short_frames_ok) {
/* follow alt next */
td = td->alt_next;
} else {
@@ -1189,7 +1193,7 @@
/* update transfer cache */
- urb->td_transfer_cache = td;
+ pipe->td_transfer_cache = td;
/* update data toggle */
@@ -1229,23 +1233,23 @@
if (ehcidebug > 10) {
ehci_softc_t *sc = EHCI_BUS2SC(pipe->xroot->bus);
- ehci_dump_sqtds(sc, urb->td_transfer_first);
+ ehci_dump_sqtds(sc, pipe->td_transfer_first);
}
#endif
/* reset scanner */
- urb->td_transfer_cache = urb->td_transfer_first;
+ pipe->td_transfer_cache = pipe->td_transfer_first;
- if (urb->flags_int.control_xfr) {
+ if (pipe->flags_int.control_xfr) {
- if (urb->flags_int.control_hdr) {
+ if (pipe->flags_int.control_hdr) {
err = ehci_non_isoc_done_sub(urb);
}
urb->aframes = 1;
- if (urb->td_transfer_cache == NULL) {
+ if (pipe->td_transfer_cache == NULL) {
goto done;
}
}
@@ -1254,13 +1258,13 @@
err = ehci_non_isoc_done_sub(urb);
urb->aframes++;
- if (urb->td_transfer_cache == NULL) {
+ if (pipe->td_transfer_cache == NULL) {
goto done;
}
}
- if (urb->flags_int.control_xfr &&
- !urb->flags_int.control_act) {
+ if (pipe->flags_int.control_xfr &&
+ !pipe->flags_int.control_act) {
err = ehci_non_isoc_done_sub(urb);
}
@@ -1279,7 +1283,7 @@
ehci_check_transfer(struct usb_urb *urb)
{
struct usb_pipe *pipe = urb->ub_pipe;
- struct usb_pipe_methods *methods = pipe->endpoint->methods;
+ struct usb_pipe_methods *methods = pipe->methods;
ehci_softc_t *sc = EHCI_BUS2SC(pipe->xroot->bus);
uint32_t status;
@@ -1291,13 +1295,13 @@
/* isochronous full speed transfer */
- td = urb->td_transfer_last;
+ td = pipe->td_transfer_last;
usb2_pc_cpu_invalidate(td->page_cache);
status = hc32toh(sc, td->sitd_status);
/* also check if first is complete */
- td = urb->td_transfer_first;
+ td = pipe->td_transfer_first;
usb2_pc_cpu_invalidate(td->page_cache);
status |= hc32toh(sc, td->sitd_status);
@@ -1310,7 +1314,7 @@
/* isochronous high speed transfer */
- td = urb->td_transfer_last;
+ td = pipe->td_transfer_last;
usb2_pc_cpu_invalidate(td->page_cache);
status =
td->itd_status[0] | td->itd_status[1] |
@@ -1319,7 +1323,7 @@
td->itd_status[6] | td->itd_status[7];
/* also check first transfer */
- td = urb->td_transfer_first;
+ td = pipe->td_transfer_first;
usb2_pc_cpu_invalidate(td->page_cache);
status |=
td->itd_status[0] | td->itd_status[1] |
@@ -1341,7 +1345,7 @@
* check whether there is an error somewhere in the middle,
* or whether there was a short packet (SPD and not ACTIVE)
*/
- td = urb->td_transfer_cache;
+ td = pipe->td_transfer_cache;
while (1) {
usb2_pc_cpu_invalidate(td->page_cache);
@@ -1352,13 +1356,13 @@
*/
if (status & EHCI_QTD_ACTIVE) {
/* update cache */
- urb->td_transfer_cache = td;
+ pipe->td_transfer_cache = td;
goto done;
}
/*
* last transfer descriptor makes the transfer done
*/
- if (((void *)td) == urb->td_transfer_last) {
+ if (((void *)td) == pipe->td_transfer_last) {
break;
}
/*
@@ -1372,7 +1376,7 @@
* packet also makes the transfer done
*/
if (EHCI_QTD_GET_BYTES(status)) {
- if (urb->flags_int.short_frames_ok) {
+ if (pipe->flags_int.short_frames_ok) {
/* follow alt next */
if (td->alt_next) {
td = td->alt_next;
@@ -1551,6 +1555,7 @@
td = temp->td;
td_next = temp->td_next;
+ //printf("%s: td %p td_next %p td_nextnext %p\n", __func__, td, td_next, td_next->obj_next);
while (1) {
@@ -1583,6 +1588,7 @@
td = td_next;
td_next = td->obj_next;
+ //printf("%s1: td %p td_next %p\n", __func__, td, td_next);
/* check if we are pre-computing */
@@ -1684,6 +1690,7 @@
}
if (precompute) {
+ //printf("done precompute\n");
precompute = 0;
/* setup alt next pointer, if any */
@@ -1730,21 +1737,22 @@
temp.sc = EHCI_BUS2SC(pipe->xroot->bus);
/* toggle the DMA set we are using */
- urb->flags_int.curr_dma_set ^= 1;
+ pipe->curr_dma_set ^= 1;
/* get next DMA set */
- td = urb->td_start[urb->flags_int.curr_dma_set];
+ td = pipe->td_start[pipe->curr_dma_set];
- urb->td_transfer_first = td;
- urb->td_transfer_cache = td;
+ KASSERT(td != NULL, ("td is null, dma = %d", pipe->curr_dma_set));
+ pipe->td_transfer_first = td;
+ pipe->td_transfer_cache = td;
temp.td = NULL;
temp.td_next = td;
temp.qtd_status = 0;
temp.last_frame = 0;
- temp.setup_alt_next = urb->flags_int.short_frames_ok;
+ temp.setup_alt_next = pipe->flags_int.short_frames_ok;
- if (urb->flags_int.control_xfr) {
+ if (pipe->flags_int.control_xfr) {
if (pipe->endpoint->toggle_next) {
/* DATA1 is next */
temp.qtd_status |=
@@ -1762,8 +1770,8 @@
}
/* check if we should prepend a setup message */
- if (urb->flags_int.control_xfr) {
- if (urb->flags_int.control_hdr) {
+ if (pipe->flags_int.control_xfr) {
+ if (pipe->flags_int.control_hdr) {
temp.qtd_status &=
htohc32(temp.sc, EHCI_QTD_SET_CERR(3));
@@ -1778,7 +1786,7 @@
/* check for last frame */
if (urb->nframes == 1) {
/* no STATUS stage yet, SETUP is last */
- if (urb->flags_int.control_act) {
+ if (pipe->flags_int.control_act) {
temp.last_frame = 1;
temp.setup_alt_next = 0;
}
@@ -1800,9 +1808,9 @@
x++;
if (x == urb->nframes) {
- if (urb->flags_int.control_xfr) {
+ if (pipe->flags_int.control_xfr) {
/* no STATUS stage yet, DATA is last */
- if (urb->flags_int.control_act) {
+ if (pipe->flags_int.control_act) {
temp.last_frame = 1;
temp.setup_alt_next = 0;
}
@@ -1844,8 +1852,8 @@
/* check if we should append a status stage */
- if (urb->flags_int.control_xfr &&
- !urb->flags_int.control_act) {
+ if (pipe->flags_int.control_xfr &&
+ !pipe->flags_int.control_act) {
/*
* Send a DATA1 message and invert the current endpoint
@@ -1882,20 +1890,20 @@
/* must have at least one frame! */
- urb->td_transfer_last = td;
+ pipe->td_transfer_last = td;
#if USB_DEBUG
if (ehcidebug > 8) {
DPRINTF("nexttog=%d; data before transfer:\n",
pipe->endpoint->toggle_next);
ehci_dump_sqtds(temp.sc,
- urb->td_transfer_first);
+ pipe->td_transfer_first);
}
#endif
- methods = pipe->endpoint->methods;
+ methods = pipe->methods;
- qh = urb->qh_start[urb->flags_int.curr_dma_set];
+ qh = pipe->qh_start[pipe->curr_dma_set];
/* the "qh_link" field is filled when the QH is added */
@@ -1955,7 +1963,7 @@
htohc32(temp.sc, EHCI_QTD_SET_TOGGLE(1));
}
}
- td = urb->td_transfer_first;
+ td = pipe->td_transfer_first;
qh->qh_qtd.qtd_next = td->qtd_self;
qh->qh_qtd.qtd_altnext =
@@ -2003,7 +2011,7 @@
uint32_t status;
uint32_t *plen = urb->frlengths;
uint16_t len = 0;
- ehci_sitd_t *td = urb->td_transfer_first;
+ ehci_sitd_t *td = pipe->td_transfer_first;
ehci_sitd_t **pp_last = &sc->sc_isoc_fs_p_last[pipe->qh_pos];
DPRINTFN(13, "urb=%p endpoint=%p transfer done\n",
@@ -2058,7 +2066,7 @@
uint32_t *plen = urb->frlengths;
uint16_t len = 0;
uint8_t td_no = 0;
- ehci_itd_t *td = urb->td_transfer_first;
+ ehci_itd_t *td = pipe->td_transfer_first;
ehci_itd_t **pp_last = &sc->sc_isoc_hs_p_last[pipe->qh_pos];
DPRINTFN(13, "urb=%p endpoint=%p transfer done\n",
@@ -2122,7 +2130,7 @@
ehci_device_done(struct usb_urb *urb, usb_error_t error)
{
struct usb_pipe *pipe = urb->ub_pipe;
- struct usb_pipe_methods *methods = pipe->endpoint->methods;
+ struct usb_pipe_methods *methods = pipe->methods;
ehci_softc_t *sc = EHCI_BUS2SC(pipe->xroot->bus);
USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
@@ -2130,6 +2138,12 @@
DPRINTFN(2, "urb=%p, endpoint=%p, error=%d\n",
urb, pipe->endpoint, error);
+ if (urb != pipe->urb_curr) {
+ printf("urb %p wasnt the current one\n", urb);
+ usb2_transfer_done(urb, error);
+ return;
+ }
+
if ((methods == &ehci_device_bulk_methods) ||
(methods == &ehci_device_ctrl_methods)) {
#if USB_DEBUG
@@ -2137,59 +2151,106 @@
DPRINTF("nexttog=%d; data after transfer:\n",
pipe->endpoint->toggle_next);
ehci_dump_sqtds(sc,
- urb->td_transfer_first);
+ pipe->td_transfer_first);
}
#endif
- EHCI_REMOVE_QH(urb->qh_start[urb->flags_int.curr_dma_set],
+ EHCI_REMOVE_QH(pipe->qh_start[pipe->curr_dma_set],
sc->sc_async_p_last);
}
if (methods == &ehci_device_intr_methods) {
- EHCI_REMOVE_QH(urb->qh_start[urb->flags_int.curr_dma_set],
+ EHCI_REMOVE_QH(pipe->qh_start[pipe->curr_dma_set],
sc->sc_intr_p_last[pipe->qh_pos]);
}
/*
* Only finish isochronous transfers once which will update
* "urb->frlengths".
*/
- if (urb->td_transfer_first &&
- urb->td_transfer_last) {
+ if (pipe->td_transfer_first &&
+ pipe->td_transfer_last) {
if (methods == &ehci_device_isoc_fs_methods) {
ehci_isoc_fs_done(sc, urb);
}
if (methods == &ehci_device_isoc_hs_methods) {
ehci_isoc_hs_done(sc, urb);
}
- urb->td_transfer_first = NULL;
- urb->td_transfer_last = NULL;
+ pipe->td_transfer_first = NULL;
+ pipe->td_transfer_last = NULL;
}
- /* dequeue transfer and start next transfer */
+ pipe->urb_curr = NULL;
+ /* dequeue transfer */
usb2_transfer_done(urb, error);
+
+ /* Load next */
+ urb = TAILQ_FIRST(&pipe->urb_xmit_q);
+ if (error == 0 && urb != NULL) {
+ printf("LOAD NEXT %p\n", urb);
+ TAILQ_REMOVE(&pipe->urb_xmit_q, urb, ub_next);
+ error = (pipe->methods->load)(urb);
+ if (error)
+ usb2_transfer_done(urb, error);
+ }
}
-/*------------------------------------------------------------------------*
- * ehci bulk support
- *------------------------------------------------------------------------*/
static void
-ehci_device_bulk_open(struct usb_urb *urb)
+ehci_urb_load(struct usb_urb *urb)
{
- return;
+ struct usb_pipe *pipe = urb->ub_pipe;
+ usb_error_t error;
+
+ USB_BUS_LOCK(pipe->bus);
+
+ if (pipe->urb_curr != NULL || TAILQ_FIRST(&pipe->urb_xmit_q) != NULL) {
+ TAILQ_INSERT_TAIL(&pipe->urb_xmit_q, urb, ub_next);
+ USB_BUS_UNLOCK(pipe->bus);
+ return;
+ }
+
+ /* Rock n' Roll */
+ error = (pipe->methods->load)(urb);
+ USB_BUS_UNLOCK(pipe->bus);
+ if (error)
+ usb2_transfer_done(urb, error);
}
static void
-ehci_device_bulk_close(struct usb_urb *urb)
+ehci_pipe_unload(struct usb_pipe *pipe)
{
- ehci_device_done(urb, USB_ERR_CANCELLED);
+ struct usb_urb *urb;
+
+ USB_BUS_LOCK_ASSERT(pipe->bus, MA_OWNED);
+
+ if (pipe->urb_curr != NULL) {
+ ehci_device_done(pipe->urb_curr, USB_ERR_CANCELLED);
+ pipe->urb_curr = NULL;
+ }
+ /* Flush queued urbs */
+ while ((urb = TAILQ_FIRST(&pipe->urb_xmit_q)) != NULL) {
+ TAILQ_REMOVE(&pipe->urb_xmit_q, urb, ub_next);
+ usb2_transfer_done(urb, USB_ERR_CANCELLED);
+ }
}
+/*------------------------------------------------------------------------*
+ * ehci bulk support
+ *------------------------------------------------------------------------*/
static void
-ehci_device_bulk_enter(struct usb_urb *urb)
+ehci_device_bulk_open(struct usb_pipe *pipe)
{
+ KASSERT(TAILQ_FIRST(&pipe->urb_xmit_q) == NULL, ("corrupt q"));
return;
}
static void
-ehci_device_bulk_start(struct usb_urb *urb)
+ehci_device_bulk_close(struct usb_pipe *pipe)
+{
+ USB_BUS_LOCK(pipe->bus);
+ ehci_pipe_unload(pipe);
+ USB_BUS_UNLOCK(pipe->bus);
+}
+
+static usb_error_t
+ehci_device_bulk_load(struct usb_urb *urb)
{
struct usb_pipe *pipe = urb->ub_pipe;
ehci_softc_t *sc = EHCI_BUS2SC(pipe->xroot->bus);
@@ -2208,40 +2269,41 @@
temp = EOREAD4(sc, EHCI_USBCMD);
if (!(temp & EHCI_CMD_IAAD))
EOWRITE4(sc, EHCI_USBCMD, temp | EHCI_CMD_IAAD);
+
+ /* put transfer on interrupt queue */
+ ehci_transfer_intr_enqueue(urb);
+ return (0);
}
struct usb_pipe_methods ehci_device_bulk_methods =
{
.open = ehci_device_bulk_open,
.close = ehci_device_bulk_close,
- .enter = ehci_device_bulk_enter,
- .start = ehci_device_bulk_start,
+ .enqueue = ehci_urb_load,
+ .load = ehci_device_bulk_load,
};
/*------------------------------------------------------------------------*
* ehci control support
*------------------------------------------------------------------------*/
static void
-ehci_device_ctrl_open(struct usb_urb *urb)
+ehci_device_ctrl_open(struct usb_pipe *pipe)
{
+ KASSERT(TAILQ_FIRST(&pipe->urb_xmit_q) == NULL, ("corrupt q"));
return;
}
static void
-ehci_device_ctrl_close(struct usb_urb *urb)
+ehci_device_ctrl_close(struct usb_pipe *pipe)
{
- ehci_device_done(urb, USB_ERR_CANCELLED);
+ USB_BUS_LOCK(pipe->bus);
+ ehci_pipe_unload(pipe);
+ USB_BUS_UNLOCK(pipe->bus);
}
-static void
-ehci_device_ctrl_enter(struct usb_urb *urb)
+static usb_error_t
+ehci_device_ctrl_load(struct usb_urb *urb)
{
- return;
-}
-
-static void
-ehci_device_ctrl_start(struct usb_urb *urb)
-{
struct usb_pipe *pipe = urb->ub_pipe;
ehci_softc_t *sc = EHCI_BUS2SC(pipe->xroot->bus);
@@ -2250,31 +2312,34 @@
/* put transfer on interrupt queue */
ehci_transfer_intr_enqueue(urb);
+ return (0);
}
struct usb_pipe_methods ehci_device_ctrl_methods =
{
.open = ehci_device_ctrl_open,
.close = ehci_device_ctrl_close,
- .enter = ehci_device_ctrl_enter,
- .start = ehci_device_ctrl_start,
+ .enqueue = ehci_urb_load,
+ .load = ehci_device_ctrl_load,
};
/*------------------------------------------------------------------------*
* ehci interrupt support
*------------------------------------------------------------------------*/
static void
-ehci_device_intr_open(struct usb_urb *urb)
+ehci_device_intr_open(struct usb_pipe *pipe)
{
- struct usb_pipe *pipe = urb->ub_pipe;
ehci_softc_t *sc = EHCI_BUS2SC(pipe->xroot->bus);
uint16_t best;
uint16_t bit;
uint16_t x;
uint8_t slot;
+ KASSERT(TAILQ_FIRST(&pipe->urb_xmit_q) == NULL, ("corrupt q"));
+
/* Allocate a microframe slot first: */
+ USB_BUS_LOCK(pipe->bus);
slot = usb2_intr_schedule_adjust
(pipe->xroot->udev, pipe->max_frame_size, USB_HS_MICRO_FRAMES_MAX);
@@ -2312,34 +2377,30 @@
sc->sc_intr_stat[best]++;
pipe->qh_pos = best;
+ USB_BUS_UNLOCK(pipe->bus);
DPRINTFN(3, "best=%d interval=%d\n",
best, pipe->interval);
}
static void
-ehci_device_intr_close(struct usb_urb *urb)
+ehci_device_intr_close(struct usb_pipe *pipe)
{
- struct usb_pipe *pipe = urb->ub_pipe;
ehci_softc_t *sc = EHCI_BUS2SC(pipe->xroot->bus);
uint8_t slot;
+ USB_BUS_LOCK(pipe->bus);
slot = usb2_intr_schedule_adjust
(pipe->xroot->udev, -(pipe->max_frame_size), pipe->usb2_uframe);
sc->sc_intr_stat[pipe->qh_pos]--;
- ehci_device_done(urb, USB_ERR_CANCELLED);
+ ehci_pipe_unload(pipe);
+ USB_BUS_UNLOCK(pipe->bus);
}
-static void
-ehci_device_intr_enter(struct usb_urb *urb)
-{
- return;
-}
-
-static void
-ehci_device_intr_start(struct usb_urb *urb)
+static usb_error_t
+ehci_device_intr_load(struct usb_urb *urb)
{
struct usb_pipe *pipe = urb->ub_pipe;
ehci_softc_t *sc = EHCI_BUS2SC(pipe->xroot->bus);
@@ -2349,28 +2410,31 @@
/* put transfer on interrupt queue */
ehci_transfer_intr_enqueue(urb);
+ return (0);
}
struct usb_pipe_methods ehci_device_intr_methods =
{
.open = ehci_device_intr_open,
.close = ehci_device_intr_close,
- .enter = ehci_device_intr_enter,
- .start = ehci_device_intr_start,
+ .enqueue = ehci_urb_load,
+ .load = ehci_device_intr_load,
};
/*------------------------------------------------------------------------*
* ehci full speed isochronous support
*------------------------------------------------------------------------*/
static void
-ehci_device_isoc_fs_open(struct usb_urb *urb)
+ehci_device_isoc_fs_open(struct usb_pipe *pipe)
{
- struct usb_pipe *pipe = urb->ub_pipe;
ehci_softc_t *sc = EHCI_BUS2SC(pipe->xroot->bus);
ehci_sitd_t *td;
uint32_t sitd_portaddr;
uint8_t ds;
+ KASSERT(TAILQ_FIRST(&pipe->urb_xmit_q) == NULL, ("corrupt q"));
+
+ USB_BUS_LOCK(pipe->bus);
sitd_portaddr =
EHCI_SITD_SET_ADDR(pipe->address) |
EHCI_SITD_SET_ENDPT(UE_GET_ADDR(pipe->endpointno)) |
@@ -2386,7 +2450,7 @@
for (ds = 0; ds != 2; ds++) {
- for (td = urb->td_start[ds]; td; td = td->obj_next) {
+ for (td = pipe->td_start[ds]; td; td = td->obj_next) {
td->sitd_portaddr = sitd_portaddr;
@@ -2402,16 +2466,19 @@
usb2_pc_cpu_flush(td->page_cache);
}
}
+ USB_BUS_UNLOCK(pipe->bus);
}
static void
-ehci_device_isoc_fs_close(struct usb_urb *urb)
+ehci_device_isoc_fs_close(struct usb_pipe *pipe)
{
- ehci_device_done(urb, USB_ERR_CANCELLED);
+ USB_BUS_LOCK(pipe->bus);
+ ehci_pipe_unload(pipe);
+ USB_BUS_UNLOCK(pipe->bus);
}
-static void
-ehci_device_isoc_fs_enter(struct usb_urb *urb)
+static usb_error_t
+ehci_device_isoc_fs_load(struct usb_urb *urb)
{
struct usb_page_search buf_res;
struct usb_pipe *pipe = urb->ub_pipe;
@@ -2488,11 +2555,11 @@
plen = urb->frlengths;
/* toggle the DMA set we are using */
- urb->flags_int.curr_dma_set ^= 1;
+ pipe->curr_dma_set ^= 1;
/* get next DMA set */
- td = urb->td_start[urb->flags_int.curr_dma_set];
- urb->td_transfer_first = td;
+ td = pipe->td_start[pipe->curr_dma_set];
+ pipe->td_transfer_first = td;
pp_last = &sc->sc_isoc_fs_p_last[pipe->endpoint->isoc_next];
@@ -2622,45 +2689,44 @@
td = td->obj_next;
}
- urb->td_transfer_last = td_last;
+ pipe->td_transfer_last = td_last;
/* update isoc_next */
pipe->endpoint->isoc_next = (pp_last - &sc->sc_isoc_fs_p_last[0]) &
(EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
-}
-static void
-ehci_device_isoc_fs_start(struct usb_urb *urb)
-{
/* put transfer on interrupt queue */
ehci_transfer_intr_enqueue(urb);
+ return (0);
}
struct usb_pipe_methods ehci_device_isoc_fs_methods =
{
.open = ehci_device_isoc_fs_open,
.close = ehci_device_isoc_fs_close,
- .enter = ehci_device_isoc_fs_enter,
- .start = ehci_device_isoc_fs_start,
+ .enqueue = ehci_urb_load,
+ .load = ehci_device_isoc_fs_load,
};
/*------------------------------------------------------------------------*
* ehci high speed isochronous support
*------------------------------------------------------------------------*/
static void
-ehci_device_isoc_hs_open(struct usb_urb *urb)
+ehci_device_isoc_hs_open(struct usb_pipe *pipe)
{
- struct usb_pipe *pipe = urb->ub_pipe;
ehci_softc_t *sc = EHCI_BUS2SC(pipe->xroot->bus);
ehci_itd_t *td;
uint32_t temp;
uint8_t ds;
+ KASSERT(TAILQ_FIRST(&pipe->urb_xmit_q) == NULL, ("corrupt q"));
+
/* initialize all TD's */
+ USB_BUS_LOCK(pipe->bus);
for (ds = 0; ds != 2; ds++) {
- for (td = urb->td_start[ds]; td; td = td->obj_next) {
+ for (td = pipe->td_start[ds]; td; td = td->obj_next) {
/* set TD inactive */
td->itd_status[0] = 0;
@@ -2693,16 +2759,19 @@
usb2_pc_cpu_flush(td->page_cache);
}
}
+ USB_BUS_UNLOCK(pipe->bus);
}
static void
-ehci_device_isoc_hs_close(struct usb_urb *urb)
+ehci_device_isoc_hs_close(struct usb_pipe *pipe)
{
- ehci_device_done(urb, USB_ERR_CANCELLED);
+ USB_BUS_LOCK(pipe->bus);
+ ehci_pipe_unload(pipe);
+ USB_BUS_UNLOCK(pipe->bus);
}
-static void
-ehci_device_isoc_hs_enter(struct usb_urb *urb)
+static usb_error_t
+ehci_device_isoc_hs_load(struct usb_urb *urb)
{
struct usb_page_search buf_res;
struct usb_pipe *pipe = urb->ub_pipe;
@@ -2776,11 +2845,11 @@
plen = urb->frlengths;
/* toggle the DMA set we are using */
- urb->flags_int.curr_dma_set ^= 1;
+ pipe->curr_dma_set ^= 1;
/* get next DMA set */
- td = urb->td_start[urb->flags_int.curr_dma_set];
- urb->td_transfer_first = td;
+ td = pipe->td_start[pipe->curr_dma_set];
+ pipe->td_transfer_first = td;
pp_last = &sc->sc_isoc_hs_p_last[pipe->endpoint->isoc_next];
@@ -2890,26 +2959,23 @@
}
}
- urb->td_transfer_last = td_last;
+ pipe->td_transfer_last = td_last;
/* update isoc_next */
pipe->endpoint->isoc_next = (pp_last - &sc->sc_isoc_hs_p_last[0]) &
(EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
-}
-static void
-ehci_device_isoc_hs_start(struct usb_urb *urb)
-{
/* put transfer on interrupt queue */
ehci_transfer_intr_enqueue(urb);
+ return (0);
}
struct usb_pipe_methods ehci_device_isoc_hs_methods =
{
.open = ehci_device_isoc_hs_open,
.close = ehci_device_isoc_hs_close,
- .enter = ehci_device_isoc_hs_enter,
- .start = ehci_device_isoc_hs_start,
+ .enqueue = ehci_urb_load,
+ .load = ehci_device_isoc_hs_load,
};
/*------------------------------------------------------------------------*
@@ -3420,7 +3486,7 @@
/*
* compute maximum number of some structures
*/
- if (parm->methods == &ehci_device_ctrl_methods) {
+ if (pipe->methods == &ehci_device_ctrl_methods) {
/*
* The proof for the "nqtd" formula is illustrated like
@@ -3454,28 +3520,28 @@
parm->hc_max_packet_size = 0x400;
parm->hc_max_packet_count = 1;
parm->hc_max_frame_size = EHCI_QTD_PAYLOAD_MAX;
- (&pipe->urb0)->flags_int.bdma_enable = 1;
+ pipe->flags_int.bdma_enable = 1;
usb2_transfer_setup_sub(parm);
nqh = 1;
- nqtd = ((2 * (&pipe->urb0)->nframes) + 1 /* STATUS */
+ nqtd = ((2 * pipe->nframes) + 1 /* STATUS */
+ (pipe->max_data_length / pipe->max_hc_frame_size));
- } else if (parm->methods == &ehci_device_bulk_methods) {
+ } else if (pipe->methods == &ehci_device_bulk_methods) {
parm->hc_max_packet_size = 0x400;
parm->hc_max_packet_count = 1;
parm->hc_max_frame_size = EHCI_QTD_PAYLOAD_MAX;
- (&pipe->urb0)->flags_int.bdma_enable = 1;
+ pipe->flags_int.bdma_enable = 1;
usb2_transfer_setup_sub(parm);
nqh = 1;
- nqtd = ((2 * (&pipe->urb0)->nframes)
+ nqtd = ((2 * pipe->nframes)
+ (pipe->max_data_length / pipe->max_hc_frame_size));
- } else if (parm->methods == &ehci_device_intr_methods) {
+ } else if (pipe->methods == &ehci_device_intr_methods) {
if (parm->speed == USB_SPEED_HIGH) {
parm->hc_max_packet_size = 0x400;
@@ -3489,35 +3555,35 @@
}
parm->hc_max_frame_size = EHCI_QTD_PAYLOAD_MAX;
- (&pipe->urb0)->flags_int.bdma_enable = 1;
+ pipe->flags_int.bdma_enable = 1;
usb2_transfer_setup_sub(parm);
nqh = 1;
- nqtd = ((2 * (&pipe->urb0)->nframes)
+ nqtd = ((2 * pipe->nframes)
+ (pipe->max_data_length / pipe->max_hc_frame_size));
- } else if (parm->methods == &ehci_device_isoc_fs_methods) {
+ } else if (pipe->methods == &ehci_device_isoc_fs_methods) {
parm->hc_max_packet_size = 0x3FF;
parm->hc_max_packet_count = 1;
parm->hc_max_frame_size = 0x3FF;
- (&pipe->urb0)->flags_int.bdma_enable = 1;
+ pipe->flags_int.bdma_enable = 1;
usb2_transfer_setup_sub(parm);
- nsitd = (&pipe->urb0)->nframes;
+ nsitd = pipe->nframes;
- } else if (parm->methods == &ehci_device_isoc_hs_methods) {
+ } else if (pipe->methods == &ehci_device_isoc_hs_methods) {
parm->hc_max_packet_size = 0x400;
parm->hc_max_packet_count = 3;
parm->hc_max_frame_size = 0xC00;
- (&pipe->urb0)->flags_int.bdma_enable = 1;
+ pipe->flags_int.bdma_enable = 1;
usb2_transfer_setup_sub(parm);
- nitd = ((&pipe->urb0)->nframes + 7) / 8;
+ nitd = (pipe->nframes + 7) / 8;
} else {
@@ -3610,7 +3676,7 @@
usb2_pc_cpu_flush(pc + n);
}
}
- (&pipe->urb0)->td_start[(&pipe->urb0)->flags_int.curr_dma_set] = last_obj;
+ pipe->td_start[pipe->curr_dma_set] = last_obj;
last_obj = NULL;
@@ -3638,10 +3704,10 @@
usb2_pc_cpu_flush(pc + n);
}
}
- (&pipe->urb0)->qh_start[(&pipe->urb0)->flags_int.curr_dma_set] = last_obj;
+ pipe->qh_start[pipe->curr_dma_set] = last_obj;
- if (!(&pipe->urb0)->flags_int.curr_dma_set) {
- (&pipe->urb0)->flags_int.curr_dma_set = 1;
+ if (!pipe->curr_dma_set) {
+ pipe->curr_dma_set = 1;
goto alloc_dma_set;
}
}
@@ -3653,8 +3719,8 @@
}
static void
-ehci_pipe_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc,
- struct usb_endpoint *ep)
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list