Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 13 Jan 2009 19:04:59 +0000 (UTC)
From:      Andrew Thompson <thompsa@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r187180 - in head/sys/dev/usb2: core include
Message-ID:  <200901131904.n0DJ4xbg012820@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: thompsa
Date: Tue Jan 13 19:04:58 2009
New Revision: 187180
URL: http://svn.freebsd.org/changeset/base/187180

Log:
  MFp4: //depot/projects/usb@155957
  
  	Make code more compliant with SuperSpeed USB and Wireless USB.
  
  Submitted by: Hans Petter Selasky

Modified:
  head/sys/dev/usb2/core/usb2_compat_linux.c
  head/sys/dev/usb2/core/usb2_device.c
  head/sys/dev/usb2/core/usb2_generic.c
  head/sys/dev/usb2/core/usb2_hub.c
  head/sys/dev/usb2/core/usb2_transfer.c
  head/sys/dev/usb2/include/usb2_standard.h

Modified: head/sys/dev/usb2/core/usb2_compat_linux.c
==============================================================================
--- head/sys/dev/usb2/core/usb2_compat_linux.c	Tue Jan 13 19:04:48 2009	(r187179)
+++ head/sys/dev/usb2/core/usb2_compat_linux.c	Tue Jan 13 19:04:58 2009	(r187180)
@@ -393,8 +393,14 @@ usb_linux_shutdown(device_t dev)
 static uint16_t
 usb_max_isoc_frames(struct usb_device *dev)
 {
-	return ((usb2_get_speed(dev->bsd_udev) == USB_SPEED_HIGH) ?
-	    USB_MAX_HIGH_SPEED_ISOC_FRAMES : USB_MAX_FULL_SPEED_ISOC_FRAMES);
+	;				/* indent fix */
+	switch (usb2_get_speed(dev->bsd_udev)) {
+	case USB_SPEED_LOW:
+	case USB_SPEED_FULL:
+		return (USB_MAX_FULL_SPEED_ISOC_FRAMES);
+	default:
+		return (USB_MAX_HIGH_SPEED_ISOC_FRAMES);
+	}
 }
 
 /*------------------------------------------------------------------------*

Modified: head/sys/dev/usb2/core/usb2_device.c
==============================================================================
--- head/sys/dev/usb2/core/usb2_device.c	Tue Jan 13 19:04:48 2009	(r187179)
+++ head/sys/dev/usb2/core/usb2_device.c	Tue Jan 13 19:04:58 2009	(r187180)
@@ -75,18 +75,6 @@ static usb2_error_t usb2_fill_iface_data
 static void	usb2_notify_addq(const char *type, struct usb2_device *);
 static void	usb2_fifo_free_wrap(struct usb2_device *, uint8_t, uint8_t);
 
-/* static structures */
-
-static const uint8_t usb2_hub_speed_combs[USB_SPEED_MAX][USB_SPEED_MAX] = {
-	/* HUB *//* subdevice */
-	[USB_SPEED_HIGH][USB_SPEED_HIGH] = 1,
-	[USB_SPEED_HIGH][USB_SPEED_FULL] = 1,
-	[USB_SPEED_HIGH][USB_SPEED_LOW] = 1,
-	[USB_SPEED_FULL][USB_SPEED_FULL] = 1,
-	[USB_SPEED_FULL][USB_SPEED_LOW] = 1,
-	[USB_SPEED_LOW][USB_SPEED_LOW] = 1,
-};
-
 /* This variable is global to allow easy access to it: */
 
 int	usb2_template = 0;
