svn commit: r235011 - in stable/8/sys/dev/usb: . controller

Hans Petter Selasky hselasky at FreeBSD.org
Fri May 4 15:55:32 UTC 2012


Author: hselasky
Date: Fri May  4 15:55:31 2012
New Revision: 235011
URL: http://svn.freebsd.org/changeset/base/235011

Log:
  MFC r234803 and r234961:
  Add support for Multi-TT mode of modern USB HUBs.
  This will give you more bandwidth for isochronous
  FULL speed applications connected through a
  High Speed HUB.
  
  This patch has been tested with XHCI and EHCI.

Modified:
  stable/8/sys/dev/usb/controller/ehci.c
  stable/8/sys/dev/usb/controller/xhci.c
  stable/8/sys/dev/usb/usb_controller.h
  stable/8/sys/dev/usb/usb_hub.c
  stable/8/sys/dev/usb/usb_hub.h
  stable/8/sys/dev/usb/usb_transfer.c
Directory Properties:
  stable/8/sys/   (props changed)

Modified: stable/8/sys/dev/usb/controller/ehci.c
==============================================================================
--- stable/8/sys/dev/usb/controller/ehci.c	Fri May  4 15:51:23 2012	(r235010)
+++ stable/8/sys/dev/usb/controller/ehci.c	Fri May  4 15:55:31 2012	(r235011)
@@ -2398,9 +2398,9 @@ ehci_device_isoc_fs_open(struct usb_xfer
 	    EHCI_SITD_SET_HUBA(xfer->xroot->udev->hs_hub_addr) |
 	    EHCI_SITD_SET_PORT(xfer->xroot->udev->hs_port_no);
 
-	if (UE_GET_DIR(xfer->endpointno) == UE_DIR_IN) {
+	if (UE_GET_DIR(xfer->endpointno) == UE_DIR_IN)
 		sitd_portaddr |= EHCI_SITD_SET_DIR_IN;
-	}
+
 	sitd_portaddr = htohc32(sc, sitd_portaddr);
 
 	/* initialize all TD's */
@@ -2436,9 +2436,6 @@ ehci_device_isoc_fs_enter(struct usb_xfe
 {
 	struct usb_page_search buf_res;
 	ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
-	struct usb_fs_isoc_schedule *fss_start;
-	struct usb_fs_isoc_schedule *fss_end;
-	struct usb_fs_isoc_schedule *fss;
 	ehci_sitd_t *td;
 	ehci_sitd_t *td_last = NULL;
 	ehci_sitd_t **pp_last;
@@ -2450,7 +2447,6 @@ ehci_device_isoc_fs_enter(struct usb_xfe
 	uint16_t tlen;
 	uint8_t sa;
 	uint8_t sb;
-	uint8_t error;
 
 #ifdef USB_DEBUG
 	uint8_t once = 1;
@@ -2495,9 +2491,8 @@ ehci_device_isoc_fs_enter(struct usb_xfe
 	 * pre-compute when the isochronous transfer will be finished:
 	 */
 	xfer->isoc_time_complete =
-	    usbd_fs_isoc_schedule_isoc_time_expand
-	    (xfer->xroot->udev, &fss_start, &fss_end, nframes) + buf_offset +
-	    xfer->nframes;
+	    usb_isoc_time_expand(&sc->sc_bus, nframes) +
+	    buf_offset + xfer->nframes;
 
 	/* get the real number of frames */
 
@@ -2520,19 +2515,14 @@ ehci_device_isoc_fs_enter(struct usb_xfe
 
 	xfer->qh_pos = xfer->endpoint->isoc_next;
 
-	fss = fss_start + (xfer->qh_pos % USB_ISOC_TIME_MAX);
-
 	while (nframes--) {
 		if (td == NULL) {
 			panic("%s:%d: out of TD's\n",
 			    __FUNCTION__, __LINE__);
 		}
-		if (pp_last >= &sc->sc_isoc_fs_p_last[EHCI_VIRTUAL_FRAMELIST_COUNT]) {
+		if (pp_last >= &sc->sc_isoc_fs_p_last[EHCI_VIRTUAL_FRAMELIST_COUNT])
 			pp_last = &sc->sc_isoc_fs_p_last[0];
-		}
-		if (fss >= fss_end) {
-			fss = fss_start;
-		}
+
 		/* reuse sitd_portaddr and sitd_back from last transfer */
 
 		if (*plen > xfer->max_frame_size) {
@@ -2547,17 +2537,19 @@ ehci_device_isoc_fs_enter(struct usb_xfe
 #endif
 			*plen = xfer->max_frame_size;
 		}
-		/*
-		 * We currently don't care if the ISOCHRONOUS schedule is
-		 * full!
-		 */
-		error = usbd_fs_isoc_schedule_alloc(fss, &sa, *plen);
-		if (error) {
+
+		/* allocate a slot */
+
+		sa = usbd_fs_isoc_schedule_alloc_slot(xfer,
+		    xfer->isoc_time_complete - nframes - 1);
+
+		if (sa == 255) {
 			/*
-			 * The FULL speed schedule is FULL! Set length
-			 * to zero.
+			 * Schedule is FULL, set length to zero:
 			 */
+
 			*plen = 0;
+			sa = USB_FS_ISOC_UFRAME_MAX - 1;
 		}
 		if (*plen) {
 			/*
@@ -2637,7 +2629,6 @@ ehci_device_isoc_fs_enter(struct usb_xfe
 		pp_last++;
 
 		plen++;
-		fss++;
 		td_last = td;
 		td = td->obj_next;
 	}
@@ -2647,11 +2638,29 @@ ehci_device_isoc_fs_enter(struct usb_xfe
 	/* update isoc_next */
 	xfer->endpoint->isoc_next = (pp_last - &sc->sc_isoc_fs_p_last[0]) &
 	    (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
+
+	/*
+	 * We don't allow cancelling of the SPLIT transaction USB FULL
+	 * speed transfer, because it disturbs the bandwidth
+	 * computation algorithm.
+	 */
+	xfer->flags_int.can_cancel_immed = 0;
 }
 
 static void
 ehci_device_isoc_fs_start(struct usb_xfer *xfer)
 {
+	/*
+	 * We don't allow cancelling of the SPLIT transaction USB FULL
+	 * speed transfer, because it disturbs the bandwidth
+	 * computation algorithm.
+	 */
+	xfer->flags_int.can_cancel_immed = 0;
+
+	/* set a default timeout */
+	if (xfer->timeout == 0)
+		xfer->timeout = 500; /* ms */
+
 	/* put transfer on interrupt queue */
 	ehci_transfer_intr_enqueue(xfer);
 }

Modified: stable/8/sys/dev/usb/controller/xhci.c
==============================================================================
--- stable/8/sys/dev/usb/controller/xhci.c	Fri May  4 15:51:23 2012	(r235010)
+++ stable/8/sys/dev/usb/controller/xhci.c	Fri May  4 15:55:31 2012	(r235011)
@@ -115,6 +115,7 @@ struct xhci_std_temp {
 	uint8_t			tbc;
 	uint8_t			tlbpc;
 	uint8_t			step_td;
+	uint8_t			do_isoc_sync;
 };
 
 static void	xhci_do_poll(struct usb_bus *);
@@ -1657,11 +1658,15 @@ restart:
 			td->td_trb[x].dwTrb2 = htole32(dword);
 
 			dword = XHCI_TRB_3_CHAIN_BIT | XHCI_TRB_3_CYCLE_BIT |
-			  XHCI_TRB_3_TYPE_SET(temp->trb_type) | 
-			  XHCI_TRB_3_FRID_SET(temp->isoc_frame / 8) | 
+			  XHCI_TRB_3_TYPE_SET(temp->trb_type) |
+			  (temp->do_isoc_sync ?
+			   XHCI_TRB_3_FRID_SET(temp->isoc_frame / 8) :
+			   XHCI_TRB_3_ISO_SIA_BIT) |
 			  XHCI_TRB_3_TBC_SET(temp->tbc) |
 			  XHCI_TRB_3_TLBPC_SET(temp->tlbpc);
 
+			temp->do_isoc_sync = 0;
+
 			if (temp->direction == UE_DIR_IN) {
 				dword |= XHCI_TRB_3_DIR_IN;
 
@@ -1764,6 +1769,7 @@ xhci_setup_generic_chain(struct usb_xfer
 	uint32_t y;
 	uint8_t mult;
 
+	temp.do_isoc_sync = 0;
 	temp.step_td = 0;
 	temp.tbc = 0;
 	temp.tlbpc = 0;
@@ -1841,6 +1847,8 @@ xhci_setup_generic_chain(struct usb_xfer
 			 */
 			xfer->endpoint->isoc_next = XHCI_MFINDEX_GET(x + (3 * 8));
 			xfer->endpoint->is_synced = 1;
+			temp.do_isoc_sync = 1;
+
 			DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
 		}
 
@@ -1931,7 +1939,10 @@ xhci_setup_generic_chain(struct usb_xfer
 
 			uint8_t tdpc;
 
-			/* isochronous transfers don't have short packet termination */
+			/*
+			 * Isochronous transfers don't have short
+			 * packet termination:
+			 */
 
 			temp.shortpkt = 1;
 
@@ -2271,12 +2282,29 @@ xhci_configure_device(struct usb_device 
 	switch (udev->speed) {
 	case USB_SPEED_LOW:
 		temp |= XHCI_SCTX_0_SPEED_SET(2);
+		if (udev->parent_hs_hub != NULL &&
+		    udev->parent_hs_hub->ddesc.bDeviceProtocol ==
+		    UDPROTO_HSHUBMTT) {
+			DPRINTF("Device inherits MTT\n");
+			temp |= XHCI_SCTX_0_MTT_SET(1);
+		}
 		break;
 	case USB_SPEED_HIGH:
 		temp |= XHCI_SCTX_0_SPEED_SET(3);
+		if (sc->sc_hw.devs[index].nports != 0 &&
+		    udev->ddesc.bDeviceProtocol == UDPROTO_HSHUBMTT) {
+			DPRINTF("HUB supports MTT\n");
+			temp |= XHCI_SCTX_0_MTT_SET(1);
+		}
 		break;
 	case USB_SPEED_FULL:
 		temp |= XHCI_SCTX_0_SPEED_SET(1);
+		if (udev->parent_hs_hub != NULL &&
+		    udev->parent_hs_hub->ddesc.bDeviceProtocol ==
+		    UDPROTO_HSHUBMTT) {
+			DPRINTF("Device inherits MTT\n");
+			temp |= XHCI_SCTX_0_MTT_SET(1);
+		}
 		break;
 	default:
 		temp |= XHCI_SCTX_0_SPEED_SET(4);
@@ -2287,15 +2315,8 @@ xhci_configure_device(struct usb_device 
 	    (udev->speed == USB_SPEED_SUPER ||
 	    udev->speed == USB_SPEED_HIGH);
 
-	if (is_hub) {
+	if (is_hub)
 		temp |= XHCI_SCTX_0_HUB_SET(1);
-#if 0
-		if (udev->ddesc.bDeviceProtocol == UDPROTO_HSHUBMTT) {
-			DPRINTF("HUB supports MTT\n");
-			temp |= XHCI_SCTX_0_MTT_SET(1);
-		}
-#endif
-	}
 
 	xhci_ctx_set_le32(sc, &pinp->ctx_slot.dwSctx0, temp);
 
@@ -2327,8 +2348,10 @@ xhci_configure_device(struct usb_device 
 
 	temp = XHCI_SCTX_2_IRQ_TARGET_SET(0);
 
-	if (is_hub)
-		temp |= XHCI_SCTX_2_TT_THINK_TIME_SET(sc->sc_hw.devs[index].tt);
+	if (is_hub) {
+		temp |= XHCI_SCTX_2_TT_THINK_TIME_SET(
+		    sc->sc_hw.devs[index].tt);
+	}
 
 	hubdev = udev->parent_hs_hub;
 

Modified: stable/8/sys/dev/usb/usb_controller.h
==============================================================================
--- stable/8/sys/dev/usb/usb_controller.h	Fri May  4 15:51:23 2012	(r235010)
+++ stable/8/sys/dev/usb/usb_controller.h	Fri May  4 15:55:31 2012	(r235011)
@@ -231,7 +231,8 @@ void	usb_bus_mem_flush_all(struct usb_bu
 uint8_t	usb_bus_mem_alloc_all(struct usb_bus *bus, bus_dma_tag_t dmat, usb_bus_mem_cb_t *cb);
 void	usb_bus_mem_free_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb);
 uint16_t usb_isoc_time_expand(struct usb_bus *bus, uint16_t isoc_time_curr);
-uint16_t usbd_fs_isoc_schedule_isoc_time_expand(struct usb_device *udev, struct usb_fs_isoc_schedule **pp_start, struct usb_fs_isoc_schedule **pp_end, uint16_t isoc_time);
-uint8_t	usbd_fs_isoc_schedule_alloc(struct usb_fs_isoc_schedule *fss, uint8_t *pstart, uint16_t len);
+#if USB_HAVE_TT_SUPPORT
+uint8_t	usbd_fs_isoc_schedule_alloc_slot(struct usb_xfer *isoc_xfer, uint16_t isoc_time);
+#endif
 
 #endif					/* _USB_CONTROLLER_H_ */

Modified: stable/8/sys/dev/usb/usb_hub.c
==============================================================================
--- stable/8/sys/dev/usb/usb_hub.c	Fri May  4 15:51:23 2012	(r235010)
+++ stable/8/sys/dev/usb/usb_hub.c	Fri May  4 15:55:31 2012	(r235011)
@@ -109,6 +109,7 @@ struct uhub_softc {
 #define	UHUB_PROTO(sc) ((sc)->sc_udev->ddesc.bDeviceProtocol)
 #define	UHUB_IS_HIGH_SPEED(sc) (UHUB_PROTO(sc) != UDPROTO_FSHUB)
 #define	UHUB_IS_SINGLE_TT(sc) (UHUB_PROTO(sc) == UDPROTO_HSHUBSTT)
+#define	UHUB_IS_MULTI_TT(sc) (UHUB_PROTO(sc) == UDPROTO_HSHUBMTT)
 #define	UHUB_IS_SUPER_SPEED(sc) (UHUB_PROTO(sc) == UDPROTO_SSHUB)
 
 /* prototypes for type checking: */
@@ -948,6 +949,16 @@ uhub_attach(device_t dev)
 		    "bus powered HUB. HUB ignored\n");
 		goto error;
 	}
+
+	if (UHUB_IS_MULTI_TT(sc)) {
+		err = usbd_set_alt_interface_index(udev, 0, 1);
+		if (err) {
+			device_printf(dev, "MTT could not be enabled\n");
+			goto error;
+		}
+		device_printf(dev, "MTT enabled\n");
+	}
+
 	/* get HUB descriptor */
 
 	DPRINTFN(2, "Getting HUB descriptor\n");
@@ -1057,10 +1068,6 @@ uhub_attach(device_t dev)
 	}
 	udev->hub = hub;
 
-#if USB_HAVE_TT_SUPPORT
-	/* init FULL-speed ISOCHRONOUS schedule */
-	usbd_fs_isoc_schedule_init_all(hub->fs_isoc_schedule);
-#endif
 	/* initialize HUB structure */
 	hub->hubsoftc = sc;
 	hub->explore = &uhub_explore;
@@ -1656,42 +1663,6 @@ usb_hs_bandwidth_free(struct usb_xfer *x
 }
 
 /*------------------------------------------------------------------------*
- *	usbd_fs_isoc_schedule_init_sub
- *
- * This function initialises an USB FULL speed isochronous schedule
- * entry.
- *------------------------------------------------------------------------*/
-#if USB_HAVE_TT_SUPPORT
-static void
-usbd_fs_isoc_schedule_init_sub(struct usb_fs_isoc_schedule *fss)
-{
-	fss->total_bytes = (USB_FS_ISOC_UFRAME_MAX *
-	    USB_FS_BYTES_PER_HS_UFRAME);
-	fss->frame_bytes = (USB_FS_BYTES_PER_HS_UFRAME);
-	fss->frame_slot = 0;
-}
-#endif
-
-/*------------------------------------------------------------------------*
- *	usbd_fs_isoc_schedule_init_all
- *
- * This function will reset the complete USB FULL speed isochronous
- * bandwidth schedule.
- *------------------------------------------------------------------------*/
-#if USB_HAVE_TT_SUPPORT
-void
-usbd_fs_isoc_schedule_init_all(struct usb_fs_isoc_schedule *fss)
-{
-	struct usb_fs_isoc_schedule *fss_end = fss + USB_ISOC_TIME_MAX;
-
-	while (fss != fss_end) {
-		usbd_fs_isoc_schedule_init_sub(fss);
-		fss++;
-	}
-}
-#endif
-
-/*------------------------------------------------------------------------*
  *	usb_isoc_time_expand
  *
  * This function will expand the time counter from 7-bit to 16-bit.
@@ -1723,114 +1694,130 @@ usb_isoc_time_expand(struct usb_bus *bus
 }
 
 /*------------------------------------------------------------------------*
- *	usbd_fs_isoc_schedule_isoc_time_expand
+ *	usbd_fs_isoc_schedule_alloc_slot
  *
- * This function does multiple things. First of all it will expand the
- * passed isochronous time, which is the return value. Then it will
- * store where the current FULL speed isochronous schedule is
- * positioned in time and where the end is. See "pp_start" and
- * "pp_end" arguments.
+ * This function will allocate bandwidth for an isochronous FULL speed
+ * transaction in the FULL speed schedule.
  *
  * Returns:
- *   Expanded version of "isoc_time".
- *
- * NOTE: This function depends on being called regularly with
- * intervals less than "USB_ISOC_TIME_MAX".
+ *    <8: Success
+ * Else: Error
  *------------------------------------------------------------------------*/
 #if USB_HAVE_TT_SUPPORT
-uint16_t
-usbd_fs_isoc_schedule_isoc_time_expand(struct usb_device *udev,
-    struct usb_fs_isoc_schedule **pp_start,
-    struct usb_fs_isoc_schedule **pp_end,
-    uint16_t isoc_time)
+uint8_t
+usbd_fs_isoc_schedule_alloc_slot(struct usb_xfer *isoc_xfer, uint16_t isoc_time)
 {
-	struct usb_fs_isoc_schedule *fss_end;
-	struct usb_fs_isoc_schedule *fss_a;
-	struct usb_fs_isoc_schedule *fss_b;
-	struct usb_hub *hs_hub;
+	struct usb_xfer *xfer;
+	struct usb_xfer *pipe_xfer;
+	struct usb_bus *bus;
+	usb_frlength_t len;
+	usb_frlength_t data_len;
+	uint16_t delta;
+	uint16_t slot;
+	uint8_t retval;
 
-	isoc_time = usb_isoc_time_expand(udev->bus, isoc_time);
+	data_len = 0;
+	slot = 0;
 
-	hs_hub = udev->parent_hs_hub->hub;
+	bus = isoc_xfer->xroot->bus;
 
-	if (hs_hub != NULL) {
+	TAILQ_FOREACH(xfer, &bus->intr_q.head, wait_entry) {
 
-		fss_a = hs_hub->fs_isoc_schedule +
-		    (hs_hub->isoc_last_time % USB_ISOC_TIME_MAX);
+		/* skip self, if any */
 
-		hs_hub->isoc_last_time = isoc_time;
+		if (xfer == isoc_xfer)
+			continue;
 
-		fss_b = hs_hub->fs_isoc_schedule +
-		    (isoc_time % USB_ISOC_TIME_MAX);
+		/* check if this USB transfer is going through the same TT */
 
-		fss_end = hs_hub->fs_isoc_schedule + USB_ISOC_TIME_MAX;
+		if (xfer->xroot->udev->parent_hs_hub !=
+		    isoc_xfer->xroot->udev->parent_hs_hub) {
+			continue;
+		}
+		if ((isoc_xfer->xroot->udev->parent_hs_hub->
+		    ddesc.bDeviceProtocol == UDPROTO_HSHUBMTT) &&
+		    (xfer->xroot->udev->hs_port_no !=
+		    isoc_xfer->xroot->udev->hs_port_no)) {
+			continue;
+		}
+		if (xfer->endpoint->methods != isoc_xfer->endpoint->methods)
+			continue;
+
+		/* check if isoc_time is part of this transfer */
+
+		delta = xfer->isoc_time_complete - isoc_time;
+		if (delta > 0 && delta <= xfer->nframes) {
+			delta = xfer->nframes - delta;
+
+			len = xfer->frlengths[delta];
+			len += 8;
+			len *= 7;
+			len /= 6;
+
+			data_len += len;
+		}
+
+		/* check double buffered transfers */
 
-		*pp_start = hs_hub->fs_isoc_schedule;
-		*pp_end = fss_end;
+		TAILQ_FOREACH(pipe_xfer, &xfer->endpoint->endpoint_q.head,
+		    wait_entry) {
 
-		while (fss_a != fss_b) {
-			if (fss_a == fss_end) {
-				fss_a = hs_hub->fs_isoc_schedule;
+			/* skip self, if any */
+
+			if (pipe_xfer == isoc_xfer)
 				continue;
+
+			/* check if isoc_time is part of this transfer */
+
+			delta = pipe_xfer->isoc_time_complete - isoc_time;
+			if (delta > 0 && delta <= pipe_xfer->nframes) {
+				delta = pipe_xfer->nframes - delta;
+
+				len = pipe_xfer->frlengths[delta];
+				len += 8;
+				len *= 7;
+				len /= 6;
+
+				data_len += len;
 			}
-			usbd_fs_isoc_schedule_init_sub(fss_a);
-			fss_a++;
 		}
+	}
 
-	} else {
-
-		*pp_start = NULL;
-		*pp_end = NULL;
+	while (data_len >= USB_FS_BYTES_PER_HS_UFRAME) {
+		data_len -= USB_FS_BYTES_PER_HS_UFRAME;
+		slot++;
 	}
-	return (isoc_time);
-}
-#endif
 
-/*------------------------------------------------------------------------*
- *	usbd_fs_isoc_schedule_alloc
- *
- * This function will allocate bandwidth for an isochronous FULL speed
- * transaction in the FULL speed schedule. The microframe slot where
- * the transaction should be started is stored in the byte pointed to
- * by "pstart". The "len" argument specifies the length of the
- * transaction in bytes.
- *
- * Returns:
- *    0: Success
- * Else: Error
- *------------------------------------------------------------------------*/
-#if USB_HAVE_TT_SUPPORT
-uint8_t
-usbd_fs_isoc_schedule_alloc(struct usb_fs_isoc_schedule *fss,
-    uint8_t *pstart, uint16_t len)
-{
-	uint8_t slot = fss->frame_slot;
+	/* check for overflow */
 
-	/* Compute overhead and bit-stuffing */
+	if (slot >= USB_FS_ISOC_UFRAME_MAX)
+		return (255);
 
-	len += 8;
+	retval = slot;
 
-	len *= 7;
-	len /= 6;
+	delta = isoc_xfer->isoc_time_complete - isoc_time;
+	if (delta > 0 && delta <= isoc_xfer->nframes) {
+		delta = isoc_xfer->nframes - delta;
 
-	if (len > fss->total_bytes) {
-		*pstart = 0;		/* set some dummy value */
-		return (1);		/* error */
+		len = isoc_xfer->frlengths[delta];
+		len += 8;
+		len *= 7;
+		len /= 6;
+
+		data_len += len;
 	}
-	if (len > 0) {
 
-		fss->total_bytes -= len;
+	while (data_len >= USB_FS_BYTES_PER_HS_UFRAME) {
+		data_len -= USB_FS_BYTES_PER_HS_UFRAME;
+		slot++;
+	}
 
-		while (len >= fss->frame_bytes) {
-			len -= fss->frame_bytes;
-			fss->frame_bytes = USB_FS_BYTES_PER_HS_UFRAME;
-			fss->frame_slot++;
-		}
+	/* check for overflow */
 
-		fss->frame_bytes -= len;
-	}
-	*pstart = slot;
-	return (0);			/* success */
+	if (slot >= USB_FS_ISOC_UFRAME_MAX)
+		return (255);
+
+	return (retval);
 }
 #endif
 

Modified: stable/8/sys/dev/usb/usb_hub.h
==============================================================================
--- stable/8/sys/dev/usb/usb_hub.h	Fri May  4 15:51:23 2012	(r235010)
+++ stable/8/sys/dev/usb/usb_hub.h	Fri May  4 15:55:31 2012	(r235011)
@@ -38,22 +38,9 @@ struct usb_port {
 };
 
 /*
- * The following structure defines how many bytes are
- * left in an 1ms USB time slot.
- */
-struct usb_fs_isoc_schedule {
-	uint16_t total_bytes;
-	uint8_t	frame_bytes;
-	uint8_t	frame_slot;
-};
-
-/*
  * The following structure defines an USB HUB.
  */
 struct usb_hub {
-#if USB_HAVE_TT_SUPPORT
-	struct usb_fs_isoc_schedule fs_isoc_schedule[USB_ISOC_TIME_MAX];
-#endif
 	struct usb_device *hubudev;	/* the HUB device */
 	usb_error_t (*explore) (struct usb_device *hub);
 	void   *hubsoftc;
@@ -68,7 +55,6 @@ struct usb_hub {
 
 void	usb_hs_bandwidth_alloc(struct usb_xfer *xfer);
 void	usb_hs_bandwidth_free(struct usb_xfer *xfer);
-void	usbd_fs_isoc_schedule_init_all(struct usb_fs_isoc_schedule *fss);
 void	usb_bus_port_set_device(struct usb_bus *bus, struct usb_port *up,
 	    struct usb_device *udev, uint8_t device_index);
 struct usb_device *usb_bus_port_get_device(struct usb_bus *bus,

Modified: stable/8/sys/dev/usb/usb_transfer.c
==============================================================================
--- stable/8/sys/dev/usb/usb_transfer.c	Fri May  4 15:51:23 2012	(r235010)
+++ stable/8/sys/dev/usb/usb_transfer.c	Fri May  4 15:55:31 2012	(r235011)
@@ -1680,11 +1680,12 @@ usbd_pipe_enter(struct usb_xfer *xfer)
 
 	DPRINTF("enter\n");
 
+	/* the transfer can now be cancelled */
+	xfer->flags_int.can_cancel_immed = 1;
+
 	/* enter the transfer */
 	(ep->methods->enter) (xfer);
 
-	xfer->flags_int.can_cancel_immed = 1;
-
 	/* check for transfer error */
 	if (xfer->error) {
 		/* some error has happened */
@@ -2417,13 +2418,15 @@ usbd_transfer_start_cb(void *arg)
 #if USB_HAVE_PF
 	usbpf_xfertap(xfer, USBPF_XFERTAP_SUBMIT);
 #endif
+
+	/* the transfer can now be cancelled */
+	xfer->flags_int.can_cancel_immed = 1;
+
 	/* start USB transfer, if no error */
 	if (xfer->error == 0)
 		(ep->methods->start) (xfer);
 
-	xfer->flags_int.can_cancel_immed = 1;
-
-	/* check for error */
+	/* check for transfer error */
 	if (xfer->error) {
 		/* some error has happened */
 		usbd_transfer_done(xfer, 0);
@@ -2598,13 +2601,14 @@ usbd_pipe_start(struct usb_xfer_queue *p
 #if USB_HAVE_PF
 	usbpf_xfertap(xfer, USBPF_XFERTAP_SUBMIT);
 #endif
+	/* the transfer can now be cancelled */
+	xfer->flags_int.can_cancel_immed = 1;
+
 	/* start USB transfer, if no error */
 	if (xfer->error == 0)
 		(ep->methods->start) (xfer);
 
-	xfer->flags_int.can_cancel_immed = 1;
-
-	/* check for error */
+	/* check for transfer error */
 	if (xfer->error) {
 		/* some error has happened */
 		usbd_transfer_done(xfer, 0);


More information about the svn-src-stable mailing list