From owner-p4-projects@FreeBSD.ORG Fri Nov 30 22:02:01 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 9426016A41B; Fri, 30 Nov 2007 22:02:01 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 312DD16A419 for ; Fri, 30 Nov 2007 22:02:01 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 2345D13C448 for ; Fri, 30 Nov 2007 22:02:01 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id lAUM21Kd019191 for ; Fri, 30 Nov 2007 22:02:01 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id lAUM21KI019188 for perforce@freebsd.org; Fri, 30 Nov 2007 22:02:01 GMT (envelope-from hselasky@FreeBSD.org) Date: Fri, 30 Nov 2007 22:02:01 GMT Message-Id: <200711302202.lAUM21KI019188@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 129844 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 30 Nov 2007 22:02:01 -0000 http://perforce.freebsd.org/chv.cgi?CH=129844 Change 129844 by hselasky@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) <<<