Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 30 Nov 2007 22:02:01 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 129844 for review
Message-ID:  <200711302202.lAUM21KI019188@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
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) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200711302202.lAUM21KI019188>