diff --git a/Documentation/i2c/porting-clients b/Documentation/i2c/porting-clients
index 62f32e7247bc498faf14007b301eb9954aefade4..fab37c46bbca1affc7ff6e108e8a50b88777de4d 100644
--- a/Documentation/i2c/porting-clients
+++ b/Documentation/i2c/porting-clients
@@ -92,10 +92,7 @@ Technical changes:
   i2c_get_clientdata(client) instead.
 
 * [Interface] Init function should not print anything. Make sure
-  there is a MODULE_LICENSE() line. MODULE_PARM() is replaced
-  by module_param(). Note that module_param has a third parameter,
-  that you should set to 0 by default. See include/linux/moduleparam.h
-  for details.
+  there is a MODULE_LICENSE() line.
 
 Coding policy:
 
diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c
index 95f77b1dfa117db9693076cb4ba57b8cb6d3fcb6..6cb14f493cd9f05f74ef953564063e8f9f1b82ff 100644
--- a/arch/ia64/kernel/unaligned.c
+++ b/arch/ia64/kernel/unaligned.c
@@ -1,7 +1,7 @@
 /*
  * Architecture-specific unaligned trap handling.
  *
- * Copyright (C) 1999-2002 Hewlett-Packard Co
+ * Copyright (C) 1999-2002, 2004 Hewlett-Packard Co
  *	Stephane Eranian <eranian@hpl.hp.com>
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
@@ -1328,7 +1328,7 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
 	 * handler into reading an arbitrary kernel addresses...
 	 */
 	if (!user_mode(regs))
-		eh = SEARCH_EXCEPTION_TABLE(regs);
+		eh = search_exception_tables(regs->cr_iip + ia64_psr(regs)->ri);
 	if (user_mode(regs) || eh) {
 		if ((current->thread.flags & IA64_THREAD_UAC_SIGBUS) != 0)
 			goto force_sigbus;
diff --git a/arch/ia64/mm/extable.c b/arch/ia64/mm/extable.c
index 7f7955395173d5ec446699e4ca5efc40001c6bac..58ef7a74601235d56d49fea66267fe0d7c748644 100644
--- a/arch/ia64/mm/extable.c
+++ b/arch/ia64/mm/extable.c
@@ -1,7 +1,7 @@
 /*
  * Kernel exception handling table support.  Derived from arch/alpha/mm/extable.c.
  *
- * Copyright (C) 1998, 1999, 2001-2002 Hewlett-Packard Co
+ * Copyright (C) 1998, 1999, 2001-2002, 2004 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
@@ -10,9 +10,51 @@
 #include <asm/uaccess.h>
 #include <asm/module.h>
 
-void sort_extable(struct exception_table_entry *start,
-		  struct exception_table_entry *finish)
+static inline int
+compare_entries (struct exception_table_entry *l, struct exception_table_entry *r)
 {
+	u64 lip = (u64) &l->addr + l->addr;
+	u64 rip = (u64) &r->addr + r->addr;
+
+	if (lip < rip)
+		return -1;
+	if (lip == rip)
+		return 0;
+	else
+		return 1;
+}
+
+static inline void
+swap_entries (struct exception_table_entry *l, struct exception_table_entry *r)
+{
+	u64 delta = (u64) r - (u64) l;
+	struct exception_table_entry tmp;
+
+	tmp = *l;
+	l->addr = r->addr + delta;
+	l->cont = r->cont + delta;
+	r->addr = tmp.addr - delta;
+	r->cont = tmp.cont - delta;
+}
+
+/*
+ * Sort the exception table.  It's usually already sorted, but there may be unordered
+ * entries due to multiple text sections (such as the .init text section).  Note that the
+ * exception-table-entries contain location-relative addresses, which requires a bit of
+ * care during sorting to avoid overflows in the offset members (e.g., it would not be
+ * safe to make a temporary copy of an exception-table entry on the stack, because the
+ * stack may be more than 2GB away from the exception-table).
+ */
+void
+sort_extable (struct exception_table_entry *start, struct exception_table_entry *finish)
+{
+	struct exception_table_entry *p, *q;
+
+ 	/* insertion sort */
+	for (p = start + 1; p < finish; ++p)
+		/* start .. p-1 is sorted; push p down to it's proper place */
+		for (q = p; q > start && compare_entries(&q[0], &q[-1]) < 0; --q)
+			swap_entries(&q[0], &q[-1]);
 }
 
 const struct exception_table_entry *
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index fa66ec8b4cfb4beb8f7ab1517f47b91ecf834645..9584a1b2248ab54e943fa78634439d42848d3b33 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -58,7 +58,7 @@ mapped_kernel_page_is_present (unsigned long address)
 	if (pgd_none(*pgd) || pgd_bad(*pgd))
 		return 0;
 
-	pmd = pmd_offset(pgd,address);
+	pmd = pmd_offset(pgd, address);
 	if (pmd_none(*pmd) || pmd_bad(*pmd))
 		return 0;
 
diff --git a/arch/x86_64/mm/extable.c b/arch/x86_64/mm/extable.c
index 39f7d6df69785ee515c8b551865bc6d2e2ec876c..7e039db623a036a187012c120f2dc9cee34708da 100644
--- a/arch/x86_64/mm/extable.c
+++ b/arch/x86_64/mm/extable.c
@@ -55,5 +55,4 @@ void sort_extable(struct exception_table_entry *start,
 			}
 		}
 	} while (change != 0);
-	return 0;
 }
diff --git a/arch/x86_64/mm/k8topology.c b/arch/x86_64/mm/k8topology.c
index 37f31b397d7b600bbdb73b62170372be72207587..2f909cd0d65a9b9f0f047b21d99a56cc0d283bc7 100644
--- a/arch/x86_64/mm/k8topology.c
+++ b/arch/x86_64/mm/k8topology.c
@@ -75,7 +75,7 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
 			continue;
 		} 
 		if (nodeid >= numnodes) { 
-			printk("Ignoring excess node %d (%x:%x)\n", nodeid, 
+			printk("Ignoring excess node %d (%lx:%lx)\n", nodeid,
 			       base, limit); 
 			continue;
 		} 
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 25ba41b0f6a7f28c0c1bb8a0c30f8b1470e823c6..f2b73f078eef6103e36fce6c6ad9ed497c5c5597 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -868,7 +868,7 @@ int cpufreq_update_policy(unsigned int cpu)
 	down(&data->lock);
 
 	memcpy(&policy, 
-	       &data, 
+	       data,
 	       sizeof(struct cpufreq_policy));
 	policy.min = data->user_policy.min;
 	policy.max = data->user_policy.max;
diff --git a/drivers/i2c/busses/i2c-parport.h b/drivers/i2c/busses/i2c-parport.h
index 8db6be015a38878961bc6b7a9c033bd28887b88b..1f0441e42d6ba2c4c67023d07d1f8dcccd9543b1 100644
--- a/drivers/i2c/busses/i2c-parport.h
+++ b/drivers/i2c/busses/i2c-parport.h
@@ -67,12 +67,13 @@ static struct adapter_parm adapter_parm[] = {
 		.getsda	= { 0x40, STAT, 1 },
 		.getscl	= { 0x08, STAT, 1 },
 	},
-	/* type 4: ADM 1032 evaluation board */
+	/* type 4: ADM1025 and ADM1032 evaluation boards */
 	{
 		.setsda	= { 0x02, DATA, 1 },
 		.setscl	= { 0x01, DATA, 1 },
 		.getsda	= { 0x10, STAT, 1 },
-		.init	= { 0xf0, DATA, 0 },
+		.init	= { 0xf0, DATA, 0 }, /* ADM1025 doesn't need this,
+						but it doesn't hurt */
 	},
 };
 
@@ -84,4 +85,4 @@ MODULE_PARM_DESC(type,
 	" 1 = home brew teletext adapter\n"
 	" 2 = Velleman K8000 adapter\n"
 	" 3 = ELV adapter\n"
-	" 4 = ADM 1032 evalulation board\n");
+	" 4 = ADM1025 and ADM1032 evaluation boards\n");
diff --git a/drivers/i2c/busses/i2c-philips-par.c b/drivers/i2c/busses/i2c-philips-par.c
index 583efdb6001f55da57618e1ef193dad79d76e10d..f1bbb148e11a1b0be4635d13a5fe50692b548ba5 100644
--- a/drivers/i2c/busses/i2c-philips-par.c
+++ b/drivers/i2c/busses/i2c-philips-par.c
@@ -184,8 +184,8 @@ static void i2c_parport_attach (struct parport *port)
 		return;
 	}
 	/* reset hardware to sane state */
