PERFORCE change 163516 for review

Andrew Thompson thompsa at FreeBSD.org
Thu Jun 4 19:47:25 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=163516

Change 163516 by thompsa at thompsa_burger on 2009/06/04 19:47:02

	Checkpoint buffer WIP. Basic operation works, many things broken.

Affected files ...

.. //depot/projects/usb_buf/src/sys/dev/usb/controller/ehci.c#8 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/input/uhid.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/input/ukbd.c#7 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/input/ums.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/misc/udbp.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/net/if_aue.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/net/if_axe.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/net/if_cdce.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/net/if_cue.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/net/if_kue.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/net/if_rue.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/net/if_udav.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/u3g.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/uark.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/ubsa.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/ubser.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/uchcom.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/ucycom.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/ufoma.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/uftdi.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/ugensa.c#7 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/uipaq.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/ulpt.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/umct.c#7 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/umodem.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/umoscom.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/uplcom.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/uslcom.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/uvisor.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/serial/uvscom.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/storage/umass.c#7 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/storage/urio.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/storage/ustorage_fs.c#7 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_busdma.c#7 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_compat_linux.c#7 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_controller.h#7 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_core.h#8 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_debug.c#7 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_debug.h#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_device.c#9 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_device.h#8 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_generic.c#8 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_handle_request.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_hub.c#8 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_msctest.c#5 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_request.c#10 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_transfer.c#8 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/usb_transfer.h#7 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/wlan/if_rum.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/wlan/if_uath.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/wlan/if_upgt.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/wlan/if_ural.c#6 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/wlan/if_urtw.c#3 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/wlan/if_zyd.c#7 edit

Differences ...

==== //depot/projects/usb_buf/src/sys/dev/usb/controller/ehci.c#8 (text+ko) ====

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

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list