@@ -1364,21 +1352,10 @@ usb2_alloc_device(device_t parent_dev, s
 	udev->speed = speed;
 	udev->flags.usb2_mode = usb2_mode;
 
-	/* check speed combination */
+	/* speed combination should be checked by the parent HUB */
 
 	hub = udev->parent_hub;
-	if (hub) {
-		if (usb2_hub_speed_combs[hub->speed][speed] == 0) {
-#if USB_DEBUG
-			printf("%s: the selected subdevice and HUB speed "
-			    "combination is not supported %d/%d.\n",
-			    __FUNCTION__, speed, hub->speed);
-#endif
-			/* reject this combination */
-			err = USB_ERR_INVAL;
-			goto done;
-		}
-	}
+
 	/* search for our High Speed USB HUB, if any */
 
 	adev = udev;

Modified: head/sys/dev/usb2/core/usb2_generic.c
==============================================================================
--- head/sys/dev/usb2/core/usb2_generic.c	Tue Jan 13 19:04:48 2009	(r187179)
+++ head/sys/dev/usb2/core/usb2_generic.c	Tue Jan 13 19:04:58 2009	(r187180)
@@ -157,12 +157,16 @@ ugen_open(struct usb2_fifo *f, int fflag
 	DPRINTFN(6, "flag=0x%x\n", fflags);
 
 	mtx_lock(f->priv_mtx);
-	if (usb2_get_speed(f->udev) == USB_SPEED_HIGH) {
-		f->nframes = UGEN_HW_FRAMES * 8;
-		f->bufsize = UGEN_BULK_HS_BUFFER_SIZE;
-	} else {
+	switch (usb2_get_speed(f->udev)) {
+	case USB_SPEED_LOW:
+	case USB_SPEED_FULL:
 		f->nframes = UGEN_HW_FRAMES;
 		f->bufsize = UGEN_BULK_FS_BUFFER_SIZE;
+		break;
+	default:
+		f->nframes = UGEN_HW_FRAMES * 8;
+		f->bufsize = UGEN_BULK_HS_BUFFER_SIZE;
+		break;
 	}
 
 	type = ed->bmAttributes & UE_XFERTYPE;

Modified: head/sys/dev/usb2/core/usb2_hub.c
==============================================================================
--- head/sys/dev/usb2/core/usb2_hub.c	Tue Jan 13 19:04:48 2009	(r187179)
+++ head/sys/dev/usb2/core/usb2_hub.c	Tue Jan 13 19:04:58 2009	(r187180)
@@ -372,18 +372,38 @@ repeat:
 	/*
 	 * Figure out the device speed
 	 */
-	speed =
-	    (sc->sc_st.port_status & UPS_HIGH_SPEED) ? USB_SPEED_HIGH :
-	    (sc->sc_st.port_status & UPS_LOW_SPEED) ? USB_SPEED_LOW : USB_SPEED_FULL;
-
+	switch (udev->speed) {
+	case USB_SPEED_HIGH:
+		if (sc->sc_st.port_status & UPS_HIGH_SPEED)
+			speed = USB_SPEED_HIGH;
+		else if (sc->sc_st.port_status & UPS_LOW_SPEED)
+			speed = USB_SPEED_LOW;
+		else
+			speed = USB_SPEED_FULL;
+		break;
+	case USB_SPEED_FULL:
+		if (sc->sc_st.port_status & UPS_LOW_SPEED)
+			speed = USB_SPEED_LOW;
+		else
+			speed = USB_SPEED_FULL;
+		break;
+	case USB_SPEED_LOW:
+		speed = USB_SPEED_LOW;
+		break;
+	default:
+		/* same speed like parent */
+		speed = udev->speed;
+		break;
+	}
 	/*
 	 * Figure out the device mode
 	 *
 	 * NOTE: This part is currently FreeBSD specific.
 	 */
-	usb2_mode =
-	    (sc->sc_st.port_status & UPS_PORT_MODE_DEVICE) ?
-	    USB_MODE_DEVICE : USB_MODE_HOST;
+	if (sc->sc_st.port_status & UPS_PORT_MODE_DEVICE)
+		usb2_mode = USB_MODE_DEVICE;
+	else
+		usb2_mode = USB_MODE_HOST;
 
 	/* need to create a new child */
 
@@ -1049,17 +1069,16 @@ usb2_intr_schedule_adjust(struct usb2_de
 {
 	struct usb2_bus *bus = udev->bus;
 	struct usb2_hub *hub;
+	uint8_t speed;
 
 	USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
 
-	if (usb2_get_speed(udev) == USB_SPEED_HIGH) {
-		if (slot >= USB_HS_MICRO_FRAMES_MAX) {
-			slot = usb2_intr_find_best_slot(bus->uframe_usage, 0,
-			    USB_HS_MICRO_FRAMES_MAX);
-		}
-		bus->uframe_usage[slot] += len;
-	} else {
-		if (usb2_get_speed(udev) == USB_SPEED_LOW) {
+	speed = usb2_get_speed(udev);
+
+	switch (speed) {
+	case USB_SPEED_LOW:
+	case USB_SPEED_FULL:
+		if (speed == USB_SPEED_LOW) {
 			len *= 8;
 		}
 		/*
@@ -1076,6 +1095,14 @@ usb2_intr_schedule_adjust(struct usb2_de
 		}
 		hub->uframe_usage[slot] += len;
 		bus->uframe_usage[slot] += len;
+		break;
+	default:
+		if (slot >= USB_HS_MICRO_FRAMES_MAX) {
+			slot = usb2_intr_find_best_slot(bus->uframe_usage, 0,
+			    USB_HS_MICRO_FRAMES_MAX);
+		}
+		bus->uframe_usage[slot] += len;
+		break;
 	}
 	return (slot);
 }

Modified: head/sys/dev/usb2/core/usb2_transfer.c
==============================================================================
--- head/sys/dev/usb2/core/usb2_transfer.c	Tue Jan 13 19:04:48 2009	(r187179)
+++ head/sys/dev/usb2/core/usb2_transfer.c	Tue Jan 13 19:04:58 2009	(r187180)
@@ -63,6 +63,7 @@ static const struct usb2_std_packet_size
 		[USB_SPEED_FULL] = {.range = {0, 64}},
 		[USB_SPEED_HIGH] = {.range = {0, 1024}},
 		[USB_SPEED_VARIABLE] = {.range = {0, 1024}},
+		[USB_SPEED_SUPER] = {.range = {0, 1024}},
 	},
 
 	[UE_CONTROL] = {
@@ -70,6 +71,7 @@ static const struct usb2_std_packet_size
 		[USB_SPEED_FULL] = {.fixed = {8, 16, 32, 64}},
 		[USB_SPEED_HIGH] = {.fixed = {64, 64, 64, 64}},
 		[USB_SPEED_VARIABLE] = {.fixed = {512, 512, 512, 512}},
+		[USB_SPEED_SUPER] = {.fixed = {512, 512, 512, 512}},
 	},
 
 	[UE_BULK] = {
@@ -77,6 +79,7 @@ static const struct usb2_std_packet_size
 		[USB_SPEED_FULL] = {.fixed = {8, 16, 32, 64}},
 		[USB_SPEED_HIGH] = {.fixed = {512, 512, 512, 512}},
 		[USB_SPEED_VARIABLE] = {.fixed = {512, 512, 1024, 1536}},
+		[USB_SPEED_SUPER] = {.fixed = {1024, 1024, 1024, 1024}},
 	},
 
 	[UE_ISOCHRONOUS] = {
@@ -84,6 +87,7 @@ static const struct usb2_std_packet_size
 		[USB_SPEED_FULL] = {.range = {0, 1023}},
 		[USB_SPEED_HIGH] = {.range = {0, 1024}},
 		[USB_SPEED_VARIABLE] = {.range = {0, 3584}},
+		[USB_SPEED_SUPER] = {.range = {0, 1024}},
 	},
 };
 
@@ -413,10 +417,14 @@ usb2_transfer_setup_sub(struct usb2_setu
 			 */
 			xfer->timeout = 1000 / 4;
 		}
-		if (parm->speed == USB_SPEED_HIGH) {
-			frame_limit = USB_MAX_HS_ISOC_FRAMES_PER_XFER;
-		} else {
+		switch (parm->speed) {
+		case USB_SPEED_LOW:
+		case USB_SPEED_FULL:
 			frame_limit = USB_MAX_FS_ISOC_FRAMES_PER_XFER;
+			break;
+		default:
+			frame_limit = USB_MAX_HS_ISOC_FRAMES_PER_XFER;
+			break;
 		}
 
 		if (xfer->nframes > frame_limit) {
@@ -446,13 +454,29 @@ usb2_transfer_setup_sub(struct usb2_setu
 
 				xfer->interval = edesc->bInterval;
 
-				if (parm->speed == USB_SPEED_HIGH) {
-					xfer->interval /= 8;	/* 125us -> 1ms */
+				switch (parm->speed) {
+				case USB_SPEED_SUPER:
+				case USB_SPEED_VARIABLE:
+					/* 125us -> 1ms */
+					if (xfer->interval < 4)
+						xfer->interval = 1;
+					else if (xfer->interval > 16)
+						xfer->interval = (1<<(16-4));
+					else
+						xfer->interval = 
+						    (1 << (xfer->interval-4));
+					break;
+				case USB_SPEED_HIGH:
+					/* 125us -> 1ms */
+					xfer->interval /= 8;
+					break;
+				default:
+					break;
 				}
 				if (xfer->interval == 0) {
 					/*
-					 * one millisecond is the smallest
-					 * interval
+					 * One millisecond is the smallest
+					 * interval we support:
 					 */
 					xfer->interval = 1;
 				}

Modified: head/sys/dev/usb2/include/usb2_standard.h
==============================================================================
--- head/sys/dev/usb2/include/usb2_standard.h	Tue Jan 13 19:04:48 2009	(r187179)
+++ head/sys/dev/usb2/include/usb2_standard.h	Tue Jan 13 19:04:58 2009	(r187180)
@@ -602,12 +602,12 @@ struct usb2_port_status {
 #define	UPS_SUSPEND			0x0004
 #define	UPS_OVERCURRENT_INDICATOR	0x0008
 #define	UPS_RESET			0x0010
-#define	UPS_PORT_MODE_DEVICE		0x0020	/* currently FreeBSD specific */
 #define	UPS_PORT_POWER			0x0100
 #define	UPS_LOW_SPEED			0x0200
 #define	UPS_HIGH_SPEED			0x0400
 #define	UPS_PORT_TEST			0x0800
 #define	UPS_PORT_INDICATOR		0x1000
+#define	UPS_PORT_MODE_DEVICE		0x8000	/* currently FreeBSD specific */
 	uWord	wPortChange;
 #define	UPS_C_CONNECT_STATUS		0x0001
 #define	UPS_C_PORT_ENABLED		0x0002



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