-	bit_lp_setsda(port, 1);
-	bit_lp_setscl(port, 1);
+	adapter->bit_lp_data.setsda(port, 1);
+	adapter->bit_lp_data.setscl(port, 1);
 	parport_release(adapter->pdev);
 
 	if (i2c_bit_add_bus(&adapter->adapter) < 0) {
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 1fbaac9d80d985882b5d46f91bf54d2e3269dfa5..c0aeaba29467f5b39905b600d91cf9b3f0eb979b 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -68,6 +68,9 @@ struct sd {
 #define SMBSLVEVT	(0xA + piix4_smba)
 #define SMBSLVDAT	(0xC + piix4_smba)
 
+/* count for request_region */
+#define SMBIOSIZE	8
+
 /* PCI Address Constants */
 #define SMBBA		0x090
 #define SMBHSTCFG	0x0D2
@@ -112,14 +115,13 @@ MODULE_PARM_DESC(fix_hstcfg,
 
 static int piix4_transaction(void);
 
-
 static unsigned short piix4_smba = 0;
 static struct i2c_adapter piix4_adapter;
 
 /*
  * Get DMI information.
  */
-static int ibm_dmi_probe(void)
+static int __devinit ibm_dmi_probe(void)
 {
 #ifdef CONFIG_X86
 	extern int is_unsafe_smbus;
@@ -129,9 +131,9 @@ static int ibm_dmi_probe(void)
 #endif
 }
 
-static int piix4_setup(struct pci_dev *PIIX4_dev, const struct pci_device_id *id)
+static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
+				const struct pci_device_id *id)
 {
-	int error_return = 0;
 	unsigned char temp;
 
 	/* match up the function */
@@ -144,8 +146,7 @@ static int piix4_setup(struct pci_dev *PIIX4_dev, const struct pci_device_id *id
 		dev_err(&PIIX4_dev->dev, "IBM Laptop detected; this module "
 			"may corrupt your serial eeprom! Refusing to load "
 			"module!\n");
-		error_return = -EPERM;
-		goto END;
+		return -EPERM;
 	}
 
 	/* Determine the address of the SMBus areas */
@@ -163,11 +164,10 @@ static int piix4_setup(struct pci_dev *PIIX4_dev, const struct pci_device_id *id
 		}
 	}
 
-	if (!request_region(piix4_smba, 8, "piix4-smbus")) {
+	if (!request_region(piix4_smba, SMBIOSIZE, "piix4-smbus")) {
 		dev_err(&PIIX4_dev->dev, "SMB region 0x%x already in use!\n",
 			piix4_smba);
-		error_return = -ENODEV;
-		goto END;
+		return -ENODEV;
 	}
 
 	pci_read_config_byte(PIIX4_dev, SMBHSTCFG, &temp);
@@ -214,8 +214,9 @@ static int piix4_setup(struct pci_dev *PIIX4_dev, const struct pci_device_id *id
 		} else {
 			dev_err(&PIIX4_dev->dev,
 				"Host SMBus controller not enabled!\n");
-			error_return = -ENODEV;
-			goto END;
+			release_region(piix4_smba, SMBIOSIZE);
+			piix4_smba = 0;
+			return -ENODEV;
 		}
 	}
 
@@ -231,8 +232,7 @@ static int piix4_setup(struct pci_dev *PIIX4_dev, const struct pci_device_id *id
 	dev_dbg(&PIIX4_dev->dev, "SMBREV = 0x%X\n", temp);
 	dev_dbg(&PIIX4_dev->dev, "SMBA = 0x%X\n", piix4_smba);
 
-END:
-	return error_return;
+	return 0;
 }
 
 /* Another internally used function */
@@ -465,7 +465,8 @@ static struct pci_device_id piix4_ids[] = {
 	{ 0, }
 };
 
-static int __devinit piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
+static int __devinit piix4_probe(struct pci_dev *dev,
+				const struct pci_device_id *id)
 {
 	int retval;
 
@@ -479,17 +480,24 @@ static int __devinit piix4_probe(struct pci_dev *dev, const struct pci_device_id
 	snprintf(piix4_adapter.name, I2C_NAME_SIZE,
 		"SMBus PIIX4 adapter at %04x", piix4_smba);
 
-	retval = i2c_add_adapter(&piix4_adapter);
+	if ((retval = i2c_add_adapter(&piix4_adapter))) {
+		dev_err(&dev->dev, "Couldn't register adapter!\n");
+		release_region(piix4_smba, SMBIOSIZE);
+		piix4_smba = 0;
+	}
 
 	return retval;
 }
 
 static void __devexit piix4_remove(struct pci_dev *dev)
 {
-	i2c_del_adapter(&piix4_adapter);
+	if (piix4_smba) {
+		i2c_del_adapter(&piix4_adapter);
+		release_region(piix4_smba, SMBIOSIZE);
+		piix4_smba = 0;
+	}
 }
 
-
 static struct pci_driver piix4_driver = {
 	.name		= "piix4-smbus",
 	.id_table	= piix4_ids,
@@ -502,15 +510,13 @@ static int __init i2c_piix4_init(void)
 	return pci_module_init(&piix4_driver);
 }
 
-
 static void __exit i2c_piix4_exit(void)
 {
 	pci_unregister_driver(&piix4_driver);
-	release_region(piix4_smba, 8);
 }
 
-MODULE_AUTHOR
-    ("Frodo Looijaard <frodol@dds.nl> and Philip Edelbrock <phil@netroedge.com>");
+MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and "
+		"Philip Edelbrock <phil@netroedge.com>");
 MODULE_DESCRIPTION("PIIX4 SMBus driver");
 MODULE_LICENSE("GPL");
 
diff --git a/drivers/i2c/chips/lm75.c b/drivers/i2c/chips/lm75.c
index 337f9a32b08e7ad498f119cd992a75adf6f16939..c1488261677ea09d44368098d10cdd0fab1bb69c 100644
--- a/drivers/i2c/chips/lm75.c
+++ b/drivers/i2c/chips/lm75.c
@@ -104,9 +104,9 @@ static ssize_t set_##value(struct device *dev, const char *buf, size_t count)	\
 set(temp_max, LM75_REG_TEMP_OS);
 set(temp_hyst, LM75_REG_TEMP_HYST);
 
-static DEVICE_ATTR(temp_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max);
-static DEVICE_ATTR(temp_hyst, S_IWUSR | S_IRUGO, show_temp_hyst, set_temp_hyst);
-static DEVICE_ATTR(temp_input, S_IRUGO, show_temp_input, NULL);
+static DEVICE_ATTR(temp_max1, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max);
+static DEVICE_ATTR(temp_hyst1, S_IWUSR | S_IRUGO, show_temp_hyst, set_temp_hyst);
+static DEVICE_ATTR(temp_input1, S_IRUGO, show_temp_input, NULL);
 
 static int lm75_attach_adapter(struct i2c_adapter *adapter)
 {
@@ -197,9 +197,9 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
 	lm75_init_client(new_client);
 	
 	/* Register sysfs hooks */
-	device_create_file(&new_client->dev, &dev_attr_temp_max);
-	device_create_file(&new_client->dev, &dev_attr_temp_hyst);
-	device_create_file(&new_client->dev, &dev_attr_temp_input);
+	device_create_file(&new_client->dev, &dev_attr_temp_max1);
+	device_create_file(&new_client->dev, &dev_attr_temp_hyst1);
+	device_create_file(&new_client->dev, &dev_attr_temp_input1);
 
 	return 0;
 
diff --git a/drivers/i2c/chips/lm78.c b/drivers/i2c/chips/lm78.c
index f5925c28383332f27b96e10803365fc57a34b827..e33cd233234da2bf1929b1dc481fc298b128a1e4 100644
--- a/drivers/i2c/chips/lm78.c
+++ b/drivers/i2c/chips/lm78.c
@@ -369,10 +369,10 @@ static ssize_t set_temp_hyst(struct device *dev, const char *buf, size_t count)
 	return count;
 }
 
-static DEVICE_ATTR(temp_input, S_IRUGO, show_temp, NULL)
-static DEVICE_ATTR(temp_max, S_IRUGO | S_IWUSR,
+static DEVICE_ATTR(temp_input1, S_IRUGO, show_temp, NULL)
+static DEVICE_ATTR(temp_max1, S_IRUGO | S_IWUSR,
 		show_temp_over, set_temp_over)
-static DEVICE_ATTR(temp_hyst, S_IRUGO | S_IWUSR,
+static DEVICE_ATTR(temp_hyst1, S_IRUGO | S_IWUSR,
 		show_temp_hyst, set_temp_hyst)
 
 /* 3 Fans */
@@ -678,9 +678,9 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
 	device_create_file(&new_client->dev, &dev_attr_in_input6);
 	device_create_file(&new_client->dev, &dev_attr_in_min6);
 	device_create_file(&new_client->dev, &dev_attr_in_max6);
-	device_create_file(&new_client->dev, &dev_attr_temp_input);
-	device_create_file(&new_client->dev, &dev_attr_temp_max);
-	device_create_file(&new_client->dev, &dev_attr_temp_hyst);
+	device_create_file(&new_client->dev, &dev_attr_temp_input1);
+	device_create_file(&new_client->dev, &dev_attr_temp_max1);
+	device_create_file(&new_client->dev, &dev_attr_temp_hyst1);
 	device_create_file(&new_client->dev, &dev_attr_fan_input1);
 	device_create_file(&new_client->dev, &dev_attr_fan_min1);
 	device_create_file(&new_client->dev, &dev_attr_fan_div1);
diff --git a/drivers/i2c/chips/lm85.c b/drivers/i2c/chips/lm85.c
index 6ac26d84e665f898734d8e40060aff7b5e59efa9..36c09df60da6925bdfc81770a8f1b828d9896b7e 100644
--- a/drivers/i2c/chips/lm85.c
+++ b/drivers/i2c/chips/lm85.c
@@ -48,9 +48,6 @@ static unsigned int normal_isa_range[] = { I2C_CLIENT_ISA_END };
 /* Insmod parameters */
 SENSORS_INSMOD_4(lm85b, lm85c, adm1027, adt7463);
 
-/* Enable debug if true */
-static int	lm85debug = 0;
-
 /* The LM85 registers */
 
 #define	LM85_REG_IN(nr)			(0x20 + (nr))
@@ -802,19 +799,15 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
 	company = lm85_read_value(new_client, LM85_REG_COMPANY);
 	verstep = lm85_read_value(new_client, LM85_REG_VERSTEP);
 
-	if (lm85debug) {
-		printk("lm85: Detecting device at %d,0x%02x with"
+	dev_dbg(&adapter->dev, "Detecting device at %d,0x%02x with"
 		" COMPANY: 0x%02x and VERSTEP: 0x%02x\n",
 		i2c_adapter_id(new_client->adapter), new_client->addr,
 		company, verstep);
-	}
 
 	/* If auto-detecting, Determine the chip type. */
 	if (kind <= 0) {
-		if (lm85debug) {
-			printk("lm85: Autodetecting device at %d,0x%02x ...\n",
+		dev_dbg(&adapter->dev, "Autodetecting device at %d,0x%02x ...\n",
 			i2c_adapter_id(adapter), address );
-		}
 		if( company == LM85_COMPANY_NATIONAL
 		    && verstep == LM85_VERSTEP_LM85C ) {
 			kind = lm85c ;
@@ -823,8 +816,8 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
 			kind = lm85b ;
 		} else if( company == LM85_COMPANY_NATIONAL
 		    && (verstep & 0xf0) == LM85_VERSTEP_GENERIC ) {
-			printk("lm85: Unrecgonized version/stepping 0x%02x"
-			    " Defaulting to LM85.\n", verstep );
+			dev_err(&adapter->dev, "Unrecgonized version/stepping 0x%02x"
+				" Defaulting to LM85.\n", verstep);
 			kind = any_chip ;
 		} else if( company == LM85_COMPANY_ANALOG_DEV
 		    && verstep == LM85_VERSTEP_ADM1027 ) {
@@ -834,21 +827,19 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
 			kind = adt7463 ;
 		} else if( company == LM85_COMPANY_ANALOG_DEV
 		    && (verstep & 0xf0) == LM85_VERSTEP_GENERIC ) {
-			printk("lm85: Unrecgonized version/stepping 0x%02x"
-			    " Defaulting to ADM1027.\n", verstep );
+			dev_err(&adapter->dev, "Unrecgonized version/stepping 0x%02x"
+				" Defaulting to ADM1027.\n", verstep);
 			kind = adm1027 ;
 		} else if( kind == 0 && (verstep & 0xf0) == 0x60) {
-			printk("lm85: Generic LM85 Version 6 detected\n");
+			dev_err(&adapter->dev, "Generic LM85 Version 6 detected\n");
 			/* Leave kind as "any_chip" */
 		} else {
-			if (lm85debug) {
-				printk("lm85: Autodetection failed\n");
-			}
+			dev_dbg(&adapter->dev, "Autodetection failed\n");
 			/* Not an LM85 ... */
 			if( kind == 0 ) {  /* User used force=x,y */
-			    printk("lm85: Generic LM85 Version 6 not"
-				" found at %d,0x%02x. Try force_lm85c.\n",
-				i2c_adapter_id(adapter), address );
+				dev_err(&adapter->dev, "Generic LM85 Version 6 not"
+					" found at %d,0x%02x. Try force_lm85c.\n",
+					i2c_adapter_id(adapter), address );
 			}
 			err = 0 ;
 			goto ERROR1;
@@ -879,12 +870,10 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
 	data->valid = 0;
 	init_MUTEX(&data->update_lock);
 
-	if (lm85debug) {
-		printk("lm85: Assigning ID %d to %s at %d,0x%02x\n",
+	dev_dbg(&adapter->dev, "Assigning ID %d to %s at %d,0x%02x\n",
 		new_client->id, new_client->name,
 		i2c_adapter_id(new_client->adapter),
 		new_client->addr);
-	}
 
 	/* Tell the I2C layer a new client has arrived */
 	if ((err = i2c_attach_client(new_client)))
@@ -1021,31 +1010,24 @@ void lm85_init_client(struct i2c_client *client)
 	int value;
 	struct lm85_data *data = i2c_get_clientdata(client);
 
-	if (lm85debug) {
-		printk("lm85(%d): Initializing device\n", client->id);
-	}
+	dev_dbg(&client->dev, "Initializing device\n");
 
 	/* Warn if part was not "READY" */
 	value = lm85_read_value(client, LM85_REG_CONFIG);
-	if (lm85debug) {
-		printk("lm85(%d): LM85_REG_CONFIG is: 0x%02x\n", client->id, value );
-	}
+	dev_dbg(&client->dev, "LM85_REG_CONFIG is: 0x%02x\n", value);
 	if( value & 0x02 ) {
-		printk("lm85(%d): Client (%d,0x%02x) config is locked.\n",
-			    client->id,
+		dev_err(&client->dev, "Client (%d,0x%02x) config is locked.\n",
 			    i2c_adapter_id(client->adapter), client->addr );
 	};
 	if( ! (value & 0x04) ) {
-		printk("lm85(%d): Client (%d,0x%02x) is not ready.\n",
-			    client->id,
+		dev_err(&client->dev, "Client (%d,0x%02x) is not ready.\n",
 			    i2c_adapter_id(client->adapter), client->addr );
 	};
 	if( value & 0x10
 	    && ( data->type == adm1027
 		|| data->type == adt7463 ) ) {
-		printk("lm85(%d): Client (%d,0x%02x) VxI mode is set.  "
+		dev_err(&client->dev, "Client (%d,0x%02x) VxI mode is set.  "
 			"Please report this to the lm85 maintainer.\n",
-			    client->id,
 			    i2c_adapter_id(client->adapter), client->addr );
 	};
 
@@ -1061,11 +1043,8 @@ void lm85_init_client(struct i2c_client *client)
 	value = lm85_read_value(client, LM85_REG_CONFIG);
 	/* Try to clear LOCK, Set START, save everything else */
 	value = (value & ~ 0x02) | 0x01 ;
-	if (lm85debug) {
-		printk("lm85(%d): Setting CONFIG to: 0x%02x\n", client->id, value );
-	}
+	dev_dbg(&client->dev, "Setting CONFIG to: 0x%02x\n", value);
 	lm85_write_value(client, LM85_REG_CONFIG, value);
-
 }
 
 void lm85_update_client(struct i2c_client *client)
@@ -1078,10 +1057,8 @@ void lm85_update_client(struct i2c_client *client)
 	if ( !data->valid ||
 	     (jiffies - data->last_reading > LM85_DATA_INTERVAL ) ) {
 		/* Things that change quickly */
-
-		if (lm85debug) {
-			printk("lm85(%d): Reading sensor values\n", client->id);
-		}
+		dev_dbg(&client->dev, "Reading sensor values\n");
+		
 		/* Have to read extended bits first to "freeze" the
 		 * more significant bits that are read later.
 		 */
@@ -1125,10 +1102,8 @@ void lm85_update_client(struct i2c_client *client)
 	if ( !data->valid ||
 	     (jiffies - data->last_config > LM85_CONFIG_INTERVAL) ) {
 		/* Things that don't change often */
+		dev_dbg(&client->dev, "Reading config values\n");
 
-		if (lm85debug) {
-			printk("lm85(%d): Reading config values\n", client->id);
-		}
 		for (i = 0; i <= 4; ++i) {
 			data->in_min[i] =
 			    lm85_read_value(client, LM85_REG_IN_MIN(i));
@@ -1234,8 +1209,6 @@ static void  __exit sm_lm85_exit(void)
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Philip Pokorny <ppokorny@penguincomputing.com>, Margit Schubert-While <margitsw@t-online.de>");
 MODULE_DESCRIPTION("LM85-B, LM85-C driver");
-MODULE_PARM(lm85debug, "i");
-MODULE_PARM_DESC(lm85debug, "Enable debugging statements");
 
 module_init(sm_lm85_init);
 module_exit(sm_lm85_exit);
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 7beca18247b176a2926ffdfd1119a7c74b8ae6df..27a2e91313bd5371ed8bad147353ac5175fcbf4e 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -7,7 +7,7 @@ menu "USB support"
 # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
 config USB
 	tristate "Support for USB"
-	depends on PCI || SA1111
+	depends on PCI || SA1111 || ARCH_OMAP1510 || ARCH_OMAP1610
 	---help---
 	  Universal Serial Bus (USB) is a specification for a serial bus
 	  subsystem which offers higher speeds and more features than the
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 99553a58bfaec2475b474005913a3142f53ba0ca..c28626d2e4d4e75eca3113eee7e08b3f7b543a65 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -31,6 +31,7 @@
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
 
+#include "usb.h"
 #include "hcd.h"
 #include "hub.h"
 
@@ -1316,8 +1317,8 @@ int usb_physical_reset_device(struct usb_device *dev)
 		kfree(descriptor);
 		usb_destroy_configuration(dev);
 
-		ret = usb_get_device_descriptor(dev);
-		if (ret < sizeof(dev->descriptor)) {
+		ret = usb_get_device_descriptor(dev, sizeof(dev->descriptor));
+		if (ret != sizeof(dev->descriptor)) {
 			if (ret < 0)
 				err("unable to get device %s descriptor "
 					"(error=%d)", dev->devpath, ret);
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 04d08713e2bf430fd57ed0c10903e43c423fdf93..430c5b15f91d4a2ca221837d697fc76a66ba2e6e 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -546,10 +546,10 @@ void usb_sg_cancel (struct usb_sg_request *io)
  *
  * Gets a USB descriptor.  Convenience functions exist to simplify
  * getting some types of descriptors.  Use
- * usb_get_device_descriptor() for USB_DT_DEVICE,
+ * usb_get_device_descriptor() for USB_DT_DEVICE (not exported),
  * and usb_get_string() or usb_string() for USB_DT_STRING.
- * Configuration descriptors (USB_DT_CONFIG) are part of the device
- * structure, at least for the current configuration.
+ * Device (USB_DT_DEVICE) and configuration descriptors (USB_DT_CONFIG)
+ * are part of the device structure.
  * In addition to a number of USB-standard descriptors, some
  * devices also use class-specific or vendor-specific descriptors.
  *
@@ -610,6 +610,7 @@ int usb_get_string(struct usb_device *dev, unsigned short langid, unsigned char
 /**
  * usb_get_device_descriptor - (re)reads the device descriptor
  * @dev: the device whose device descriptor is being updated
+ * @size: how much of the descriptor to read
  * Context: !in_interrupt ()
  *
  * Updates the copy of the device descriptor stored in the device structure,
@@ -618,24 +619,35 @@ int usb_get_string(struct usb_device *dev, unsigned short langid, unsigned char
  * vendors product and version fields (idVendor, idProduct, and bcdDevice).
  * That lets device drivers compare against non-byteswapped constants.
  *
- * There's normally no need to use this call, although some devices
- * will change their descriptors after events like updating firmware.
+ * Not exported, only for use by the core.  If drivers really want to read
+ * the device descriptor directly, they can call usb_get_descriptor() with
+ * type = USB_DT_DEVICE and index = 0.
  *
  * This call is synchronous, and may not be used in an interrupt context.
  *
  * Returns the number of bytes received on success, or else the status code
  * returned by the underlying usb_control_msg() call.
  */
-int usb_get_device_descriptor(struct usb_device *dev)
+int usb_get_device_descriptor(struct usb_device *dev, unsigned int size)
 {
-	int ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor,
-				     sizeof(dev->descriptor));
+	struct usb_device_descriptor *desc;
+	int ret;
+
+	if (size > sizeof(*desc))
+		return -EINVAL;
+	desc = kmalloc(sizeof(*desc), GFP_NOIO);
+	if (!desc)
+		return -ENOMEM;
+
+	ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, size);
 	if (ret >= 0) {
-		le16_to_cpus(&dev->descriptor.bcdUSB);
-		le16_to_cpus(&dev->descriptor.idVendor);
-		le16_to_cpus(&dev->descriptor.idProduct);
-		le16_to_cpus(&dev->descriptor.bcdDevice);
+		le16_to_cpus(&desc->bcdUSB);
+		le16_to_cpus(&desc->idVendor);
+		le16_to_cpus(&desc->idProduct);
+		le16_to_cpus(&desc->bcdDevice);
+		memcpy(&dev->descriptor, desc, size);
 	}
+	kfree(desc);
 	return ret;
 }
 
@@ -1241,7 +1253,6 @@ EXPORT_SYMBOL(usb_sg_wait);
 
 // synchronous control message convenience routines
 EXPORT_SYMBOL(usb_get_descriptor);
-EXPORT_SYMBOL(usb_get_device_descriptor);
 EXPORT_SYMBOL(usb_get_status);
 EXPORT_SYMBOL(usb_get_string);
 EXPORT_SYMBOL(usb_string);
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 05a7a9f8fa551c944bf8eb112cd4581131181807..e3b10d895a51cab9eb7825c2ef2787c57cf64c44 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -206,12 +206,15 @@ void usb_deregister(struct usb_driver *driver)
  */
 struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum)
 {
+	struct usb_host_config *config = dev->actconfig;
 	int i;
 
-	for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++)
-		if (dev->actconfig->interface[i]->altsetting[0]
+	if (!config)
+		return NULL;
+	for (i = 0; i < config->desc.bNumInterfaces; i++)
+		if (config->interface[i]->altsetting[0]
 				.desc.bInterfaceNumber == ifnum)
-			return dev->actconfig->interface[i];
+			return config->interface[i];
 
 	return NULL;
 }
@@ -233,14 +236,17 @@ struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum)
 struct usb_endpoint_descriptor *
 usb_epnum_to_ep_desc(struct usb_device *dev, unsigned epnum)
 {
+	struct usb_host_config *config = dev->actconfig;
 	int i, k;
 
-	for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
+	if (!config)
+		return NULL;
+	for (i = 0; i < config->desc.bNumInterfaces; i++) {
 		struct usb_interface		*intf;
 		struct usb_host_interface	*alt;
 
-		/* only endpoints in current altseting are active */
-		intf = dev->actconfig->interface[i];
+		/* only endpoints in current altsetting are active */
+		intf = config->interface[i];
 		alt = intf->altsetting + intf->act_altsetting;
 
 		for (k = 0; k < alt->desc.bNumEndpoints; k++)
@@ -1059,7 +1065,7 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
 		wait_ms(10);	/* Let the SET_ADDRESS settle */
 
 		/* high and low speed devices don't need this... */
-		err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, 8);
+		err = usb_get_device_descriptor(dev, 8);
 		if (err >= 8)
 			break;
 		wait_ms(100);
@@ -1079,8 +1085,8 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
 
 	/* USB device state == addressed ... still not usable */
 
-	err = usb_get_device_descriptor(dev);
-	if (err < (signed)sizeof(dev->descriptor)) {
+	err = usb_get_device_descriptor(dev, sizeof(dev->descriptor));
+	if (err != (signed)sizeof(dev->descriptor)) {
 		dev_err(&dev->dev, "device descriptor read/all, error %d\n", err);
 		goto fail;
 	}
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 5f03c160036ac85b9b8439002c4e85bbe9ab9012..ea0336fd58544ccf45b68aa1a8c79f405da9a2c8 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -14,3 +14,6 @@ extern void usb_enable_endpoint (struct usb_device *dev,
 		struct usb_endpoint_descriptor *epd);
 extern void usb_enable_interface (struct usb_device *dev,
 		struct usb_interface *intf);
+
+extern int usb_get_device_descriptor(struct usb_device *dev,
+		unsigned int size);
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 77a7eef3647722ce3d8af31960eb0d5306bd9f5a..38e9f6a2a2bf0e4023362f27ead7dd90019d59f8 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -3,12 +3,10 @@
 #    (a) a peripheral controller, and
 #    (b) the gadget driver using it.
 #
-# for 2.5 kbuild, drivers/usb/gadget/Kconfig
-# source this at the end of drivers/usb/Kconfig
-#
-menuconfig USB_GADGET
+menu "USB Gadget Support"
+
+config USB_GADGET
 	tristate "Support for USB Gadgets"
-	depends on EXPERIMENTAL
 	help
 	   USB is a master/slave protocol, organized with one master
 	   host (such as a PC) controlling up to 127 peripheral devices.
@@ -36,12 +34,15 @@ menuconfig USB_GADGET
 # USB Peripheral Controller Support
 #
 choice
-	prompt "USB Peripheral Controller Support"
+	prompt "USB Peripheral Controller"
 	depends on USB_GADGET
+	help
+	   A USB device uses a controller to talk to its host.
+	   Systems should have only one such upstream link.
 
-config USB_NET2280
-	tristate "NetChip 2280 USB Peripheral Controller"
-	depends on PCI && USB_GADGET
+config USB_GADGET_NET2280
+	boolean "NetChip 2280"
+	depends on PCI
 	help
 	   NetChip 2280 is a PCI based USB peripheral controller which
 	   supports both full and high speed USB 2.0 data transfers.  
@@ -54,21 +55,91 @@ config USB_NET2280
 	   dynamically linked module called "net2280" and force all
 	   gadget drivers to also be dynamically linked.
 
+config USB_NET2280
+	tristate
+	depends on USB_GADGET_NET2280
+	default USB_GADGET
+
+config USB_GADGET_PXA2XX
+	boolean "PXA 2xx or IXP 42x"
+	depends on ARCH_PXA || ARCH_IXP425
+	help
+	   Intel's PXA 2xx series XScale ARM-5TE processors include
+	   an integrated full speed USB 1.1 device controller.  The
+	   controller in the IXP 4xx series is register-compatible.
+
+	   It has fifteen fixed-function endpoints, as well as endpoint
+	   zero (for control transfers).
+
+	   Say "y" to link the driver statically, or "m" to build a
+	   dynamically linked module called "pxa2xx_udc" and force all
+	   gadget drivers to also be dynamically linked.
+
+config USB_PXA2XX
+	tristate
+	depends on USB_GADGET_PXA2XX
+	default USB_GADGET
+
+# if there's only one gadget driver, using only two bulk endpoints,
+# don't waste memory for the other endpoints
+config USB_PXA2XX_SMALL
+	depends on USB_GADGET_PXA2XX
+	bool
+	default y if USB_ZERO
+	default y if USB_ETH
+	default y if USB_G_SERIAL
+
+config USB_GADGET_GOKU
+	boolean "Toshiba TC86C001 'Goku-S'"
+	depends on PCI
+	help
+	   The Toshiba TC86C001 is a PCI device which includes controllers
+	   for full speed USB devices, IDE, I2C, SIO, plus a USB host (OHCI).
+	   
+	   The device controller has three configurable (bulk or interrupt)
+	   endpoints, plus endpoint zero (for control transfers).
+
+	   Say "y" to link the driver statically, or "m" to build a
+	   dynamically linked module called "goku_udc" and to force all
+	   gadget drivers to also be dynamically linked.
+
+config USB_GOKU
+	tristate
+	depends on USB_GADGET_GOKU
+	default USB_GADGET
+
+# this could be built elsewhere (doesn't yet exist)
+config USB_GADGET_SA1100
+	boolean "SA 1100"
+	depends on ARCH_SA1100
+	help
+	   Intel's SA-1100 is an ARM-4 processor with an integrated
+	   full speed USB 1.1 device controller.
+
+	   It has two fixed-function endpoints, as well as endpoint
+	   zero (for control transfers).
+
+config USB_SA1100
+	tristate
+	depends on USB_GADGET_SA1100
+	default USB_GADGET
+
 endchoice
 
+
 #
 # USB Gadget Drivers
 #
 choice
-	prompt "USB Gadget Drivers"
+	tristate "USB Gadget Drivers"
 	depends on USB_GADGET
 	default USB_ETH
 
-# FIXME want a cleaner dependency/config approach for drivers.
+# this first set of drivers all depend on bulk-capable hardware.
 
 config USB_ZERO
 	tristate "Gadget Zero (DEVELOPMENT)"
-	depends on USB_GADGET && (USB_DUMMY_HCD || USB_NET2280 || USB_PXA2XX || USB_SA1100)
+	depends on EXPERIMENTAL
 	help
 	  Gadget Zero is a two-configuration device.  It either sinks and
 	  sources bulk data; or it loops back a configurable number of
@@ -91,26 +162,9 @@ config USB_ZERO
 	  Say "y" to link the driver statically, or "m" to build a
 	  dynamically linked module called "g_zero".
 
-config USB_ZERO_NET2280
-	bool
-	# for now, treat the "dummy" hcd as if it were a net2280
-	depends on USB_ZERO && (USB_NET2280 || USB_DUMMY_HCD)
-	default y
-
-config USB_ZERO_PXA2XX
-	bool
-	depends on USB_ZERO && USB_PXA2XX
-	default y
-
-config USB_ZERO_SA1100
-	bool
-	depends on USB_ZERO && USB_SA1100
-	default y
-
-
 config USB_ETH
 	tristate "Ethernet Gadget"
-	depends on USB_GADGET && NET && (USB_DUMMY_HCD || USB_NET2280 || USB_PXA2XX || USB_SA1100)
+	depends on NET
 	help
 	  This driver implements Ethernet style communication, in either
 	  of two ways:
@@ -136,26 +190,9 @@ config USB_ETH
 	  Say "y" to link the driver statically, or "m" to build a
 	  dynamically linked module called "g_ether".
 
-
-config USB_ETH_NET2280
-	bool
-	# for now, treat the "dummy" hcd as if it were a net2280
-	depends on USB_ETH && (USB_NET2280 || USB_DUMMY_HCD)
-	default y
-
-config USB_ETH_PXA2XX
-	bool
-	depends on USB_ETH && USB_PXA2XX
-	default y
-
-config USB_ETH_SA1100
-	bool
-	depends on USB_ETH && USB_SA1100
-	default y
-
 config USB_GADGETFS
 	tristate "Gadget Filesystem (EXPERIMENTAL)"
-	depends on USB_GADGET && (USB_DUMMY_HCD || USB_NET2280 || USB_PXA2XX) && EXPERIMENTAL
+	depends on EXPERIMENTAL
 	help
 	  This driver provides a filesystem based API that lets user mode
 	  programs implement a single-configuration USB device, including
@@ -166,38 +203,44 @@ config USB_GADGETFS
 	  Say "y" to link the driver statically, or "m" to build a
 	  dynamically linked module called "gadgetfs".
 
-config USB_GADGETFS_NET2280
-	bool
-	# for now, treat the "dummy" hcd as if it were a net2280
-	depends on USB_GADGETFS && (USB_NET2280 || USB_DUMMY_HCD)
-	default y
+config USB_FILE_STORAGE
+	tristate "File-backed Storage Gadget (DEVELOPMENT)"
+	# we don't support the SA1100 because of its limitations
+	depends on USB_GADGET_SA1100 = n
+	help
+	  The File-backed Storage Gadget acts as a USB Mass Storage
+	  disk drive.  As its storage repository it can use a regular
+	  file or a block device (in much the same way as the "loop"
+	  device driver), specified as a module parameter.
 
-config USB_GADGETFS_PXA2XX
-	bool
-	depends on USB_GADGETFS && USB_PXA2XX
-	default y
+	  Say "y" to link the driver statically, or "m" to build a
+	  dynamically linked module called "g_file_storage".
+
+config USB_FILE_STORAGE_TEST
+	bool "File-backed Storage Gadget test version"
+	depends on USB_FILE_STORAGE
+	default n
+	help
+	  Say "y" to generate the larger testing version of the
+	  File-backed Storage Gadget, useful for probing the
+	  behavior of USB Mass Storage hosts.  Not needed for
+	  normal operation.
 
 config USB_G_SERIAL
-	tristate "serial Gadget"
-	depends on USB_GADGET && (USB_DUMMY_HCD || USB_NET2280 || USB_PXA2XX || USB_SA1100)
+	tristate "Serial Gadget"
+	help
+	  The Serial Gadget talks to the Linux-USB generic serial driver.
 
-config USB_G_SERIAL_NET2280
-	bool
-	# for now, treat the "dummy" hcd as if it were a net2280
-	depends on USB_G_SERIAL && (USB_NET2280 || USB_DUMMY_HCD)
-	default y
+	  Say "y" to link the driver statically, or "m" to build a
+	  dynamically linked module called "g_serial".
 
-config USB_G_SERIAL_PXA2XX
-	bool
-	depends on USB_G_SERIAL && USB_PXA2XX
-	default y
 
-config USB_G_SERIAL_SA1100
-	bool
-	depends on USB_G_SERIAL && USB_SA1100
-	default y
 
+# put drivers that need isochronous transfer support (for audio
+# or video class gadget drivers), or specific hardware, here.
+
+# - none yet
 
 endchoice
 
-# endmenuconfig
+endmenu
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index dca74c3b1bab9f62c2a558af287bfda85b91af14..8c332a4dee102f81a96e485c135c6e1a0e193ce4 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -2,6 +2,8 @@
 # USB peripheral controller drivers
 #
 obj-$(CONFIG_USB_NET2280)	+= net2280.o
+obj-$(CONFIG_USB_PXA2XX)	+= pxa2xx_udc.o
+obj-$(CONFIG_USB_GOKU)		+= goku_udc.o
 
 #
 # USB gadget drivers
@@ -10,8 +12,11 @@ g_zero-objs			:= zero.o usbstring.o
 g_ether-objs			:= ether.o usbstring.o
 g_serial-objs			:= serial.o usbstring.o
 gadgetfs-objs			:= inode.o usbstring.o
+g_file_storage-objs		:= file_storage.o usbstring.o
  
 obj-$(CONFIG_USB_ZERO)		+= g_zero.o
 obj-$(CONFIG_USB_ETH)		+= g_ether.o
 obj-$(CONFIG_USB_GADGETFS)	+= gadgetfs.o
+obj-$(CONFIG_USB_FILE_STORAGE)	+= g_file_storage.o
 obj-$(CONFIG_USB_G_SERIAL)	+= g_serial.o
+
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 131ee14bc56872214914a0b5f47384cfb47c7520..7d64b7cbe88f16f280ed764a0a767070661c513e 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -122,12 +122,9 @@ struct eth_dev {
  *
  * CHIP ... hardware identifier
  * DRIVER_VERSION_NUM ... alerts the host side driver to differences
- * EP0_MAXPACKET ... controls packetization of control requests
  * EP_*_NAME ... which endpoints do we use for which purpose?
  * EP_*_NUM ... numbers for them (often limited by hardware)
  * HIGHSPEED ... define if ep0 and descriptors need high speed support
- * MAX_USB_POWER ... define if we use other than 100 mA bus current
- * SELFPOWER ... unless we can run on bus power, USB_CONFIG_ATT_SELFPOWER
  * WAKEUP ... if hardware supports remote wakeup AND we will issue the
  * 	usb_gadget_wakeup() call to initiate it, USB_CONFIG_ATT_WAKEUP
  *
@@ -143,6 +140,9 @@ struct eth_dev {
 /* #undef on hardware that can't implement CDC */
 #define	DEV_CONFIG_CDC
 
+/* undef on bus-powered hardware, and #define MAX_USB_POWER */
+#define SELFPOWER
+
 /*
  * NetChip 2280, PCI based.
  *
@@ -152,11 +152,10 @@ struct eth_dev {
  * performance note:  only PIO needs per-usb-packet IRQs (ep0, ep-e, ep-f)
  * otherwise IRQs are per-Ethernet-packet unless TX_DELAY and chaining help.
  */
-#ifdef	CONFIG_USB_ETH_NET2280
+#ifdef	CONFIG_USB_GADGET_NET2280
 #define CHIP			"net2280"
 #define DEFAULT_QLEN		4		/* has dma chaining */
 #define DRIVER_VERSION_NUM	0x0101
-#define EP0_MAXPACKET		64
 static const char EP_OUT_NAME [] = "ep-a";
 #define EP_OUT_NUM	1
 static const char EP_IN_NAME [] = "ep-b";
@@ -164,8 +163,6 @@ static const char EP_IN_NAME [] = "ep-b";
 static const char EP_STATUS_NAME [] = "ep-f";
 #define EP_STATUS_NUM	3
 #define HIGHSPEED
-/* specific hardware configs could be bus-powered */
-#define SELFPOWER USB_CONFIG_ATT_SELFPOWER
 /* supports remote wakeup, but this driver doesn't */
 
 extern int net2280_set_fifo_mode (struct usb_gadget *gadget, int mode);
@@ -186,17 +183,14 @@ static inline void hw_optimize (struct usb_gadget *gadget)
  * multiple interfaces (or altsettings) aren't usable.  so this hardware
  * can't implement CDC, which needs both capabilities.
  */
-#ifdef	CONFIG_USB_ETH_PXA2XX
+#ifdef	CONFIG_USB_GADGET_PXA2XX
 #undef	DEV_CONFIG_CDC
 #define CHIP			"pxa2xx"
 #define DRIVER_VERSION_NUM	0x0103
-#define EP0_MAXPACKET		16
 static const char EP_OUT_NAME [] = "ep2out-bulk";
 #define EP_OUT_NUM	2
 static const char EP_IN_NAME [] = "ep1in-bulk";
 #define EP_IN_NUM	1
-/* doesn't support bus-powered operation */
-#define SELFPOWER USB_CONFIG_ATT_SELFPOWER
 /* supports remote wakeup, but this driver doesn't */
 
 /* no hw optimizations to apply */
@@ -209,17 +203,14 @@ static const char EP_IN_NAME [] = "ep1in-bulk";
  * can't have a notification endpoint, since there are only the two
  * bulk-capable ones.  the CDC spec allows that.
  */
-#ifdef	CONFIG_USB_ETH_SA1100
+#ifdef	CONFIG_USB_GADGET_SA1100
 #define CHIP			"sa1100"
 #define DRIVER_VERSION_NUM	0x0105
-#define EP0_MAXPACKET		8
 static const char EP_OUT_NAME [] = "ep1out-bulk";
 #define EP_OUT_NUM	1
 static const char EP_IN_NAME [] = "ep2in-bulk";
 #define EP_IN_NUM	2
 // EP_STATUS_NUM is undefined
-/* doesn't support bus-powered operation */
-#define SELFPOWER USB_CONFIG_ATT_SELFPOWER
 /* doesn't support remote wakeup? */
 
 /* no hw optimizations to apply */
@@ -231,25 +222,43 @@ static const char EP_IN_NAME [] = "ep2in-bulk";
  *
  * This has three semi-configurable full speed bulk/interrupt endpoints.
  */
-#ifdef	CONFIG_USB_ETH_GOKU
+#ifdef	CONFIG_USB_GADGET_GOKU
 #define CHIP			"goku"
 #define DRIVER_VERSION_NUM	0x0106
-#define EP0_MAXPACKET		8
 static const char EP_OUT_NAME [] = "ep1-bulk";
 #define EP_OUT_NUM	1
 static const char EP_IN_NAME [] = "ep2-bulk";
 #define EP_IN_NUM	2
 static const char EP_STATUS_NAME [] = "ep3-bulk";
 #define EP_STATUS_NUM	3
-#define SELFPOWER USB_CONFIG_ATT_SELFPOWER
 /* doesn't support remote wakeup */
 
 #define hw_optimize(g) do {} while (0)
 #endif
 
+/*
+ * SuperH UDC:  UDC built-in to some Renesas SH processors.
+ *
+ * This has three semi-configurable full speed bulk/interrupt endpoints.
+ *
+ * Only one configuration and interface is supported.  So this hardware
+ * can't implement CDC.
+ */
+#ifdef	CONFIG_USB_GADGET_SUPERH
+#undef	DEV_CONFIG_CDC
+#define CHIP			"superh"
+#define DRIVER_VERSION_NUM	0x0107
+static const char EP_OUT_NAME[] = "ep1out-bulk";
+#define EP_OUT_NUM		1
+static const char EP_IN_NAME[] = "ep2in-bulk";
+#define EP_IN_NUM		2
+
+#define hw_optimize(g) do {} while (0)
+#endif
+
 /*-------------------------------------------------------------------------*/
 
-#ifndef EP0_MAXPACKET
+#ifndef CHIP
 #	error Configure some USB peripheral controller driver!
 #endif
 
@@ -280,19 +289,15 @@ static const char EP_STATUS_NAME [] = "ep3-bulk";
  * hardware that supports remote wakeup defaults to disabling it.
  */
 
-#ifndef	SELFPOWER
-/* default: say we rely on bus power */
-#define SELFPOWER	0
-/* else:
- * - SELFPOWER value must be USB_CONFIG_ATT_SELFPOWER
- * - MAX_USB_POWER may be nonzero.
- */
-#endif
-
 #ifndef	MAX_USB_POWER
-/* any hub supports this steady state bus power consumption */
-#define MAX_USB_POWER	100	/* mA */
+#ifdef	SELFPOWER
+/* some hosts are confused by 0mA  */
+#define MAX_USB_POWER	2	/* mA */
+#else
+/* bus powered */
+#error	Define your bus power consumption!
 #endif
+#endif	/* MAX_USB_POWER */
 
 #ifndef	WAKEUP
 /* default: this driver won't do remote wakeup */
@@ -376,7 +381,7 @@ module_param (qmult, uint, S_IRUGO|S_IWUSR);
 /*
  * This device advertises one configuration.
  */
-static const struct usb_device_descriptor
+static struct usb_device_descriptor
 device_desc = {
 	.bLength =		sizeof device_desc,
 	.bDescriptorType =	USB_DT_DEVICE,
@@ -386,7 +391,6 @@ device_desc = {
 	.bDeviceClass =		DEV_CONFIG_CLASS,
 	.bDeviceSubClass =	0,
 	.bDeviceProtocol =	0,
-	.bMaxPacketSize0 =	EP0_MAXPACKET,
 
 	.idVendor =		__constant_cpu_to_le16 (DRIVER_VENDOR_NUM),
 	.idProduct =		__constant_cpu_to_le16 (DRIVER_PRODUCT_NUM),
@@ -396,7 +400,7 @@ device_desc = {
 	.bNumConfigurations =	1,
 };
 
-static const struct usb_config_descriptor
+static struct usb_config_descriptor
 eth_config = {
 	.bLength =		sizeof eth_config,
 	.bDescriptorType =	USB_DT_CONFIG,
@@ -409,7 +413,7 @@ eth_config = {
 #endif
 	.bConfigurationValue =	DEV_CONFIG_VALUE,
 	.iConfiguration =	STRING_PRODUCT,
-	.bmAttributes =		USB_CONFIG_ATT_ONE | SELFPOWER | WAKEUP,
+	.bmAttributes =		USB_CONFIG_ATT_ONE | WAKEUP,
 	.bMaxPower =		(MAX_USB_POWER + 1) / 2,
 };
 
@@ -645,7 +649,7 @@ hs_sink_desc = {
 	.bInterval =		1,
 };
 
-static const struct usb_qualifier_descriptor
+static struct usb_qualifier_descriptor
 dev_qualifier = {
 	.bLength =		sizeof dev_qualifier,
 	.bDescriptorType =	USB_DT_DEVICE_QUALIFIER,
@@ -653,12 +657,10 @@ dev_qualifier = {
 	.bcdUSB =		__constant_cpu_to_le16 (0x0200),
 	.bDeviceClass =		DEV_CONFIG_CLASS,
 
-	/* assumes ep0 uses the same value for both speeds ... */
-	.bMaxPacketSize0 =	EP0_MAXPACKET,
-
 	.bNumConfigurations =	1,
 };
 
+
 /* maxpacket and other transfer characteristics vary by speed. */
 #define ep_desc(g,hs,fs) (((g)->speed==USB_SPEED_HIGH)?(hs):(fs))
 
@@ -959,7 +961,7 @@ eth_set_config (struct eth_dev *dev, unsigned number, int gfp_flags)
 	if (number == dev->config)
 		return 0;
 
-#ifdef CONFIG_USB_ETH_SA1100
+#ifdef CONFIG_USB_GADGET_SA1100
 	if (dev->config && atomic_read (&dev->tx_qlen) != 0) {
 		/* tx fifo is full, but we can't clear it...*/
 		INFO (dev, "can't change configurations\n");
@@ -1006,6 +1008,7 @@ eth_set_config (struct eth_dev *dev, unsigned number, int gfp_flags)
 
 /* section 3.8.2 table 11 of the CDC spec lists Ethernet notifications */
 #define CDC_NOTIFY_NETWORK_CONNECTION	0x00	/* required; 6.3.1 */
+#define CDC_NOTIFY_RESPONSE_AVAILABLE	0x01	/* optional; 6.3.2 */
 #define CDC_NOTIFY_SPEED_CHANGE		0x2a	/* required; 6.3.8 */
 
 struct cdc_notification {
@@ -1123,6 +1126,8 @@ static void eth_setup_complete (struct usb_ep *ep, struct usb_request *req)
 /* see section 3.8.2 table 10 of the CDC spec for more ethernet
  * requests, mostly for filters (multicast, pm) and statistics
  */
+#define CDC_SEND_ENCAPSULATED_REQUEST	0x00	/* optional */
+#define CDC_GET_ENCAPSULATED_RESPONSE	0x01	/* optional */
 #define CDC_SET_ETHERNET_PACKET_FILTER	0x43	/* required */
 
 /*
@@ -1188,7 +1193,7 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
 		value = eth_set_config (dev, ctrl->wValue, GFP_ATOMIC);
 		spin_unlock (&dev->lock);
 		break;
-#ifdef	CONFIG_USB_ETH_PXA2XX
+#ifdef	CONFIG_USB_GADGET_PXA2XX
 	/* PXA UDC prevents us from using SET_INTERFACE in normal ways.
 	 * And it hides GET_CONFIGURATION and GET_INTERFACE too.
 	 */
@@ -1638,7 +1643,7 @@ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net)
 	req->context = skb;
 	req->complete = tx_complete;
 
-#ifdef	CONFIG_USB_ETH_SA1100
+#ifdef	CONFIG_USB_GADGET_SA1100
 	/* don't demand zlp (req->zero) support from all hardware */
 	if ((length % dev->in_ep->maxpacket) == 0)
 		length++;
@@ -1770,6 +1775,17 @@ eth_bind (struct usb_gadget *gadget)
 		return -ENODEV;
 #endif
 
+	device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
+#ifdef	HIGHSPEED
+	/* assumes ep0 uses the same value for both speeds ... */
+	dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0;
+#endif
+
+#ifdef	SELFPOWERED
+	eth_config.bmAttributes |= USB_CONFIG_ATT_SELFPOWERED;
+	usb_gadget_set_selfpowered (gadget);
+#endif
+
  	net = alloc_etherdev (sizeof *dev);
  	if (!net)
 		return status;
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
new file mode 100644
index 0000000000000000000000000000000000000000..5c34452c0654e8efa4ae0b1da5e3bfaa1aa9120d
--- /dev/null
+++ b/drivers/usb/gadget/file_storage.c
@@ -0,0 +1,4169 @@
+/*
+ * file_storage.c -- File-backed USB Storage Gadget, for USB development
+ *
+ * Copyright (C) 2003 Alan Stern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/*
+ * The File-backed Storage Gadget acts as a USB Mass Storage device,
+ * appearing to the host as a disk drive.  In addition to providing an
+ * example of a genuinely useful gadget driver for a USB device, it also
+ * illustrates a technique of double-buffering for increased throughput.
+ * Last but not least, it gives an easy way to probe the behavior of the
+ * Mass Storage drivers in a USB host.
+ *
+ * Backing storage is provided by a regular file or a block device, specified
+ * by the "file" module parameter.  Access can be limited to read-only by
+ * setting the optional "ro" module parameter.
+ *
+ * The gadget supports the Control-Bulk (CB), Control-Bulk-Interrupt (CBI),
+ * and Bulk-Only (also known as Bulk-Bulk-Bulk or BBB) transports, selected
+ * by the optional "transport" module parameter.  It also supports the
+ * following protocols: RBC (0x01), ATAPI or SFF-8020i (0x02), QIC-157 (0c03),
+ * UFI (0x04), SFF-8070i (0x05), and transparent SCSI (0x06), selected by
+ * the optional "protocol" module parameter.  For testing purposes the
+ * gadget will indicate that it has removable media if the optional
+ * "removable" module parameter is set.  In addition, the default Vendor ID,
+ * Product ID, and release number can be overridden.
+ *
+ * There is support for multiple logical units (LUNs), each of which has
+ * its own backing file.  The number of LUNs can be set using the optional
+ * "luns" module parameter (anywhere from 1 to 8), and the corresponding
+ * files are specified using comma-separated lists for "file" and "ro".
+ * The default number of LUNs is taken from the number of "file" elements;
+ * it is 1 if "file" is not given.  If "removable" is not set then a backing
+ * file must be specified for each LUN.  If it is set, then an unspecified
+ * or empty backing filename means the LUN's medium is not loaded.
+ *
+ * Requirements are modest; only a bulk-in and a bulk-out endpoint are
+ * needed (an interrupt-out endpoint is also needed for CBI).  The memory
+ * requirement amounts to two 16K buffers, size configurable by a parameter.
+ * Support is included for both full-speed and high-speed operation.
+ *
+ * Module options:
+ *
+ *	file=filename[,filename...]
+ *				Required if "removable" is not set, names of
+ *					the files or block devices used for
+ *					backing storage
+ *	ro=b[,b...]		Default false, booleans for read-only access
+ *	luns=N			Default N = number of filenames, number of
+ *					LUNs to support
+ *	transport=XXX		Default BBB, transport name (CB, CBI, or BBB)
+ *	protocol=YYY		Default SCSI, protocol name (RBC, 8020 or
+ *					ATAPI, QIC, UFI, 8070, or SCSI;
+ *					also 1 - 6)
+ *	removable		Default false, boolean for removable media
+ *	vendor=0xVVVV		Default 0x0525 (NetChip), USB Vendor ID
+ *	product=0xPPPP		Default 0xa4a5 (FSG), USB Product ID
+ *	release=0xRRRR		Override the USB release number (bcdDevice)
+ *	buflen=N		Default N=16384, buffer size used (will be
+ *					rounded down to a multiple of
+ *					PAGE_CACHE_SIZE)
+ *	stall			Default determined according to the type of
+ *					USB device controller (usually true),
+ *					boolean to permit the driver to halt
+ *					bulk endpoints
+ *
+ * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file" and "ro"
+ * options are available; default values are used for everything else.
+ *
+ * The pathnames of the backing files and the ro settings are available in
+ * the attribute files "file" and "ro" in the lun<n> subdirectory of the
+ * gadget's sysfs directory.  If CONFIG_USB_FILE_STORAGE_TEST and the
+ * "removable" option are both set, writing to these files will simulate
+ * ejecting/loading the medium (writing an empty line means eject) and
+ * adjusting a write-enable tab.  Changes to the ro setting are not allowed
+ * when the medium is loaded.
+ *
+ * This gadget driver is heavily based on "Gadget Zero" by David Brownell.
+ */
+
+
+/*
+ *				Driver Design
+ *
+ * The FSG driver is fairly straightforward.  There is a main kernel
+ * thread that handles most of the work.  Interrupt routines field
+ * callbacks from the controller driver: bulk- and interrupt-request
+ * completion notifications, endpoint-0 events, and disconnect events.
+ * Completion events are passed to the main thread by wakeup calls.  Many
+ * ep0 requests are handled at interrupt time, but SetInterface,
+ * SetConfiguration, and device reset requests are forwarded to the
+ * thread in the form of "exceptions" using SIGUSR1 signals (since they
+ * should interrupt any ongoing file I/O operations).
+ *
+ * The thread's main routine implements the standard command/data/status
+ * parts of a SCSI interaction.  It and its subroutines are full of tests
+ * for pending signals/exceptions -- all this polling is necessary since
+ * the kernel has no setjmp/longjmp equivalents.  (Maybe this is an
+ * indication that the driver really wants to be running in userspace.)
+ * An important point is that so long as the thread is alive it keeps an
+ * open reference to the backing file.  This will prevent unmounting
+ * the backing file's underlying filesystem and could cause problems
+ * during system shutdown, for example.  To prevent such problems, the
+ * thread catches INT, TERM, and KILL signals and converts them into
+ * an EXIT exception.
+ *
+ * In normal operation the main thread is started during the gadget's
+ * fsg_bind() callback and stopped during fsg_unbind().  But it can also
+ * exit when it receives a signal, and there's no point leaving the
+ * gadget running when the thread is dead.  So just before the thread
+ * exits, it deregisters the gadget driver.  This makes things a little
+ * tricky: The driver is deregistered at two places, and the exiting
+ * thread can indirectly call fsg_unbind() which in turn can tell the
+ * thread to exit.  The first problem is resolved through the use of the
+ * REGISTERED atomic bitflag; the driver will only be deregistered once.
+ * The second problem is resolved by having fsg_unbind() check
+ * fsg->state; it won't try to stop the thread if the state is already
+ * FSG_STATE_TERMINATED.
+ *
+ * To provide maximum throughput, the driver uses a circular pipeline of
+ * buffer heads (struct fsg_buffhd).  In principle the pipeline can be
+ * arbitrarily long; in practice the benefits don't justify having more
+ * than 2 stages (i.e., double buffering).  But it helps to think of the
+ * pipeline as being a long one.  Each buffer head contains a bulk-in and
+ * a bulk-out request pointer (since the buffer can be used for both
+ * output and input -- directions always are given from the host's
+ * point of view) as well as a pointer to the buffer and various state
+ * variables.
+ *
+ * Use of the pipeline follows a simple protocol.  There is a variable
+ * (fsg->next_buffhd_to_fill) that points to the next buffer head to use.
+ * At any time that buffer head may still be in use from an earlier
+ * request, so each buffer head has a state variable indicating whether
+ * it is EMPTY, FULL, or BUSY.  Typical use involves waiting for the
+ * buffer head to be EMPTY, filling the buffer either by file I/O or by
+ * USB I/O (during which the buffer head is BUSY), and marking the buffer
+ * head FULL when the I/O is complete.  Then the buffer will be emptied
+ * (again possibly by USB I/O, during which it is marked BUSY) and
+ * finally marked EMPTY again (possibly by a completion routine).
+ *
+ * A module parameter tells the driver to avoid stalling the bulk
+ * endpoints wherever the transport specification allows.  This is
+ * necessary for some UDCs like the SuperH, which cannot reliably clear a
+ * halt on a bulk endpoint.  However, under certain circumstances the
+ * Bulk-only specification requires a stall.  In such cases the driver
+ * will halt the endpoint and set a flag indicating that it should clear
+ * the halt in software during the next device reset.  Hopefully this
+ * will permit everything to work correctly.
+ *
+ * One subtle point concerns sending status-stage responses for ep0
+ * requests.  Some of these requests, such as device reset, can involve
+ * interrupting an ongoing file I/O operation, which might take an
+ * arbitrarily long time.  During that delay the host might give up on
+ * the original ep0 request and issue a new one.  When that happens the
+ * driver should not notify the host about completion of the original
+ * request, as the host will no longer be waiting for it.  So the driver
+ * assigns to each ep0 request a unique tag, and it keeps track of the
+ * tag value of the request associated with a long-running exception
+ * (device-reset, interface-change, or configuration-change).  When the
+ * exception handler is finished, the status-stage response is submitted
+ * only if the current ep0 request tag is equal to the exception request
+ * tag.  Thus only the most recently received ep0 request will get a
+ * status-stage response.
+ *
+ * Warning: This driver source file is too long.  It ought to be split up
+ * into a header file plus about 3 separate .c files, to handle the details
+ * of the Gadget, USB Mass Storage, and SCSI protocols.
+ */
+
+
+#undef DEBUG
+#undef VERBOSE
+#undef DUMP_MSGS
+
+#include <linux/config.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include <linux/bitops.h>
+#include <linux/blkdev.h>
+#include <linux/compiler.h>
+#include <linux/completion.h>
+#include <linux/dcache.h>
+#include <linux/device.h>
+#include <linux/fcntl.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/limits.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/pagemap.h>
+#include <linux/rwsem.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/uts.h>
+#include <linux/version.h>
+#include <linux/wait.h>
+
+#include <linux/usb_ch9.h>
+#include <linux/usb_gadget.h>
+
+
+/*-------------------------------------------------------------------------*/
+
+#define DRIVER_DESC		"File-backed Storage Gadget"
+#define DRIVER_NAME		"g_file_storage"
+#define DRIVER_VERSION		"14 January 2004"
+
+static const char longname[] = DRIVER_DESC;
+static const char shortname[] = DRIVER_NAME;
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Alan Stern");
+MODULE_LICENSE("Dual BSD/GPL");
+
+/* Thanks to NetChip Technologies for donating this product ID.
+ *
+ * DO NOT REUSE THESE IDs with any other driver!!  Ever!!
+ * Instead:  allocate your own, using normal USB-IF procedures. */
+#define DRIVER_VENDOR_ID	0x0525	// NetChip
+#define DRIVER_PRODUCT_ID	0xa4a5	// Linux-USB File-backed Storage Gadget
+
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Hardware-specific configuration, controlled by which device
+ * controller driver was configured.
+ *
+ * CHIP ... hardware identifier
+ * DRIVER_VERSION_NUM ... alerts the host side driver to differences
+ * EP_*_NAME ... which endpoints do we use for which purpose?
+ * EP_*_NUM ... numbers for them (often limited by hardware)
+ * FS_BULK_IN_MAXPACKET ... maxpacket value for full-speed bulk-in ep
+ * FS_BULK_OUT_MAXPACKET ... maxpacket value for full-speed bulk-out ep
+ * HIGHSPEED ... define if ep0 and descriptors need high speed support
+ * MAX_USB_POWER ... define if we use other than 100 mA bus current
+ * SELFPOWER ... if we can run on bus power, zero
+ * NO_BULK_STALL ... bulk endpoint halts don't work well so avoid them
+ */
+
+
+/*
+ * NetChip 2280, PCI based.
+ *
+ * This has half a dozen configurable endpoints, four with dedicated
+ * DMA channels to manage their FIFOs.  It supports high speed.
+ * Those endpoints can be arranged in any desired configuration.
+ */
+#ifdef	CONFIG_USB_GADGET_NET2280
+#define CHIP			"net2280"
+#define DRIVER_VERSION_NUM	0x0201
+static const char EP_BULK_IN_NAME[] = "ep-a";
+#define EP_BULK_IN_NUM		1
+#define FS_BULK_IN_MAXPACKET	64
+static const char EP_BULK_OUT_NAME[] = "ep-b";
+#define EP_BULK_OUT_NUM		2
+#define FS_BULK_OUT_MAXPACKET	64
+static const char EP_INTR_IN_NAME[] = "ep-e";
+#define EP_INTR_IN_NUM		5
+#define HIGHSPEED
+#endif
+
+
+/*
+ * Dummy_hcd, software-based loopback controller.
+ *
+ * This imitates the abilities of the NetChip 2280, so we will use
+ * the same configuration.
+ */
+#ifdef	CONFIG_USB_GADGET_DUMMY_HCD
+#define CHIP			"dummy"
+#define DRIVER_VERSION_NUM	0x0202
+static const char EP_BULK_IN_NAME[] = "ep-a";
+#define EP_BULK_IN_NUM		1
+#define FS_BULK_IN_MAXPACKET	64
+static const char EP_BULK_OUT_NAME[] = "ep-b";
+#define EP_BULK_OUT_NUM		2
+#define FS_BULK_OUT_MAXPACKET	64
+static const char EP_INTR_IN_NAME[] = "ep-e";
+#define EP_INTR_IN_NUM		5
+#define HIGHSPEED
+#endif
+
+
+/*
+ * PXA-2xx UDC:  widely used in second gen Linux-capable PDAs.
+ *
+ * This has fifteen fixed-function full speed endpoints, and it
+ * can support all USB transfer types.
+ *
+ * These supports three or four configurations, with fixed numbers.
+ * The hardware interprets SET_INTERFACE, net effect is that you
+ * can't use altsettings or reset the interfaces independently.
+ * So stick to a single interface.
+ */
+#ifdef	CONFIG_USB_GADGET_PXA2XX
+#define CHIP			"pxa2xx"
+#define DRIVER_VERSION_NUM	0x0203
+static const char EP_BULK_IN_NAME[] = "ep1in-bulk";
+#define EP_BULK_IN_NUM		1
+#define FS_BULK_IN_MAXPACKET	64
+static const char EP_BULK_OUT_NAME[] = "ep2out-bulk";
+#define EP_BULK_OUT_NUM		2
+#define FS_BULK_OUT_MAXPACKET	64
+static const char EP_INTR_IN_NAME[] = "ep6in-bulk";
+#define EP_INTR_IN_NUM		6
+#endif
+
+
+/*
+ * SuperH UDC:  UDC built-in to some Renesas SH processors.
+ *
+ * This has three fixed-function full speed bulk/interrupt endpoints.
+ *
+ * Only one configuration and interface is supported (SET_CONFIGURATION
+ * and SET_INTERFACE are handled completely by the hardware).
+ */
+#ifdef	CONFIG_USB_GADGET_SUPERH
+#define CHIP			"superh"
+#define DRIVER_VERSION_NUM	0x0205
+static const char EP_BULK_IN_NAME[] = "ep2in-bulk";
+#define EP_BULK_IN_NUM		2
+#define FS_BULK_IN_MAXPACKET	64
+static const char EP_BULK_OUT_NAME[] = "ep1out-bulk";
+#define EP_BULK_OUT_NUM		1
+#define FS_BULK_OUT_MAXPACKET	64
+static const char EP_INTR_IN_NAME[] = "ep3in-bulk";
+#define EP_INTR_IN_NUM		3
+#define NO_BULK_STALL
+#endif
+
+
+/*
+ * Toshiba TC86C001 ("Goku-S") UDC
+ *
+ * This has three semi-configurable full speed bulk/interrupt endpoints.
+ */
+#ifdef	CONFIG_USB_GADGET_GOKU
+#define CHIP			"goku"
+#define DRIVER_VERSION_NUM	0x0206
+static const char EP_BULK_OUT_NAME [] = "ep1-bulk";
+#define EP_BULK_OUT_NUM		1
+#define FS_BULK_IN_MAXPACKET	64
+static const char EP_BULK_IN_NAME [] = "ep2-bulk";
+#define EP_BULK_IN_NUM		2
+#define FS_BULK_OUT_MAXPACKET	64
+static const char EP_INTR_IN_NAME [] = "ep3-bulk";
+#define EP_INTR_IN_NUM		3
+#endif
+
+
+/*-------------------------------------------------------------------------*/
+
+#ifndef CHIP
+#	error Configure some USB peripheral controller driver!
+#endif
+
+/* Power usage is config specific.
+ * Hardware that supports remote wakeup defaults to disabling it.
+ */
+#ifndef	SELFPOWER
+/* default: say we're self-powered */
+#define SELFPOWER USB_CONFIG_ATT_SELFPOWER
+/* else:
+ * - SELFPOWER value must be zero
+ * - MAX_USB_POWER may be nonzero.
+ */
+#endif
+
+#ifndef	MAX_USB_POWER
+/* Any hub supports this steady state bus power consumption */
+#define MAX_USB_POWER	100	/* mA */
+#endif
+
+/* We don't support remote wake-up */
+
+#ifdef NO_BULK_STALL
+#define CAN_STALL	0
+#else
+#define CAN_STALL	1
+#endif
+
+
+/*-------------------------------------------------------------------------*/
+
+#define xprintk(f,level,fmt,args...) \
+	dev_printk(level , &(f)->gadget->dev , fmt , ## args)
+#define yprintk(l,level,fmt,args...) \
+	dev_printk(level , &(l)->dev , fmt , ## args)
+
+#ifdef DEBUG
+#define DBG(fsg,fmt,args...) \
+	xprintk(fsg , KERN_DEBUG , fmt , ## args)
+#define LDBG(lun,fmt,args...) \
+	yprintk(lun , KERN_DEBUG , fmt , ## args)
+#define MDBG(fmt,args...) \
+	printk(KERN_DEBUG DRIVER_NAME ": " fmt, ## args)
+#else
+#define DBG(fsg,fmt,args...) \
+	do { } while (0)
+#define LDBG(lun,fmt,args...) \
+	do { } while (0)
+#define MDBG(fmt,args...) \
+	do { } while (0)
+#undef VERBOSE
+#undef DUMP_MSGS
+#endif /* DEBUG */
+
+#ifdef VERBOSE
+#define VDBG	DBG
+#define VLDBG	LDBG
+#else
+#define VDBG(fsg,fmt,args...) \
+	do { } while (0)
+#define VLDBG(lun,fmt,args...) \
+	do { } while (0)
+#endif /* VERBOSE */
+
+#define ERROR(fsg,fmt,args...) \
+	xprintk(fsg , KERN_ERR , fmt , ## args)
+#define LERROR(lun,fmt,args...) \
+	yprintk(lun , KERN_ERR , fmt , ## args)
+
+#define WARN(fsg,fmt,args...) \
+	xprintk(fsg , KERN_WARNING , fmt , ## args)
+#define LWARN(lun,fmt,args...) \
+	yprintk(lun , KERN_WARNING , fmt , ## args)
+
+#define INFO(fsg,fmt,args...) \
+	xprintk(fsg , KERN_INFO , fmt , ## args)
+#define LINFO(lun,fmt,args...) \
+	yprintk(lun , KERN_INFO , fmt , ## args)
+
+#define MINFO(fmt,args...) \
+	printk(KERN_INFO DRIVER_NAME ": " fmt, ## args)
+
+
+/*-------------------------------------------------------------------------*/
+
+/* Encapsulate the module parameter settings */
+
+#define MAX_LUNS	8
+
+	/* Arggh!  There should be a module_param_array_named macro! */
+static char		*file[MAX_LUNS] = {NULL, };
+static int		ro[MAX_LUNS] = {0, };
+
+static struct {
+	int		num_filenames;
+	int		num_ros;
+	unsigned int	nluns;
+
+	char		*transport_parm;
+	char		*protocol_parm;
+	int		removable;
+	unsigned short	vendor;
+	unsigned short	product;
+	unsigned short	release;
+	unsigned int	buflen;
+	int		can_stall;
+
+	int		transport_type;
+	char		*transport_name;
+	int		protocol_type;
+	char		*protocol_name;
+
+} mod_data = {					// Default values
+	.transport_parm		= "BBB",
+	.protocol_parm		= "SCSI",
+	.removable		= 0,
+	.vendor			= DRIVER_VENDOR_ID,
+	.product		= DRIVER_PRODUCT_ID,
+	.release		= DRIVER_VERSION_NUM,
+	.buflen			= 16384,
+	.can_stall		= CAN_STALL,
+	};
+
+
+module_param_array(file, charp, mod_data.num_filenames, S_IRUGO);
+MODULE_PARM_DESC(file, "names of backing files or devices");
+
+module_param_array(ro, bool, mod_data.num_ros, S_IRUGO);
+MODULE_PARM_DESC(ro, "true to force read-only");
+
+
+/* In the non-TEST version, only the file and ro module parameters
+ * are available. */
+#ifdef CONFIG_USB_FILE_STORAGE_TEST
+
+module_param_named(luns, mod_data.nluns, uint, S_IRUGO);
+MODULE_PARM_DESC(luns, "number of LUNs");
+
+module_param_named(transport, mod_data.transport_parm, charp, S_IRUGO);
+MODULE_PARM_DESC(transport, "type of transport (BBB, CBI, or CB)");
+
+module_param_named(protocol, mod_data.protocol_parm, charp, S_IRUGO);
+MODULE_PARM_DESC(protocol, "type of protocol (RBC, 8020, QIC, UFI, "
+		"8070, or SCSI)");
+
+module_param_named(removable, mod_data.removable, bool, S_IRUGO);
+MODULE_PARM_DESC(removable, "true to simulate removable media");
+
+module_param_named(vendor, mod_data.vendor, ushort, S_IRUGO);
+MODULE_PARM_DESC(vendor, "USB Vendor ID");
+
+module_param_named(product, mod_data.product, ushort, S_IRUGO);
+MODULE_PARM_DESC(product, "USB Product ID");
+
+module_param_named(release, mod_data.release, ushort, S_IRUGO);
+MODULE_PARM_DESC(release, "USB release number");
+
+module_param_named(buflen, mod_data.buflen, uint, S_IRUGO);
+MODULE_PARM_DESC(buflen, "I/O buffer size");
+
+module_param_named(stall, mod_data.can_stall, bool, S_IRUGO);
+MODULE_PARM_DESC(stall, "false to prevent bulk stalls");
+
+#endif /* CONFIG_USB_FILE_STORAGE_TEST */
+
+
+/*-------------------------------------------------------------------------*/
+
+/* USB protocol value = the transport method */
+#define USB_PR_CBI	0x00		// Control/Bulk/Interrupt
+#define USB_PR_CB	0x01		// Control/Bulk w/o interrupt
+#define USB_PR_BULK	0x50		// Bulk-only
+
+/* USB subclass value = the protocol encapsulation */
+#define USB_SC_RBC	0x01		// Reduced Block Commands (flash)
+#define USB_SC_8020	0x02		// SFF-8020i, MMC-2, ATAPI (CD-ROM)
+#define USB_SC_QIC	0x03		// QIC-157 (tape)
+#define USB_SC_UFI	0x04		// UFI (floppy)
+#define USB_SC_8070	0x05		// SFF-8070i (removable)
+#define USB_SC_SCSI	0x06		// Transparent SCSI
+
+/* Bulk-only data structures */
+
+/* Command Block Wrapper */
+struct bulk_cb_wrap {
+	u32	Signature;		// Contains 'USBC'
+	u32	Tag;			// Unique per command id
+	u32	DataTransferLength;	// Size of the data
+	u8	Flags;			// Direction in bit 7
+	u8	Lun;			// LUN (normally 0)
+	u8	Length;			// Of the CDB, <= MAX_COMMAND_SIZE
+	u8	CDB[16];		// Command Data Block
+};
+
+#define USB_BULK_CB_WRAP_LEN	31
+#define USB_BULK_CB_SIG		0x43425355	// Spells out USBC
+#define USB_BULK_IN_FLAG	0x80
+
+/* Command Status Wrapper */
+struct bulk_cs_wrap {
+	u32	Signature;		// Should = 'USBS'
+	u32	Tag;			// Same as original command
+	u32	Residue;		// Amount not transferred
+	u8	Status;			// See below
+};
+
+#define USB_BULK_CS_WRAP_LEN	13
+#define USB_BULK_CS_SIG		0x53425355	// Spells out 'USBS'
+#define USB_STATUS_PASS		0
+#define USB_STATUS_FAIL		1
+#define USB_STATUS_PHASE_ERROR	2
+
+/* Bulk-only class specific requests */
+#define USB_BULK_RESET_REQUEST		0xff
+#define USB_BULK_GET_MAX_LUN_REQUEST	0xfe
+
+
+/* CBI Interrupt data structure */
+struct interrupt_data {
+	u8	bType;
+	u8	bValue;
+};
+
+#define CBI_INTERRUPT_DATA_LEN		2
+
+/* CBI Accept Device-Specific Command request */
+#define USB_CBI_ADSC_REQUEST		0x00
+
+
+#define MAX_COMMAND_SIZE	16	// Length of a SCSI Command Data Block
+
+/* SCSI commands that we recognize */
+#define SC_FORMAT_UNIT			0x04
+#define SC_INQUIRY			0x12
+#define SC_MODE_SELECT_6		0x15
+#define SC_MODE_SELECT_10		0x55
+#define SC_MODE_SENSE_6			0x1a
+#define SC_MODE_SENSE_10		0x5a
+#define SC_PREVENT_ALLOW_MEDIUM_REMOVAL	0x1e
+#define SC_READ_6			0x08
+#define SC_READ_10			0x28
+#define SC_READ_12			0xa8
+#define SC_READ_CAPACITY		0x25
+#define SC_READ_FORMAT_CAPACITIES	0x23
+#define SC_RELEASE			0x17
+#define SC_REQUEST_SENSE		0x03
+#define SC_RESERVE			0x16
+#define SC_SEND_DIAGNOSTIC		0x1d
+#define SC_START_STOP_UNIT		0x1b
+#define SC_SYNCHRONIZE_CACHE		0x35
+#define SC_TEST_UNIT_READY		0x00
+#define SC_VERIFY			0x2f
+#define SC_WRITE_6			0x0a
+#define SC_WRITE_10			0x2a
+#define SC_WRITE_12			0xaa
+
+/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */
+#define SS_NO_SENSE				0
+#define SS_COMMUNICATION_FAILURE		0x040800
+#define SS_INVALID_COMMAND			0x052000
+#define SS_INVALID_FIELD_IN_CDB			0x052400
+#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE	0x052100
+#define SS_LOGICAL_UNIT_NOT_SUPPORTED		0x052500
+#define SS_MEDIUM_NOT_PRESENT			0x023a00
+#define SS_MEDIUM_REMOVAL_PREVENTED		0x055302
+#define SS_NOT_READY_TO_READY_TRANSITION	0x062800
+#define SS_RESET_OCCURRED			0x062900
+#define SS_SAVING_PARAMETERS_NOT_SUPPORTED	0x053900
+#define SS_UNRECOVERED_READ_ERROR		0x031100
+#define SS_WRITE_ERROR				0x030c02
+#define SS_WRITE_PROTECTED			0x072700
+
+#define SK(x)		((u8) ((x) >> 16))	// Sense Key byte, etc.
+#define ASC(x)		((u8) ((x) >> 8))
+#define ASCQ(x)		((u8) (x))
+
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * These definitions will permit the compiler to avoid generating code for
+ * parts of the driver that aren't used in the non-TEST version.  Even gcc
+ * can recognize when a test of a constant expression yields a dead code
+ * path.
+ *
+ * Also, in the non-TEST version, open_backing_file() is only used during
+ * initialization and the sysfs attribute store_xxx routines aren't used
+ * at all.  We will define NORMALLY_INIT to mark them as __init so they
+ * don't occupy kernel code space unnecessarily.
+ */
+
+#ifdef CONFIG_USB_FILE_STORAGE_TEST
+
+#define transport_is_bbb()	(mod_data.transport_type == USB_PR_BULK)
+#define transport_is_cbi()	(mod_data.transport_type == USB_PR_CBI)
+#define protocol_is_scsi()	(mod_data.protocol_type == USB_SC_SCSI)
+#define backing_file_is_open(curlun)	((curlun)->filp != NULL)
+#define NORMALLY_INIT
+
+#else
+
+#define transport_is_bbb()	1
+#define transport_is_cbi()	0
+#define protocol_is_scsi()	1
+#define backing_file_is_open(curlun)	1
+#define NORMALLY_INIT		__init
+
+#endif /* CONFIG_USB_FILE_STORAGE_TEST */
+
+
+struct lun {
+	struct file	*filp;
+	loff_t		file_length;
+	loff_t		num_sectors;
+
+	unsigned int	ro : 1;
+	unsigned int	prevent_medium_removal : 1;
+	unsigned int	registered : 1;
+
+	u32		sense_data;
+	u32		sense_data_info;
+	u32		unit_attention_data;
+
+	struct device	dev;
+};
+
+static inline struct lun *dev_to_lun(struct device *dev)
+{
+	return container_of(dev, struct lun, dev);
+}
+
+
+/* Big enough to hold our biggest descriptor */
+#define EP0_BUFSIZE	256
+#define DELAYED_STATUS	(EP0_BUFSIZE + 999)	// An impossibly large value
+
+/* Number of buffers we will use.  2 is enough for double-buffering */
+#define NUM_BUFFERS	2
+
+enum fsg_buffer_state {
+	BUF_STATE_EMPTY = 0,
+	BUF_STATE_FULL,
+	BUF_STATE_BUSY
+};
+
+struct fsg_buffhd {
+	void				*buf;
+	dma_addr_t			dma;
+	volatile enum fsg_buffer_state	state;
+	struct fsg_buffhd		*next;
+
+	/* The NetChip 2280 is faster, and handles some protocol faults
+	 * better, if we don't submit any short bulk-out read requests.
+	 * So we will record the intended request length here. */
+	unsigned int			bulk_out_intended_length;
+
+	struct usb_request		*inreq;
+	volatile int			inreq_busy;
+	struct usb_request		*outreq;
+	volatile int			outreq_busy;
+};
+
+enum fsg_state {
+	FSG_STATE_COMMAND_PHASE = -10,		// This one isn't used anywhere
+	FSG_STATE_DATA_PHASE,
+	FSG_STATE_STATUS_PHASE,
+
+	FSG_STATE_IDLE = 0,
+	FSG_STATE_ABORT_BULK_OUT,
+	FSG_STATE_RESET,
+	FSG_STATE_INTERFACE_CHANGE,
+	FSG_STATE_CONFIG_CHANGE,
+	FSG_STATE_DISCONNECT,
+	FSG_STATE_EXIT,
+	FSG_STATE_TERMINATED
+};
+
+enum data_direction {
+	DATA_DIR_UNKNOWN = 0,
+	DATA_DIR_FROM_HOST,
+	DATA_DIR_TO_HOST,
+	DATA_DIR_NONE
+};
+
+struct fsg_dev {
+	/* lock protects: state, all the req_busy's, and cbbuf_cmnd */
+	spinlock_t		lock;
+	struct usb_gadget	*gadget;
+
+	/* filesem protects: backing files in use */
+	struct rw_semaphore	filesem;
+
+	struct usb_ep		*ep0;		// Handy copy of gadget->ep0
+	struct usb_request	*ep0req;	// For control responses
+	volatile unsigned int	ep0_req_tag;
+	const char		*ep0req_name;
+
+	struct usb_request	*intreq;	// For interrupt responses
+	volatile int		intreq_busy;
+	struct fsg_buffhd	*intr_buffhd;
+
+ 	unsigned int		bulk_out_maxpacket;
+	enum fsg_state		state;		// For exception handling
+	unsigned int		exception_req_tag;
+
+	u8			config, new_config;
+
+	unsigned int		running : 1;
+	unsigned int		bulk_in_enabled : 1;
+	unsigned int		bulk_out_enabled : 1;
+	unsigned int		intr_in_enabled : 1;
+	unsigned int		phase_error : 1;
+	unsigned int		short_packet_received : 1;
+	unsigned int		bad_lun_okay : 1;
+
+	unsigned long		atomic_bitflags;
+#define REGISTERED		0
+#define CLEAR_BULK_HALTS	1
+
+	struct usb_ep		*bulk_in;
+	struct usb_ep		*bulk_out;
+	struct usb_ep		*intr_in;
+
+	struct fsg_buffhd	*next_buffhd_to_fill;
+	struct fsg_buffhd	*next_buffhd_to_drain;
+	struct fsg_buffhd	buffhds[NUM_BUFFERS];
+
+	wait_queue_head_t	thread_wqh;
+	int			thread_wakeup_needed;
+	struct completion	thread_notifier;
+	int			thread_pid;
+	struct task_struct	*thread_task;
+	sigset_t		thread_signal_mask;
+
+	int			cmnd_size;
+	u8			cmnd[MAX_COMMAND_SIZE];
+	enum data_direction	data_dir;
+	u32			data_size;
+	u32			data_size_from_cmnd;
+	u32			tag;
+	unsigned int		lun;
+	u32			residue;
+	u32			usb_amount_left;
+
+	/* The CB protocol offers no way for a host to know when a command
+	 * has completed.  As a result the next command may arrive early,
+	 * and we will still have to handle it.  For that reason we need
+	 * a buffer to store new commands when using CB (or CBI, which
+	 * does not oblige a host to wait for command completion either). */
+	int			cbbuf_cmnd_size;
+	u8			cbbuf_cmnd[MAX_COMMAND_SIZE];
+
+	unsigned int		nluns;
+	struct lun		*luns;
+	struct lun		*curlun;
+};
+
+typedef void (*fsg_routine_t)(struct fsg_dev *);
+
+static int inline exception_in_progress(struct fsg_dev *fsg)
+{
+	return (fsg->state > FSG_STATE_IDLE);
+}
+
+/* Make bulk-out requests be divisible by the maxpacket size */
+static void inline set_bulk_out_req_length(struct fsg_dev *fsg,
+		struct fsg_buffhd *bh, unsigned int length)
+{
+	unsigned int	rem;
+
+	bh->bulk_out_intended_length = length;
+	rem = length % fsg->bulk_out_maxpacket;
+	if (rem > 0)
+		length += fsg->bulk_out_maxpacket - rem;
+	bh->outreq->length = length;
+}
+
+static struct fsg_dev			*the_fsg;
+static struct usb_gadget_driver		fsg_driver;
+
+static void	close_backing_file(struct lun *curlun);
+static void	close_all_backing_files(struct fsg_dev *fsg);
+
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef DUMP_MSGS
+
+static void dump_msg(struct fsg_dev *fsg, const char *label,
+		const u8 *buf, unsigned int length)
+{
+	unsigned int	start, num, i;
+	char		line[52], *p;
+
+	if (length >= 512)
+		return;
+	DBG(fsg, "%s, length %u:\n", label, length);
+
+	start = 0;
+	while (length > 0) {
+		num = min(length, 16u);
+		p = line;
+		for (i = 0; i < num; ++i) {
+			if (i == 8)
+				*p++ = ' ';
+			sprintf(p, " %02x", buf[i]);
+			p += 3;
+		}
+		*p = 0;
+		printk(KERN_DEBUG "%6x: %s\n", start, line);
+		buf += num;
+		start += num;
+		length -= num;
+	}
+}
+
+static void inline dump_cdb(struct fsg_dev *fsg)
+{}
+
+#else
+
+static void inline dump_msg(struct fsg_dev *fsg, const char *label,
+		const u8 *buf, unsigned int length)
+{}
+
+static void inline dump_cdb(struct fsg_dev *fsg)
+{
+	int	i;
+	char	cmdbuf[3*MAX_COMMAND_SIZE + 1];
+
+	for (i = 0; i < fsg->cmnd_size; ++i)
+		sprintf(cmdbuf + i*3, " %02x", fsg->cmnd[i]);
+	VDBG(fsg, "SCSI CDB: %s\n", cmdbuf);
+}
+
+#endif /* DUMP_MSGS */
+
+
+static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep)
+{
+	const char	*name;
+
+	if (ep == fsg->bulk_in)
+		name = "bulk-in";
+	else if (ep == fsg->bulk_out)
+		name = "bulk-out";
+	else
+		name = ep->name;
+	DBG(fsg, "%s set halt\n", name);
+	return usb_ep_set_halt(ep);
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/* Routines for unaligned data access */
+
+static u16 inline get_be16(u8 *buf)
+{
+	return ((u16) buf[0] << 8) | ((u16) buf[1]);
+}
+
+static u32 inline get_be32(u8 *buf)
+{
+	return ((u32) buf[0] << 24) | ((u32) buf[1] << 16) |
+			((u32) buf[2] << 8) | ((u32) buf[3]);
+}
+
+static void inline put_be16(u8 *buf, u16 val)
+{
+	buf[0] = val >> 8;
+	buf[1] = val;
+}
+
+static void inline put_be32(u8 *buf, u32 val)
+{
+	buf[0] = val >> 24;
+	buf[1] = val >> 16;
+	buf[2] = val >> 8;
+	buf[3] = val;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * DESCRIPTORS ... most are static, but strings and (full) configuration
+ * descriptors are built on demand.  Also the (static) config and interface
+ * descriptors are adjusted during fsg_bind().
+ */
+#define STRING_MANUFACTURER	1
+#define STRING_PRODUCT		2
+#define STRING_SERIAL		3
+
+/* There is only one configuration. */
+#define	CONFIG_VALUE		1
+
+static struct usb_device_descriptor
+device_desc = {
+	.bLength =		sizeof device_desc,
+	.bDescriptorType =	USB_DT_DEVICE,
+
+	.bcdUSB =		__constant_cpu_to_le16(0x0200),
+	.bDeviceClass =		USB_CLASS_PER_INTERFACE,
+
+	/* The next three values can be overridden by module parameters */
+	.idVendor =		__constant_cpu_to_le16(DRIVER_VENDOR_ID),
+	.idProduct =		__constant_cpu_to_le16(DRIVER_PRODUCT_ID),
+	.bcdDevice =		__constant_cpu_to_le16(DRIVER_VERSION_NUM),
+
+	.iManufacturer =	STRING_MANUFACTURER,
+	.iProduct =		STRING_PRODUCT,
+	.iSerialNumber =	STRING_SERIAL,
+	.bNumConfigurations =	1,
+};
+
+static struct usb_config_descriptor
+config_desc = {
+	.bLength =		sizeof config_desc,
+	.bDescriptorType =	USB_DT_CONFIG,
+
+	/* wTotalLength adjusted during bind() */
+	.bNumInterfaces =	1,
+	.bConfigurationValue =	CONFIG_VALUE,
+	.bmAttributes =		USB_CONFIG_ATT_ONE | SELFPOWER,
+	.bMaxPower =		(MAX_USB_POWER + 1) / 2,
+};
+
+/* There is only one interface. */
+
+static struct usb_interface_descriptor
+intf_desc = {
+	.bLength =		sizeof intf_desc,
+	.bDescriptorType =	USB_DT_INTERFACE,
+
+	.bNumEndpoints =	2,		// Adjusted during bind()
+	.bInterfaceClass =	USB_CLASS_MASS_STORAGE,
+	.bInterfaceSubClass =	USB_SC_SCSI,	// Adjusted during bind()
+	.bInterfaceProtocol =	USB_PR_BULK,	// Adjusted during bind()
+};
+
+/* Three full-speed endpoint descriptors: bulk-in, bulk-out,
+ * and interrupt-in. */
+
+static const struct usb_endpoint_descriptor
+fs_bulk_in_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	EP_BULK_IN_NUM | USB_DIR_IN,
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize =	__constant_cpu_to_le16(FS_BULK_IN_MAXPACKET),
+};
+
+static const struct usb_endpoint_descriptor
+fs_bulk_out_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	EP_BULK_OUT_NUM,
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize =	__constant_cpu_to_le16(FS_BULK_OUT_MAXPACKET),
+};
+
+static const struct usb_endpoint_descriptor
+fs_intr_in_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	EP_INTR_IN_NUM | USB_DIR_IN,
+	.bmAttributes =		USB_ENDPOINT_XFER_INT,
+	.wMaxPacketSize =	__constant_cpu_to_le16(2),
+	.bInterval =		32,	// frames -> 32 ms
+};
+
+#ifdef	HIGHSPEED
+
+/*
+ * USB 2.0 devices need to expose both high speed and full speed
+ * descriptors, unless they only run at full speed.
+ *
+ * That means alternate endpoint descriptors (bigger packets)
+ * and a "device qualifier" ... plus more construction options
+ * for the config descriptor.
+ */
+static const struct usb_endpoint_descriptor
+hs_bulk_in_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	EP_BULK_IN_NUM | USB_DIR_IN,
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize =	__constant_cpu_to_le16(512),
+};
+
+static const struct usb_endpoint_descriptor
+hs_bulk_out_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	EP_BULK_OUT_NUM,
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize =	__constant_cpu_to_le16(512),
+	.bInterval =		1,	// NAK every 1 uframe
+};
+
+static const struct usb_endpoint_descriptor
+hs_intr_in_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	EP_INTR_IN_NUM | USB_DIR_IN,
+	.bmAttributes =		USB_ENDPOINT_XFER_INT,
+	.wMaxPacketSize =	__constant_cpu_to_le16(2),
+	.bInterval =		9,	// 2**(9-1) = 256 uframes -> 32 ms
+};
+
+static struct usb_qualifier_descriptor
+dev_qualifier = {
+	.bLength =		sizeof dev_qualifier,
+	.bDescriptorType =	USB_DT_DEVICE_QUALIFIER,
+
+	.bcdUSB =		__constant_cpu_to_le16(0x0200),
+	.bDeviceClass =		USB_CLASS_PER_INTERFACE,
+
+	.bNumConfigurations =	1,
+};
+
+/* Maxpacket and other transfer characteristics vary by speed. */
+#define ep_desc(g,fs,hs)	(((g)->speed==USB_SPEED_HIGH) ? (hs) : (fs))
+
+#else
+
+/* If there's no high speed support, maxpacket doesn't change. */
+#define ep_desc(g,fs,hs)	fs
+
+#endif	/* !HIGHSPEED */
+
+
+/* The CBI specification limits the serial string to 12 uppercase hexadecimal
+ * characters. */
+static char				serial[13];
+
+/* Static strings, in ISO 8859/1 */
+static struct usb_string		strings[] = {
+	{ STRING_MANUFACTURER, UTS_SYSNAME " " UTS_RELEASE " with " CHIP, },
+	{ STRING_PRODUCT, longname, },
+	{ STRING_SERIAL, serial, },
+	{ }			// end of list
+};
+
+static struct usb_gadget_strings	stringtab = {
+	.language	= 0x0409,		// en-us
+	.strings	= strings,
+};
+
+
+/*
+ * Config descriptors are handcrafted.  They must agree with the code
+ * that sets configurations and with code managing interfaces and their
+ * altsettings.  They must also handle different speeds and other-speed
+ * requests.
+ */
+static int populate_config_buf(enum usb_device_speed speed,
+		u8 *buf0, u8 type, unsigned index)
+{
+	u8	*buf = buf0;
+#ifdef HIGHSPEED
+	int	hs;
+#endif
+
+	if (index > 0)
+		return -EINVAL;
+	if (config_desc.wTotalLength  > EP0_BUFSIZE)
+		return -EDOM;
+
+	/* Config (or other speed config) */
+	memcpy(buf, &config_desc, USB_DT_CONFIG_SIZE);
+	buf[1] = type;
+	buf += USB_DT_CONFIG_SIZE;
+
+	/* Interface */
+	memcpy(buf, &intf_desc, USB_DT_INTERFACE_SIZE);
+	buf += USB_DT_INTERFACE_SIZE;
+
+	/* The endpoints in the interface (at that speed) */
+#ifdef HIGHSPEED
+	hs = (speed == USB_SPEED_HIGH);
+	if (type == USB_DT_OTHER_SPEED_CONFIG)
+		hs = !hs;
+	if (hs) {
+		memcpy(buf, &hs_bulk_in_desc, USB_DT_ENDPOINT_SIZE);
+		buf += USB_DT_ENDPOINT_SIZE;
+		memcpy(buf, &hs_bulk_out_desc, USB_DT_ENDPOINT_SIZE);
+		buf += USB_DT_ENDPOINT_SIZE;
+		if (transport_is_cbi()) {
+			memcpy(buf, &hs_intr_in_desc, USB_DT_ENDPOINT_SIZE);
+			buf += USB_DT_ENDPOINT_SIZE;
+		}
+	} else
+#endif
+	{
+		memcpy(buf, &fs_bulk_in_desc, USB_DT_ENDPOINT_SIZE);
+		buf += USB_DT_ENDPOINT_SIZE;
+		memcpy(buf, &fs_bulk_out_desc, USB_DT_ENDPOINT_SIZE);
+		buf += USB_DT_ENDPOINT_SIZE;
+		if (transport_is_cbi()) {
+			memcpy(buf, &fs_intr_in_desc, USB_DT_ENDPOINT_SIZE);
+			buf += USB_DT_ENDPOINT_SIZE;
+		}
+	}
+
+	return buf - buf0;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/* These routines may be called in process context or in_irq */
+
+static void wakeup_thread(struct fsg_dev *fsg)
+{
+	/* Tell the main thread that something has happened */
+	fsg->thread_wakeup_needed = 1;
+	wake_up_all(&fsg->thread_wqh);
+}
+
+
+static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state)
+{
+	unsigned long		flags;
+	struct task_struct	*thread_task;
+
+	/* Do nothing if a higher-priority exception is already in progress.
+	 * If a lower-or-equal priority exception is in progress, preempt it
+	 * and notify the main thread by sending it a signal. */
+	spin_lock_irqsave(&fsg->lock, flags);
+	if (fsg->state <= new_state) {
+		fsg->exception_req_tag = fsg->ep0_req_tag;
+		fsg->state = new_state;
+		thread_task = fsg->thread_task;
+		if (thread_task)
+			send_sig_info(SIGUSR1, SEND_SIG_FORCED, thread_task);
+	}
+	spin_unlock_irqrestore(&fsg->lock, flags);
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/* The disconnect callback and ep0 routines.  These always run in_irq,
+ * except that ep0_queue() is called in the main thread to acknowledge
+ * completion of various requests: set config, set interface, and
+ * Bulk-only device reset. */
+
+static void fsg_disconnect(struct usb_gadget *gadget)
+{
+	struct fsg_dev		*fsg = get_gadget_data(gadget);
+
+	DBG(fsg, "disconnect or port reset\n");
+	raise_exception(fsg, FSG_STATE_DISCONNECT);
+}
+
+
+static int ep0_queue(struct fsg_dev *fsg)
+{
+	int	rc;
+
+	rc = usb_ep_queue(fsg->ep0, fsg->ep0req, GFP_ATOMIC);
+	if (rc != 0 && rc != -ESHUTDOWN) {
+
+		/* We can't do much more than wait for a reset */
+		WARN(fsg, "error in submission: %s --> %d\n",
+				fsg->ep0->name, rc);
+	}
+	return rc;
+}
+
+static void ep0_complete(struct usb_ep *ep, struct usb_request *req)
+{
+	struct fsg_dev		*fsg = (struct fsg_dev *) ep->driver_data;
+
+	if (req->actual > 0)
+		dump_msg(fsg, fsg->ep0req_name, req->buf, req->actual);
+	if (req->status || req->actual != req->length)
+		DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__,
+				req->status, req->actual, req->length);
+	if (req->status == -ECONNRESET)		// Request was cancelled
+		usb_ep_fifo_flush(ep);
+
+	if (req->status == 0 && req->context)
+		((fsg_routine_t) (req->context))(fsg);
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/* Bulk and interrupt endpoint completion handlers.
+ * These always run in_irq. */
+
+static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req)
+{
+	struct fsg_dev		*fsg = (struct fsg_dev *) ep->driver_data;
+	struct fsg_buffhd	*bh = (struct fsg_buffhd *) req->context;
+
+	if (req->status || req->actual != req->length)
+		DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__,
+				req->status, req->actual, req->length);
+	if (req->status == -ECONNRESET)		// Request was cancelled
+		usb_ep_fifo_flush(ep);
+
+	/* Hold the lock while we update the request and buffer states */
+	spin_lock(&fsg->lock);
+	bh->inreq_busy = 0;
+	bh->state = BUF_STATE_EMPTY;
+	spin_unlock(&fsg->lock);
+	wakeup_thread(fsg);
+}
+
+static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
+{
+	struct fsg_dev		*fsg = (struct fsg_dev *) ep->driver_data;
+	struct fsg_buffhd	*bh = (struct fsg_buffhd *) req->context;
+
+	dump_msg(fsg, "bulk-out", req->buf, req->actual);
+	if (req->status || req->actual != bh->bulk_out_intended_length)
+		DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__,
+				req->status, req->actual,
+				bh->bulk_out_intended_length);
+	if (req->status == -ECONNRESET)		// Request was cancelled
+		usb_ep_fifo_flush(ep);
+
+	/* Hold the lock while we update the request and buffer states */
+	spin_lock(&fsg->lock);
+	bh->outreq_busy = 0;
+	bh->state = BUF_STATE_FULL;
+	spin_unlock(&fsg->lock);
+	wakeup_thread(fsg);
+}
+
+static void intr_in_complete(struct usb_ep *ep, struct usb_request *req)
+{
+#ifdef CONFIG_USB_FILE_STORAGE_TEST
+	struct fsg_dev		*fsg = (struct fsg_dev *) ep->driver_data;
+	struct fsg_buffhd	*bh = (struct fsg_buffhd *) req->context;
+
+	if (req->status || req->actual != req->length)
+		DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__,
+				req->status, req->actual, req->length);
+	if (req->status == -ECONNRESET)		// Request was cancelled
+		usb_ep_fifo_flush(ep);
+
+	/* Hold the lock while we update the request and buffer states */
+	spin_lock(&fsg->lock);
+	fsg->intreq_busy = 0;
+	bh->state = BUF_STATE_EMPTY;
+	spin_unlock(&fsg->lock);
+	wakeup_thread(fsg);
+#endif /* CONFIG_USB_FILE_STORAGE_TEST */
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/* Ep0 class-specific handlers.  These always run in_irq. */
+
+static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh)
+{
+#ifdef CONFIG_USB_FILE_STORAGE_TEST
+	struct usb_request	*req = fsg->ep0req;
+	static u8		cbi_reset_cmnd[6] = {
+			SC_SEND_DIAGNOSTIC, 4, 0xff, 0xff, 0xff, 0xff};
+
+	/* Error in command transfer? */
+	if (req->status || req->length != req->actual ||
+			req->actual < 6 || req->actual > MAX_COMMAND_SIZE) {
+
+		/* Not all controllers allow a protocol stall after
+		 * receiving control-out data, but we'll try anyway. */
+		fsg_set_halt(fsg, fsg->ep0);
+		return;			// Wait for reset
+	}
+
+	/* Is it the special reset command? */
+	if (req->actual >= sizeof cbi_reset_cmnd &&
+			memcmp(req->buf, cbi_reset_cmnd,
+				sizeof cbi_reset_cmnd) == 0) {
+
+		/* Raise an exception to stop the current operation
+		 * and reinitialize our state. */
+		DBG(fsg, "cbi reset request\n");
+		raise_exception(fsg, FSG_STATE_RESET);
+		return;
+	}
+
+	VDBG(fsg, "CB[I] accept device-specific command\n");
+	spin_lock(&fsg->lock);
+
+	/* Save the command for later */
+	if (fsg->cbbuf_cmnd_size)
+		WARN(fsg, "CB[I] overwriting previous command\n");
+	fsg->cbbuf_cmnd_size = req->actual;
+	memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size);
+
+	spin_unlock(&fsg->lock);
+	wakeup_thread(fsg);
+#endif /* CONFIG_USB_FILE_STORAGE_TEST */
+}
+
+
+static int class_setup_req(struct fsg_dev *fsg,
+		const struct usb_ctrlrequest *ctrl)
+{
+	struct usb_request	*req = fsg->ep0req;
+	int			value = -EOPNOTSUPP;
+
+	if (!fsg->config)
+		return value;
+
+	/* Handle Bulk-only class-specific requests */
+	if (transport_is_bbb()) {
+		switch (ctrl->bRequest) {
+
+		case USB_BULK_RESET_REQUEST:
+			if (ctrl->bRequestType != (USB_DIR_OUT |
+					USB_TYPE_CLASS | USB_RECIP_INTERFACE))
+				break;
+			if (ctrl->wIndex != 0) {
+				value = -EDOM;
+				break;
+			}
+
+			/* Raise an exception to stop the current operation
+			 * and reinitialize our state. */
+			DBG(fsg, "bulk reset request\n");
+			raise_exception(fsg, FSG_STATE_RESET);
+			value = DELAYED_STATUS;
+			break;
+
+		case USB_BULK_GET_MAX_LUN_REQUEST:
+			if (ctrl->bRequestType != (USB_DIR_IN |
+					USB_TYPE_CLASS | USB_RECIP_INTERFACE))
+				break;
+			if (ctrl->wIndex != 0) {
+				value = -EDOM;
+				break;
+			}
+			VDBG(fsg, "get max LUN\n");
+			*(u8 *) req->buf = fsg->nluns - 1;
+			value = min(ctrl->wLength, (u16) 1);
+			break;
+		}
+	}
+
+	/* Handle CBI class-specific requests */
+	else {
+		switch (ctrl->bRequest) {
+
+		case USB_CBI_ADSC_REQUEST:
+			if (ctrl->bRequestType != (USB_DIR_OUT |
+					USB_TYPE_CLASS | USB_RECIP_INTERFACE))
+				break;
+			if (ctrl->wIndex != 0) {
+				value = -EDOM;
+				break;
+			}
+			if (ctrl->wLength > MAX_COMMAND_SIZE) {
+				value = -EOVERFLOW;
+				break;
+			}
+			value = ctrl->wLength;
+			fsg->ep0req->context = received_cbi_adsc;
+			break;
+		}
+	}
+
+	if (value == -EOPNOTSUPP)
+		VDBG(fsg,
+			"unknown class-specific control req "
+			"%02x.%02x v%04x i%04x l%u\n",
+			ctrl->bRequestType, ctrl->bRequest,
+			ctrl->wValue, ctrl->wIndex, ctrl->wLength);
+	return value;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/* Ep0 standard request handlers.  These always run in_irq. */
+
+static int standard_setup_req(struct fsg_dev *fsg,
+		const struct usb_ctrlrequest *ctrl)
+{
+	struct usb_request	*req = fsg->ep0req;
+	int			value = -EOPNOTSUPP;
+
+	/* Usually this just stores reply data in the pre-allocated ep0 buffer,
+	 * but config change events will also reconfigure hardware. */
+	switch (ctrl->bRequest) {
+
+	case USB_REQ_GET_DESCRIPTOR:
+		if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD |
+				USB_RECIP_DEVICE))
+			break;
+		switch (ctrl->wValue >> 8) {
+
+		case USB_DT_DEVICE:
+			VDBG(fsg, "get device descriptor\n");
+			value = min(ctrl->wLength, (u16) sizeof device_desc);
+			memcpy(req->buf, &device_desc, value);
+			break;
+#ifdef HIGHSPEED
+		case USB_DT_DEVICE_QUALIFIER:
+			VDBG(fsg, "get device qualifier\n");
+			value = min(ctrl->wLength, (u16) sizeof dev_qualifier);
+			memcpy(req->buf, &dev_qualifier, value);
+			break;
+
+		case USB_DT_OTHER_SPEED_CONFIG:
+			VDBG(fsg, "get other-speed config descriptor\n");
+			goto get_config;
+#endif /* HIGHSPEED */
+		case USB_DT_CONFIG:
+			VDBG(fsg, "get configuration descriptor\n");
+#ifdef HIGHSPEED
+		get_config:
+#endif /* HIGHSPEED */
+			value = populate_config_buf(fsg->gadget->speed,
+					req->buf,
+					ctrl->wValue >> 8,
+					ctrl->wValue & 0xff);
+			if (value >= 0)
+				value = min(ctrl->wLength, (u16) value);
+			break;
+
+		case USB_DT_STRING:
+			VDBG(fsg, "get string descriptor\n");
+
+			/* wIndex == language code */
+			value = usb_gadget_get_string(&stringtab,
+					ctrl->wValue & 0xff, req->buf);
+			if (value >= 0)
+				value = min(ctrl->wLength, (u16) value);
+			break;
+		}
+		break;
+
+	/* One config, two speeds */
+	case USB_REQ_SET_CONFIGURATION:
+		if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD |
+				USB_RECIP_DEVICE))
+			break;
+		VDBG(fsg, "set configuration\n");
+		if (ctrl->wValue == CONFIG_VALUE || ctrl->wValue == 0) {
+			fsg->new_config = ctrl->wValue;
+
+			/* Raise an exception to wipe out previous transaction
+			 * state (queued bufs, etc) and set the new config. */
+			raise_exception(fsg, FSG_STATE_CONFIG_CHANGE);
+			value = DELAYED_STATUS;
+		}
+		break;
+	case USB_REQ_GET_CONFIGURATION:
+		if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD |
+				USB_RECIP_DEVICE))
+			break;
+		VDBG(fsg, "get configuration\n");
+		*(u8 *) req->buf = fsg->config;
+		value = min(ctrl->wLength, (u16) 1);
+		break;
+
+	case USB_REQ_SET_INTERFACE:
+		if (ctrl->bRequestType != (USB_DIR_OUT| USB_TYPE_STANDARD |
+				USB_RECIP_INTERFACE))
+			break;
+		if (fsg->config && ctrl->wIndex == 0) {
+
+			/* Raise an exception to wipe out previous transaction
+			 * state (queued bufs, etc) and install the new
+			 * interface altsetting. */
+			raise_exception(fsg, FSG_STATE_INTERFACE_CHANGE);
+			value = DELAYED_STATUS;
+		}
+		break;
+	case USB_REQ_GET_INTERFACE:
+		if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD |
+				USB_RECIP_INTERFACE))
+			break;
+		if (!fsg->config)
+			break;
+		if (ctrl->wIndex != 0) {
+			value = -EDOM;
+			break;
+		}
+		VDBG(fsg, "get interface\n");
+		*(u8 *) req->buf = 0;
+		value = min(ctrl->wLength, (u16) 1);
+		break;
+
+	default:
+		VDBG(fsg,
+			"unknown control req %02x.%02x v%04x i%04x l%u\n",
+			ctrl->bRequestType, ctrl->bRequest,
+			ctrl->wValue, ctrl->wIndex, ctrl->wLength);
+	}
+
+	return value;
+}
+
+
+static int fsg_setup(struct usb_gadget *gadget,
+		const struct usb_ctrlrequest *ctrl)
+{
+	struct fsg_dev		*fsg = get_gadget_data(gadget);
+	int			rc;
+
+	++fsg->ep0_req_tag;		// Record arrival of a new request
+	fsg->ep0req->context = NULL;
+	fsg->ep0req->length = 0;
+	dump_msg(fsg, "ep0-setup", (u8 *) ctrl, sizeof(*ctrl));
+
+	if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS)
+		rc = class_setup_req(fsg, ctrl);
+	else
+		rc = standard_setup_req(fsg, ctrl);
+
+	/* Respond with data/status or defer until later? */
+	if (rc >= 0 && rc != DELAYED_STATUS) {
+		fsg->ep0req->length = rc;
+		fsg->ep0req_name = (ctrl->bRequestType & USB_DIR_IN ?
+				"ep0-in" : "ep0-out");
+		rc = ep0_queue(fsg);
+	}
+
+	/* Device either stalls (rc < 0) or reports success */
+	return rc;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/* All the following routines run in process context */
+
+
+/* Use this for bulk or interrupt transfers, not ep0 */
+static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep,
+		struct usb_request *req, volatile int *pbusy,
+		volatile enum fsg_buffer_state *state)
+{
+	int	rc;
+
+	if (ep == fsg->bulk_in)
+		dump_msg(fsg, "bulk-in", req->buf, req->length);
+	else if (ep == fsg->intr_in)
+		dump_msg(fsg, "intr-in", req->buf, req->length);
+	*pbusy = 1;
+	*state = BUF_STATE_BUSY;
+	rc = usb_ep_queue(ep, req, GFP_KERNEL);
+	if (rc != 0) {
+		*pbusy = 0;
+		*state = BUF_STATE_EMPTY;
+
+		/* We can't do much more than wait for a reset */
+
+		/* Note: currently the net2280 driver fails zero-length
+		 * submissions if DMA is enabled. */
+		if (rc != -ESHUTDOWN && !(rc == -EOPNOTSUPP &&
+						req->length == 0))
+			WARN(fsg, "error in submission: %s --> %d\n",
+					ep->name, rc);
+	}
+}
+
+
+static int sleep_thread(struct fsg_dev *fsg)
+{
+	int	rc;
+
+	/* Wait until a signal arrives or we are woken up */
+	rc = wait_event_interruptible(fsg->thread_wqh,
+			fsg->thread_wakeup_needed);
+	fsg->thread_wakeup_needed = 0;
+	return (rc ? -EINTR : 0);
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static int do_read(struct fsg_dev *fsg)
+{
+	struct lun		*curlun = fsg->curlun;
+	u32			lba;
+	struct fsg_buffhd	*bh;
+	int			rc;
+	u32			amount_left;
+	loff_t			file_offset, file_offset_tmp;
+	unsigned int		amount;
+	unsigned int		partial_page;
+	ssize_t			nread;
+
+	/* Get the starting Logical Block Address and check that it's
+	 * not too big */
+	if (fsg->cmnd[0] == SC_READ_6)
+		lba = (fsg->cmnd[1] << 16) | get_be16(&fsg->cmnd[2]);
+	else {
+		lba = get_be32(&fsg->cmnd[2]);
+
+		/* We allow DPO (Disable Page Out = don't save data in the
+		 * cache) and FUA (Force Unit Access = don't read from the
+		 * cache), but we don't implement them. */
+		if ((fsg->cmnd[1] & ~0x18) != 0) {
+			curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+			return -EINVAL;
+		}
+	}
+	if (lba >= curlun->num_sectors) {
+		curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+		return -EINVAL;
+	}
+	file_offset = ((loff_t) lba) << 9;
+
+	/* Carry out the file reads */
+	amount_left = fsg->data_size_from_cmnd;
+	if (unlikely(amount_left == 0))
+		return -EIO;		// No default reply
+
+	for (;;) {
+
+		/* Figure out how much we need to read:
+		 * Try to read the remaining amount.
+		 * But don't read more than the buffer size.
+		 * And don't try to read past the end of the file.
+		 * Finally, if we're not at a page boundary, don't read past
+		 *	the next page.
+		 * If this means reading 0 then we were asked to read past
+		 *	the end of file. */
+		amount = min((unsigned int) amount_left, mod_data.buflen);
+		amount = min((loff_t) amount,
+				curlun->file_length - file_offset);
+		partial_page = file_offset & (PAGE_CACHE_SIZE - 1);
+		if (partial_page > 0)
+			amount = min(amount, (unsigned int) PAGE_CACHE_SIZE -
+					partial_page);
+
+		/* Wait for the next buffer to become available */
+		bh = fsg->next_buffhd_to_fill;
+		while (bh->state != BUF_STATE_EMPTY) {
+			if ((rc = sleep_thread(fsg)) != 0)
+				return rc;
+		}
+
+		/* If we were asked to read past the end of file,
+		 * end with an empty buffer. */
+		if (amount == 0) {
+			curlun->sense_data =
+					SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+			curlun->sense_data_info = file_offset >> 9;
+			bh->inreq->length = 0;
+			bh->state = BUF_STATE_FULL;
+			break;
+		}
+
+		/* Perform the read */
+		file_offset_tmp = file_offset;
+		nread = vfs_read(curlun->filp,
+				(char __user *) bh->buf,
+				amount, &file_offset_tmp);
+		VLDBG(curlun, "file read %u @ %llu -> %d\n", amount,
+				(unsigned long long) file_offset,
+				(int) nread);
+		if (signal_pending(current))
+			return -EINTR;
+
+		if (nread < 0) {
+			LDBG(curlun, "error in file read: %d\n",
+					(int) nread);
+			nread = 0;
+		} else if (nread < amount) {
+			LDBG(curlun, "partial file read: %d/%u\n",
+					(int) nread, amount);
+			nread -= (nread & 511);	// Round down to a block
+		}
+		file_offset  += nread;
+		amount_left  -= nread;
+		fsg->residue -= nread;
+		bh->inreq->length = nread;
+		bh->state = BUF_STATE_FULL;
+
+		/* If an error occurred, report it and its position */
+		if (nread < amount) {
+			curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
+			curlun->sense_data_info = file_offset >> 9;
+			break;
+		}
+
+		if (amount_left == 0)
+			break;		// No more left to read
+
+		/* Send this buffer and go read some more */
+		bh->inreq->zero = 0;
+		start_transfer(fsg, fsg->bulk_in, bh->inreq,
+				&bh->inreq_busy, &bh->state);
+		fsg->next_buffhd_to_fill = bh->next;
+	}
+
+	return -EIO;		// No default reply
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static int do_write(struct fsg_dev *fsg)
+{
+	struct lun		*curlun = fsg->curlun;
+	u32			lba;
+	struct fsg_buffhd	*bh;
+	int			get_some_more;
+	u32			amount_left_to_req, amount_left_to_write;
+	loff_t			usb_offset, file_offset, file_offset_tmp;
+	unsigned int		amount;
+	unsigned int		partial_page;
+	ssize_t			nwritten;
+	int			rc;
+
+	if (curlun->ro) {
+		curlun->sense_data = SS_WRITE_PROTECTED;
+		return -EINVAL;
+	}
+	curlun->filp->f_flags &= ~O_SYNC;	// Default is not to wait
+
+	/* Get the starting Logical Block Address and check that it's
+	 * not too big */
+	if (fsg->cmnd[0] == SC_WRITE_6)
+		lba = (fsg->cmnd[1] << 16) | get_be16(&fsg->cmnd[2]);
+	else {
+		lba = get_be32(&fsg->cmnd[2]);
+
+		/* We allow DPO (Disable Page Out = don't save data in the
+		 * cache) and FUA (Force Unit Access = write directly to the
+		 * medium).  We don't implement DPO; we implement FUA by
+		 * performing synchronous output. */
+		if ((fsg->cmnd[1] & ~0x18) != 0) {
+			curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+			return -EINVAL;
+		}
+		if (fsg->cmnd[1] & 0x08)	// FUA
+			curlun->filp->f_flags |= O_SYNC;
+	}
+	if (lba >= curlun->num_sectors) {
+		curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+		return -EINVAL;
+	}
+
+	/* Carry out the file writes */
+	get_some_more = 1;
+	file_offset = usb_offset = ((loff_t) lba) << 9;
+	amount_left_to_req = amount_left_to_write = fsg->data_size_from_cmnd;
+
+	while (amount_left_to_write > 0) {
+
+		/* Queue a request for more data from the host */
+		bh = fsg->next_buffhd_to_fill;
+		if (bh->state == BUF_STATE_EMPTY && get_some_more) {
+
+			/* Figure out how much we want to get:
+			 * Try to get the remaining amount.
+			 * But don't get more than the buffer size.
+			 * And don't try to go past the end of the file.
+			 * If we're not at a page boundary,
+			 *	don't go past the next page.
+			 * If this means getting 0, then we were asked
+			 *	to write past the end of file.
+			 * Finally, round down to a block boundary. */
+			amount = min(amount_left_to_req, mod_data.buflen);
+			amount = min((loff_t) amount, curlun->file_length -
+					usb_offset);
+			partial_page = usb_offset & (PAGE_CACHE_SIZE - 1);
+			if (partial_page > 0)
+				amount = min(amount,
+	(unsigned int) PAGE_CACHE_SIZE - partial_page);
+
+			if (amount == 0) {
+				get_some_more = 0;
+				curlun->sense_data =
+					SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+				curlun->sense_data_info = usb_offset >> 9;
+				continue;
+			}
+			amount -= (amount & 511);
+			if (amount == 0) {
+
+				/* Why were we were asked to transfer a
+				 * partial block? */
+				get_some_more = 0;
+				continue;
+			}
+
+			/* Get the next buffer */
+			usb_offset += amount;
+			fsg->usb_amount_left -= amount;
+			amount_left_to_req -= amount;
+			if (amount_left_to_req == 0)
+				get_some_more = 0;
+
+			/* amount is always divisible by 512, hence by
+			 * the bulk-out maxpacket size */
+			bh->outreq->length = bh->bulk_out_intended_length =
+					amount;
+			start_transfer(fsg, fsg->bulk_out, bh->outreq,
+					&bh->outreq_busy, &bh->state);
+			fsg->next_buffhd_to_fill = bh->next;
+			continue;
+		}
+
+		/* Write the received data to the backing file */
+		bh = fsg->next_buffhd_to_drain;
+		if (bh->state == BUF_STATE_EMPTY && !get_some_more)
+			break;			// We stopped early
+		if (bh->state == BUF_STATE_FULL) {
+			fsg->next_buffhd_to_drain = bh->next;
+			bh->state = BUF_STATE_EMPTY;
+
+			/* Did something go wrong with the transfer? */
+			if (bh->outreq->status != 0) {
+				curlun->sense_data = SS_COMMUNICATION_FAILURE;
+				curlun->sense_data_info = file_offset >> 9;
+				break;
+			}
+
+			amount = bh->outreq->actual;
+			if (curlun->file_length - file_offset < amount) {
+				LERROR(curlun,
+	"write %u @ %llu beyond end %llu\n",
+	amount, (unsigned long long) file_offset,
+	(unsigned long long) curlun->file_length);
+				amount = curlun->file_length - file_offset;
+			}
+
+			/* Perform the write */
+			file_offset_tmp = file_offset;
+			nwritten = vfs_write(curlun->filp,
+					(char __user *) bh->buf,
+					amount, &file_offset_tmp);
+			VLDBG(curlun, "file write %u @ %llu -> %d\n", amount,
+					(unsigned long long) file_offset,
+					(int) nwritten);
+			if (signal_pending(current))
+				return -EINTR;		// Interrupted!
+
+			if (nwritten < 0) {
+				LDBG(curlun, "error in file write: %d\n",
+						(int) nwritten);
+				nwritten = 0;
+			} else if (nwritten < amount) {
+				LDBG(curlun, "partial file write: %d/%u\n",
+						(int) nwritten, amount);
+				nwritten -= (nwritten & 511);
+						// Round down to a block
+			}
+			file_offset += nwritten;
+			amount_left_to_write -= nwritten;
+			fsg->residue -= nwritten;
+
+			/* If an error occurred, report it and its position */
+			if (nwritten < amount) {
+				curlun->sense_data = SS_WRITE_ERROR;
+				curlun->sense_data_info = file_offset >> 9;
+				break;
+			}
+
+			/* Did the host decide to stop early? */
+			if (bh->outreq->actual != bh->outreq->length) {
+				fsg->short_packet_received = 1;
+				break;
+			}
+			continue;
+		}
+
+		/* Wait for something to happen */
+		if ((rc = sleep_thread(fsg)) != 0)
+			return rc;
+	}
+
+	return -EIO;		// No default reply
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/* Sync the file data, don't bother with the metadata.
+ * This code was copied from fs/buffer.c:sys_fdatasync(). */
+static int fsync_sub(struct lun *curlun)
+{
+	struct file	*filp = curlun->filp;
+	struct inode	*inode;
+	int		rc, err;
+
+	if (curlun->ro || !filp)
+		return 0;
+	if (!filp->f_op->fsync)
+		return -EINVAL;
+
+	inode = filp->f_dentry->d_inode;
+	down(&inode->i_sem);
+	current->flags |= PF_SYNCWRITE;
+	rc = filemap_fdatawrite(inode->i_mapping);
+	err = filp->f_op->fsync(filp, filp->f_dentry, 1);
+	if (!rc)
+		rc = err;
+	err = filemap_fdatawait(inode->i_mapping);
+	if (!rc)
+		rc = err;
+	current->flags &= ~PF_SYNCWRITE;
+	up(&inode->i_sem);
+	VLDBG(curlun, "fdatasync -> %d\n", rc);
+	return rc;
+}
+
+static void fsync_all(struct fsg_dev *fsg)
+{
+	int	i;
+
+	for (i = 0; i < fsg->nluns; ++i)
+		fsync_sub(&fsg->luns[i]);
+}
+
+static int do_synchronize_cache(struct fsg_dev *fsg)
+{
+	struct lun	*curlun = fsg->curlun;
+	int		rc;
+
+	/* We ignore the requested LBA and write out all file's
+	 * dirty data buffers. */
+	rc = fsync_sub(curlun);
+	if (rc)
+		curlun->sense_data = SS_WRITE_ERROR;
+	return 0;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static void invalidate_sub(struct lun *curlun)
+{
+	struct file	*filp = curlun->filp;
+	struct inode	*inode = filp->f_dentry->d_inode;
+	unsigned long	rc;
+
+	rc = invalidate_inode_pages(inode->i_mapping);
+	VLDBG(curlun, "invalidate_inode_pages -> %ld\n", rc);
+}
+
+static int do_verify(struct fsg_dev *fsg)
+{
+	struct lun		*curlun = fsg->curlun;
+	u32			lba;
+	u32			verification_length;
+	struct fsg_buffhd	*bh = fsg->next_buffhd_to_fill;
+	loff_t			file_offset, file_offset_tmp;
+	u32			amount_left;
+	unsigned int		amount;
+	ssize_t			nread;
+
+	/* Get the starting Logical Block Address and check that it's
+	 * not too big */
+	lba = get_be32(&fsg->cmnd[2]);
+	if (lba >= curlun->num_sectors) {
+		curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+		return -EINVAL;
+	}
+
+	/* We allow DPO (Disable Page Out = don't save data in the
+	 * cache) but we don't implement it. */
+	if ((fsg->cmnd[1] & ~0x10) != 0) {
+		curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+		return -EINVAL;
+	}
+
+	verification_length = get_be16(&fsg->cmnd[7]);
+	if (unlikely(verification_length == 0))
+		return -EIO;		// No default reply
+
+	/* Prepare to carry out the file verify */
+	amount_left = verification_length << 9;
+	file_offset = ((loff_t) lba) << 9;
+
+	/* Write out all the dirty buffers before invalidating them */
+	fsync_sub(curlun);
+	if (signal_pending(current))
+		return -EINTR;
+
+	invalidate_sub(curlun);
+	if (signal_pending(current))
+		return -EINTR;
+
+	/* Just try to read the requested blocks */
+	while (amount_left > 0) {
+
+		/* Figure out how much we need to read:
+		 * Try to read the remaining amount, but not more than
+		 * the buffer size.
+		 * And don't try to read past the end of the file.
+		 * If this means reading 0 then we were asked to read
+		 * past the end of file. */
+		amount = min((unsigned int) amount_left, mod_data.buflen);
+		amount = min((loff_t) amount,
+				curlun->file_length - file_offset);
+		if (amount == 0) {
+			curlun->sense_data =
+					SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+			curlun->sense_data_info = file_offset >> 9;
+			break;
+		}
+
+		/* Perform the read */
+		file_offset_tmp = file_offset;
+		nread = vfs_read(curlun->filp,
+				(char __user *) bh->buf,
+				amount, &file_offset_tmp);
+		VLDBG(curlun, "file read %u @ %llu -> %d\n", amount,
+				(unsigned long long) file_offset,
+				(int) nread);
+		if (signal_pending(current))
+			return -EINTR;
+
+		if (nread < 0) {
+			LDBG(curlun, "error in file verify: %d\n",
+					(int) nread);
+			nread = 0;
+		} else if (nread < amount) {
+			LDBG(curlun, "partial file verify: %d/%u\n",
+					(int) nread, amount);
+			nread -= (nread & 511);	// Round down to a sector
+		}
+		if (nread == 0) {
+			curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
+			curlun->sense_data_info = file_offset >> 9;
+			break;
+		}
+		file_offset += nread;
+		amount_left -= nread;
+	}
+	return 0;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static int do_inquiry(struct fsg_dev *fsg, struct fsg_buffhd *bh)
+{
+	u8	*buf = (u8 *) bh->buf;
+
+	static char vendor_id[] = "Linux   ";
+	static char product_id[] = "File-Stor Gadget";
+
+	if (!fsg->curlun) {		// Unsupported LUNs are okay
+		fsg->bad_lun_okay = 1;
+		memset(buf, 0, 36);
+		buf[0] = 0x7f;		// Unsupported, no device-type
+		return 36;
+	}
+
+	memset(buf, 0, 8);	// Non-removable, direct-access device
+	if (mod_data.removable)
+		buf[1] = 0x80;
+	buf[2] = 2;		// ANSI SCSI level 2
+	buf[3] = 2;		// SCSI-2 INQUIRY data format
+	buf[4] = 31;		// Additional length
+				// No special options
+	sprintf(buf + 8, "%-8s%-16s%04x", vendor_id, product_id,
+			DRIVER_VERSION_NUM);
+	return 36;
+}
+
+
+static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
+{
+	struct lun	*curlun = fsg->curlun;
+	u8		*buf = (u8 *) bh->buf;
+	u32		sd, sdinfo;
+
+	/*
+	 * From the SCSI-2 spec., section 7.9 (Unit attention condition):
+	 *
+	 * If a REQUEST SENSE command is received from an initiator
+	 * with a pending unit attention condition (before the target
+	 * generates the contingent allegiance condition), then the
+	 * target shall either:
+	 *   a) report any pending sense data and preserve the unit
+	 *	attention condition on the logical unit, or,
+	 *   b) report the unit attention condition, may discard any
+	 *	pending sense data, and clear the unit attention
+	 *	condition on the logical unit for that initiator.
+	 *
+	 * FSG normally uses option a); enable this code to use option b).
+	 */
+#if 0
+	if (curlun && curlun->unit_attention_data != SS_NO_SENSE) {
+		curlun->sense_data = curlun->unit_attention_data;
+		curlun->unit_attention_data = SS_NO_SENSE;
+	}
+#endif
+
+	if (!curlun) {		// Unsupported LUNs are okay
+		fsg->bad_lun_okay = 1;
+		sd = SS_LOGICAL_UNIT_NOT_SUPPORTED;
+		sdinfo = 0;
+	} else {
+		sd = curlun->sense_data;
+		sdinfo = curlun->sense_data_info;
+		curlun->sense_data = SS_NO_SENSE;
+		curlun->sense_data_info = 0;
+	}
+
+	memset(buf, 0, 18);
+	buf[0] = 0x80 | 0x70;			// Valid, current error
+	buf[2] = SK(sd);
+	put_be32(&buf[3], sdinfo);		// Sense information
+	buf[7] = 18 - 7;			// Additional sense length
+	buf[12] = ASC(sd);
+	buf[13] = ASCQ(sd);
+	return 18;
+}
+
+
+static int do_read_capacity(struct fsg_dev *fsg, struct fsg_buffhd *bh)
+{
+	struct lun	*curlun = fsg->curlun;
+	u32		lba = get_be32(&fsg->cmnd[2]);
+	int		pmi = fsg->cmnd[8];
+	u8		*buf = (u8 *) bh->buf;
+
+	/* Check the PMI and LBA fields */
+	if (pmi > 1 || (pmi == 0 && lba != 0)) {
+		curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+		return -EINVAL;
+	}
+
+	put_be32(&buf[0], curlun->num_sectors - 1);	// Max logical block
+	put_be32(&buf[4], 512);				// Block length
+	return 8;
+}
+
+
+static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
+{
+	struct lun	*curlun = fsg->curlun;
+	int		mscmnd = fsg->cmnd[0];
+	u8		*buf = (u8 *) bh->buf;
+	u8		*buf0 = buf;
+	int		pc, page_code;
+	int		changeable_values, all_pages;
+	int		valid_page = 0;
+	int		len, limit;
+
+	if ((fsg->cmnd[1] & ~0x08) != 0) {		// Mask away DBD
+		curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+		return -EINVAL;
+	}
+	pc = fsg->cmnd[2] >> 6;
+	page_code = fsg->cmnd[2] & 0x3f;
+	if (pc == 3) {
+		curlun->sense_data = SS_SAVING_PARAMETERS_NOT_SUPPORTED;
+		return -EINVAL;
+	}
+	changeable_values = (pc == 1);
+	all_pages = (page_code == 0x3f);
+
+	/* Write the mode parameter header.  Fixed values are: default
+	 * medium type, no cache control (DPOFUA), and no block descriptors.
+	 * The only variable value is the WriteProtect bit.  We will fill in
+	 * the mode data length later. */
+	memset(buf, 0, 8);
+	if (mscmnd == SC_MODE_SENSE_6) {
+		buf[2] = (curlun->ro ? 0x80 : 0x00);		// WP, DPOFUA
+		buf += 4;
+		limit = 255;
+	} else {			// SC_MODE_SENSE_10
+		buf[3] = (curlun->ro ? 0x80 : 0x00);		// WP, DPOFUA
+		buf += 8;
+		limit = 65535;		// Should really be mod_data.buflen
+	}
+
+	/* No block descriptors */
+
+	/* The mode pages, in numerical order.  The only page we support
+	 * is the Caching page. */
+	if (page_code == 0x08 || all_pages) {
+		valid_page = 1;
+		buf[0] = 0x08;		// Page code
+		buf[1] = 10;		// Page length
+		memset(buf+2, 0, 10);	// None of the fields are changeable
+
+		if (!changeable_values) {
+			buf[2] = 0x04;	// Write cache enable,
+					// Read cache not disabled
+					// No cache retention priorities
+			put_be16(&buf[4], 0xffff);  // Don't disable prefetch
+					// Minimum prefetch = 0
+			put_be16(&buf[8], 0xffff);  // Maximum prefetch
+			put_be16(&buf[10], 0xffff); // Maximum prefetch ceiling
+		}
+		buf += 12;
+	}
+
+	/* Check that a valid page was requested and the mode data length
+	 * isn't too long. */
+	len = buf - buf0;
+	if (!valid_page || len > limit) {
+		curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+		return -EINVAL;
+	}
+
+	/*  Store the mode data length */
+	if (mscmnd == SC_MODE_SENSE_6)
+		buf0[0] = len - 1;
+	else
+		put_be16(buf0, len - 2);
+	return len;
+}
+
+
+static int do_start_stop(struct fsg_dev *fsg)
+{
+	struct lun	*curlun = fsg->curlun;
+	int		loej, start;
+
+	if (!mod_data.removable) {
+		curlun->sense_data = SS_INVALID_COMMAND;
+		return -EINVAL;
+	}
+
+	// int immed = fsg->cmnd[1] & 0x01;
+	loej = fsg->cmnd[4] & 0x02;
+	start = fsg->cmnd[4] & 0x01;
+
+#ifdef CONFIG_USB_FILE_STORAGE_TEST
+	if ((fsg->cmnd[1] & ~0x01) != 0 ||		// Mask away Immed
+			(fsg->cmnd[4] & ~0x03) != 0) {	// Mask LoEj, Start
+		curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+		return -EINVAL;
+	}
+
+	if (!start) {
+
+		/* Are we allowed to unload the media? */
+		if (curlun->prevent_medium_removal) {
+			LDBG(curlun, "unload attempt prevented\n");
+			curlun->sense_data = SS_MEDIUM_REMOVAL_PREVENTED;
+			return -EINVAL;
+		}
+		if (loej) {		// Simulate an unload/eject
+			up_read(&fsg->filesem);
+			down_write(&fsg->filesem);
+			close_backing_file(curlun);
+			up_write(&fsg->filesem);
+			down_read(&fsg->filesem);
+		}
+	} else {
+
+		/* Our emulation doesn't support mounting; the medium is
+		 * available for use as soon as it is loaded. */
+		if (!backing_file_is_open(curlun)) {
+			curlun->sense_data = SS_MEDIUM_NOT_PRESENT;
+			return -EINVAL;
+		}
+	}
+#endif
+	return 0;
+}
+
+
+static int do_prevent_allow(struct fsg_dev *fsg)
+{
+	struct lun	*curlun = fsg->curlun;
+	int		prevent;
+
+	if (!mod_data.removable) {
+		curlun->sense_data = SS_INVALID_COMMAND;
+		return -EINVAL;
+	}
+
+	prevent = fsg->cmnd[4] & 0x01;
+	if ((fsg->cmnd[4] & ~0x01) != 0) {		// Mask away Prevent
+		curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+		return -EINVAL;
+	}
+
+	if (curlun->prevent_medium_removal && !prevent)
+		fsync_sub(curlun);
+	curlun->prevent_medium_removal = prevent;
+	return 0;
+}
+
+
+static int do_read_format_capacities(struct fsg_dev *fsg,
+			struct fsg_buffhd *bh)
+{
+	struct lun	*curlun = fsg->curlun;
+	u8		*buf = (u8 *) bh->buf;
+
+	buf[0] = buf[1] = buf[2] = 0;
+	buf[3] = 8;		// Only the Current/Maximum Capacity Descriptor
+	buf += 4;
+
+	put_be32(&buf[0], curlun->num_sectors);		// Number of blocks
+	put_be32(&buf[4], 512);				// Block length
+	buf[4] = 0x02;					// Current capacity
+	return 12;
+}
+
+
+static int do_mode_select(struct fsg_dev *fsg, struct fsg_buffhd *bh)
+{
+	struct lun	*curlun = fsg->curlun;
+
+	/* We don't support MODE SELECT */
+	curlun->sense_data = SS_INVALID_COMMAND;
+	return -EINVAL;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static int halt_bulk_in_endpoint(struct fsg_dev *fsg)
+{
+	int	rc;
+
+	rc = fsg_set_halt(fsg, fsg->bulk_in);
+	if (rc == -EAGAIN)
+		VDBG(fsg, "delayed bulk-in endpoint halt\n");
+	while (rc != 0) {
+		if (rc != -EAGAIN) {
+			WARN(fsg, "usb_ep_set_halt -> %d\n", rc);
+			rc = 0;
+			break;
+		}
+
+		/* Wait for a short time and then try again */
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (schedule_timeout(HZ / 10) != 0)
+			return -EINTR;
+		rc = usb_ep_set_halt(fsg->bulk_in);
+	}
+	return rc;
+}
+
+static int pad_with_zeros(struct fsg_dev *fsg)
+{
+	struct fsg_buffhd	*bh = fsg->next_buffhd_to_fill;
+	u32			nkeep = bh->inreq->length;
+	u32			nsend;
+	int			rc;
+
+	bh->state = BUF_STATE_EMPTY;		// For the first iteration
+	fsg->usb_amount_left = nkeep + fsg->residue;
+	while (fsg->usb_amount_left > 0) {
+
+		/* Wait for the next buffer to be free */
+		while (bh->state != BUF_STATE_EMPTY) {
+			if ((rc = sleep_thread(fsg)) != 0)
+				return rc;
+		}
+
+		nsend = min(fsg->usb_amount_left, (u32) mod_data.buflen);
+		memset(bh->buf + nkeep, 0, nsend - nkeep);
+		bh->inreq->length = nsend;
+		bh->inreq->zero = 0;
+		start_transfer(fsg, fsg->bulk_in, bh->inreq,
+				&bh->inreq_busy, &bh->state);
+		bh = fsg->next_buffhd_to_fill = bh->next;
+		fsg->usb_amount_left -= nsend;
+		nkeep = 0;
+	}
+	return 0;
+}
+
+static int throw_away_data(struct fsg_dev *fsg)
+{
+	struct fsg_buffhd	*bh;
+	u32			amount;
+	int			rc;
+
+	while ((bh = fsg->next_buffhd_to_drain)->state != BUF_STATE_EMPTY ||
+			fsg->usb_amount_left > 0) {
+
+		/* Throw away the data in a filled buffer */
+		if (bh->state == BUF_STATE_FULL) {
+			bh->state = BUF_STATE_EMPTY;
+			fsg->next_buffhd_to_drain = bh->next;
+
+			/* A short packet or an error ends everything */
+			if (bh->outreq->actual != bh->outreq->length ||
+					bh->outreq->status != 0) {
+				raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT);
+				return -EINTR;
+			}
+			continue;
+		}
+
+		/* Try to submit another request if we need one */
+		bh = fsg->next_buffhd_to_fill;
+		if (bh->state == BUF_STATE_EMPTY && fsg->usb_amount_left > 0) {
+			amount = min(fsg->usb_amount_left,
+					(u32) mod_data.buflen);
+
+			/* amount is always divisible by 512, hence by
+			 * the bulk-out maxpacket size */
+			bh->outreq->length = bh->bulk_out_intended_length =
+					amount;
+			start_transfer(fsg, fsg->bulk_out, bh->outreq,
+					&bh->outreq_busy, &bh->state);
+			fsg->next_buffhd_to_fill = bh->next;
+			fsg->usb_amount_left -= amount;
+			continue;
+		}
+
+		/* Otherwise wait for something to happen */
+		if ((rc = sleep_thread(fsg)) != 0)
+			return rc;
+	}
+	return 0;
+}
+
+
+static int finish_reply(struct fsg_dev *fsg)
+{
+	struct fsg_buffhd	*bh = fsg->next_buffhd_to_fill;
+	int			rc = 0;
+
+	switch (fsg->data_dir) {
+	case DATA_DIR_NONE:
+		break;			// Nothing to send
+
+	/* If we don't know whether the host wants to read or write,
+	 * this must be CB or CBI with an unknown command.  We mustn't
+	 * try to send or receive any data.  So stall both bulk pipes
+	 * if we can and wait for a reset. */
+	case DATA_DIR_UNKNOWN:
+		if (mod_data.can_stall) {
+			fsg_set_halt(fsg, fsg->bulk_out);
+			rc = halt_bulk_in_endpoint(fsg);
+		}
+		break;
+
+	/* All but the last buffer of data must have already been sent */
+	case DATA_DIR_TO_HOST:
+		if (fsg->data_size == 0)
+			;		// Nothing to send
+
+		/* If there's no residue, simply send the last buffer */
+		else if (fsg->residue == 0) {
+			bh->inreq->zero = 0;
+			start_transfer(fsg, fsg->bulk_in, bh->inreq,
+					&bh->inreq_busy, &bh->state);
+			fsg->next_buffhd_to_fill = bh->next;
+		}
+
+		/* There is a residue.  For CB and CBI, simply mark the end
+		 * of the data with a short packet.  However, if we are
+		 * allowed to stall, there was no data at all (residue ==
+		 * data_size), and the command failed (invalid LUN or
+		 * sense data is set), then halt the bulk-in endpoint
+		 * instead. */
+		else if (!transport_is_bbb()) {
+			if (mod_data.can_stall &&
+					fsg->residue == fsg->data_size &&
+	(!fsg->curlun || fsg->curlun->sense_data != SS_NO_SENSE)) {
+				bh->state = BUF_STATE_EMPTY;
+				rc = halt_bulk_in_endpoint(fsg);
+			} else {
+				bh->inreq->zero = 1;
+				start_transfer(fsg, fsg->bulk_in, bh->inreq,
+						&bh->inreq_busy, &bh->state);
+				fsg->next_buffhd_to_fill = bh->next;
+			}
+		}
+
+		/* For Bulk-only, if we're allowed to stall then send the
+		 * short packet and halt the bulk-in endpoint.  If we can't
+		 * stall, pad out the remaining data with 0's. */
+		else {
+			if (mod_data.can_stall) {
+				bh->inreq->zero = 1;
+				start_transfer(fsg, fsg->bulk_in, bh->inreq,
+						&bh->inreq_busy, &bh->state);
+				fsg->next_buffhd_to_fill = bh->next;
+				rc = halt_bulk_in_endpoint(fsg);
+			} else
+				rc = pad_with_zeros(fsg);
+		}
+		break;
+
+	/* We have processed all we want from the data the host has sent.
+	 * There may still be outstanding bulk-out requests. */
+	case DATA_DIR_FROM_HOST:
+		if (fsg->residue == 0)
+			;		// Nothing to receive
+
+		/* Did the host stop sending unexpectedly early? */
+		else if (fsg->short_packet_received) {
+			raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT);
+			rc = -EINTR;
+		}
+
+		/* We haven't processed all the incoming data.  If we are
+		 * allowed to stall, halt the bulk-out endpoint and cancel
+		 * any outstanding requests. */
+		else if (mod_data.can_stall) {
+			fsg_set_halt(fsg, fsg->bulk_out);
+			raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT);
+			rc = -EINTR;
+		}
+
+		/* We can't stall.  Read in the excess data and throw it
+		 * all away. */
+		else
+			rc = throw_away_data(fsg);
+		break;
+	}
+	return rc;
+}
+
+
+static int send_status(struct fsg_dev *fsg)
+{
+	struct lun		*curlun = fsg->curlun;
+	struct fsg_buffhd	*bh;
+	int			rc;
+	u8			status = USB_STATUS_PASS;
+	u32			sd, sdinfo = 0;
+
+	/* Wait for the next buffer to become available */
+	bh = fsg->next_buffhd_to_fill;
+	while (bh->state != BUF_STATE_EMPTY) {
+		if ((rc = sleep_thread(fsg)) != 0)
+			return rc;
+	}
+
+	if (curlun) {
+		sd = curlun->sense_data;
+		sdinfo = curlun->sense_data_info;
+	} else if (fsg->bad_lun_okay)
+		sd = SS_NO_SENSE;
+	else
+		sd = SS_LOGICAL_UNIT_NOT_SUPPORTED;
+
+	if (fsg->phase_error) {
+		DBG(fsg, "sending phase-error status\n");
+		status = USB_STATUS_PHASE_ERROR;
+		sd = SS_INVALID_COMMAND;
+	} else if (sd != SS_NO_SENSE) {
+		DBG(fsg, "sending command-failure status\n");
+		status = USB_STATUS_FAIL;
+		VDBG(fsg, "  sense data: SK x%02x, ASC x%02x, ASCQ x%02x;"
+				"  info x%x\n",
+				SK(sd), ASC(sd), ASCQ(sd), sdinfo);
+	}
+
+	if (transport_is_bbb()) {
+		struct bulk_cs_wrap	*csw = (struct bulk_cs_wrap *) bh->buf;
+
+		/* Store and send the Bulk-only CSW */
+		csw->Signature = __constant_cpu_to_le32(USB_BULK_CS_SIG);
+		csw->Tag = fsg->tag;
+		csw->Residue = fsg->residue;
+		csw->Status = status;
+
+		bh->inreq->length = USB_BULK_CS_WRAP_LEN;
+		bh->inreq->zero = 0;
+		start_transfer(fsg, fsg->bulk_in, bh->inreq,
+				&bh->inreq_busy, &bh->state);
+
+	} else if (mod_data.transport_type == USB_PR_CB) {
+
+		/* Control-Bulk transport has no status stage! */
+		return 0;
+
+	} else {			// USB_PR_CBI
+		struct interrupt_data	*buf = (struct interrupt_data *)
+						bh->buf;
+
+		/* Store and send the Interrupt data.  UFI sends the ASC
+		 * and ASCQ bytes.  Everything else sends a Type (which
+		 * is always 0) and the status Value. */
+		if (mod_data.protocol_type == USB_SC_UFI) {
+			buf->bType = ASC(sd);
+			buf->bValue = ASCQ(sd);
+		} else {
+			buf->bType = 0;
+			buf->bValue = status;
+		}
+		fsg->intreq->length = CBI_INTERRUPT_DATA_LEN;
+
+		fsg->intr_buffhd = bh;		// Point to the right buffhd
+		fsg->intreq->buf = bh->inreq->buf;
+		fsg->intreq->dma = bh->inreq->dma;
+		fsg->intreq->context = bh;
+		start_transfer(fsg, fsg->intr_in, fsg->intreq,
+				&fsg->intreq_busy, &bh->state);
+	}
+
+	fsg->next_buffhd_to_fill = bh->next;
+	return 0;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/* Check whether the command is properly formed and whether its data size
+ * and direction agree with the values we already have. */
+static int check_command(struct fsg_dev *fsg, int cmnd_size,
+		enum data_direction data_dir, unsigned int mask,
+		int needs_medium, const char *name)
+{
+	int			i;
+	int			lun = fsg->cmnd[1] >> 5;
+	static const char	dirletter[4] = {'u', 'o', 'i', 'n'};
+	char			hdlen[20];
+	struct lun		*curlun;
+
+	/* Adjust the expected cmnd_size for protocol encapsulation padding.
+	 * Transparent SCSI doesn't pad. */
+	if (protocol_is_scsi())
+		;
+
+	/* There's some disagreement as to whether RBC pads commands or not.
+	 * We'll play it safe and accept either form. */
+	else if (mod_data.protocol_type == USB_SC_RBC) {
+		if (fsg->cmnd_size == 12)
+			cmnd_size = 12;
+
+	/* All the other protocols pad to 12 bytes */
+	} else
+		cmnd_size = 12;
+
+	hdlen[0] = 0;
+	if (fsg->data_dir != DATA_DIR_UNKNOWN)
+		sprintf(hdlen, ", H%c=%u", dirletter[(int) fsg->data_dir],
+				fsg->data_size);
+	VDBG(fsg, "SCSI command: %s;  Dc=%d, D%c=%u;  Hc=%d%s\n",
+			name, cmnd_size, dirletter[(int) data_dir],
+			fsg->data_size_from_cmnd, fsg->cmnd_size, hdlen);
+
+	/* We can't reply at all until we know the correct data direction
+	 * and size. */
+	if (fsg->data_size_from_cmnd == 0)
+		data_dir = DATA_DIR_NONE;
+	if (fsg->data_dir == DATA_DIR_UNKNOWN) {	// CB or CBI
+		fsg->data_dir = data_dir;
+		fsg->data_size = fsg->data_size_from_cmnd;
+
+	} else {					// Bulk-only
+		if (fsg->data_size < fsg->data_size_from_cmnd) {
+
+			/* Host data size < Device data size is a phase error.
+			 * Carry out the command, but only transfer as much
+			 * as we are allowed. */
+			fsg->data_size_from_cmnd = fsg->data_size;
+			fsg->phase_error = 1;
+		}
+	}
+	fsg->residue = fsg->usb_amount_left = fsg->data_size;
+
+	/* Conflicting data directions is a phase error */
+	if (fsg->data_dir != data_dir && fsg->data_size_from_cmnd > 0)
+		goto phase_error;
+
+	/* Verify the length of the command itself */
+	if (cmnd_size != fsg->cmnd_size) {
+
+		/* Special case workaround: MS-Windows issues REQUEST SENSE
+		 * with cbw->Length == 12 (it should be 6). */
+		if (fsg->cmnd[0] == SC_REQUEST_SENSE && fsg->cmnd_size == 12)
+			cmnd_size = fsg->cmnd_size;
+		else
+			goto phase_error;
+	}
+
+	/* Check that the LUN values are oonsistent */
+	if (transport_is_bbb()) {
+		if (fsg->lun != lun)
+			DBG(fsg, "using LUN %d from CBW, "
+					"not LUN %d from CDB\n",
+					fsg->lun, lun);
+	} else
+		fsg->lun = lun;		// Use LUN from the command
+
+	/* Check the LUN */
+	if (fsg->lun >= 0 && fsg->lun < fsg->nluns) {
+		fsg->curlun = curlun = &fsg->luns[fsg->lun];
+		if (fsg->cmnd[0] != SC_REQUEST_SENSE) {
+			curlun->sense_data = SS_NO_SENSE;
+			curlun->sense_data_info = 0;
+		}
+	} else {
+		fsg->curlun = curlun = NULL;
+		fsg->bad_lun_okay = 0;
+
+		/* INQUIRY and REQUEST SENSE commands are explicitly allowed
+		 * to use unsupported LUNs; all others may not. */
+		if (fsg->cmnd[0] != SC_INQUIRY &&
+				fsg->cmnd[0] != SC_REQUEST_SENSE) {
+			DBG(fsg, "unsupported LUN %d\n", fsg->lun);
+			return -EINVAL;
+		}
+	}
+
+	/* If a unit attention condition exists, only INQUIRY and
+	 * REQUEST SENSE commands are allowed; anything else must fail. */
+	if (curlun && curlun->unit_attention_data != SS_NO_SENSE &&
+			fsg->cmnd[0] != SC_INQUIRY &&
+			fsg->cmnd[0] != SC_REQUEST_SENSE) {
+		curlun->sense_data = curlun->unit_attention_data;
+		curlun->unit_attention_data = SS_NO_SENSE;
+		return -EINVAL;
+	}
+
+	/* Check that only command bytes listed in the mask are non-zero */
+	fsg->cmnd[1] &= 0x1f;			// Mask away the LUN
+	for (i = 1; i < cmnd_size; ++i) {
+		if (fsg->cmnd[i] && !(mask & (1 << i))) {
+			if (curlun)
+				curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+			return -EINVAL;
+		}
+	}
+
+	/* If the medium isn't mounted and the command needs to access
+	 * it, return an error. */
+	if (curlun && !backing_file_is_open(curlun) && needs_medium) {
+		curlun->sense_data = SS_MEDIUM_NOT_PRESENT;
+		return -EINVAL;
+	}
+
+	return 0;
+
+phase_error:
+	fsg->phase_error = 1;
+	return -EINVAL;
+}
+
+
+static int do_scsi_command(struct fsg_dev *fsg)
+{
+	struct fsg_buffhd	*bh;
+	int			rc;
+	int			reply = -EINVAL;
+	int			i;
+	static char		unknown[16];
+
+	dump_cdb(fsg);
+
+	/* Wait for the next buffer to become available for data or status */
+	bh = fsg->next_buffhd_to_drain = fsg->next_buffhd_to_fill;
+	while (bh->state != BUF_STATE_EMPTY) {
+		if ((rc = sleep_thread(fsg)) != 0)
+			return rc;
+		}
+	fsg->phase_error = 0;
+	fsg->short_packet_received = 0;
+
+	down_read(&fsg->filesem);	// We're using the backing file
+	switch (fsg->cmnd[0]) {
+
+	case SC_INQUIRY:
+		fsg->data_size_from_cmnd = fsg->cmnd[4];
+		if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST,
+				(1<<4), 0,
+				"INQUIRY")) == 0)
+			reply = do_inquiry(fsg, bh);
+		break;
+
+	case SC_MODE_SELECT_6:
+		fsg->data_size_from_cmnd = fsg->cmnd[4];
+		if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST,
+				(1<<1) | (1<<4), 0,
+				"MODE SELECT(6)")) == 0)
+			reply = do_mode_select(fsg, bh);
+		break;
+
+	case SC_MODE_SELECT_10:
+		fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]);
+		if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST,
+				(1<<1) | (3<<7), 0,
+				"MODE SELECT(10)")) == 0)
+			reply = do_mode_select(fsg, bh);
+		break;
+
+	case SC_MODE_SENSE_6:
+		fsg->data_size_from_cmnd = fsg->cmnd[4];
+		if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST,
+				(1<<1) | (1<<2) | (1<<4), 0,
+				"MODE SENSE(6)")) == 0)
+			reply = do_mode_sense(fsg, bh);
+		break;
+
+	case SC_MODE_SENSE_10:
+		fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]);
+		if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
+				(1<<1) | (1<<2) | (3<<7), 0,
+				"MODE SENSE(10)")) == 0)
+			reply = do_mode_sense(fsg, bh);
+		break;
+
+	case SC_PREVENT_ALLOW_MEDIUM_REMOVAL:
+		fsg->data_size_from_cmnd = 0;
+		if ((reply = check_command(fsg, 6, DATA_DIR_NONE,
+				(1<<4), 0,
+				"PREVENT-ALLOW MEDIUM REMOVAL")) == 0)
+			reply = do_prevent_allow(fsg);
+		break;
+
+	case SC_READ_6:
+		i = fsg->cmnd[4];
+		fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
+		if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST,
+				(7<<1) | (1<<4), 1,
+				"READ(6)")) == 0)
+			reply = do_read(fsg);
+		break;
+
+	case SC_READ_10:
+		fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]) << 9;
+		if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
+				(1<<1) | (0xf<<2) | (3<<7), 1,
+				"READ(10)")) == 0)
+			reply = do_read(fsg);
+		break;
+
+	case SC_READ_12:
+		fsg->data_size_from_cmnd = get_be32(&fsg->cmnd[6]) << 9;
+		if ((reply = check_command(fsg, 12, DATA_DIR_TO_HOST,
+				(1<<1) | (0xf<<2) | (0xf<<6), 1,
+				"READ(12)")) == 0)
+			reply = do_read(fsg);
+		break;
+
+	case SC_READ_CAPACITY:
+		fsg->data_size_from_cmnd = 8;
+		if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
+				(0xf<<2) | (1<<8), 1,
+				"READ CAPACITY")) == 0)
+			reply = do_read_capacity(fsg, bh);
+		break;
+
+	case SC_READ_FORMAT_CAPACITIES:
+		fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]);
+		if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
+				(3<<7), 1,
+				"READ FORMAT CAPACITIES")) == 0)
+			reply = do_read_format_capacities(fsg, bh);
+		break;
+
+	case SC_REQUEST_SENSE:
+		fsg->data_size_from_cmnd = fsg->cmnd[4];
+		if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST,
+				(1<<4), 0,
+				"REQUEST SENSE")) == 0)
+			reply = do_request_sense(fsg, bh);
+		break;
+
+	case SC_START_STOP_UNIT:
+		fsg->data_size_from_cmnd = 0;
+		if ((reply = check_command(fsg, 6, DATA_DIR_NONE,
+				(1<<1) | (1<<4), 0,
+				"START-STOP UNIT")) == 0)
+			reply = do_start_stop(fsg);
+		break;
+
+	case SC_SYNCHRONIZE_CACHE:
+		fsg->data_size_from_cmnd = 0;
+		if ((reply = check_command(fsg, 10, DATA_DIR_NONE,
+				(0xf<<2) | (3<<7), 1,
+				"SYNCHRONIZE CACHE")) == 0)
+			reply = do_synchronize_cache(fsg);
+		break;
+
+	case SC_TEST_UNIT_READY:
+		fsg->data_size_from_cmnd = 0;
+		reply = check_command(fsg, 6, DATA_DIR_NONE,
+				0, 1,
+				"TEST UNIT READY");
+		break;
+
+	/* Although optional, this command is used by MS-Windows.  We
+	 * support a minimal version: BytChk must be 0. */
+	case SC_VERIFY:
+		fsg->data_size_from_cmnd = 0;
+		if ((reply = check_command(fsg, 10, DATA_DIR_NONE,
+				(1<<1) | (0xf<<2) | (3<<7), 1,
+				"VERIFY")) == 0)
+			reply = do_verify(fsg);
+		break;
+
+	case SC_WRITE_6:
+		i = fsg->cmnd[4];
+		fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
+		if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST,
+				(7<<1) | (1<<4), 1,
+				"WRITE(6)")) == 0)
+			reply = do_write(fsg);
+		break;
+
+	case SC_WRITE_10:
+		fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]) << 9;
+		if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST,
+				(1<<1) | (0xf<<2) | (3<<7), 1,
+				"WRITE(10)")) == 0)
+			reply = do_write(fsg);
+		break;
+
+	case SC_WRITE_12:
+		fsg->data_size_from_cmnd = get_be32(&fsg->cmnd[6]) << 9;
+		if ((reply = check_command(fsg, 12, DATA_DIR_FROM_HOST,
+				(1<<1) | (0xf<<2) | (0xf<<6), 1,
+				"WRITE(12)")) == 0)
+			reply = do_write(fsg);
+		break;
+
+	/* Some mandatory commands that we recognize but don't implement.
+	 * They don't mean much in this setting.  It's left as an exercise
+	 * for anyone interested to implement RESERVE and RELEASE in terms
+	 * of Posix locks. */
+	case SC_FORMAT_UNIT:
+	case SC_RELEASE:
+	case SC_RESERVE:
+	case SC_SEND_DIAGNOSTIC:
+		// Fall through
+
+	default:
+		fsg->data_size_from_cmnd = 0;
+		sprintf(unknown, "Unknown x%02x", fsg->cmnd[0]);
+		if ((reply = check_command(fsg, fsg->cmnd_size,
+				DATA_DIR_UNKNOWN, 0xff, 0, unknown)) == 0) {
+			fsg->curlun->sense_data = SS_INVALID_COMMAND;
+			reply = -EINVAL;
+		}
+		break;
+	}
+	up_read(&fsg->filesem);
+
+	if (reply == -EINTR || signal_pending(current))
+		return -EINTR;
+
+	/* Set up the single reply buffer for finish_reply() */
+	if (reply == -EINVAL)
+		reply = 0;		// Error reply length
+	if (reply >= 0 && fsg->data_dir == DATA_DIR_TO_HOST) {
+		reply = min((u32) reply, fsg->data_size_from_cmnd);
+		bh->inreq->length = reply;
+		bh->state = BUF_STATE_FULL;
+		fsg->residue -= reply;
+	}				// Otherwise it's already set
+
+	return 0;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
+{
+	struct usb_request	*req = bh->outreq;
+	struct bulk_cb_wrap	*cbw = (struct bulk_cb_wrap *) req->buf;
+
+	/* Was this a real packet? */
+	if (req->status)
+		return -EINVAL;
+
+	/* Is the CBW valid? */
+	if (req->actual != USB_BULK_CB_WRAP_LEN ||
+			cbw->Signature != __constant_cpu_to_le32(
+				USB_BULK_CB_SIG)) {
+		DBG(fsg, "invalid CBW: len %u sig 0x%x\n",
+				req->actual,
+				le32_to_cpu(cbw->Signature));
+
+		/* The Bulk-only spec says we MUST stall the bulk pipes!
+		 * If we want to avoid stalls, set a flag so that we will
+		 * clear the endpoint halts at the next reset. */
+		if (!mod_data.can_stall)
+			set_bit(CLEAR_BULK_HALTS, &fsg->atomic_bitflags);
+		fsg_set_halt(fsg, fsg->bulk_out);
+		halt_bulk_in_endpoint(fsg);
+		return -EINVAL;
+	}
+
+	/* Is the CBW meaningful? */
+	if (cbw->Lun >= MAX_LUNS || cbw->Flags & ~USB_BULK_IN_FLAG ||
+			cbw->Length < 6 || cbw->Length > MAX_COMMAND_SIZE) {
+		DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, "
+				"cmdlen %u\n",
+				cbw->Lun, cbw->Flags, cbw->Length);
+
+		/* We can do anything we want here, so let's stall the
+		 * bulk pipes if we are allowed to. */
+		if (mod_data.can_stall) {
+			fsg_set_halt(fsg, fsg->bulk_out);
+			halt_bulk_in_endpoint(fsg);
+		}
+		return -EINVAL;
+	}
+
+	/* Save the command for later */
+	fsg->cmnd_size = cbw->Length;
+	memcpy(fsg->cmnd, cbw->CDB, fsg->cmnd_size);
+	if (cbw->Flags & USB_BULK_IN_FLAG)
+		fsg->data_dir = DATA_DIR_TO_HOST;
+	else
+		fsg->data_dir = DATA_DIR_FROM_HOST;
+	fsg->data_size = cbw->DataTransferLength;
+	if (fsg->data_size == 0)
+		fsg->data_dir = DATA_DIR_NONE;
+	fsg->lun = cbw->Lun;
+	fsg->tag = cbw->Tag;
+	return 0;
+}
+
+
+static int get_next_command(struct fsg_dev *fsg)
+{
+	struct fsg_buffhd	*bh;
+	int			rc = 0;
+
+	if (transport_is_bbb()) {
+
+		/* Wait for the next buffer to become available */
+		bh = fsg->next_buffhd_to_fill;
+		while (bh->state != BUF_STATE_EMPTY) {
+			if ((rc = sleep_thread(fsg)) != 0)
+				return rc;
+			}
+
+		/* Queue a request to read a Bulk-only CBW */
+		set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN);
+		start_transfer(fsg, fsg->bulk_out, bh->outreq,
+				&bh->outreq_busy, &bh->state);
+
+		/* We will drain the buffer in software, which means we
+		 * can reuse it for the next filling.  No need to advance
+		 * next_buffhd_to_fill. */
+
+		/* Wait for the CBW to arrive */
+		while (bh->state != BUF_STATE_FULL) {
+			if ((rc = sleep_thread(fsg)) != 0)
+				return rc;
+			}
+		rc = received_cbw(fsg, bh);
+		bh->state = BUF_STATE_EMPTY;
+
+	} else {		// USB_PR_CB or USB_PR_CBI
+
+		/* Wait for the next command to arrive */
+		while (fsg->cbbuf_cmnd_size == 0) {
+			if ((rc = sleep_thread(fsg)) != 0)
+				return rc;
+			}
+
+		/* Is the previous status interrupt request still busy?
+		 * The host is allowed to skip reading the status,
+		 * so we must cancel it. */
+		if (fsg->intreq_busy)
+			usb_ep_dequeue(fsg->intr_in, fsg->intreq);
+
+		/* Copy the command and mark the buffer empty */
+		fsg->data_dir = DATA_DIR_UNKNOWN;
+		spin_lock_irq(&fsg->lock);
+		fsg->cmnd_size = fsg->cbbuf_cmnd_size;
+		memcpy(fsg->cmnd, fsg->cbbuf_cmnd, fsg->cmnd_size);
+		fsg->cbbuf_cmnd_size = 0;
+		spin_unlock_irq(&fsg->lock);
+	}
+	return rc;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static int enable_endpoint(struct fsg_dev *fsg, struct usb_ep *ep,
+		const struct usb_endpoint_descriptor *d)
+{
+	int	rc;
+
+	ep->driver_data = fsg;
+	rc = usb_ep_enable(ep, d);
+	if (rc)
+		ERROR(fsg, "can't enable %s, result %d\n", ep->name, rc);
+	return rc;
+}
+
+static int alloc_request(struct fsg_dev *fsg, struct usb_ep *ep,
+		struct usb_request **preq)
+{
+	*preq = usb_ep_alloc_request(ep, GFP_ATOMIC);
+	if (*preq)
+		return 0;
+	ERROR(fsg, "can't allocate request for %s\n", ep->name);
+	return -ENOMEM;
+}
+
+/*
+ * Reset interface setting and re-init endpoint state (toggle etc).
+ * Call with altsetting < 0 to disable the interface.  The only other
+ * available altsetting is 0, which enables the interface.
+ */
+static int do_set_interface(struct fsg_dev *fsg, int altsetting)
+{
+	int	rc = 0;
+	int	i;
+	const struct usb_endpoint_descriptor	*d;
+
+	if (fsg->running)
+		DBG(fsg, "reset interface\n");
+
+reset:
+	/* Deallocate the requests */
+	for (i = 0; i < NUM_BUFFERS; ++i) {
+		struct fsg_buffhd *bh = &fsg->buffhds[i];
+
+		if (bh->inreq) {
+			usb_ep_free_request(fsg->bulk_in, bh->inreq);
+			bh->inreq = NULL;
+		}
+		if (bh->outreq) {
+			usb_ep_free_request(fsg->bulk_out, bh->outreq);
+			bh->outreq = NULL;
+		}
+	}
+	if (fsg->intreq) {
+		usb_ep_free_request(fsg->intr_in, fsg->intreq);
+		fsg->intreq = NULL;
+	}
+
+	/* Disable the endpoints */
+	if (fsg->bulk_in_enabled) {
+		usb_ep_disable(fsg->bulk_in);
+		fsg->bulk_in_enabled = 0;
+	}
+	if (fsg->bulk_out_enabled) {
+		usb_ep_disable(fsg->bulk_out);
+		fsg->bulk_out_enabled = 0;
+	}
+	if (fsg->intr_in_enabled) {
+		usb_ep_disable(fsg->intr_in);
+		fsg->intr_in_enabled = 0;
+	}
+
+	fsg->running = 0;
+	if (altsetting < 0 || rc != 0)
+		return rc;
+
+	DBG(fsg, "set interface %d\n", altsetting);
+
+	/* Enable the endpoints */
+	d = ep_desc(fsg->gadget, &fs_bulk_in_desc, &hs_bulk_in_desc);
+	if ((rc = enable_endpoint(fsg, fsg->bulk_in, d)) != 0)
+		goto reset;
+	fsg->bulk_in_enabled = 1;
+
+	d = ep_desc(fsg->gadget, &fs_bulk_out_desc, &hs_bulk_out_desc);
+	if ((rc = enable_endpoint(fsg, fsg->bulk_out, d)) != 0)
+		goto reset;
+	fsg->bulk_out_enabled = 1;
+
+	if (transport_is_cbi()) {
+		d = ep_desc(fsg->gadget, &fs_intr_in_desc, &hs_intr_in_desc);
+		if ((rc = enable_endpoint(fsg, fsg->intr_in, d)) != 0)
+			goto reset;
+		fsg->intr_in_enabled = 1;
+	}
+
+	/* Allocate the requests */
+	for (i = 0; i < NUM_BUFFERS; ++i) {
+		struct fsg_buffhd	*bh = &fsg->buffhds[i];
+
+		if ((rc = alloc_request(fsg, fsg->bulk_in, &bh->inreq)) != 0)
+			goto reset;
+		if ((rc = alloc_request(fsg, fsg->bulk_out, &bh->outreq)) != 0)
+			goto reset;
+		bh->inreq->buf = bh->outreq->buf = bh->buf;
+		bh->inreq->dma = bh->outreq->dma = bh->dma;
+		bh->inreq->context = bh->outreq->context = bh;
+		bh->inreq->complete = bulk_in_complete;
+		bh->outreq->complete = bulk_out_complete;
+	}
+	if (transport_is_cbi()) {
+		if ((rc = alloc_request(fsg, fsg->intr_in, &fsg->intreq)) != 0)
+			goto reset;
+		fsg->intreq->complete = intr_in_complete;
+	}
+
+	fsg->running = 1;
+	for (i = 0; i < fsg->nluns; ++i)
+		fsg->luns[i].unit_attention_data = SS_RESET_OCCURRED;
+	return rc;
+}
+
+
+/*
+ * Change our operational configuration.  This code must agree with the code
+ * that returns config descriptors, and with interface altsetting code.
+ *
+ * It's also responsible for power management interactions.  Some
+ * configurations might not work with our current power sources.
+ * For now we just assume the gadget is always self-powered.
+ */
+static int do_set_config(struct fsg_dev *fsg, u8 new_config)
+{
+	int	rc = 0;
+
+	/* Disable the single interface */
+	if (fsg->config != 0) {
+		DBG(fsg, "reset config\n");
+		fsg->config = 0;
+		rc = do_set_interface(fsg, -1);
+	}
+
+	/* Enable the interface */
+	if (new_config != 0) {
+		fsg->config = new_config;
+		if ((rc = do_set_interface(fsg, 0)) != 0)
+			fsg->config = 0;	// Reset on errors
+		else {
+			char *speed;
+
+			switch (fsg->gadget->speed) {
+			case USB_SPEED_LOW:	speed = "low";	break;
+			case USB_SPEED_FULL:	speed = "full";	break;
+			case USB_SPEED_HIGH:	speed = "high";	break;
+			default: 		speed = "?";	break;
+			}
+			INFO(fsg, "%s speed config #%d\n", speed, fsg->config);
+		}
+	}
+	return rc;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static void handle_exception(struct fsg_dev *fsg)
+{
+	siginfo_t		info;
+	int			sig;
+	int			i;
+	int			num_active;
+	struct fsg_buffhd	*bh;
+	enum fsg_state		old_state;
+	u8			new_config;
+	struct lun		*curlun;
+	unsigned int		exception_req_tag;
+	int			rc;
+
+	/* Clear the existing signals.  Anything but SIGUSR1 is converted
+	 * into a high-priority EXIT exception. */
+	for (;;) {
+		sig = dequeue_signal_lock(current, &fsg->thread_signal_mask,
+				&info);
+		if (!sig)
+			break;
+		if (sig != SIGUSR1) {
+			if (fsg->state < FSG_STATE_EXIT)
+				DBG(fsg, "Main thread exiting on signal\n");
+			raise_exception(fsg, FSG_STATE_EXIT);
+		}
+	}
+
+	/* Cancel all the pending transfers */
+	if (fsg->intreq_busy)
+		usb_ep_dequeue(fsg->intr_in, fsg->intreq);
+	for (i = 0; i < NUM_BUFFERS; ++i) {
+		bh = &fsg->buffhds[i];
+		if (bh->inreq_busy)
+			usb_ep_dequeue(fsg->bulk_in, bh->inreq);
+		if (bh->outreq_busy)
+			usb_ep_dequeue(fsg->bulk_out, bh->outreq);
+	}
+
+	/* Wait until everything is idle */
+	for (;;) {
+		num_active = fsg->intreq_busy;
+		for (i = 0; i < NUM_BUFFERS; ++i) {
+			bh = &fsg->buffhds[i];
+			num_active += bh->inreq_busy + bh->outreq_busy;
+		}
+		if (num_active == 0)
+			break;
+		if (sleep_thread(fsg))
+			return;
+	}
+
+	/* Clear out the controller's fifos */
+	if (fsg->bulk_in_enabled)
+		usb_ep_fifo_flush(fsg->bulk_in);
+	if (fsg->bulk_out_enabled)
+		usb_ep_fifo_flush(fsg->bulk_out);
+	if (fsg->intr_in_enabled)
+		usb_ep_fifo_flush(fsg->intr_in);
+
+	/* Reset the I/O buffer states and pointers, the SCSI
+	 * state, and the exception.  Then invoke the handler. */
+	spin_lock_irq(&fsg->lock);
+
+	for (i = 0; i < NUM_BUFFERS; ++i) {
+		bh = &fsg->buffhds[i];
+		bh->state = BUF_STATE_EMPTY;
+	}
+	fsg->next_buffhd_to_fill = fsg->next_buffhd_to_drain =
+			&fsg->buffhds[0];
+
+	exception_req_tag = fsg->exception_req_tag;
+	new_config = fsg->new_config;
+	old_state = fsg->state;
+
+	if (old_state == FSG_STATE_ABORT_BULK_OUT)
+		fsg->state = FSG_STATE_STATUS_PHASE;
+	else {
+		for (i = 0; i < fsg->nluns; ++i) {
+			curlun = &fsg->luns[i];
+			curlun->prevent_medium_removal = 0;
+			curlun->sense_data = curlun->unit_attention_data =
+					SS_NO_SENSE;
+			curlun->sense_data_info = 0;
+		}
+		fsg->state = FSG_STATE_IDLE;
+	}
+	spin_unlock_irq(&fsg->lock);
+
+	/* Carry out any extra actions required for the exception */
+	switch (old_state) {
+	default:
+		break;
+
+	case FSG_STATE_ABORT_BULK_OUT:
+		send_status(fsg);
+		spin_lock_irq(&fsg->lock);
+		if (fsg->state == FSG_STATE_STATUS_PHASE)
+			fsg->state = FSG_STATE_IDLE;
+		spin_unlock_irq(&fsg->lock);
+		break;
+
+	case FSG_STATE_RESET:
+		/* In case we were forced against our will to halt a
+		 * bulk endpoint, clear the halt now.  (The SuperH UDC
+		 * requires this.) */
+		if (test_and_clear_bit(CLEAR_BULK_HALTS,
+				&fsg->atomic_bitflags)) {
+			usb_ep_clear_halt(fsg->bulk_in);
+			usb_ep_clear_halt(fsg->bulk_out);
+		}
+
+		if (transport_is_bbb()) {
+			if (fsg->ep0_req_tag == exception_req_tag)
+				ep0_queue(fsg);	// Complete the status stage
+
+		} else if (transport_is_cbi())
+			send_status(fsg);	// Status by interrupt pipe
+
+		/* Technically this should go here, but it would only be
+		 * a waste of time.  Ditto for the INTERFACE_CHANGE and
+		 * CONFIG_CHANGE cases. */
+		// for (i = 0; i < fsg->nluns; ++i)
+		//	fsg->luns[i].unit_attention_data = SS_RESET_OCCURRED;
+		break;
+
+	case FSG_STATE_INTERFACE_CHANGE:
+		rc = do_set_interface(fsg, 0);
+		if (fsg->ep0_req_tag != exception_req_tag)
+			break;
+		if (rc != 0)			// STALL on errors
+			fsg_set_halt(fsg, fsg->ep0);
+		else				// Complete the status stage
+			ep0_queue(fsg);
+		break;
+
+	case FSG_STATE_CONFIG_CHANGE:
+		rc = do_set_config(fsg, new_config);
+		if (fsg->ep0_req_tag != exception_req_tag)
+			break;
+		if (rc != 0)			// STALL on errors
+			fsg_set_halt(fsg, fsg->ep0);
+		else				// Complete the status stage
+			ep0_queue(fsg);
+		break;
+
+	case FSG_STATE_DISCONNECT:
+		fsync_all(fsg);
+		do_set_config(fsg, 0);		// Unconfigured state
+		break;
+
+	case FSG_STATE_EXIT:
+	case FSG_STATE_TERMINATED:
+		do_set_config(fsg, 0);			// Free resources
+		spin_lock_irq(&fsg->lock);
+		fsg->state = FSG_STATE_TERMINATED;	// Stop the thread
+		spin_unlock_irq(&fsg->lock);
+		break;
+	}
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static int fsg_main_thread(void *fsg_)
+{
+	struct fsg_dev		*fsg = (struct fsg_dev *) fsg_;
+
+	fsg->thread_task = current;
+
+	/* Release all our userspace resources */
+	daemonize("file-storage-gadget");
+
+	/* Allow the thread to be killed by a signal, but set the signal mask
+	 * to block everything but INT, TERM, KILL, and USR1. */
+	siginitsetinv(&fsg->thread_signal_mask, sigmask(SIGINT) |
+			sigmask(SIGTERM) | sigmask(SIGKILL) |
+			sigmask(SIGUSR1));
+	sigprocmask(SIG_SETMASK, &fsg->thread_signal_mask, NULL);
+
+	/* Arrange for userspace references to be interpreted as kernel
+	 * pointers.  That way we can pass a kernel pointer to a routine
+	 * that expects a __user pointer and it will work okay. */
+	set_fs(get_ds());
+
+	/* Wait for the gadget registration to finish up */
+	wait_for_completion(&fsg->thread_notifier);
+
+	/* The main loop */
+	while (fsg->state != FSG_STATE_TERMINATED) {
+		if (exception_in_progress(fsg) || signal_pending(current)) {
+			handle_exception(fsg);
+			continue;
+		}
+
+		if (!fsg->running) {
+			sleep_thread(fsg);
+			continue;
+		}
+
+		if (get_next_command(fsg))
+			continue;
+
+		spin_lock_irq(&fsg->lock);
+		if (!exception_in_progress(fsg))
+			fsg->state = FSG_STATE_DATA_PHASE;
+		spin_unlock_irq(&fsg->lock);
+
+		if (do_scsi_command(fsg) || finish_reply(fsg))
+			continue;
+
+		spin_lock_irq(&fsg->lock);
+		if (!exception_in_progress(fsg))
+			fsg->state = FSG_STATE_STATUS_PHASE;
+		spin_unlock_irq(&fsg->lock);
+
+		if (send_status(fsg))
+			continue;
+
+		spin_lock_irq(&fsg->lock);
+		if (!exception_in_progress(fsg))
+			fsg->state = FSG_STATE_IDLE;
+		spin_unlock_irq(&fsg->lock);
+		}
+
+	fsg->thread_task = NULL;
+	flush_signals(current);
+
+	/* In case we are exiting because of a signal, unregister the
+	 * gadget driver and close the backing file. */
+	if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags)) {
+		usb_gadget_unregister_driver(&fsg_driver);
+		close_all_backing_files(fsg);
+	}
+
+	/* Let the unbind and cleanup routines know the thread has exited */
+	complete_and_exit(&fsg->thread_notifier, 0);
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/* If the next two routines are called while the gadget is registered,
+ * the caller must own fsg->filesem for writing. */
+
+static int NORMALLY_INIT open_backing_file(struct lun *curlun,
+		const char *filename)
+{
+	int				ro;
+	struct file			*filp = NULL;
+	int				rc = -EINVAL;
+	struct inode			*inode = NULL;
+	loff_t				size;
+	loff_t				num_sectors;
+
+	/* R/W if we can, R/O if we must */
+	ro = curlun->ro;
+	if (!ro) {
+		filp = filp_open(filename, O_RDWR | O_LARGEFILE, 0);
+		if (-EROFS == PTR_ERR(filp))
+			ro = 1;
+	}
+	if (ro)
+		filp = filp_open(filename, O_RDONLY | O_LARGEFILE, 0);
+	if (IS_ERR(filp)) {
+		LINFO(curlun, "unable to open backing file: %s\n", filename);
+		return PTR_ERR(filp);
+	}
+
+	if (!(filp->f_mode & FMODE_WRITE))
+		ro = 1;
+
+	if (filp->f_dentry)
+		inode = filp->f_dentry->d_inode;
+	if (inode && S_ISBLK(inode->i_mode)) {
+		if (bdev_read_only(inode->i_bdev))
+			ro = 1;
+	} else if (!inode || !S_ISREG(inode->i_mode)) {
+		LINFO(curlun, "invalid file type: %s\n", filename);
+		goto out;
+	}
+
+	/* If we can't read the file, it's no good.
+	 * If we can't write the file, use it read-only. */
+	if (!filp->f_op || !(filp->f_op->read || filp->f_op->aio_read)) {
+		LINFO(curlun, "file not readable: %s\n", filename);
+		goto out;
+	}
+	if (!(filp->f_op->write || filp->f_op->aio_write))
+		ro = 1;
+
+	size = i_size_read(inode->i_mapping->host);
+	if (size < 0) {
+		LINFO(curlun, "unable to find file size: %s\n", filename);
+		rc = (int) size;
+		goto out;
+	}
+	num_sectors = size >> 9;	// File size in 512-byte sectors
+	if (num_sectors == 0) {
+		LINFO(curlun, "file too small: %s\n", filename);
+		rc = -ETOOSMALL;
+		goto out;
+	}
+
+	get_file(filp);
+	curlun->ro = ro;
+	curlun->filp = filp;
+	curlun->file_length = size;
+	curlun->num_sectors = num_sectors;
+	LDBG(curlun, "open backing file: %s\n", filename);
+	rc = 0;
+
+out:
+	filp_close(filp, current->files);
+	return rc;
+}
+
+
+static void close_backing_file(struct lun *curlun)
+{
+	if (curlun->filp) {
+		LDBG(curlun, "close backing file\n");
+		fput(curlun->filp);
+		curlun->filp = NULL;
+	}
+}
+
+static void close_all_backing_files(struct fsg_dev *fsg)
+{
+	int	i;
+
+	for (i = 0; i < fsg->nluns; ++i)
+		close_backing_file(&fsg->luns[i]);
+}
+
+
+static ssize_t show_ro(struct device *dev, char *buf)
+{
+	struct lun	*curlun = dev_to_lun(dev);
+
+	return sprintf(buf, "%d\n", curlun->ro);
+}
+
+static ssize_t show_file(struct device *dev, char *buf)
+{
+	struct lun	*curlun = dev_to_lun(dev);
+	struct fsg_dev	*fsg = (struct fsg_dev *) dev_get_drvdata(dev);
+	char		*p;
+	ssize_t		rc;
+
+	down_read(&fsg->filesem);
+	if (backing_file_is_open(curlun)) {	// Get the complete pathname
+		p = d_path(curlun->filp->f_dentry, curlun->filp->f_vfsmnt,
+				buf, PAGE_SIZE - 1);
+		if (IS_ERR(p))
+			rc = PTR_ERR(p);
+		else {
+			rc = strlen(p);
+			memmove(buf, p, rc);
+			buf[rc] = '\n';		// Add a newline
+			buf[++rc] = 0;
+		}
+	} else {				// No file, return 0 bytes
+		*buf = 0;
+		rc = 0;
+	}
+	up_read(&fsg->filesem);
+	return rc;
+}
+
+
+ssize_t NORMALLY_INIT store_ro(struct device *dev, const char *buf,
+		size_t count)
+{
+	ssize_t		rc = count;
+	struct lun	*curlun = dev_to_lun(dev);
+	struct fsg_dev	*fsg = (struct fsg_dev *) dev_get_drvdata(dev);
+	int		i;
+
+	if (sscanf(buf, "%d", &i) != 1)
+		return -EINVAL;
+
+	/* Allow the write-enable status to change only while the backing file
+	 * is closed. */
+	down_read(&fsg->filesem);
+	if (backing_file_is_open(curlun)) {
+		LDBG(curlun, "read-only status change prevented\n");
+		rc = -EBUSY;
+	} else {
+		curlun->ro = !!i;
+		LDBG(curlun, "read-only status set to %d\n", curlun->ro);
+	}
+	up_read(&fsg->filesem);
+	return rc;
+}
+
+ssize_t NORMALLY_INIT store_file(struct device *dev, const char *buf,
+		size_t count)
+{
+	struct lun	*curlun = dev_to_lun(dev);
+	struct fsg_dev	*fsg = (struct fsg_dev *) dev_get_drvdata(dev);
+	int		rc = 0;
+
+	if (curlun->prevent_medium_removal && backing_file_is_open(curlun)) {
+		LDBG(curlun, "eject attempt prevented\n");
+		return -EBUSY;				// "Door is locked"
+	}
+
+	/* Remove a trailing newline */
+	if (count > 0 && buf[count-1] == '\n')
+		((char *) buf)[count-1] = 0;		// Ugh!
+
+	/* Eject current medium */
+	down_write(&fsg->filesem);
+	if (backing_file_is_open(curlun)) {
+		close_backing_file(curlun);
+		curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT;
+	}
+
+	/* Load new medium */
+	if (count > 0 && buf[0]) {
+		rc = open_backing_file(curlun, buf);
+		if (rc == 0)
+			curlun->unit_attention_data =
+					SS_NOT_READY_TO_READY_TRANSITION;
+	}
+	up_write(&fsg->filesem);
+	return (rc < 0 ? rc : count);
+}
+
+
+/* The write permissions and store_xxx pointers are set in fsg_bind() */
+static DEVICE_ATTR(ro, 0444, show_ro, NULL);
+static DEVICE_ATTR(file, 0444, show_file, NULL);
+
+
+/*-------------------------------------------------------------------------*/
+
+static void fsg_unbind(struct usb_gadget *gadget)
+{
+	struct fsg_dev		*fsg = get_gadget_data(gadget);
+	int			i;
+	struct lun		*curlun;
+	struct usb_request	*req = fsg->ep0req;
+
+	DBG(fsg, "unbind\n");
+	clear_bit(REGISTERED, &fsg->atomic_bitflags);
+
+	/* Unregister the sysfs attribute files and the LUNs */
+	for (i = 0; i < fsg->nluns; ++i) {
+		curlun = &fsg->luns[i];
+		if (curlun->registered) {
+			device_remove_file(&curlun->dev, &dev_attr_ro);
+			device_remove_file(&curlun->dev, &dev_attr_file);
+			device_unregister_wait(&curlun->dev);
+			curlun->registered = 0;
+		}
+	}
+
+	/* If the thread isn't already dead, tell it to exit now */
+	if (fsg->state != FSG_STATE_TERMINATED) {
+		raise_exception(fsg, FSG_STATE_EXIT);
+		wait_for_completion(&fsg->thread_notifier);
+
+		/* The cleanup routine waits for this completion also */
+		complete(&fsg->thread_notifier);
+	}
+
+	/* Free the data buffers */
+	for (i = 0; i < NUM_BUFFERS; ++i) {
+		struct fsg_buffhd	*bh = &fsg->buffhds[i];
+
+		if (bh->buf)
+			usb_ep_free_buffer(fsg->bulk_in, bh->buf, bh->dma,
+					mod_data.buflen);
+	}
+
+	/* Free the request and buffer for endpoint 0 */
+	if (req) {
+		if (req->buf)
+			usb_ep_free_buffer(fsg->ep0, req->buf,
+					req->dma, EP0_BUFSIZE);
+		usb_ep_free_request(fsg->ep0, req);
+	}
+
+	set_gadget_data(gadget, 0);
+}
+
+
+static int __init check_parameters(struct fsg_dev *fsg)
+{
+	int	prot;
+
+	/* Store the default values */
+	mod_data.transport_type = USB_PR_BULK;
+	mod_data.transport_name = "Bulk-only";
+	mod_data.protocol_type = USB_SC_SCSI;
+	mod_data.protocol_name = "Transparent SCSI";
+
+	prot = simple_strtol(mod_data.protocol_parm, NULL, 0);
+
+#ifdef CONFIG_USB_FILE_STORAGE_TEST
+	if (strnicmp(mod_data.transport_parm, "BBB", 10) == 0) {
+		;		// Use default setting
+	} else if (strnicmp(mod_data.transport_parm, "CB", 10) == 0) {
+		mod_data.transport_type = USB_PR_CB;
+		mod_data.transport_name = "Control-Bulk";
+	} else if (strnicmp(mod_data.transport_parm, "CBI", 10) == 0) {
+		mod_data.transport_type = USB_PR_CBI;
+		mod_data.transport_name = "Control-Bulk-Interrupt";
+	} else {
+		INFO(fsg, "invalid transport: %s\n", mod_data.transport_parm);
+		return -EINVAL;
+	}
+
+	if (strnicmp(mod_data.protocol_parm, "SCSI", 10) == 0 ||
+			prot == USB_SC_SCSI) {
+		;		// Use default setting
+	} else if (strnicmp(mod_data.protocol_parm, "RBC", 10) == 0 ||
+			prot == USB_SC_RBC) {
+		mod_data.protocol_type = USB_SC_RBC;
+		mod_data.protocol_name = "RBC";
+	} else if (strnicmp(mod_data.protocol_parm, "8020", 4) == 0 ||
+			strnicmp(mod_data.protocol_parm, "ATAPI", 10) == 0 ||
+			prot == USB_SC_8020) {
+		mod_data.protocol_type = USB_SC_8020;
+		mod_data.protocol_name = "8020i (ATAPI)";
+	} else if (strnicmp(mod_data.protocol_parm, "QIC", 3) == 0 ||
+			prot == USB_SC_QIC) {
+		mod_data.protocol_type = USB_SC_QIC;
+		mod_data.protocol_name = "QIC-157";
+	} else if (strnicmp(mod_data.protocol_parm, "UFI", 10) == 0 ||
+			prot == USB_SC_UFI) {
+		mod_data.protocol_type = USB_SC_UFI;
+		mod_data.protocol_name = "UFI";
+	} else if (strnicmp(mod_data.protocol_parm, "8070", 4) == 0 ||
+			prot == USB_SC_8070) {
+		mod_data.protocol_type = USB_SC_8070;
+		mod_data.protocol_name = "8070i";
+	} else {
+		INFO(fsg, "invalid protocol: %s\n", mod_data.protocol_parm);
+		return -EINVAL;
+	}
+
+	mod_data.buflen &= PAGE_CACHE_MASK;
+	if (mod_data.buflen <= 0) {
+		INFO(fsg, "invalid buflen\n");
+		return -ETOOSMALL;
+	}
+#endif /* CONFIG_USB_FILE_STORAGE_TEST */
+
+	return 0;
+}
+
+
+static int __init fsg_bind(struct usb_gadget *gadget)
+{
+	struct fsg_dev		*fsg = the_fsg;
+	int			rc;
+	int			i;
+	struct lun		*curlun;
+	struct usb_ep		*ep;
+	struct usb_request	*req;
+	char			*pathbuf, *p;
+
+	fsg->gadget = gadget;
+	set_gadget_data(gadget, fsg);
+	fsg->ep0 = gadget->ep0;
+	fsg->ep0->driver_data = fsg;
+
+	if ((rc = check_parameters(fsg)) != 0)
+		goto out;
+
+	if (mod_data.removable) {	// Enable the store_xxx attributes
+		dev_attr_ro.attr.mode = dev_attr_file.attr.mode = 0644;
+		dev_attr_ro.store = store_ro;
+		dev_attr_file.store = store_file;
+	}
+
+	/* Find out how many LUNs there should be */
+	i = mod_data.nluns;
+	if (i == 0)
+		i = max(mod_data.num_filenames, 1);
+	if (i > MAX_LUNS) {
+		INFO(fsg, "invalid number of LUNs: %d\n", i);
+		rc = -EINVAL;
+		goto out;
+	}
+
+	/* Create the LUNs and open their backing files.  We can't register
+	 * the LUN devices until the gadget itself is registered, which
+	 * doesn't happen until after fsg_bind() returns. */
+	fsg->luns = kmalloc(i * sizeof(struct lun), GFP_KERNEL);
+	if (!fsg->luns) {
+		rc = -ENOMEM;
+		goto out;
+	}
+	memset(fsg->luns, 0, i * sizeof(struct lun));
+	fsg->nluns = i;
+
+	for (i = 0; i < fsg->nluns; ++i) {
+		curlun = &fsg->luns[i];
+		curlun->ro = ro[i];
+		curlun->dev.parent = &gadget->dev;
+		curlun->dev.driver = &fsg_driver.driver;
+		dev_set_drvdata(&curlun->dev, fsg);
+		snprintf(curlun->dev.bus_id, BUS_ID_SIZE,
+				"%s-lun%d", gadget->dev.bus_id, i);
+
+		if (file[i] && *file[i]) {
+			if ((rc = open_backing_file(curlun, file[i])) != 0)
+				goto out;
+		} else if (!mod_data.removable) {
+			INFO(fsg, "no file given for LUN%d\n", i);
+			rc = -EINVAL;
+			goto out;
+		}
+	}
+
+	/* Fix up the descriptors */
+	device_desc.bMaxPacketSize0 = fsg->ep0->maxpacket;
+#ifdef HIGHSPEED
+	dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket;		// ???
+#endif
+	device_desc.idVendor = cpu_to_le16(mod_data.vendor);
+	device_desc.idProduct = cpu_to_le16(mod_data.product);
+	device_desc.bcdDevice = cpu_to_le16(mod_data.release);
+
+	i = (transport_is_cbi() ? 3 : 2);	// Number of endpoints
+	config_desc.wTotalLength = USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE
+			+ USB_DT_ENDPOINT_SIZE * i;
+	intf_desc.bNumEndpoints = i;
+	intf_desc.bInterfaceSubClass = mod_data.protocol_type;
+	intf_desc.bInterfaceProtocol = mod_data.transport_type;
+
+	/* Find all the endpoints we will use */
+	gadget_for_each_ep(ep, gadget) {
+		if (strcmp(ep->name, EP_BULK_IN_NAME) == 0)
+			fsg->bulk_in = ep;
+		else if (strcmp(ep->name, EP_BULK_OUT_NAME) == 0)
+			fsg->bulk_out = ep;
+		else if (strcmp(ep->name, EP_INTR_IN_NAME) == 0)
+			fsg->intr_in = ep;
+	}
+	if (!fsg->bulk_in || !fsg->bulk_out ||
+			(transport_is_cbi() && !fsg->intr_in)) {
+		DBG(fsg, "unable to find all endpoints\n");
+		rc = -ENOTSUPP;
+		goto out;
+	}
+	fsg->bulk_out_maxpacket = (gadget->speed == USB_SPEED_HIGH ? 512 :
+			FS_BULK_OUT_MAXPACKET);
+
+	rc = -ENOMEM;
+
+	/* Allocate the request and buffer for endpoint 0 */
+	fsg->ep0req = req = usb_ep_alloc_request(fsg->ep0, GFP_KERNEL);
+	if (!req)
+		goto out;
+	req->buf = usb_ep_alloc_buffer(fsg->ep0, EP0_BUFSIZE,
+			&req->dma, GFP_KERNEL);
+	if (!req->buf)
+		goto out;
+	req->complete = ep0_complete;
+
+	/* Allocate the data buffers */
+	for (i = 0; i < NUM_BUFFERS; ++i) {
+		struct fsg_buffhd	*bh = &fsg->buffhds[i];
+
+		bh->buf = usb_ep_alloc_buffer(fsg->bulk_in, mod_data.buflen,
+				&bh->dma, GFP_KERNEL);
+		if (!bh->buf)
+			goto out;
+		bh->next = bh + 1;
+	}
+	fsg->buffhds[NUM_BUFFERS - 1].next = &fsg->buffhds[0];
+
+	/* This should reflect the actual gadget power source */
+	usb_gadget_set_selfpowered(gadget);
+
+	/* On a real device, serial[] would be loaded from permanent
+	 * storage.  We just encode it from the driver version string. */
+	for (i = 0; i < sizeof(serial) - 2; i += 2) {
+		unsigned char		c = DRIVER_VERSION[i / 2];
+
+		if (!c)
+			break;
+		sprintf(&serial[i], "%02X", c);
+	}
+
+	if ((rc = kernel_thread(fsg_main_thread, fsg, (CLONE_VM | CLONE_FS |
+			CLONE_FILES))) < 0)
+		goto out;
+	fsg->thread_pid = rc;
+
+	INFO(fsg, DRIVER_DESC ", version: " DRIVER_VERSION "\n");
+	INFO(fsg, "Number of LUNs=%d\n", fsg->nluns);
+
+	pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
+	for (i = 0; i < fsg->nluns; ++i) {
+		curlun = &fsg->luns[i];
+		if (backing_file_is_open(curlun)) {
+			p = NULL;
+			if (pathbuf) {
+				p = d_path(curlun->filp->f_dentry,
+					curlun->filp->f_vfsmnt,
+					pathbuf, PATH_MAX);
+				if (IS_ERR(p))
+					p = NULL;
+			}
+			LINFO(curlun, "ro=%d, file: %s\n",
+					curlun->ro, (p ? p : "(error)"));
+		}
+	}
+	kfree(pathbuf);
+
+	DBG(fsg, "transport=%s (x%02x)\n",
+			mod_data.transport_name, mod_data.transport_type);
+	DBG(fsg, "protocol=%s (x%02x)\n",
+			mod_data.protocol_name, mod_data.protocol_type);
+	DBG(fsg, "VendorID=x%04x, ProductID=x%04x, Release=x%04x\n",
+			mod_data.vendor, mod_data.product, mod_data.release);
+	DBG(fsg, "removable=%d, stall=%d, buflen=%u\n",
+			mod_data.removable, mod_data.can_stall,
+			mod_data.buflen);
+	DBG(fsg, "I/O thread pid: %d\n", fsg->thread_pid);
+	return 0;
+
+out:
+	fsg->state = FSG_STATE_TERMINATED;	// The thread is dead
+	fsg_unbind(gadget);
+	close_all_backing_files(fsg);
+	return rc;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static struct usb_gadget_driver		fsg_driver = {
+#ifdef HIGHSPEED
+	.speed		= USB_SPEED_HIGH,
+#else
+	.speed		= USB_SPEED_FULL,
+#endif
+	.function	= (char *) longname,
+	.bind		= fsg_bind,
+	.unbind		= fsg_unbind,
+	.disconnect	= fsg_disconnect,
+	.setup		= fsg_setup,
+
+	.driver		= {
+		.name		= (char *) shortname,
+		// .release = ...
+		// .suspend = ...
+		// .resume = ...
+	},
+};
+
+
+static int __init fsg_alloc(void)
+{
+	struct fsg_dev		*fsg;
+
+	fsg = kmalloc(sizeof *fsg, GFP_KERNEL);
+	if (!fsg)
+		return -ENOMEM;
+	memset(fsg, 0, sizeof *fsg);
+	spin_lock_init(&fsg->lock);
+	init_rwsem(&fsg->filesem);
+	init_waitqueue_head(&fsg->thread_wqh);
+	init_completion(&fsg->thread_notifier);
+
+	the_fsg = fsg;
+	return 0;
+}
+
+
+static void fsg_free(struct fsg_dev *fsg)
+{
+	kfree(fsg->luns);
+	kfree(fsg);
+}
+
+
+static int __init fsg_init(void)
+{
+	int		rc;
+	struct fsg_dev	*fsg;
+	int		i;
+	struct lun	*curlun;
+
+	if ((rc = fsg_alloc()) != 0)
+		return rc;
+	fsg = the_fsg;
+	if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0) {
+		fsg_free(fsg);
+		return rc;
+	}
+	set_bit(REGISTERED, &fsg->atomic_bitflags);
+
+	/* Register the LUN devices and their attribute files */
+	for (i = 0; i < fsg->nluns; ++i) {
+		curlun = &fsg->luns[i];
+		if ((rc = device_register(&curlun->dev)) != 0)
+			INFO(fsg, "failed to register LUN%d: %d\n", i, rc);
+		else {
+			curlun->registered = 1;
+			device_create_file(&curlun->dev, &dev_attr_ro);
+			device_create_file(&curlun->dev, &dev_attr_file);
+		}
+	}
+
+	/* Tell the thread to start working */
+	complete(&fsg->thread_notifier);
+	return 0;
+}
+module_init(fsg_init);
+
+
+static void __exit fsg_cleanup(void)
+{
+	struct fsg_dev	*fsg = the_fsg;
+
+	/* Unregister the driver iff the thread hasn't already done so */
+	if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags))
+		usb_gadget_unregister_driver(&fsg_driver);
+
+	/* Wait for the thread to finish up */
+	wait_for_completion(&fsg->thread_notifier);
+
+	close_all_backing_files(fsg);
+	fsg_free(fsg);
+}
+module_exit(fsg_cleanup);
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index 96bddf7b525de3c230c95f7e7527832912c6865c..8d4a76751411e8d3adfee6e845a57cc3698807a2 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -232,18 +232,27 @@ static void put_ep (struct ep_data *data)
  * the usb controller exposes.
  */
 
