--- include/linux/usb.h-dist	Mon Dec 31 11:34:18 2001
+++ include/linux/usb.h	Mon Dec 31 11:34:18 2001
@@ -591,6 +593,22 @@
 	atomic_t refcnt;
 };
 
+/*
+ * As of USB 2.0, full/low speed devices are segregated into trees.
+ * One type grows from USB 1.1 host controllers (OHCI, UHCI etc).
+ * The other type grows from high speed hubs when they connect to
+ * full/low speed devices using "Transaction Translators" (TTs).
+ *
+ * TTs should only be known to the hub driver, and high speed bus
+ * drivers (only EHCI for now).  They affect periodic scheduling and
+ * sometimes control/bulk error recovery.
+ */
+struct usb_tt {
+	struct usb_device	*hub;	/* upstream highspeed hub */
+	int			multi;	/* true means one TT per port */
+};
+
+
 /* This is arbitrary.
  * From USB 2.0 spec Table 11-13, offset 7, a hub can
  * have up to 255 ports. The most yet reported is 10.
@@ -606,8 +624,8 @@
 		USB_SPEED_HIGH				/* usb 2.0 */
 	} speed;
 
-	struct usb_device *tt;		/* usb1.1 device on usb2.0 bus */
-	int ttport;			/* device/hub port on that tt */
+	struct usb_tt	*tt; 		/* low/full speed dev, highspeed hub */
+	int		ttport;		/* device port on that tt hub */
 
 	atomic_t refcnt;		/* Reference count */
 	struct semaphore serialize;
--- drivers/usb-dist/hub.h	Mon Dec 31 11:35:35 2001
+++ drivers/usb/hub.h	Mon Dec 31 11:33:03 2001
@@ -136,6 +137,7 @@
 	struct usb_hub_descriptor *descriptor;
 
 	struct semaphore khubd_sem;
+	struct usb_tt		tt;		/* Transaction Translator */
 };
 
 #endif /* __LINUX_HUB_H */
--- drivers/usb-dist/hub.c	Mon Dec 31 11:35:35 2001
+++ drivers/usb/hub.c	Mon Dec 31 11:33:03 2001
@@ -217,9 +217,12 @@
 			break;
 		case 1:
 			dbg("Single TT");
+			hub->tt.hub = dev;
 			break;
 		case 2:
-			dbg("Multiple TT");
+			dbg("TT per port");
+			hub->tt.hub = dev;
+			hub->tt.multi = 1;
 			break;
 		default:
 			dbg("Unrecognized hub protocol %d",
@@ -592,9 +595,10 @@
 			port + 1, hub->devnum, ret);
 }
 
-static void usb_hub_port_connect_change(struct usb_device *hub, int port,
+static void usb_hub_port_connect_change(struct usb_hub *hubstate, int port,
 					struct usb_port_status *portsts)
 {
+	struct usb_device *hub = hubstate->dev;
 	struct usb_device *dev;
 	unsigned short portstatus, portchange;
 	unsigned int delay = HUB_SHORT_RESET_TIME;
@@ -654,6 +658,16 @@
 		/* Find a new device ID for it */
 		usb_connect(dev);
 
+		/* Set up TT records, if needed  */
+		if (hub->tt) {
+			dev->tt = hub->tt;
+			dev->ttport = hub->ttport;
+		} else if (dev->speed != USB_SPEED_HIGH
+				&& hub->speed == USB_SPEED_HIGH) {
+			dev->tt = &hubstate->tt;
+			dev->ttport = port + 1;
+		}
+
 		/* Create a readable topology string */
 		cdev = dev;
 		pdev = dev->parent;
@@ -766,7 +780,7 @@
 			if (portchange & USB_PORT_STAT_C_CONNECTION) {
 				dbg("port %d connection change", i + 1);
 
-				usb_hub_port_connect_change(dev, i, &portsts);
+				usb_hub_port_connect_change(hub, i, &portsts);
 			} else if (portchange & USB_PORT_STAT_C_ENABLE) {
 				dbg("port %d enable change, status %x", i + 1, portstatus);
 				usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_ENABLE);
@@ -780,7 +794,7 @@
 				    (portstatus & USB_PORT_STAT_CONNECTION) && (dev->children[i])) {
 					err("already running port %i disabled by hub (EMI?), re-enabling...",
 						i + 1);
-					usb_hub_port_connect_change(dev, i, &portsts);
+					usb_hub_port_connect_change(hub, i, &portsts);
 				}
 			}
 
