PERFORCE change 129844 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Fri Nov 30 14:02:01 PST 2007
http://perforce.freebsd.org/chv.cgi?CH=129844
Change 129844 by hselasky at hselasky_laptop001 on 2007/11/30 22:01:33
Updates to OHCI according to change 129799 .
Affected files ...
.. //depot/projects/usb/src/sys/arm/at91/ohci_atmelarm.c#8 edit
.. //depot/projects/usb/src/sys/dev/usb/ohci.c#42 edit
.. //depot/projects/usb/src/sys/dev/usb/ohci.h#18 edit
.. //depot/projects/usb/src/sys/dev/usb/ohci_pci.c#26 edit
Differences ...
==== //depot/projects/usb/src/sys/arm/at91/ohci_atmelarm.c#8 (text) ====
@@ -71,10 +71,18 @@
if (sc == NULL) {
return (ENXIO);
}
- if (usbd_bus_mem_setup(&(sc->sc_ohci.sc_bus), device_get_dma_tag(dev),
- sizeof(*(sc->sc_ohci.sc_bus.hw_ptr.ohci)), 32, LOG2(OHCI_HCCA_ALIGN))) {
- device_printf(dev, "Could not allocate DMA-able memory\n");
- return (ENOMEM);
+ /* store parent DMA tag */
+
+ sc->sc_bus.dma_tag_parent = device_get_dma_tag(self);
+
+ /* get all DMA memory */
+
+ ohci_iterate_hw_softc(sc, &ohci_alloc_all);
+
+ if (sc->sc_alloc_failed) {
+ ohci_iterate_hw_softc(sc, &ohci_free_all);
+ usbd_dma_tag_unsetup(sc->sc_bus.dma_tag);
+ return ENOMEM;
}
sc->iclk = at91_pmc_clock_ref("ohci_clk");
sc->fclk = at91_pmc_clock_ref("uhpck");
@@ -195,7 +203,11 @@
sc->sc_ohci.sc_io_res);
sc->sc_ohci.sc_io_res = NULL;
}
- usbd_bus_mem_unsetup(&(sc->sc_ohci.sc_bus));
+ usbd_config_td_unsetup(&(sc->sc_config_td));
+
+ ohci_iterate_hw_softc(sc, &ohci_free_all);
+
+ usbd_dma_tag_unsetup(sc->sc_bus.dma_tag);
mtx_destroy(&(sc->sc_ohci.sc_bus.mtx));
==== //depot/projects/usb/src/sys/dev/usb/ohci.c#42 (text+ko) ====
@@ -123,14 +123,11 @@
static usbd_config_td_command_t ohci_root_ctrl_task;
static void ohci_root_ctrl_task_td(struct ohci_softc *sc, struct thread *ctd);
static void ohci_do_poll(struct usbd_bus *bus);
+static void ohci_device_done(struct usbd_xfer *xfer, usbd_status error);
static usbd_std_root_transfer_func_t ohci_root_intr_done;
static usbd_std_root_transfer_func_t ohci_root_ctrl_task_td_sub;
-#define SC_HW_PHYSADDR(sc,what) \
- ((sc)->sc_hw_page.physaddr + \
- POINTER_TO_UNSIGNED(&(((struct ohci_hw_softc *)0)->what)))
-
struct ohci_std_temp {
struct usbd_page_cache *pc;
ohci_td_t *td;
@@ -143,11 +140,76 @@
uint8_t setup_alt_next;
};
+static struct ohci_hcca *
+ohci_get_hcca(ohci_softc_t *sc)
+{
+ usbd_pc_cpu_invalidate(&(sc->sc_hw.hcca_pc));
+ return (sc->sc_hcca_p);
+}
+
+void
+ohci_iterate_hw_softc(ohci_softc_t *sc, ohci_iterate_cb_t *cb)
+{
+ uint32_t i;
+
+ cb(sc, &(sc->sc_hw.hcca_pc), &(sc->sc_hw.hcca_pg),
+ sizeof(ohci_hcca_t), OHCI_HCCA_ALIGN);
+
+ cb(sc, &(sc->sc_hw.ctrl_start_pc), &(sc->sc_hw.ctrl_start_pg),
+ sizeof(ohci_ed_t), OHCI_ED_ALIGN);
+
+ cb(sc, &(sc->sc_hw.bulk_start_pc), &(sc->sc_hw.bulk_start_pg),
+ sizeof(ohci_ed_t), OHCI_ED_ALIGN);
+
+ cb(sc, &(sc->sc_hw.isoc_start_pc), &(sc->sc_hw.isoc_start_pg),
+ sizeof(ohci_ed_t), OHCI_ED_ALIGN);
+
+ for (i = 0; i != OHCI_NO_EDS; i++) {
+ cb(sc, sc->sc_hw.intr_start_pc + i, sc->sc_hw.intr_start_pg + i,
+ sizeof(ohci_ed_t), OHCI_ED_ALIGN);
+ }
+ return;
+}
+
+void
+ohci_flush_all(ohci_softc_t *sc, struct usbd_page_cache *pc,
+ struct usbd_page *pg, uint32_t size, uint32_t align)
+{
+ usbd_pc_cpu_flush(pc);
+ return;
+}
+
+void
+ohci_alloc_all(ohci_softc_t *sc, struct usbd_page_cache *pc,
+ struct usbd_page *pg, uint32_t size, uint32_t align)
+{
+ if (usbd_dma_alloc_mem(sc->sc_bus.dma_tag_parent,
+ sc->sc_bus.dma_tag, pc, pg, size, align)) {
+ sc->sc_alloc_failed = 1;
+ }
+ return;
+}
+
+void
+ohci_free_all(ohci_softc_t *sc, struct usbd_page_cache *pc,
+ struct usbd_page *pg, uint32_t size, uint32_t align)
+{
+ usbd_dma_free_mem(pc);
+ return;
+}
+
static usbd_status
ohci_controller_init(ohci_softc_t *sc)
{
- int i;
- uint32_t s, ctl, ival, hcr, fm, per, desca;
+ struct usbd_page_search buf_res;
+ uint32_t i;
+ uint32_t s;
+ uint32_t ctl;
+ uint32_t ival;
+ uint32_t hcr;
+ uint32_t fm;
+ uint32_t per;
+ uint32_t desca;
/* Determine in what context we are running. */
ctl = OREAD4(sc, OHCI_CONTROL);
@@ -215,9 +277,15 @@
/* The controller is now in SUSPEND state, we have 2ms to finish. */
/* set up HC registers */
- OWRITE4(sc, OHCI_HCCA, SC_HW_PHYSADDR(sc, hcca));
- OWRITE4(sc, OHCI_CONTROL_HEAD_ED, SC_HW_PHYSADDR(sc, ctrl_start));
- OWRITE4(sc, OHCI_BULK_HEAD_ED, SC_HW_PHYSADDR(sc, bulk_start));
+ usbd_get_page(&(sc->sc_hw.hcca_pc), 0, &buf_res);
+ OWRITE4(sc, OHCI_HCCA, buf_res.physaddr);
+
+ usbd_get_page(&(sc->sc_hw.ctrl_start_pc), 0, &buf_res);
+ OWRITE4(sc, OHCI_CONTROL_HEAD_ED, buf_res.physaddr);
+
+ usbd_get_page(&(sc->sc_hw.bulk_start_pc), 0, &buf_res);
+ OWRITE4(sc, OHCI_BULK_HEAD_ED, buf_res.physaddr);
+
/* disable all interrupts and then switch on all desired interrupts */
OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS);
OWRITE4(sc, OHCI_INTERRUPT_ENABLE, sc->sc_eintrs | OHCI_MIE);
@@ -265,11 +333,28 @@
return (USBD_NORMAL_COMPLETION);
}
+static struct ohci_ed *
+ohci_init_ed(struct usbd_page_cache *pc)
+{
+ struct usbd_page_search buf_res;
+ struct ohci_ed *ed;
+
+ usbd_get_page(pc, 0, &buf_res);
+
+ ed = buf_res.buffer;
+
+ ed->ed_self = htole32(buf_res.physaddr);
+ ed->ed_flags = htole32(OHCI_ED_SKIP);
+ ed->page_cache = pc;
+
+ return (ed);
+}
+
usbd_status
ohci_init(ohci_softc_t *sc)
{
- struct ohci_hw_softc *hw_ptr;
- u_int i;
+ struct usbd_page_search buf_res;
+ uint16_t i;
uint16_t bit;
uint16_t x;
uint16_t y;
@@ -278,37 +363,24 @@
DPRINTF(("start\n"));
- hw_ptr = sc->sc_hw_ptr;
-
sc->sc_eintrs = OHCI_NORMAL_INTRS;
- usbd_page_cpu_invalidate(&(sc->sc_hw_page));
-
/*
- * setup self pointers
+ * Setup all ED's
*/
- hw_ptr->ctrl_start.ed_self = htole32(SC_HW_PHYSADDR(sc, ctrl_start));
- hw_ptr->ctrl_start.ed_flags = htole32(OHCI_ED_SKIP);
- hw_ptr->ctrl_start.page = &(sc->sc_hw_page);
- sc->sc_ctrl_p_last = &(hw_ptr->ctrl_start);
+
+ sc->sc_ctrl_p_last =
+ ohci_init_ed(&(sc->sc_hw.ctrl_start_pc));
- hw_ptr->bulk_start.ed_self = htole32(SC_HW_PHYSADDR(sc, bulk_start));
- hw_ptr->bulk_start.ed_flags = htole32(OHCI_ED_SKIP);
- hw_ptr->bulk_start.page = &(sc->sc_hw_page);
- sc->sc_bulk_p_last = &(hw_ptr->bulk_start);
+ sc->sc_bulk_p_last =
+ ohci_init_ed(&(sc->sc_hw.bulk_start_pc));
- hw_ptr->isoc_start.ed_self = htole32(SC_HW_PHYSADDR(sc, isoc_start));
- hw_ptr->isoc_start.ed_flags = htole32(OHCI_ED_SKIP);
- hw_ptr->isoc_start.page = &(sc->sc_hw_page);
- sc->sc_isoc_p_last = &(hw_ptr->isoc_start);
+ sc->sc_isoc_p_last =
+ ohci_init_ed(&(sc->sc_hw.isoc_start_pc));
- for (i = 0;
- i < OHCI_NO_EDS;
- i++) {
- hw_ptr->intr_start[i].ed_self = htole32(SC_HW_PHYSADDR(sc, intr_start[i]));
- hw_ptr->intr_start[i].ed_flags = htole32(OHCI_ED_SKIP);
- hw_ptr->intr_start[i].page = &(sc->sc_hw_page);
- sc->sc_intr_p_last[i] = &(hw_ptr->intr_start[i]);
+ for (i = 0; i != OHCI_NO_EDS; i++) {
+ sc->sc_intr_p_last[i] =
+ ohci_init_ed(sc->sc_hw.intr_start_pc + i);
}
/*
@@ -319,34 +391,51 @@
while (bit) {
x = bit;
while (x & bit) {
+ ohci_ed_t *ed_x;
+ ohci_ed_t *ed_y;
+
y = (x ^ bit) | (bit / 2);
+
/*
* the next QH has half the poll interval
*/
- hw_ptr->intr_start[x].next = NULL;
- hw_ptr->intr_start[x].ed_next =
- hw_ptr->intr_start[y].ed_self;
+ ed_x = sc->sc_intr_p_last[x];
+ ed_y = sc->sc_intr_p_last[y];
+
+ ed_x->next = NULL;
+ ed_x->ed_next = ed_y->ed_self;
+
x++;
}
bit >>= 1;
}
- /* the last (1ms) QH */
- hw_ptr->intr_start[0].next = &(hw_ptr->isoc_start);
- hw_ptr->intr_start[0].ed_next = hw_ptr->isoc_start.ed_self;
+ if (1) {
+
+ ohci_ed_t *ed_int;
+ ohci_ed_t *ed_isc;
+
+ ed_int = sc->sc_intr_p_last[0];
+ ed_isc = sc->sc_isoc_p_last;
+
+ /* the last (1ms) QH */
+ ed_int->next = ed_isc;
+ ed_int->ed_next = ed_isc->ed_self;
+ }
+ usbd_get_page(&(sc->sc_hw.hcca_pc), 0, &buf_res);
+
+ sc->sc_hcca_p = buf_res.buffer;
/*
* Fill HCCA interrupt table. The bit reversal is to get
* the tree set up properly to spread the interrupts.
*/
- for (i = 0;
- i < OHCI_NO_INTRS;
- i++) {
- hw_ptr->hcca.hcca_interrupt_table[i] =
- hw_ptr->intr_start[i | (OHCI_NO_EDS / 2)].ed_self;
+ for (i = 0; i != OHCI_NO_INTRS; i++) {
+ sc->sc_hcca_p->hcca_interrupt_table[i] =
+ sc->sc_intr_p_last[i | (OHCI_NO_EDS / 2)]->ed_self;
}
- usbd_page_cpu_flush(&(sc->sc_hw_page));
+ ohci_iterate_hw_softc(sc, &ohci_flush_all);
LIST_INIT(&sc->sc_interrupt_list_head);
@@ -358,14 +447,12 @@
#ifdef USB_DEBUG
if (ohcidebug > 15) {
- for (i = 0;
- i < OHCI_NO_EDS;
- i++) {
+ for (i = 0; i != OHCI_NO_EDS; i++) {
printf("ed#%d ", i);
- ohci_dump_ed(&(hw_ptr->intr_start[i]));
+ ohci_dump_ed(sc->sc_intr_p_last[i]);
}
printf("iso ");
- ohci_dump_ed(&(hw_ptr->isoc_start));
+ ohci_dump_ed(sc->sc_isoc_p_last);
}
#endif
@@ -482,7 +569,7 @@
static void
ohci_dumpregs(ohci_softc_t *sc)
{
- struct ohci_hw_softc *hw_ptr;
+ struct ohci_hcca *hcca;
DPRINTF(("ohci_dumpregs: rev=0x%08x control=0x%08x command=0x%08x\n",
OREAD4(sc, OHCI_REVISION),
@@ -516,13 +603,11 @@
OREAD4(sc, OHCI_RH_PORT_STATUS(1)),
OREAD4(sc, OHCI_RH_PORT_STATUS(2))));
- hw_ptr = sc->sc_hw_ptr;
+ hcca = ohci_get_hcca(sc);
- usbd_page_cpu_invalidate(&(sc->sc_hw_page));
DPRINTF((" HCCA: frame_number=0x%04x done_head=0x%08x\n",
- le32toh(hw_ptr->hcca.hcca_frame_number),
- le32toh(hw_ptr->hcca.hcca_done_head)));
- usbd_page_cpu_flush(&(sc->sc_hw_page));
+ le32toh(hcca->hcca_frame_number),
+ le32toh(hcca->hcca_done_head)));
return;
}
static void
@@ -542,7 +627,7 @@
uint32_t td_flags;
uint8_t temp;
- usbd_page_cpu_invalidate(std->page);
+ usbd_pc_cpu_invalidate(std->page_cache);
td_flags = le32toh(std->td_flags);
temp = (std->td_next == 0);
@@ -562,7 +647,6 @@
le32toh(std->td_next),
le32toh(std->td_be));
- usbd_page_cpu_flush(std->page);
return (temp);
}
@@ -573,7 +657,7 @@
uint16_t i;
uint8_t temp;
- usbd_page_cpu_invalidate(sitd->page);
+ usbd_pc_cpu_invalidate(sitd->page_cache);
itd_flags = le32toh(sitd->itd_flags);
temp = (sitd->itd_next == 0);
@@ -594,7 +678,6 @@
}
printf("\n");
- usbd_page_cpu_flush(sitd->page);
return (temp);
}
@@ -615,7 +698,7 @@
uint32_t ed_flags;
uint32_t ed_headp;
- usbd_page_cpu_invalidate(sed->page);
+ usbd_pc_cpu_invalidate(sed->page_cache);
ed_flags = le32toh(sed->ed_flags);
ed_headp = le32toh(sed->ed_headp);
@@ -636,8 +719,6 @@
(ed_headp & OHCI_TOGGLECARRY) ? "-CARRY" : "",
le32toh(sed->ed_headp),
le32toh(sed->ed_next));
-
- usbd_page_cpu_flush(sed->page);
return;
}
@@ -652,8 +733,6 @@
/* (sc->sc_bus.mtx) must be locked */
- usbd_page_cpu_invalidate(sed->page);
-
sed->next = last->next;
sed->ed_next = last->ed_next;
sed->ed_tailp = 0;
@@ -661,8 +740,7 @@
sed->prev = last;
- usbd_page_cpu_flush(sed->page);
- usbd_page_cpu_invalidate(last->page);
+ usbd_pc_cpu_flush(sed->page_cache);
/*
* the last->next->prev is never followed: sed->next->prev = sed;
@@ -671,7 +749,7 @@
last->next = sed;
last->ed_next = sed->ed_self;
- usbd_page_cpu_flush(last->page);
+ usbd_pc_cpu_flush(last->page_cache);
return (sed);
}
@@ -686,20 +764,16 @@
/* only remove if not removed from a queue */
if (sed->prev) {
- usbd_page_cpu_invalidate(sed->prev->page);
sed->prev->next = sed->next;
sed->prev->ed_next = sed->ed_next;
- usbd_page_cpu_flush(sed->prev->page);
+ usbd_pc_cpu_flush(sed->prev->page_cache);
if (sed->next) {
- usbd_page_cpu_invalidate(sed->next->page);
sed->next->prev = sed->prev;
- usbd_page_cpu_flush(sed->next->page);
+ usbd_pc_cpu_flush(sed->next->page_cache);
}
- usbd_page_cpu_invalidate(sed->page);
-
/*
* terminate transfer in case the transferred packet was
* short so that the ED still points at the last used TD
@@ -707,7 +781,7 @@
sed->ed_flags |= htole32(OHCI_ED_SKIP);
sed->ed_headp = sed->ed_tailp;
- usbd_page_cpu_flush(sed->page);
+ usbd_pc_cpu_flush(sed->page_cache);
last = ((last == sed) ? sed->prev : last);
@@ -717,9 +791,6 @@
}
static void
- ohci_device_done(struct usbd_xfer *xfer, usbd_status error);
-
-static void
ohci_isoc_done(struct usbd_xfer *xfer)
{
uint8_t nframes;
@@ -739,7 +810,7 @@
ohci_dump_itd(td);
}
#endif
- usbd_page_cpu_invalidate(td->page);
+ usbd_pc_cpu_invalidate(td->page_cache);
nframes = td->frames;
olen = &td->itd_offset[0];
@@ -764,8 +835,6 @@
olen++;
}
- usbd_page_cpu_flush(td->page);
-
if (((void *)td) == xfer->td_transfer_last) {
break;
}
@@ -821,7 +890,7 @@
while (1) {
- usbd_page_cpu_invalidate(td->page);
+ usbd_pc_cpu_invalidate(td->page_cache);
phy_start = le32toh(td->td_cbp);
td_flags = le32toh(td->td_flags);
cc = OHCI_TD_GET_CC(td_flags);
@@ -848,8 +917,6 @@
xfer->frlengths[xfer->aframes] -= temp;
}
}
- usbd_page_cpu_flush(td->page);
-
/* Check for last transfer */
if (((void *)td) == xfer->td_transfer_last) {
td = NULL;
@@ -961,11 +1028,10 @@
while (1) {
- usbd_page_cpu_invalidate(td->page);
+ usbd_pc_cpu_invalidate(td->page_cache);
phy_start = le32toh(td->td_cbp);
td_flags = le32toh(td->td_flags);
td_next = le32toh(td->td_next);
- usbd_page_cpu_flush(td->page);
/* Check for last transfer */
if (((void *)td) == xfer->td_transfer_last) {
@@ -1001,9 +1067,8 @@
ed = xfer->qh_start;
- usbd_page_cpu_invalidate(ed->page);
ed->ed_headp = td->td_self;
- usbd_page_cpu_flush(ed->page);
+ usbd_pc_cpu_flush(ed->page_cache);
DPRINTFN(12, ("xfer=%p following alt next\n", xfer));
}
@@ -1033,11 +1098,10 @@
}
DPRINTFN(12, ("xfer=%p checking transfer\n", xfer));
- usbd_page_cpu_invalidate(ed->page);
+ usbd_pc_cpu_invalidate(ed->page_cache);
ed_flags = le32toh(ed->ed_flags);
ed_headp = le32toh(ed->ed_headp);
ed_tailp = le32toh(ed->ed_tailp);
- usbd_page_cpu_flush(ed->page);
if ((ed_flags & OHCI_ED_SKIP) ||
(ed_headp & OHCI_HALTED) ||
@@ -1097,7 +1161,7 @@
struct usbd_xfer *xlist[FINISH_LIST_MAX + 1];
struct usbd_xfer **xptr = xlist;
- struct ohci_hw_softc *hw_ptr;
+ struct ohci_hcca *hcca;
struct usbd_xfer *xfer;
struct thread *td;
uint32_t status;
@@ -1121,7 +1185,7 @@
}
td = curthread; /* NULL is not a valid thread */
- hw_ptr = sc->sc_hw_ptr;
+ hcca = ohci_get_hcca(sc);
DPRINTFN(15, ("%s: real interrupt\n",
device_get_nameunit(sc->sc_bus.bdev)));
@@ -1135,8 +1199,7 @@
status = 0;
- usbd_page_cpu_invalidate(&(sc->sc_hw_page));
- done = le32toh(hw_ptr->hcca.hcca_done_head);
+ done = le32toh(hcca->hcca_done_head);
/*
* The LSb of done is used to inform the HC Driver that an interrupt
@@ -1158,13 +1221,13 @@
status |= OREAD4(sc, OHCI_INTERRUPT_STATUS);
done &= ~OHCI_DONE_INTRS;
}
- hw_ptr->hcca.hcca_done_head = 0;
+ hcca->hcca_done_head = 0;
+
+ usbd_pc_cpu_flush(&(sc->sc_hw.hcca_pc));
} else {
status = OREAD4(sc, OHCI_INTERRUPT_STATUS) & ~OHCI_WDH;
}
- usbd_page_cpu_flush(&(sc->sc_hw_page));
-
if (status == 0) { /* nothing to be done (PCI shared
* interrupt) */
goto done;
@@ -1400,8 +1463,6 @@
continue;
}
- usbd_page_cpu_invalidate(td->page);
-
/* fill out current TD */
td->td_flags = temp->td_flags;
@@ -1445,7 +1506,7 @@
td->alt_next = td_alt_next;
- usbd_page_cpu_flush(td->page);
+ usbd_pc_cpu_flush(td->page_cache);
}
if (precompute) {
@@ -1593,13 +1654,11 @@
}
td = temp.td;
- usbd_page_cpu_invalidate(td->page);
-
td->td_next = htole32(OHCI_TD_NEXT_END);
td->td_flags &= ~htole32(OHCI_TD_INTR_MASK);
td->td_flags |= htole32(OHCI_TD_SET_DI(1));
- usbd_page_cpu_flush(td->page);
+ usbd_pc_cpu_flush(td->page_cache);
/* must have at least one frame! */
@@ -1615,8 +1674,6 @@
ed = xfer->qh_start;
- usbd_page_cpu_invalidate(ed->page);
-
ed_flags = (OHCI_ED_SET_FA(xfer->address) |
OHCI_ED_SET_EN(UE_GET_ADDR(xfer->endpoint)) |
OHCI_ED_SET_MAXP(xfer->max_frame_size));
@@ -1628,7 +1685,7 @@
}
ed->ed_flags = htole32(ed_flags);
- usbd_page_cpu_flush(ed->page);
+ usbd_pc_cpu_flush(ed->page_cache);
td = xfer->td_transfer_first;
@@ -1711,14 +1768,13 @@
xfer, xfer->pipe, error));
for (ed = xfer->qh_start; ed; ed = ed->obj_next) {
- usbd_page_cpu_invalidate(ed->page);
+ usbd_pc_cpu_invalidate(ed->page_cache);
if ((!(ed->ed_flags & htole32(OHCI_ED_SKIP))) &&
(!(ed->ed_headp & htole32(OHCI_HALTED))) &&
((ed->ed_headp ^ ed->ed_tailp) & htole32(-0x10))) {
need_delay = 1;
}
- usbd_page_cpu_flush(ed->page);
}
if (methods == &ohci_device_bulk_methods) {
@@ -1962,7 +2018,7 @@
{
struct usbd_page_search buf_res;
ohci_softc_t *sc = xfer->usb_sc;
- struct ohci_hw_softc *hw_ptr = sc->sc_hw_ptr;
+ struct ohci_hcca *hcca;
uint32_t buf_offset;
uint32_t nframes;
uint32_t bp0;
@@ -1979,9 +2035,9 @@
DPRINTFN(5, ("xfer=%p next=%d nframes=%d\n",
xfer, xfer->pipe->isoc_next, xfer->nframes));
- usbd_page_cpu_invalidate(&(sc->sc_hw_page));
- nframes = le32toh(hw_ptr->hcca.hcca_frame_number);
- usbd_page_cpu_flush(&(sc->sc_hw_page));
+ hcca = ohci_get_hcca(sc);
+
+ nframes = le32toh(hcca->hcca_frame_number);
if ((LIST_FIRST(&(xfer->pipe->list_head)) == NULL) ||
(((nframes - xfer->pipe->isoc_next) & 0xFFFF) < xfer->nframes) ||
@@ -2013,7 +2069,7 @@
nframes = xfer->nframes;
buf_offset = 0;
- usbd_get_page(&(xfer->buf_data), buf_offset, &buf_res);
+ usbd_get_page(xfer->frbuffers + 0, buf_offset, &buf_res);
plen = xfer->frlengths;
@@ -2037,11 +2093,11 @@
if (*plen) {
allzero = 0;
buf_offset += (*plen) - 1;
- usbd_get_page(&(xfer->buf_data), buf_offset, &buf_res);
+ usbd_get_page(xfer->frbuffers + 0, buf_offset, &buf_res);
end_phy = buf_res.physaddr;
buf_offset += 1;
- usbd_get_page(&(xfer->buf_data), buf_offset, &buf_res);
+ usbd_get_page(xfer->frbuffers + 0, buf_offset, &buf_res);
}
plen++;
ncur++;
@@ -2049,7 +2105,6 @@
if ((ncur == OHCI_ITD_NOFFSET) ||
(OHCI_PAGE(buf_res.physaddr) != bp0) ||
(nframes == 0)) {
- usbd_page_cpu_invalidate(td->page);
/* fill current ITD */
td->itd_flags = htole32(
@@ -2081,18 +2136,16 @@
/* link the last TD with the next one */
td_last->itd_next = td->itd_self;
}
- usbd_page_cpu_flush(td_last->page);
+ usbd_pc_cpu_flush(td_last->page_cache);
}
}
- usbd_page_cpu_invalidate(td_last->page);
-
/* update the last TD */
td_last->itd_flags &= ~htole32(OHCI_ITD_NOINTR);
td_last->itd_flags |= htole32(OHCI_ITD_SET_DI(0));
td_last->itd_next = 0;
- usbd_page_cpu_flush(td_last->page);
+ usbd_pc_cpu_flush(td_last->page_cache);
xfer->td_transfer_last = td_last;
@@ -2104,8 +2157,6 @@
#endif
ed = xfer->qh_start;
- usbd_page_cpu_invalidate(ed->page);
-
if (UE_GET_DIR(xfer->endpoint) == UE_DIR_IN)
ed_flags = (OHCI_ED_DIR_IN | OHCI_ED_FORMAT_ISO);
else
@@ -2120,7 +2171,7 @@
}
ed->ed_flags = htole32(ed_flags);
- usbd_page_cpu_flush(ed->page);
+ usbd_pc_cpu_flush(ed->page_cache);
td = xfer->td_transfer_first;
@@ -2645,6 +2696,15 @@
.start = ohci_root_intr_start,
};
+static uint8_t
+ohci_dma_alloc_mem(struct usbd_setup_params *parm, uint32_t size,
+ uint32_t align, struct usbd_page_search *info)
+{
+ XXX this function will be factored out shortly;
+
+ return (0);
+}
+
static void
ohci_xfer_setup(struct usbd_setup_params *parm)
{
@@ -2679,22 +2739,34 @@
ntd = ((2 * xfer->nframes) + 1 /* STATUS */
+ (xfer->max_data_length / xfer->max_usb_frame_size));
nqh = 1;
+
+ xfer->flags_int.bdma_enable = 1;
+
} else if (parm->methods == &ohci_device_bulk_methods) {
nitd = 0;
ntd = ((2 * xfer->nframes)
+ (xfer->max_data_length / xfer->max_usb_frame_size));
nqh = 1;
+
+ xfer->flags_int.bdma_enable = 1;
+
} else if (parm->methods == &ohci_device_intr_methods) {
nitd = 0;
ntd = ((2 * xfer->nframes)
+ (xfer->max_data_length / xfer->max_usb_frame_size));
nqh = 1;
+
+ xfer->flags_int.bdma_enable = 1;
+
} else if (parm->methods == &ohci_device_isoc_methods) {
nitd = ((xfer->max_data_length / OHCI_PAGE_SIZE) +
((xfer->nframes + OHCI_ITD_NOFFSET - 1) / OHCI_ITD_NOFFSET) +
1 /* EXTRA */ );
ntd = 0;
nqh = 1;
+
+ xfer->flags_int.bdma_enable = 1;
+
} else {
nitd = 0;
ntd = 0;
@@ -2704,100 +2776,92 @@
if (parm->err) {
return;
}
- /* align data */
- parm->size[1] += ((-parm->size[1]) & (OHCI_ITD_ALIGN - 1));
-
last_obj = NULL;
- for (n = 0; n < ntd; n++) {
+ for (n = 0; n != ntd; n++) {
- parm->size[1] += usbd_page_fit_obj(parm->size[1], sizeof(ohci_td_t));
+ ohci_td_t *td;
+ if (ohci_dma_alloc_mem(parm, sizeof(*td),
+ OHCI_TD_ALIGN, &page_info)) {
+ parm->err = USBD_NOMEM;
+ break;
+ }
if (parm->buf) {
- register ohci_td_t *td;
-
- usbd_get_page(&(parm->pc), parm->size[1], &page_info);
-
- usbd_page_cpu_invalidate(page_info.page);
-
td = page_info.buffer;
/* init TD */
td->td_self = htole32(page_info.physaddr);
td->obj_next = last_obj;
- td->page = page_info.page;
+ td->page_cache = parm->dma_page_cache_ptr;
last_obj = td;
- usbd_page_cpu_flush(page_info.page);
+ usbd_pc_cpu_flush(parm->dma_page_cache_ptr);
}
- parm->size[1] += sizeof(ohci_td_t);
+ parm->dma_page_ptr++;
+ parm->dma_page_cache_ptr++;
}
- for (n = 0; n < nitd; n++) {
+ for (n = 0; n != nitd; n++) {
- parm->size[1] += usbd_page_fit_obj(parm->size[1], sizeof(ohci_itd_t));
+ ohci_itd_t *itd;
+ if (ohci_dma_alloc_mem(parm, sizeof(*itd),
+ OHCI_ITD_ALIGN, &page_info)) {
+ parm->err = USBD_NOMEM;
+ break;
+ }
if (parm->buf) {
- register ohci_itd_t *itd;
-
- usbd_get_page(&(parm->pc), parm->size[1], &page_info);
-
- usbd_page_cpu_invalidate(page_info.page);
-
itd = page_info.buffer;
/* init TD */
itd->itd_self = htole32(page_info.physaddr);
itd->obj_next = last_obj;
- itd->page = page_info.page;
+ itd->page_cache = parm->dma_page_cache_ptr;
last_obj = itd;
- usbd_page_cpu_flush(page_info.page);
+ usbd_pc_cpu_flush(parm->dma_page_cache_ptr);
}
- parm->size[1] += sizeof(ohci_itd_t);
+ parm->dma_page_ptr++;
+ parm->dma_page_cache_ptr++;
}
xfer->td_start = last_obj;
- /* align data */
- parm->size[1] += ((-parm->size[1]) & (OHCI_ED_ALIGN - 1));
-
last_obj = NULL;
- for (n = 0; n < nqh; n++) {
+ for (n = 0; n != nqh; n++) {
- parm->size[1] += usbd_page_fit_obj(parm->size[1], sizeof(ohci_ed_t));
+ ohci_ed_t *ed;
+ if (ohci_dma_alloc_mem(parm, sizeof(*ed),
+ OHCI_ED_ALIGN, &page_info)) {
+ parm->err = USBD_NOMEM;
+ break;
+ }
if (parm->buf) {
- register ohci_ed_t *ed;
-
- usbd_get_page(&(parm->pc), parm->size[1], &page_info);
-
- usbd_page_cpu_invalidate(page_info.page);
-
ed = page_info.buffer;
/* init QH */
ed->ed_self = htole32(page_info.physaddr);
ed->obj_next = last_obj;
- ed->page = page_info.page;
+ ed->page_cache = parm->dma_page_cache_ptr;
last_obj = ed;
- usbd_page_cpu_flush(page_info.page);
+ usbd_pc_cpu_flush(parm->dma_page_cache_ptr);
}
- parm->size[1] += sizeof(ohci_ed_t);
+ parm->dma_page_ptr++;
+ parm->dma_page_cache_ptr++;
}
xfer->qh_start = last_obj;
- xfer->flags_int.bdma_enable = 1;/* enable BUS-DMA support */
-
return;
}
@@ -2849,9 +2913,16 @@
return;
}
+static void
+ohci_xfer_unsetup(struct usbd_xfer *xfer)
+{
+ return;
+}
+
struct usbd_bus_methods ohci_bus_methods =
{
.pipe_init = ohci_pipe_init,
.xfer_setup = ohci_xfer_setup,
+ .xfer_unsetup = ohci_xfer_unsetup,
.do_poll = ohci_do_poll,
};
==== //depot/projects/usb/src/sys/dev/usb/ohci.h#18 (text+ko) ====
@@ -161,6 +161,8 @@
#define OHCI_DONE_INTRS 1
} __aligned(OHCI_HCCA_ALIGN);
+typedef struct ohci_hcca ohci_hcca_t;
+
struct ohci_ed {
volatile uint32_t ed_flags;
#define OHCI_ED_GET_FA(s) ((s) & 0x7f)
@@ -191,7 +193,7 @@
struct ohci_ed *next;
struct ohci_ed *prev;
struct ohci_ed *obj_next;
- struct usbd_page *page;
+ struct usbd_page_cache *page_cache;
uint32_t ed_self;
} __aligned(OHCI_ED_ALIGN);
@@ -225,7 +227,7 @@
*/
struct ohci_td *obj_next;
struct ohci_td *alt_next;
- struct usbd_page *page;
+ struct usbd_page_cache *page_cache;
uint32_t td_self;
uint16_t len;
} __aligned(OHCI_TD_ALIGN);
@@ -257,7 +259,7 @@
* Extra information needed:
*/
struct ohci_itd *obj_next;
- struct usbd_page *page;
+ struct usbd_page_cache *page_cache;
uint32_t itd_self;
uint8_t frames;
} __aligned(OHCI_ITD_ALIGN);
@@ -285,11 +287,17 @@
#define OHCI_NO_EDS (2*OHCI_NO_INTRS)
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list