-#ifdef	CONFIG_USB_GADGETFS_NET2280
+#ifdef	CONFIG_USB_GADGET_DUMMY_HCD
+/* act (mostly) like a net2280 */
+#define CONFIG_USB_GADGET_NET2280
+#endif
+
+#ifdef	CONFIG_USB_GADGET_NET2280
 #define CHIP			"net2280"
 #define HIGHSPEED
 #endif
 
-#ifdef	CONFIG_USB_GADGETFS_PXA2XX
+#ifdef	CONFIG_USB_GADGET_PXA2XX
 #define CHIP			"pxa2xx_udc"
 /* earlier hardware doesn't have UDCCFR, races set_{config,interface} */
 #warning works best with pxa255 or newer
 #endif
 
-#ifdef	CONFIG_USB_GADGETFS_SA1100
+#ifdef	CONFIG_USB_GADGET_GOKU
+#define CHIP			"goku_udc"
+#endif
+
+#ifdef	CONFIG_USB_GADGET_SA1100
 #define CHIP			"sa1100"
 #endif
 
@@ -397,7 +406,7 @@ ep_io (struct ep_data *epdata, void *buf, unsigned len)
 
 /* handle a synchronous OUT bulk/intr/iso transfer */
 static ssize_t
-ep_read (struct file *fd, char *buf, size_t len, loff_t *ptr)
+ep_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr)
 {
 	struct ep_data		*data = fd->private_data;
 	void			*kbuf;
@@ -441,7 +450,7 @@ ep_read (struct file *fd, char *buf, size_t len, loff_t *ptr)
 
 /* handle a synchronous IN bulk/intr/iso transfer */
 static ssize_t
-ep_write (struct file *fd, const char *buf, size_t len, loff_t *ptr)
+ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
 {
 	struct ep_data		*data = fd->private_data;
 	void			*kbuf;
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 60b294c2b9441428490b74a550a7c5e4e4f25eeb..915b1645a1de3f2e240ded0da3740395a6a48be9 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -25,9 +25,6 @@
  * rev1 chips.  Rev1a silicon (0110) fixes almost all of them.
  */
 
-#define USE_DMA_CHAINING
-
-
 /*
  * Copyright (C) 2003 David Brownell
  * Copyright (C) 2003 NetChip Technologies
@@ -47,8 +44,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#define DEBUG	1
-// #define	VERBOSE		/* extra debug messages (success too) */
+#undef	DEBUG		/* messages on error and most fault paths */
+#undef	VERBOSE		/* extra debug messages (success too) */
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -77,7 +74,7 @@
 
 
 #define	DRIVER_DESC		"NetChip 2280 USB Peripheral Controller"
-#define	DRIVER_VERSION		"Bastille Day 2003"
+#define	DRIVER_VERSION		"2004 Jan 14"
 
 #define	DMA_ADDR_INVALID	(~(dma_addr_t)0)
 #define	EP_DONTUSE		13	/* nonzero */
@@ -96,10 +93,21 @@ static const char *ep_name [] = {
 	"ep-e", "ep-f",
 };
 
+/* use_dma -- general goodness, fewer interrupts, less cpu load (vs PIO)
+ * use_dma_chaining -- dma descriptor queueing gives even more irq reduction
+ *
+ * The net2280 DMA engines are not tightly integrated with their FIFOs;
+ * not all cases are (yet) handled well in this driver or the silicon.
+ * Some gadget drivers work better with the dma support here than others.
+ * These two parameters let you use PIO or more aggressive DMA.
+ */
 static int use_dma = 1;
+static int use_dma_chaining = 0;
 
 /* "modprobe net2280 use_dma=n" etc */
-module_param (use_dma, bool, S_IRUGO|S_IWUSR);
+module_param (use_dma, bool, S_IRUGO);
+module_param (use_dma_chaining, bool, S_IRUGO);
+
 
 /* mode 0 == ep-{a,b,c,d} 1K fifo each
  * mode 1 == ep-{a,b} 2K fifo each, ep-{c,d} unavailable
@@ -110,6 +118,7 @@ static ushort fifo_mode = 0;
 /* "modprobe net2280 fifo_mode=1" etc */
 module_param (fifo_mode, ushort, 0644);
 
+
 #define	DIR_STRING(bAddress) (((bAddress) & USB_DIR_IN) ? "in" : "out")
 
 #if defined(USE_SYSFS_DEBUG_FILES) || defined (DEBUG)
@@ -162,6 +171,7 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
 
 	/* ep_reset() has already been called */
 	ep->stopped = 0;
+	ep->out_overflow = 0;
 
 	/* set speed-dependent max packet; may kick in high bandwidth */
 	set_idx_reg (dev->regs, REG_EP_MAXPKT (dev, ep->num), max);
@@ -169,8 +179,8 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
 	/* FIFO lines can't go to different packets.  PIO is ok, so
 	 * use it instead of troublesome (non-bulk) multi-packet DMA.
 	 */
-	if (ep->is_in && ep->dma && (max % 4) != 0) {
-		DEBUG (ep->dev, "%s, no IN dma for maxpacket %d\n",
+	if (ep->dma && (max % 4) != 0 && use_dma_chaining) {
+		DEBUG (ep->dev, "%s, no dma for maxpacket %d\n",
 			ep->ep.name, ep->ep.maxpacket);
 		ep->dma = 0;
 	}
@@ -179,17 +189,21 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
 	writel ((1 << FIFO_FLUSH), &ep->regs->ep_stat);
 	tmp = (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
 	if (tmp == USB_ENDPOINT_XFER_INT) {
-		/* not just because of erratum 0105; avoid ever
-		 * kicking in the "toggle-irrelevant" mode.
-		 */
-		tmp = USB_ENDPOINT_XFER_BULK;
+		/* erratum 0105 workaround prevents hs NYET */
+		if (dev->chiprev == 0100
+				&& dev->gadget.speed == USB_SPEED_HIGH
+				&& !(desc->bEndpointAddress & USB_DIR_IN))
+			writel ((1 << CLEAR_NAK_OUT_PACKETS_MODE),
+				&ep->regs->ep_rsp);
 	} else if (tmp == USB_ENDPOINT_XFER_BULK) {
 		/* catch some particularly blatant driver bugs */
 		if ((dev->gadget.speed == USB_SPEED_HIGH
 					&& max != 512)
 				|| (dev->gadget.speed == USB_SPEED_FULL
-					&& max > 64))
+					&& max > 64)) {
+			spin_unlock_irqrestore (&dev->lock, flags);
 			return -ERANGE;
+		}
 	}
 	ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC) ? 1 : 0;
 	tmp <<= ENDPOINT_TYPE;
@@ -205,11 +219,6 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
 
 	writel (tmp, &ep->regs->ep_cfg);
 
-#ifdef NET2280_DMA_OUT_WORKAROUND
-	if (!ep->is_in)
-		ep->dma = 0;
-#endif
-
 	/* enable irqs */
 	if (!ep->dma) {				/* pio, per-packet */
 		tmp = (1 << ep->num) | readl (&dev->regs->pciirqenb0);
@@ -388,6 +397,7 @@ net2280_alloc_request (struct usb_ep *_ep, int gfp_flags)
 		}
 		td->dmacount = 0;	/* not VALID */
 		td->dmaaddr = __constant_cpu_to_le32 (DMA_ADDR_INVALID);
+		td->dmadesc = td->dmaaddr;
 		req->td = td;
 	}
 	return &req->req;
@@ -541,8 +551,11 @@ write_fifo (struct net2280_ep *ep, struct usb_request *req)
 		count -= 4;
 	}
 
