Date: Thu, 4 Jun 2009 19:47:23 GMT From: Andrew Thompson <thompsa@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 163516 for review Message-ID: <200906041947.n54JlNHU028378@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=163516 Change 163516 by thompsa@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) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906041947.n54JlNHU028378>