-	/* last fifo entry is "short" unless we wrote a full packet */
-	if (total < ep->ep.maxpacket) {
+	/* last fifo entry is "short" unless we wrote a full packet.
+	 * also explicitly validate last word in (periodic) transfers
+	 * when maxpacket is not a multiple of 4 bytes.
+	 */
+	if (count || total < ep->ep.maxpacket) {
 		tmp = count ? get_unaligned ((u32 *)buf) : count;
 		cpu_to_le32s (&tmp);
 		set_fifo_bytecount (ep, count & 0x03);
@@ -555,6 +568,9 @@ write_fifo (struct net2280_ep *ep, struct usb_request *req)
 /* work around erratum 0106: PCI and USB race over the OUT fifo.
  * caller guarantees chiprev 0100, out endpoint is NAKing, and
  * there's no real data in the fifo.
+ *
+ * NOTE:  also used in cases where that erratum doesn't apply:
+ * where the host wrote "too much" data to us.
  */
 static void out_flush (struct net2280_ep *ep)
 {
@@ -599,13 +615,13 @@ read_fifo (struct net2280_ep *ep, struct net2280_request *req)
 	/* erratum 0106 ... packets coming in during fifo reads might
 	 * be incompletely rejected.  not all cases have workarounds.
 	 */
-	if (ep->dev->chiprev == 0x0100) {
+	if (ep->dev->chiprev == 0x0100
+			&& ep->dev->gadget.speed == USB_SPEED_FULL) {
+		udelay (1);
 		tmp = readl (&ep->regs->ep_stat);
 		if ((tmp & (1 << NAK_OUT_PACKETS)))
-			/* cleanup = 1 */;
-		else if ((tmp & (1 << FIFO_FULL))
-				/* don't break hs PING protocol ... */
-				|| ep->dev->gadget.speed == USB_SPEED_FULL) {
+			cleanup = 1;
+		else if ((tmp & (1 << FIFO_FULL))) {
 			start_out_naking (ep);
 			prevent = 1;
 		}
@@ -617,6 +633,15 @@ read_fifo (struct net2280_ep *ep, struct net2280_request *req)
 	 */
 	prefetchw (buf);
 	count = readl (&regs->ep_avail);
+	if (unlikely (count == 0)) {
+		udelay (1);
+		tmp = readl (&ep->regs->ep_stat);
+		count = readl (&regs->ep_avail);
+		/* handled that data already? */
+		if (count == 0 && (tmp & (1 << NAK_OUT_PACKETS)) == 0)
+			return 0;
+	}
+
 	tmp = req->req.length - req->req.actual;
 	if (count > tmp) {
 		/* as with DMA, data overflow gets flushed */
@@ -626,7 +651,10 @@ read_fifo (struct net2280_ep *ep, struct net2280_request *req)
 				ep->ep.name, count, tmp);
 			req->req.status = -EOVERFLOW;
 			cleanup = 1;
-		}
+			/* NAK_OUT_PACKETS will be set, so flushing is safe;
+			 * the next read will start with the next packet
+			 */
+		} /* else it's a ZLP, no worries */
 		count = tmp;
 	}
 	req->req.actual += count;
@@ -665,7 +693,7 @@ read_fifo (struct net2280_ep *ep, struct net2280_request *req)
 }
 
 /* fill out dma descriptor to match a given request */
-static inline void
+static void
 fill_dma_desc (struct net2280_ep *ep, struct net2280_request *req, int valid)
 {
 	struct net2280_dma	*td = req->td;
@@ -678,15 +706,13 @@ fill_dma_desc (struct net2280_ep *ep, struct net2280_request *req, int valid)
 	 */
 	if (ep->is_in)
 		dmacount |= (1 << DMA_DIRECTION);
-	else
+	else if ((dmacount % ep->ep.maxpacket) != 0)
 		dmacount |= (1 << END_OF_CHAIN);
 
 	req->valid = valid;
 	if (valid)
 		dmacount |= (1 << VALID_BIT);
-#ifdef USE_DMA_CHAINING
-	if (!req->req.no_interrupt)
-#endif
+	if (likely(!req->req.no_interrupt || !use_dma_chaining))
 		dmacount |= (1 << DMA_DONE_INTERRUPT_ENABLE);
 
 	/* td->dmadesc = previously set by caller */
@@ -698,7 +724,8 @@ fill_dma_desc (struct net2280_ep *ep, struct net2280_request *req, int valid)
 }
 
 static const u32 dmactl_default =
-		  (1 << DMA_CLEAR_COUNT_ENABLE)
+		  (1 << DMA_SCATTER_GATHER_DONE_INTERRUPT)
+		| (1 << DMA_CLEAR_COUNT_ENABLE)
 		/* erratum 0116 workaround part 1 (use POLLING) */
 		| (POLL_100_USEC << DESCRIPTOR_POLLING_RATE)
 		| (1 << DMA_VALID_BIT_POLLING_ENABLE)
@@ -714,18 +741,41 @@ static inline void spin_stop_dma (struct net2280_dma_regs *dma)
 
 static inline void stop_dma (struct net2280_dma_regs *dma)
 {
-	writel (dmactl_default & ~(1 << DMA_ENABLE), &dma->dmactl);
+	writel (readl (&dma->dmactl) & ~(1 << DMA_ENABLE), &dma->dmactl);
 	spin_stop_dma (dma);
 }
 
+static void start_queue (struct net2280_ep *ep, u32 dmactl, u32 td_dma)
+{
+	struct net2280_dma_regs	*dma = ep->dma;
+
+	writel ((1 << VALID_BIT) | (ep->is_in << DMA_DIRECTION),
+			&dma->dmacount);
+	writel (readl (&dma->dmastat), &dma->dmastat);
+
+	writel (td_dma, &dma->dmadesc);
+	writel (dmactl, &dma->dmactl);
+
+	/* erratum 0116 workaround part 3:  pci arbiter away from net2280 */
+	(void) readl (&ep->dev->pci->pcimstctl);
+
+	writel ((1 << DMA_START), &dma->dmastat);
+
+	if (!ep->is_in)
+		stop_out_naking (ep);
+}
+
 static void start_dma (struct net2280_ep *ep, struct net2280_request *req)
 {
 	u32			tmp;
-	int			clear_nak = 0;
 	struct net2280_dma_regs	*dma = ep->dma;
 
 	/* FIXME can't use DMA for ZLPs */
 
+	/* on this path we "know" there's no dma active (yet) */
+	WARN_ON (readl (&dma->dmactl) & (1 << DMA_ENABLE));
+	writel (0, &ep->dma->dmactl);
+
 	/* previous OUT packet might have been short */
 	if (!ep->is_in && ((tmp = readl (&ep->regs->ep_stat))
 		 		& (1 << NAK_OUT_PACKETS)) != 0) {
@@ -733,9 +783,9 @@ static void start_dma (struct net2280_ep *ep, struct net2280_request *req)
 			&ep->regs->ep_stat);
 
 		tmp = readl (&ep->regs->ep_avail);
-		if (tmp == 0)
-			clear_nak = 1;
-		else {
+		if (tmp) {
+			writel (readl (&dma->dmastat), &dma->dmastat);
+
 			/* transfer all/some fifo data */
 			writel (req->req.dma, &dma->dmaaddr);
 			tmp = min (tmp, req->req.length);
@@ -744,6 +794,8 @@ static void start_dma (struct net2280_ep *ep, struct net2280_request *req)
 			req->td->dmacount = cpu_to_le32 (req->req.length - tmp);
 			writel ((1 << DMA_DONE_INTERRUPT_ENABLE)
 				| tmp, &dma->dmacount);
+			req->td->dmadesc = 0;
+			req->valid = 1;
 
 			writel ((1 << DMA_ENABLE), &dma->dmactl);
 			writel ((1 << DMA_START), &dma->dmastat);
@@ -751,8 +803,6 @@ static void start_dma (struct net2280_ep *ep, struct net2280_request *req)
 		}
 	}
 
-	/* on this path we know there's no dma queue (yet) */
-	WARN_ON (readl (&dma->dmactl) & (1 << DMA_ENABLE));
 	tmp = dmactl_default;
 
 	/* force packet boundaries between dma requests, but prevent the
@@ -772,25 +822,10 @@ static void start_dma (struct net2280_ep *ep, struct net2280_request *req)
 	req->td->dmadesc = cpu_to_le32 (ep->td_dma);
 	fill_dma_desc (ep, req, 1);
 
-#ifdef USE_DMA_CHAINING
-	writel (  (1 << VALID_BIT)
-		| (ep->is_in << DMA_DIRECTION)
-		| 0, &dma->dmacount);
-#else
-	req->td->dmacount |= __constant_cpu_to_le32 (1 << END_OF_CHAIN);
-#endif
-
-	writel (req->td_dma, &dma->dmadesc);
-	writel (tmp, &dma->dmactl);
+	if (!use_dma_chaining)
+		req->td->dmacount |= __constant_cpu_to_le32 (1 << END_OF_CHAIN);
 
-	/* erratum 0116 workaround part 3:  pci arbiter away from net2280 */
-	(void) readl (&ep->dev->pci->pcimstctl);
-
-	writel ((1 << DMA_START), &dma->dmastat);
-
-	/* recover from previous short read; erratum 0112 workaround #1 */
-	if (clear_nak)
-		writel ((1 << CLEAR_NAK_OUT_PACKETS), &ep->regs->ep_rsp);
+	start_queue (ep, tmp, req->td_dma);
 }
 
 static inline void
@@ -893,7 +928,6 @@ net2280_queue (struct usb_ep *_ep, struct usb_request *_req, int gfp_flags)
 
 	_req->status = -EINPROGRESS;
 	_req->actual = 0;
-	req->dma_done = 0;
 
 	/* kickstart this i/o queue? */
 	if (list_empty (&ep->queue) && !ep->stopped) {
@@ -977,10 +1011,11 @@ dma_done (
 )
 {
 	req->req.actual = req->req.length - (DMA_BYTE_COUNT_MASK & dmacount);
-	rmb ();
 	done (ep, req, status);
 }
 
+static void restart_dma (struct net2280_ep *ep);
+
 static void scan_dma_completions (struct net2280_ep *ep)
 {
 	/* only look at descriptors that were "naturally" retired,
@@ -1000,14 +1035,37 @@ static void scan_dma_completions (struct net2280_ep *ep)
 			break;
 
 		/* SHORT_PACKET_TRANSFERRED_INTERRUPT handles "usb-short"
-		 * packets, including overruns, even when the transfer was
-		 * exactly the length requested (dmacount now zero).
-		 * FIXME there's an overrun case here too, where we expect
-		 * a short packet but receive a max length one (won't NAK).
+		 * cases where DMA must be aborted; this code handles
+		 * all non-abort DMA completions.
 		 */
-		if (!ep->is_in && (req->req.length % ep->ep.maxpacket) != 0) {
-			req->dma_done = 1;
+		if (unlikely (req->td->dmadesc == 0)) {
+			/* paranoia */
+			tmp = readl (&ep->dma->dmacount);
+			if (tmp & DMA_BYTE_COUNT_MASK)
+				break;
+			/* single transfer mode */
+			dma_done (ep, req, tmp, 0);
 			break;
+		} else if (!ep->is_in
+				&& (req->req.length % ep->ep.maxpacket) != 0) {
+			tmp = readl (&ep->regs->ep_stat);
+
+			/* AVOID TROUBLE HERE by not issuing short reads from
+			 * your gadget driver.  That helps avoids errata 0121,
+			 * 0122, and 0124; not all cases trigger the warning.
+			 */
+			if ((tmp & (1 << NAK_OUT_PACKETS)) == 0) {
+				WARN (ep->dev, "%s lost packet sync!\n",
+						ep->ep.name);
+				req->req.status = -EOVERFLOW;
+			} else if ((tmp = readl (&ep->regs->ep_avail)) != 0) {
+				/* fifo gets flushed later */
+				ep->out_overflow = 1;
+				DEBUG (ep->dev, "%s dma, discard %d len %d\n",
+						ep->ep.name, tmp,
+						req->req.length);
+				req->req.status = -EOVERFLOW;
+			}
 		}
 		dma_done (ep, req, tmp, 0);
 	}
@@ -1016,41 +1074,50 @@ static void scan_dma_completions (struct net2280_ep *ep)
 static void restart_dma (struct net2280_ep *ep)
 {
 	struct net2280_request	*req;
+	u32			dmactl = dmactl_default;
 
 	if (ep->stopped)
 		return;
 	req = list_entry (ep->queue.next, struct net2280_request, queue);
 
-#ifdef USE_DMA_CHAINING
+	if (!use_dma_chaining) {
+		start_dma (ep, req);
+		return;
+	}
+
 	/* the 2280 will be processing the queue unless queue hiccups after
 	 * the previous transfer:
 	 *  IN:   wanted automagic zlp, head doesn't (or vice versa)
+	 *        DMA_FIFO_VALIDATE doesn't init from dma descriptors.
 	 *  OUT:  was "usb-short", we must restart.
 	 */
-	if (!req->valid) {
+	if (ep->is_in && !req->valid) {
 		struct net2280_request	*entry, *prev = 0;
-		int			qmode, reqmode, done = 0;
+		int			reqmode, done = 0;
 
 		DEBUG (ep->dev, "%s dma hiccup td %p\n", ep->ep.name, req->td);
-		qmode = likely (req->req.zero
+		ep->in_fifo_validate = likely (req->req.zero
 			|| (req->req.length % ep->ep.maxpacket) != 0);
+		if (ep->in_fifo_validate)
+			dmactl |= (1 << DMA_FIFO_VALIDATE);
 		list_for_each_entry (entry, &ep->queue, queue) {
 			u32		dmacount;
 
-			if (entry != req)
+			if (entry == req)
 				continue;
 			dmacount = entry->td->dmacount;
 			if (!done) {
 				reqmode = likely (entry->req.zero
 					|| (entry->req.length
 						% ep->ep.maxpacket) != 0);
-				if (reqmode == qmode) {
+				if (reqmode == ep->in_fifo_validate) {
 					entry->valid = 1;
 					dmacount |= valid_bit;
 					entry->td->dmacount = dmacount;
 					prev = entry;
 					continue;
 				} else {
+					/* force a hiccup */
 					prev->td->dmacount |= dma_done_ie;
 					done = 1;
 				}
@@ -1062,22 +1129,21 @@ static void restart_dma (struct net2280_ep *ep)
 			entry->td->dmacount = dmacount;
 			prev = entry;
 		}
-		start_dma (ep, req);
-	} else if (!ep->is_in
-			&& (readl (&ep->regs->ep_stat)
-				& (1 << NAK_OUT_PACKETS)) != 0)
-		start_dma (ep, req);
-#else
-	start_dma (ep, req);
-#endif
+	}
+
+	writel (0, &ep->dma->dmactl);
+	start_queue (ep, dmactl, req->td_dma);
 }
 
-static inline void abort_dma (struct net2280_ep *ep)
+static void abort_dma (struct net2280_ep *ep)
 {
 	/* abort the current transfer */
-	writel ((1 << DMA_ABORT), &ep->dma->dmastat);
-
-	/* collect completed transfers (except the current one) */
+	if (likely (!list_empty (&ep->queue))) {
+		/* FIXME work around errata 0121, 0122, 0124 */
+		writel ((1 << DMA_ABORT), &ep->dma->dmastat);
+		spin_stop_dma (ep->dma);
+	} else
+		stop_dma (ep->dma);
 	scan_dma_completions (ep);
 }
 
@@ -1108,43 +1174,53 @@ static int net2280_dequeue (struct usb_ep *_ep, struct usb_request *_req)
 	int			stopped;
 
 	ep = container_of (_ep, struct net2280_ep, ep);
-	req = container_of (_req, struct net2280_request, req);
 	if (!_ep || (!ep->desc && ep->num != 0) || !_req)
 		return -EINVAL;
 
 	spin_lock_irqsave (&ep->dev->lock, flags);
 	stopped = ep->stopped;
 
-	/* pause dma while we scan the queue */
+	/* quiesce dma while we patch the queue */
 	dmactl = 0;
 	ep->stopped = 1;
 	if (ep->dma) {
 		dmactl = readl (&ep->dma->dmactl);
-		writel (dmactl & ~(1 << DMA_ENABLE), &ep->dma->dmactl);
-		/* force synch, clean any completed requests */
-		spin_stop_dma (ep->dma);
+		/* WARNING erratum 0127 may kick in ... */
+		stop_dma (ep->dma);
 		scan_dma_completions (ep);
 	}
 
+	/* make sure it's still queued on this endpoint */
+	list_for_each_entry (req, &ep->queue, queue) {
+		if (&req->req == _req)
+			break;
+	}
+	if (&req->req != _req) {
+		spin_unlock_irqrestore (&ep->dev->lock, flags);
+		return -EINVAL;
+	}
+
 	/* queue head may be partially complete. */
 	if (ep->queue.next == &req->queue) {
 		if (ep->dma) {
 			DEBUG (ep->dev, "unlink (%s) dma\n", _ep->name);
 			_req->status = -ECONNRESET;
 			abort_dma (ep);
-			if (likely (ep->queue.next == &req->queue))
+			if (likely (ep->queue.next == &req->queue)) {
+				// NOTE: misreports single-transfer mode
+				req->td->dmacount = 0;	/* invalidate */
 				dma_done (ep, req,
-					le32_to_cpup (&req->td->dmacount),
+					readl (&ep->dma->dmacount),
 					-ECONNRESET);
+			}
 		} else {
 			DEBUG (ep->dev, "unlink (%s) pio\n", _ep->name);
 			done (ep, req, -ECONNRESET);
 		}
 		req = 0;
 
-#ifdef USE_DMA_CHAINING
 	/* patch up hardware chaining data */
-	} else if (ep->dma) {
+	} else if (ep->dma && use_dma_chaining) {
 		if (req->queue.prev == ep->queue.next) {
 			writel (le32_to_cpu (req->td->dmadesc),
 				&ep->dma->dmadesc);
@@ -1161,7 +1237,6 @@ static int net2280_dequeue (struct usb_ep *_ep, struct usb_request *_req)
 			if (req->td->dmacount & dma_done_ie)
 				prev->td->dmacount |= dma_done_ie;
 		}
-#endif
 	}
 
 	if (req)
@@ -1188,10 +1263,14 @@ static int net2280_dequeue (struct usb_ep *_ep, struct usb_request *_req)
 
 /*-------------------------------------------------------------------------*/
 
+static int net2280_fifo_status (struct usb_ep *_ep);
+
 static int
 net2280_set_halt (struct usb_ep *_ep, int value)
 {
 	struct net2280_ep	*ep;
+	unsigned long		flags;
+	int			retval = 0;
 
 	ep = container_of (_ep, struct net2280_ep, ep);
 	if (!_ep || (!ep->desc && ep->num != 0))
@@ -1202,19 +1281,27 @@ net2280_set_halt (struct usb_ep *_ep, int value)
 						== USB_ENDPOINT_XFER_ISOC)
 		return -EINVAL;
 
-	VDEBUG (ep->dev, "%s %s halt\n", _ep->name, value ? "set" : "clear");
-
-	/* set/clear, then synch memory views with the device */
-	if (value) {
-		if (ep->num == 0)
-			ep->dev->protocol_stall = 1;
-		else
-			set_halt (ep);
-	} else
-		clear_halt (ep);
-	(void) readl (&ep->regs->ep_rsp);
+	spin_lock_irqsave (&ep->dev->lock, flags);
+	if (!list_empty (&ep->queue))
+		retval = -EAGAIN;
+	else if (ep->is_in && value && net2280_fifo_status (_ep) != 0)
+		retval = -EAGAIN;
+	else {
+		VDEBUG (ep->dev, "%s %s halt\n", _ep->name,
+				value ? "set" : "clear");
+		/* set/clear, then synch memory views with the device */
+		if (value) {
+			if (ep->num == 0)
+				ep->dev->protocol_stall = 1;
+			else
+				set_halt (ep);
+		} else
+			clear_halt (ep);
+		(void) readl (&ep->regs->ep_rsp);
+	}
+	spin_unlock_irqrestore (&ep->dev->lock, flags);
 
-	return 0;
+	return retval;
 }
 
 static int
@@ -1290,21 +1377,49 @@ static int net2280_get_frame (struct usb_gadget *_gadget)
 static int net2280_wakeup (struct usb_gadget *_gadget)
 {
 	struct net2280		*dev;
+	u32			tmp;
+	unsigned long		flags;
 
 	if (!_gadget)
 		return 0;
 	dev = container_of (_gadget, struct net2280, gadget);
-	writel (1 << GENERATE_RESUME, &dev->usb->usbstat);
+
+	spin_lock_irqsave (&dev->lock, flags);
+	tmp = readl (&dev->usb->usbctl);
+	if (tmp & (1 << DEVICE_REMOTE_WAKEUP_ENABLE))
+		writel (1 << GENERATE_RESUME, &dev->usb->usbstat);
+	spin_unlock_irqrestore (&dev->lock, flags);
 
 	/* pci writes may still be posted */
 	return 0;
 }
 
+static int net2280_set_selfpowered (struct usb_gadget *_gadget, int value)
+{
+	struct net2280		*dev;
+	u32			tmp;
+	unsigned long		flags;
+
+	if (!_gadget)
+		return 0;
+	dev = container_of (_gadget, struct net2280, gadget);
+
+	spin_lock_irqsave (&dev->lock, flags);
+	tmp = readl (&dev->usb->usbctl);
+	if (value)
+		tmp |= (1 << SELF_POWERED_STATUS);
+	else
+		tmp &= ~(1 << SELF_POWERED_STATUS);
+	writel (tmp, &dev->usb->usbctl);
+	spin_unlock_irqrestore (&dev->lock, flags);
+
+	return 0;
+}
+
 static const struct usb_gadget_ops net2280_ops = {
 	.get_frame	= net2280_get_frame,
 	.wakeup		= net2280_wakeup,
-
-	// .set_selfpowered = net2280_set_selfpowered,
+	.set_selfpowered = net2280_set_selfpowered,
 };
 
 /*-------------------------------------------------------------------------*/
@@ -1348,11 +1463,14 @@ show_registers (struct device *_dev, char *buf)
 
 	/* Main Control Registers */
 	t = snprintf (next, size, "%s version " DRIVER_VERSION
-			", chiprev %04x\n"
+			", chiprev %04x, dma %s\n\n"
 			"devinit %03x fifoctl %08x gadget '%s'\n"
 			"pci irqenb0 %02x irqenb1 %08x "
 			"irqstat0 %04x irqstat1 %08x\n",
 			driver_name, dev->chiprev,
+			use_dma
+				? (use_dma_chaining ? "chaining" : "enabled")
+				: "disabled",
 			readl (&dev->regs->devinit),
 			readl (&dev->regs->fifoctl),
 			s,
@@ -1399,7 +1517,7 @@ show_registers (struct device *_dev, char *buf)
 		t1 = readl (&ep->regs->ep_cfg);
 		t2 = readl (&ep->regs->ep_rsp) & 0xff;
 		t = snprintf (next, size,
-				"%s\tcfg %05x rsp (%02x) %s%s%s%s%s%s%s%s"
+				"\n%s\tcfg %05x rsp (%02x) %s%s%s%s%s%s%s%s"
 					"irqenb %02x\n",
 				ep->ep.name, t1, t2,
 				(t2 & (1 << CLEAR_NAK_OUT_PACKETS))
@@ -1453,7 +1571,7 @@ show_registers (struct device *_dev, char *buf)
 		// none yet 
 
 	/* Statistics */
-	t = snprintf (next, size, "irqs:  ");
+	t = snprintf (next, size, "\nirqs:  ");
 	size -= t;
 	next += t;
 	for (i = 0; i < 7; i++) {
@@ -1462,7 +1580,7 @@ show_registers (struct device *_dev, char *buf)
 		ep = &dev->ep [i];
 		if (i && !ep->irqs)
 			continue;
-		t = snprintf (next, size, " %s/%ld", ep->ep.name, ep->irqs);
+		t = snprintf (next, size, " %s/%lu", ep->ep.name, ep->irqs);
 		size -= t;
 		next += t;
 
@@ -1504,7 +1622,7 @@ show_queues (struct device *_dev, char *buf)
 				continue;
 			t = d->bEndpointAddress;
 			t = snprintf (next, size,
-				"%s (ep%d%s-%s) max %04x %s\n",
+				"\n%s (ep%d%s-%s) max %04x %s fifo %d\n",
 				ep->ep.name, t & USB_ENDPOINT_NUMBER_MASK,
 				(t & USB_DIR_IN) ? "in" : "out",
 				({ char *val;
@@ -1517,7 +1635,7 @@ show_queues (struct device *_dev, char *buf)
 				 	val = "iso"; break;
 				 }; val; }),
 				le16_to_cpu (d->wMaxPacketSize) & 0x1fff,
-				ep->dma ? "dma" : "pio"
+				ep->dma ? "dma" : "pio", ep->fifo_size
 				);
 		} else /* ep0 should only have one transfer queued */
 			t = snprintf (next, size, "ep0 max 64 pio %s\n",
@@ -1552,6 +1670,20 @@ show_queues (struct device *_dev, char *buf)
 				goto done;
 			size -= t;
 			next += t;
+
+			if (ep->dma) {
+				struct net2280_dma	*td;
+
+				td = req->td;
+				t = snprintf (next, size, "\t    td %08x "
+					" count %08x buf %08x desc %08x\n",
+					req->td_dma, td->dmacount,
+					td->dmaaddr, td->dmadesc);
+				if (t <= 0 || t > size)
+					goto done;
+				size -= t;
+				next += t;
+			}
 		}
 	}
 
@@ -1686,8 +1818,10 @@ static void usb_reset (struct net2280 *dev)
 
 	/* clear old dma and irq state */
 	for (tmp = 0; tmp < 4; tmp++) {
-		writel ((1 << DMA_ABORT), &dev->dma [tmp].dmastat);
-		stop_dma (&dev->dma [tmp]);
+		struct net2280_ep	*ep = &dev->ep [tmp + 1];
+
+		if (ep->dma)
+			abort_dma (ep);
 	}
 	writel (~0, &dev->regs->irqstat0),
 	writel (~(1 << SUSPEND_REQUEST_INTERRUPT), &dev->regs->irqstat1),
@@ -1767,7 +1901,7 @@ static void ep0_start (struct net2280 *dev)
 		| (1 << SELF_POWERED_USB_DEVICE)
 		| (1 << REMOTE_WAKEUP_SUPPORT)
 		| (1 << USB_DETECT_ENABLE)
-		| (1 << DEVICE_REMOTE_WAKEUP_ENABLE)
+		| (1 << SELF_POWERED_STATUS)
 		, &dev->usb->usbctl);
 
 	/* enable irqs so we can see ep0 and general operation  */
@@ -1889,6 +2023,7 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
 	spin_unlock_irqrestore (&dev->lock, flags);
 
 	driver->unbind (&dev->gadget);
+	dev->gadget.dev.driver = 0;
 	dev->driver = 0;
 
 	net2280_led_active (dev, 0);
@@ -1947,6 +2082,8 @@ static void handle_ep_small (struct net2280_ep *ep)
 					ep->stopped = 1;
 					set_halt (ep);
 				}
+				if (!req)
+					allow_status (ep);
 				mode = 2;
 			/* reply to extra IN data tokens with a zlp */
 			} else if (t & (1 << DATA_IN_TOKEN_INTERRUPT)) {
@@ -1987,41 +2124,62 @@ static void handle_ep_small (struct net2280_ep *ep)
 	if (likely (ep->dma != 0)) {
 		if (t & (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT)) {
 			u32	count;
+			int	stopped = ep->stopped;
 
 			/* TRANSFERRED works around OUT_DONE erratum 0112.
 			 * we expect (N <= maxpacket) bytes; host wrote M.
 			 * iff (M < N) we won't ever see a DMA interrupt.
 			 */
-			count = readl (&ep->dma->dmacount);
-			count &= DMA_BYTE_COUNT_MASK;
-			if (!req->dma_done) {
-				/* dma can finish with the FIFO non-empty,
-				 * on (M > N) errors.
+			ep->stopped = 1;
+			for (count = 0; ; t = readl (&ep->regs->ep_stat)) {
+
+				/* any preceding dma transfers must finish.
+				 * dma handles (M >= N), may empty the queue
+				 */
+				scan_dma_completions (ep);
+				if (unlikely (list_empty (&ep->queue)
+						|| ep->out_overflow)) {
+					req = 0;
+					break;
+				}
+				req = list_entry (ep->queue.next,
+					struct net2280_request, queue);
+
+				/* here either (M < N), a "real" short rx;
+				 * or (M == N) and the queue didn't empty
 				 */
-				while (count && (t & (1 << FIFO_EMPTY)) == 0) {
-					cpu_relax ();
-					t = readl (&ep->regs->ep_stat);
+				if (likely (t & (1 << FIFO_EMPTY))) {
 					count = readl (&ep->dma->dmacount);
 					count &= DMA_BYTE_COUNT_MASK;
+					if (readl (&ep->dma->dmadesc)
+							!= req->td_dma)
+						req = 0;
+					break;
 				}
+				udelay(1);
 			}
 
 			/* stop DMA, leave ep NAKing */
 			writel ((1 << DMA_ABORT), &ep->dma->dmastat);
 			spin_stop_dma (ep->dma);
 
-			/* buffer might have been too small */
-			t = readl (&ep->regs->ep_avail);
-			if (t != 0)
-				DEBUG (ep->dev, "%s dma, discard %d len %d\n",
-						ep->ep.name, t, count);
-			dma_done (ep, req, count, t ? -EOVERFLOW : 0);
+			if (likely (req)) {
+				req->td->dmacount = 0;
+				t = readl (&ep->regs->ep_avail);
+				dma_done (ep, req, count, t);
+			}
 
 			/* also flush to prevent erratum 0106 trouble */
-			if (t || ep->dev->chiprev == 0x0100)
+			if (unlikely (ep->out_overflow
+					|| (ep->dev->chiprev == 0x0100
+						&& ep->dev->gadget.speed
+							== USB_SPEED_FULL))) {
 				out_flush (ep);
+				ep->out_overflow = 0;
+			}
 
-			/* restart dma (still NAKing OUT!) if needed */
+			/* (re)start dma if needed, stop NAKing */
+			ep->stopped = stopped;
 			if (!list_empty (&ep->queue))
 				restart_dma (ep);
 		} else
@@ -2192,11 +2350,12 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
 		 * that'll mean a lot less irqs for some drivers.
 		 */
 		ep->is_in = (u.r.bRequestType & USB_DIR_IN) != 0;
-		if (ep->is_in)
+		if (ep->is_in) {
 			scratch = (1 << DATA_PACKET_TRANSMITTED_INTERRUPT)
 				| (1 << DATA_OUT_PING_TOKEN_INTERRUPT)
 				| (1 << DATA_IN_TOKEN_INTERRUPT);
-		else
+			stop_out_naking (ep);
+		} else
 			scratch = (1 << DATA_PACKET_RECEIVED_INTERRUPT)
 				| (1 << DATA_OUT_PING_TOKEN_INTERRUPT)
 				| (1 << DATA_IN_TOKEN_INTERRUPT);
@@ -2398,18 +2557,18 @@ static void handle_stat1_irqs (struct net2280 *dev, u32 stat)
 		tmp = readl (&dma->dmastat);
 		writel (tmp, &dma->dmastat);
 
-#ifdef USE_DMA_CHAINING
-		/* chaining should stop only on error (which?)
+		/* chaining should stop on abort, short OUT from fifo,
 		 * or (stat0 codepath) short OUT transfer.
 		 */
-#else
-		if ((tmp & (1 << DMA_TRANSACTION_DONE_INTERRUPT)) == 0) {
-			DEBUG (ep->dev, "%s no xact done? %08x\n",
-				ep->ep.name, tmp);
-			continue;
+		if (!use_dma_chaining) {
+			if ((tmp & (1 << DMA_TRANSACTION_DONE_INTERRUPT))
+					== 0) {
+				DEBUG (ep->dev, "%s no xact done? %08x\n",
+					ep->ep.name, tmp);
+				continue;
+			}
+			stop_dma (ep->dma);
 		}
-		stop_dma (ep->dma);
-#endif
 
 		/* OUT transfers terminate when the data from the
 		 * host is in our memory.  Process whatever's done.
@@ -2425,16 +2584,14 @@ static void handle_stat1_irqs (struct net2280 *dev, u32 stat)
 
 		/* disable dma on inactive queues; else maybe restart */
 		if (list_empty (&ep->queue)) {
-#ifdef USE_DMA_CHAINING
-			stop_dma (ep->dma);
-#endif
+			if (use_dma_chaining)
+				stop_dma (ep->dma);
 		} else {
 			tmp = readl (&dma->dmactl);
-			if ((tmp & (1 << DMA_SCATTER_GATHER_ENABLE)) == 0
+			if (!use_dma_chaining
 					|| (tmp & (1 << DMA_ENABLE)) == 0)
 				restart_dma (ep);
-#ifdef USE_DMA_CHAINING
-			else if (ep->desc->bEndpointAddress & USB_DIR_IN) {
+			else if (ep->is_in && use_dma_chaining) {
 				struct net2280_request	*req;
 				u32			dmacount;
 
@@ -2449,12 +2606,9 @@ static void handle_stat1_irqs (struct net2280 *dev, u32 stat)
 				dmacount &= __constant_cpu_to_le32 (
 						(1 << VALID_BIT)
 						| DMA_BYTE_COUNT_MASK);
-				if (dmacount && (dmacount & valid_bit) == 0) {
-					stop_dma (ep->dma);
+				if (dmacount && (dmacount & valid_bit) == 0)
 					restart_dma (ep);
-				}
 			}
-#endif
 		}
 		ep->irqs++;
 	}
@@ -2505,7 +2659,7 @@ static void gadget_release (struct device *_dev)
 
 /* tear down the binding between this driver and the pci device */
 
-static void net2280_remove (struct pci_dev *pdev)
+static void __exit net2280_remove (struct pci_dev *pdev)
 {
 	struct net2280		*dev = pci_get_drvdata (pdev);
 
@@ -2665,12 +2819,14 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
 		}
 		td->dmacount = 0;	/* not VALID */
 		td->dmaaddr = __constant_cpu_to_le32 (DMA_ADDR_INVALID);
+		td->dmadesc = td->dmaaddr;
 		dev->ep [i].dummy = td;
 	}
 
 	/* enable lower-overhead pci memory bursts during DMA */
-	writel ((1 << PCI_RETRY_ABORT_ENABLE)
-			| (1 << DMA_MEMORY_WRITE_AND_INVALIDATE_ENABLE)
+	writel ( (1 << DMA_MEMORY_WRITE_AND_INVALIDATE_ENABLE)
+			// 256 write retries may not be enough...
+			// | (1 << PCI_RETRY_ABORT_ENABLE)
 			| (1 << DMA_READ_MULTIPLE_ENABLE)
 			| (1 << DMA_READ_LINE_ENABLE)
 			, &dev->pci->pcimstctl);
@@ -2686,15 +2842,10 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
 	INFO (dev, "%s\n", driver_desc);
 	INFO (dev, "irq %s, pci mem %p, chip rev %04x\n",
 			bufp, base, dev->chiprev);
-	bufp = DRIVER_VERSION
-#ifndef USE_DMA_CHAINING
-		" (no dma chain)"
-#endif
-#ifdef NET2280_DMA_OUT_WORKAROUND
-		" (no dma out)"
-#endif
-		;
-	INFO (dev, "version: %s\n", bufp);
+	INFO (dev, "version: " DRIVER_VERSION "; dma %s\n",
+			use_dma
+				? (use_dma_chaining ? "chaining" : "enabled")
+				: "disabled");
 	the_controller = dev;
 
 	device_register (&dev->gadget.dev);
@@ -2729,7 +2880,7 @@ static struct pci_driver net2280_pci_driver = {
 	.id_table =	pci_ids,
 
 	.probe =	net2280_probe,
-	.remove =	net2280_remove,
+	.remove =	__exit_p(net2280_remove),
 
 	/* FIXME add power management support */
 };
@@ -2740,6 +2891,8 @@ MODULE_LICENSE ("GPL");
 
 static int __init init (void)
 {
+	if (!use_dma)
+		use_dma_chaining = 0;
 	return pci_module_init (&net2280_pci_driver);
 }
 module_init (init);
diff --git a/drivers/usb/gadget/net2280.h b/drivers/usb/gadget/net2280.h
index d6af2e86bdf86cad2277e3f30eff725feb1653be..ec9d6f7e7cfcd90503dbd1223d1c4fb1a029141b 100644
--- a/drivers/usb/gadget/net2280.h
+++ b/drivers/usb/gadget/net2280.h
@@ -520,6 +520,7 @@ struct net2280_ep {
 	unsigned				num : 8,
 						fifo_size : 12,
 						in_fifo_validate : 1,
+						out_overflow : 1,
 						stopped : 1,
 						is_in : 1,
 						is_iso : 1;
@@ -529,6 +530,7 @@ static inline void allow_status (struct net2280_ep *ep)
 {
 	/* ep0 only */
 	writel (  (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE)
+		| (1 << CLEAR_NAK_OUT_PACKETS)
 		| (1 << CLEAR_NAK_OUT_PACKETS_MODE)
 		, &ep->regs->ep_rsp);
 	ep->stopped = 1;
@@ -546,7 +548,6 @@ struct net2280_request {
 	dma_addr_t			td_dma;
 	struct list_head		queue;
 	unsigned			mapped : 1,
-					dma_done : 1,
 					valid : 1;
 };
 
@@ -559,8 +560,7 @@ struct net2280 {
 	unsigned			enabled : 1,
 					protocol_stall : 1,
 					got_irq : 1,
-					region : 1,
-					selfpowered : 1;
+					region : 1;
 	u16				chiprev;
 
 	/* pci state used to access those endpoints */
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index 3ac41bbdfa67bda6f7180ebf7377b1878104ab84..158ebd8e1dd4824a7fa9278201e297ca3cbd42d5 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -135,9 +135,6 @@ do {									\
 
 #define GS_NUM_PORTS			16
 
-#define GS_VENDOR_ID			0x05F9
-#define GS_PRODUCT_ID			0xFFFF
-
 #define GS_NUM_CONFIGS			1
 #define GS_NO_CONFIG_ID			0
 #define GS_BULK_CONFIG_ID		2
@@ -187,7 +184,7 @@ static int debug = G_SERIAL_DEBUG;
  * DMA channels to manage their FIFOs.  It supports high speed.
  * Those endpoints can be arranged in any desired configuration.
  */
-#ifdef	CONFIG_USB_G_SERIAL_NET2280
+#ifdef	CONFIG_USB_GADGET_NET2280
 #define CHIP				"net2280"
 #define EP0_MAXPACKET			64
 static const char EP_OUT_NAME[] =	"ep-a";
@@ -220,13 +217,13 @@ static inline void hw_optimize(struct usb_gadget *gadget)
  * can't use altsettings or reset the interfaces independently.
  * So stick to a single interface.
  */
-#ifdef	CONFIG_USB_G_SERIAL_PXA2XX
+#ifdef	CONFIG_USB_GADGET_PXA2XX
 #define CHIP				"pxa2xx"
 #define EP0_MAXPACKET			16
-static const char EP_OUT_NAME[] =	"ep12out-bulk";
-#define EP_OUT_NUM			12
-static const char EP_IN_NAME[] =	"ep11in-bulk";
-#define EP_IN_NUM			11
+static const char EP_OUT_NAME[] =	"ep2out-bulk";
+#define EP_OUT_NUM			2
+static const char EP_IN_NAME[] =	"ep1in-bulk";
+#define EP_IN_NUM			1
 #define SELFPOWER 			USB_CONFIG_ATT_SELFPOWER
 
 /* no hw optimizations to apply */
@@ -245,7 +242,7 @@ static const char EP_IN_NAME[] =	"ep11in-bulk";
  * in special situations.  So this is a case of "choose it right
  * during enumeration" ...
  */
-#ifdef	CONFIG_USB_G_SERIAL_SA1100
+#ifdef	CONFIG_USB_GADGET_SA1100
 #define CHIP				"sa1100"
 #define EP0_MAXPACKET			8
 static const char EP_OUT_NAME[] =	"ep1out-bulk";
@@ -264,7 +261,7 @@ static const char EP_IN_NAME [] =	"ep2in-bulk";
  *
  * This has three semi-configurable full speed bulk/interrupt endpoints.
  */
-#ifdef	CONFIG_USB_G_SERIAL_GOKU
+#ifdef	CONFIG_USB_GADGET_GOKU
 #define CHIP				"goku"
 #define DRIVER_VERSION_NUM		0x0116
 #define EP0_MAXPACKET			8
@@ -302,6 +299,14 @@ static const char EP_IN_NAME [] =	"ep2-bulk";
 /* else value must be USB_CONFIG_ATT_WAKEUP */
 #endif
 
+/* Thanks to NetChip Technologies for donating this product ID.
+ *
+ * DO NOT REUSE THESE IDs with a protocol-incompatible driver!!  Ever!!
+ * Instead:  allocate your own, using normal USB-IF procedures.
+ */
+#define GS_VENDOR_ID	0x0525		/* NetChip */
+#define GS_PRODUCT_ID	0xa4a6		/* Linux-USB Serial Gadget */
+
 
 /* Structures */
 
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index e5e6f4b5b1d48bc8d9129eb3b3fedaf3d9e159eb..704183437a76ffa652b100396de1347233267375 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -131,7 +131,7 @@ static const char loopback [] = "loop input to output";
  * DMA channels to manage their FIFOs.  It supports high speed.
  * Those endpoints can be arranged in any desired configuration.
  */
-#ifdef	CONFIG_USB_ZERO_NET2280
+#if defined(CONFIG_USB_GADGET_NET2280) || defined(CONFIG_USB_GADGET_DUMMY_HCD)
 #define CHIP			"net2280"
 #define DRIVER_VERSION_NUM	0x0101
 static const char EP_OUT_NAME [] = "ep-a";
@@ -154,7 +154,7 @@ static const char EP_IN_NAME [] = "ep-b";
  * can't use altsettings or reset the interfaces independently.
  * So stick to a single interface.
  */
-#ifdef	CONFIG_USB_ZERO_PXA2XX
+#ifdef	CONFIG_USB_GADGET_PXA2XX
 #define CHIP			"pxa2xx"
 #define DRIVER_VERSION_NUM	0x0103
 static const char EP_OUT_NAME [] = "ep12out-bulk";
@@ -176,7 +176,7 @@ static const char EP_IN_NAME [] = "ep11in-bulk";
  * in special situations.  So this is a case of "choose it right
  * during enumeration" ...
  */
-#ifdef	CONFIG_USB_ZERO_SA1100
+#ifdef	CONFIG_USB_GADGET_SA1100
 #define CHIP			"sa1100"
 #define DRIVER_VERSION_NUM	0x0105
 static const char EP_OUT_NAME [] = "ep1out-bulk";
@@ -192,7 +192,7 @@ static const char EP_IN_NAME [] = "ep2in-bulk";
  *
  * This has three semi-configurable full speed bulk/interrupt endpoints.
  */
-#ifdef	CONFIG_USB_ZERO_GOKU
+#ifdef	CONFIG_USB_GADGET_GOKU
 #define CHIP			"goku"
 #define DRIVER_VERSION_NUM	0x0106
 static const char EP_OUT_NAME [] = "ep1-bulk";
@@ -936,7 +936,7 @@ zero_set_config (struct zero_dev *dev, unsigned number, int gfp_flags)
 	if (number == dev->config)
 		return 0;
 
-#ifdef CONFIG_USB_ZERO_SA1100
+#ifdef CONFIG_USB_GADGET_SA1100
 	if (dev->config) {
 		/* tx fifo is full, but we can't clear it...*/
 		INFO (dev, "can't change configurations\n");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 83076a7801ddab9312a87e065670c1d21ecbf830..168c9e9edcc4ae6a3044cea33dcbfc0f10b4ed05 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -684,6 +684,10 @@ MODULE_LICENSE ("GPL");
 #include "ohci-sa1111.c"
 #endif
 
-#if !(defined(CONFIG_PCI) || defined(CONFIG_SA1111))
+#ifdef CONFIG_ARCH_OMAP
+#include "ohci-omap.c"
+#endif
+
+#if !(defined(CONFIG_PCI) || defined(CONFIG_SA1111) || defined(CONFIG_ARCH_OMAP))
 #error "missing bus glue for ohci-hcd"
 #endif
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
new file mode 100644
index 0000000000000000000000000000000000000000..d664ed24f9873fbc9ee211fc58cfaacad9954e96
--- /dev/null
+++ b/drivers/usb/host/ohci-omap.c
@@ -0,0 +1,673 @@
+/*
+ * OHCI HCD (Host Controller Driver) for USB.
+ *
+ * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
+ * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
+ * (C) Copyright 2002 Hewlett-Packard Company
+ * 
+ * OMAP Bus Glue
+ *
+ * Written by Christopher Hoover <ch@hpl.hp.com>
+ * Based on fragments of previous driver by Rusell King et al.
+ *
+ * Modified for OMAP from ohci-sa1111.c by Tony Lindgren <tony@atomide.com>
+ * Based on the 2.4 OMAP OHCI driver originally done by MontaVista Software Inc.
+ *
+ * This file is licenced under the GPL.
+ */
+ 
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/io.h>
+
+#include <asm/arch/bus.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/irqs.h>
+
+#include "ohci-omap.h"
+
+#ifndef CONFIG_ARCH_OMAP
+#error "This file is OMAP bus glue.  CONFIG_OMAP must be defined."
+#endif
+
+extern int usb_disabled(void);
+extern int ocpi_enable(void);
+
+/*
+ * Use the first port only by default. Override with hmc_mode option.
+ *
+ * NOTE: Many OMAP-1510 Innovators supposedly have bad wiring for the USB ports
+ *       1 & 2, so only port 0 will work. To use the OHCI on the first port, use 
+ *       the Innovator USB client cable with a client-to-client connector and modify
+ *       either the cable or the hub to feed 5V VBUS back to Innovator. VBUS should
+ *       be the red lead in the cable.
+ *
+ *       To mount USB hard disk as root, see the patch for do_mounts.c that tries 
+ *       remounting the root, and use root=0801 if your root is on sda1. Does not 
+ *       work with devfs.
+ */
+static int default_hmc_mode = 16;
+static int hmc_mode = 1234;
+
+/*
+ * Set the USB host pin multiplexing and the selected HMC mode
+ */
+static int omap_usb_set_hmc_mode(int hmc_mode)
+{
+	unsigned int val;
+
+	switch (hmc_mode) {
+	case 0:
+		/* 0: function, 1: disabled, 2: disabled */
+		omap_cfg_reg(W4_USB_PUEN);
+		omap_cfg_reg(R18_1510_USB_GPIO0);
+		break;
+	case 4:
+		/* 0: function 1: host 2: host */
+		omap_cfg_reg(usb1_speed);
+		omap_cfg_reg(usb1_susp);
+		omap_cfg_reg(usb1_seo);
+		omap_cfg_reg(usb1_txen);
+		omap_cfg_reg(usb1_txd);
+		omap_cfg_reg(usb1_vp);
+		omap_cfg_reg(usb1_vm);
+		omap_cfg_reg(usb1_rcv);
+		omap_cfg_reg(usb2_susp);
+		omap_cfg_reg(usb2_seo);
+		omap_cfg_reg(usb2_txen);
+		omap_cfg_reg(usb2_txd);
+		omap_cfg_reg(usb2_vp);
+		omap_cfg_reg(usb2_vm);
+		omap_cfg_reg(usb2_rcv);
+		break;
+	case 16:
+		/* 0: host, 1: disabled, 2: disabled */
+		omap_cfg_reg(W9_USB0_TXEN);
+		omap_cfg_reg(AA9_USB0_VP);
+		omap_cfg_reg(Y5_USB0_RCV);
+		omap_cfg_reg(R9_USB0_VM);
+		omap_cfg_reg(V6_USB0_TXD);
+		omap_cfg_reg(W5_USB0_SE0);
+		break;
+	default:
+		printk("Unknown USB host configuration: %i\n", hmc_mode);
+		return -ENODEV;
+	}
+
+	/* Write the selected HMC mode */
+	val = readl(MOD_CONF_CTRL_0) & ~HMC_CLEAR;
+	val |= (hmc_mode << 1);
+	writel(val, MOD_CONF_CTRL_0);
+
+	return 0;
+}
+
+/*
+ * OHCI clock initialization for OMAP-1510 and 1610
+ */
+static int omap_ohci_clock_power(int on)
+{
+	if (on) {
+		if (cpu_is_omap_1510()) {
+			/* Use DPLL, not APLL */
+			writel(readl(ULPD_APLL_CTRL_REG) & ~APLL_NDPLL_SWITCH,
+			       ULPD_APLL_CTRL_REG);
+
+			/* Enable DPLL */
+			writel(readl(ULPD_DPLL_CTRL_REG) | DPLL_PLL_ENABLE,
+			       ULPD_DPLL_CTRL_REG);
+
+			/* Software request for USB 48MHz clock */
+			writel(readl(ULPD_SOFT_REQ_REG) | SOFT_REQ_REG_REQ,
+			       ULPD_SOFT_REQ_REG);
+
+			while (!(readl(ULPD_DPLL_CTRL_REG) & DPLL_LOCK));
+		}
+
+		if (cpu_is_omap_1610()) {
+			/* Enable OHCI */
+			writel(readl(ULPD_SOFT_REQ_REG) | SOFT_USB_OTG_REQ,
+				ULPD_SOFT_REQ_REG);
+
+			/* USB host clock request if not using OTG */
+			writel(readl(ULPD_SOFT_REQ_REG) | SOFT_USB_REQ,
+				ULPD_SOFT_REQ_REG);
+
+			outl(inl(ULPD_STATUS_REQ_REG) | USB_HOST_DPLL_REQ,
+			     ULPD_STATUS_REQ_REG);
+		}
+
+		/* Enable 48MHz clock to USB */
+		writel(readl(ULPD_CLOCK_CTRL_REG) | USB_MCLK_EN,
+		       ULPD_CLOCK_CTRL_REG);
+
+		writel(readl(ARM_IDLECT2) | (1 << EN_LBFREECK) | (1 << EN_LBCK),
+		       ARM_IDLECT2);
+
+		writel(readl(MOD_CONF_CTRL_0) | USB_HOST_HHC_UHOST_EN,
+		       MOD_CONF_CTRL_0);
+	} else {
+		/* Disable 48MHz clock to USB */
+		writel(readl(ULPD_CLOCK_CTRL_REG) & ~USB_MCLK_EN,
+		       ULPD_CLOCK_CTRL_REG);
+
+		/* FIXME: The DPLL stays on for now */
+	}
+
+	return 0;
+}
+
+/*
+ * Hardware specific transceiver power on/off
+ */
+static int omap_ohci_transceiver_power(int on)
+{
+	if (on) {
+		if (omap_is_innovator())
+			writel(readl(OMAP1510_FPGA_HOST_CTRL) | 0x20, 
+			       OMAP1510_FPGA_HOST_CTRL);
+	} else {
+		if (omap_is_innovator())
+			writel(readl(OMAP1510_FPGA_HOST_CTRL) & ~0x20, 
+			       OMAP1510_FPGA_HOST_CTRL);
+	}
+
+	return 0;
+}
+
+/*
+ * OMAP-1510 specific Local Bus clock on/off
+ */
+static int omap_1510_local_bus_power(int on)
+{
+	if (on) {
+		writel((1 << 1) | (1 << 0), OMAP1510_LB_MMU_CTL);
+		udelay(200);
+	} else {
+		writel(0, OMAP1510_LB_MMU_CTL);
+	}
+
+	return 0;
+}
+
+/*
+ * OMAP-1510 specific Local Bus initialization
+ * NOTE: This assumes 32MB memory size in OMAP1510LB_MEMSIZE.
+ *       See also arch/mach-omap/memory.h for __virt_to_bus() and 
+ *       __bus_to_virt() which need to match with the physical 
+ *       Local Bus address below.
+ */
+static int omap_1510_local_bus_init(void)
+{
+	unsigned int tlb;
+	unsigned long lbaddr, physaddr;
+
+	writel((readl(OMAP1510_LB_CLOCK_DIV) & 0xfffffff8) | 0x4, 
+	       OMAP1510_LB_CLOCK_DIV);
+
+	/* Configure the Local Bus MMU table */
+	for (tlb = 0; tlb < OMAP1510_LB_MEMSIZE; tlb++) {
+		lbaddr = tlb * 0x00100000 + OMAP1510_LB_OFFSET;
+		physaddr = tlb * 0x00100000 + PHYS_OFFSET;
+		writel((lbaddr & 0x0fffffff) >> 22, OMAP1510_LB_MMU_CAM_H);
+		writel(((lbaddr & 0x003ffc00) >> 6) | 0xc, 
+		       OMAP1510_LB_MMU_CAM_L);
+		writel(physaddr >> 16, OMAP1510_LB_MMU_RAM_H);
+		writel((physaddr & 0x0000fc00) | 0x300, OMAP1510_LB_MMU_RAM_L);
+		writel(tlb << 4, OMAP1510_LB_MMU_LCK);
+		writel(0x1, OMAP1510_LB_MMU_LD_TLB);
+	}
+
+	/* Enable the walking table */
+	writel(readl(OMAP1510_LB_MMU_CTL) | (1 << 3), OMAP1510_LB_MMU_CTL);
+	udelay(200);
+
+	return 0;
+}
+
+/*
+ * OMAP-1610 specific hardware initialization
+ *
+ * Intended to configure OMAP-1610 USB host and OTG ports depending on 
+ * the HMC mode selected.
+ *
+ * FIXME: Currently only supports alternate ping group 2 mode, should
+ *        be easy to modify for other configurations once there is some
+ *        hardware to test with.
+ */
+static int omap_1610_usb_init(int mode)
+{
+	u_int val = 0;
+
+	/* Configure the OMAP transceiver settings */
+	val |= (1 << 8); /* CONF_USB2_UNI TRM p 15-205*/
+	val |= (4 << 4); /* TRM p 5-59, p 15-157 (1224) */
+
+	//val |= (1 << 3); /* Isolate integrated transceiver from port 0 */
+	val |= (1 << 2); /* Disable pulldown on integrated transceiver DM */
+	val |= (1 << 1); /* Disable pulldown on integraded transceiver DP */
+
+	outl(val, USB_TRANSCEIVER_CTRL);
+
+	/* Set the USB0_TRX_MODE */
+	val = 0;
+	val &= ~OTG_IDLE_EN;
+	val &= ~DEV_IDLE_EN;
+	val &= ~(7 << 16);	/* Clear USB0_TRX_MODE */
+	val |= (3 << 16);	/* 0 or 3, 6-wire DAT/SE0, TRM p 15-159 */
+	outl(val, OTG_SYSCON_1);
+
+	/* 
+	 * Control via OTG, see TRM p 15-163
+	 */
+	val = 0;
+	//val |= 1;		/* REVISIT: Enable OTG = 1 */
+
+	/* Control via OTG */
+	val &= ~HMC_PADEN;
+	val &= ~OTG_PADEN;
+	val |= UHOST_EN;	
+
+	val &= ~0x3f;		/* Clear HMC mode */
+	val |= mode;		/* Set HMC mode */
+	val &= ~(7 << 16);	/* Clear ASE0_BRST */
+	val |= (4 << 16);	/* Must be 4 */
+	val |= USBX_SYNCHRO;	/* Must be set */
+	val |= SRP_VBUS;
+	outl(val, OTG_SYSCON_2);
+
+	/* Enable OTG idle */
+	//outl(inl(OTG_SYSCON_1) | OTG_IDLE_EN, OTG_SYSCON_1);
+
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void omap_start_hc(struct omap_dev *dev)
+{
+	printk(KERN_DEBUG __FILE__ 
+	       ": starting OMAP OHCI USB Controller\n");
+
+	/* 
+	 * Set the HMC mode for the USB ports
+	 */
+#if 0
+	/* See note about the Innovator wiring above */
+	if (omap_is_innovator())
+		hmc_mode = 4;	/* 0: function 1: host 2: host */
+#endif
+
+	if (cpu_is_omap_1610())
+		ocpi_enable();
+
+	omap_usb_set_hmc_mode(hmc_mode);
+
+	omap_ohci_clock_power(1);
+	omap_ohci_transceiver_power(1);
+
+	if (cpu_is_omap_1510()) {
+		omap_1510_local_bus_power(1);
+		omap_1510_local_bus_init();
+	}
+
+	if (cpu_is_omap_1610())
+		omap_1610_usb_init(hmc_mode);
+
+	//omap_enable_device(dev);
+}
+
+static void omap_stop_hc(struct omap_dev *dev)
+{
+	printk(KERN_DEBUG __FILE__ 
+	       ": stopping OMAP OHCI USB Controller\n");
+
+	/*
+	 * FIXME: Put the USB host controller into reset.
+	 */
+
+	/*
+	 * FIXME: Stop the USB clock.
+	 */
+	//omap_disable_device(dev);
+
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static irqreturn_t usb_hcd_omap_hcim_irq (int irq, void *__hcd, struct pt_regs * r)
+{
+	struct usb_hcd *hcd = __hcd;
+
+	return usb_hcd_irq(irq, hcd, r);
+}
+
+/*-------------------------------------------------------------------------*/
+
+void usb_hcd_omap_remove (struct usb_hcd *, struct omap_dev *);
+
+/* configure so an HC device and id are always provided */
+/* always called with process context; sleeping is OK */
+
+
+/**
+ * usb_hcd_omap_probe - initialize OMAP-based HCDs
+ * Context: !in_interrupt()
+ *
+ * Allocates basic resources for this USB host controller, and
+ * then invokes the start() method for the HCD associated with it
+ * through the hotplug entry's driver_data.
+ *
+ * Store this function in the HCD's struct pci_driver as probe().
+ */
+int usb_hcd_omap_probe (const struct hc_driver *driver,
+			  struct usb_hcd **hcd_out,
+			  struct omap_dev *dev)
+{
+	int retval;
+	struct usb_hcd *hcd = 0;
+
+	if (!request_mem_region(dev->res.start, 
+				dev->res.end - dev->res.start + 1, hcd_name)) {
+		dbg("request_mem_region failed");
+		return -EBUSY;
+	}
+
+	omap_start_hc(dev);
+
+	hcd = driver->hcd_alloc ();
+	if (hcd == NULL){
+		dbg ("hcd_alloc failed");
+		retval = -ENOMEM;
+		goto err1;
+	}
+
+	hcd->driver = (struct hc_driver *) driver;
+	hcd->description = driver->description;
+	hcd->irq = dev->irq[0];
+	hcd->regs = dev->mapbase;
+	hcd->pdev = OMAP_FAKE_PCIDEV;
+	hcd->self.controller = &dev->dev;
+	hcd->controller = hcd->self.controller;
+
+	retval = hcd_buffer_create (hcd);
+	if (retval != 0) {
+		dbg ("pool alloc fail");
+		goto err1;
+	}
+
+	retval = request_irq (hcd->irq, 
+			      usb_hcd_omap_hcim_irq, 
+			      SA_INTERRUPT, hcd->description, hcd);
+	if (retval != 0) {
+		dbg("request_irq failed");
+		retval = -EBUSY;
+		goto err2;
+	}
+
+	info ("%s (OMAP) at 0x%p, irq %d\n",
+	      hcd->description, hcd->regs, hcd->irq);
+
+	usb_bus_init (&hcd->self);
+	hcd->self.op = &usb_hcd_operations;
+	hcd->self.hcpriv = (void *) hcd;
+	hcd->self.bus_name = "omap";
+	hcd->product_desc = "OMAP OHCI";
+
+	INIT_LIST_HEAD (&hcd->dev_list);
+	usb_register_bus (&hcd->self);
+
+	if ((retval = driver->start (hcd)) < 0) 
+	{
+		usb_hcd_omap_remove(hcd, dev);
+		return retval;
+	}
+
+	*hcd_out = hcd;
+	return 0;
+
+ err2:
+	hcd_buffer_destroy (hcd);
+	if (hcd)
+		driver->hcd_free(hcd);
+ err1:
+	omap_stop_hc(dev);
+
+	release_mem_region(dev->res.start, dev->res.end - dev->res.start + 1);
+
+	return retval;
+}
+
+
+/* may be called without controller electrically present */
+/* may be called with controller, bus, and devices active */
+
+/**
+ * usb_hcd_omap_remove - shutdown processing for OMAP-based HCDs
+ * @dev: USB Host Controller being removed
+ * Context: !in_interrupt()
+ *
+ * Reverses the effect of usb_hcd_omap_probe(), first invoking
+ * the HCD's stop() method.  It is always called from a thread
+ * context, normally "rmmod", "apmd", or something similar.
+ *
+ */
+void usb_hcd_omap_remove (struct usb_hcd *hcd, struct omap_dev *dev)
+{
+	struct usb_device	*hub;
+	void *base;
+
+	info ("remove: %s, state %x", hcd->self.bus_name, hcd->state);
+
+	if (in_interrupt ())
+		BUG ();
+
+	hub = hcd->self.root_hub;
+	hcd->state = USB_STATE_QUIESCING;
+
+	dbg ("%s: roothub graceful disconnect", hcd->self.bus_name);
+	usb_disconnect (&hub);
+
+	hcd->driver->stop (hcd);
+	hcd_buffer_destroy (hcd);
+	hcd->state = USB_STATE_HALT;
+
+	free_irq (hcd->irq, hcd);
+
+	usb_deregister_bus (&hcd->self);
+
+	base = hcd->regs;
+	hcd->driver->hcd_free (hcd);
+
+	omap_stop_hc(dev);
+
+	release_mem_region(dev->res.start, dev->res.end - dev->res.start + 1);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int __devinit
+ohci_omap_start (struct usb_hcd *hcd)
+{
+	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
+	int		ret;
+
+	if (hcd->pdev) {
+		ohci->hcca = pci_alloc_consistent (hcd->pdev,
+				sizeof *ohci->hcca, &ohci->hcca_dma);
+		if (!ohci->hcca)
+			return -ENOMEM;
+	}
+
+        memset (ohci->hcca, 0, sizeof (struct ohci_hcca));
+	if ((ret = ohci_mem_init (ohci)) < 0) {
+		ohci_stop (hcd);
+		return ret;
+	}
+	ohci->regs = hcd->regs;
+	if (hc_reset (ohci) < 0) {
+		ohci_stop (hcd);
+		return -ENODEV;
+	}
+
+	if (hc_start (ohci) < 0) {
+		err ("can't start %s", ohci->hcd.self.bus_name);
+		ohci_stop (hcd);
+		return -EBUSY;
+	}
+	create_debug_files (ohci);
+
+#ifdef	DEBUG
+	ohci_dump (ohci, 1);
+#endif
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static const struct hc_driver ohci_omap_hc_driver = {
+	.description =		hcd_name,
+
+	/*
+	 * generic hardware linkage
+	 */
+	.irq =			ohci_irq,
+	.flags =		HCD_USB11,
+
+	/*
+	 * basic lifecycle operations
+	 */
+	.start =		ohci_omap_start,
+#ifdef	CONFIG_PM
+	/* suspend:		ohci_omap_suspend,  -- tbd */
+	/* resume:		ohci_omap_resume,   -- tbd */
+#endif
+	.stop =			ohci_stop,
+
+	/*
+	 * memory lifecycle (except per-request)
+	 */
+	.hcd_alloc =		ohci_hcd_alloc,
+	.hcd_free =		ohci_hcd_free,
+
+	/*
+	 * managing i/o requests and associated device resources
+	 */
+	.urb_enqueue =		ohci_urb_enqueue,
+	.urb_dequeue =		ohci_urb_dequeue,
+	.endpoint_disable =	ohci_endpoint_disable,
+
+	/*
+	 * scheduling support
+	 */
+	.get_frame_number =	ohci_get_frame,
+
+	/*
+	 * root hub support
+	 */
+	.hub_status_data =	ohci_hub_status_data,
+	.hub_control =		ohci_hub_control,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int ohci_hcd_omap_drv_probe(struct omap_dev *dev)
+{
+	struct usb_hcd *hcd = NULL;
+	int ret;
+
+	if (usb_disabled())
+		return -ENODEV;
+
+	ret = usb_hcd_omap_probe(&ohci_omap_hc_driver, &hcd, dev);
+
+	if (ret == 0)
+		omap_set_drvdata(dev, hcd);
+
+	return ret;
+}
+
+static int ohci_hcd_omap_drv_remove(struct omap_dev *dev)
+{
+	struct usb_hcd *hcd = omap_get_drvdata(dev);
+
+	usb_hcd_omap_remove(hcd, dev);
+
+	omap_set_drvdata(dev, NULL);
+
+	return 0;
+}
+
+/*
+ * Driver definition to register with the OMAP bus
+ */
+static struct omap_driver ohci_hcd_omap_driver = {
+	.drv = {
+		.name	= OMAP_OHCI_NAME,
+	},
+	.devid		= OMAP_OCP_DEVID_USB,
+	.busid		= OMAP_BUS_OCP,
+	.clocks		= 0,
+	.probe		= ohci_hcd_omap_drv_probe,
+	.remove		= ohci_hcd_omap_drv_remove,
+};
+
+/* Any dma_mask must be set for OHCI to work */
+static u64 omap_dmamask = 0xffffffffUL;	
+
+/*
+ * Device definition to match the driver above
+ */
+static struct omap_dev ohci_hcd_omap_device = {
+	.name		= OMAP_OHCI_NAME,
+	.devid		= OMAP_OCP_DEVID_USB,
+	.busid		= OMAP_BUS_OCP,
+	.mapbase	= (void *)OMAP_OHCI_BASE,
+	.dma_mask	= &omap_dmamask,	/* Needed only for OHCI */
+	.res = {
+		.start	= OMAP_OHCI_BASE,
+		.end	= OMAP_OHCI_BASE + OMAP_OHCI_SIZE,
+	},
+	.irq = {
+		INT_OHCI,
+	},
+};
+
+static int __init ohci_hcd_omap_init (void)
+{
+	int ret;
+
+	dbg (DRIVER_INFO " (OMAP)");
+	dbg ("block sizes: ed %d td %d\n",
+		sizeof (struct ed), sizeof (struct td));
+
+	if (hmc_mode < 0 || hmc_mode > 25)
+		hmc_mode = default_hmc_mode;
+
+	/* Register the driver with OMAP bus */
+	ret = omap_driver_register(&ohci_hcd_omap_driver);
+	if (ret != 0)
+		return -ENODEV;
+
+	/* Register the device with OMAP bus */
+	ret = omap_device_register(&ohci_hcd_omap_device);
+	if (ret != 0) {
+		omap_driver_unregister(&ohci_hcd_omap_driver);
+		return -ENODEV;
+	}
+
+	return ret;
+}
+
+MODULE_PARM(hmc_mode, "hmc_mode");
+
+static void __exit ohci_hcd_omap_cleanup (void)
+{
+	omap_device_unregister(&ohci_hcd_omap_device);
+	omap_driver_unregister(&ohci_hcd_omap_driver);
+}
+
+module_init (ohci_hcd_omap_init);
+module_exit (ohci_hcd_omap_cleanup);
diff --git a/drivers/usb/host/ohci-omap.h b/drivers/usb/host/ohci-omap.h
new file mode 100644
index 0000000000000000000000000000000000000000..58ae2b40008f667cb02a25e4ea94e59485facef6
--- /dev/null
+++ b/drivers/usb/host/ohci-omap.h
@@ -0,0 +1,57 @@
+/*
+ * linux/drivers/usb/host/ohci-omap.h
+ *
+ * OMAP OHCI USB controller specific defines
+ */
+
+/* OMAP USB OHCI common defines */
+#define OMAP_OHCI_NAME		"omap-ohci"
+#define OMAP_OHCI_BASE		0xfffba000
+#define OMAP_OHCI_SIZE		4096
+
+#define HMC_CLEAR		(0x3f << 1)
+#define APLL_NDPLL_SWITCH	0x0001
+#define DPLL_PLL_ENABLE		0x0010
+#define DPLL_LOCK		0x0001
+#define SOFT_REQ_REG_REQ	0x0001
+#define USB_MCLK_EN		0x0010
+#define USB_HOST_HHC_UHOST_EN	0x00000200
+#define SOFT_USB_OTG_REQ	(1 << 8)
+#define SOFT_USB_REQ		(1 << 3)
+#define STATUS_REQ_REG		0xfffe0840
+#define USB_HOST_DPLL_REQ	(1 << 8)
+#define SOFT_DPLL_REQ		(1 << 0)
+
+/* OMAP-1510 USB OHCI defines */
+#define OMAP1510_LB_MEMSIZE	32		/* Should be same as SDRAM size */
+#define OMAP1510_LB_CLOCK_DIV	0xfffec10c
+#define OMAP1510_LB_MMU_CTL	0xfffec208	
+#define OMAP1510_LB_MMU_LCK	0xfffec224
+#define OMAP1510_LB_MMU_LD_TLB	0xfffec228
+#define OMAP1510_LB_MMU_CAM_H	0xfffec22c
+#define OMAP1510_LB_MMU_CAM_L	0xfffec230
+#define OMAP1510_LB_MMU_RAM_H	0xfffec234
+#define OMAP1510_LB_MMU_RAM_L	0xfffec238
+
+/* OMAP-1610 USB OHCI defines */
+#define USB_TRANSCEIVER_CTRL	0xfffe1064
+#define OTG_REV			0xfffb0400
+
+#define OTG_SYSCON_1		0xfffb0404
+#define OTG_IDLE_EN		(1 << 15)
+#define DEV_IDLE_EN		(1 << 13)
+
+#define OTG_SYSCON_2		0xfffb0408
+#define OTG_CTRL		0xfffb040c
+#define OTG_IRQ_EN		0xfffb0410
+#define OTG_IRQ_SRC		0xfffb0414
+
+#define OTG_EN			(1 << 31)
+#define USBX_SYNCHRO		(1 << 30)
+#define SRP_VBUS		(1 << 12)
+#define OTG_PADEN		(1 << 10)
+#define HMC_PADEN		(1 << 9)
+#define UHOST_EN		(1 << 8)
+
+/* Hardware specific defines */
+#define OMAP1510_FPGA_HOST_CTRL	0xe800020c
diff --git a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c
index cce0dbb55b7d1dde4f840f0109baf7b0eb273f66..4510ace39d2a4f9306e0c0fbd4a3b9b2c74fcff2 100644
--- a/drivers/usb/media/dabusb.c
+++ b/drivers/usb/media/dabusb.c
@@ -781,17 +781,25 @@ static int dabusb_probe (struct usb_interface *intf,
 
 static void dabusb_disconnect (struct usb_interface *intf)
 {
+	wait_queue_t __wait;
 	pdabusb_t s = usb_get_intfdata (intf);
 
 	dbg("dabusb_disconnect");
-
+	
+	init_waitqueue_entry(&__wait, current);
+	
 	usb_set_intfdata (intf, NULL);
 	if (s) {
 		usb_deregister_dev (intf, &dabusb_class);
 		s->remove_pending = 1;
 		wake_up (&s->wait);
+		add_wait_queue(&s->remove_ok, &__wait);
+		set_current_state(TASK_UNINTERRUPTIBLE);
 		if (s->state == _started)
-			sleep_on (&s->remove_ok);
+			schedule();
+		current->state = TASK_RUNNING;
+		remove_wait_queue(&s->remove_ok, &__wait);
+		
 		s->usbdev = NULL;
 		s->overruns = 0;
 	}
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
index 4b43ea5972d11940616570256068a3ce11288906..521597f375c0e1934a5138dd73a6cec6f52ae766 100644
--- a/drivers/usb/misc/Kconfig
+++ b/drivers/usb/misc/Kconfig
@@ -6,6 +6,7 @@ comment "USB Miscellaneous drivers"
 
 config USB_EMI62
 	tristate "EMI 6|2m USB Audio interface support"
+	depends on USB
 	---help---
 	  This driver loads firmware to Emagic EMI 6|2m low latency USB
 	  Audio and Midi interface.
@@ -20,6 +21,7 @@ config USB_EMI62
 
 config USB_EMI26
 	tristate "EMI 2|6 USB Audio interface support"
+	depends on USB
 	---help---
 	  This driver loads firmware to Emagic EMI 2|6 low latency USB
 	  Audio interface.
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
index a8f581e58df576cf300debbc44cf77bfe01de8f7..b137da951670e9e2b3791b3ca2bb8b9199f6eede 100644
--- a/drivers/usb/misc/auerswald.c
+++ b/drivers/usb/misc/auerswald.c
@@ -1927,7 +1927,6 @@ static int auerswald_probe (struct usb_interface *intf,
 {
 	struct usb_device *usbdev = interface_to_usbdev(intf);
 	pauerswald_t cp = NULL;
-	DECLARE_WAIT_QUEUE_HEAD (wqh);
 	unsigned int u = 0;
 	char *pbuf;
 	int ret;
@@ -1975,7 +1974,8 @@ static int auerswald_probe (struct usb_interface *intf,
 	dbg ("Version is %X", cp->version);
 
 	/* allow some time to settle the device */
-	sleep_on_timeout (&wqh, HZ / 3 );
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(HZ/3);
 
 	/* Try to get a suitable textual description of the device */
 	/* Device name:*/
diff --git a/drivers/usb/misc/tiglusb.c b/drivers/usb/misc/tiglusb.c
index 5ee81f7d95774944ab36348e4e0cc78018860ebf..85c32711e768d36a9a22cbb3e3752bc52d833942 100644
--- a/drivers/usb/misc/tiglusb.c
+++ b/drivers/usb/misc/tiglusb.c
@@ -161,7 +161,7 @@ tiglusb_read (struct file *filp, char __user *buf, size_t count, loff_t * f_pos)
 	int bytes_to_read = 0;
 	int bytes_read = 0;
 	int result = 0;
-	char buffer[BULK_RCV_MAX];
+	char *buffer;
 	unsigned int pipe;
 
 	if (*f_pos)
@@ -173,6 +173,10 @@ tiglusb_read (struct file *filp, char __user *buf, size_t count, loff_t * f_pos)
 	if (!s->dev)
 		return -EIO;
 
+	buffer = kmalloc(BULK_RCV_MAX, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
 	bytes_to_read = (count >= BULK_RCV_MAX) ? BULK_RCV_MAX : count;
 
 	pipe = usb_rcvbulkpipe (s->dev, 1);
@@ -203,6 +207,7 @@ tiglusb_read (struct file *filp, char __user *buf, size_t count, loff_t * f_pos)
 	}
 
       out:
+	kfree(buffer);
 	return ret ? ret : bytes_read;
 }
 
@@ -214,7 +219,7 @@ tiglusb_write (struct file *filp, const char __user *buf, size_t count, loff_t *
 	int bytes_to_write = 0;
 	int bytes_written = 0;
 	int result = 0;
-	char buffer[BULK_SND_MAX];
+	char *buffer;
 	unsigned int pipe;
 
 	if (*f_pos)
@@ -226,6 +231,10 @@ tiglusb_write (struct file *filp, const char __user *buf, size_t count, loff_t *
 	if (!s->dev)
 		return -EIO;
 
+	buffer = kmalloc(BULK_SND_MAX, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
 	bytes_to_write = (count >= BULK_SND_MAX) ? BULK_SND_MAX : count;
 	if (copy_from_user (buffer, buf, bytes_to_write)) {
 		ret = -EFAULT;
@@ -258,6 +267,7 @@ tiglusb_write (struct file *filp, const char __user *buf, size_t count, loff_t *
 	}
 
       out:
+	kfree(buffer);
 	return ret ? ret : bytes_written;
 }
 
@@ -387,7 +397,11 @@ tiglusb_probe (struct usb_interface *intf,
 static void
 tiglusb_disconnect (struct usb_interface *intf)
 {
+	wait_queue_t __wait;
 	ptiglusb_t s = usb_get_intfdata (intf);
+	
+	init_waitqueue_entry(&__wait, current);
+	
 
 	usb_set_intfdata (intf, NULL);
 	if (!s || !s->dev) {
@@ -397,8 +411,12 @@ tiglusb_disconnect (struct usb_interface *intf)
 
 	s->remove_pending = 1;
 	wake_up (&s->wait);
+	add_wait_queue(&s->wait, &__wait);
+	set_current_state(TASK_UNINTERRUPTIBLE);
 	if (s->state == _started)
-		sleep_on (&s->remove_ok);
+		schedule();
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&s->wait, &__wait);
 	down (&s->mutex);
 	s->dev = NULL;
 	s->opened = 0;
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index cb588ec79c5a055e3db3b0e94ed2ddc567c3954f..2bf6eb109524bffcb30d049354cf98203548a88f 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -651,7 +651,7 @@ static int  kobil_ioctl(struct usb_serial_port *port, struct file *file,
 		return 0;
 
 	case TCSETS:   // 0x5402
-		if (! &port->tty->termios) {
+		if (!(port->tty->termios)) {
 			dbg("%s - port %d Error: port->tty->termios is NULL", __FUNCTION__, port->number);
 			return -ENOTTY;
 		}
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index c398585976f7a486a0c7799dcb07b44f36e5bc83..412d2173d521a6891dd4f341b54bd2a9c45b053c 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -353,8 +353,8 @@ static int whiteheat_attach (struct usb_serial *serial)
 	int pipe;
 	int ret;
 	int alen;
-	__u8 command[2] = { WHITEHEAT_GET_HW_INFO, 0 };
-	__u8 result[sizeof(*hw_info) + 1];
+	__u8 *command;
+	__u8 *result;
 	int i;
 	int j;
 	struct urb *urb;
@@ -365,13 +365,22 @@ static int whiteheat_attach (struct usb_serial *serial)
 	command_port = serial->port[COMMAND_PORT];
 
 	pipe = usb_sndbulkpipe (serial->dev, command_port->bulk_out_endpointAddress);
+	command = kmalloc(2, GFP_KERNEL);
+	if (!command)
+		goto no_command_buffer;
+	command[0] = WHITEHEAT_GET_HW_INFO;
+	command[1] = 0;
+	
+	result = kmalloc(sizeof(*hw_info) + 1, GFP_KERNEL);
+	if (!result)
+		goto no_result_buffer;
 	/*
 	 * When the module is reloaded the firmware is still there and
 	 * the endpoints are still in the usb core unchanged. This is the
          * unlinking bug in disguise. Same for the call below.
          */
 	usb_clear_halt(serial->dev, pipe);
-	ret = usb_bulk_msg (serial->dev, pipe, command, sizeof(command), &alen, COMMAND_TIMEOUT);
+	ret = usb_bulk_msg (serial->dev, pipe, command, 2, &alen, COMMAND_TIMEOUT);
 	if (ret) {
 		err("%s: Couldn't send command [%d]", serial->type->name, ret);
 		goto no_firmware;
@@ -383,7 +392,7 @@ static int whiteheat_attach (struct usb_serial *serial)
 	pipe = usb_rcvbulkpipe (serial->dev, command_port->bulk_in_endpointAddress);
 	/* See the comment on the usb_clear_halt() above */
 	usb_clear_halt(serial->dev, pipe);
-	ret = usb_bulk_msg (serial->dev, pipe, result, sizeof(result), &alen, COMMAND_TIMEOUT);
+	ret = usb_bulk_msg (serial->dev, pipe, result, sizeof(*hw_info) + 1, &alen, COMMAND_TIMEOUT);
 	if (ret) {
 		err("%s: Couldn't get results [%d]", serial->type->name, ret);
 		goto no_firmware;
@@ -485,6 +494,8 @@ static int whiteheat_attach (struct usb_serial *serial)
 	usb_set_serial_port_data(command_port, command_info);
 	command_port->write_urb->complete = command_port_write_callback;
 	command_port->read_urb->complete = command_port_read_callback;
+	kfree(result);
+	kfree(command);
 
 	return 0;
 
@@ -526,6 +537,10 @@ static int whiteheat_attach (struct usb_serial *serial)
 no_private:
 		;
 	}
+	kfree(result);
+no_result_buffer:
+	kfree(command);
+no_command_buffer:
 	return -ENOMEM;
 }
 
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index 10d012e386ce365bbe9f0519ece27e0b42d19565..6f1ea41d83a86ac52d792a4cd662ea49b317dd7a 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -309,44 +309,6 @@ static int proc_info (struct Scsi_Host *hostptr, char *buffer, char **start, off
  * Sysfs interface
  ***********************************************************************/
 
-/* Output routine for the sysfs info file */
-static ssize_t show_info(struct device *dev, char *buffer)
-{
-	char *pos = buffer;
-	const int length = PAGE_SIZE;
-
-	struct scsi_device *sdev = to_scsi_device(dev);
-	struct us_data *us = (struct us_data*)sdev->host->hostdata[0];
-
-	/* print the controller name */
-	SPRINTF("   Host scsi%d: usb-storage\n", sdev->host->host_no);
-
-	/* print product, vendor, and serial number strings */
-	SPRINTF("       Vendor: %s\n", us->vendor);
-	SPRINTF("      Product: %s\n", us->product);
-	SPRINTF("Serial Number: %s\n", us->serial);
-
-	/* show the protocol and transport */
-	SPRINTF("     Protocol: %s\n", us->protocol_name);
-	SPRINTF("    Transport: %s\n", us->transport_name);
-
-	/* show the device flags */
-	if (pos < buffer + length) {
-		pos += sprintf(pos, "       Quirks:");
-
-		DO_FLAG(SINGLE_LUN);
-		DO_FLAG(SCM_MULT_TARG);
-		DO_FLAG(FIX_INQUIRY);
-		DO_FLAG(FIX_CAPACITY);
-
-		*(pos++) = '\n';
-	}
-
-	return (pos - buffer);
-}
-
-static DEVICE_ATTR(info, S_IRUGO, show_info, NULL);
-
 /* Output routine for the sysfs max_sectors file */
 static ssize_t show_max_sectors(struct device *dev, char *buf)
 {
@@ -373,7 +335,6 @@ static DEVICE_ATTR(max_sectors, S_IRUGO | S_IWUSR, show_max_sectors,
 		store_max_sectors);
 
 static struct device_attribute *sysfs_device_attr_list[] = {
-		&dev_attr_info,
 		&dev_attr_max_sectors,
 		NULL,
 		};
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index bcedc902b7b55fb443292948bae645db5e580961..924fdc3b04f704d123e4073dbf38fa9878417539 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -115,6 +115,13 @@ UNUSUAL_DEV(  0x04a4, 0x0004, 0x0001, 0x0001,
 		"DVD-CAM DZ-MV100A Camcorder",
 		US_SC_SCSI, US_PR_CB, NULL, US_FL_SINGLE_LUN),
 
+/* Reported by Simon Levitt <simon@whattf.com>
+ * This entry needs Sub and Proto fields */
+UNUSUAL_DEV(  0x04b8, 0x0601, 0x0100, 0x0100,
+		"Epson",
+		"875DC Storage",
+		US_SC_SCSI, US_PR_CB, NULL, US_FL_FIX_INQUIRY),
+
 /* Reported by Khalid Aziz <khalid@gonehiking.org>
  * This entry is needed because the device reports Sub=ff */
 UNUSUAL_DEV(  0x04b8, 0x0602, 0x0110, 0x0110,
@@ -482,11 +489,6 @@ UNUSUAL_DEV(  0x07ab, 0xfc01, 0x0000, 0x9999,
 		"Freecom",
 		"USB-IDE",
 		US_SC_QIC, US_PR_FREECOM, freecom_init, 0),
-
-UNUSUAL_DEV(  0x07ab, 0xfc84, 0x0000, 0x9999,
-		"Freecom",
-		"FX-5/FX-50",
-		US_SC_QIC, US_PR_FREECOM, freecom_init, 0),
 #endif
 
 UNUSUAL_DEV(  0x07af, 0x0004, 0x0100, 0x0133, 
diff --git a/include/asm-ia64/uaccess.h b/include/asm-ia64/uaccess.h
index add46cb74d48a13f9e5cf1740bc4244b97879a58..60e77a780790457deea6e178d39fa88b11243ebd 100644
--- a/include/asm-ia64/uaccess.h
+++ b/include/asm-ia64/uaccess.h
@@ -28,7 +28,7 @@
  *
  * Based on <asm-alpha/uaccess.h>.
  *
- * Copyright (C) 1998, 1999, 2001-2003 Hewlett-Packard Co
+ * Copyright (C) 1998, 1999, 2001-2004 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
@@ -283,24 +283,23 @@ extern unsigned long __strnlen_user (const char *, long);
 	__su_ret;						\
 })
 
+/* Generic code can't deal with the location-relative format that we use for compactness.  */
 #define ARCH_HAS_SORT_EXTABLE
 #define ARCH_HAS_SEARCH_EXTABLE
 
 struct exception_table_entry {
-	int addr;	/* gp-relative address of insn this fixup is for */
-	int cont;	/* gp-relative continuation address; if bit 2 is set, r9 is set to 0 */
+	int addr;	/* location-relative address of insn this fixup is for */
+	int cont;	/* location-relative continuation addr.; if bit 2 is set, r9 is set to 0 */
 };
 
 extern void handle_exception (struct pt_regs *regs, const struct exception_table_entry *e);
 extern const struct exception_table_entry *search_exception_tables (unsigned long addr);
 
-# define SEARCH_EXCEPTION_TABLE(regs) search_exception_tables(regs->cr_iip + ia64_psr(regs)->ri)
-
 static inline int
 done_with_exception (struct pt_regs *regs)
 {
 	const struct exception_table_entry *e;
-	e = SEARCH_EXCEPTION_TABLE(regs);
+	e = search_exception_tables(regs->cr_iip + ia64_psr(regs)->ri);
 	if (e) {
 		handle_exception(regs, e);
 		return 1;
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 5e49f861230d745f16216e7f64b9a8d064896883..c405f81be7658eddf0051fba0a35d2baf90864cd 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -856,7 +856,6 @@ extern int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
 /* wrappers around usb_control_msg() for the most common standard requests */
 extern int usb_get_descriptor(struct usb_device *dev, unsigned char desctype,
 	unsigned char descindex, void *buf, int size);
-extern int usb_get_device_descriptor(struct usb_device *dev);
 extern int usb_get_status(struct usb_device *dev,
 	int type, int target, void *data);
 extern int usb_get_string(struct usb_device *dev,
diff --git a/kernel/power/pmdisk.c b/kernel/power/pmdisk.c
index 449d3e57cfdb07060ca368ea831282dbb2cce477..ef35bd28505def68e66b6baabda71988d02bf17e 100644
--- a/kernel/power/pmdisk.c
+++ b/kernel/power/pmdisk.c
@@ -28,6 +28,7 @@
 #include <linux/device.h>
 #include <linux/swapops.h>
 #include <linux/bootmem.h>
+#include <linux/utsname.h>
 
 #include <asm/mmu_context.h>
 
diff --git a/kernel/sched.c b/kernel/sched.c
index 574327cd2e4828cc0183cf1a28a2a47a1df9563e..141e0c348758a32ffbf269194771cab7e234694e 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -124,9 +124,6 @@
 	(NS_TO_JIFFIES((p)->sleep_avg) * MAX_BONUS / \
 		MAX_SLEEP_AVG)
 
-/* spinlock debugging needs this, even on !CONFIG_SMP */
-spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
-
 #ifdef CONFIG_SMP
 #define TIMESLICE_GRANULARITY(p)	(MIN_TIMESLICE * \
 		(1 << (((MAX_BONUS - CURRENT_BONUS(p)) ? : 1) - 1)) * \
@@ -2859,7 +2856,6 @@ __init int migration_init(void)
 
 #endif
 
-#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
 /*
  * The 'big kernel lock'
  *
@@ -2869,10 +2865,11 @@ __init int migration_init(void)
  * been migrated to a proper locking design yet.
  *
  * Don't use in new code.
+ *
+ * Note: spinlock debugging needs this even on !CONFIG_SMP.
  */
-
+spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
 EXPORT_SYMBOL(kernel_flag);
-#endif
 
 static void kstat_init_cpu(int cpu)
 {
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 480292321923509311a044051fb5108495df7cdb..f6926ed69d37954f9296c0df70f609ad5488d53d 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -33,6 +33,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/usb.h>
+#include <linux/usb_ch9.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/pcm.h>
@@ -2560,9 +2561,10 @@ static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interfac
 		err = usb_control_msg(dev, usb_sndctrlpipe(dev,0),
 				      0x10, 0x43, 0x0001, 0x000a, NULL, 0, HZ);
 		if (err < 0) snd_printdd("error sending boot message: %d\n", err);
-		err = usb_get_device_descriptor(dev);
+		err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
+				&dev->descriptor, sizeof(dev->descriptor));
 		config = dev->actconfig;
-		if (err < 0) snd_printdd("error usb_get_device_descriptor: %d\n", err);
+		if (err < 0) snd_printdd("error usb_get_descriptor: %d\n", err);
 		err = usb_reset_configuration(dev);
 		if (err < 0) snd_printdd("error usb_reset_configuration: %d\n", err);
 		snd_printdd("extigy_boot: new boot length = %d\n", get_cfg_desc(config)->wTotalLength);