## Automatically generated incremental diff
## From:   linux-2.2.12-pre1
## To:     linux-2.2.12-pre3
## Robot:  $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp hpa $

diff -urN linux-2.2.12-pre1/arch/alpha/kernel/alpha_ksyms.c linux-2.2.12-pre3/arch/alpha/kernel/alpha_ksyms.c
--- linux-2.2.12-pre1/arch/alpha/kernel/alpha_ksyms.c	1999-05-22 13:41:43.000000000 -0700
+++ linux-2.2.12-pre3/arch/alpha/kernel/alpha_ksyms.c	2003-08-15 15:06:49.000000000 -0700
@@ -14,8 +14,6 @@
 #include <linux/in.h>
 #include <linux/in6.h>
 #include <linux/pci.h>
-#include <linux/tty.h>
-#include <linux/mm.h>
 
 #include <asm/io.h>
 #include <asm/hwrpb.h>
@@ -25,10 +23,6 @@
 #include <linux/interrupt.h>
 #include <asm/softirq.h>
 #include <asm/fpu.h>
-#include <asm/irq.h>
-#include <asm/machvec.h>
-#include <asm/pgtable.h>
-#include <asm/semaphore.h>
 
 #define __KERNEL_SYSCALLS__
 #include <asm/unistd.h>
@@ -47,14 +41,8 @@
 extern void __divqu (void);
 extern void __remqu (void);
 
-EXPORT_SYMBOL(alpha_mv);
 EXPORT_SYMBOL(local_bh_count);
 EXPORT_SYMBOL(local_irq_count);
-EXPORT_SYMBOL(enable_irq);
-EXPORT_SYMBOL(disable_irq);
-EXPORT_SYMBOL(disable_irq_nosync);
-EXPORT_SYMBOL(screen_info);
-EXPORT_SYMBOL(perf_irq);
 
 /* platform dependent support */
 EXPORT_SYMBOL(_inb);
@@ -71,7 +59,7 @@
 EXPORT_SYMBOL(_writel);
 EXPORT_SYMBOL(_memcpy_fromio);
 EXPORT_SYMBOL(_memcpy_toio);
-EXPORT_SYMBOL(_memset_c_io);
+EXPORT_SYMBOL(_memset_io);
 EXPORT_SYMBOL(insb);
 EXPORT_SYMBOL(insw);
 EXPORT_SYMBOL(insl);
@@ -88,14 +76,12 @@
 EXPORT_SYMBOL(strncat);
 EXPORT_SYMBOL(strstr);
 EXPORT_SYMBOL(strtok);
-EXPORT_SYMBOL(strpbrk);
 EXPORT_SYMBOL(strchr);
 EXPORT_SYMBOL(strrchr);
 EXPORT_SYMBOL(memcmp);
 EXPORT_SYMBOL(memmove);
 EXPORT_SYMBOL(__memcpy);
 EXPORT_SYMBOL(__memset);
-EXPORT_SYMBOL(__memsetw);
 EXPORT_SYMBOL(__constant_c_memset);
 
 EXPORT_SYMBOL(dump_thread);
@@ -129,9 +115,7 @@
 
 #ifdef CONFIG_MATHEMU_MODULE
 extern long (*alpha_fp_emul_imprecise)(struct pt_regs *, unsigned long);
-extern long (*alpha_fp_emul) (unsigned long pc);
 EXPORT_SYMBOL(alpha_fp_emul_imprecise);
-EXPORT_SYMBOL(alpha_fp_emul);
 #endif
 
 /*
@@ -143,44 +127,6 @@
 EXPORT_SYMBOL(__strlen_user);
 
 /*
- * The following are specially called from the semaphore assembly stubs.
- */
-EXPORT_SYMBOL_NOVERS(__down_failed);
-EXPORT_SYMBOL_NOVERS(__down_failed_interruptible);
-EXPORT_SYMBOL_NOVERS(__up_wakeup);
-
-/* 
- * SMP-specific symbols.
- */
-
-#ifdef __SMP__
-EXPORT_SYMBOL(synchronize_irq);
-EXPORT_SYMBOL(flush_tlb_all);
-EXPORT_SYMBOL(flush_tlb_mm);
-EXPORT_SYMBOL(flush_tlb_page);
-EXPORT_SYMBOL(flush_tlb_range);
-EXPORT_SYMBOL(cpu_data);
-EXPORT_SYMBOL(cpu_number_map);
-EXPORT_SYMBOL(global_bh_lock);
-EXPORT_SYMBOL(global_bh_count);
-EXPORT_SYMBOL(synchronize_bh);
-EXPORT_SYMBOL(global_irq_holder);
-EXPORT_SYMBOL(__global_cli);
-EXPORT_SYMBOL(__global_sti);
-EXPORT_SYMBOL(__global_save_flags);
-EXPORT_SYMBOL(__global_restore_flags);
-#if DEBUG_SPINLOCK
-EXPORT_SYMBOL(spin_unlock);
-EXPORT_SYMBOL(debug_spin_lock);
-EXPORT_SYMBOL(debug_spin_trylock);
-#endif
-#if DEBUG_RWLOCK
-EXPORT_SYMBOL(write_lock);
-EXPORT_SYMBOL(read_lock);
-#endif
-#endif /* __SMP__ */
-
-/*
  * The following are special because they're not called
  * explicitly (the C compiler or assembler generates them in
  * response to division operations).  Fortunately, their
diff -urN linux-2.2.12-pre1/arch/i386/config.in linux-2.2.12-pre3/arch/i386/config.in
--- linux-2.2.12-pre1/arch/i386/config.in	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/arch/i386/config.in	1999-08-09 12:04:38.000000000 -0700
@@ -172,7 +172,7 @@
 
 source drivers/char/Config.in
 
-source drivers/usb/Config.in
+# source drivers/usb/Config.in
 
 source fs/Config.in
 
diff -urN linux-2.2.12-pre1/arch/sparc64/kernel/process.c linux-2.2.12-pre3/arch/sparc64/kernel/process.c
--- linux-2.2.12-pre1/arch/sparc64/kernel/process.c	1999-05-11 08:24:32.000000000 -0700
+++ linux-2.2.12-pre3/arch/sparc64/kernel/process.c	2003-08-15 15:06:49.000000000 -0700
@@ -652,10 +652,14 @@
  * a system call from a "real" process, but the process memory space will
  * not be free'd until both the parent and the child have exited.
  */
-pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+pid_t kernel_thread(int (*__fn)(void *), void * __arg, unsigned long flags)
 {
+	register int (*fn)(void *) asm("g2");
+	register void *arg asm("g3");
 	long retval;
 
+	fn = __fn;
+	arg = __arg;
 	__asm__ __volatile("mov %1, %%g1\n\t"
 			   "mov %2, %%o0\n\t"	   /* Clone flags. */
 			   "mov 0, %%o1\n\t"	   /* usp arg == 0 */
diff -urN linux-2.2.12-pre1/drivers/block/floppy.c linux-2.2.12-pre3/drivers/block/floppy.c
--- linux-2.2.12-pre1/drivers/block/floppy.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/block/floppy.c	2003-08-15 15:06:49.000000000 -0700
@@ -106,6 +106,12 @@
  * 1998/09/20 -- David Weinehall -- Added slow-down code for buggy PS/2-drives.
  */
 
+/*
+ * 1999/08/13 -- Paul Slootman -- floppy stopped working on Alpha after 24
+ * days, 6 hours, 32 minutes and 32 seconds (i.e. MAXINT jiffies; ints were
+ * being used to store jiffies, which are unsigned longs).
+ */
+
 #define FLOPPY_SANITY_CHECK
 #undef  FLOPPY_SILENT_DCL_CLEAR
 
@@ -604,10 +610,10 @@
 #define OLOGSIZE 20
 
 static void (*lasthandler)(void) = NULL;
-static int interruptjiffies=0;
-static int resultjiffies=0;
+static unsigned long interruptjiffies=0;
+static unsigned long resultjiffies=0;
 static int resultsize=0;
-static int lastredo=0;
+static unsigned long lastredo=0;
 
 static struct output_log {
 	unsigned char data;
@@ -627,7 +633,7 @@
 		drive = current_drive;
 	del_timer(&fd_timeout);
 	if (drive < 0 || drive > N_DRIVE) {
-		fd_timeout.expires = jiffies + 20*HZ;
+		fd_timeout.expires = jiffies + 20UL*HZ;
 		drive=0;
 	} else
 		fd_timeout.expires = jiffies + UDP->timeout;
@@ -710,7 +716,7 @@
 #ifdef DCL_DEBUG
 	if (UDP->flags & FD_DEBUG){
 		DPRINT("checking disk change line for drive %d\n",drive);
-		DPRINT("jiffies=%ld\n", jiffies);
+		DPRINT("jiffies=%lu\n", jiffies);
 		DPRINT("disk change line=%x\n",fd_inb(FD_DIR)&0x80);
 		DPRINT("flags=%lx\n",UDRS->flags);
 	}
@@ -1004,7 +1010,7 @@
 }
 
 /* waits for a delay (spinup or select) to pass */
-static int wait_for_completion(int delay, timeout_fn function)
+static int wait_for_completion(unsigned long delay, timeout_fn function)
 {
 	if (FDCS->reset){
 		reset_fdc(); /* do the reset during sleep to win time
@@ -1275,7 +1281,7 @@
 static void fdc_specify(void)
 {
 	unsigned char spec1, spec2;
-	int srt, hlt, hut;
+	unsigned long srt, hlt, hut;
 	unsigned long dtr = NOMINAL_DTR;
 	unsigned long scale_dtr = NOMINAL_DTR;
 	int hlt_max_code = 0x7f;
@@ -1365,7 +1371,7 @@
 	 * Pause 5 msec to avoid trouble. (Needs to be 2 jiffies)
 	 */
 	FDCS->dtr = raw_cmd->rate & 3;
-	return(wait_for_completion(jiffies+2*HZ/100,
+	return(wait_for_completion(jiffies+2UL*HZ/100,
 				   (timeout_fn) floppy_ready));
 } /* fdc_dtr */
 
@@ -1461,7 +1467,8 @@
  */
 static void setup_rw_floppy(void)
 {
-	int i,ready_date,r, flags,dflags;
+	int i,r, flags,dflags;
+	unsigned long ready_date;
 	timeout_fn function;
 
 	flags = raw_cmd->flags;
@@ -1534,7 +1541,7 @@
 #ifdef DCL_DEBUG
 		if (DP->flags & FD_DEBUG){
 			DPRINT("clearing NEWCHANGE flag because of effective seek\n");
-			DPRINT("jiffies=%ld\n", jiffies);
+			DPRINT("jiffies=%lu\n", jiffies);
 		}
 #endif
 		CLEARF(FD_DISK_NEWCHANGE); /* effective seek */
@@ -1824,20 +1831,20 @@
 	printk("\n");
 	printk("floppy driver state\n");
 	printk("-------------------\n");
-	printk("now=%ld last interrupt=%d last called handler=%p\n",
-	       jiffies, interruptjiffies, lasthandler);
+	printk("now=%lu last interrupt=%lu diff=%lu last called handler=%p\n",
+	       jiffies, interruptjiffies, jiffies-interruptjiffies, lasthandler);
 
 
 #ifdef FLOPPY_SANITY_CHECK
 	printk("timeout_message=%s\n", timeout_message);
 	printk("last output bytes:\n");
 	for (i=0; i < OLOGSIZE; i++)
-		printk("%2x %2x %ld\n",
+		printk("%2x %2x %lu\n",
 		       output_log[(i+output_log_pos) % OLOGSIZE].data,
 		       output_log[(i+output_log_pos) % OLOGSIZE].status,
 		       output_log[(i+output_log_pos) % OLOGSIZE].jiffies);
-	printk("last result at %d\n", resultjiffies);
-	printk("last redo_fd_request at %d\n", lastredo);
+	printk("last result at %lu\n", resultjiffies);
+	printk("last redo_fd_request at %lu\n", lastredo);
 	for (i=0; i<resultsize; i++){
 		printk("%2x ", reply_buffer[i]);
 	}
@@ -1854,8 +1861,8 @@
 		printk("fd_timer.function=%p\n", fd_timer.function);
 	if (fd_timeout.prev){
 		printk("timer_table=%p\n",fd_timeout.function);
-		printk("expires=%ld\n",fd_timeout.expires-jiffies);
-		printk("now=%ld\n",jiffies);
+		printk("expires=%lu\n",fd_timeout.expires-jiffies);
+		printk("now=%lu\n",jiffies);
 	}
 	printk("cont=%p\n", cont);
 	printk("CURRENT=%p\n", CURRENT);
@@ -3000,12 +3007,12 @@
  * Misc Ioctl's and support
  * ========================
  */
-static inline int fd_copyout(void *param, const void *address, int size)
+static inline int fd_copyout(void *param, const void *address, unsigned long size)
 {
 	return copy_to_user(param,address, size) ? -EFAULT : 0;
 }
 
-static inline int fd_copyin(void *param, void *address, int size)
+static inline int fd_copyin(void *param, void *address, unsigned long size)
 {
 	return copy_from_user(address, param, size) ? -EFAULT : 0;
 }
@@ -3811,7 +3818,7 @@
 	if (UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY))
 		return 1;
 
-	if (UDP->checkfreq < jiffies - UDRS->last_checked){
+	if (UDP->checkfreq < (int)(jiffies - UDRS->last_checked)) {
 		lock_fdc(drive,0);
 		poll_drive(0,0);
 		process_fd_request();
diff -urN linux-2.2.12-pre1/drivers/block/xor.c linux-2.2.12-pre3/drivers/block/xor.c
--- linux-2.2.12-pre1/drivers/block/xor.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/block/xor.c	2003-08-15 15:06:49.000000000 -0700
@@ -847,7 +847,7 @@
  * Copyright (C) 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz)
  *
  *	Requirements:
- *	!(((long)destp | (long)sourcep) & (64 - 1)) &&
+ *	!(((long)dest | (long)sourceN) & (64 - 1)) &&
  *	!(len & 127) && len >= 256
  *
  * It is done in pure assembly, as otherwise gcc makes it
@@ -855,24 +855,28 @@
  * Also, we don't measure the speeds as on other architectures,
  * as the measuring routine does not take into account cold caches
  * and the fact that xor_block_VIS bypasses the caches.
- * xor_block_32regs might be 5% faster if caches are hot and things
- * just right, but I think it is better not to pollute the caches.
+ * xor_block_32regs might be 5% faster for count 2 if caches are hot
+ * and things just right (for count 3 VIS is about as fast as 32regs for
+ * hot caches and for count 4 and 5 VIS is faster by good margin always),
+ * but I think it is better not to pollute the caches.
  * Actually, if I'd just fight for speed for hot caches, I could
  * write a hybrid VIS/integer routine, which would do always two
  * 64B blocks in VIS and two in IEUs, but I really care more about
  * caches.
  */
 extern void *VISenter(void);
-extern void xor_block_VIS SRCDEST;
+extern void xor_block_VIS XOR_ARGS;
 
 void __xor_block_VIS(void)
 {
 __asm__ ("
 	.globl xor_block_VIS
 xor_block_VIS:
-	ldx	[%%o1 + %0], %%o1
-	ldx	[%%o0 + %1], %%o2
-	ldx	[%%o0 + %0], %%o0
+	ldx	[%%o1 + 0], %%o4
+	ldx	[%%o1 + 8], %%o3
+	ldx	[%%o4 + %1], %%g5
+	ldx	[%%o4 + %0], %%o4
+	ldx	[%%o3 + %0], %%o3
 	rd	%%fprs, %%o5
 	andcc	%%o5, %2, %%g0
 	be,pt	%%icc, 297f
@@ -880,38 +884,170 @@
 	jmpl	%%g1 + %%lo(%5), %%g7
 	 add	%%g7, 8, %%g7
 297:	wr	%%g0, %4, %%fprs
-	wr	%%g0, %3, %%asi
 	membar	#LoadStore|#StoreLoad|#StoreStore
-	sub	%%o2, 128, %%o2
-	ldda	[%%o0] %3, %%f0
-	ldda	[%%o1] %3, %%f16
-1:	ldda	[%%o0 + 64] %%asi, %%f32
+	sub	%%g5, 64, %%g5
+	ldda	[%%o4] %3, %%f0
+	ldda	[%%o3] %3, %%f16
+	cmp	%%o0, 4
+	bgeu,pt	%%xcc, 10f
+	 cmp	%%o0, 3
+	be,pn	%%xcc, 13f
+	 mov	-64, %%g1
+	sub	%%g5, 64, %%g5
+	rd	%%asi, %%g1
+	wr	%%g0, %3, %%asi
+
+2:	ldda	[%%o4 + 64] %%asi, %%f32
+	fxor	%%f0, %%f16, %%f16
+	fxor	%%f2, %%f18, %%f18
+	fxor	%%f4, %%f20, %%f20
+	fxor	%%f6, %%f22, %%f22
+	fxor	%%f8, %%f24, %%f24
+	fxor	%%f10, %%f26, %%f26
+	fxor	%%f12, %%f28, %%f28
+	fxor	%%f14, %%f30, %%f30
+	stda	%%f16, [%%o4] %3
+	ldda	[%%o3 + 64] %%asi, %%f48
+	ldda	[%%o4 + 128] %%asi, %%f0
+	fxor	%%f32, %%f48, %%f48
+	fxor	%%f34, %%f50, %%f50
+	add	%%o4, 128, %%o4
+	fxor	%%f36, %%f52, %%f52
+	add	%%o3, 128, %%o3
+	fxor	%%f38, %%f54, %%f54
+	subcc	%%g5, 128, %%g5
+	fxor	%%f40, %%f56, %%f56
+	fxor	%%f42, %%f58, %%f58
+	fxor	%%f44, %%f60, %%f60
+	fxor	%%f46, %%f62, %%f62
+	stda	%%f48, [%%o4 - 64] %%asi
+	bne,pt	%%xcc, 2b
+	 ldda	[%%o3] %3, %%f16
+
+	ldda	[%%o4 + 64] %%asi, %%f32
+	fxor	%%f0, %%f16, %%f16
+	fxor	%%f2, %%f18, %%f18
+	fxor	%%f4, %%f20, %%f20
+	fxor	%%f6, %%f22, %%f22
+	fxor	%%f8, %%f24, %%f24
+	fxor	%%f10, %%f26, %%f26
+	fxor	%%f12, %%f28, %%f28
+	fxor	%%f14, %%f30, %%f30
+	stda	%%f16, [%%o4] %3
+	ldda	[%%o3 + 64] %%asi, %%f48
+	membar	#Sync
+	fxor	%%f32, %%f48, %%f48
+	fxor	%%f34, %%f50, %%f50
+	fxor	%%f36, %%f52, %%f52
+	fxor	%%f38, %%f54, %%f54
+	fxor	%%f40, %%f56, %%f56
+	fxor	%%f42, %%f58, %%f58
+	fxor	%%f44, %%f60, %%f60
+	fxor	%%f46, %%f62, %%f62
+	stda	%%f48, [%%o4 + 64] %%asi
+	membar	#Sync|#StoreStore|#StoreLoad
+	wr	%%g0, 0, %%fprs
+	retl
+	 wr	%%g1, %%g0, %%asi
+
+13:	ldx	[%%o1 + 16], %%o2
+	ldx	[%%o2 + %0], %%o2
+
+3:	ldda	[%%o2] %3, %%f32
+	fxor	%%f0, %%f16, %%f48
+	fxor	%%f2, %%f18, %%f50
+	add	%%o4, 64, %%o4
+	fxor	%%f4, %%f20, %%f52
+	fxor	%%f6, %%f22, %%f54
+	add	%%o3, 64, %%o3
+	fxor	%%f8, %%f24, %%f56
+	fxor	%%f10, %%f26, %%f58
+	fxor	%%f12, %%f28, %%f60
+	fxor	%%f14, %%f30, %%f62
+	ldda	[%%o4] %3, %%f0
+	fxor	%%f48, %%f32, %%f48
+	fxor	%%f50, %%f34, %%f50
+	fxor	%%f52, %%f36, %%f52
+	fxor	%%f54, %%f38, %%f54
+	add	%%o2, 64, %%o2
+	fxor	%%f56, %%f40, %%f56
+	fxor	%%f58, %%f42, %%f58
+	subcc	%%g5, 64, %%g5
+	fxor	%%f60, %%f44, %%f60
+	fxor	%%f62, %%f46, %%f62
+	stda	%%f48, [%%o4 + %%g1] %3
+	bne,pt	%%xcc, 3b
+	 ldda	[%%o3] %3, %%f16
+
+	ldda	[%%o2] %3, %%f32
+	fxor	%%f0, %%f16, %%f48
+	fxor	%%f2, %%f18, %%f50
+	fxor	%%f4, %%f20, %%f52
+	fxor	%%f6, %%f22, %%f54
+	fxor	%%f8, %%f24, %%f56
+	fxor	%%f10, %%f26, %%f58
+	fxor	%%f12, %%f28, %%f60
+	fxor	%%f14, %%f30, %%f62
+	membar	#Sync
+	fxor	%%f48, %%f32, %%f48
+	fxor	%%f50, %%f34, %%f50
+	fxor	%%f52, %%f36, %%f52
+	fxor	%%f54, %%f38, %%f54
+	fxor	%%f56, %%f40, %%f56
+	fxor	%%f58, %%f42, %%f58
+	fxor	%%f60, %%f44, %%f60
+	fxor	%%f62, %%f46, %%f62
+	stda	%%f48, [%%o4] %3
+	membar	#Sync|#StoreStore|#StoreLoad
+	retl
+	 wr	%%g0, 0, %%fprs
+
+10:	cmp	%%o0, 5
+	be,pt	%%xcc, 15f
+	 mov	-64, %%g1
+
+14:	ldx	[%%o1 + 16], %%o2
+	ldx	[%%o1 + 24], %%o0
+	ldx	[%%o2 + %0], %%o2
+	ldx	[%%o0 + %0], %%o0
+
+4:	ldda	[%%o2] %3, %%f32
 	fxor	%%f0, %%f16, %%f16
 	fxor	%%f2, %%f18, %%f18
+	add	%%o4, 64, %%o4
 	fxor	%%f4, %%f20, %%f20
 	fxor	%%f6, %%f22, %%f22
+	add	%%o3, 64, %%o3
 	fxor	%%f8, %%f24, %%f24
 	fxor	%%f10, %%f26, %%f26
 	fxor	%%f12, %%f28, %%f28
 	fxor	%%f14, %%f30, %%f30
-	stda	%%f16, [%%o0] %3
-	ldda	[%%o1 + 64] %%asi, %%f48
-	ldda	[%%o0 + 128] %%asi, %%f0
+	ldda	[%%o0] %3, %%f48
+	fxor	%%f16, %%f32, %%f32
+	fxor	%%f18, %%f34, %%f34
+	fxor	%%f20, %%f36, %%f36
+	fxor	%%f22, %%f38, %%f38
+	add	%%o2, 64, %%o2
+	fxor	%%f24, %%f40, %%f40
+	fxor	%%f26, %%f42, %%f42
+	fxor	%%f28, %%f44, %%f44
+	fxor	%%f30, %%f46, %%f46
+	ldda	[%%o4] %3, %%f0
 	fxor	%%f32, %%f48, %%f48
 	fxor	%%f34, %%f50, %%f50
-	add	%%o0, 128, %%o0
 	fxor	%%f36, %%f52, %%f52
-	add	%%o1, 128, %%o1
+	add	%%o0, 64, %%o0
 	fxor	%%f38, %%f54, %%f54
-	subcc	%%o2, 128, %%o2
 	fxor	%%f40, %%f56, %%f56
 	fxor	%%f42, %%f58, %%f58
+	subcc	%%g5, 64, %%g5
 	fxor	%%f44, %%f60, %%f60
 	fxor	%%f46, %%f62, %%f62
-	stda	%%f48, [%%o0 - 64] %%asi
-	bne,pt	%%xcc, 1b
-	 ldda	[%%o1] %3, %%f16
-	ldda	[%%o0 + 64] %%asi, %%f32
+	stda	%%f48, [%%o4 + %%g1] %3
+	bne,pt	%%xcc, 4b
+	 ldda	[%%o3] %3, %%f16
+
+	ldda	[%%o2] %3, %%f32
 	fxor	%%f0, %%f16, %%f16
 	fxor	%%f2, %%f18, %%f18
 	fxor	%%f4, %%f20, %%f20
@@ -920,8 +1056,15 @@
 	fxor	%%f10, %%f26, %%f26
 	fxor	%%f12, %%f28, %%f28
 	fxor	%%f14, %%f30, %%f30
-	stda	%%f16, [%%o0] %3
-	ldda	[%%o1 + 64] %%asi, %%f48
+	ldda	[%%o0] %3, %%f48
+	fxor	%%f16, %%f32, %%f32
+	fxor	%%f18, %%f34, %%f34
+	fxor	%%f20, %%f36, %%f36
+	fxor	%%f22, %%f38, %%f38
+	fxor	%%f24, %%f40, %%f40
+	fxor	%%f26, %%f42, %%f42
+	fxor	%%f28, %%f44, %%f44
+	fxor	%%f30, %%f46, %%f46
 	membar	#Sync
 	fxor	%%f32, %%f48, %%f48
 	fxor	%%f34, %%f50, %%f50
@@ -931,7 +1074,101 @@
 	fxor	%%f42, %%f58, %%f58
 	fxor	%%f44, %%f60, %%f60
 	fxor	%%f46, %%f62, %%f62
-	stda	%%f48, [%%o0 + 64] %%asi
+	stda	%%f48, [%%o4] %3
+	membar	#Sync|#StoreStore|#StoreLoad
+	retl
+	 wr	%%g0, 0, %%fprs
+
+15:	ldx	[%%o1 + 16], %%o2
+	ldx	[%%o1 + 24], %%o0
+	ldx	[%%o1 + 32], %%o1
+	ldx	[%%o2 + %0], %%o2
+	ldx	[%%o0 + %0], %%o0
+	ldx	[%%o1 + %0], %%o1
+
+5:	ldda	[%%o2] %3, %%f32
+	fxor	%%f0, %%f16, %%f48
+	fxor	%%f2, %%f18, %%f50
+	add	%%o4, 64, %%o4
+	fxor	%%f4, %%f20, %%f52
+	fxor	%%f6, %%f22, %%f54
+	add	%%o3, 64, %%o3
+	fxor	%%f8, %%f24, %%f56
+	fxor	%%f10, %%f26, %%f58
+	fxor	%%f12, %%f28, %%f60
+	fxor	%%f14, %%f30, %%f62
+	ldda	[%%o0] %3, %%f16
+	fxor	%%f48, %%f32, %%f48
+	fxor	%%f50, %%f34, %%f50
+	fxor	%%f52, %%f36, %%f52
+	fxor	%%f54, %%f38, %%f54
+	add	%%o2, 64, %%o2
+	fxor	%%f56, %%f40, %%f56
+	fxor	%%f58, %%f42, %%f58
+	fxor	%%f60, %%f44, %%f60
+	fxor	%%f62, %%f46, %%f62
+	ldda	[%%o1] %3, %%f32
+	fxor	%%f48, %%f16, %%f48
+	fxor	%%f50, %%f18, %%f50
+	add	%%o0, 64, %%o0
+	fxor	%%f52, %%f20, %%f52
+	fxor	%%f54, %%f22, %%f54
+	add	%%o1, 64, %%o1
+	fxor	%%f56, %%f24, %%f56
+	fxor	%%f58, %%f26, %%f58
+	fxor	%%f60, %%f28, %%f60
+	fxor	%%f62, %%f30, %%f62
+	ldda	[%%o4] %3, %%f0
+	fxor	%%f48, %%f32, %%f48
+	fxor	%%f50, %%f34, %%f50
+	fxor	%%f52, %%f36, %%f52
+	fxor	%%f54, %%f38, %%f54
+	fxor	%%f56, %%f40, %%f56
+	fxor	%%f58, %%f42, %%f58
+	subcc	%%g5, 64, %%g5
+	fxor	%%f60, %%f44, %%f60
+	fxor	%%f62, %%f46, %%f62
+	stda	%%f48, [%%o4 + %%g1] %3
+	bne,pt	%%xcc, 5b
+	 ldda	[%%o3] %3, %%f16
+
+	ldda	[%%o2] %3, %%f32
+	fxor	%%f0, %%f16, %%f48
+	fxor	%%f2, %%f18, %%f50
+	fxor	%%f4, %%f20, %%f52
+	fxor	%%f6, %%f22, %%f54
+	fxor	%%f8, %%f24, %%f56
+	fxor	%%f10, %%f26, %%f58
+	fxor	%%f12, %%f28, %%f60
+	fxor	%%f14, %%f30, %%f62
+	ldda	[%%o0] %3, %%f16
+	fxor	%%f48, %%f32, %%f48
+	fxor	%%f50, %%f34, %%f50
+	fxor	%%f52, %%f36, %%f52
+	fxor	%%f54, %%f38, %%f54
+	fxor	%%f56, %%f40, %%f56
+	fxor	%%f58, %%f42, %%f58
+	fxor	%%f60, %%f44, %%f60
+	fxor	%%f62, %%f46, %%f62
+	ldda	[%%o1] %3, %%f32
+	fxor	%%f48, %%f16, %%f48
+	fxor	%%f50, %%f18, %%f50
+	fxor	%%f52, %%f20, %%f52
+	fxor	%%f54, %%f22, %%f54
+	fxor	%%f56, %%f24, %%f56
+	fxor	%%f58, %%f26, %%f58
+	fxor	%%f60, %%f28, %%f60
+	fxor	%%f62, %%f30, %%f62
+	membar	#Sync
+	fxor	%%f48, %%f32, %%f48
+	fxor	%%f50, %%f34, %%f50
+	fxor	%%f52, %%f36, %%f52
+	fxor	%%f54, %%f38, %%f54
+	fxor	%%f56, %%f40, %%f56
+	fxor	%%f58, %%f42, %%f58
+	fxor	%%f60, %%f44, %%f60
+	fxor	%%f62, %%f46, %%f62
+	stda	%%f48, [%%o4] %3
 	membar	#Sync|#StoreStore|#StoreLoad
 	retl
 	 wr	%%g0, 0, %%fprs
@@ -954,38 +1191,216 @@
 
 XORBLOCK_TEMPLATE(SPARC)
 {
-	int size  = dest->b_size;
+	int size  = bh_ptr[0]->b_size;
 	int lines = size / (sizeof (long)) / 8, i;
-	long *destp   = (long *) dest->b_data;
-	long *sourcep = (long *) source->b_data;
-
-	for (i = lines; i > 0; i--) {
-	  __asm__ __volatile__("
-	  ldd [%0 + 0x00], %%g2
-	  ldd [%0 + 0x08], %%g4
-	  ldd [%0 + 0x10], %%o0
-	  ldd [%0 + 0x18], %%o2
-	  ldd [%1 + 0x00], %%o4
-	  ldd [%1 + 0x08], %%l0
-	  ldd [%1 + 0x10], %%l2
-	  ldd [%1 + 0x18], %%l4
-	  xor %%g2, %%o4, %%g2
-	  xor %%g3, %%o5, %%g3
-	  xor %%g4, %%l0, %%g4
-	  xor %%g5, %%l1, %%g5
-	  xor %%o0, %%l2, %%o0
-	  xor %%o1, %%l3, %%o1
-	  xor %%o2, %%l4, %%o2
-	  xor %%o3, %%l5, %%o3
-	  std %%g2, [%0 + 0x00]
-	  std %%g4, [%0 + 0x08]
-	  std %%o0, [%0 + 0x10]
-	  std %%o2, [%0 + 0x18]
-	  " : : "r" (destp), "r" (sourcep) : "g2", "g3", "g4", "g5", "o0", 
-	  "o1", "o2", "o3", "o4", "o5", "l0", "l1", "l2", "l3", "l4", "l5");
+	long *destp   = (long *) bh_ptr[0]->b_data;
+	long *source1 = (long *) bh_ptr[1]->b_data;
+	long *source2, *source3, *source4;
 
-	  destp += 8;
-	  sourcep += 8;
+	switch (count) {
+	case 2:
+		for (i = lines; i > 0; i--) {
+		  __asm__ __volatile__("
+		  ldd [%0 + 0x00], %%g2
+		  ldd [%0 + 0x08], %%g4
+		  ldd [%0 + 0x10], %%o0
+		  ldd [%0 + 0x18], %%o2
+		  ldd [%1 + 0x00], %%o4
+		  ldd [%1 + 0x08], %%l0
+		  ldd [%1 + 0x10], %%l2
+		  ldd [%1 + 0x18], %%l4
+		  xor %%g2, %%o4, %%g2
+		  xor %%g3, %%o5, %%g3
+		  xor %%g4, %%l0, %%g4
+		  xor %%g5, %%l1, %%g5
+		  xor %%o0, %%l2, %%o0
+		  xor %%o1, %%l3, %%o1
+		  xor %%o2, %%l4, %%o2
+		  xor %%o3, %%l5, %%o3
+		  std %%g2, [%0 + 0x00]
+		  std %%g4, [%0 + 0x08]
+		  std %%o0, [%0 + 0x10]
+		  std %%o2, [%0 + 0x18]
+		  " : : "r" (destp), "r" (source1) : "g2", "g3", "g4", "g5", "o0", 
+		  "o1", "o2", "o3", "o4", "o5", "l0", "l1", "l2", "l3", "l4", "l5");
+		  destp += 8;
+		  source1 += 8;
+		}
+		break;
+	case 3:
+		source2 = (long *) bh_ptr[2]->b_data;
+		for (i = lines; i > 0; i--) {
+		  __asm__ __volatile__("
+		  ldd [%0 + 0x00], %%g2
+		  ldd [%0 + 0x08], %%g4
+		  ldd [%0 + 0x10], %%o0
+		  ldd [%0 + 0x18], %%o2
+		  ldd [%1 + 0x00], %%o4
+		  ldd [%1 + 0x08], %%l0
+		  ldd [%1 + 0x10], %%l2
+		  ldd [%1 + 0x18], %%l4
+		  xor %%g2, %%o4, %%g2
+		  xor %%g3, %%o5, %%g3
+		  ldd [%2 + 0x00], %%o4
+		  xor %%g4, %%l0, %%g4
+		  xor %%g5, %%l1, %%g5
+		  ldd [%2 + 0x08], %%l0
+		  xor %%o0, %%l2, %%o0
+		  xor %%o1, %%l3, %%o1
+		  ldd [%2 + 0x10], %%l2
+		  xor %%o2, %%l4, %%o2
+		  xor %%o3, %%l5, %%o3
+		  ldd [%2 + 0x18], %%l4
+		  xor %%g2, %%o4, %%g2
+		  xor %%g3, %%o5, %%g3
+		  xor %%g4, %%l0, %%g4
+		  xor %%g5, %%l1, %%g5
+		  xor %%o0, %%l2, %%o0
+		  xor %%o1, %%l3, %%o1
+		  xor %%o2, %%l4, %%o2
+		  xor %%o3, %%l5, %%o3
+		  std %%g2, [%0 + 0x00]
+		  std %%g4, [%0 + 0x08]
+		  std %%o0, [%0 + 0x10]
+		  std %%o2, [%0 + 0x18]
+		  " : : "r" (destp), "r" (source1), "r" (source2)
+		  : "g2", "g3", "g4", "g5", "o0", "o1", "o2", "o3", "o4", "o5",
+		  "l0", "l1", "l2", "l3", "l4", "l5");
+		  destp += 8;
+		  source1 += 8;
+		  source2 += 8;
+		}
+		break;
+	case 4:
+		source2 = (long *) bh_ptr[2]->b_data;
+		source3 = (long *) bh_ptr[3]->b_data;
+		for (i = lines; i > 0; i--) {
+		  __asm__ __volatile__("
+		  ldd [%0 + 0x00], %%g2
+		  ldd [%0 + 0x08], %%g4
+		  ldd [%0 + 0x10], %%o0
+		  ldd [%0 + 0x18], %%o2
+		  ldd [%1 + 0x00], %%o4
+		  ldd [%1 + 0x08], %%l0
+		  ldd [%1 + 0x10], %%l2
+		  ldd [%1 + 0x18], %%l4
+		  xor %%g2, %%o4, %%g2
+		  xor %%g3, %%o5, %%g3
+		  ldd [%2 + 0x00], %%o4
+		  xor %%g4, %%l0, %%g4
+		  xor %%g5, %%l1, %%g5
+		  ldd [%2 + 0x08], %%l0
+		  xor %%o0, %%l2, %%o0
+		  xor %%o1, %%l3, %%o1
+		  ldd [%2 + 0x10], %%l2
+		  xor %%o2, %%l4, %%o2
+		  xor %%o3, %%l5, %%o3
+		  ldd [%2 + 0x18], %%l4
+		  xor %%g2, %%o4, %%g2
+		  xor %%g3, %%o5, %%g3
+		  ldd [%3 + 0x00], %%o4
+		  xor %%g4, %%l0, %%g4
+		  xor %%g5, %%l1, %%g5
+		  ldd [%3 + 0x08], %%l0
+		  xor %%o0, %%l2, %%o0
+		  xor %%o1, %%l3, %%o1
+		  ldd [%3 + 0x10], %%l2
+		  xor %%o2, %%l4, %%o2
+		  xor %%o3, %%l5, %%o3
+		  ldd [%3 + 0x18], %%l4
+		  xor %%g2, %%o4, %%g2
+		  xor %%g3, %%o5, %%g3
+		  xor %%g4, %%l0, %%g4
+		  xor %%g5, %%l1, %%g5
+		  xor %%o0, %%l2, %%o0
+		  xor %%o1, %%l3, %%o1
+		  xor %%o2, %%l4, %%o2
+		  xor %%o3, %%l5, %%o3
+		  std %%g2, [%0 + 0x00]
+		  std %%g4, [%0 + 0x08]
+		  std %%o0, [%0 + 0x10]
+		  std %%o2, [%0 + 0x18]
+		  " : : "r" (destp), "r" (source1), "r" (source2), "r" (source3)
+		  : "g2", "g3", "g4", "g5", "o0", "o1", "o2", "o3", "o4", "o5",
+		  "l0", "l1", "l2", "l3", "l4", "l5");
+		  destp += 8;
+		  source1 += 8;
+		  source2 += 8;
+		  source3 += 8;
+		}
+		break;
+	case 5:
+		source2 = (long *) bh_ptr[2]->b_data;
+		source3 = (long *) bh_ptr[3]->b_data;
+		source4 = (long *) bh_ptr[4]->b_data;
+		for (i = lines; i > 0; i--) {
+		  __asm__ __volatile__("
+		  ldd [%0 + 0x00], %%g2
+		  ldd [%0 + 0x08], %%g4
+		  ldd [%0 + 0x10], %%o0
+		  ldd [%0 + 0x18], %%o2
+		  ldd [%1 + 0x00], %%o4
+		  ldd [%1 + 0x08], %%l0
+		  ldd [%1 + 0x10], %%l2
+		  ldd [%1 + 0x18], %%l4
+		  xor %%g2, %%o4, %%g2
+		  xor %%g3, %%o5, %%g3
+		  ldd [%2 + 0x00], %%o4
+		  xor %%g4, %%l0, %%g4
+		  xor %%g5, %%l1, %%g5
+		  ldd [%2 + 0x08], %%l0
+		  xor %%o0, %%l2, %%o0
+		  xor %%o1, %%l3, %%o1
+		  ldd [%2 + 0x10], %%l2
+		  xor %%o2, %%l4, %%o2
+		  xor %%o3, %%l5, %%o3
+		  ldd [%2 + 0x18], %%l4
+		  xor %%g2, %%o4, %%g2
+		  xor %%g3, %%o5, %%g3
+		  ldd [%3 + 0x00], %%o4
+		  xor %%g4, %%l0, %%g4
+		  xor %%g5, %%l1, %%g5
+		  ldd [%3 + 0x08], %%l0
+		  xor %%o0, %%l2, %%o0
+		  xor %%o1, %%l3, %%o1
+		  ldd [%3 + 0x10], %%l2
+		  xor %%o2, %%l4, %%o2
+		  xor %%o3, %%l5, %%o3
+		  ldd [%3 + 0x18], %%l4
+		  xor %%g2, %%o4, %%g2
+		  xor %%g3, %%o5, %%g3
+		  ldd [%4 + 0x00], %%o4
+		  xor %%g4, %%l0, %%g4
+		  xor %%g5, %%l1, %%g5
+		  ldd [%4 + 0x08], %%l0
+		  xor %%o0, %%l2, %%o0
+		  xor %%o1, %%l3, %%o1
+		  ldd [%4 + 0x10], %%l2
+		  xor %%o2, %%l4, %%o2
+		  xor %%o3, %%l5, %%o3
+		  ldd [%4 + 0x18], %%l4
+		  xor %%g2, %%o4, %%g2
+		  xor %%g3, %%o5, %%g3
+		  xor %%g4, %%l0, %%g4
+		  xor %%g5, %%l1, %%g5
+		  xor %%o0, %%l2, %%o0
+		  xor %%o1, %%l3, %%o1
+		  xor %%o2, %%l4, %%o2
+		  xor %%o3, %%l5, %%o3
+		  std %%g2, [%0 + 0x00]
+		  std %%g4, [%0 + 0x08]
+		  std %%o0, [%0 + 0x10]
+		  std %%o2, [%0 + 0x18]
+		  " : : "r" (destp), "r" (source1), "r" (source2), "r" (source3), "r" (source4)
+		  : "g2", "g3", "g4", "g5", "o0", "o1", "o2", "o3", "o4", "o5",
+		  "l0", "l1", "l2", "l3", "l4", "l5");
+		  destp += 8;
+		  source1 += 8;
+		  source2 += 8;
+		  source3 += 8;
+		  source4 += 8;
+		}
+		break;
 	}
 }
 #endif /* __sparc_v[78]__ */
@@ -1429,7 +1844,7 @@
 	sti(); /* should be safe */
 
 #if defined(__sparc__) && !defined(__sparc_v9__)
-	printk(KERN_INFO "raid5: using high-speed SPARC checksum routine\n");
+	printk(KERN_INFO "raid5: trying high-speed SPARC checksum routine\n");
 	xor_speed(&t_xor_block_SPARC,&b1,&b2);
 #endif
 
diff -urN linux-2.2.12-pre1/drivers/char/mem.c linux-2.2.12-pre3/drivers/char/mem.c
--- linux-2.2.12-pre1/drivers/char/mem.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/char/mem.c	1999-08-09 12:04:57.000000000 -0700
@@ -52,8 +52,14 @@
 #if defined(CONFIG_PPC) || defined(CONFIG_MAC)
 extern void adbdev_init(void);
 #endif
-#ifdef CONFIG_USB
-extern void usb_init(void);
+#ifdef CONFIG_USB_UHCI
+int uhci_init(void);
+#endif
+#ifdef CONFIG_USB_OHCI
+int ohci_init(void);
+#endif
+#ifdef CONFIG_USB_OHCI_HCD
+int ohci_hcd_init(void);
 #endif
      
 static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
@@ -612,7 +618,15 @@
 		printk("unable to get major %d for memory devs\n", MEM_MAJOR);
 	rand_initialize();
 #ifdef CONFIG_USB
-	usb_init();
+#ifdef CONFIG_USB_UHCI
+	uhci_init();
+#endif
+#ifdef CONFIG_USB_OHCI
+	ohci_init();
+#endif
+#ifdef CONFIG_USB_OHCI_HCD
+        ohci_hcd_init(); 
+#endif
 #endif
 #if defined (CONFIG_FB)
 	fbmem_init();
diff -urN linux-2.2.12-pre1/drivers/sound/sb_common.c linux-2.2.12-pre3/drivers/sound/sb_common.c
--- linux-2.2.12-pre1/drivers/sound/sb_common.c	1999-04-12 16:18:27.000000000 -0700
+++ linux-2.2.12-pre3/drivers/sound/sb_common.c	2003-08-15 15:06:49.000000000 -0700
@@ -897,7 +897,7 @@
 		}
 		if (!(devc->caps & SB_NO_AUDIO && devc->caps & SB_NO_MIDI))
 		{
-			if (devc->irq > 0);
+			if (devc->irq > 0)
 				free_irq(devc->irq, devc);
 
 			sound_unload_mixerdev(devc->my_mixerdev);
diff -urN linux-2.2.12-pre1/drivers/usb/acm.c linux-2.2.12-pre3/drivers/usb/acm.c
--- linux-2.2.12-pre1/drivers/usb/acm.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/acm.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,295 +0,0 @@
-/*
- * USB Abstract Control Model based on Brad Keryan's USB busmouse driver 
- *
- * Armin Fuerst 5/8/1999
- *
- * version 0.2: Improved Bulk transfer. TX led now flashes every time data is
- * sent. Send Encapsulated Data is not needed, nor does it do anything.
- * Why's that ?!? Thanks to Thomas Sailer for his close look at the bulk code.
- * He told me about some importand bugs. (5/21/99)
- *
- * version 0.1: Bulk transfer for uhci seems to work now, no dangling tds any
- * more. TX led of the ISDN TA flashed the first time. Does this mean it works?
- * The interrupt of the ctrl endpoint crashes the kernel => no read possible
- * (5/19/99)
- *
- * version 0.0: Driver sets up configuration, sets up data pipes, opens misc
- * device. No actual data transfer is done, since we don't have bulk transfer,
- * yet. Purely skeleton for now. (5/8/99)
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/errno.h>
-#include <linux/miscdevice.h>
-#include <linux/poll.h>
-#include <linux/init.h>
-#include <linux/malloc.h>
-#include <linux/module.h>
-
-#include <asm/spinlock.h>
-
-#include "usb.h"
-
-#define USB_ACM_MINOR 32
-
-struct acm_state {
-	int present; /* this acm is plugged in */
-	int active; /* someone is has this acm's device open */
-	int serstate; /* Status of the serial port (rate, handshakelines,...) */
-	struct usb_device *dev;
-	unsigned ctrlbuffer;	/*buffer for control messages*/
-	unsigned int readendp,writeendp,ctrlendp;
-	unsigned int readpipe,writepipe,ctrlpipe;
-	char buffer;
-};
-
-static struct acm_state static_acm_state;
-
-spinlock_t usb_acm_lock = SPIN_LOCK_UNLOCKED;
-
-static int acm_irq(int state, void *__buffer, int len, void *dev_id)
-{
-//	unsigned char *data = __buffer;
-        struct acm_state *acm = &static_acm_state; 
-        devrequest *dr;
-
-        dr=__buffer;
-	printk("ACM_USB_IRQ\n");
-        printk("reqtype: %02X\n",dr->requesttype);
-        printk("request: %02X\n",dr->request);
-	printk("wValue: %02X\n",dr->value);
-	printk("wIndex: %02X\n",dr->index);
-	printk("wLength: %02X\n",dr->length);
-	
-	switch(dr->request) {
-	  //Network connection 
-	  case 0x00:
-	    printk("Network connection: ");
-	    if (dr->request==0) printk("disconnected\n");
-	    if (dr->request==1) printk("connected\n");
-	    break;
-
-    	  //Response available
-	  case 0x01:
-	    printk("Response available\n");
-	    acm->buffer=1;
-	    break;
-	
-	  //Set serial line state
-	  case 0x20:
-	    if ((dr->index==1)&&(dr->length==2)) {
-	      acm->serstate=acm->ctrlbuffer;
-	      printk("Serstate: %02X\n",acm->ctrlbuffer);
-	    }
-	    break;
-	}
-/*
-	if(!acm->active)
-		return 1;
-*/
-	return 1;
-}
-
-static int release_acm(struct inode * inode, struct file * file)
-{
-	struct acm_state *acm = &static_acm_state;
-	printk("ACM_FILE_RELEASE\n");
-
-//	fasync_acm(-1, file, 0);
-	if (--acm->active)
-		return 0;
-	return 0;
-}
-
-static int open_acm(struct inode * inode, struct file * file)
-{
-	struct acm_state *acm = &static_acm_state;
-	printk("USB_FILE_OPEN\n");
-
-	if (!acm->present)
-		return -EINVAL;
-	if (acm->active++)
-		return 0;
-	return 0;
-}
-
-static ssize_t write_acm(struct file * file,
-       const char * buffer, size_t count, loff_t *ppos)
-{
-        devrequest dr;
-	struct acm_state *acm = &static_acm_state;
-	unsigned long retval;	        
-
-	printk("USB_FILE_WRITE\n");
-//Huh, i seem to got that wrong, we don't need this ?!?
-/*
-	dr.requesttype = USB_TYPE_CLASS | USB_RT_ENDPOINT;
-	dr.request = 0;
-	dr.value = 0;
-	dr.index = acm->writeendp;
-	dr.length = count;
-	acm->dev->bus->op->control_msg(acm->dev, usb_sndctrlpipe(acm->dev, 0), &dr, NULL, 0);
-*/	
-
-	acm->dev->bus->op->bulk_msg(acm->dev,&acm->writepipe,buffer, count, &retval);
-	return -EINVAL;
-}
-
-
-static ssize_t read_acm(struct file * file, const char * buffer, size_t count, loff_t *ppos)
-{
-	devrequest dr;
-        struct acm_state *acm = &static_acm_state;
-	unsigned long retval;
-	printk("USB_FILE_READ\n");
-//        if (!acm->buffer) return -1;
-     	acm->buffer=0;
-//We don't need this
-/*
-	printk("writing control msg\n");
-	dr.requesttype = USB_TYPE_CLASS | USB_RT_ENDPOINT | 0x80;
-	dr.request = 1;
-	dr.value = 0;
-	dr.index = acm->readendp;
-	dr.length = 0;
-	acm->dev->bus->op->control_msg(acm->dev, usb_sndctrlpipe(acm->dev, 0), &dr, NULL, 0);
-*/
-	printk("reading:>%s<\n",buffer);
-	acm->dev->bus->op->bulk_msg(acm->dev,&acm->readpipe,buffer, 1,&retval);
-	printk("done:>%s<\n",buffer);
-	return 1;
-}
-
-struct file_operations usb_acm_fops = {
-	NULL,		/* acm_seek */
-	read_acm,
-	write_acm,
-	NULL, 		/* acm_readdir */
-	NULL,	 	/* acm_poll */
-	NULL, 		/* acm_ioctl */
-	NULL,		/* acm_mmap */
-	open_acm,
-	NULL,		/* flush */
-	release_acm,
-	NULL,
-	NULL,		/*fasync*/
-};
-
-static struct miscdevice usb_acm = {
-	USB_ACM_MINOR, "USB ACM", &usb_acm_fops
-};
-
-static int acm_probe(struct usb_device *dev)
-{
-	struct usb_interface_descriptor *interface;
-	struct usb_endpoint_descriptor *endpoint;
-	struct acm_state *acm = &static_acm_state;
-	int cfgnum;
-
-	/* Only use CDC */
-	if (dev->descriptor.bDeviceClass != 2 ||
-	    dev->descriptor.bDeviceSubClass != 0 ||
-            dev->descriptor.bDeviceProtocol != 0)
-		return -1;
-
-	/*Now scan all configs for a ACM configuration*/
-	for (cfgnum=0;cfgnum<dev->descriptor.bNumConfigurations;cfgnum++) {
-		/* The first one should be Communications interface? */
-		interface = &dev->config[cfgnum].altsetting[0].interface[0];
-		if (interface->bInterfaceClass != 2 ||
-		    interface->bInterfaceSubClass != 2 ||
-		    interface->bInterfaceProtocol != 1 ||
-	    	    interface->bNumEndpoints != 1)
-			continue;
-
-		/*Which uses an interrupt input */
-		endpoint = &interface->endpoint[0];
-		if ((endpoint->bEndpointAddress & 0x80) != 0x80 ||
-		    (endpoint->bmAttributes & 3) != 3)
-			continue;
-			
-		/* The second one should be a Data interface? */
-		interface = &dev->config[cfgnum].altsetting[0].interface[1];
-		if (interface->bInterfaceClass != 10 ||
-		    interface->bInterfaceSubClass != 0 ||
-		    interface->bInterfaceProtocol != 0 ||
-	    	    interface->bNumEndpoints != 2)
-			continue;
-
-		/*With a bulk input */
-		endpoint = &interface->endpoint[0];
-		if ((endpoint->bEndpointAddress & 0x80) != 0x80 ||
-		    (endpoint->bmAttributes & 3) != 2)
-			continue;
-			
-		/*And a bulk output */
-		endpoint = &interface->endpoint[1];
-		if ((endpoint->bEndpointAddress & 0x80) == 0x80 ||
-		    (endpoint->bmAttributes & 3) != 2)
-			continue;
-
-		printk("USB ACM found\n");
-		if (usb_set_configuration(dev, dev->config[cfgnum].bConfigurationValue)) {
-			printk (KERN_INFO " Failed usb_set_configuration: ACM\n");
-			continue;
-		}
-		acm->dev=dev;
-		acm->readendp=dev->config[cfgnum].altsetting[0].interface[1].endpoint[0].bEndpointAddress;
-		acm->writeendp=dev->config[cfgnum].altsetting[0].interface[1].endpoint[1].bEndpointAddress;
-		acm->ctrlendp=dev->config[cfgnum].altsetting[0].interface[0].endpoint[0].bEndpointAddress;
-		acm->readpipe=usb_rcvbulkpipe(dev,acm->readendp);
-		acm->writepipe=usb_sndbulkpipe(dev,acm->writeendp);
-		usb_request_irq(dev,acm->ctrlpipe=usb_rcvctrlpipe(dev,acm->ctrlendp), acm_irq, dev->config[cfgnum].altsetting[0].interface[0].endpoint[0].bInterval, &acm->ctrlbuffer);
-		acm->present = 1;
-		acm->buffer=0;
-		return 0;
-	}
-
-	return -1;
-}
-
-static void acm_disconnect(struct usb_device *dev)
-{
-	struct acm_state *acm = &static_acm_state;
-
-	/* this might need work */
-	acm->present = 0;
-}
-
-static struct usb_driver acm_driver = {
-	"acm",
-	acm_probe,
-	acm_disconnect,
-	{ NULL, NULL }
-};
-
-int usb_acm_init(void)
-{
-	struct acm_state *acm = &static_acm_state;
-
-	misc_register(&usb_acm);
-
-	acm->present = acm->active = 0;
-
-	usb_register(&acm_driver);
-	printk(KERN_INFO "USB ACM registered.\n");
-	return 0;
-}
-
-#ifdef MODULE
-
-int init_module(void)
-{
-	return usb_acm_init();
-}
-
-void cleanup_module(void)
-{
-	/* this, too, probably needs work */
-	usb_deregister(&acm_driver);
-	misc_deregister(&usb_acm);
-}
-
-#endif
diff -urN linux-2.2.12-pre1/drivers/usb/audio.c linux-2.2.12-pre3/drivers/usb/audio.c
--- linux-2.2.12-pre1/drivers/usb/audio.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/audio.c	1999-04-28 11:14:03.000000000 -0700
@@ -3,8 +3,6 @@
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/sched.h>
-#include <linux/module.h>
-
 #include "usb.h"
 
 static int usb_audio_probe(struct usb_device *dev);
@@ -26,7 +24,7 @@
 };
 
 
-static int usb_audio_irq(int state, void *buffer, int len, void *dev_id)
+static int usb_audio_irq(int state, void *buffer, void *dev_id)
 {
 	struct usb_audio *aud = (struct usb_audio*) dev_id;
 	return 1;
@@ -41,7 +39,7 @@
 	int i;
 	int na=0;
 	
-	interface = &dev->config[0].altsetting[0].interface[0];
+	interface = &dev->config[0].interface[0];
 
 	for(i=0;i<dev->config[0].bNumInterfaces;i++)
 	{
@@ -81,10 +79,7 @@
 
 		endpoint = &interface->endpoint[0];
 
-//        	if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) {
-//			printk (KERN_INFO " Failed usb_set_configuration: Audio\n");
-//			break;
-//		}
+//        	usb_set_configuration(dev, dev->config[0].bConfigurationValue);
 //        	usb_set_protocol(dev, 0);
 //        	usb_set_idle(dev, 0, 0);
         
@@ -95,13 +90,8 @@
                         aud);
 
 		list_add(&aud->list, &usb_audio_list);
-		
-		return 0;
 	}
-	
-	if (aud)
-		kfree (aud);
-	return -1;
+	return 0;
 }
 
 static void usb_audio_disconnect(struct usb_device *dev)
@@ -134,15 +124,3 @@
 {
 }
 
-#ifdef MODULE
-int init_module(void)
-{
-	return usb_audio_init();
-}
-
-void cleanup_module(void)
-{
-	usb_deregister(&usb_audio_driver);
-}
-
-#endif
diff -urN linux-2.2.12-pre1/drivers/usb/Config.in linux-2.2.12-pre3/drivers/usb/Config.in
--- linux-2.2.12-pre1/drivers/usb/Config.in	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/Config.in	1999-05-10 10:18:34.000000000 -0700
@@ -5,39 +5,25 @@
 # Right now hubs, mice and keyboards work - at least with UHCI.
 # But that may be more a lucky coincidence than anything else..
 #
+# This was all developed modularly, but I've been lazy in cleaning
+# it up, so right now they are all bools. 
+#
 mainmenu_option next_comment
 comment 'USB drivers - not for the faint of heart'
 
-tristate 'Support for USB (EXPERIMENTAL!)' CONFIG_USB
-if [ ! "$CONFIG_USB" = "n" ]; then
-  dep_tristate 'UHCI (intel PIIX4 and others) support' CONFIG_USB_UHCI \
-	$CONFIG_USB
-    dep_tristate 'OHCI (mac, compaq and others) support' CONFIG_USB_OHCI \
-	$CONFIG_USB
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  tristate 'Support for USB (EXPERIMENTAL!)' CONFIG_USB
+  if [ ! "$CONFIG_USB" = "n" ]; then
+    bool 'UHCI (intel PIIX4 and others) support?' CONFIG_USB_UHCI
+    bool 'OHCI (compaq and some others) support?' CONFIG_USB_OHCI
+    bool 'OHCI-HCD (other OHCI opt. Virt. Root Hub) support?' CONFIG_USB_OHCI_HCD
+    if [ "$CONFIG_USB_OHCI_HCD" = "y" ]; then
+       bool 'OHCI-HCD Virtual Root Hub' CONFIG_USB_OHCI_VROOTHUB
+    fi
 
-  if [ "$CONFIG_USB_OHCI" != "n" ]; then
-     bool '  Enable tons of OHCI debugging output' CONFIG_USB_OHCI_DEBUG
-  fi
-  dep_tristate 'OHCI-HCD (other OHCI opt. Virt. Root Hub) support' \
-		CONFIG_USB_OHCI_HCD $CONFIG_USB
-  if [ "$CONFIG_USB_OHCI_HCD" != "n" ]; then
-#     	bool '  OHCI-HCD Virtual Root Hub' CONFIG_USB_OHCI_VROOTHUB
-	define_bool CONFIG_USB_OHCI_VROOTHUB y
-  fi
-
-  dep_tristate 'USB hub support' CONFIG_USB_HUB $CONFIG_USB
-  dep_tristate 'USB mouse support' CONFIG_USB_MOUSE $CONFIG_USB
-  dep_tristate 'USB keyboard support' CONFIG_USB_KBD $CONFIG_USB
-  dep_tristate 'USB audio parsing support' CONFIG_USB_AUDIO $CONFIG_USB
-  dep_tristate 'USB Abstract Control Model support' CONFIG_USB_ACM $CONFIG_USB
-  dep_tristate 'USB Printer support' CONFIG_USB_PRINTER $CONFIG_USB
-  dep_tristate 'USB SCSI Support' CONFIG_USB_SCSI $CONFIG_USB
-  if [ "$CONFIG_USB_SCSI" != "n" ]; then
-	  dep_tristate '  USB SCSI verbose debug' CONFIG_USB_SCSI_DEBUG $CONFIG_USB_SCSI
-  fi
-  dep_tristate 'EZUSB Firmware downloader' CONFIG_USB_EZUSB $CONFIG_USB
-  if [ "$CONFIG_PROC_FS" != "n" ]; then
-  	bool 'Preliminary /proc/bus/usb support' CONFIG_USB_PROC
+    bool 'USB mouse support' CONFIG_USB_MOUSE
+    bool 'USB keyboard support' CONFIG_USB_KBD
+    bool 'USB audio parsing support' CONFIG_USB_AUDIO
   fi
 fi
 
diff -urN linux-2.2.12-pre1/drivers/usb/cpia.c linux-2.2.12-pre3/drivers/usb/cpia.c
--- linux-2.2.12-pre1/drivers/usb/cpia.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/cpia.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1277 +0,0 @@
-/*
- * USB CPiA Video Camera driver
- *
- * Supports CPiA based Video Camera's. Many manufacturers use this chipset.
- * There's a good chance, if you have a USB video camera, it's a CPiA based
- * one
- *
- * (C) Copyright 1999 Johannes Erdfelt
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/list.h>
-#include <linux/malloc.h>
-#include <linux/mm.h>
-#include <linux/smp_lock.h>
-#include <linux/videodev.h>
-#include <linux/vmalloc.h>
-#include <linux/wrapper.h>
-#include <linux/module.h>
-
-#include <asm/spinlock.h>
-#include <asm/io.h>
-
-#include "usb.h"
-#include "cpia.h"
-
-#define MAX_FRAME_SIZE (384 * 288 * 3)
-
-/*******************************/
-/* Memory management functions */
-/*******************************/
-
-/* convert virtual user memory address to physical address */
-/* (virt_to_phys only works for kmalloced kernel memory) */
-
-static inline unsigned long uvirt_to_phys(unsigned long adr)
-{
-        pgd_t *pgd;
-        pmd_t *pmd;
-        pte_t *ptep, pte;
-  
-        pgd = pgd_offset(current->mm, adr);
-        if (pgd_none(*pgd))
-                return 0;
-        pmd = pmd_offset(pgd, adr);
-        if (pmd_none(*pmd))
-                return 0;
-        ptep = pte_offset(pmd, adr/*&(~PGDIR_MASK)*/);
-        pte = *ptep;
-        if(pte_present(pte))
-                return 
-                  virt_to_phys((void *)(pte_page(pte)|(adr&(PAGE_SIZE-1))));
-        return 0;
-}
-
-static inline unsigned long uvirt_to_bus(unsigned long adr) 
-{
-        return virt_to_bus(phys_to_virt(uvirt_to_phys(adr)));
-}
-
-/* convert virtual kernel memory address to physical address */
-/* (virt_to_phys only works for kmalloced kernel memory) */
-
-static inline unsigned long kvirt_to_phys(unsigned long adr) 
-{
-        return uvirt_to_phys(VMALLOC_VMADDR(adr));
-}
-
-static inline unsigned long kvirt_to_bus(unsigned long adr) 
-{
-        return uvirt_to_bus(VMALLOC_VMADDR(adr));
-}
-
-
-static void * rvmalloc(unsigned long size)
-{
-	void * mem;
-	unsigned long adr, page;
-        
-	size += (PAGE_SIZE - 1);
-	size &= ~(PAGE_SIZE - 1);
-
-	mem=vmalloc(size);
-	if (mem) 
-	{
-		memset(mem, 0, size); /* Clear the ram out, no junk to the user */
-		adr=(unsigned long) mem;
-		while (size > 0) 
-		{
-			page = kvirt_to_phys(adr);
-			mem_map_reserve(MAP_NR(phys_to_virt(page)));
-			adr+=PAGE_SIZE;
-			if (size > PAGE_SIZE)
-				size-=PAGE_SIZE;
-			else
-				size=0;
-		}
-	}
-	return mem;
-}
-
-static void rvfree(void * mem, unsigned long size)
-{
-	unsigned long adr, page;
-        
-	size += (PAGE_SIZE - 1);
-	size &= ~(PAGE_SIZE - 1);
-
-	if (mem) 
-	{
-		adr=(unsigned long) mem;
-		while (size > 0) 
-		{
- 			page = kvirt_to_phys(adr);
-			mem_map_unreserve(MAP_NR(phys_to_virt(page)));
-			adr+=PAGE_SIZE;
-			if (size > PAGE_SIZE)
-				size-=PAGE_SIZE;
-			else
-				size=0;
-		}
-		vfree(mem);
-	}
-}
-
-int usb_cpia_get_version(struct usb_device *dev, void *buf)
-{
-	devrequest dr;
-
-	dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE) | 0x80;
-	dr.request = USB_REQ_CPIA_GET_VERSION;
-	dr.value = 0;
-	dr.index = 0;
-	dr.length = 4;
-
-	return dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, buf, 4);
-}
-
-int usb_cpia_get_pnp_id(struct usb_device *dev, void *buf)
-{
-	devrequest dr;
-
-	dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE) | 0x80;
-	dr.request = USB_REQ_CPIA_GET_PNP_ID;
-	dr.value = 0;
-	dr.index = 0;
- 	dr.length = 6;
-
-	return dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, buf, 6);
-}
-
-int usb_cpia_get_camera_status(struct usb_device *dev, void *buf)
-{
-	devrequest dr;
-
-	dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE) | 0x80;
-	dr.request = USB_REQ_CPIA_GET_CAMERA_STATUS;
-	dr.value = 0;
-	dr.index = 0;
-	dr.length = 8;
-
-	return dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, buf, 8);
-}
-
-int usb_cpia_goto_hi_power(struct usb_device *dev)
-{
-	devrequest dr;
-
-	dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE);
-	dr.request = USB_REQ_CPIA_GOTO_HI_POWER;
-	dr.value = 0;
-	dr.index = 0;
-	dr.length = 0;
-
-	return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0);
-}
-
-int usb_cpia_get_vp_version(struct usb_device *dev, void *buf)
-{
-	devrequest dr;
-
-	dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE);
-	dr.request = USB_REQ_CPIA_GET_VP_VERSION;
-	dr.value = 0;
-	dr.index = 0;
-	dr.length = 4;
-
-	return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, buf, 4);
-}
-
-int usb_cpia_set_sensor_fps(struct usb_device *dev, int sensorbaserate, int sensorclkdivisor)
-{
-	devrequest dr;
-
-	dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE);
-	dr.request = USB_REQ_CPIA_SET_SENSOR_FPS;
-	dr.value = (sensorclkdivisor << 8) + sensorbaserate;
-	dr.index = 0;
-	dr.length = 0;
-
-	return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0);
-}
-
-int usb_cpia_grab_frame(struct usb_device *dev, int streamstartline)
-{
-	devrequest dr;
-
-	dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE);
-	dr.request = USB_REQ_CPIA_GRAB_FRAME;
-	dr.value = streamstartline << 8;
-	dr.index = 0;
-	dr.length = 0;
-
-	return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0);
-}
-
-int usb_cpia_upload_frame(struct usb_device *dev, int forceupload)
-{
-	devrequest dr;
-
-	dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE);
-	dr.request = USB_REQ_CPIA_UPLOAD_FRAME;
-	dr.value = forceupload;
-	dr.index = 0;
-	dr.length = 0;
-
-	return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0);
-}
-
-int usb_cpia_set_grab_mode(struct usb_device *dev, int continuousgrab)
-{
-	devrequest dr;
-
-	dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE);
-	dr.request = USB_REQ_CPIA_SET_GRAB_MODE;
-	dr.value = continuousgrab;
-	dr.index = 0;
-	dr.length = 0;
-
-	return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0);
-}
-
-int usb_cpia_set_format(struct usb_device *dev, int size, int subsample, int order)
-{
-	devrequest dr;
-
-	dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE);
-	dr.request = USB_REQ_CPIA_SET_FORMAT;
-	dr.value = (subsample << 8) + size;
-	dr.index = order;
-	dr.length = 0;
-
-	return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0);
-}
-
-int usb_cpia_set_compression(struct usb_device *dev, int compmode, int decimation)
-{
-	devrequest dr;
-
-	dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE);
-	dr.request = USB_REQ_CPIA_SET_COMPRESSION;
-	dr.value = (decimation << 8) + compmode;
-	dr.index = 0;
-	dr.length = 0;
-
-	return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0);
-}
-
-int usb_cpia_initstreamcap(struct usb_device *dev, int skipframes, int streamstartline)
-{
-	devrequest dr;
-
-	dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE);
-	dr.request = USB_REQ_CPIA_INIT_STREAM_CAP;
-	dr.value = (streamstartline << 8) + skipframes;
-	dr.index = 0;
-	dr.length = 0;
-
-	return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0);
-}
-
-int usb_cpia_finistreamcap(struct usb_device *dev)
-{
-	devrequest dr;
-
-	dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE);
-	dr.request = USB_REQ_CPIA_FINI_STREAM_CAP;
-	dr.value = 0;
-	dr.index = 0;
-	dr.length = 0;
-
-	return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0);
-}
-
-int usb_cpia_startstreamcap(struct usb_device *dev)
-{
-	devrequest dr;
-
-	dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE);
-	dr.request = USB_REQ_CPIA_START_STREAM_CAP;
-	dr.value = 0;
-	dr.index = 0;
-	dr.length = 0;
-
-	return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0);
-}
-
-int usb_cpia_endstreamcap(struct usb_device *dev)
-{
-	devrequest dr;
-
-	dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE);
-	dr.request = USB_REQ_CPIA_END_STREAM_CAP;
-	dr.value = 0;
-	dr.index = 0;
-	dr.length = 0;
-
-	return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0);
-}
-
-#define scratch_left(x)	(cpia->scratchlen - (int)((char *)x - (char *)cpia->scratch))
-
-static void cpia_parse_data(struct usb_cpia *cpia)
-{
-	unsigned char *data = cpia->scratch;
-	int done;
-
-	done = 0;
-	while (!done && scratch_left(data)) {
-		switch (cpia->state) {
-		case STATE_SCANNING:
-		{
-			unsigned char *begin = data;
-
-			/* We need atleast 2 bytes for the magic value */
-			if (scratch_left(data) < 2) {
-				done = 1;
-				break;
-			}
-
-			printk("header: %X\n", (*data << 8) + *(data + 1));
-			if ((*data == 0x19) && (*(data + 1) == 0x68)) {
-				cpia->state = STATE_HEADER;
-				printk("moving to header\n");
-				break;
-			}
-
-			if (scratch_left(data) < 4) {
-				done = 1;
-				break;
-			}
-
-			printk("Scanning for end of frame\n");
-			while (scratch_left(data) >= 4) {
-				if ((*data == 0xFF) &&
-					(*(data + 1) == 0xFF) &&
-					(*(data + 2) == 0xFF) &&
-					(*(data + 3) == 0xFF)) {
-					data += 4;
-					break;
-				}
-				data++;
-			}
-printk("scan: scanned %d bytes\n", data-begin);
-			break;
-		}
-		case STATE_HEADER:
-			/* We need atleast 64 bytes for the header */
-			if (scratch_left(data) < 64) {
-				done = 1;
-				break;
-			}
-
-printk("header: framerate %d\n", data[41]);
-
-			data += 64;
-
-			cpia->state = STATE_LINES;
-				
-			break;
-		case STATE_LINES:
-		{
-			unsigned char *begin = data;
-			int found = 0;
-
-			while (scratch_left(data)) {
-				if (*data == 0xFD) {
-					data++;
-					found = 1;
-					break;
-				} else if ((*data == 0xFF) &&
-					(scratch_left(data) >= 3) &&
-					(*(data + 1) == 0xFF) &&
-					(*(data + 2) == 0xFF) &&
-					(*(data + 3) == 0xFF)) {
-					data+=4;
-					cpia->curline = 144;
-					found = 1;
-					break;
-				}
-
-				data++;
-			}
-#if 0
-printk("line %d: scanned %d bytes\n", cpia->curline, data-begin);
-#endif
-if (data-begin == 355 && cpia->frame[cpia->curframe].width != 64) {
-	int i;
-	char *f = cpia->frame[cpia->curframe].data, *b = begin;
-
-#if 0
-printk("copying\n");
-#endif
-
-	b+=2;
-	f+=(cpia->frame[cpia->curframe].width*3)*cpia->curline;
-	for (i = 0; i < 176; i++)
-		f[(i * 3) + 0] =
-		f[(i * 3) + 1] =
-		f[(i * 3) + 2] =
-			b[(i * 2)];
-}
-			if (found) {
-				cpia->curline++;
-				if (cpia->curline >= 144) {
-					wake_up(&cpia->wq);
-					cpia->state = STATE_SCANNING;
-					cpia->curline = 0;
-					cpia->curframe = -1;
-					done = 1;
-				}
-			} else {
-				data = begin;
-				done = 1;
-			}
-			
-			break;
-		}
-		}
-	}
-
-	{
-	int l;
-
-	l = scratch_left(data);
-	memmove(cpia->scratch, data, l);
-	cpia->scratchlen = l;
-	}
-}
-
-static int cpia_isoc_irq(int status, void *__buffer, int len, void *dev_id)
-{
-	struct usb_cpia *cpia = dev_id;
-	struct usb_device *dev = cpia->dev;
-	struct cpia_sbuf *sbuf;
-	int i;
-	char *p;
-
-	if (!cpia->streaming) {
-		printk("oops, not streaming, but interrupt\n");
-		return 0;
-	}
-	
-	if (cpia->curframe < 0) {
-		if (cpia->frame[0].state == FRAME_READY) {
-			cpia->curframe = 0;
-			cpia->frame[0].state = FRAME_GRABBING;
-printk("capturing to frame 0\n");
-		} else if (cpia->frame[1].state == FRAME_READY) {
-			cpia->curframe = 1;
-			cpia->frame[1].state = FRAME_GRABBING;
-printk("capturing to frame 1\n");
-		} else
-printk("no frame available\n");
-	}
-
-	sbuf = &cpia->sbuf[cpia->receivesbuf];
-
-	usb_unschedule_isochronous(dev, sbuf->isodesc);
-
-	/* Do something to it now */
-	sbuf->len = usb_compress_isochronous(dev, sbuf->isodesc);
-
-	if (sbuf->len)
-	printk("%d bytes received\n", sbuf->len);
-
-	if (sbuf->len && cpia->curframe >= 0) {
-		if (sbuf->len > (SCRATCH_BUF_SIZE - cpia->scratchlen)) {
-			printk("overflow!\n");
-			return 0;
-		}
-		memcpy(cpia->scratch + cpia->scratchlen, sbuf->data, sbuf->len);
-		cpia->scratchlen += sbuf->len;
-
-		cpia_parse_data(cpia);
-	}
-
-	/* Reschedule this block of Isochronous desc */
-	usb_schedule_isochronous(dev, sbuf->isodesc, cpia->sbuf[(cpia->receivesbuf + 2) % 3].isodesc);
-
-	/* Move to the next one */
-	cpia->receivesbuf = (cpia->receivesbuf + 1) % 3;
-
-	return 1;
-}
-
-int cpia_init_isoc(struct usb_cpia *cpia)
-{
-	struct usb_device *dev = cpia->dev;
-
-	cpia->receivesbuf = 0;
-
-#if 0
-	cpia->parsesbuf = 0;
-	cpia->parsepos = 0;
-#endif
-	cpia->scratchlen = 0;
-	cpia->curline = 0;
-	cpia->state = STATE_SCANNING;
-
-	/* Allocate all of the memory necessary */
-	cpia->sbuf[0].isodesc = usb_allocate_isochronous(dev, usb_rcvisocpipe(dev,1), cpia->sbuf[0].data, STREAM_BUF_SIZE, 960, cpia_isoc_irq, cpia);
-	cpia->sbuf[1].isodesc = usb_allocate_isochronous(dev, usb_rcvisocpipe(dev,1), cpia->sbuf[1].data, STREAM_BUF_SIZE, 960, cpia_isoc_irq, cpia);
-	cpia->sbuf[2].isodesc = usb_allocate_isochronous(dev, usb_rcvisocpipe(dev,1), cpia->sbuf[2].data, STREAM_BUF_SIZE, 960, cpia_isoc_irq, cpia);
-
-	printk("isodesc[0] @ %p\n", cpia->sbuf[0].isodesc);
-	printk("isodesc[1] @ %p\n", cpia->sbuf[1].isodesc);
-	printk("isodesc[2] @ %p\n", cpia->sbuf[2].isodesc);
-
-	/* Schedule the queues */
-	usb_schedule_isochronous(dev, cpia->sbuf[0].isodesc, NULL);
-	usb_schedule_isochronous(dev, cpia->sbuf[1].isodesc, cpia->sbuf[0].isodesc);
-	usb_schedule_isochronous(dev, cpia->sbuf[2].isodesc, cpia->sbuf[1].isodesc);
-
-	if (usb_set_interface(cpia->dev, 1, 3)) {
-		printk("cpia_set_interface error\n");
-		return -EINVAL;
-	}
-
-	usb_cpia_startstreamcap(cpia->dev);
-
-	cpia->streaming = 1;
-
-	return 0;
-}
-
-void cpia_stop_isoc(struct usb_cpia *cpia)
-{
-	struct usb_device *dev = cpia->dev;
-
-	if (!cpia->streaming)
-		return;
-
-	cpia->streaming = 0;
-
-	/* Stop the streaming */
-	usb_cpia_endstreamcap(cpia->dev);
-
-	/* Set packet size to 0 */
-	if (usb_set_interface(cpia->dev, 1, 0)) {
-		printk("cpia_set_interface error\n");
-		return /* -EINVAL */;
-	}
-
-	/* Unschedule all of the iso td's */
-	usb_unschedule_isochronous(dev, cpia->sbuf[2].isodesc);
-	usb_unschedule_isochronous(dev, cpia->sbuf[1].isodesc);
-	usb_unschedule_isochronous(dev, cpia->sbuf[0].isodesc);
-
-	/* Delete them all */
-	usb_delete_isochronous(dev, cpia->sbuf[2].isodesc);
-	usb_delete_isochronous(dev, cpia->sbuf[1].isodesc);
-	usb_delete_isochronous(dev, cpia->sbuf[0].isodesc);
-}
-
-/* Video 4 Linux API */
-static int cpia_open(struct video_device *dev, int flags)
-{
-	struct usb_cpia *cpia = (struct usb_cpia *)dev;
-
-printk("cpia_open\n");
-
-	cpia->fbuf = rvmalloc(2 * MAX_FRAME_SIZE);
-	if (!cpia->fbuf)
-		goto open_err_ret;
-
-	cpia->frame[0].state = FRAME_DONE;
-	cpia->frame[1].state = FRAME_DONE;
-
-	cpia->frame[0].data = cpia->fbuf;
-	cpia->frame[1].data = cpia->fbuf + MAX_FRAME_SIZE;
-	printk("frame [0] @ %p\n", cpia->frame[0].data);
-	printk("frame [1] @ %p\n", cpia->frame[1].data);
-
-	cpia->sbuf[0].data = kmalloc(STREAM_BUF_SIZE, GFP_KERNEL);
-	if (!cpia->sbuf[0].data)
-		goto open_err_on0;
-
-	cpia->sbuf[1].data = kmalloc(STREAM_BUF_SIZE, GFP_KERNEL);
-	if (!cpia->sbuf[1].data)
-		goto open_err_on1;
-
-	cpia->sbuf[2].data = kmalloc(STREAM_BUF_SIZE, GFP_KERNEL);
-	if (!cpia->sbuf[2].data)
-		goto open_err_on2;
-
-	printk("sbuf[0] @ %p\n", cpia->sbuf[0].data);
-	printk("sbuf[1] @ %p\n", cpia->sbuf[1].data);
-	printk("sbuf[2] @ %p\n", cpia->sbuf[2].data);
-
-	cpia->curframe = -1;
-	cpia->receivesbuf = 0;
-
-	usb_cpia_initstreamcap(cpia->dev, 0, 60);
-
-	cpia_init_isoc(cpia);
-
-	return 0;
-
-open_err_on2:
-	kfree (cpia->sbuf[1].data);
-open_err_on1:
-	kfree (cpia->sbuf[0].data);
-open_err_on0:
-	rvfree(cpia->fbuf, 2 * MAX_FRAME_SIZE);
-open_err_ret:
-	return -ENOMEM;
-}
-
-static void cpia_close(struct video_device *dev)
-{
-	struct usb_cpia *cpia = (struct usb_cpia *)dev;
-
-printk("cpia_close\n");
-
-	cpia_stop_isoc(cpia);
-
-	usb_cpia_finistreamcap(cpia->dev);
-
-	rvfree(cpia->fbuf, 2 * MAX_FRAME_SIZE);
-
-	kfree(cpia->sbuf[2].data);
-	kfree(cpia->sbuf[1].data);
-	kfree(cpia->sbuf[0].data);
-}
-
-static int cpia_init_done(struct video_device *dev)
-{
-	return 0;
-}
-
-static long cpia_write(struct video_device *dev, const char *buf, unsigned long count, int noblock)
-{
-	return -EINVAL;
-}
-
-#if 0
-	if (usb_set_interface(dev, 1, 3)) {
-		printk("cpia_set_interface error\n");
-		return -EINVAL;
-	}
-
-	if (usb_cpia_grab_frame(dev, 0)) {
-		printk("cpia_grab_frame error\n");
-		return -EINVAL;
-	}
-
-	if (usb_cpia_upload_frame(dev, 0)) {
-		printk("cpia_upload_frame error\n");
-		return -EINVAL;
-	}
-
-	buf = cpia->ibuf;
-	uhci_receive_isochronous(dev, usb_rcvisocpipe(dev,1), buf, 176*144*4);
-
-	{
-	printk("header magic: %X\n", (buf[0] << 8) + buf[1]);
-
-	while ((buf[0] != 0x19) || (buf[1] != 0x68)) {
-		int i;
-
-		printk("resync'ing\n");
-		for (i=0;i<(176*144*4)-4;i++, buf++)
-			if (
-				(buf[0] == 0xFF) &&
-				(buf[1] == 0xFF) &&
-				(buf[2] == 0xFF) &&
-				(buf[3] == 0xFF)) {
-				buf+=4;
-				i+=4;
-				break;
-			}
-
-		memmove(cpia->ibuf, buf, (176*144*4) - i);
-		uhci_receive_isochronous(dev, usb_rcvisocpipe(dev,1), cpia->ibuf + (176*144*4) - i, i);
-		buf = cpia->ibuf;
-
-#if 0
-		printk("header magic: %X\n", (buf[0] << 8) + buf[1]);
-#endif
-	}
-
-	printk("size: %d, sample: %d, order: %d\n", buf[16], buf[17], buf[18]);
-	printk("comp: %d, decimation: %d\n", buf[28], buf[29]);
-	printk("roi: top left: %d, %d bottom right: %d, %d\n",
-		buf[26] * 4, buf[24] * 8,
-		buf[27] * 4, buf[25] * 8);
-
-	printk("vm->frame: %d\n", vm->frame);
-
-	{
-	int i, i1;
-	char *b = buf + 64, *fbuf = &cpia->fbuffer[MAX_FRAME_SIZE * (vm->frame & 1)];
-	for (i=0;i<144;i++) {
-#if 0
-		printk("line len: %d\n", (b[1] << 8) + b[0]);
-#endif
-		b += 2;
-		for (i1=0;i1<176;i1++) {
-			fbuf[(i * vm->width * 3) + (i1 * 3)] = 
-			fbuf[(i * vm->width * 3) + (i1 * 3) + 1] = 
-			fbuf[(i * vm->width * 3) + (i1 * 3) + 2] = 
-				b[i1 * 2];
-#if 0
-			*((short *)&fbuf[(i * vm->width * 2) + (i1 * 2)]) =
-				((b[i1 * 2] >> 3) << 11) + ((b[i1 * 2] >> 2) << 6) + (b[i1 * 2] >> 3);
-#endif
-		}
-		b += (176 * 2) + 1;
-	}
-	}
-
-	}
-
-	if (usb_set_interface(dev, 1, 0)) {
-		printk("cpia_set_interface error\n");
-		return -EINVAL;
-	}
-#endif
-
-static int cpia_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
-	struct usb_cpia *cpia = (struct usb_cpia *)dev;
-
-	switch (cmd) {
-		case VIDIOCGCAP:
-		{
-			struct video_capability b;
-
-			strcpy(b.name, "CPiA USB Camera");
-			b.type = VID_TYPE_CAPTURE /* | VID_TYPE_SUBCAPTURE */;
-			b.channels = 1;
-			b.audios = 0;
-			b.maxwidth = 176 /* 352 */;
-			b.maxheight = 144 /* 240 */;
-			b.minwidth = 176 /* (Something small?) */;
-			b.minheight = 144 /* "         " */;
-
-			if (copy_to_user(arg, &b, sizeof(b)))
-				return -EFAULT;
-			return 0;
-		}
-		case VIDIOCGCHAN:
-		{
-			struct video_channel v;
-
-			if (copy_from_user(&v, arg, sizeof(v)))
-				return -EFAULT;
-			if (v.channel != 0)
-				return -EINVAL;
-
-			v.flags = 0;
-			v.tuners = 0;
-			v.type = VIDEO_TYPE_CAMERA;
-			strcpy(v.name, "Camera");
-
-			if (copy_to_user(arg, &v, sizeof(v)))
-				return -EFAULT;
-			return 0;
-		}
-		case VIDIOCSCHAN:
-		{
-			int v;
-
-			if (copy_from_user(&v, arg, sizeof(v)))
-				return -EFAULT;
-
-			if (v != 0)
-				return -EINVAL;
-
-			return 0;
-		}
-		case VIDIOCGTUNER:
-		{
-			struct video_tuner v;
-
-			if (copy_from_user(&v, arg, sizeof(v)))
-				return -EFAULT;
-
-			if (v.tuner)
-				return -EINVAL;
-
-			strcpy(v.name, "Format");
-
-			v.rangelow = 0;
-			v.rangehigh = 0;
-			v.flags = 0;
-			v.mode = VIDEO_MODE_AUTO;
-
-			if (copy_to_user(arg, &v, sizeof(v)))
-				return -EFAULT;
-
-			return 0;
-		}
-		case VIDIOCSTUNER:
-		{
-			struct video_tuner v;
-
-			if (copy_from_user(&v, arg, sizeof(v)))
-				return -EFAULT;
-
-			if (v.tuner)
-				return -EINVAL;
-
-			if (v.mode != VIDEO_MODE_AUTO)
-				return -EINVAL;
-
-			return 0;
-		}
-		case VIDIOCGPICT:
-		{
-			struct video_picture p;
-
-			p.colour = 0x8000;	/* Damn British people :) */
-			p.hue = 0x8000;
-			p.brightness = 180 << 8;	/* XXX */
-			p.contrast = 192 << 8;		/* XXX */
-			p.whiteness = 105 << 8;		/* XXX */
-#if 0
-			p.depth = 24;
-#endif
-			p.depth = 16;
-			p.palette = VIDEO_PALETTE_YUYV;
-
-			if (copy_to_user(arg, &p, sizeof(p)))
-				return -EFAULT;
-
-			return 0;
-		}
-		case VIDIOCSPICT:
-		{
-			struct video_picture p;
-
-			if (copy_from_user(&p, arg, sizeof(p)))
-				return -EFAULT;
-
-printk("Attempting to set palette %d, depth %d\n", p.palette, p.depth);
-
-#if 0
-			if (p.palette != VIDEO_PALETTE_YUYV)
-				return -EINVAL;
-			if (p.depth != 16)
-				return -EINVAL;
-#endif
-
-			return 0;
-		}
-		case VIDIOCSWIN:
-		{
-			struct video_window vw;
-
-printk("VIDIOCSWIN\n");
-			if (copy_from_user(&vw, arg, sizeof(vw)))
-				return -EFAULT;
-			if (vw.flags)
-				return -EINVAL;
-			if (vw.clipcount)
-				return -EINVAL;
-			if (vw.height != 176)
-				return -EINVAL;
-			if (vw.width != 144)
-				return -EINVAL;
-
-			return 0;
-		}
-		case VIDIOCGWIN:
-		{
-			struct video_window vw;
-
-printk("VIDIOCGWIN\n");
-			vw.x = 0;
-			vw.y = 0;
-			vw.width = 176;
-			vw.height = 144;
-			vw.chromakey = 0;
-			vw.flags = 0;
-
-			if (copy_to_user(arg, &vw, sizeof(vw)))
-				return -EFAULT;
-
-			return 0;
-		}
-		case VIDIOCGMBUF:
-		{
-			struct video_mbuf vm;
-
-			memset(&vm, 0, sizeof(vm));
-			vm.size = MAX_FRAME_SIZE * 2;
-			vm.frames = 2;
-			vm.offsets[0] = 0;
-			vm.offsets[1] = MAX_FRAME_SIZE;
-
-			if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
-				return -EFAULT;
-
-			return 0;
-		}
-		case VIDIOCMCAPTURE:
-		{
-			struct video_mmap vm;
-
-			if (copy_from_user((void *)&vm, (void *)arg, sizeof(vm)))
-				return -EFAULT;
-
-printk("MCAPTURE\n");
-printk("frame: %d, size: %dx%d, format: %d\n", vm.frame, vm.width, vm.height, vm.format);
-
-			if (vm.format != VIDEO_PALETTE_RGB24)
-				return -EINVAL;
-
-			if ((vm.frame != 0) && (vm.frame != 1))
-				return -EINVAL;
-
-			cpia->frame[vm.frame].width = vm.width;
-			cpia->frame[vm.frame].height = vm.height;
-
-			/* Mark it as free */
-			cpia->frame[vm.frame].state = FRAME_READY;
-
-			return 0;
-		}
-		case VIDIOCSYNC:
-		{
-			int frame;
-
-			if (copy_from_user((void *)&frame, arg, sizeof(int)))
-				return -EFAULT;
-
-			printk("syncing to frame %d\n", frame);
-			switch (cpia->frame[frame].state) {
-				case FRAME_UNUSED:
-					return -EINVAL;
-				case FRAME_READY:
-				case FRAME_GRABBING:
-					interruptible_sleep_on(&cpia->wq);
-				case FRAME_DONE:
-					cpia->frame[frame].state = FRAME_UNUSED;
-					break;
-			}
-			printk("synced to frame %d\n", frame);
-			return 0;
-		}
-		case VIDIOCCAPTURE:
-			return -EINVAL;
-		case VIDIOCGFBUF:
-			return -EINVAL;
-		case VIDIOCSFBUF:
-			return -EINVAL;
-		case VIDIOCKEY:
-			return 0;
-		case VIDIOCGFREQ:
-			return -EINVAL;
-		case VIDIOCSFREQ:
-			return -EINVAL;
-		case VIDIOCGAUDIO:
-			return -EINVAL;
-		case VIDIOCSAUDIO:
-			return -EINVAL;
-		default:
-			return -ENOIOCTLCMD;
-	}
-	return 0;
-}
-
-static long cpia_read(struct video_device *dev, char *buf, unsigned long count, int noblock)
-{
-	struct usb_cpia *cpia = (struct usb_cpia *)dev;
-	int len;
-
-	printk("cpia_read: %ld bytes\n", count);
-#if 0
-	len = cpia_capture(cpia, buf, count);
-
-	return len;
-#endif
-	return 0;
-}
-
-static int cpia_mmap(struct video_device *dev, const char *adr, unsigned long size)
-{
-	struct usb_cpia *cpia = (struct usb_cpia *)dev;
-	unsigned long start = (unsigned long)adr;
-	unsigned long page, pos;
-
-	printk("mmap: %ld (%lX) bytes\n", size, size);
-	if (size > (((2 * MAX_FRAME_SIZE) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
-		return -EINVAL;
-
-#if 0
-	if (!cpia->fbuffer) {
-		if ((cpia->fbuffer = rvmalloc(2 * MAX_FRAME_SIZE)) == NULL)
-			return -EINVAL;
-	}
-#endif
-
-	pos = (unsigned long)cpia->fbuf;
-	while (size > 0)
-	{
-		page = kvirt_to_phys(pos);
-		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
-			return -EAGAIN;
-		start+=PAGE_SIZE;
-		pos+=PAGE_SIZE;
-		if (size > PAGE_SIZE)
-			size-=PAGE_SIZE;
-		else
-			size=0;
-	}
-
-	return 0;
-}
-
-static struct video_device cpia_template = {
-	"CPiA USB Camera",
-	VID_TYPE_CAPTURE,
-	VID_HARDWARE_CPIA,
-	cpia_open,
-	cpia_close,
-	cpia_read,
-	cpia_write,
-	NULL,
-	cpia_ioctl,
-	cpia_mmap,
-	cpia_init_done,
-	NULL,
-	0,
-	0
-};
-
-static void usb_cpia_configure(struct usb_cpia *cpia)
-{
-	struct usb_device *dev = cpia->dev;
-	unsigned char version[4];
-	unsigned char pnpid[6];
-	unsigned char camerastat[8];
-	unsigned char *buf;
-
-	if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) {
-		printk (KERN_INFO " Failed usb_set_configuration: CPIA\n");
-		return;
-	}
-
-	if (usb_cpia_get_version(dev, version)) {
-		printk("cpia_get_version error\n");
-		return;
-	}
-
-	printk("cpia: Firmware v%d.%d, VC Hardware v%d.%d\n",
-		version[0], version[1], version[2], version[3]);
-
-	if (usb_cpia_get_pnp_id(dev, pnpid)) {
-		printk("cpia_get_pnp_id error\n");
-		return;
-	}
-
-	printk("cpia: PnP Id: Vendor: %X, Product: %X, Revision: %X\n",
-		(pnpid[1] << 8) + pnpid[0], (pnpid[3] << 8) + pnpid[2],
-		(pnpid[5] << 8) + pnpid[4]);
-
-	memcpy(&cpia->vdev, &cpia_template, sizeof(cpia_template));
-
-	init_waitqueue_head(&cpia->wq);
-
-	if (video_register_device(&cpia->vdev, VFL_TYPE_GRABBER) == -1) {
-		printk("video_register_device failed\n");
-		return;
-	}
-
-	if (usb_cpia_goto_hi_power(dev)) {
-		printk("cpia_goto_hi_power error\n");
-		return;
-	}
-
-	if (usb_cpia_get_vp_version(dev, version)) {
-		printk("cpia_get_vp_version error\n");
-		return;
-	}
-
-	printk("cpia: VP v%d rev %d\n", version[0], version[1]);
-	printk("cpia: Camera Head ID %04X\n", (version[3] << 8) + version[2]);
-
-	/* Turn off continuous grab */
-	if (usb_cpia_set_grab_mode(dev, 1)) {
-		printk("cpia_set_grab_mode error\n");
-		return;
-	}
-
-	/* Set up the sensor to be 30fps */
-	if (usb_cpia_set_sensor_fps(dev, 1, 0)) {
-		printk("cpia_set_sensor_fps error\n");
-		return;
-	}
-
-	/* Set video into QCIF mode, and order into YUYV mode */
-	if (usb_cpia_set_format(dev, CPIA_QCIF, 1, CPIA_YUYV)) {
-		printk("cpia_set_format error\n");
-		return;
-	}
-
-	/* Turn off compression */
-	if (usb_cpia_set_compression(dev, 0, 0)) {
-		printk("cpia_set_compression error\n");
-		return;
-	}
-
-#if 0
-	if (usb_cpia_grab_frame(dev, 0)) {
-		printk("cpia_grab_frame error\n");
-		return;
-	}
-
-	if (usb_cpia_upload_frame(dev, 1)) {
-		printk("cpia_upload_frame error\n");
-		return;
-	}
-
-	buf = (void *)__get_free_page(GFP_KERNEL);
-
-	{
-	int i;
-	for (i=0;i<448;i++)
-		buf[i]=0;
-	}
-	uhci_receive_isochronous(dev, usb_rcvisocpipe(dev,1), buf, 448);
-
-	{
-	int i;
-	for (i=0;i<448;i++) {
-		printk("%02X ", buf[i]);
-		if ((i % 16) == 15)
-			printk("\n");
-	}
-	printk("\n");
-	}
-
-	free_page((unsigned long)buf);
-#endif
-}
-
-static int cpia_probe(struct usb_device *dev)
-{
-	struct usb_interface_descriptor *interface;
-	struct usb_endpoint_descriptor *endpoint;
-	struct usb_cpia *cpia;
-
-	/* We don't handle multi-config cameras */
-	if (dev->descriptor.bNumConfigurations != 1)
-		return -1;
-
-#if 0
-	/* We don't handle multi-interface hubs */
-	if (dev->config[0].bNumInterfaces != 1)
-		return -1;
-#endif
-
-	interface = &dev->config[0].altsetting[0].interface[0];
-
-	/* Is it a CPiA? */
-/*
-Apr 24 17:49:04 bjorn kernel:   Vendor:  0545 
-Apr 24 17:49:04 bjorn kernel:   Product: 8080 
-*/
-/*
-	if (dev->descriptor.idVendor != 0x0545)
-		return -1;
-	if (dev->descriptor.idProduct != 0x8080)
-		return -1;
-	if (interface->bInterfaceClass != 0xFF)
-		return -1;
-	if (interface->bInterfaceSubClass != 0xFF)
-		return -1;
-*/
-	if (dev->descriptor.idVendor != 0x0553)
-		return -1;
-	if (dev->descriptor.idProduct != 0x0002)
-		return -1;
-	if (interface->bInterfaceClass != 0xFF)
-		return -1;
-	if (interface->bInterfaceSubClass != 0x00)
-		return -1;
-
-#if 0
-	/* Multiple endpoints? What kind of mutant ninja-hub is this? */
-	if (interface->bNumEndpoints != 1)
-		return -1;
-
-	endpoint = &interface->endpoint[0];
-
-	/* Output endpoint? Curiousier and curiousier.. */
-	if (!(endpoint->bEndpointAddress & 0x80))
-		return -1;
-
-	/* If it's not an interrupt endpoint, we'd better punt! */
-	if ((endpoint->bmAttributes & 3) != 3)
-		return -1;
-#endif
-
-	/* We found a CPiA */
-	printk("USB CPiA camera found\n");
-
-	if ((cpia = kmalloc(sizeof(*cpia), GFP_KERNEL)) == NULL) {
-		printk("couldn't kmalloc cpia struct\n");
-		return -1;
-	}
-
-	memset(cpia, 0, sizeof(*cpia));
-
-	dev->private = cpia;
-	cpia->dev = dev;
-
-	usb_cpia_configure(cpia);
-
-#if 0
-	usb_request_irq(dev, usb_rcvctrlpipe(dev, endpoint->bEndpointAddress), pport_irq, endpoint->bInterval, pport);
-#endif
-
-	return 0;
-}
-
-static void cpia_disconnect(struct usb_device *dev)
-{
-	struct usb_cpia *cpia = dev->private;
-
-	video_unregister_device(&cpia->vdev);
-
-	/* Free the memory */
-	kfree(cpia);
-}
-
-static struct usb_driver cpia_driver = {
-	"cpia",
-	cpia_probe,
-	cpia_disconnect,
-	{ NULL, NULL }
-};
-
-/*
- * This should be a separate module.
- */
-int usb_cpia_init(void)
-{
-	usb_register(&cpia_driver);
-
-	return 0;
-}
-
-#ifdef MODULE
-int init_module(void)
-{
-	return usb_cpia_init();
-}
-void cleanup_module(void)
-{
-}
-#endif
-
diff -urN linux-2.2.12-pre1/drivers/usb/cpia.h linux-2.2.12-pre3/drivers/usb/cpia.h
--- linux-2.2.12-pre1/drivers/usb/cpia.h	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/cpia.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,139 +0,0 @@
-#ifndef __LINUX_CPIA_H
-#define __LINUX_CPIA_H
-
-#include <linux/list.h>
-
-#define USB_REQ_CPIA_GET_VERSION		0x01
-#define USB_REQ_CPIA_GET_PNP_ID			0x02
-#define USB_REQ_CPIA_GET_CAMERA_STATUS		0x03
-#define USB_REQ_CPIA_GOTO_HI_POWER		0x04
-#define USB_REQ_CPIA_GOTO_LO_POWER		0x05
-/* No 0x06 */
-#define USB_REQ_CPIA_GOTO_SUSPEND		0x07
-#define USB_REQ_CPIA_GOTO_PASS_THROUGH		0x08
-/* No 0x09 */
-#define USB_REQ_CPIA_MODIFY_CAMERA_STATUS	0x0A
-
-#define USB_REQ_CPIA_READ_VC_REGS		0x21
-#define USB_REQ_CPIA_WRITE_BC_REG		0x22
-#define USB_REQ_CPIA_READ_MC_PORTS		0x23
-#define USB_REQ_CPIA_WRITE_MC_PORT		0x24
-#define USB_REQ_CPIA_SET_BAUD_RATE		0x25
-#define USB_REQ_CPIA_SET_ECP_TIMING		0x26
-#define USB_REQ_CPIA_READ_IDATA			0x27
-#define USB_REQ_CPIA_WRITE_IDATA		0x28
-#define USB_REQ_CPIA_GENERIC_CALL		0x29
-#define USB_REQ_CPIA_I2CSTART			0x2A
-#define USB_REQ_CPIA_I2CSTOP			0x2B
-#define USB_REQ_CPIA_I2CWRITE			0x2C
-#define USB_REQ_CPIA_I2CREAD			0x2D
-
-#define USB_REQ_CPIA_GET_VP_VERSION		0xA1
-#define USB_REQ_CPIA_SET_COLOUR_PARAMS		0xA3
-#define USB_REQ_CPIA_SET_EXPOSURE		0xA4
-/* No 0xA5 */
-#define USB_REQ_CPIA_SET_COLOUR_BALANCE		0xA6
-#define USB_REQ_CPIA_SET_SENSOR_FPS		0xA7
-#define USB_REQ_CPIA_SET_VP_DEFAULTS		0xA8
-#define USB_REQ_CPIA_SET_APCOR			0xA9
-#define USB_REQ_CPIA_SET_FLICKER_CTRL		0xAA
-#define USB_REQ_CPIA_SET_VL_OFFSET		0xAB
-
-#define USB_REQ_CPIA_GET_COLOUR_PARAMETERS	0xB0
-#define USB_REQ_CPIA_GET_COLOUR_BALANCE		0xB1
-#define USB_REQ_CPIA_GET_EXPOSURE		0xB2
-#define USB_REQ_CPIA_SET_SENSOR_MATRIX		0xB3
-
-#define USB_REQ_CPIA_COLOUR_BARS		0xBD
-#define USB_REQ_CPIA_READ_VP_REGS		0xBE
-#define USB_REQ_CPIA_WRITE_VP_REGS		0xBF
-
-#define USB_REQ_CPIA_GRAB_FRAME			0xC1
-#define USB_REQ_CPIA_UPLOAD_FRAME		0xC2
-#define USB_REQ_CPIA_SET_GRAB_MODE		0xC3
-#define USB_REQ_CPIA_INIT_STREAM_CAP		0xC4
-#define USB_REQ_CPIA_FINI_STREAM_CAP		0xC5
-#define USB_REQ_CPIA_START_STREAM_CAP		0xC6
-#define USB_REQ_CPIA_END_STREAM_CAP		0xC7
-#define USB_REQ_CPIA_SET_FORMAT			0xC8
-#define USB_REQ_CPIA_SET_ROI			0xC9
-#define USB_REQ_CPIA_SET_COMPRESSION		0xCA
-#define USB_REQ_CPIA_SET_COMPRESSION_TARGET	0xCB
-#define USB_REQ_CPIA_SET_YUV_THRESH		0xCC
-#define USB_REQ_CPIA_SET_COMPRESSION_PARAMS	0xCD
-#define USB_REQ_CPIA_DISCARD_FRAME		0xCE
-
-#define USB_REQ_CPIA_OUTPUT_RS232		0xE1
-#define USB_REQ_CPIA_ABORT_PROCESS		0xE4
-#define USB_REQ_CPIA_SET_DRAM_PAGE		0xE5
-#define USB_REQ_CPIA_START_DRAM_UPLOAD		0xE6
-#define USB_REQ_CPIA_START_DUMMY_STREAM		0xE8
-#define USB_REQ_CPIA_ABORT_STREAM		0xE9
-#define USB_REQ_CPIA_DOWNLOAD_DRAM		0xEA
-/* #define USB_REQ_CPIA_NULL_CMD		0x?? */
-
-#define CPIA_QCIF	0
-#define CPIA_CIF	1
-
-#define CPIA_YUYV	0
-#define CPIA_UYVY	1
-
-#define STREAM_BUF_SIZE	(PAGE_SIZE * 4)
-
-#define SCRATCH_BUF_SIZE (STREAM_BUF_SIZE * 2)
-
-enum {
-	STATE_SCANNING,		/* Scanning for start */
-	STATE_HEADER,		/* Parsing header */
-	STATE_LINES,		/* Parsing lines */
-};
-
-struct usb_device;
-
-struct cpia_sbuf {
-	char *data;
-	int len;
-	void *isodesc;
-};
-
-enum {
-	FRAME_READY,		/* Ready to grab into */
-	FRAME_GRABBING,		/* In the process of being grabbed into */
-	FRAME_DONE,		/* Finished grabbing, but not been synced yet */
-	FRAME_UNUSED,		/* Unused (no MCAPTURE) */
-};
-
-struct cpia_frame {
-	char *data;
-	int width;
-	int height;
-	int state;
-};
-
-struct usb_cpia {
-	struct video_device vdev;
-
-	/* Device structure */
-	struct usb_device *dev;
-
-	int streaming;
-
-	char *fbuf;			/* Videodev buffer area */
-
-	int curframe;
-	struct cpia_frame frame[2];	/* Double buffering */
-
-	int receivesbuf;		/* Current receiving sbuf */
-	struct cpia_sbuf sbuf[3];	/* Triple buffering */
-
-	int state;			/* Current scanning state */
-	int curline;
-
-	char scratch[SCRATCH_BUF_SIZE];
-	int scratchlen;
-
-	wait_queue_head_t wq;
-};
-
-#endif
-
diff -urN linux-2.2.12-pre1/drivers/usb/CREDITS linux-2.2.12-pre3/drivers/usb/CREDITS
--- linux-2.2.12-pre1/drivers/usb/CREDITS	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/CREDITS	1999-05-11 10:04:03.000000000 -0700
@@ -8,7 +8,6 @@
   Johannes Erdfelt <jerdfelt@sventech.com>
   ham <ham@unsuave.com>
   Bradley M Keryan <keryan@andrew.cmu.edu>
-  Paul Mackerras <paulus@cs.anu.edu.au>
   Vojtech Pavlik <vojtech@twilight.ucw.cz>
   Gregory P. Smith <greg@electricrain.com>
   Linus Torvalds <torvalds@transmeta.com>
@@ -29,11 +28,7 @@
 THANKS file in Inaky's driver):
 
         The following corporations have helped us in the development
-        of Linux USB / UUSBD:
-
-	- 3Com GmbH for donating a ISDN Pro TA and supporting me
-	  in technical questions and with test equipment. I'd never 
-	  expect such a great help.
+of Linux USB / UUSBD:
 
         - USAR Systems provided us with one of their excellent USB
           Evaluation Kits. It allows us to test the Linux-USB driver
diff -urN linux-2.2.12-pre1/drivers/usb/ezusb.c linux-2.2.12-pre3/drivers/usb/ezusb.c
--- linux-2.2.12-pre1/drivers/usb/ezusb.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/ezusb.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,472 +0,0 @@
-/*****************************************************************************/
-
-/*
- *	ezusb.c  --  Firmware download miscdevice for Anchorchips EZUSB microcontrollers.
- *
- *	Copyright (C) 1999
- *          Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- *	This program is free software; you can redistribute it and/or modify
- *	it under the terms of the GNU General Public License as published by
- *	the Free Software Foundation; either version 2 of the License, or
- *	(at your option) any later version.
- *
- *	This program is distributed in the hope that it will be useful,
- *	but WITHOUT ANY WARRANTY; without even the implied warranty of
- *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *	GNU General Public License for more details.
- *
- *	You should have received a copy of the GNU General Public License
- *	along with this program; if not, write to the Free Software
- *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  History:
- *   0.1  26.05.99  Created
- *
- */
-
-/*****************************************************************************/
-
-#include <linux/module.h>
-#include <linux/socket.h>
-#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
-
-#include "usb.h"
-#include "ezusb.h"
-
-/* --------------------------------------------------------------------- */
-
-#define NREZUSB 1
-
-static struct ezusb {
-	struct semaphore mutex;
-	struct usb_device *usbdev;
-	unsigned int irqep;
-	unsigned int intlen;
-	unsigned char intdata[64];
-} ezusb[NREZUSB];
-
-/* --------------------------------------------------------------------- */
-
-static int ezusb_irq(int state, void *__buffer, int len, void *dev_id)
-{
-	struct ezusb *ez = (struct ezusb *)dev_id;
-	
-	if (len > sizeof(ez->intdata))
-		len = sizeof(ez->intdata);
-	ez->intlen = len;
-	memcpy(ez->intdata, __buffer, len);
-	return 1;
-}
-
-/* --------------------------------------------------------------------- */
-
-static loff_t ezusb_llseek(struct file *file, loff_t offset, int origin)
-{
-	struct ezusb *ez = (struct ezusb *)file->private_data;
-
-	switch(origin) {
-	case 1:
-		offset += file->f_pos;
-		break;
-	case 2:
-		offset += 0x10000;
-		break;
-	}
-	if (offset < 0 || offset >= 0x10000)
-		return -EINVAL;
-	return (file->f_pos = offset);
-}
-
-static ssize_t ezusb_read(struct file *file, char *buf, size_t sz, loff_t *ppos)
-{
-	struct ezusb *ez = (struct ezusb *)file->private_data;
-	unsigned pos = *ppos;
-	unsigned ret = 0;
-	unsigned len;
-	unsigned char b[64];
-        devrequest dr;
-	int i;
-
-	if (*ppos < 0 || *ppos >= 0x10000)
-		return -EINVAL;
-	down(&ez->mutex);
-	if (!ez->usbdev) {
-		up(&ez->mutex);
-		return -EIO;
-	}
-	while (sz > 0 && pos < 0x10000) {
-		len = sz;
-		if (len > sizeof(b))
-			len = sizeof(b);
-		if (pos + len > 0x10000)
-			len = 0x10000 - pos;
-		dr.requesttype = 0xc0;
-		dr.request = 0xa0;
-		dr.value = pos;
-		dr.index = 0;
-		dr.length = len;
-		i = ez->usbdev->bus->op->control_msg(ez->usbdev, usb_rcvctrlpipe(ez->usbdev, 0), &dr, b, len);
-		if (i) {
-			up(&ez->mutex);
-			printk(KERN_WARNING "ezusb: upload failed pos %u len %u ret %d\n", dr.value, dr.length, i);
-			*ppos = pos;
-			if (ret)
-				return ret;
-			return -ENXIO;
-		}
-		if (copy_to_user(buf, b, len)) {
-			up(&ez->mutex);
-			*ppos = pos;
-			if (ret)
-				return ret;
-			return -EFAULT;
-		}
-		pos += len;
-		buf += len;
-		sz -= len;
-		ret += len;
-	}
-	up(&ez->mutex);
-	*ppos = pos;
-	return ret;
-}
-
-static ssize_t ezusb_write(struct file *file, const char *buf, size_t sz, loff_t *ppos)
-{
-	struct ezusb *ez = (struct ezusb *)file->private_data;
-	unsigned pos = *ppos;
-	unsigned ret = 0;
-	unsigned len;
-	unsigned char b[64];
-        devrequest dr;
-	int i;
-
-	if (*ppos < 0 || *ppos >= 0x10000)
-		return -EINVAL;
-	down(&ez->mutex);
-	if (!ez->usbdev) {
-		up(&ez->mutex);
-		return -EIO;
-	}
-	while (sz > 0 && pos < 0x10000) {
-		len = sz;
-		if (len > sizeof(b))
-			len = sizeof(b);
-		if (pos + len > 0x10000)
-			len = 0x10000 - pos;
-		if (copy_from_user(b, buf, len)) {
-			up(&ez->mutex);
-			*ppos = pos;
-			if (ret)
-				return ret;
-			return -EFAULT;
-		}
-		dr.requesttype = 0x40;
-		dr.request = 0xa0;
-		dr.value = pos;
-		dr.index = 0;
-		dr.length = len;
-		i = ez->usbdev->bus->op->control_msg(ez->usbdev, usb_sndctrlpipe(ez->usbdev, 0), &dr, b, len);
-		if (i) {
-			up(&ez->mutex);
-			printk(KERN_WARNING "ezusb: download failed pos %u len %u ret %d\n", dr.value, dr.length, i);
-			*ppos = pos;
-			if (ret)
-				return ret;
-			return -ENXIO;
-		}
-		pos += len;
-		buf += len;
-		sz -= len;
-		ret += len;
-	}
-	up(&ez->mutex);
-	*ppos = pos;
-	return ret;
-}
-
-static int ezusb_open(struct inode *inode, struct file *file)
-{
-	struct ezusb *ez = &ezusb[0];
-
-	down(&ez->mutex);
-	while (!ez->usbdev) {
-		up(&ez->mutex);
-		if (!(file->f_flags & O_NONBLOCK)) {
-			return -EIO;
-		}
-		schedule_timeout(HZ/2);
-		if (signal_pending(current))
-			return -EAGAIN;
-		down(&ez->mutex);
-	}
-	up(&ez->mutex);
-	file->f_pos = 0;
-	file->private_data = ez;
-	return 0;
-}
-
-static int ezusb_release(struct inode *inode, struct file *file)
-{
-	struct ezusb *ez = (struct ezusb *)file->private_data;
-	return 0;
-}
-
-static int ezusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	struct ezusb *ez = (struct ezusb *)file->private_data;
-	struct ezusb_ctrltransfer ctrl;
-	struct ezusb_bulktransfer bulk;
-	unsigned int len1, ep;
-	unsigned long len2;
-	unsigned int irqep;
-	unsigned char tbuf[1024];
-	int i;
-
-	switch (cmd) {
-	case EZUSB_CONTROL:
-		copy_from_user_ret(&ctrl, (void *)arg, sizeof(ctrl), -EFAULT);
-		if (ctrl.dlen > sizeof(tbuf) || ctrl.dlen > 1024)
-			return -EINVAL;
-		if (ctrl.requesttype & 0x80) {
-			if (ctrl.dlen && !access_ok(VERIFY_WRITE, ctrl.data, ctrl.dlen))
-				return -EINVAL;
-			down(&ez->mutex);
-			if (!ez->usbdev) {
-				up(&ez->mutex);
-				return -EIO;
-			}
-			i = ez->usbdev->bus->op->control_msg(ez->usbdev, usb_rcvctrlpipe(ez->usbdev, 0),
-							     (devrequest *)&ctrl, tbuf, ctrl.dlen);
-			up(&ez->mutex);
-			if (!i && ctrl.dlen) {
-				copy_to_user_ret(ctrl.data, tbuf, ctrl.dlen, -EFAULT);
-			}
-		} else {
-			if (ctrl.dlen) {
-				copy_from_user_ret(tbuf, ctrl.data, ctrl.dlen, -EFAULT);
-			}
-			down(&ez->mutex);
-			if (!ez->usbdev) {
-				up(&ez->mutex);
-				return -EIO;
-			}
-			i = ez->usbdev->bus->op->control_msg(ez->usbdev, usb_sndctrlpipe(ez->usbdev, 0),
-							     (devrequest *)&ctrl, tbuf, ctrl.dlen);
-			up(&ez->mutex);
-		}
-		if (i) {
-			printk(KERN_WARNING "ezusb: EZUSB_CONTROL failed rqt %u rq %u len %u ret %d\n", 
-			       ctrl.requesttype, ctrl.request, ctrl.length, i);
-			return -ENXIO;
-		}
-		return 0;
-
-	case EZUSB_INTERRUPT:
-		get_user_ret(irqep, (unsigned int *)arg, -EFAULT);
-		if (irqep != ez->irqep) {
-			if (ez->irqep)
-				return -EIO;
-			ez->irqep = irqep;
-			usb_request_irq(ez->usbdev, usb_rcvctrlpipe(ez->usbdev, ez->irqep),
-					ezusb_irq, 2 /* interval */, ez);
-			ez->intlen = 0;
-			return -EAGAIN;
-		}
-		copy_to_user_ret((&((struct ezusb_interrupttransfer *)0)->data) + arg, 
-				 ez->intdata, 64, -EFAULT);
-		return ez->intlen;
-
-	case EZUSB_BULK:
-		copy_from_user_ret(&bulk, (void *)arg, sizeof(bulk), -EFAULT);
-		len1 = bulk.len;
-		if (len1 > sizeof(tbuf))
-			len1 = sizeof(tbuf);
-		if (bulk.ep & 0x80) {
-			if (len1 && !access_ok(VERIFY_WRITE, bulk.data, len1))
-				return -EINVAL;
-			down(&ez->mutex);
-			if (!ez->usbdev) {
-				up(&ez->mutex);
-				return -EIO;
-			}
-			i = ez->usbdev->bus->op->bulk_msg(ez->usbdev, usb_rcvbulkpipe(ez->usbdev, bulk.ep & 0x7f),
-							  tbuf, len1, &len2);
-			up(&ez->mutex);
-			if (!i && len2) {
-				copy_to_user_ret(bulk.data, tbuf, len2, -EFAULT);
-			}
-		} else {
-			if (len1) {
-				copy_from_user_ret(tbuf, bulk.data, len1, -EFAULT);
-			}
-			down(&ez->mutex);
-			if (!ez->usbdev) {
-				up(&ez->mutex);
-				return -EIO;
-			}
-			i = ez->usbdev->bus->op->bulk_msg(ez->usbdev, usb_sndbulkpipe(ez->usbdev, bulk.ep & 0x7f),
-							  tbuf, len1, &len2);
-			up(&ez->mutex);
-		}
-		if (i) {
-			printk(KERN_WARNING "ezusb: EZUSB_BULK failed ep 0x%x len %u ret %d\n", 
-			       bulk.ep, bulk.len, i);
-			return -ENXIO;
-		}
-		return len2;
-
-	case EZUSB_RESETEP:
-		get_user_ret(ep, (unsigned int *)arg, -EFAULT);
-		if ((ep & ~0x80) >= 16)
-			return -EINVAL;
-		usb_settoggle(ez->usbdev, ep & 0xf, !(ep & 0x80), 0);
-		return 0;
-	}
-	return -ENOIOCTLCMD;
-}
-
-static struct file_operations ezusb_fops = {
-	ezusb_llseek,
-	ezusb_read,
-	ezusb_write,
-	NULL,  /* readdir */
-	NULL,  /* poll */
-	ezusb_ioctl,
-	NULL,  /* mmap */
-	ezusb_open,
-	NULL,  /* flush */
-	ezusb_release,
-	NULL,  /* fsync */
-	NULL,  /* fasync */
-	NULL,  /* check_media_change */
-	NULL,  /* revalidate */
-	NULL   /* lock */
-};
-
-static struct miscdevice ezusb_misc = {
-	192, "ezusb", &ezusb_fops
-};
-
-/* --------------------------------------------------------------------- */
-
-static int ezusb_probe(struct usb_device *usbdev)
-{
-	struct ezusb *ez = &ezusb[0];
-        struct usb_interface_descriptor *interface;
-        struct usb_endpoint_descriptor *endpoint;
-
-#undef KERN_DEBUG
-#define KERN_DEBUG ""
-        printk(KERN_DEBUG "ezusb: probe: vendor id 0x%x, device id 0x%x\n",
-               usbdev->descriptor.idVendor, usbdev->descriptor.idProduct);
-
-	/* the 1234:5678 is just a self assigned test ID */
-        if ((usbdev->descriptor.idVendor != 0x0547 || usbdev->descriptor.idProduct != 0x2131) &&
-	    (usbdev->descriptor.idVendor != 0x1234 || usbdev->descriptor.idProduct != 0x5678))
-                return -1;
-
-        /* We don't handle multiple configurations */
-        if (usbdev->descriptor.bNumConfigurations != 1)
-                return -1;
-
-        /* We don't handle multiple interfaces */
-        if (usbdev->config[0].bNumInterfaces != 1)
-                return -1;
-
-	down(&ez->mutex);
-	if (ez->usbdev) {
-		up(&ez->mutex);
-		printk(KERN_INFO "ezusb: device already used\n");
-		return -1;
-	}
-	ez->usbdev = usbdev;
-	usbdev->private = ez;
-        if (usb_set_configuration(usbdev, usbdev->config[0].bConfigurationValue)) {
-		printk(KERN_ERR "ezusb: set_configuration failed\n");
-		goto err;
-	}
-        interface = &usbdev->config[0].altsetting[1].interface[0];
-	if (usb_set_interface(usbdev, 0, 1)) {
-		printk(KERN_ERR "ezusb: set_interface failed\n");
-		goto err;
-	}
-	up(&ez->mutex);
-	MOD_INC_USE_COUNT;
-        return 0;
-
- err:
-	up(&ez->mutex);
-	ez->usbdev = NULL;
-	usbdev->private = NULL;
-	return -1;
-}
-
-static void ezusb_disconnect(struct usb_device *usbdev)
-{
-	struct ezusb *ez = (struct ezusb *)usbdev->private;
-
-	down(&ez->mutex);
-	ez->usbdev = NULL;
-	up(&ez->mutex);
-        usbdev->private = NULL;
-	MOD_DEC_USE_COUNT;
-}
-
-static struct usb_driver ezusb_driver = {
-        "ezusb",
-        ezusb_probe,
-        ezusb_disconnect,
-        { NULL, NULL }
-};
-
-/* --------------------------------------------------------------------- */
-
-int ezusb_init(void)
-{
-	unsigned u;
-
-	/* initialize struct */
-	for (u = 0; u < NREZUSB; u++) {
-		ezusb[u].mutex = MUTEX;
-		ezusb[u].usbdev = NULL;
-		ezusb[u].irqep = 0;
-	}
-	/* register misc device */
-	if (misc_register(&ezusb_misc)) {
-		printk(KERN_WARNING "ezusb: cannot register minor %d\n", ezusb_misc.minor);
-		return -1;
-	}
-	usb_register(&ezusb_driver);
-        printk(KERN_INFO "ezusb: Anchorchip firmware download driver registered\n");
-	return 0;
-}
-
-void ezusb_cleanup(void)
-{
-	usb_deregister(&ezusb_driver);
-	misc_deregister(&ezusb_misc);
-}
-
-/* --------------------------------------------------------------------- */
-
-#ifdef MODULE
-
-int minor = 192;
-
-int init_module(void)
-{
-	ezusb_misc.minor = minor;
-	return ezusb_init();
-}
-
-void cleanup_module(void)
-{
-	ezusb_cleanup();
-}
-
-#endif
-
-/* --------------------------------------------------------------------- */
diff -urN linux-2.2.12-pre1/drivers/usb/ezusb.h linux-2.2.12-pre3/drivers/usb/ezusb.h
--- linux-2.2.12-pre1/drivers/usb/ezusb.h	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/ezusb.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,67 +0,0 @@
-/*****************************************************************************/
-
-/*
- *	ezusb.h  --  Firmware download miscdevice for Anchorchips EZUSB microcontrollers.
- *
- *	Copyright (C) 1999
- *          Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- *	This program is free software; you can redistribute it and/or modify
- *	it under the terms of the GNU General Public License as published by
- *	the Free Software Foundation; either version 2 of the License, or
- *	(at your option) any later version.
- *
- *	This program is distributed in the hope that it will be useful,
- *	but WITHOUT ANY WARRANTY; without even the implied warranty of
- *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *	GNU General Public License for more details.
- *
- *	You should have received a copy of the GNU General Public License
- *	along with this program; if not, write to the Free Software
- *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-/*****************************************************************************/
-
-#ifndef _LINUX_EZUSB_H
-#define _LINUX_EZUSB_H
-
-#include <linux/ioctl.h>
-
-/* --------------------------------------------------------------------- */
-
-struct ezusb_ctrltransfer {
-	/* keep in sync with usb.h:devrequest */
-	unsigned char requesttype;
-	unsigned char request;
-	unsigned short value;
-	unsigned short index;
-	unsigned short length;
-	/* pointer to data */
-	unsigned dlen;
-	void *data;
-};
-
-#define EZUSB_CONTROL        _IOWR('E', 0, struct ezusb_ctrltransfer)
-
-struct ezusb_interrupttransfer {
-	unsigned int ep;
-	unsigned char data[64];
-};
-
-#define EZUSB_INTERRUPT      _IOWR('E', 1, struct ezusb_interrupttransfer)
-
-struct ezusb_bulktransfer {
-	unsigned int ep;
-	unsigned int len;
-	void *data;
-};
-
-#define EZUSB_BULK           _IOWR('E', 2, struct ezusb_bulktransfer)
-
-#define EZUSB_RESETEP        _IOR('E', 3, unsigned int)
-
-
-/* --------------------------------------------------------------------- */
-#endif /* _LINUX_EZUSB_H */
diff -urN linux-2.2.12-pre1/drivers/usb/hub.c linux-2.2.12-pre3/drivers/usb/hub.c
--- linux-2.2.12-pre1/drivers/usb/hub.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/hub.c	1999-04-30 08:20:01.000000000 -0700
@@ -1,9 +1,12 @@
 /*
  * USB hub driver.
  *
+ * This is horrible, it knows about the UHCI driver
+ * internals, but it's just meant as a rough example,
+ * let's do the virtualization later when this works.
+ *
  * (C) Copyright 1999 Linus Torvalds
  * (C) Copyright 1999 Johannes Erdfelt
- * (C) Copyright 1999 Gregory P. Smith
  */
 
 #include <linux/kernel.h>
@@ -11,24 +14,22 @@
 #include <linux/list.h>
 #include <linux/malloc.h>
 #include <linux/smp_lock.h>
-#include <linux/module.h>
 
 #include <asm/spinlock.h>
 
 #include "usb.h"
+#include "uhci.h"
 #include "hub.h"
 
+extern struct usb_operations uhci_device_operations;
+
 /* Wakes up khubd */
-static DECLARE_WAIT_QUEUE_HEAD(usb_hub_wait);
+static struct wait_queue *usb_hub_wait = NULL;
 static spinlock_t hub_event_lock = SPIN_LOCK_UNLOCKED;
-static spinlock_t hub_list_lock = SPIN_LOCK_UNLOCKED;
 
 /* List of hubs needing servicing */
 static struct list_head hub_event_list;
 
-/* List containing all of the hubs (for cleanup) */
-static struct list_head all_hubs_list;
-
 /* PID of khubd */
 static int khubd_pid = 0;
 
@@ -37,7 +38,7 @@
  * the low-level driver that it wants to be re-activated,
  * or zero to say "I'm done".
  */
-static int hub_irq(int status, void *__buffer, int len, void *dev_id)
+static int hub_irq(int status, void *__buffer, void *dev_id)
 {
 	struct usb_hub *hub = dev_id;
 	unsigned long flags;
@@ -68,59 +69,59 @@
 		return;
 
 	hub->nports = dev->maxchild = hubdescriptor[2];
-	printk(KERN_DEBUG "hub: %d-port%s detected\n", hub->nports,
+	printk("hub: %d-port%s detected\n", hub->nports,
 		(hub->nports == 1) ? "" : "s");
 
 	charac = (hubdescriptor[4] << 8) + hubdescriptor[3];
 	switch (charac & HUB_CHAR_LPSM) {
 		case 0x00:
-			printk(KERN_DEBUG "hub: ganged power switching\n");
+			printk("hub: ganged power switching\n");
 			break;
 		case 0x01:
-			printk(KERN_DEBUG "hub: individual port power switching\n");
+			printk("hub: individual port power switching\n");
 			break;
 		case 0x02:
 		case 0x03:
-			printk(KERN_DEBUG "hub: unknown reserved power switching mode\n");
+			printk("hub: unknown reserved power switching mode\n");
 			break;
 	}
 
 	if (charac & HUB_CHAR_COMPOUND)
-		printk(KERN_DEBUG "hub: part of a compound device\n");
+		printk("hub: part of a compound device\n");
 	else
-		printk(KERN_DEBUG "hub: standalone hub\n");
+		printk("hub: standalone hub\n");
 
 	switch (charac & HUB_CHAR_OCPM) {
 		case 0x00:
-			printk(KERN_DEBUG "hub: global over current protection\n");
+			printk("hub: global over current protection\n");
 			break;
 		case 0x08:
-			printk(KERN_DEBUG "hub: individual port over current protection\n");
+			printk("hub: individual port over current protection\n");
 			break;
 		case 0x10:
 		case 0x18:
-			printk(KERN_DEBUG "hub: no over current protection\n");
+			printk("hub: no over current protection\n");
                         break;
 	}
 
-	printk(KERN_DEBUG "hub: power on to power good time: %dms\n",
+	printk("hub: power on to power good time: %dms\n",
 		hubdescriptor[5] * 2);
 
-	printk(KERN_DEBUG "hub: hub controller current requirement: %dmA\n",
+	printk("hub: hub controller current requirement: %dmA\n",
 		hubdescriptor[6]);
 
 	for (i = 0; i < dev->maxchild; i++)
-		printk(KERN_DEBUG "hub:  port %d is%s removable\n", i + 1,
+		printk("hub:  port %d is%s removable\n", i + 1,
 			hubdescriptor[7 + ((i + 1)/8)] & (1 << ((i + 1) % 8))
 			? " not" : "");
 
 	if (usb_get_hub_status(dev, buf))
 		return;
 
-	printk(KERN_DEBUG "hub: local power source is %s\n",
+	printk("hub: local power source is %s\n",
 		(buf[0] & 1) ? "lost (inactive)" : "good");
 
-	printk(KERN_DEBUG "hub: %sover current condition exists\n",
+	printk("hub: %sover current condition exists\n",
 		(buf[0] & 2) ? "" : "no ");
 
 #if 0
@@ -133,19 +134,18 @@
 		portstat = (portstatus[1] << 8) + portstatus[0];
 		portchange = (portstatus[3] << 8) + portstatus[2];
 
-		printk(KERN_DEBUG "hub: port %d status\n", i + 1);
-		printk(KERN_DEBUG "hub:  %sdevice present\n", (portstat & 1) ? "" : "no ");
-		printk(KERN_DEBUG "hub:  %s\n", (portstat & 2) ? "enabled" : "disabled");
-		printk(KERN_DEBUG "hub:  %ssuspended\n", (portstat & 4) ? "" : "not ");
-		printk(KERN_DEBUG "hub:  %sover current\n", (portstat & 8) ? "" : "not ");
-		printk(KERN_DEBUG "hub:  has %spower\n", (portstat & 0x100) ? "" : "no ");
-		printk(KERN_DEBUG "hub:  %s speed\n", (portstat & 0x200) ? "low" : "full");
+		printk("hub: port %d status\n", i + 1);
+		printk("hub:  %sdevice present\n", (portstat & 1) ? "" : "no ");
+		printk("hub:  %s\n", (portstat & 2) ? "enabled" : "disabled");
+		printk("hub:  %ssuspended\n", (portstat & 4) ? "" : "not ");
+		printk("hub:  %sover current\n", (portstat & 8) ? "" : "not ");
+		printk("hub:  has %spower\n", (portstat & 0x100) ? "" : "no ");
+		printk("hub:  %s speed\n", (portstat & 0x200) ? "low" : "full");
 	}
 #endif
 
 	/* Enable power to the ports */
-	printk(KERN_INFO "USB hub %d: enabling power on all ports\n",
-	       dev->devnum);
+	printk("enabling power on all ports\n");
 	for (i = 0; i < hub->nports; i++)
 		usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
 }
@@ -155,7 +155,6 @@
 	struct usb_interface_descriptor *interface;
 	struct usb_endpoint_descriptor *endpoint;
 	struct usb_hub *hub;
-	unsigned long flags;
 
 	/* We don't handle multi-config hubs */
 	if (dev->descriptor.bNumConfigurations != 1)
@@ -165,7 +164,7 @@
 	if (dev->config[0].bNumInterfaces != 1)
 		return -1;
 
-	interface = &dev->config[0].altsetting[0].interface[0];
+	interface = &dev->config[0].interface[0];
 
 	/* Is it a hub? */
 	if (interface->bInterfaceClass != 9)
@@ -189,10 +188,10 @@
 		return -1;
 
 	/* We found a hub */
-	printk(KERN_INFO "USB hub found\n");
+	printk("USB hub found\n");
 
 	if ((hub = kmalloc(sizeof(*hub), GFP_KERNEL)) == NULL) {
-		printk(KERN_ERR "couldn't kmalloc hub struct\n");
+		printk("couldn't kmalloc hub struct\n");
 		return -1;
 	}
 
@@ -203,15 +202,9 @@
 	INIT_LIST_HEAD(&hub->event_list);
 	hub->dev = dev;
 
-	/* Record the new hub's existence */
-	spin_lock_irqsave(&hub_list_lock, flags);
-	INIT_LIST_HEAD(&hub->hub_list);
-	list_add(&hub->hub_list, &all_hubs_list);
-	spin_unlock_irqrestore(&hub_list_lock, flags);
-
 	usb_hub_configure(hub);
 
-	hub->irq_handle = usb_request_irq(dev, usb_rcvctrlpipe(dev, endpoint->bEndpointAddress), hub_irq, endpoint->bInterval, hub);
+	usb_request_irq(dev, usb_rcvctrlpipe(dev, endpoint->bEndpointAddress), hub_irq, endpoint->bInterval, hub);
 
 	/* Wake up khubd */
 	wake_up(&usb_hub_wait);
@@ -229,14 +222,9 @@
 	/* Delete it and then reset it */
 	list_del(&hub->event_list);
 	INIT_LIST_HEAD(&hub->event_list);
-	list_del(&hub->hub_list);
-	INIT_LIST_HEAD(&hub->hub_list);
 
 	spin_unlock_irqrestore(&hub_event_lock, flags);
 
-	usb_release_irq(hub->dev, hub->irq_handle);
-	hub->irq_handle = NULL;
-
 	/* Free the memory */
 	kfree(hub);
 }
@@ -254,12 +242,12 @@
 	wait_ms(50);	/* FIXME: This is from the *BSD stack, thanks! :) */
 
 	if (usb_get_port_status(hub, port + 1, buf)) {
-		printk(KERN_ERR "get_port_status failed\n");
+		printk("get_port_status failed\n");
 		return;
 	}
 
-	portstatus = le16_to_cpup((unsigned short *)buf + 0);
-	portchange = le16_to_cpup((unsigned short *)buf + 1);
+	portstatus = *((unsigned short *)buf + 0);
+	portchange = *((unsigned short *)buf + 1);
 
 	if ((!(portstatus & USB_PORT_STAT_CONNECTION)) &&
 		(!(portstatus & USB_PORT_STAT_ENABLE))) {
@@ -270,7 +258,7 @@
 
 	usb = hub->bus->op->allocate(hub);
 	if (!usb) {
-		printk(KERN_ERR "couldn't allocate usb_device\n");
+		printk("couldn't allocate usb_device\n");
 		return;
 	}
 
@@ -307,15 +295,15 @@
 
 		for (i = 0; i < hub->nports; i++) {
 			if (usb_get_port_status(dev, i + 1, buf)) {
-				printk(KERN_ERR "get_port_status failed\n");
+				printk("get_port_status failed\n");
 				continue;
 			}
 
-			portstatus = le16_to_cpup((unsigned short *)buf + 0);
-			portchange = le16_to_cpup((unsigned short *)buf + 1);
+			portstatus = *((unsigned short *)buf + 0);
+			portchange = *((unsigned short *)buf + 1);
 
 			if (portchange & USB_PORT_STAT_C_CONNECTION) {
-				printk(KERN_DEBUG "hub: port %d connection change\n", i + 1);
+				printk("hub: port %d connection change\n", i + 1);
 
 				usb_clear_port_feature(dev, i + 1,
 					USB_PORT_FEAT_C_CONNECTION);
@@ -324,19 +312,19 @@
 			}
 
 			if (portchange & USB_PORT_STAT_C_ENABLE) {
-				printk(KERN_DEBUG "hub: port %d enable change\n", i + 1);
+				printk("hub: port %d enable change\n", i + 1);
 				usb_clear_port_feature(dev, i + 1,
 					USB_PORT_FEAT_C_ENABLE);
 			}
 
 			if (portchange & USB_PORT_STAT_C_SUSPEND)
-				printk(KERN_DEBUG "hub: port %d suspend change\n", i + 1);
+				printk("hub: port %d suspend change\n", i + 1);
 
 			if (portchange & USB_PORT_STAT_C_OVERCURRENT)
-				printk(KERN_DEBUG "hub: port %d over-current change\n", i + 1);
+				printk("hub: port %d over-current change\n", i + 1);
 
 			if (portchange & USB_PORT_STAT_C_RESET) {
-				printk(KERN_DEBUG "hub: port %d reset change\n", i + 1);
+				printk("hub: port %d reset change\n", i + 1);
 				usb_clear_port_feature(dev, i + 1,
 					USB_PORT_FEAT_C_RESET);
 			}
@@ -351,13 +339,13 @@
 			portstatus = (buf[1] << 8) + buf[0];
 			portchange = (buf[3] << 8) + buf[2];
 
-			printk(KERN_DEBUG "hub: port %d status\n", i + 1);
-			printk(KERN_DEBUG "hub:  %sdevice present\n", (portstatus & 1) ? "" : "no ");
-			printk(KERN_DEBUG "hub:  %s\n", (portstatus & 2) ? "enabled" : "disabled");
-			printk(KERN_DEBUG "hub:  %ssuspended\n", (portstatus & 4) ? "" : "not ");
-			printk(KERN_DEBUG "hub:  %sover current\n", (portstatus & 8) ? "" : "not ");
-			printk(KERN_DEBUG "hub:  has %spower\n", (portstatus & 0x100) ? "" : "no ");
-			printk(KERN_DEBUG "hub:  %s speed\n", (portstatus & 0x200) ? "low" : "full");
+			printk("hub: port %d status\n", i + 1);
+			printk("hub:  %sdevice present\n", (portstatus & 1) ? "" : "no ");
+			printk("hub:  %s\n", (portstatus & 2) ? "enabled" : "disabled");
+			printk("hub:  %ssuspended\n", (portstatus & 4) ? "" : "not ");
+			printk("hub:  %sover current\n", (portstatus & 8) ? "" : "not ");
+			printk("hub:  has %spower\n", (portstatus & 0x100) ? "" : "no ");
+			printk("hub:  %s speed\n", (portstatus & 0x200) ? "low" : "full");
 #endif
 		}
 		tmp = next;
@@ -371,19 +359,16 @@
 
 static int usb_hub_thread(void *__hub)
 {
-	MOD_INC_USE_COUNT;
-	
-	printk(KERN_INFO "USB hub driver registered\n");
-
 	lock_kernel();
 
 	/*
 	 * This thread doesn't need any user-level access,
 	 * so get rid of all our resources
 	 */
+	printk("usb_hub_thread at %p\n", &usb_hub_thread);
 	exit_mm(current);
 	exit_files(current);
-	/* exit_fs(current); */
+	exit_fs(current);
 
 	/* Setup a nice name */
 	strcpy(current->comm, "khubd");
@@ -394,9 +379,7 @@
 		usb_hub_events();
 	} while (!signal_pending(current));
 
-	MOD_DEC_USE_COUNT;
-
-	printk(KERN_DEBUG "usb_hub_thread exiting\n");
+	printk("usb_hub_thread exiting\n");
 
 	return 0;
 }
@@ -411,12 +394,11 @@
 /*
  * This should be a separate module.
  */
-int usb_hub_init(void)
+int hub_init(void)
 {
 	int pid;
 
 	INIT_LIST_HEAD(&hub_event_list);
-	INIT_LIST_HEAD(&all_hubs_list);
 
 	usb_register(&hub_driver);
 	pid = kernel_thread(usb_hub_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
@@ -431,24 +413,10 @@
 	return 0;
 }
 
-void usb_hub_cleanup(void)
+void hub_cleanup(void)
 {
-	/*
-	 * Hub resources are freed for us by usb_deregister.  It
-	 * usb_driver_purge on every device which in turn calls that
-	 * devices disconnect function if it is using this driver.
-	 * The hub_disconnect function takes care of releasing the
-	 * individual hub resources. -greg
-	 */
-	usb_deregister(&hub_driver);
-} /* usb_hub_cleanup() */
+	if (khubd_pid >= 0)
+		kill_proc(khubd_pid, SIGINT, 1);
 
-#ifdef MODULE
-int init_module(void){
-	return usb_hub_init();
-}
-
-void cleanup_module(void){
-	usb_hub_cleanup();
+	usb_deregister(&hub_driver);
 }
-#endif
diff -urN linux-2.2.12-pre1/drivers/usb/hub.h linux-2.2.12-pre3/drivers/usb/hub.h
--- linux-2.2.12-pre1/drivers/usb/hub.h	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/hub.h	1999-04-21 05:41:59.000000000 -0700
@@ -12,7 +12,6 @@
 /*
  * Port feature numbers
  */
-#define USB_PORT_FEAT_CONNECTION	0
 #define USB_PORT_FEAT_ENABLE		1
 #define USB_PORT_FEAT_SUSPEND		2
 #define USB_PORT_FEAT_OVER_CURRENT	3
@@ -41,7 +40,7 @@
 #define USB_PORT_STAT_C_OVERCURRENT	0x0008
 #define USB_PORT_STAT_C_RESET		0x0010
 
-/* wHubCharacteristics (masks) */
+/* Characteristics */
 #define HUB_CHAR_LPSM		0x0003
 #define HUB_CHAR_COMPOUND	0x0004
 #define HUB_CHAR_OCPM		0x0018
@@ -68,12 +67,6 @@
 	/* Device structure */
 	struct usb_device *dev;
 
-	/* Reference to the hub's polling IRQ */
-	void* irq_handle;
-
-	/* List of hubs */
-	struct list_head hub_list;
-
 	/* Temporary event list */
 	struct list_head event_list;
 
diff -urN linux-2.2.12-pre1/drivers/usb/inits.h linux-2.2.12-pre3/drivers/usb/inits.h
--- linux-2.2.12-pre1/drivers/usb/inits.h	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/inits.h	1999-04-30 08:20:30.000000000 -0700
@@ -1,9 +1,6 @@
+int bp_mouse_init(void);
 int usb_kbd_init(void);
 int usb_audio_init(void);
-int usb_hub_init(void);
-int usb_acm_init(void);
-int usb_printer_init(void);
-void usb_hub_cleanup(void);
+int hub_init(void);
+void hub_cleanup(void);
 void usb_mouse_cleanup(void);
-int proc_usb_init (void);
-void proc_usb_cleanup (void);
diff -urN linux-2.2.12-pre1/drivers/usb/keyboard.c linux-2.2.12-pre3/drivers/usb/keyboard.c
--- linux-2.2.12-pre1/drivers/usb/keyboard.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/keyboard.c	1999-04-26 13:35:01.000000000 -0700
@@ -3,9 +3,6 @@
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/sched.h>
-#include <linux/config.h>
-#include <linux/module.h>
-
 #include <linux/kbd_ll.h>
 #include "usb.h"
 
@@ -56,12 +53,10 @@
     int scancode = (int) usb_kbd_map[key];
     if(scancode)
     {
-#ifndef CONFIG_MAC_KEYBOARD
         if(scancode & PCKBD_NEEDS_E0)
         {
             handle_scancode(0xe0, 1);
         }
-#endif /* CONFIG_MAC_KEYBOARD */
         handle_scancode((scancode & ~PCKBD_NEEDS_E0), down);
     }
 }
@@ -92,7 +87,7 @@
 }
 
 static int
-usb_kbd_irq(int state, void *buffer, int len, void *dev_id)
+usb_kbd_irq(int state, void *buffer, void *dev_id)
 {
     struct usb_keyboard *kbd = (struct usb_keyboard*) dev_id;
     unsigned long *down = (unsigned long*) buffer;
@@ -173,10 +168,7 @@
     struct usb_endpoint_descriptor *endpoint;
     struct usb_keyboard *kbd;
 
-    if (dev->descriptor.bNumConfigurations < 1)
-	return -1;
-
-    interface = &dev->config[0].altsetting[0].interface[0];
+    interface = &dev->config[0].interface[0];
     endpoint = &interface->endpoint[0];
 
     if(interface->bInterfaceClass != 3
@@ -195,10 +187,7 @@
         kbd->dev = dev;
         dev->private = kbd;
 
-        if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) {
-		printk (KERN_INFO " Failed usb_set_configuration: kbd\n");
-		goto probe_err;
-	}
+        usb_set_configuration(dev, dev->config[0].bConfigurationValue);
         usb_set_protocol(dev, 0);
         usb_set_idle(dev, 0, 0);
         
@@ -209,14 +198,9 @@
                         kbd);
 
         list_add(&kbd->list, &usb_kbd_list);
-	
-	return 0;
     }
 
-probe_err:
-    if (kbd)
-    	kfree (kbd);
-    return -1;
+    return 0;
 }
 
 static void
@@ -234,21 +218,9 @@
     printk(KERN_INFO "USB HID boot protocol keyboard removed.\n");
 }
 
-int usb_kbd_init(void)
+int
+usb_kbd_init(void)
 {
     usb_register(&usb_kbd_driver);
     return 0;
 }
-
-#ifdef MODULE
-int init_module(void)
-{
-	return usb_kbd_init();
-}
-
-void cleanup_module(void)
-{
-	usb_deregister(&usb_kbd_driver);
-}
-#endif
-
diff -urN linux-2.2.12-pre1/drivers/usb/keymap.c linux-2.2.12-pre3/drivers/usb/keymap.c
--- linux-2.2.12-pre1/drivers/usb/keymap.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/keymap.c	1999-04-26 12:19:05.000000000 -0700
@@ -7,13 +7,13 @@
     0x16,  0x2f,  0x11,  0x2d,  0x15,  0x2c,  0x02,  0x03,
 
     0x04,  0x05,  0x06,  0x07,  0x08,  0x09,  0x0a,  0x0b,
-    0x1c,  0x01,  0x0e,  0x0f,  0x39,  0x0c,  0x0d,  0x1a,
+    0x1c,  0x01,  0xd3,  0x0f,  0x39,  0x0c,  0x0d,  0x1a,
 
     0x1b,  0x2b,  0x00,  0x27,  0x28,  0x29,  0x33,  0x34,
     0x35,  0x3a,  0x3b,  0x3c,  0x3d,  0x3e,  0x3f,  0x40,
 
     0x41,  0x42,  0x43,  0x44,  0x57,  0x58,  0xb7,  0x46,
-    0x00,  0xd2,  0xc7,  0xc9,  0xd3,  0xcf,  0xd1,  0xcd,
+    0x00,  0xd2,  0xc7,  0xc9,  0x63,  0xcf,  0xd1,  0xcd,
 
     0xcb,  0xd0,  0xc8,  0x45,  0xb5,  0x37,  0x4a,  0x4e,
     0x9c,  0x4f,  0x50,  0x51,  0x4b,  0x4c,  0x4d,  0x47,
diff -urN linux-2.2.12-pre1/drivers/usb/Makefile linux-2.2.12-pre3/drivers/usb/Makefile
--- linux-2.2.12-pre1/drivers/usb/Makefile	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/Makefile	1999-05-10 10:18:34.000000000 -0700
@@ -7,6 +7,8 @@
 #
 # Note 2! The CFLAGS definitions are now inherited from the
 # parent makes..
+#
+# This isn't actually supported yet. Don't try to use it.
 
 SUB_DIRS     :=
 MOD_SUB_DIRS := $(SUB_DIRS)
@@ -15,127 +17,59 @@
 L_TARGET := usb.a
 M_OBJS   :=
 L_OBJS   :=
-
-ifeq ($(CONFIG_USB),y)
-  L_OBJS +=usbcore.o
-endif
-ifeq ($(CONFIG_USB),m)
-  M_OBJS +=usbcore.o
-  MIX_OBJS +=usb.o usb-debug.o usb-core.o
-  ifeq ($(CONFIG_USB_PROC),y)
-    MIX_OBJS += proc_usb.o
-  endif
-endif
-
-ifeq ($(CONFIG_USB_UHCI),y)
-    L_OBJS += uhci.o uhci-debug.o
-endif
-
-ifeq ($(CONFIG_USB_UHCI),m)
-      M_OBJS += usb-uhci.o
-    MIX_OBJS += uhci.o uhci-debug.o
-endif
-
-ifeq ($(CONFIG_USB_OHCI),y)
-    L_OBJS += ohci.o ohci-debug.o
-endif
-ifeq ($(CONFIG_USB_OHCI),m)
-      M_OBJS += usb-ohci.o
-      MIX_OBJS += ohci.o ohci-debug.o
-endif
-
-ifeq ($(CONFIG_USB_OHCI_HCD),y)
-    L_OBJS += ohci-hcd.o ohci-root-hub.o
-endif
-ifeq ($(CONFIG_USB_OHCI_HCD),m)
-      M_OBJS += usb-ohci-hcd.o
-      MIX_OBJS += ohci-hcd.o ohci-root-hub.o
-endif
+LX_OBJS  :=
+USBX_OBJS := usb.o hub.o usb-debug.o
 
 ifeq ($(CONFIG_USB_MOUSE),y)
-  L_OBJS += mouse.o
-endif
-ifeq ($(CONFIG_USB_MOUSE),m)
-  M_OBJS  +=mouse.o	
-  MIX_OBJS +=mouse.o
+  USBX_OBJS += mouse.o
 endif
 
-ifeq ($(CONFIG_USB_HUB),y)
-  L_OBJS += hub.o
-endif
-ifeq ($(CONFIG_USB_HUB),m)
-  M_OBJS  +=hub.o
-  MIX_OBJS +=hub.o	
-endif
-
-ifeq ($(CONFIG_USB_ACM),y)
-  L_OBJS += acm.o
-endif
-ifeq ($(CONFIG_USB_ACM),m)
-  M_OBJS += acm.o
-  MIX_OBJS +=acm.o
+ifeq ($(CONFIG_USB_KBD),y)
+  USBX_OBJS += keyboard.o keymap.o
 endif
 
-ifeq ($(CONFIG_USB_PRINTER),y)
-  L_OBJS += printer.o
+ifeq ($(CONFIG_USB_AUDIO),y)
+  USBX_OBJS += audio.o
 endif
 
-ifeq ($(CONFIG_USB_PRINTER),m)
-  M_OBJS += printer.o
-  MIX_OBJS += printer.o  
+ifeq ($(CONFIG_USB), y)
+  L_OBJS += $(USBX_OBJS)
 endif
 
-ifeq ($(CONFIG_USB_KBD),y)
-  ifneq ($(CONFIG_MAC_KEYBOARD),y)
-    L_OBJS += keyboard.o keymap.o
+ifeq ($(CONFIG_USB_UHCI),y)
+  ifeq ($(CONFIG_USB), y)
+    L_OBJS += uhci.o uhci-debug.o
   else
-    L_OBJS += keyboard.o keymap-mac.o
+    ifeq ($(CONFIG_USB),m)
+      M_OBJS += usb-uhci.o
+      MIX_OBJS += $(USBX_OBJS)
+    endif
   endif
 endif
 
-ifeq ($(CONFIG_USB_KBD),m)
-  M_OBJS += usb-keyboard.o
-  ifneq ($(CONFIG_MAC_KEYBOARD),y)
-    MIX_OBJS += keyboard.o keymap.o
+ifeq ($(CONFIG_USB_OHCI),y)
+  ifeq ($(CONFIG_USB), y)
+    L_OBJS += ohci.o ohci-debug.o
   else
-    MIX_OBJS += keyboard.o keymap-mac.o
+    ifeq ($(CONFIG_USB),m)
+      USBO_OBJS += ohci.o ohci-debug.o
+      M_OBJS += usb-ohci.o
+      MIX_OBJS += $(USBX_OBJS)
+    endif
   endif
 endif
 
-ifeq ($(CONFIG_USB_AUDIO),y)
-  L_OBJS += audio.o
-endif
-
-ifeq ($(CONFIG_USB_AUDIO),m)
-  M_OBJS += audio.o
-  MIX_OBJS += audio.o
-endif
-
-ifeq ($(CONFIG_USB_CPIA),y)
-  L_OBJS += cpia.o
-endif
-
-ifeq ($(CONFIG_USB_CPIA),m)
-  M_OBJS += cpia.o
-  MIX_OBJS += cpia.o
-endif
-
-ifeq ($(CONFIG_USB_SCSI),y)
-  L_OBJS += usb_scsi.o
-  ifeq ($(CONFIG_USB_SCSI_DEBUG),y)
-    L_OBJS += usb_scsi_debug.o
+ifeq ($(CONFIG_USB_OHCI_HCD),y)
+  ifeq ($(CONFIG_USB), y)
+    L_OBJS += ohci-hcd.o ohci-root-hub.o
+  else
+    ifeq ($(CONFIG_USB),m)
+      USBO_OBJS += ohci-hcd.o ohci-root-hub.o
+      M_OBJS += usb-ohci-hcd.o
+      MIX_OBJS += $(USBX_OBJS)
+    endif
   endif
 endif
-
-ifeq ($(CONFIG_USB_EZUSB),y)
-  L_OBJS += ezusb.o
-endif
-
-ifeq ($(CONFIG_USB_EZUSB),m)
-  M_OBJS += ezusb.o
-  MIX_OBJS += ezusb.o
-endif
-
 include $(TOPDIR)/Rules.make
 
 keymap.o: keymap.c
@@ -143,31 +77,12 @@
 keymap.c: maps/serial.map maps/usb.map maps/fixup.map
 	./mkmap > $@
 
-keymap-mac.o: keymap-mac.c
-keymap-mac.c: maps/mac.map maps/usb.map
-	./mkmap.adb > $@
-
-ifneq ($(CONFIG_MAC_KEYBOARD),y)
-usb-keyboard.o: keymap.o keyboard.o
-	$(LD) $(LD_RFLAG) -r -o $@  keymap.o keyboard.o 
-else
-usb-keyboard.o: keymap-mac.o keyboard.o
-	$(LD) $(LD_RFLAG) -r -o $@  keymap-mac.o keyboard.o 
-endif
+usb-uhci.o: uhci.o uhci-debug.o $(USBX_OBJS)
+	$(LD) $(LD_RFLAG) -r -o $@  uhci.o uhci-debug.o $(USBX_OBJS)
 
-usb-uhci.o: uhci.o uhci-debug.o 
-	$(LD) $(LD_RFLAG) -r -o $@  uhci.o uhci-debug.o 
+usb-ohci.o: ohci.o ohci-debug.o $(USBX_OBJS)
+	$(LD) $(LD_RFLAG) -r -o $@ ohci.o ohci-debug.o $(USBX_OBJS)
 
-usb-ohci.o: ohci.o ohci-debug.o 
-	$(LD) $(LD_RFLAG) -r -o $@ ohci.o ohci-debug.o 
-       
-usb-ohci-hcd.o: ohci-hcd.o ohci-root-hub.o 
-	$(LD) $(LD_RFLAG) -r -o $@ ohci-hcd.o ohci-root-hub.o 
+usb-ohci-hcd.o: ohci-hcd.o ohci-root-hub.o $(USBX_OBJS)
+	$(LD) $(LD_RFLAG) -r -o $@ ohci-hcd.o ohci-root-hub.o $(USBX_OBJS)
        
-ifeq ($(CONFIG_USB_PROC),y)
-usbcore.o: usb.o usb-debug.o usb-core.o proc_usb.o
-	$(LD) $(LD_RFLAG) -r -o $@ usb.o usb-debug.o usb-core.o proc_usb.o
-else
-usbcore.o: usb.o usb-debug.o usb-core.o
-	$(LD) $(LD_RFLAG) -r -o $@ usb.o usb-debug.o usb-core.o
-endif
diff -urN linux-2.2.12-pre1/drivers/usb/maps/fixup.map linux-2.2.12-pre3/drivers/usb/maps/fixup.map
--- linux-2.2.12-pre1/drivers/usb/maps/fixup.map	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/maps/fixup.map	1999-04-16 15:38:24.000000000 -0700
@@ -1,6 +1,7 @@
 # misc fixes
 keycode   0 = Pause
 keycode  29 = Control
+keycode  99 = Remove
 keycode  42 = Shift
 keycode  54 = Shift_R
 keycode 109 = Application
@@ -24,7 +25,7 @@
 keycode 208 = Down
 keycode 209 = Next
 keycode 210 = Insert
-keycode 211 = Remove
+keycode 211 = Delete
 keycode 219 = Window
 keycode 220 = Window_R
 keycode 221 = Menu
diff -urN linux-2.2.12-pre1/drivers/usb/maps/mac.map linux-2.2.12-pre3/drivers/usb/maps/mac.map
--- linux-2.2.12-pre1/drivers/usb/maps/mac.map	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/maps/mac.map	1969-12-31 16:00:00.000000000 -0800
@@ -1,350 +0,0 @@
-# Kernel keymap for Macintoshes. This uses 7 modifier combinations.
-keymaps 0-2,4-5,8,12
-#
-# Fixups:
-keycode 0x69 = Print_Screen
-keycode 0x6b = F14
-keycode 0x37 = Window_R
-#
-#keycode 0x00 = a
-# hack!
-keycode 0x80 = a
-	altgr   keycode 0x00 = Hex_A
-keycode 0x01 = s               
-keycode 0x02 = d
-	altgr   keycode 0x02 = Hex_D   
-keycode 0x03 = f
-	altgr   keycode 0x03 = Hex_F               
-keycode 0x04 = h               
-keycode 0x05 = g  
-keycode 0x06 = z
-keycode 0x07 = x               
-keycode 0x08 = c
-	altgr   keycode 0x08 = Hex_C   
-keycode 0x09 = v
-keycode 0x0a =
-keycode 0x0b = b
-	altgr   keycode 0x0b = Hex_B
-keycode 0x0c = q               
-keycode 0x0d = w               
-keycode 0x0e = e
-	altgr   keycode 0x0e = Hex_E   
-keycode 0x0f = r               
-keycode 0x10 = y               
-keycode 0x11 = t               
-keycode 0x12 = one              exclam          
-	alt     keycode 0x12 = Meta_one        
-keycode 0x13 = two              at               at              
-	control	keycode 0x13 = nul             
-	shift	control	keycode 0x13 = nul             
-	alt	keycode 0x13 = Meta_two        
-keycode 0x14 = three            numbersign      
-	control keycode 0x14 = Escape          
-	alt     keycode 0x14 = Meta_three      
-keycode 0x15 = four             dollar           dollar          
-	control keycode 0x15 = Control_backslash
-	alt     keycode 0x15 = Meta_four       
-keycode 0x16 = six              asciicircum     
-	control keycode 0x16 = Control_asciicircum
-	alt     keycode 0x16 = Meta_six        
-keycode 0x17 = five             percent         
-	control keycode 0x17 = Control_bracketright
-	alt     keycode 0x17 = Meta_five       
-keycode 0x18 = equal            plus            
-	alt     keycode 0x18 = Meta_equal      
-keycode 0x19 = nine             parenleft        bracketright    
-	alt     keycode 0x19 = Meta_nine       
-keycode 0x1a = seven            ampersand        braceleft       
-	control keycode 0x1a = Control_underscore
-	alt     keycode 0x1a = Meta_seven      
-keycode 0x1b = minus            underscore       backslash       
-	control	keycode 0x1b = Control_underscore
-	shift	control	keycode 0x1b = Control_underscore
-	alt	keycode 0x1b = Meta_minus      
-keycode 0x1c = eight            asterisk         bracketleft     
-	control keycode 0x1c = Delete          
-	alt     keycode 0x1c = Meta_eight      
-keycode 0x1d = zero             parenright       braceright      
-	alt     keycode 0x1d = Meta_zero       
-keycode 0x1e = bracketright     braceright       asciitilde      
-	control keycode 0x1e = Control_bracketright
-	alt     keycode 0x1e = Meta_bracketright
-keycode 0x1f = o               
-keycode 0x20 = u               
-keycode 0x21 = bracketleft      braceleft       
-	control keycode 0x21 = Escape          
-	alt     keycode 0x21 = Meta_bracketleft
-keycode 0x22 = i               
-keycode 0x23 = p               
-keycode 0x24 = Return          
-	alt     keycode 0x24 = Meta_Control_m  
-keycode 0x25 = l               
-keycode 0x26 = j               
-keycode 0x27 = apostrophe       quotedbl        
-	control keycode 0x27 = Control_g       
-	alt     keycode 0x27 = Meta_apostrophe 
-keycode 0x28 = k               
-keycode 0x29 = semicolon        colon           
-	alt     keycode 0x29 = Meta_semicolon  
-keycode 0x2a = backslash        bar             
-	control keycode 0x2a = Control_backslash
-	alt     keycode 0x2a = Meta_backslash  
-keycode 0x2b = comma            less            
-	alt     keycode 0x2b = Meta_comma      
-keycode 0x2c = slash            question        
-	control keycode 0x2c = Delete          
-	alt     keycode 0x2c = Meta_slash      
-keycode 0x2d = n
-keycode 0x2e = m               
-keycode 0x2f = period           greater         
-	control keycode 0x2f = Compose         
-	alt     keycode 0x2f = Meta_period     
-keycode 0x30 = Tab              Tab             
-	alt     keycode 0x30 = Meta_Tab        
-keycode 0x31 = space            space           
-	control keycode 0x31 = nul             
-	alt     keycode 0x31 = Meta_space      
-keycode 0x32 = grave            asciitilde      
-	control keycode 0x32 = nul             
-	alt     keycode 0x32 = Meta_grave      
-keycode 0x33 = Delete           Delete          
-	control keycode 0x33 = BackSpace
-	alt     keycode 0x33 = Meta_Delete     
-keycode 0x34 =
-keycode 0x35 = Escape           Escape          
-	alt     keycode 0x35 = Meta_Escape     
-keycode 0x36 = Control         
-keycode 0x37 = Window             
-keycode 0x38 = Shift
-keycode 0x39 = Caps_Lock       
-keycode 0x3a = Alt
-keycode 0x3b = Left            
-	alt     keycode 0x3b = Decr_Console
-keycode 0x3c = Right           
-	alt     keycode 0x3c = Incr_Console
-keycode 0x3d = Down            
-keycode 0x3e = Up              
-keycode 0x3f =
-keycode 0x40 =
-keycode 0x41 = KP_Period       
-keycode 0x42 =
-keycode 0x43 = KP_Multiply     
-keycode 0x44 =
-keycode 0x45 = KP_Add          
-keycode 0x46 =
-keycode 0x47 = Num_Lock
-#	shift   keycode 0x47 = Bare_Num_Lock
-keycode 0x48 =
-keycode 0x49 =
-keycode 0x4a =
-keycode 0x4b = KP_Divide       
-keycode 0x4c = KP_Enter        
-keycode 0x4d =
-keycode 0x4e = KP_Subtract     
-keycode 0x4f =
-keycode 0x50 =
-keycode 0x51 =
-#keycode 0x51 = KP_Equals
-keycode 0x52 = KP_0            
-	alt     keycode 0x52 = Ascii_0         
-	altgr   keycode 0x52 = Hex_0         
-keycode 0x53 = KP_1            
-	alt     keycode 0x53 = Ascii_1         
-	altgr   keycode 0x53 = Hex_1         
-keycode 0x54 = KP_2            
-	alt     keycode 0x54 = Ascii_2         
-	altgr   keycode 0x54 = Hex_2         
-keycode 0x55 = KP_3            
-	alt     keycode 0x55 = Ascii_3         
-	altgr   keycode 0x55 = Hex_3         
-keycode 0x56 = KP_4            
-	alt     keycode 0x56 = Ascii_4         
-	altgr   keycode 0x56 = Hex_4         
-keycode 0x57 = KP_5            
-	alt     keycode 0x57 = Ascii_5         
-	altgr   keycode 0x57 = Hex_5         
-keycode 0x58 = KP_6            
-	alt     keycode 0x58 = Ascii_6         
-	altgr   keycode 0x58 = Hex_6         
-keycode 0x59 = KP_7            
-	alt     keycode 0x59 = Ascii_7         
-	altgr   keycode 0x59 = Hex_7
-keycode 0x5b = KP_8            
-	alt     keycode 0x5b = Ascii_8         
-	altgr   keycode 0x5b = Hex_8         
-keycode 0x5c = KP_9            
-	alt     keycode 0x5c = Ascii_9         
-	altgr   keycode 0x5c = Hex_9         
-keycode 0x5d =
-keycode 0x5e =
-keycode 0x5f =
-keycode 0x60 = F5               F15              Console_17      
-	control keycode 0x60 = F5              
-	alt     keycode 0x60 = Console_5       
-	control alt     keycode 0x60 = Console_5       
-keycode 0x61 = F6               F16              Console_18      
-	control keycode 0x61 = F6              
-	alt     keycode 0x61 = Console_6       
-	control alt     keycode 0x61 = Console_6       
-keycode 0x62 = F7               F17              Console_19      
-	control keycode 0x62 = F7              
-	alt     keycode 0x62 = Console_7       
-	control alt     keycode 0x62 = Console_7       
-keycode 0x63 = F3               F13              Console_15      
-	control keycode 0x63 = F3              
-	alt     keycode 0x63 = Console_3       
-	control alt     keycode 0x63 = Console_3       
-keycode 0x64 = F8               F18              Console_20      
-	control keycode 0x64 = F8              
-	alt     keycode 0x64 = Console_8       
-	control alt     keycode 0x64 = Console_8       
-keycode 0x65 = F9               F19              Console_21      
-	control keycode 0x65 = F9              
-	alt     keycode 0x65 = Console_9       
-	control alt     keycode 0x65 = Console_9       
-keycode 0x66 =
-keycode 0x67 = F11              F11              Console_23      
-	control keycode 0x67 = F11             
-	alt     keycode 0x67 = Console_11      
-	control alt     keycode 0x67 = Console_11      
-keycode 0x68 =
-keycode 0x69 = F13             
-keycode 0x6a =
-keycode 0x6b = Scroll_Lock      Show_Memory      Show_Registers  
-	control keycode 0x6b = Show_State      
-	alt     keycode 0x6b = Scroll_Lock     
-keycode 0x6c =
-keycode 0x6d = F10              F20              Console_22      
-	control keycode 0x6d = F10             
-	alt     keycode 0x6d = Console_10      
-	control alt     keycode 0x6d = Console_10      
-keycode 0x6e =
-keycode 0x6f = F12              F12              Console_24      
-	control keycode 0x6f = F12             
-	alt     keycode 0x6f = Console_12      
-	control alt     keycode 0x6f = Console_12      
-keycode 0x70 =
-keycode 0x71 = Pause
-keycode 0x72 = Insert          
-keycode 0x73 = Home
-keycode 0x74 = Prior           
-	shift   keycode 0x74 = Scroll_Backward 
-keycode 0x75 = Remove          
-keycode 0x76 = F4               F14              Console_16      
-	control keycode 0x76 = F4              
-	alt     keycode 0x76 = Console_4       
-	control alt     keycode 0x76 = Console_4       
-keycode 0x77 = End
-keycode 0x78 = F2               F12              Console_14      
-	control keycode 0x78 = F2              
-	alt     keycode 0x78 = Console_2       
-	control alt     keycode 0x78 = Console_2       
-keycode 0x79 = Next            
-	shift   keycode 0x79 = Scroll_Forward  
-keycode 0x7a = F1               F11              Console_13      
-	control keycode 0x7a = F1              
-	alt     keycode 0x7a = Console_1       
-	control alt     keycode 0x7a = Console_1       
-keycode 0x7b = Shift_R
-keycode 0x7c = Alt_R
-keycode 0x7d = Control_R
-keycode 0x7e =
-keycode 0x7f =
-#keycode 0x7f = Power
-	control shift   keycode 0x7f = Boot
-string F1 = "\033[[A"
-string F2 = "\033[[B"
-string F3 = "\033[[C"
-string F4 = "\033[[D"
-string F5 = "\033[[E"
-string F6 = "\033[17~"
-string F7 = "\033[18~"
-string F8 = "\033[19~"
-string F9 = "\033[20~"
-string F10 = "\033[21~"
-string F11 = "\033[23~"
-string F12 = "\033[24~"
-string F13 = "\033[25~"
-string F14 = "\033[26~"
-string F15 = "\033[28~"
-string F16 = "\033[29~"
-string F17 = "\033[31~"
-string F18 = "\033[32~"
-string F19 = "\033[33~"
-string F20 = "\033[34~"
-string Find = "\033[1~"
-string Insert = "\033[2~"
-string Remove = "\033[3~"
-string Select = "\033[4~"
-string Prior = "\033[5~"
-string Next = "\033[6~"
-string Macro = "\033[M"
-string Pause = "\033[P"
-compose '`' 'A' to 'À'
-compose '`' 'a' to 'à'
-compose '\'' 'A' to 'Á'
-compose '\'' 'a' to 'á'
-compose '^' 'A' to 'Â'
-compose '^' 'a' to 'â'
-compose '~' 'A' to 'Ã'
-compose '~' 'a' to 'ã'
-compose '"' 'A' to 'Ä'
-compose '"' 'a' to 'ä'
-compose 'O' 'A' to 'Å'
-compose 'o' 'a' to 'å'
-compose '0' 'A' to 'Å'
-compose '0' 'a' to 'å'
-compose 'A' 'A' to 'Å'
-compose 'a' 'a' to 'å'
-compose 'A' 'E' to 'Æ'
-compose 'a' 'e' to 'æ'
-compose ',' 'C' to 'Ç'
-compose ',' 'c' to 'ç'
-compose '`' 'E' to 'È'
-compose '`' 'e' to 'è'
-compose '\'' 'E' to 'É'
-compose '\'' 'e' to 'é'
-compose '^' 'E' to 'Ê'
-compose '^' 'e' to 'ê'
-compose '"' 'E' to 'Ë'
-compose '"' 'e' to 'ë'
-compose '`' 'I' to 'Ì'
-compose '`' 'i' to 'ì'
-compose '\'' 'I' to 'Í'
-compose '\'' 'i' to 'í'
-compose '^' 'I' to 'Î'
-compose '^' 'i' to 'î'
-compose '"' 'I' to 'Ï'
-compose '"' 'i' to 'ï'
-compose '-' 'D' to 'Ð'
-compose '-' 'd' to 'ð'
-compose '~' 'N' to 'Ñ'
-compose '~' 'n' to 'ñ'
-compose '`' 'O' to 'Ò'
-compose '`' 'o' to 'ò'
-compose '\'' 'O' to 'Ó'
-compose '\'' 'o' to 'ó'
-compose '^' 'O' to 'Ô'
-compose '^' 'o' to 'ô'
-compose '~' 'O' to 'Õ'
-compose '~' 'o' to 'õ'
-compose '"' 'O' to 'Ö'
-compose '"' 'o' to 'ö'
-compose '/' 'O' to 'Ø'
-compose '/' 'o' to 'ø'
-compose '`' 'U' to 'Ù'
-compose '`' 'u' to 'ù'
-compose '\'' 'U' to 'Ú'
-compose '\'' 'u' to 'ú'
-compose '^' 'U' to 'Û'
-compose '^' 'u' to 'û'
-compose '"' 'U' to 'Ü'
-compose '"' 'u' to 'ü'
-compose '\'' 'Y' to 'Ý'
-compose '\'' 'y' to 'ý'
-compose 'T' 'H' to 'Þ'
-compose 't' 'h' to 'þ'
-compose 's' 's' to 'ß'
-compose '"' 'y' to 'ÿ'
-compose 's' 'z' to 'ß'
-compose 'i' 'j' to 'ÿ'
diff -urN linux-2.2.12-pre1/drivers/usb/mkmap.adb linux-2.2.12-pre3/drivers/usb/mkmap.adb
--- linux-2.2.12-pre1/drivers/usb/mkmap.adb	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/mkmap.adb	1969-12-31 16:00:00.000000000 -0800
@@ -1,88 +0,0 @@
-#!/usr/bin/perl
-
-($ME = $0) =~ s|.*/||;
-
-$file = "maps/mac.map";
-$line = 1;
-open(PC, $file) || die("$!");
-while(<PC>)
-{
-    if(/^\s*keycode\s+(\d+|0x[0-9a-fA-F]+)\s*=\s*(\S+)/)
-    {
-        my($idx) = $1;
-        my($sym) = $2;
-        if ($idx =~ "0x.*") {
-            $idx = hex($idx);
-        } else {
-            $idx = int($idx);
-        }
-        if(defined($map{uc($sym)}))
-        {
-            # print STDERR "$file:$line: warning: `$sym' redefined\n";
-        }
-        $map{uc($sym)} = $idx;
-    }
-    $line++;
-}
-close(PC);
-
-# $file = "maps/fixup.map";
-# $line = 1;
-# open(FIXUP, $file) || die("$!");
-# while(<FIXUP>)
-# {
-#     if(/^\s*keycode\s+(\d+)\s*=\s*/)
-#     {
-#       my($idx) = int($1);
-#       for $sym (split(/\s+/, $'))
-#         {
-#           $map{uc($sym)} = $idx;
-#       }
-#     }
-#     $line++;
-# }
-# close(FIXUP);
-
-$file = "maps/usb.map";
-$line = 1;
-open(USB, $file) || die("$!");
-while(<USB>)
-{
-    if(/^\s*keycode\s+(\d+)\s*=\s*/)
-    {
-        my($idx) = int($1);
-        for $sym (split(/\s+/, $'))
-        {
-            my($val) = $map{uc($sym)};
-            $map[$idx] = $val;
-            if(!defined($val))
-            {
-                print STDERR "$file:$line: warning: `$sym' undefined\n";
-            }
-            else
-            {
-                last;
-            }
-        }
-    }
-    $line++;
-}
-close(USB);
-
-print "unsigned char usb_kbd_map[256] = \n{\n";
-for($x = 0; $x < 32; $x++)
-{
-    if($x && !($x % 2))
-    {
-        print "\n";
-    }
-    print "  ";
-    for($y = 0; $y < 8; $y++)
-    {
-        my($idx) = $x * 8 + $y;
-        print sprintf("  0x%02x,",
-                      int(defined($map[$idx]) ? $map[$idx]:0));
-    }
-    print "\n";
-}
-print "};\n";
diff -urN linux-2.2.12-pre1/drivers/usb/mouse.c linux-2.2.12-pre3/drivers/usb/mouse.c
--- linux-2.2.12-pre1/drivers/usb/mouse.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/mouse.c	1999-04-30 08:20:49.000000000 -0700
@@ -2,8 +2,6 @@
  * USB HID boot protocol mouse support based on MS BusMouse driver, psaux 
  * driver, and Linus's skeleton USB mouse driver. Fixed up a lot by Linus.
  *
- * N.B. this driver can't cope if more than one mouse is connected! - paulus
- *
  * Brad Keryan 4/3/1999
  *
  * version 0.20: Linus rewrote read_mouse() to do PS/2 and do it
@@ -35,7 +33,6 @@
 #include <linux/poll.h>
 #include <linux/init.h>
 #include <linux/malloc.h>
-#include <linux/module.h>
 
 #include <asm/spinlock.h>
 
@@ -51,23 +48,17 @@
 	int present; /* this mouse is plugged in */
 	int active; /* someone is has this mouse's device open */
 	int ready; /* the mouse has changed state since the last read */
-	wait_queue_head_t wait; /* for polling */
+	struct wait_queue *wait; /* for polling */
 	struct fasync_struct *fasync;
 	/* later, add a list here to support multiple mice */
 	/* but we will also need a list of file pointers to identify it */
-
-	/* FIXME: move these to a per-mouse structure */
-	struct usb_device *dev;  /* host controller this mouse is on */
-	void* irq_handle;  /* host controller's IRQ transfer handle */
-	__u8 bEndpointAddress;  /* these are from the endpoint descriptor */
-	__u8 bInterval;		/* ...  used when calling usb_request_irq */
 };
 
 static struct mouse_state static_mouse_state;
 
 spinlock_t usb_mouse_lock = SPIN_LOCK_UNLOCKED;
 
-static int mouse_irq(int state, void *__buffer, int len, void *dev_id)
+static int mouse_irq(int state, void *__buffer, void *dev_id)
 {
 	signed char *data = __buffer;
 	/* finding the mouse is easy when there's only one */
@@ -82,7 +73,7 @@
 	mouse->buttons = data[0] & 0x07;
 	mouse->dx += data[1]; /* data[] is signed, so this works */
 	mouse->dy -= data[2]; /* y-axis is reversed */
-	mouse->dz -= data[3];
+	mouse->dz += data[3];
 	mouse->ready = 1;
 
 	add_mouse_randomness((mouse->buttons << 24) + (mouse->dz << 16 ) + 
@@ -111,16 +102,8 @@
 	struct mouse_state *mouse = &static_mouse_state;
 
 	fasync_mouse(-1, file, 0);
-
-	MOD_DEC_USE_COUNT;
-
-	if (--mouse->active == 0) {
-		/* stop polling the mouse while its not in use */
-	    	usb_release_irq(mouse->dev, mouse->irq_handle);
-		/* never keep a reference to a released IRQ! */
-		mouse->irq_handle = NULL;
-	}
-
+	if (--mouse->active)
+		return 0;
 	return 0;
 }
 
@@ -134,13 +117,6 @@
 		return 0;
 	/* flush state */
 	mouse->buttons = mouse->dx = mouse->dy = mouse->dz = 0;
-
-	/* prevent the driver from being unloaded while its in use */
-	MOD_INC_USE_COUNT;
-
-	/* start the usb controller's polling of the mouse */
-	mouse->irq_handle = usb_request_irq(mouse->dev, usb_rcvctrlpipe(mouse->dev, mouse->bEndpointAddress), mouse_irq, mouse->bInterval, NULL);
-
 	return 0;
 }
 
@@ -196,30 +172,6 @@
 			buffer++;
 			retval++;
 			state = 0;
-			if (!--count)
-				break;
-		}
-
-		/*
-		 * SUBTLE:
-		 *
-		 * The only way to get here is to do a read() of
-		 * more than 3 bytes: if you read a byte at a time
-		 * you will just ever see states 0-2, for backwards
-		 * compatibility.
-		 *
-		 * So you can think of this as a packet interface,
-		 * where you have arbitrary-sized packets, and you
-		 * only ever see the first three bytes when you read
-		 * them in small chunks.
-		 */
-		{ /* fallthrough - dz */
-			int dz = mouse->dz;
-			mouse->dz = 0;
-			put_user(dz, buffer);
-			buffer++;
-			retval++;
-			state = 0;
 		}
 		break;
 		}
@@ -271,7 +223,7 @@
 		return -1;
 
 	/* Is it a mouse interface? */
-	interface = &dev->config[0].altsetting[0].interface[0];
+	interface = &dev->config[0].interface[0];
 	if (interface->bInterfaceClass != 3)
 		return -1;
 	if (interface->bInterfaceSubClass != 1)
@@ -293,17 +245,11 @@
 	if ((endpoint->bmAttributes & 3) != 3)
 		return -1;
 
-	printk(KERN_INFO "USB mouse found\n");
+	printk("USB mouse found\n");
 
-	if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) {
-		printk (KERN_INFO " Failed usb_set_configuration: mouse\n");
-		return -1;
-	}
+	usb_set_configuration(dev, dev->config[0].bConfigurationValue);
 
-	/* these are used to request the irq when the mouse is opened */
-	mouse->dev = dev;
-	mouse->bEndpointAddress = endpoint->bEndpointAddress;
-	mouse->bInterval = endpoint->bInterval;
+	usb_request_irq(dev, usb_rcvctrlpipe(dev, endpoint->bEndpointAddress), mouse_irq, endpoint->bInterval, NULL);
 
 	mouse->present = 1;
 	return 0;
@@ -313,18 +259,8 @@
 {
 	struct mouse_state *mouse = &static_mouse_state;
 
-	/* stop the usb interrupt transfer */
-	if (mouse->present) {
-	    	usb_release_irq(mouse->dev, mouse->irq_handle);
-		/* never keep a reference to a released IRQ! */
-		mouse->irq_handle = NULL;
-	}
-
-	mouse->irq_handle = NULL;
-
 	/* this might need work */
 	mouse->present = 0;
-	printk(KERN_INFO "Mouse disconnected\n");
 }
 
 static struct usb_driver mouse_driver = {
@@ -338,42 +274,20 @@
 {
 	struct mouse_state *mouse = &static_mouse_state;
 
+	misc_register(&usb_mouse);
+
 	mouse->present = mouse->active = 0;
-	mouse->irq_handle = NULL;
-	init_waitqueue_head(&mouse->wait);
+	mouse->wait = NULL;
 	mouse->fasync = NULL;
 
-	misc_register(&usb_mouse);
-
 	usb_register(&mouse_driver);
-	printk(KERN_INFO "USB HID boot protocol mouse driver registered.\n");
+	printk(KERN_INFO "USB HID boot protocol mouse registered.\n");
 	return 0;
 }
 
 void usb_mouse_cleanup(void)
 {
-	struct mouse_state *mouse = &static_mouse_state;
-
-	/* stop the usb interrupt transfer */
-	if (mouse->present) {
-	    	usb_release_irq(mouse->dev, mouse->irq_handle);
-		/* never keep a reference to a released IRQ! */
-		mouse->irq_handle = NULL;
-	}
-
 	/* this, too, probably needs work */
 	usb_deregister(&mouse_driver);
 	misc_deregister(&usb_mouse);
 }
-
-#ifdef MODULE
-int init_module(void)
-{
-	return usb_mouse_init();
-}
-
-void cleanup_module(void)
-{
-	usb_mouse_cleanup();
-}
-#endif
diff -urN linux-2.2.12-pre1/drivers/usb/ohci.c linux-2.2.12-pre3/drivers/usb/ohci.c
--- linux-2.2.12-pre1/drivers/usb/ohci.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/ohci.c	1999-05-11 10:27:04.000000000 -0700
@@ -2,14 +2,19 @@
  * Open Host Controller Interface driver for USB.
  *
  * (C) Copyright 1999 Gregory P. Smith <greg@electricrain.com>
- * Significant code from the following individuals has also been used:
- * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> [ohci-hcd.c]
- * (C) Copyright 1999 Linus Torvalds [uhci.c]
  *
  * This is the "other" host controller interface for USB.  You will
  * find this on many non-Intel based motherboards, and of course the
- * Mac.  As Linus hacked his UHCI driver together first, I originally
- * modeled this after his.. (it should be obvious)
+ * Mac.  As Linus hacked his UHCI driver together first, I modeled
+ * this after his.. (it should be obvious)
+ *
+ * From the programming standpoint the OHCI interface seems a little
+ * prettier and potentially less CPU intensive.  This remains to be
+ * proven.  In reality, I don't believe it'll make one darn bit of
+ * difference.  USB v1.1 is a slow bus by today's standards.
+ *
+ * OHCI hardware takes care of most of the scheduling of different
+ * transfer types with the correct prioritization for us.
  *
  * To get started in USB, I used the "Universal Serial Bus System
  * Architecture" book by Mindshare, Inc.  It was a reasonable introduction
@@ -24,7 +29,7 @@
  *
  * No filesystems were harmed in the development of this code.
  *
- * $Id: ohci.c,v 1.43 1999/05/16 22:35:24 greg Exp $
+ * $Id: ohci.c,v 1.26 1999/05/11 07:34:47 greg Exp $
  */
 
 #include <linux/config.h>
@@ -44,6 +49,7 @@
 #include <asm/system.h>
 
 #include "ohci.h"
+#include "inits.h"
 
 #ifdef CONFIG_APM
 #include <linux/apm_bios.h>
@@ -51,128 +57,94 @@
 static int apm_resume = 0;
 #endif
 
-static DECLARE_WAIT_QUEUE_HEAD(ohci_configure);
+static struct wait_queue *ohci_configure = NULL;
 
-#ifdef CONFIG_USB_OHCI_DEBUG
-#define OHCI_DEBUG    /* to make typing it easier.. */
+#ifdef OHCI_TIMER
+static struct timer_list ohci_timer;	/* timer for root hub polling */
 #endif
 
-int MegaDebug = 0;	/* SIGUSR2 to the control thread toggles this */
 
+static int ohci_td_result(struct ohci_device *dev, struct ohci_td *td)
+{
+	unsigned int status;
 
-#ifdef OHCI_TIMER
-static struct timer_list ohci_timer;	/* timer for root hub polling */
-#endif
+	status = td->info & OHCI_TD_CC;
 
-static spinlock_t ohci_edtd_lock = SPIN_LOCK_UNLOCKED;
+	/* TODO Debugging code for TD failures goes here */
+
+	return status;
+} /* ohci_td_result() */
 
-#define FIELDS_OF_ED(e)	le32_to_cpup(&e->status), le32_to_cpup(&e->tail_td), \
-			le32_to_cpup(&e->_head_td), le32_to_cpup(&e->next_ed)
-#define FIELDS_OF_TD(t)	le32_to_cpup(&t->info), le32_to_cpup(&t->cur_buf), \
-			le32_to_cpup(&t->next_td), le32_to_cpup(&t->buf_end)
-
-#ifdef OHCI_DEBUG
-static const char *cc_names[16] = {
-	"no error",
-	"CRC error",
-	"bit stuff error",
-	"data toggle mismatch",
-	"stall",
-	"device not responding",
-	"PID check failed",
-	"unexpected PID",
-	"data overrun",
-	"data underrun",
-	"reserved (10)",
-	"reserved (11)",
-	"buffer overrun",
-	"buffer underrun",
-	"not accessed (14)",
-	"not accessed"
-};
-#endif
+
+static spinlock_t ohci_edtd_lock = SPIN_LOCK_UNLOCKED;
 
 /*
- * Add a chain of TDs to the end of the TD list on a given ED.
- *
- * This function uses the first TD of the chain as the new dummy TD
- * for the ED, and uses the old dummy TD instead of the first TD
- * of the chain.  The reason for this is that this makes it possible
- * to update the TD chain without needing any locking between the
- * CPU and the OHCI controller.
- *
- * The return value is the pointer to the new first TD (the old
- * dummy TD).
- *
- * Important!  This function is not re-entrant w.r.t. each ED.
- * Locking ohci_edtd_lock while using the function is a must
- * if there is any possibility of another CPU or an interrupt routine
- * calling this function with the same ED.
+ * Add a TD to the end of the TD list on a given ED.  If td->next_td
+ * points to any more TDs, they will be added as well (naturally).
+ * Otherwise td->next_td must be 0.
+ * 
+ * The SKIP flag will be cleared after this function.
+ *
+ * Important!  This function needs locking and atomicity as it works
+ * in parallel with the HC's DMA.  Locking ohci_edtd_lock while using
+ * the function is a must.
  *
  * This function can be called by the interrupt handler.
  */
-static struct ohci_td *ohci_add_tds_to_ed(struct ohci_td *td,
-					  struct ohci_ed *ed)
+static void ohci_add_td_to_ed(struct ohci_td *td, struct ohci_ed *ed)
 {
-	struct ohci_td *t, *dummy_td;
-	u32 new_dummy;
+	/* don't let the HC pull anything from underneath us */
+	ed->status |= OHCI_ED_SKIP;
 
-	if (ed->tail_td == 0) {
-		printk(KERN_ERR "eek! an ED without a dummy_td\n");
-		return td;
+	if (ed_head_td(ed) == 0) {	/* empty list, put it on the head */
+		set_ed_head_td(ed, virt_to_bus(td));
+		ed->tail_td = 0;
+	} else {
+		struct ohci_td *tail, *head;
+		head = (ed_head_td(ed) == 0) ? NULL : bus_to_virt(ed_head_td(ed));
+		tail = (ed->tail_td == 0) ? NULL : bus_to_virt(ed->tail_td);
+		if (!tail) {	/* no tail, single element list */
+			td->next_td = head->next_td;
+			head->next_td = virt_to_bus(td);
+			ed->tail_td = virt_to_bus(td);
+		} else {	/* append to the list */
+			td->next_td = tail->next_td;
+			tail->next_td = virt_to_bus(td);
+			ed->tail_td = virt_to_bus(td);
+		}
 	}
 
-	/* Get a pointer to the current dummy TD. */
-	dummy_td = bus_to_virt(ed_tail_td(ed));
-
-	for (t = td; ; t = bus_to_virt(le32_to_cpup(&t->next_td))) {
-		t->ed = ed;
-		if (t->next_td == 0)
-			break;
+	/* save the ED link in each of the TDs added */
+	td->ed = ed;
+	while (td->next_td != 0) {
+		td = bus_to_virt(td->next_td);
+		td->ed = ed;
 	}
 
-	/* Make the last TD point back to the first, since it
-	 * will become the new dummy TD. */
-	new_dummy = cpu_to_le32(virt_to_bus(td));
-	t->next_td = new_dummy;
-
-	/* Copy the contents of the first TD into the dummy */
-	*dummy_td = *td;
-
-	/* Turn the first TD into a dummy */
-	make_dumb_td(td);
-
-	/* Set the HC's tail pointer to the new dummy */
-	ed->tail_td = new_dummy;
-
-	return dummy_td;	/* replacement head of chain */
-} /* ohci_add_tds_to_ed() */
-
-
-/* .......... */
+	/* turn off the SKIP flag */
+	ed->status &= ~OHCI_ED_SKIP;
+} /* ohci_add_td_to_ed() */
 
 
-void ohci_start_control(struct ohci *ohci)
+inline void ohci_start_control(struct ohci *ohci)
 {
 	/* tell the HC to start processing the control list */
-	writel_set(OHCI_USB_CLE, &ohci->regs->control);
-	writel_set(OHCI_CMDSTAT_CLF, &ohci->regs->cmdstatus);
+	writel(OHCI_CMDSTAT_CLF, &ohci->regs->cmdstatus);
 }
 
-void ohci_start_bulk(struct ohci *ohci)
+inline void ohci_start_bulk(struct ohci *ohci)
 {
 	/* tell the HC to start processing the bulk list */
-	writel_set(OHCI_USB_BLE, &ohci->regs->control);
-	writel_set(OHCI_CMDSTAT_BLF, &ohci->regs->cmdstatus);
+	writel(OHCI_CMDSTAT_BLF, &ohci->regs->cmdstatus);
 }
 
-void ohci_start_periodic(struct ohci *ohci)
+inline void ohci_start_periodic(struct ohci *ohci)
 {
-	/* enable processing periodic (intr) transfers starting next frame */
+	/* enable processing periodc transfers starting next frame */
 	writel_set(OHCI_USB_PLE, &ohci->regs->control);
 }
 
-void ohci_start_isoc(struct ohci *ohci)
+inline void ohci_start_isoc(struct ohci *ohci)
 {
 	/* enable processing isoc. transfers starting next frame */
 	writel_set(OHCI_USB_IE, &ohci->regs->control);
@@ -180,7 +152,6 @@
 
 /*
  * Add an ED to the hardware register ED list pointed to by hw_listhead_p
- * This function only makes sense for Control and Bulk EDs.
  */
 static void ohci_add_ed_to_hw(struct ohci_ed *ed, void* hw_listhead_p)
 {
@@ -193,17 +164,19 @@
 
 	/* if the list is not empty, insert this ED at the front */
 	/* XXX should they go on the end? */
-	ed->next_ed = cpu_to_le32(listhead);
+	if (listhead) {
+		ed->next_ed = listhead;
+	}
 
 	/* update the hardware listhead pointer */
 	writel(virt_to_bus(ed), hw_listhead_p);
 
 	spin_unlock_irqrestore(&ohci_edtd_lock, flags);
-} /* ohci_add_ed_to_hw() */
+} /* ohci_add_ed() */
 
 
 /*
- *  Put a control ED on the controller's list
+ *  Put another control ED on the controller's list
  */
 void ohci_add_control_ed(struct ohci *ohci, struct ohci_ed *ed)
 {
@@ -211,187 +184,37 @@
 	ohci_start_control(ohci);
 } /* ohci_add_control_ed() */
 
-/*
- *  Put a bulk ED on the controller's list
- */
-void ohci_add_bulk_ed(struct ohci *ohci, struct ohci_ed *ed)
-{
-	ohci_add_ed_to_hw(ed, &ohci->regs->ed_bulkhead);
-	ohci_start_bulk(ohci);
-} /* ohci_add_bulk_ed() */
 
+#if 0
 /*
- *  Put a periodic ED on the appropriate list given the period.
+ *  Put another control ED on the controller's list
  */
 void ohci_add_periodic_ed(struct ohci *ohci, struct ohci_ed *ed, int period)
 {
-	struct ohci_ed *int_ed;
-	struct ohci_device *root_hub=usb_to_ohci(ohci->bus->root_hub);
-	unsigned long flags;
-
-	/*
-	 * Pick a good frequency endpoint based on the requested period
-	 */
-	int_ed = &root_hub->ed[ms_to_ed_int(period)];
-#ifdef OHCI_DEBUG
-	if (MegaDebug)
-	printk(KERN_DEBUG "usb-ohci: Using INT ED queue %d for %dms period\n",
-	       ms_to_ed_int(period), period);
-#endif
-
-	spin_lock_irqsave(&ohci_edtd_lock, flags);
-	/*
-	 * Insert this ED at the front of the list.
-	 */
-	ed->next_ed = int_ed->next_ed;
-	int_ed->next_ed = cpu_to_le32(virt_to_bus(ed));
-
-	spin_unlock_irqrestore(&ohci_edtd_lock, flags);
-
+	ohci_add_ed_to_hw(ed, /* XXX */);
 	ohci_start_periodic(ohci);
-} /* ohci_add_periodic_ed() */
-
-/*
- * Locate the periodic ED for a given interrupt endpoint.
- */
-struct ohci_ed *ohci_get_periodic_ed(struct ohci_device *dev, int period,
-				     unsigned int pipe, int isoc)
-{
-	struct ohci_device *root_hub = usb_to_ohci(dev->ohci->bus->root_hub);
-	unsigned long flags;
-	struct ohci_ed *int_ed;
-	unsigned int status, req_status;
-
-	/* get the dummy ED before the EDs for this period */
-	int_ed = &root_hub->ed[ms_to_ed_int(period)];
-
-	/* decide on what the status field should look like */
-	req_status = ed_set_maxpacket(usb_maxpacket(ohci_to_usb(dev), pipe))
-		| ed_set_speed(usb_pipeslow(pipe))
-		| (usb_pipe_endpdev(pipe) & 0x7ff)
-		| ed_set_type_isoc(isoc);
-
-	spin_lock_irqsave(&ohci_edtd_lock, flags);
-	for (;;) {
-		int_ed = bus_to_virt(le32_to_cpup(&int_ed->next_ed));
-		/* stop if we get to the end or to another dummy ED. */
-		if (int_ed == 0)
-			break;
-		status = le32_to_cpup(&int_ed->status);
-		if ((status & OHCI_ED_FA) == 0) {
-			int_ed = 0;
-			break;
-		}
-		/* check whether all the appropriate fields match */
-		if ((status & 0x7ffa7ff) == req_status)
-			break;
-	}
-	spin_unlock_irqrestore(&ohci_edtd_lock, flags);
-	return int_ed;
-}
-
-/*
- *  Put an isochronous ED on the controller's list
- */
-inline void ohci_add_isoc_ed(struct ohci *ohci, struct ohci_ed *ed)
-{
-	ohci_add_periodic_ed(ohci, ed, 1);
-}
-
-
-/*
- * This will be used for the interrupt to wake us up on the next SOF
- */
-DECLARE_WAIT_QUEUE_HEAD(start_of_frame_wakeup);
-
-static void ohci_wait_sof(struct ohci_regs *regs)
-{
-	DECLARE_WAITQUEUE(wait, current);
-
-	add_wait_queue(&start_of_frame_wakeup, &wait);
-
-	/* clear the SOF interrupt status and enable it */
-	writel(OHCI_INTR_SF, &regs->intrstatus);
-	writel(OHCI_INTR_SF, &regs->intrenable);
-
-	schedule_timeout(HZ/10);
-
-	remove_wait_queue(&start_of_frame_wakeup, &wait);
-}
-
-/*
- * Guarantee that an ED is safe to be modified by the HCD (us).
- *
- * This function can NOT be called from an interrupt.
- */
-void ohci_wait_for_ed_safe(struct ohci_regs *regs, struct ohci_ed *ed, int ed_type)
-{
-	__u32 *hw_listcurrent;
-
-	/* tell the controller to skip this ED */
-	ed->status |= cpu_to_le32(OHCI_ED_SKIP);
-
-	switch (ed_type) {
-	case HCD_ED_CONTROL:
-		hw_listcurrent = &regs->ed_controlcurrent;
-		break;
-	case HCD_ED_BULK:
-		hw_listcurrent = &regs->ed_bulkcurrent;
-		break;
-	case HCD_ED_ISOC:
-	case HCD_ED_INT:
-		hw_listcurrent = &regs->ed_periodcurrent;
-		break;
-	default:
-		return;
-	}
-
-	/* 
-	 * If the HC is processing this ED we need to wait until the
-	 * at least the next frame.
-	 */
-	if (virt_to_bus(ed) == readl(hw_listcurrent)) {
-#ifdef OHCI_DEBUG
-		printk(KERN_INFO "Waiting a frame for OHC to finish with ED %p [%x %x %x %x]\n", ed, FIELDS_OF_ED(ed));
+} /* ohci_add_control_ed() */
 #endif
-		ohci_wait_sof(regs);
-
-	}
-
-	return; /* The ED is now safe */
-} /* ohci_wait_for_ed_safe() */
 
 
 /*
- *  Remove an ED from the HC's list.
- *  This function can ONLY be used for Control or Bulk EDs.
+ *  Remove an ED from the HC list whos bus headpointer is pointed to
+ *  by hw_listhead_p
  *  
  *  Note that the SKIP bit is left on in the removed ED.
  */
-void ohci_remove_norm_ed_from_hw(struct ohci *ohci, struct ohci_ed *ed, int ed_type)
+void ohci_remove_ed_from_hw(struct ohci_ed *ed, __u32* hw_listhead_p)
 {
 	unsigned long flags;
-	struct ohci_regs *regs = ohci->regs;
 	struct ohci_ed *cur;
 	__u32 bus_ed = virt_to_bus(ed);
 	__u32 bus_cur;
-	__u32 *hw_listhead_p;
 
 	if (ed == NULL || !bus_ed)
 		return;
-	ed->status |= cpu_to_le32(OHCI_ED_SKIP);
 
-	switch (ed_type) {
-	case HCD_ED_CONTROL:
-		hw_listhead_p = &regs->ed_controlhead;
-		break;
-	case HCD_ED_BULK:
-		hw_listhead_p = &regs->ed_bulkhead;
-		break;
-	default:
-		printk(KERN_ERR "Unknown HCD ED type %d.\n", ed_type);
-		return;
-	}
+	/* tell the controller this skip ED */
+	ed->status |= OHCI_ED_SKIP;
 
 	bus_cur = readl(hw_listhead_p);
 
@@ -404,33 +227,31 @@
 
 	/* if its the head ED, move the head */
 	if (bus_cur == bus_ed) {
-		writel(le32_to_cpup(&cur->next_ed), hw_listhead_p);
+		writel(cur->next_ed, hw_listhead_p);
 	} else if (cur->next_ed != 0) {
 		struct ohci_ed *prev;
 
 		/* walk the list and unlink the ED if found */
-		do {
+		for (;;) {
 			prev = cur;
-			cur = bus_to_virt(le32_to_cpup(&cur->next_ed));
+			cur = bus_to_virt(cur->next_ed);
 
-			if (cur == ed) {
+			if (virt_to_bus(cur) == bus_ed) {
 				/* unlink from the list */
 				prev->next_ed = cur->next_ed;
 				break;
 			}
-		} while (cur->next_ed != 0);
-	}
 
-	/*
-	 * Make sure this ED is not being accessed by the HC as we speak.
-	 */
-	ohci_wait_for_ed_safe(regs, ed, ed_type);
+			if (cur->next_ed == 0)
+				break;
+		}
+	}
 
 	/* clear any links from the ED for safety */
 	ed->next_ed = 0;
 
 	spin_unlock_irqrestore(&ohci_edtd_lock, flags);
-} /* ohci_remove_norm_ed_from_hw() */
+} /* ohci_remove_ed_from_hw() */
 
 /*
  *  Remove an ED from the controller's control list.  Note that the SKIP bit
@@ -438,7 +259,7 @@
  */
 inline void ohci_remove_control_ed(struct ohci *ohci, struct ohci_ed *ed)
 {
-	ohci_remove_norm_ed_from_hw(ohci, ed, HCD_ED_CONTROL);
+	ohci_remove_ed_from_hw(ed, &ohci->regs->ed_controlhead);
 }
 
 /*
@@ -447,128 +268,12 @@
  */
 inline void ohci_remove_bulk_ed(struct ohci *ohci, struct ohci_ed *ed)
 {
-	ohci_remove_norm_ed_from_hw(ohci, ed, HCD_ED_BULK);
+	ohci_remove_ed_from_hw(ed, &ohci->regs->ed_bulkhead);
 }
 
 
 /*
- *  Remove a periodic ED from the host controller
- */
-void ohci_remove_periodic_ed(struct ohci *ohci, struct ohci_ed *ed)
-{
-	struct ohci_device *root_hub = usb_to_ohci(ohci->bus->root_hub);
-	struct ohci_ed *cur_ed = NULL, *prev_ed;
-	unsigned long flags;
-
-	/* FIXME: this will need to up fixed when add_periodic_ed()
-	 * is updated to spread similar polling rate EDs out over
-	 * multiple periodic queues.  Currently this assumes that the
-	 * 32ms (slowest) polling queue links to all others... */
-
-	/* search the periodic EDs, skipping the first one which is
-	 * only a placeholder. */
-	prev_ed = &root_hub->ed[ED_INT_32];
-	if (prev_ed->next_ed)
-		cur_ed = bus_to_virt(le32_to_cpup(&prev_ed->next_ed));
-
-	while (cur_ed) {
-		if (ed == cur_ed) {		/* remove the ED */
-			/* set its SKIP bit and be sure its not in use */
-			ohci_wait_for_ed_safe(ohci->regs, ed, HCD_ED_INT);
-
-			/* unlink it */
-			spin_lock_irqsave(&ohci_edtd_lock, flags);
-			prev_ed->next_ed = ed->next_ed;
-			spin_unlock_irqrestore(&ohci_edtd_lock, flags);
-			ed->next_ed = 0;
-
-			break;
-		}
-
-		spin_lock_irqsave(&ohci_edtd_lock, flags);
-		if (cur_ed->next_ed) {
-			prev_ed = cur_ed;
-			cur_ed = bus_to_virt(le32_to_cpup(&cur_ed->next_ed));
-			spin_unlock_irqrestore(&ohci_edtd_lock, flags);
-		} else {
-			spin_unlock_irqrestore(&ohci_edtd_lock, flags);
-
-			/* if multiple polling queues need to be checked,
-			 * here is where you'd advance to the next one */
-
-			printk(KERN_ERR "usb-ohci: ed %p not found on periodic queue\n", ed);
-			break;
-		}
-	}
-} /* ohci_remove_periodic_ed() */
-
-
-/*
- * Remove all the EDs which have a given device address from a list.
- * Used when the device is unplugged.
- * Returns 1 if anything was changed.
- */
-static int ohci_remove_device_list(__u32 *headp, int devnum)
-{
-	struct ohci_ed *ed;
-	__u32 *prevp = headp;
-	int removed = 0;
-
-	while (*prevp != 0) {
-		ed = bus_to_virt(le32_to_cpup(prevp));
-		if ((le32_to_cpup(&ed->status) & OHCI_ED_FA) == devnum) {
-			/* set the controller to skip this one
-			   and remove it from the list */
-			ed->status |= cpu_to_le32(OHCI_ED_SKIP);
-			/* XXX should call td->completed for each td */
-			*prevp = ed->next_ed;
-			removed = 1;
-		} else {
-			prevp = &ed->next_ed;
-		}
-	}
-	wmb();
-
-	return removed;
-}
-
-/*
- * Remove all the EDs for a given device from all lists.
- */
-void ohci_remove_device(struct ohci *ohci, int devnum)
-{
-	unsigned long flags;
-	__u32 head;
-	struct ohci_regs *regs = ohci->regs;
-	struct ohci_device *root_hub=usb_to_ohci(ohci->bus->root_hub);
-
-	spin_lock_irqsave(&ohci_edtd_lock, flags);
-
-	/* Control list */
-	head = cpu_to_le32(readl(&regs->ed_controlhead));
-	if (ohci_remove_device_list(&head, devnum))
-		writel(le32_to_cpup(&head), &regs->ed_controlhead);
-
-	/* Bulk list */
-	head = cpu_to_le32(readl(&regs->ed_bulkhead));
-	if (ohci_remove_device_list(&head, devnum))
-		writel(le32_to_cpup(&head), &regs->ed_bulkhead);
-
-	/* Interrupt/iso list */
-	head = cpu_to_le32(virt_to_bus(&root_hub->ed[ED_INT_32]));
-	ohci_remove_device_list(&head, devnum);
-
-	/*
-	 * Wait until the start of the next frame to ensure
-	 * that the HC has seen any changes.
-	 */
-	ohci_wait_sof(ohci->regs);
-
-	spin_unlock_irqrestore(&ohci_edtd_lock, flags);
-}
-
-/*
- *  Remove a TD from the given EDs TD list.  The TD is freed as well.
+ *  Remove a TD from the given EDs TD list.
  */
 static void ohci_remove_td_from_ed(struct ohci_td *td, struct ohci_ed *ed)
 {
@@ -578,13 +283,13 @@
 	if ((td == NULL) || (ed == NULL))
 		return;
 
+	spin_lock_irqsave(&ohci_edtd_lock, flags);
+
 	if (ed_head_td(ed) == 0)
 		return;
 
-	spin_lock_irqsave(&ohci_edtd_lock, flags);
-
 	/* set the "skip me bit" in this ED */
-	ed->status |= cpu_to_le32(OHCI_ED_SKIP);
+	ed->status |= OHCI_ED_SKIP;
 
 	/* XXX Assuming this list will never be circular */
 
@@ -598,7 +303,7 @@
 		/* FIXME: collapse this into a nice simple loop :) */
 		if (head_td->next_td != 0) {
 			prev_td = head_td;
-			cur_td = bus_to_virt(le32_to_cpup(&head_td->next_td));
+			cur_td = bus_to_virt(head_td->next_td);
 			for (;;) {
 				if (td == cur_td) {
 					/* remove it */
@@ -608,7 +313,7 @@
 				if (cur_td->next_td == 0)
 					break;
 				prev_td = cur_td;
-				cur_td = bus_to_virt(le32_to_cpup(&cur_td->next_td));
+				cur_td = bus_to_virt(cur_td->next_td);
 			}
 		}
 	}
@@ -616,11 +321,10 @@
 	td->next_td = 0;  /* remove the TDs links */
 	td->ed = NULL;
 
-	/* return this TD to the pool of free TDs */
-	ohci_free_td(td);
+	/* TODO return this TD to the pool of free TDs */
 
 	/* unset the "skip me bit" in this ED */
-	ed->status &= cpu_to_le32(~OHCI_ED_SKIP);
+	ed->status &= ~OHCI_ED_SKIP;
 
 	spin_unlock_irqrestore(&ohci_edtd_lock, flags);
 } /* ohci_remove_td_from_ed() */
@@ -628,109 +332,47 @@
 
 /*
  * Get a pointer (virtual) to an available TD from the given device's
- * pool.  Return NULL if none are left.
+ * pool.
+ *
+ * Return NULL if none are left.
  */
 static struct ohci_td *ohci_get_free_td(struct ohci_device *dev)
 {
 	int idx;
 
-	/* FIXME: this is horribly inefficient */
 	for (idx=0; idx < NUM_TDS; idx++) {
 		if (!td_allocated(dev->td[idx])) {
 			struct ohci_td *new_td = &dev->td[idx];
 			/* zero out the TD */
 			memset(new_td, 0, sizeof(*new_td));
 			/* mark the new TDs as unaccessed */
-			new_td->info = cpu_to_le32(OHCI_TD_CC_NEW);
+			new_td->info = OHCI_TD_CC_NEW;
 			/* mark it as allocated */
 			allocate_td(new_td);
-			/* record the device that its on */
-			new_td->usb_dev = ohci_to_usb(dev);
 			return new_td;
 		}
 	}
 
-	printk(KERN_ERR "usb-ohci: unable to allocate a TD\n");
+	printk("usb-ohci error: unable to allocate a TD\n");
 	return NULL;
 } /* ohci_get_free_td() */
 
 
 /*
- * Get a pointer (virtual) to an available TD from the given device's
- * pool.  Return NULL if none are left.
- *
- * NOTE: This function does not allocate and attach the dummy_td.
- * That is done in ohci_fill_ed().  FIXME: it should probably be moved
- * into here.
- */
-static struct ohci_ed *ohci_get_free_ed(struct ohci_device *dev)
-{
-	int idx;
-
-	/* FIXME: this is horribly inefficient */
-	for (idx=0; idx < NUM_EDS; idx++) {
-		if (!ed_allocated(dev->ed[idx])) {
-			struct ohci_ed *new_ed = &dev->ed[idx];
-			/* zero out the ED */
-			memset(new_ed, 0, sizeof(*new_ed));
-			/* all new EDs start with the SKIP bit set */
-			new_ed->status |= cpu_to_le32(OHCI_ED_SKIP);
-			/* mark it as allocated */
-			allocate_ed(new_ed);
-			new_ed->ohci_dev = dev;
-			return new_ed;
-		}
-	}
-
-	printk(KERN_ERR "usb-ohci: unable to allocate an ED\n");
-	return NULL;
-} /* ohci_get_free_ed() */
-
-
-/*
- * Free an OHCI ED and all of the TDs on its list.  It is assumed that
- * this ED is not active.  You should call ohci_wait_for_ed_safe()
- * beforehand if you can't guarantee that.
- */
-void ohci_free_ed(struct ohci_ed *ed)
-{
-	if (!ed)
-		return;
-
-	if (ed_head_td(ed) != 0) {
-		struct ohci_td *td, *tail_td, *next_td;
-
-		td = bus_to_virt(ed_head_td(ed));
-		tail_td = bus_to_virt(ed_tail_td(ed));
-		for (;;) {
-			next_td = bus_to_virt(le32_to_cpup(&td->next_td));
-			ohci_free_td(td);
-			if (td == tail_td)
-				break;
-			td = next_td;
-		}
-	}
-
-	ed->status &= cpu_to_le32(~(__u32)ED_ALLOCATED);
-} /* ohci_free_ed() */
-
-
-/*
  *  Initialize a TD
  *
  * 	dir = OHCI_TD_D_IN, OHCI_TD_D_OUT, or OHCI_TD_D_SETUP
  * 	toggle = TOGGLE_AUTO, TOGGLE_DATA0, TOGGLE_DATA1
  */
-struct ohci_td *ohci_fill_new_td(struct ohci_td *td, int dir, int toggle, __u32 flags, void *data, __u32 len, void *dev_id, usb_device_irq completed)
+inline struct ohci_td *ohci_fill_new_td(struct ohci_td *td, int dir, int toggle, __u32 flags, void *data, __u32 len, void *dev_id, usb_device_irq completed)
 {
 	/* hardware fields */
-	td->info = cpu_to_le32(OHCI_TD_CC_NEW |
-			       (dir & OHCI_TD_D) |
-			       (toggle & OHCI_TD_DT) |
-			       flags);
-	td->cur_buf = (data == NULL) ? 0 : cpu_to_le32(virt_to_bus(data));
-	td->buf_end = (len == 0) ? 0 :
-		cpu_to_le32(virt_to_bus((char *)data + len - 1));
+	td->info = OHCI_TD_CC_NEW |
+		(dir & OHCI_TD_D) |
+		(toggle & OHCI_TD_DT) |
+		flags;
+	td->cur_buf = (data == NULL) ? 0 : virt_to_bus(data);
+	td->buf_end = (len == 0) ? 0 : td->cur_buf + len - 1;
 
 	/* driver fields */
 	td->data = data;
@@ -741,177 +383,6 @@
 } /* ohci_fill_new_td() */
 
 
-/*
- *  Initialize a new ED on device dev, including allocating and putting the
- *  dummy tail_td on its queue if it doesn't already have one.  Any
- *  TDs on this ED other than the dummy will be lost (so there better
- *  not be any!).  This assumes that the ED is Allocated and will
- *  force the Allocated bit on.
- */
-struct ohci_ed *ohci_fill_ed(struct ohci_device *dev, struct ohci_ed *ed,
-			     int maxpacketsize, int lowspeed, int endp_id,
-			     int isoc_tds)
-{
-	struct ohci_td *dummy_td;
-
-	if (ed_head_td(ed) != ed_tail_td(ed))
-		printk(KERN_ERR "Reusing a non-empty ED %p!\n", ed);
-
-	if (!ed->tail_td) {
-		dummy_td = ohci_get_free_td(dev);
-		if (dummy_td == NULL) {
-			printk(KERN_ERR "Error allocating dummy TD for ED %p\n", ed);
-			return NULL;	/* no dummy available! */
-		}
-		make_dumb_td(dummy_td);	/* flag it as a dummy */
-		ed->tail_td = cpu_to_le32(virt_to_bus(dummy_td));
-	} else {
-		dummy_td = bus_to_virt(ed_tail_td(ed));
-		if (!td_dummy(*dummy_td))
-			printk(KERN_ERR "ED %p's dummy %p is screwy\n", ed, dummy_td);
-	}
-
-	/* set the head TD to the dummy and clear the Carry & Halted bits */
-	ed->_head_td = ed->tail_td;
-
-	ed->status = cpu_to_le32(
-		ed_set_maxpacket(maxpacketsize) |
-		ed_set_speed(lowspeed) |
-		(endp_id & 0x7ff) |
-		((isoc_tds == 0) ? OHCI_ED_F_NORM : OHCI_ED_F_ISOC));
-	allocate_ed(ed);
-	ed->next_ed = 0;
-
-	return ed;
-} /* ohci_fill_ed() */
-
-
-/*
- *  Create a chain of Normal TDs to be used for a large data transfer
- *  (bulk or control).
- *
- *  Returns the head TD in the chain.
- */
-struct ohci_td *ohci_build_td_chain(struct ohci_device *dev,
-		void *data, unsigned int len, int dir, __u32 toggle,
-		int round, int auto_free, void* dev_id,
-		usb_device_irq handler, __u32 next_td)
-{
-	struct ohci_td *head, *cur_td;
-	unsigned max_len;
-
-	if (!data || (len == 0))
-		return NULL;
-
-	/* Get the first TD */
-	head = ohci_get_free_td(dev);
-	if (head == NULL) {
-		printk(KERN_ERR "usb-ohci: out of TDs\n");
-		return NULL;
-	}
-
-	cur_td = head;
-
-	/* AFICT, that the OHCI controller takes care of the innards of
-	 * bulk & control data transfers by sending zero length
-	 * packets as necessary if the transfer falls on an even packet
-	 * size boundary, we don't need a special TD for that. */
-
-	/* check the 4096 byte alignment of the start of the data */
-	max_len = 0x2000 - ((unsigned long)data & 0xfff);
-
-	/* check if the remaining data occupies more than two pages */
-	while (len > max_len) {
-		struct ohci_td *new_td;
-
-		/* TODO lookup effect of rounding bit on
-		 * individual TDs vs. whole TD chain transfers;
-		 * disable cur_td's rounding bit here if needed. */
-
-		ohci_fill_new_td(cur_td,
-				 td_set_dir_out(dir),
-				 toggle & OHCI_TD_DT,
-				 (round ? OHCI_TD_ROUND : 0),
-				 data, max_len - 1,
-				 dev_id, handler);
-		if (!auto_free)
-			noauto_free_td(head);
-
-		/* adjust the data pointer & remaining length */
-		data += max_len;
-		len  -= max_len;
-
-		/* allocate another td */
-		new_td = ohci_get_free_td(dev);
-		if (new_td == NULL) {
-			printk(KERN_ERR "usb-ohci: out of TDs\n");
-			/* FIXME: free any allocated TDs */
-			return NULL;
-		}
-
-		/* Link the new TD to the chain & advance */
-		cur_td->next_td = cpu_to_le32(virt_to_bus(new_td));
-		cur_td = new_td;
-
-		/* address is page-aligned now */
-		max_len = 0x2000;
-		toggle = TOGGLE_AUTO;  /* toggle Data0/1 via the ED */
-	}
-
-	ohci_fill_new_td(cur_td,
-		td_set_dir_out(dir),
-		toggle & OHCI_TD_DT,
-		(round ? OHCI_TD_ROUND : 0),
-		data, len,
-		dev_id, handler);
-	if (!auto_free)
-		noauto_free_td(head);
-
-	/* link the given next_td to the end of this chain */
-	cur_td->next_td = cpu_to_le32(next_td);
-	if (next_td == 0)
-		set_td_endofchain(cur_td);
-
-	return head;
-} /* ohci_build_td_chain() */
-
-
-/*
- * Compute the number of bytes that have been transferred on a given
- * TD.  Do not call this on TDs that are active on the host
- * controller.
- */
-static __u16 ohci_td_bytes_done(struct ohci_td *td)
-{
-	__u16 result;
-	__u32 bus_data_start, bus_data_end;
-
-	bus_data_start = virt_to_bus(td->data);
-	if (!td->data || !bus_data_start)
-		return 0;
-
-	/* if cur_buf is 0, all data has been transferred */
-	if (!td->cur_buf) {
-		/* XXX this could be wrong for transfers > 1 page */
-		return le32_to_cpup(&td->buf_end) - bus_data_start + 1;
-	}
-
-	bus_data_end = le32_to_cpup(&td->cur_buf);
-
-	/* is it on the same page? */
-	if ((bus_data_start & ~0xfff) == (bus_data_end & ~0xfff)) {
-		result = bus_data_end - bus_data_start;
-	} else {
-		/* compute the amount transferred on the first page */
-		result = 0x1000 - (bus_data_start & 0xfff);
-		/* add the amount done in the second page */
-		result += (bus_data_end & 0xfff);
-	}
-
-	return result;
-} /* ohci_td_bytes_done() */
-
-
 /**********************************
  * OHCI interrupt list operations *
  **********************************/
@@ -925,631 +396,276 @@
  *
  * Period is desired polling interval in ms.  The closest, shorter
  * match will be used.  Powers of two from 1-32 are supported by OHCI.
- *
- * Returns: a "handle pointer" that release_irq can use to stop this
- * interrupt.  (It's really a pointer to the TD).  NULL = error.
  */
-static void* ohci_request_irq(struct usb_device *usb, unsigned int pipe,
+static int ohci_request_irq(struct usb_device *usb, unsigned int pipe,
 	usb_device_irq handler, int period, void *dev_id)
 {
 	struct ohci_device *dev = usb_to_ohci(usb);
 	struct ohci_td *td;
 	struct ohci_ed *interrupt_ed;	/* endpoint descriptor for this irq */
-	int maxps = usb_maxpacket(usb, pipe);
-	unsigned long flags;
-
-	/* Get an ED and TD */
-	interrupt_ed = ohci_get_periodic_ed(dev, period, pipe, 0);
-	if (interrupt_ed == 0) {
-		interrupt_ed = ohci_get_free_ed(dev);
-		if (!interrupt_ed) {
-			printk(KERN_ERR "Out of EDs on device %p in ohci_request_irq\n", dev);
-			return NULL;
-		}
-
-		/*
-		 * Set the max packet size, device speed, endpoint number, usb
-		 * device number (function address), and type of TD.
-		 */
-		ohci_fill_ed(dev, interrupt_ed, maxps, usb_pipeslow(pipe),
-			     usb_pipe_endpdev(pipe), 0 /* normal TDs */);
-		interrupt_ed->status &= cpu_to_le32(~OHCI_ED_SKIP);
-
-		/* Assimilate the new ED into the collective */
-		ohci_add_periodic_ed(dev->ohci, interrupt_ed, period);
-	}
-#ifdef OHCI_DEBUG
-	if (MegaDebug) {
-	printk(KERN_DEBUG "ohci_request irq: using ED %p [%x %x %x %x]\n",
-	       interrupt_ed, FIELDS_OF_ED(interrupt_ed));
-	printk(KERN_DEBUG "  for dev %d pipe %x period %d\n", usb->devnum,
-	       pipe, period);
-	}
-#endif
-
-	td = ohci_get_free_td(dev);
-	if (!td) {
-		printk(KERN_ERR "Out of TDs in ohci_request_irq\n");
-		ohci_free_ed(interrupt_ed);
-		return NULL;
-	}
-
-	/* Fill in the TD */
-	if (maxps > sizeof(dev->data))
-		maxps = sizeof(dev->data);
-	ohci_fill_new_td(td, td_set_dir_out(usb_pipeout(pipe)),
-			TOGGLE_AUTO,
-			OHCI_TD_ROUND,
-			dev->data, maxps,
-			dev_id, handler);
-	set_td_endofchain(td);
 
 	/*
-	 *  Put the TD onto our ED and make sure its ready to run
+	 * Pick a good frequency endpoint based on the requested period
 	 */
-	td->next_td = 0;
-	spin_lock_irqsave(&ohci_edtd_lock, flags);
-	td = ohci_add_tds_to_ed(td, interrupt_ed);
-	spin_unlock_irqrestore(&ohci_edtd_lock, flags);
-
-	return (void*)td;
-} /* ohci_request_irq() */
-
-/*
- * Release an interrupt handler previously allocated using
- * ohci_request_irq.  This function does no validity checking, so make
- * sure you're not releasing an already released handle as it may be
- * in use by something else..
- *
- * This function can NOT be called from an interrupt.
- */
-int ohci_release_irq(void* handle)
-{
-	struct ohci_device *dev;
-	struct ohci_td *int_td;
-	struct ohci_ed *int_ed;
-
-#ifdef OHCI_DEBUG
-	if (MegaDebug)
-		printk(KERN_DEBUG "usb-ohci: Releasing irq handle %p\n", handle);
-#endif
-
-	int_td = (struct ohci_td*)handle;
-	if (int_td == NULL)
-		return USB_ST_INTERNALERROR;
-
-	dev = usb_to_ohci(int_td->usb_dev);
-	int_ed = int_td->ed;
-
-	ohci_remove_periodic_ed(dev->ohci, int_ed);
-
-	/* Tell the driver that the IRQ has been killed. */
-	/* Passing NULL in the "buffer" void* along with the
-	 * USB_ST_REMOVED status is the signal. */
-	if (int_td->completed != NULL)
-		int_td->completed(USB_ST_REMOVED, NULL, 0, int_td->dev_id);
-
-	/* Free the ED (& TD) */
-	ohci_free_ed(int_ed);
-
-	return USB_ST_NOERROR;
-} /* ohci_release_irq() */
-
-
-/************************************
- * OHCI control transfer operations *
- ************************************/
-
-static DECLARE_WAIT_QUEUE_HEAD(control_wakeup);
-
-/*
- *  This is the handler that gets called when a control transaction
- *  completes.
- *
- *  This function is called from the interrupt handler.
- */
-static int ohci_control_completed(int stats, void *buffer, int len, void *dev_id)
-{
-	/* pass the TDs completion status back to control_msg */
-	if (dev_id) {
-		int *completion_status = (int *)dev_id;
-		*completion_status = stats;
-	}
-
-	wake_up(&control_wakeup);
-	return 0;
-} /* ohci_control_completed() */
-
-
-/*
- * Send or receive a control message on a "pipe"
- *
- * The cmd parameter is a pointer to the 8 byte setup command to be
- * sent.
- *
- * A control message contains:
- *   - The command itself
- *   - An optional data phase (if len > 0)
- *   - Status complete phase
- *
- * This function can NOT be called from an interrupt.
- */
-static int ohci_control_msg(struct usb_device *usb, unsigned int pipe,
-			    devrequest *cmd, void *data, int len)
-{
-	struct ohci_device *dev = usb_to_ohci(usb);
-	struct ohci_ed *control_ed = ohci_get_free_ed(dev);
-	struct ohci_td *setup_td, *data_td, *status_td;
-	DECLARE_WAITQUEUE(wait, current);
-	int completion_status = -1;
-	devrequest our_cmd;
-
-	/* byte-swap fields of cmd if necessary */
-	our_cmd = *cmd;
-	cpu_to_le16s(&our_cmd.value);
-	cpu_to_le16s(&our_cmd.index);
-	cpu_to_le16s(&our_cmd.length);
-
-#ifdef OHCI_DEBUG
-	if (MegaDebug)
-	printk(KERN_DEBUG "ohci_control_msg %p (ohci_dev: %p) pipe %x, cmd %p, data %p, len %d\n", usb, dev, pipe, cmd, data, len);
-#endif
-	if (!control_ed) {
-		printk(KERN_ERR "usb-ohci: couldn't get ED for dev %p\n", dev);
-		return -1;
-	}
-
-	/* get a TD to send this control message with */
-	setup_td = ohci_get_free_td(dev);
-	if (!setup_td) {
-		printk(KERN_ERR "usb-ohci: couldn't get TD for dev %p [cntl setup]\n", dev);
-		ohci_free_ed(control_ed);
-		return -1;
-	}
+	interrupt_ed = &dev->ohci->root_hub->ed[ms_to_ed_int(period)];
 
 	/*
 	 * Set the max packet size, device speed, endpoint number, usb
 	 * device number (function address), and type of TD.
 	 *
+	 * FIXME: Isochronous transfers need a pool of special 32 byte
+	 * TDs (32 byte aligned) in order to be supported.
 	 */
-	ohci_fill_ed(dev, control_ed, usb_maxpacket(usb,pipe), usb_pipeslow(pipe),
-		usb_pipe_endpdev(pipe), 0 /* normal TDs */);
+	interrupt_ed->status = \
+		ed_set_maxpacket(usb_maxpacket(pipe)) |
+		ed_set_speed(usb_pipeslow(pipe)) |
+		usb_pipe_endpdev(pipe) |
+		OHCI_ED_F_NORM;
 
-	/*
-	 * Build the control TD
-	 */
+	td = ohci_get_free_td(dev);
+	/* FIXME: check for NULL */
 
+	/* Fill in the TD */
+	ohci_fill_new_td(td, td_set_dir_out(usb_pipeout(pipe)),
+			TOGGLE_AUTO,
+			OHCI_TD_ROUND,
+			dev->data, DATA_BUF_LEN,
+			dev_id, handler);
 	/*
-	 * Set the not accessed condition code, allow odd sized data,
-	 * and set the data transfer type to SETUP.  Setup DATA always
-	 * uses a DATA0 packet.
+	 * TODO: be aware that OHCI won't advance out of the 4kb
+	 * page cur_buf started in.  It'll wrap around to the start
+	 * of the page...  annoying or useful? you decide.
 	 *
-	 * The setup packet contains a devrequest (usb.h) which
-	 * will always be 8 bytes long.
+	 * We should make sure dev->data doesn't cross a page...
 	 */
-	ohci_fill_new_td(setup_td, OHCI_TD_D_SETUP, TOGGLE_DATA0,
-			OHCI_TD_IOC_OFF,
-			&our_cmd, 8,	/* cmd is always 8 bytes long */
-			&completion_status, NULL);
-
-	/* Allocate a TD for the control xfer status */
-	status_td = ohci_get_free_td(dev);
-	if (!status_td) {
-		printk(KERN_ERR "usb-ohci: couldn't get TD for dev %p [cntl status]\n", dev);
-		ohci_free_td(setup_td);
-		ohci_free_ed(control_ed);
-		return -1;
-	}
-
-	/* The control status packet always uses a DATA1
-	 * Give "dev_id" the address of completion_status so that the
-	 * TDs status can be passed back to us from the IRQ. */
-	ohci_fill_new_td(status_td,
-			td_set_dir_in(usb_pipeout(pipe) | (len == 0)),
-			TOGGLE_DATA1,
-			0 /* flags */,
-			NULL /* data */, 0 /* data len */,
-			&completion_status, ohci_control_completed);
-	set_td_endofchain(status_td);
-	status_td->next_td = 0; /* end of TDs */
 
-	/* If there is data to transfer, create the chain of data TDs
-	 * followed by the status TD. */
-	if (len > 0) {
-		data_td = ohci_build_td_chain( dev, data, len,
-				usb_pipeout(pipe), TOGGLE_DATA1,
-				1 /* round */, 1 /* autofree */,
-				&completion_status, NULL /* no handler here */,
-				virt_to_bus(status_td) );
-		if (!data_td) {
-			printk(KERN_ERR "usb-ohci: couldn't allocate control data TDs for dev %p\n", dev);
-			ohci_free_td(setup_td);
-			ohci_free_td(status_td);
-			ohci_free_ed(control_ed);
-			return -1;
-		}
+	/* FIXME: this just guarantees that its the end of the list */
+	td->next_td = 0;
 
-		/* link the to the data & status TDs */
-		setup_td->next_td = cpu_to_le32(virt_to_bus(data_td));
-	} else {
-		/* no data TDs, link to the status TD */
-		setup_td->next_td = cpu_to_le32(virt_to_bus(status_td));
-	}
+	/* Linus did this. see asm/system.h; scary concept... I don't
+	 * know if its needed here or not but it won't hurt. */
+	wmb();
 
 	/*
-	 * Add the control TDs to the control ED (setup_td is the first)
+	 *  Put the TD onto our ED
 	 */
-	setup_td = ohci_add_tds_to_ed(setup_td, control_ed);
-  	control_ed->status &= cpu_to_le32(~OHCI_ED_SKIP);
-  	/* ohci_unhalt_ed(control_ed); */
-
-#ifdef OHCI_DEBUG
-	if (MegaDebug > 1) {
-	/* complete transaction debugging output (before) */
-	printk(KERN_DEBUG " Control ED %lx:\n", virt_to_bus(control_ed));
-	show_ohci_ed(control_ed);
-	printk(KERN_DEBUG " Control TD chain:\n");
-	show_ohci_td_chain(setup_td);
-	printk(KERN_DEBUG " OHCI Controller Status:\n");
-	show_ohci_status(dev->ohci);
+	{
+		unsigned long flags;
+		spin_lock_irqsave(&ohci_edtd_lock, flags);
+		ohci_add_td_to_ed(td, interrupt_ed);
+		spin_unlock_irqrestore(&ohci_edtd_lock, flags);
 	}
-#endif
 
+#if 0
+	/* Assimilate the new ED into the collective */
 	/*
-	 * Start the control transaction..
-	 */
-	current->state = TASK_UNINTERRUPTIBLE;
-	add_wait_queue(&control_wakeup, &wait);
-
-	/* Give the ED to the HC */
-	ohci_add_control_ed(dev->ohci, control_ed);
-
-	schedule_timeout(HZ);
-
-	remove_wait_queue(&control_wakeup, &wait);
-
-#ifdef OHCI_DEBUG
-	if (completion_status != 0) {
-		const char *what = (completion_status < 0)? "timed out":
-			cc_names[completion_status & 0xf];
-		printk(KERN_DEBUG "ohci_control_msg: %s on pipe %x\n",
-		       what, pipe);
-	}
-	if (MegaDebug) {
-		printk(KERN_DEBUG "ctrl msg %x %x %x %x %x on pipe %x",
-		       cmd->requesttype, cmd->request, cmd->value, cmd->index,
-		       cmd->length, pipe);
-		if (usb_pipeout(pipe))
-			printk(" data (%d)", len);
-		else
-			printk(" returned (%d)", len);
-		if (len > 0) {
-			int i;
-			unsigned char *q = data;
-			for (i = 0; i < len; ++i) {
-				if (i % 16 == 0)
-					printk("\n" KERN_DEBUG);
-				printk(" %x", q[i]);
-			}
-		}
-		printk("\n");
-	}
-	if (MegaDebug && completion_status < 0) {
-		printk(KERN_DEBUG "control_ed at %p:\n", control_ed);
-		show_ohci_ed(control_ed);
-		if (ed_head_td(control_ed) != ed_tail_td(control_ed))
-			show_ohci_td_chain(bus_to_virt(ed_head_td(control_ed)));
-		printk(KERN_DEBUG "setup TD at %p:\n", setup_td);
-		show_ohci_td(setup_td);
-	}
-
-	if (MegaDebug > 1) {
-	/* complete transaction debugging output (after) */
-	printk(KERN_DEBUG " *after* Control ED %lx:\n", virt_to_bus(control_ed));
-	show_ohci_ed(control_ed);
-	printk(KERN_DEBUG " *after* Control TD chain:\n");
-	show_ohci_td_chain(setup_td);
-	printk(KERN_DEBUG " *after* OHCI Controller Status:\n");
-	show_ohci_status(dev->ohci);
-	}
+	 *  When dynamic ED allocation is done, this call will be
+	 *  useful.  For now, the correct ED already on the
+	 *  controller's proper periodic ED lists was chosen above.
+	 */
+	ohci_add_periodic_ed(dev->ohci, interrupt_ed, period);
+#else
+	/* enable periodic (interrupt) transfers on the HC */
+	ohci_start_periodic(dev->ohci);
 #endif
 
-	/* no TD cleanup, the TDs were auto-freed as they finished */
-
-	/* remove the control ED from the HC */
-	ohci_remove_control_ed(dev->ohci, control_ed);
-	ohci_free_ed(control_ed);	 /* return it to the pool */
-
-	if (completion_status < 0)
-		completion_status = USB_ST_TIMEOUT;
-	return completion_status;
-} /* ohci_control_msg() */
-
-
-/**********************************************************************
- *  Bulk transfer processing
- **********************************************************************/
+	return 0;
+} /* ohci_request_irq() */
 
-/*
- * Internal state for an ohci_bulk_request
- */
-struct ohci_bulk_request_state {
-	struct usb_device *usb_dev;
-	unsigned int	pipe;		/* usb "pipe" */
-	void		*data;		/* ptr to data */
-	int		length;		/* length to transfer */
-	int		_bytes_done;	/* bytes transferred so far */
-	unsigned long	*bytes_transferred_p;	/* where to increment */
-	void		*dev_id;	/* pass to the completion handler */
-	usb_device_irq	completion;	/* completion handler */
-};
 
 /*
- * this handles the individual TDs of a (possibly) larger bulk
- * request.  It keeps track of the total bytes transferred, calls the
- * final completion handler, etc.
+ * Control thread operations:
  */
-static int ohci_bulk_td_handler(int stats, void *buffer, int len, void *dev_id)
-{
-	struct ohci_bulk_request_state *req;
-
-	req = (struct ohci_bulk_request_state *) dev_id;
-
-#ifdef OHCI_DEBUG
-	if (MegaDebug)
-	printk(KERN_DEBUG "ohci_bulk_td_handler stats %x, buffer %p, len %d, req %p\n", stats, buffer, len, req);
-#endif
-
-	/* only count TDs that were completed successfully */
-	if (stats == USB_ST_NOERROR)
-		req->_bytes_done += len;
-
-#ifdef OHCI_DEBUG
-	if (MegaDebug && req->_bytes_done) {
-		int i;
-		printk(KERN_DEBUG " %d bytes, bulk data:", req->_bytes_done);
-		for (i = 0; i < 16 && i < req->_bytes_done; ++i)
-			printk(" %.2x", ((unsigned char *)buffer)[i]);
-		if (i < req->_bytes_done)
-			printk(" ...");
-		printk("\n");
-	}
-#endif
-
-	/* call the real completion handler when done or on an error */
-	if ((stats != USB_ST_NOERROR) ||
-	    (req->_bytes_done >= req->length && req->completion != NULL)) {
-		*req->bytes_transferred_p += req->_bytes_done;
-#ifdef OHCI_DEBUG
-		if (MegaDebug)
-		printk(KERN_DEBUG "usb-ohci: bulk request %p ending\n", req);
-#endif
-		req->completion(stats, buffer, req->_bytes_done, req->dev_id);
-	}
+static struct wait_queue *control_wakeup;
 
-	return 0;	/* do not re-queue the TD */
-} /* ohci_bulk_td_handler() */
+/*
+ *  This is the handler that gets called when a control transaction
+ *  completes.
+ *
+ *  This function is called from the interrupt handler.
+ */
+static int ohci_control_completed(int stats, void *buffer, void *dev_id)
+{
+	wake_up(&control_wakeup);
+	return 0;
+} /* ohci_control_completed() */
 
 
 /*
- * Request to send or receive bulk data.  The completion() function
- * will be called when the transfer has completed or been aborted due
- * to an error.
- *
- * bytes_transferred_p is a pointer to an integer that will be
- * set to the number of bytes that have been successfully
- * transferred.  The interrupt handler will update it after each
- * internal TD completes successfully.
+ * Send or receive a control message on a "pipe"
  *
- * This function can NOT be called from an interrupt (?)
- * (TODO: verify & fix this if needed).
+ * The cmd parameter is a pointer to the 8 byte setup command to be
+ * sent.  FIXME:  This is a devrequest in usb.h.  The function
+ * should be updated to accept a devrequest* instead of void*..
  *
- * Returns: a pointer to the ED being used for this request.  At the
- * moment, removing & freeing it is the responsibilty of the caller.
+ * A control message contains:
+ *   - The command itself
+ *   - An optional data phase (if len > 0)
+ *   - Status complete phase
  */
-static struct ohci_ed* ohci_request_bulk(struct ohci_bulk_request_state *bulk_request)
+static int ohci_control_msg(struct usb_device *usb, unsigned int pipe, void *cmd, void *data, int len)
 {
-	/* local names for the readonly fields */
-	struct usb_device *usb_dev = bulk_request->usb_dev;
-	unsigned int pipe = bulk_request->pipe;
-	void *data = bulk_request->data;
-	int len = bulk_request->length;
-
-	struct ohci_device *dev = usb_to_ohci(usb_dev);
-	struct ohci_ed *bulk_ed;
-	struct ohci_td *head_td;
-	unsigned long flags;
+	struct ohci_device *dev = usb_to_ohci(usb);
+	/*
+	 * ideally dev->ed should be linked into the root hub's
+	 * control_ed list and used instead of just using it directly.
+	 * This could present a problem as is with more than one
+	 * device.  (but who wants to use a keyboard AND a mouse
+	 * anyways? ;)
+	 */
+	struct ohci_ed *control_ed = &dev->ohci->root_hub->ed[ED_CONTROL];
+	struct ohci_td *setup_td, *data_td, *status_td;
+	struct wait_queue wait = { current, NULL };
 
-#ifdef OHCI_DEBUG 
-	if (MegaDebug)
-	printk(KERN_DEBUG "ohci_request_bulk(%p) ohci_dev %p, completion %p, pipe %x, data %p, len %d\n", bulk_request, dev, bulk_request->completion, pipe, data, len);
+#if 0
+	printk(KERN_DEBUG "entering ohci_control_msg %p (ohci_dev: %p) pipe 0x%x, cmd %p, data %p, len %d\n", usb, dev, pipe, cmd, data, len);
 #endif
 
-	bulk_ed = ohci_get_free_ed(dev);
-	if (!bulk_ed) {
-		printk(KERN_ERR "usb-ohci: couldn't get ED for dev %p\n", dev);
-		return NULL;
-	}
-
-	/* allocate & fill in the TDs for this request */
-	head_td = ohci_build_td_chain(dev, data, len, usb_pipeout(pipe),
-			TOGGLE_AUTO,
-			0 /* round not required */, 1 /* autofree */,
-			bulk_request,  /* dev_id: the bulk_request  */
-			ohci_bulk_td_handler,
-			0 /* no additional TDs */);
-	if (!head_td) {
-		printk(KERN_ERR "usb-ohci: couldn't get TDs for dev %p\n", dev);
-		ohci_free_ed(bulk_ed);
-		return NULL;
-	}
+	/*
+	 * Set the max packet size, device speed, endpoint number, usb
+	 * device number (function address), and type of TD.
+	 *
+	 */
+	control_ed->status = \
+		ed_set_maxpacket(usb_maxpacket(pipe)) |
+		ed_set_speed(usb_pipeslow(pipe)) |
+		usb_pipe_endpdev(pipe) |
+		OHCI_ED_F_NORM;
 
-	/* Set the max packet size, device speed, endpoint number, usb
-	 * device number (function address), and type of TD. */
-	ohci_fill_ed(dev, bulk_ed,
-		usb_maxpacket(usb_dev, pipe),
-		usb_pipeslow(pipe),
-		usb_pipe_endpdev(pipe), 0 /* bulk uses normal TDs */);
-
-	/* initialize the toggle carry */
-	if (usb_gettoggle(usb_dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)))
-		ohci_ed_set_carry(bulk_ed);
+	/*
+	 * Build the control TD
+	 */
 
-	/* initialize the internal counter */
-	bulk_request->_bytes_done = 0;
+	/* get a TD to send this control message with */
+	setup_td = ohci_get_free_td(dev);
+	/* TODO check for NULL */
 
 	/*
-	 * Add the TDs to the ED
+	 * Set the not accessed condition code, allow odd sized data,
+	 * and set the data transfer type to SETUP.  Setup DATA always
+	 * uses a DATA0 packet.
+	 *
+	 * The setup packet contains a devrequest (usb.h) which
+	 * will always be 8 bytes long.  FIXME: the cmd parameter
+	 * should be a pointer to one of these instead of a void* !!!
 	 */
-	spin_lock_irqsave(&ohci_edtd_lock, flags);
-	head_td = ohci_add_tds_to_ed(head_td, bulk_ed);
-	bulk_ed->status &= cpu_to_le32(~OHCI_ED_SKIP);
-	/* ohci_unhalt_ed(bulk_ed); */
-	spin_unlock_irqrestore(&ohci_edtd_lock, flags);
-
-#ifdef OHCI_DEBUG
-	if (MegaDebug > 1) {
-	/* complete request debugging output (before) */
-	printk(KERN_DEBUG " Bulk ED %lx:\n", virt_to_bus(bulk_ed));
-	show_ohci_ed(bulk_ed);
-	printk(KERN_DEBUG " Bulk TDs %lx:\n", virt_to_bus(head_td));
-	show_ohci_td_chain(head_td);
-	}
-#endif
+	ohci_fill_new_td(setup_td, OHCI_TD_D_SETUP, TOGGLE_DATA0,
+			OHCI_TD_IOC_OFF,
+			cmd, 8,		/* cmd is always 8 bytes long */
+			NULL, NULL);
 
-	/* Give the ED to the HC */
-	ohci_add_bulk_ed(dev->ohci, bulk_ed);
+	/* allocate the next TD */
+	data_td = ohci_get_free_td(dev);  /* TODO check for NULL */
 
-	return bulk_ed;
-} /* ohci_request_bulk() */
+	/* link to the next TD */
+	setup_td->next_td = virt_to_bus(data_td);
 
+	if (len > 0) {
 
-static DECLARE_WAIT_QUEUE_HEAD(bulk_wakeup);
+		/* build the Control DATA TD, it starts with a DATA1. */
+		ohci_fill_new_td(data_td, td_set_dir_out(usb_pipeout(pipe)),
+				TOGGLE_DATA1,
+				OHCI_TD_ROUND | OHCI_TD_IOC_OFF,
+				data, len,
+				NULL, NULL);
 
+		/*
+		 * XXX we should check that the data buffer doesn't
+		 * cross a 4096 byte boundary.  If so, it needs to be
+		 * copied into a single 4096 byte aligned area for the
+		 * OHCI's TD logic to see it all, or multiple TDs need
+		 * to be made for each page.
+		 *
+		 * It's not likely a control transfer will run into
+		 * this problem.. (famous last words)
+		 */
 
-static int ohci_bulk_msg_completed(int stats, void *buffer, int len, void *dev_id)
-{
-#ifdef OHCI_DEBUG
-	if (MegaDebug)
-	printk("ohci_bulk_msg_completed %x, %p, %d, %p\n", stats, buffer, len, dev_id);
-#endif
-	if (dev_id != NULL) {
-		int *completion_status = (int *)dev_id;
-		*completion_status = stats;
+		status_td = ohci_get_free_td(dev);  /* TODO check for NULL */
+		data_td->next_td = virt_to_bus(status_td);
+	} else {
+		status_td = data_td; /* no data_td, use it for status */
 	}
 
-	wake_up(&bulk_wakeup);
-	return 0;	/* don't requeue the TD */
-} /* ohci_bulk_msg_completed() */
-
-
-static int ohci_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
-			 void *data, int len, unsigned long *bytes_transferred_p)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	int completion_status = USB_ST_INTERNALERROR;
-	struct ohci_bulk_request_state req;
-	struct ohci_ed *req_ed;
-
-#ifdef OHCI_DEBUG
-	if (MegaDebug)
-		printk(KERN_DEBUG "ohci_bulk_msg %p pipe %x, data %p, len %d, bytes_transferred %p\n",
-		       usb_dev, pipe, data, len, bytes_transferred_p);
-#endif
-
-	/* initialize bytes transferred to nothing */
-	*bytes_transferred_p = 0;
-
-	/* Hopefully this is similar to the "URP" (USB Request Packet) code
-	 * that michael gee is working on... */
-	req.usb_dev = usb_dev;
-	req.pipe = pipe;
-	req.data = data;
-	req.length = len;
-	req.bytes_transferred_p = bytes_transferred_p;
-	req.dev_id = &completion_status;
-	req.completion = ohci_bulk_msg_completed;
-	if (bytes_transferred_p)
-		*bytes_transferred_p = 0;
-
-	if (usb_endpoint_halted(usb_dev, usb_pipeendpoint(pipe))
-	    && usb_clear_halt(usb_dev, usb_pipeendpoint(pipe) | (pipe & 0x80)))
-		return USB_ST_STALL;
+	/* The control status packet always uses a DATA1 */
+	ohci_fill_new_td(status_td,
+			td_set_dir_in(usb_pipeout(pipe) | (len == 0)),
+			TOGGLE_DATA1,
+			0,
+			NULL, 0,
+			NULL, ohci_control_completed);
+	status_td->next_td = 0; /* end of TDs */
 
 	/*
-	 * Start the transaction..
+	 * Start the control transaction..
 	 */
 	current->state = TASK_UNINTERRUPTIBLE;
-	add_wait_queue(&bulk_wakeup, &wait);
-
-	req_ed = ohci_request_bulk(&req);
+	add_wait_queue(&control_wakeup, &wait);
 
-	/* FIXME this should to wait for a caller specified time... */
-	schedule_timeout(HZ*5);
+	/*
+	 * Add the chain of 2-3 control TDs to the control ED's TD list
+	 */
+	{
+		unsigned long flags;
+		spin_lock_irqsave(&ohci_edtd_lock, flags);
+		ohci_add_td_to_ed(setup_td, control_ed);
+		spin_unlock_irqrestore(&ohci_edtd_lock, flags);
+	}
 
-	/* completion_status will only stay in this state of the
-	 * request never finished */
-	if (completion_status == USB_ST_INTERNALERROR) {
-		struct ohci_device *dev = usb_to_ohci(usb_dev);
-		struct ohci_regs *regs = dev->ohci->regs;
-
-#ifdef OHCI_DEBUG
-		printk(KERN_DEBUG "ohci_bulk_msg timing out\n");
-#endif
-		/* XXX This code should go into a function used to stop
-		 * a previously requested bulk transfer. -greg */
-
-		/* stop the transfer & collect the number of bytes */
-		ohci_wait_for_ed_safe(regs, req_ed, HCD_ED_BULK);
-
-		/* Get the number of bytes transferred out of the head TD
-		 * on the ED if it didn't finish while we were waiting. */
-		if ( ed_head_td(req_ed) &&
-		     (ed_head_td(req_ed) != ed_tail_td(req_ed)) ) {
-			struct ohci_td *partial_td;
-			partial_td = bus_to_virt(ed_head_td(req_ed));
-
-#ifdef OHCI_DEBUG
-			if (MegaDebug) {
-			show_ohci_td(partial_td);
-			}
+#if 0
+	/* complete transaction debugging output (before) */
+	printk(KERN_DEBUG " Control ED %lx:\n", virt_to_bus(control_ed));
+	show_ohci_ed(control_ed);
+	printk(KERN_DEBUG " Setup TD %lx:\n", virt_to_bus(setup_td));
+	show_ohci_td(setup_td);
+	if (data_td != status_td) {
+		printk(KERN_DEBUG " Data TD %lx:\n", virt_to_bus(data_td));
+		show_ohci_td(data_td);
+	}
+	printk(KERN_DEBUG " Status TD %lx:\n", virt_to_bus(status_td));
+	show_ohci_td(status_td);
 #endif
-			/* Record the bytes as transferred */
-			*bytes_transferred_p += ohci_td_bytes_done(partial_td);
-			
-			/* If there was an unreported error, return it.
-			 * Otherwise return a timeout */
-			completion_status = OHCI_TD_CC_GET(partial_td->info);
-			if (completion_status == USB_ST_NOERROR) {
-				completion_status = USB_ST_TIMEOUT;
-			}
-		}
 
-	}
+	/* Give the ED to the HC */
+	ohci_add_control_ed(dev->ohci, control_ed);
 
-	remove_wait_queue(&bulk_wakeup, &wait);
+	/* FIXME:
+	 * this should really check to see that the transaction completed.
+	 */
+	schedule_timeout(HZ/10);
 
-	/* remove the ED from the HC */
-	ohci_remove_bulk_ed(usb_to_ohci(usb_dev)->ohci, req_ed);
+	remove_wait_queue(&control_wakeup, &wait);
 
-	/* save the toggle value back into the usb_dev */
-	usb_settoggle(usb_dev, usb_pipeendpoint(pipe), usb_pipeout(pipe),
-		      ohci_ed_carry(req_ed));
+#if 0
+	/* complete transaction debugging output (after) */
+	printk(KERN_DEBUG " (after) Control ED:\n");
+	show_ohci_ed(control_ed);
+	printk(KERN_DEBUG " (after) Setup TD:\n");
+	show_ohci_td(setup_td);
+	if (data_td != status_td) {
+		printk(KERN_DEBUG " (after) Data TD:\n");
+		show_ohci_td(data_td);
+	}
+	printk(KERN_DEBUG " (after) Status TD:\n");
+	show_ohci_td(status_td);
+#endif
+
+	/* clean up incase it failed */
+	/* XXX only do this if their ed pointer still points to control_ed
+	 * incase they've been reclaimed and used by something else
+	 * already. -greg */
+	ohci_remove_td_from_ed(setup_td, control_ed);
+	ohci_remove_td_from_ed(data_td, control_ed);
+	ohci_remove_td_from_ed(status_td, control_ed);
 
-	ohci_free_ed(req_ed);	 /* return it to the pool */
+	/* remove the control ED */
+	ohci_remove_control_ed(dev->ohci, control_ed);
 
-#ifdef OHCI_DEBUG
-	if (completion_status != 0 || MegaDebug)
-		printk(KERN_DEBUG "ohci_bulk_msg done, status %x (bytes_transferred = %ld).\n",
-		       completion_status, *bytes_transferred_p);
+#if 0
+	printk(KERN_DEBUG "leaving ohci_control_msg\n");
 #endif
 
-	return completion_status;
-} /* ohci_bulk_msg() */
-
-
-/* .......... */
-
+	return ohci_td_result(dev, status_td);
+} /* ohci_control_msg() */
 
 
 /*
@@ -1559,7 +675,6 @@
 {
 	struct usb_device *usb_dev;
 	struct ohci_device *dev;
-	int idx;
 
 	/*
 	 * Allocate the generic USB device
@@ -1581,12 +696,6 @@
 
 	memset(dev, 0, sizeof(*dev));
 
-	/* Initialize all EDs in a new device with the skip flag so that
-	 * they are ignored by the controller until set otherwise. */
-	for (idx = 0; idx < NUM_EDS; ++idx) {
-		dev->ed[idx].status = cpu_to_le32(OHCI_ED_SKIP);
-	}
-
 	/*
 	 * Link them together
 	 */
@@ -1614,42 +723,12 @@
  */
 static int ohci_usb_deallocate(struct usb_device *usb_dev)
 {
-	struct ohci_device *dev = usb_to_ohci(usb_dev);
-
-	ohci_remove_device(dev->ohci, usb_dev->devnum);
-
-	/* kfree(usb_to_ohci(usb_dev)); */
-	/* kfree(usb_dev); */
+	kfree(usb_to_ohci(usb_dev));
+	kfree(usb_dev);
 	return 0;
 }
 
 
-static void *ohci_alloc_isochronous (struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int maxsze, usb_device_irq completed, void *dev_id)
-{
-	return NULL;
-}
-
-static void ohci_delete_isochronous (struct usb_device *dev, void *_isodesc)
-{
-	return;
-}
-
-static int ohci_sched_isochronous (struct usb_device *usb_dev, void *_isodesc, void *_pisodesc)
-{
-	return USB_ST_NOTSUPPORTED;
-}
-
-static int ohci_unsched_isochronous (struct usb_device *usb_dev, void *_isodesc)
-{
-	return USB_ST_NOTSUPPORTED;
-}
-
-static int ohci_compress_isochronous (struct usb_device *usb_dev, void *_isodesc)
-{
-	return USB_ST_NOTSUPPORTED;
-}
-
-
 /*
  * functions for the generic USB driver
  */
@@ -1657,14 +736,7 @@
 	ohci_usb_allocate,
 	ohci_usb_deallocate,
 	ohci_control_msg,
-	ohci_bulk_msg,
 	ohci_request_irq,
-	ohci_release_irq,
-	ohci_alloc_isochronous,
-	ohci_delete_isochronous,
-	ohci_sched_isochronous,
-	ohci_unsched_isochronous,
-	ohci_compress_isochronous
 };
 
 
@@ -1677,25 +749,24 @@
  */
 static int reset_hc(struct ohci *ohci)
 {
-	int timeout = 10000;  /* prevent an infinite loop */
+	int timeout = 1000;  /* prevent an infinite loop */
+
+#if 0
+	printk(KERN_DEBUG "usb-ohci: resetting HC %p\n", ohci);
+#endif
 
 	writel(~0x0, &ohci->regs->intrdisable);    /* Disable HC interrupts */
-	/* this seems to be needed for the lucent controller on powerbooks... */
-	writel(0, &ohci->regs->control);	   /* Move to reset state */
 	writel(1, &ohci->regs->cmdstatus);	   /* HC Reset */
-	udelay(100);
+	writel_mask(0x3f, &ohci->regs->control);   /* move to UsbReset state */
 
 	while ((readl(&ohci->regs->cmdstatus) & OHCI_CMDSTAT_HCR) != 0) {
 		if (!--timeout) {
-			printk(KERN_ERR "usb-ohci: USB HC reset timed out!\n");
+			printk("usb-ohci: USB HC reset timed out!\n");
 			return -1;
 		}
 		udelay(1);
 	}
 
-	writel_mask(0x3f, &ohci->regs->control);   /* move to UsbReset state */
-	wait_ms(10);		/* give the bus time to be reset */
-
 	printk(KERN_DEBUG "usb-ohci: HC %p reset.\n", ohci);
 
 	return 0;
@@ -1708,34 +779,29 @@
 static int start_hc(struct ohci *ohci)
 {
 	int ret = 0;
-	int fminterval, pot;
-	__u32 what_to_enable;
+	int fminterval;
 
-	struct ohci_device *root_hub=usb_to_ohci(ohci->bus->root_hub);
+	fminterval = readl(&ohci->regs->fminterval) & 0x3fff;
+#if 0
+	printk(KERN_DEBUG "entering start_hc %p\n", ohci);
+#endif
 
 	if (reset_hc(ohci) < 0)
 		return -1;
 
 	/* restore registers cleared by the reset */
-	writel(virt_to_bus(root_hub->hcca), &ohci->regs->hcca);
+	writel(virt_to_bus(ohci->root_hub->hcca), &ohci->regs->hcca);
 
 	/*
-	 * fminterval has to be 11999 (it can be adjusted +/- 1
-	 * to sync with other things if necessary).
+	 * XXX Should fminterval also be set here?
+	 * The spec suggests 0x2edf [11,999]. (FIXME: make this a constant)
 	 */
-	fminterval = 11999;
-
+	fminterval |= (0x2edf << 16);
+	writel(fminterval, &ohci->regs->fminterval);
 	/* Start periodic transfers at 90% of fminterval (fmremaining
 	 * counts down; this will put them in the first 10% of the
 	 * frame). */
-	writel((fminterval * 9) / 10, &ohci->regs->periodicstart);
-
-	/* Set largest data packet counter and frame interval. */
-	fminterval |= ((fminterval - 210) * 6 / 7) << 16;
-	writel(fminterval, &ohci->regs->fminterval);
-
-	/* Set low-speed threshold (value from MacOS) */
-	writel(1576, &ohci->regs->lsthresh);
+	writel((0x2edf*9)/10, &ohci->regs->periodicstart);
 
 	/*
 	 * FNO (frame number overflow) could be enabled...  they
@@ -1743,40 +809,20 @@
 	 * useful for debugging and as a bus heartbeat. -greg
 	 */
 	/* Choose the interrupts we care about */
-	what_to_enable = OHCI_INTR_MIE |
-#ifdef OHCI_RHSC_INT
-			OHCI_INTR_RHSC |
-#endif
-			/* | OHCI_INTR_FNO */
-			OHCI_INTR_WDH;
-	writel( what_to_enable, &ohci->regs->intrenable);
+	writel( OHCI_INTR_MIE | /* OHCI_INTR_RHSC | */
+		OHCI_INTR_WDH | OHCI_INTR_FNO,
+		&ohci->regs->intrenable);
 
 	/* Enter the USB Operational state & start the frames a flowing.. */
-	writel(OHCI_USB_OPER, &ohci->regs->control);
+	writel_set(OHCI_USB_OPER, &ohci->regs->control);
 	
 	/* Enable control lists */
 	writel_set(OHCI_USB_IE | OHCI_USB_CLE | OHCI_USB_BLE, &ohci->regs->control);
 
-	/* Force global power enable -gal@cs.uni-magdeburg.de */
-	/* 
-	 * This turns on global power switching for all the ports
-	 * and tells the HC that all of the ports should be powered on
-	 * all of the time.
-	 *
-	 * TODO: This could be battery draining for laptops.. We
-	 *       should implement power switching.
-	 */
-	writel_set( OHCI_ROOT_A_NPS, &ohci->regs->roothub.a );
-	writel_mask( ~(OHCI_ROOT_A_PSM), &ohci->regs->roothub.a );
-
 	/* Turn on power to the root hub ports (thanks Roman!) */
 	writel( OHCI_ROOT_LPSC, &ohci->regs->roothub.status );
 
-	/* wait for power-on to power-good time */
-	pot = readl(&ohci->regs->roothub.a) >> 24;	/* power-on time (* 2ms) */
-	wait_ms(pot * 2);
-
-	printk(KERN_INFO "usb-ohci: host controller operational\n");
+	printk("usb-ohci: host controller operational\n");
 
 	return ret;
 } /* start_hc() */
@@ -1785,14 +831,14 @@
 /*
  * Reset a root hub port
  */
-static int ohci_reset_port(struct ohci *ohci, unsigned int port)
+static void ohci_reset_port(struct ohci *ohci, unsigned int port)
 {
 	int status;
 
 	/* Don't allow overflows. */
 	if (port >= MAX_ROOT_PORTS) {
-		printk(KERN_ERR "usb-ohci: bad port #%d in ohci_reset_port\n", port);
-		return -1;
+		printk("usb-ohci: bad port #%d in ohci_reset_port\n", port);
+		port = MAX_ROOT_PORTS-1;
 	}
 
 	writel(PORT_PRS, &ohci->regs->roothub.portstatus[port]);  /* Reset */
@@ -1800,21 +846,20 @@
 	/*
 	 * Wait for the reset to complete.
 	 */
-	wait_ms(20);
+	wait_ms(10);
 
 	/* check port status to see that the reset completed */
 	status = readl(&ohci->regs->roothub.portstatus[port]);
 	if (status & PORT_PRS) {
 		/* reset failed, try harder? */
-		printk(KERN_ERR "usb-ohci: port %d reset failed\n", port);
-		show_ohci_status(ohci);
-		return -1;
+		printk("usb-ohci: port %d reset failed, retrying\n", port);
+		writel(PORT_PRS, &ohci->regs->roothub.portstatus[port]);
+		wait_ms(50);
 	}
 
 	/* TODO we might need to re-enable the port here or is that
 	 * done elsewhere? */
 
-	return 0;
 } /* ohci_reset_port */
 
 
@@ -1825,47 +870,31 @@
 {
 	struct usb_device *usb_dev;
 	struct ohci_device *dev;
-	struct ohci_device *root_hub=usb_to_ohci(ohci->bus->root_hub);
 	/* memory I/O address of the port status register */
-	__u32 *portaddr = &ohci->regs->roothub.portstatus[port];
+	void *portaddr = &ohci->regs->roothub.portstatus[port];
 	int portstatus;	
 
+	printk(KERN_DEBUG "ohci_connect_change(%p, %d)\n", ohci, port);
+
 	/*
 	 * Because of the status change we have to forget
 	 * everything we think we know about the device
 	 * on this root hub port.  It may have changed.
 	 */
-	usb_disconnect(root_hub->usb->children + port);
+	usb_disconnect(ohci->root_hub->usb->children + port);
 
 	portstatus = readl(portaddr);
 
-#ifdef OHCI_DEBUG
-	printk(KERN_DEBUG "ohci_connect_change on port %d, status=%x\n",
-	       port, portstatus);
-#endif
-
 	/* disable the port if nothing is connected */
 	if (!(portstatus & PORT_CCS)) {
 		writel(PORT_CCS, portaddr);
-		/* We need to reset the CSC bit -after- disabling the
-		 * port because it causes the CSC bit to come on
-		 * again... */
-		wait_ms(20);
-		writel(PORT_CSC, portaddr);
-#ifdef OHCI_DEBUG
-		printk(KERN_DEBUG "ohci port %d disabled, nothing connected.\n", port);
-#endif
 		return;
 	}
 
-	if (ohci_reset_port(ohci, port) < 0)
-		return;
-	wait_ms(10);	/* give the device a while to get reset */
-
 	/*
 	 * Allocate a device for the new thingy that's been attached
 	 */
-	usb_dev = ohci_usb_allocate(root_hub->usb);
+	usb_dev = ohci_usb_allocate(ohci->root_hub->usb);
 	dev = usb_dev->hcpriv;
 
 	dev->ohci = ohci;
@@ -1873,7 +902,10 @@
 	usb_connect(dev->usb);
 
 	/* link it into the bus's device tree */
-	root_hub->usb->children[port] = usb_dev;
+	ohci->root_hub->usb->children[port] = usb_dev;
+
+	wait_ms(200); /* wait for powerup; XXX is this needed? */
+	ohci_reset_port(ohci, port);
 
 	/* Get information on speed by using LSD */
 	usb_dev->slow = readl(portaddr) & PORT_LSDA ? 1 : 0;
@@ -1896,24 +928,23 @@
 	struct ohci_regs *regs = ohci->regs;
 	int num = 0;
 	int maxport = readl(&ohci->regs->roothub) & 0xff;
-	__u32 rh_change_flags = PORT_CSC | PORT_PESC;	/* root hub status changes */
 
-#ifdef OHCI_DEBUG
-	if (MegaDebug)
-		printk(KERN_DEBUG "entering ohci_check_configuration %p\n", ohci);
+#if 1
+	printk(KERN_DEBUG "entering ohci_check_configuration %p\n", ohci);
 #endif
 
 	do {
-		__u32 *portstatus_p = &regs->roothub.portstatus[num];
-		if (readl(portstatus_p) & rh_change_flags) {
-			/* acknowledge the root hub status changes */
-			writel_set(rh_change_flags, portstatus_p);
-			/* disable the port if nothing is on it */
+		if (readl(&regs->roothub.portstatus[num]) & PORT_CSC) {
+			/* reset the connect status change bit */
+			writel(PORT_CSC, &regs->roothub.portstatus[num]);
 			/* check the port for a nifty device */
 			ohci_connect_change(ohci, num);
 		}
 	} while (++num < maxport);
 
+#if 0
+	printk(KERN_DEBUG "leaving ohci_check_configuration %p\n", ohci);
+#endif
 } /* ohci_check_configuration() */
 
 
@@ -1926,21 +957,19 @@
  */
 static void ohci_root_hub_events(struct ohci *ohci)
 {
-	int num = 0;
-	struct ohci_device *root_hub=usb_to_ohci(ohci->bus->root_hub);
-	int maxport = root_hub->usb->maxchild;
+	if (waitqueue_active(&ohci_configure)) {
+		int num = 0;
+		int maxport = ohci->root_hub->usb->maxchild;
 
-	if (!waitqueue_active(&ohci_configure))
-		return;
-	do {
-		__u32 *portstatus_p = &ohci->regs->roothub.portstatus[num];
-		if (readl(portstatus_p) & PORT_CSC) {
-			if (waitqueue_active(&ohci_configure))
-				wake_up(&ohci_configure);
-			return;
-		}
-	} while (++num < maxport);
-	
+		do {
+			if (readl(&ohci->regs->roothub.portstatus[num]) &
+					PORT_CSC) {
+				if (waitqueue_active(&ohci_configure))
+					wake_up(&ohci_configure);
+				return;
+			}
+		} while (++num < maxport);
+	}
 } /* ohci_root_hub_events() */
 
 
@@ -1956,19 +985,19 @@
 static struct ohci_td * ohci_reverse_donelist(struct ohci * ohci)
 {
 	__u32 td_list_hc;
-	struct ohci_device *root_hub=usb_to_ohci(ohci->bus->root_hub);
-	struct ohci_hcca *hcca = root_hub->hcca;
+	struct ohci_hcca *hcca = ohci->root_hub->hcca;
 	struct ohci_td *td_list = NULL;
 	struct ohci_td *td_rev = NULL;
-
-	td_list_hc = le32_to_cpup(&hcca->donehead) & 0xfffffff0;
+  	
+	td_list_hc = hcca->donehead & 0xfffffff0;
 	hcca->donehead = 0;
 
  	while(td_list_hc) {
 		td_list = (struct ohci_td *) bus_to_virt(td_list_hc);
 		td_list->next_dl_td = td_rev;
+			
 		td_rev = td_list;
-		td_list_hc = le32_to_cpup(&td_list->next_td) & 0xfffffff0;
+		td_list_hc = td_list->next_td & 0xfffffff0;
 	}
 
 	return td_list;
@@ -1985,8 +1014,6 @@
 {
 	struct ohci_td *td;		/* used for walking the list */
 
-	/* um... isn't this dangerous to do in an interrupt handler? -greg */
-	/* nope. -paulus */
 	spin_lock(&ohci_edtd_lock);
 
 	/* create the FIFO ordered donelist */
@@ -1994,85 +1021,27 @@
 
 	while (td != NULL) {
 		struct ohci_td *next_td = td->next_dl_td;
-		int cc = OHCI_TD_CC_GET(le32_to_cpup(&td->info));
-		struct ohci_ed *ed = td->ed;
-
-		if (td_dummy(*td))
-			printk(KERN_ERR "yikes! reaping a dummy TD\n");
-
-#ifdef OHCI_DEBUG
-		if (cc != 0 && MegaDebug) {
-			printk(KERN_DEBUG "cc=%s on td %p (ed %p)\n", cc_names[cc], td, ed);
-			show_ohci_td(td);
-			show_ohci_ed(ed);
-			if (ed_head_td(ed) != ed_tail_td(ed))
-				show_ohci_td_chain(bus_to_virt(ed_head_td(ed)));
-		}
-#endif
-
-		if (cc == USB_ST_STALL) {
-			/* mark endpoint as halted */
-			usb_endpoint_halt(ed->ohci_dev->usb, ed_get_en(ed));
-		}
-
-		if (cc != 0 && ohci_ed_halted(ed) && !td_endofchain(*td)) {
-			/*
-			 * There was an error on this TD and the ED
-			 * is halted, and this was not the last TD
-			 * of the transaction, so there will be TDs
-			 * to clean off the ED.
-			 */
-			struct ohci_td *tail_td = bus_to_virt(ed_tail_td(ed));
-			struct ohci_td *ntd;
-
-			ohci_free_td(td);
-			td = ntd = bus_to_virt(ed_head_td(ed));
-			while (td != tail_td) {
-				ntd = bus_to_virt(le32_to_cpup(&td->next_td));
-				if (td_endofchain(*td))
-					break;
-
-				if (MegaDebug)
-					printk(KERN_DEBUG "skipping TD %p\n", td);
-				ohci_free_td(td);
-
-				td = ntd;
-			}
-			/* Set the ED head past the ones we cleaned
-			   off, and clear the halted flag */
-			if (MegaDebug)
-				printk(KERN_DEBUG "restarting ED %p at TD %p\n", ed, ntd);
-			set_ed_head_td(ed, virt_to_bus(ntd));
-			ohci_unhalt_ed(ed);
-			/* If we didn't find an endofchain TD, give up */
-			if (td == tail_td) {
-				td = next_td;
-				continue;
-			}
-		}
 
+		/* FIXME: munge td->info into a future standard status format */
 		/* Check if TD should be re-queued */
 		if ((td->completed != NULL) &&
-		    (td->completed(cc, td->data, ohci_td_bytes_done(td), td->dev_id))) {
+		    (td->completed(OHCI_TD_CC_GET(td->info), td->data, td->dev_id)))
+		{
 			/* Mark the TD as active again:
 			 * Set the not accessed condition code
-			 * Reset the Error count
+			 * FIXME: should this reset OHCI_TD_ERRCNT?
 			 */
-			td->info |= cpu_to_le32(OHCI_TD_CC_NEW);
-			clear_td_errorcount(td);
-			/* reset the toggle field to TOGGLE_AUTO (0) */
-			td->info &= cpu_to_le32(~OHCI_TD_DT);
+			td->info |= OHCI_TD_CC_NEW;
 
 			/* point it back to the start of the data buffer */
-			td->cur_buf = cpu_to_le32(virt_to_bus(td->data));
+			td->cur_buf = virt_to_bus(td->data);
 
+			/* XXX disabled for debugging reasons right now.. */
 			/* insert it back on its ED */
-			td->next_td = 0;
-			ohci_add_tds_to_ed(td, ed);
+			ohci_add_td_to_ed(td, td->ed);
 		} else {
 			/* return it to the pool of free TDs */
-			if (can_auto_free(*td))
-				ohci_free_td(td);
+			ohci_free_td(td);
 		}
 
 		td = next_td;
@@ -2082,6 +1051,9 @@
 } /* ohci_reap_donelist() */
 
 
+#if 0
+static int in_int = 0;
+#endif
 /*
  * Get annoyed at the controller for bothering us.
  * This pretty much follows the OHCI v1.0a spec, section 5.3.
@@ -2090,18 +1062,26 @@
 {
 	struct ohci *ohci = __ohci;
 	struct ohci_regs *regs = ohci->regs;
-	struct ohci_device *root_hub=usb_to_ohci(ohci->bus->root_hub);
-	struct ohci_hcca *hcca = root_hub->hcca;
+	struct ohci_hcca *hcca = ohci->root_hub->hcca;
 	__u32 status, context;
 
+#if 0
+	/* for debugging to keep IRQs from running away. */
+	if (in_int >= 2)
+		return;
+	++in_int;
+	return;
+#endif
+
 	/* Save the status of the interrupts that are enabled */
 	status = readl(&regs->intrstatus);
 	status &= readl(&regs->intrenable);
 
+
 	/* make context = the interrupt status bits that we care about */
 	if (hcca->donehead != 0) {
 		context = OHCI_INTR_WDH;   /* hcca donehead needs processing */
-		if (hcca->donehead & cpu_to_le32(1)) {
+		if (hcca->donehead & 1) {
 			context |= status;  /* other status change to check */
 		}
 	} else {
@@ -2112,32 +1092,21 @@
 		}
 	}
 
-	/* Disable HC interrupts */ /* why? - paulus */
+	/* Disable HC interrupts */
 	writel(OHCI_INTR_MIE, &regs->intrdisable);
 
-#if 0
-	/* Only do this for SERIOUS debugging, be sure kern.debug logs
-	 * are not going to the console as this can cause your
-	 * machine to lock up if so... -greg */
-	show_ohci_status(ohci);
-#endif
-
 	/* Process the done list */
 	if (context & OHCI_INTR_WDH) {
 		/* See which TD's completed.. */
 		ohci_reap_donelist(ohci);
 
 		/* reset the done queue and tell the controller */
-		hcca->donehead = 0;	/* XXX already done in ohci_reverse_donelist */
+		hcca->donehead = 0;
 		writel(OHCI_INTR_WDH, &regs->intrstatus);
 
 		context &= ~OHCI_INTR_WDH;  /* mark this as checked */
 	}
 
-#ifdef OHCI_RHSC_INT
-	/* NOTE: this is very funky on some USB controllers (ie: it
-	 * doesn't work right).  Using the ohci_timer instead to poll
-	 * the root hub is a much better choice. */
 	/* Process any root hub status changes */
 	if (context & OHCI_INTR_RHSC) {
 		/* Wake the thread to process root hub events */
@@ -2150,17 +1119,10 @@
 		 * The control thread will re-enable it after it has
 		 * checked the root hub status.
 		 */
-	}
-#endif
-
-	/* Start of Frame interrupts, used during safe ED removal */
-	if (context & (OHCI_INTR_SF)) {
-		writel(OHCI_INTR_SF, &regs->intrstatus);
-		if (waitqueue_active(&start_of_frame_wakeup))
-			wake_up(&start_of_frame_wakeup);
-		/* Do NOT mark the frame start interrupt as checked
-		 * as we don't want to receive any more of them until
-		 * asked. */
+	} else {
+		/* check the root hub status anyways. Some controllers
+		 * might not generate the interrupt properly. (?) */
+		ohci_root_hub_events(ohci);
 	}
 
 	/* Check those "other" pesky bits */
@@ -2189,8 +1151,8 @@
 		context &= ~OHCI_INTR_OC;  /* mark this as checked */
 	}
 
-	/* Mask out any remaining unprocessed or unmasked interrupts
-	 * so that we don't get any more of them. */
+	/* Mask out any remaining unprocessed interrupts so we don't
+	 * get any more of them. */
 	if (context & ~OHCI_INTR_MIE) {
 		writel(context, &regs->intrdisable);
 	}
@@ -2217,6 +1179,10 @@
 	struct ohci_device *dev;
 	struct usb_device *usb;
 
+#if 0
+	printk(KERN_DEBUG "entering alloc_ohci %p\n", mem_base);
+#endif
+
 	ohci = kmalloc(sizeof(*ohci), GFP_KERNEL);
 	if (!ohci)
 		return NULL;
@@ -2249,8 +1215,8 @@
 	if (!usb)
 		return NULL;
 
-	dev = usb_to_ohci(usb);
-	ohci->bus->root_hub= ohci_to_usb(dev);
+	dev = ohci->root_hub = usb_to_ohci(usb);
+
 	usb->bus = bus;
 
 	/* Initialize the root hub */
@@ -2262,8 +1228,7 @@
 	 * page as that's guaranteed to have a nice boundary.
 	 */
 	dev->hcca = (struct ohci_hcca *) __get_free_page(GFP_KERNEL);
-	memset(dev->hcca, 0, sizeof(struct ohci_hcca));
- 
+
 	/* Tell the controller where the HCCA is */
 	writel(virt_to_bus(dev->hcca), &ohci->regs->hcca);
 
@@ -2274,62 +1239,66 @@
 	/* Get the number of ports on the root hub */
 	usb->maxchild = readl(&ohci->regs->roothub.a) & 0xff;
 	if (usb->maxchild > MAX_ROOT_PORTS) {
-		printk(KERN_INFO "usb-ohci: Limited to %d ports\n", MAX_ROOT_PORTS);
+		printk("usb-ohci: Limited to %d ports\n", MAX_ROOT_PORTS);
 		usb->maxchild = MAX_ROOT_PORTS;
 	}
 	if (usb->maxchild < 1) {
-		printk(KERN_ERR "usb-ohci: Less than one root hub port? Impossible!\n");
+		printk("usb-ohci: Less than one root hub port? Impossible!\n");
 		usb->maxchild = 1;
 	}
-	printk(KERN_DEBUG "usb-ohci: %d root hub ports found\n", usb->maxchild);
+	printk("usb-ohci: %d root hub ports found\n", usb->maxchild);
 
 	/*
 	 * Initialize the ED polling "tree" (for simplicity's sake in
 	 * this driver many nodes in the tree will be identical)
 	 */
-	dev->ed[ED_INT_32].next_ed = cpu_to_le32(virt_to_bus(&dev->ed[ED_INT_16]));
-	dev->ed[ED_INT_16].next_ed = cpu_to_le32(virt_to_bus(&dev->ed[ED_INT_8]));
-	dev->ed[ED_INT_8].next_ed = cpu_to_le32(virt_to_bus(&dev->ed[ED_INT_4]));
-	dev->ed[ED_INT_4].next_ed = cpu_to_le32(virt_to_bus(&dev->ed[ED_INT_2]));
-	dev->ed[ED_INT_2].next_ed = cpu_to_le32(virt_to_bus(&dev->ed[ED_INT_1]));
+	dev->ed[ED_INT_32].next_ed = virt_to_bus(&dev->ed[ED_INT_16]);
+	dev->ed[ED_INT_16].next_ed = virt_to_bus(&dev->ed[ED_INT_8]);
+	dev->ed[ED_INT_8].next_ed = virt_to_bus(&dev->ed[ED_INT_4]);
+	dev->ed[ED_INT_4].next_ed = virt_to_bus(&dev->ed[ED_INT_2]);
+	dev->ed[ED_INT_2].next_ed = virt_to_bus(&dev->ed[ED_INT_1]);
 
 	/*
 	 * Initialize the polling table to call interrupts at the
-	 * intended intervals.  Note that these EDs are just
-	 * placeholders.  They have their SKIP bit set and are used as
-	 * list heads to insert real EDs onto.
+	 * intended intervals.
 	 */
-	dev->hcca->int_table[0] = cpu_to_le32(virt_to_bus(&dev->ed[ED_INT_1]));
+	dev->hcca->int_table[0] = virt_to_bus(&dev->ed[ED_INT_32]);
 	for (i = 1; i < NUM_INTS; i++) {
-		if (i & 16)
+		if (i & 1)
 			dev->hcca->int_table[i] =
-				cpu_to_le32(virt_to_bus(&dev->ed[ED_INT_32]));
-		if (i & 8)
+				virt_to_bus(&dev->ed[ED_INT_16]);
+		else if (i & 2)
 			dev->hcca->int_table[i] =
-				cpu_to_le32(virt_to_bus(&dev->ed[ED_INT_16]));
-		if (i & 4)
+				virt_to_bus(&dev->ed[ED_INT_8]);
+		else if (i & 4)
 			dev->hcca->int_table[i] =
-				cpu_to_le32(virt_to_bus(&dev->ed[ED_INT_8]));
-		if (i & 2)
+				virt_to_bus(&dev->ed[ED_INT_4]);
+		else if (i & 8)
 			dev->hcca->int_table[i] =
-				cpu_to_le32(virt_to_bus(&dev->ed[ED_INT_4]));
-		if (i & 1)
+				virt_to_bus(&dev->ed[ED_INT_2]);
+		else if (i & 16)
 			dev->hcca->int_table[i] =
-				cpu_to_le32(virt_to_bus(&dev->ed[ED_INT_2]));
+				virt_to_bus(&dev->ed[ED_INT_1]);
 	}
 
 	/*
-	 * Tell the controller where the control and bulk lists are.
+	 * Tell the controller where the control and bulk lists are
 	 * The lists start out empty.
 	 */
 	writel(0, &ohci->regs->ed_controlhead);
 	writel(0, &ohci->regs->ed_bulkhead);
+	/*
+	writel(virt_to_bus(&dev->ed[ED_CONTROL]), &ohci->regs->ed_controlhead);
+	writel(virt_to_bus(&dev->ed[ED_BULK]), &ohci->regs->ed_bulkhead);
+	*/
 
-#ifdef OHCI_DEBUG
-	if (MegaDebug) {
-		printk(KERN_DEBUG "alloc_ohci(): controller\n");
-		show_ohci_status(ohci);
-	}
+#if 0
+	printk(KERN_DEBUG "alloc_ohci(): controller\n");
+	show_ohci_status(ohci);
+#endif
+
+#if 0
+	printk(KERN_DEBUG "leaving alloc_ohci %p\n", ohci);
 #endif
 
 	return ohci;
@@ -2341,7 +1310,7 @@
  */
 static void release_ohci(struct ohci *ohci)
 {
-	printk(KERN_DEBUG "Releasing OHCI controller 0x%p\n", ohci);
+	printk(KERN_DEBUG "entering release_ohci %p\n", ohci);
 
 #ifdef OHCI_TIMER
 	/* stop our timer */
@@ -2355,14 +1324,13 @@
 	/* stop all OHCI interrupts */
 	writel(~0x0, &ohci->regs->intrdisable);
 
-	if (ohci->bus->root_hub) {
-		struct ohci_device *root_hub=usb_to_ohci(ohci->bus->root_hub);
+	if (ohci->root_hub) {
 		/* ensure that HC is stopped before releasing the HCCA */
 		writel(OHCI_USB_SUSPEND, &ohci->regs->control);
-		free_page((unsigned long) root_hub->hcca);
-		kfree(ohci->bus->root_hub);
-		root_hub->hcca = NULL;
-		ohci->bus->root_hub = NULL;
+		free_page((unsigned long) ohci->root_hub->hcca);
+		kfree(ohci->root_hub);
+		ohci->root_hub->hcca = NULL;
+		ohci->root_hub = NULL;
 	}
 
 	/* unmap the IO address space */
@@ -2395,23 +1363,20 @@
 	 * This thread doesn't need any user-level access,
 	 * so get rid of all of our resources..
 	 */
-	printk(KERN_DEBUG "ohci-control thread code for 0x%p code at 0x%p\n", __ohci, &ohci_control_thread);
+	printk("ohci_control_thread code at %p\n", &ohci_control_thread);
 	exit_mm(current);
 	exit_files(current);
-	/*exit_fs(current);*/	/* can't do kernel_thread if we do this */
+	exit_fs(current);
 
 	strcpy(current->comm, "ohci-control");
 
-	usb_register_bus(ohci->bus);
-
 	/*
 	 * Damn the torpedoes, full speed ahead
 	 */
 	if (start_hc(ohci) < 0) {
-		printk(KERN_ERR "usb-ohci: failed to start the controller\n");
+		printk("usb-ohci: failed to start the controller\n");
 		release_ohci(ohci);
-		usb_deregister_bus(ohci->bus);
-		printk(KERN_INFO "leaving ohci_control_thread %p\n", __ohci);
+		printk(KERN_DEBUG "leaving ohci_control_thread %p\n", __ohci);
 		return 0;
 	}
 
@@ -2425,12 +1390,11 @@
 		ohci_check_configuration(ohci);
 
 		/* re-enable root hub status change interrupts. */
-#ifdef OHCI_RHSC_INT
+#if 0
 		writel(OHCI_INTR_RHSC, &ohci->regs->intrenable);
 #endif
 
-		if (MegaDebug)
-			printk(KERN_DEBUG "ohci-control thread sleeping\n");
+		printk(KERN_DEBUG "ohci-control thread sleeping\n");
 		interruptible_sleep_on(&ohci_configure);
 #ifdef CONFIG_APM
 		if (apm_resume) {
@@ -2452,19 +1416,11 @@
 			spin_unlock_irq(&current->sigmask_lock);
 
 			if(signr == SIGUSR1) {
-				/* TODO: have it do a full ed/td queue dump? */
+				/* FIXME: have it do a full ed/td queue dump */
 				printk(KERN_DEBUG "OHCI status dump:\n");
 				show_ohci_status(ohci);
-			} else if (signr == SIGUSR2) {
-				/* toggle mega TD/ED debugging output */
-#ifdef OHCI_DEBUG
-				MegaDebug = (MegaDebug + 1) & 3;
-				printk(KERN_DEBUG "usb-ohci: Mega debugging level %d.\n",
-				       MegaDebug);
-#endif
 			} else {
 				/* unknown signal, exit the thread */
-				printk(KERN_DEBUG "usb-ohci: control thread for %p exiting on signal %ld\n", __ohci, signr);
 				break;
 			}
 		}
@@ -2472,7 +1428,8 @@
 
 	reset_hc(ohci);
 	release_ohci(ohci);
-	usb_deregister_bus(ohci->bus);
+
+	printk(KERN_DEBUG "leaving ohci_control_thread %p\n", __ohci);
 
 	return 0;
 } /* ohci_control_thread() */
@@ -2513,12 +1470,9 @@
 #ifdef OHCI_TIMER
 /*
  * Inspired by Iñaky's driver.  This function is a timer routine that
- * is called every OHCI_TIMER_FREQ ms.  It polls the root hub for
- * status changes as on my system the RHSC interrupt just doesn't
- * play well with others.. (so RHSC is turned off by default in this
- * driver)
- * [my controller is a "SiS 7001 USB (rev 16)"]
- * -greg
+ * is called OHCI_TIMER_FREQ times per second.  It polls the root hub
+ * for status changes as on my system things are acting a bit odd at
+ * the moment..
  */
 static void ohci_timer_func (unsigned long ohci_ptr)
 {
@@ -2526,9 +1480,8 @@
 
 	ohci_root_hub_events(ohci);
 
-	/* set the next timer */
-	mod_timer(&ohci_timer, jiffies + ((OHCI_TIMER_FREQ*HZ)/1000));
-
+	/* press the snooze button... */
+	mod_timer(&ohci_timer, jiffies + (OHCI_TIMER_FREQ*HZ));
 } /* ohci_timer_func() */
 #endif
 
@@ -2542,6 +1495,10 @@
 	int retval;
 	struct ohci *ohci;
 
+#if 0
+	printk(KERN_DEBUG "entering found_ohci %d %p\n", irq, mem_base);
+#endif
+
 	/* Allocate the running OHCI structures */
 	ohci = alloc_ohci(mem_base);
 	if (!ohci) {
@@ -2550,10 +1507,9 @@
 
 #ifdef OHCI_TIMER
 	init_timer(&ohci_timer);
-	ohci_timer.expires = jiffies + ((OHCI_TIMER_FREQ*HZ)/1000);
+	ohci_timer.expires = jiffies + (OHCI_TIMER_FREQ*HZ);
 	ohci_timer.data = (unsigned long)ohci;
 	ohci_timer.function = ohci_timer_func;
-	add_timer(&ohci_timer);
 #endif
 
 	retval = -EBUSY;
@@ -2562,8 +1518,8 @@
 
 		ohci->irq = irq;
 
-#ifdef OHCI_DEBUG
-		printk(KERN_DEBUG "usb-ohci: forking ohci-control thread for 0x%p\n", ohci);
+#if 0
+		printk(KERN_DEBUG "usb-ohci: starting ohci-control thread\n");
 #endif
 
 		/* fork off the handler */
@@ -2575,10 +1531,14 @@
 
 		retval = pid;
 	} else {
-		printk(KERN_ERR "usb-ohci: Couldn't allocate interrupt %d\n", irq);
+		printk("usb-ohci: Couldn't allocate interrupt %d\n", irq);
 	}
 	release_ohci(ohci);
 
+#if 0
+	printk(KERN_DEBUG "leaving found_ohci %d %p\n", irq, mem_base);
+#endif
+
 	return retval;
 } /* found_ohci() */
 
@@ -2599,7 +1559,7 @@
 
 	/* no interrupt won't work... */
 	if (dev->irq == 0) {
-		printk(KERN_ERR "usb-ohci: no irq assigned? check your BIOS settings.\n");
+		printk("usb-ohci: no irq assigned? check your BIOS settings.\n");
 		return -ENODEV;
 	}
 
@@ -2612,16 +1572,11 @@
 	mem_base = (unsigned long) ioremap_nocache(mem_base, 4096);
 
 	if (!mem_base) {
-		printk(KERN_ERR "Error mapping OHCI memory\n");
+		printk("Error mapping OHCI memory\n");
 		return -EFAULT;
 	}
         MOD_INC_USE_COUNT;
 
-#ifdef OHCI_DEBUG
-	printk(KERN_INFO "usb-ohci: Warning! Gobs of debugging output has been enabled.\n");
-	printk(KERN_INFO "          Check your kern.debug logs for the bulk of it.\n");
-#endif
-
 	if (found_ohci(dev->irq, (void *) mem_base) < 0) {
 		MOD_DEC_USE_COUNT;
 		return -1;
@@ -2630,6 +1585,26 @@
 	return 0;
 } /* init_ohci() */
 
+#ifdef MODULE
+/*
+ *  Clean up when unloading the module
+ */
+void cleanup_module(void)
+{
+#ifdef CONFIG_APM
+	apm_unregister_callback(&handle_apm_event);
+#endif
+#ifdef CONFIG_USB_MOUSE
+	usb_mouse_cleanup();
+#endif
+	printk("usb-ohci: module unloaded\n");
+}
+
+#define ohci_init init_module
+
+#endif
+
+
 /* TODO this should be named following Linux convention and go in pci.h */
 #define PCI_CLASS_SERIAL_USB_OHCI ((PCI_CLASS_SERIAL_USB << 8) | 0x0010)
 
@@ -2646,11 +1621,11 @@
 	/*u8 type;*/
 
 	if (sizeof(struct ohci_device) > 4096) {
-		printk(KERN_ERR "usb-ohci: struct ohci_device to large\n");
+		printk("usb-ohci: struct ohci_device to large\n");
 		return -ENODEV;
 	}
 
-	printk(KERN_INFO "OHCI USB Driver loading\n");
+	printk("OHCI USB Driver loading\n");
 
 	retval = -ENODEV;
 	for (;;) {
@@ -2669,6 +1644,18 @@
 		if (retval < 0)
 			continue;
 
+		/* TODO check module params here to determine what to load */
+
+#ifdef CONFIG_USB_MOUSE
+		usb_mouse_init();
+#endif
+#ifdef CONFIG_USB_KBD		
+		usb_kbd_init();
+#endif		
+		hub_init();
+#ifdef CONFIG_USB_AUDIO		
+		usb_audio_init();
+#endif		
 #ifdef CONFIG_APM
 		apm_register_callback(&handle_apm_event);
 #endif
@@ -2678,22 +1665,5 @@
 	return retval;
 } /* ohci_init */
 
-
-#ifdef MODULE
-/*
- *  Clean up when unloading the module
- */
-void cleanup_module(void){
-#	ifdef CONFIG_APM
-	apm_unregister_callback(&handle_apm_event);
-#	endif
-	printk(KERN_ERR "usb-ohci: module unloaded\n");
-}
-
-int init_module(void){
-	return ohci_init();
-}
-#endif //MODULE
-
 /* vim:sw=8
  */
diff -urN linux-2.2.12-pre1/drivers/usb/ohci-debug.c linux-2.2.12-pre3/drivers/usb/ohci-debug.c
--- linux-2.2.12-pre1/drivers/usb/ohci-debug.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/ohci-debug.c	1999-05-11 10:04:03.000000000 -0700
@@ -67,7 +67,7 @@
 
 void show_ohci_ed(struct ohci_ed *ed)
 {
-	int stat = le32_to_cpup(&ed->status);
+	int stat = ed->status;
 	int skip = (stat & OHCI_ED_SKIP);
 	int mps = (stat & OHCI_ED_MPS) >> 16;
 	int isoc = (stat & OHCI_ED_F_ISOC);
@@ -75,74 +75,58 @@
 	int dir = (stat & OHCI_ED_D);
 	int endnum = (stat & OHCI_ED_EN) >> 7;
 	int funcaddr = (stat & OHCI_ED_FA);
-	int halted = (le32_to_cpup(&ed->_head_td) & 1);
-	int toggle = (le32_to_cpup(&ed->_head_td) & 2) >> 1;
+	int halted = (ed->_head_td & 1);
+	int toggle = (ed->_head_td & 2) >> 1;
 
 	printk(KERN_DEBUG "   ohci ED:\n");
 	printk(KERN_DEBUG "     status     =  0x%x\n", stat);
-	printk(KERN_DEBUG "       %sMPS %d%s%s%s%s tc%d e%d fa%d%s\n",
+	printk(KERN_DEBUG "       %sMPS %d%s%s%s%s tc%d e%d fa%d\n",
 			skip ? "Skip " : "",
 			mps,
-			isoc ? " Isoc." : "",
+			isoc ? "Isoc. " : "",
 			low_speed ? " LowSpd" : "",
 			(dir == OHCI_ED_D_IN) ? " Input" :
 			(dir == OHCI_ED_D_OUT) ? " Output" : "",
 			halted ? " Halted" : "",
 			toggle,
 			endnum,
-			funcaddr,
-			(stat & ED_ALLOCATED) ? " Allocated" : "");
-	printk(KERN_DEBUG "     tail_td    =  0x%x\n", ed_tail_td(ed));
+			funcaddr);
+	printk(KERN_DEBUG "     tail_td    =  0x%x\n", ed->tail_td);
 	printk(KERN_DEBUG "     head_td    =  0x%x\n", ed_head_td(ed));
-	printk(KERN_DEBUG "     next_ed    =  0x%x\n", le32_to_cpup(&ed->next_ed));
+	printk(KERN_DEBUG "     next_ed    =  0x%x\n", ed->next_ed);
 } /* show_ohci_ed() */
 
 
 void show_ohci_td(struct ohci_td *td)
 {
-	int info = le32_to_cpup(&td->info);
-	int td_round = info & OHCI_TD_ROUND;
-	int td_dir = info & OHCI_TD_D;
-	int td_int_delay = (info & OHCI_TD_IOC_DELAY) >> 21;
-	int td_toggle = (info & OHCI_TD_DT) >> 24;
+	int td_round = td->info & OHCI_TD_ROUND;
+	int td_dir = td->info & OHCI_TD_D;
+	int td_int_delay = (td->info & OHCI_TD_IOC_DELAY) >> 21;
+	int td_toggle = (td->info & OHCI_TD_DT) >> 24;
 	int td_errcnt = td_errorcount(*td);
-	int td_cc = OHCI_TD_CC_GET(info);
+	int td_cc = OHCI_TD_CC_GET(td->info);
 
 	printk(KERN_DEBUG "   ohci TD hardware fields:\n");
-	printk(KERN_DEBUG "      info     =  0x%x\n", info);
-	printk(KERN_DEBUG "        %s%s%s%d %s %s%d\n",
+	printk(KERN_DEBUG "      info     =  0x%x\n", td->info);
+	printk(KERN_DEBUG "        %s%s%s%d %s\n",
 		td_round ? "Rounding " : "",
 		(td_dir == OHCI_TD_D_IN) ? "Input " :
 		(td_dir == OHCI_TD_D_OUT) ? "Output " :
 		(td_dir == OHCI_TD_D_SETUP) ? "Setup " : "",
 		"IntDelay ", td_int_delay,
 		(td_toggle < 2) ? " " :
-		(td_toggle & 1) ? "Data1" : "Data0",
-		"ErrorCnt ", td_errcnt);
-	printk(KERN_DEBUG "        ComplCode 0x%x, %sAccessed\n",
-		td_cc,
-		td_cc_accessed(*td) ? "" : "Not ");
-
-	printk(KERN_DEBUG "        %s%s\n",
-		td_allocated(*td) ? "Allocated" : "Free",
-		td_dummy(*td) ? " DUMMY" : "");
-
-	printk(KERN_DEBUG "      cur_buf  =  0x%x\n", le32_to_cpup(&td->cur_buf));
-	printk(KERN_DEBUG "      next_td  =  0x%x\n", le32_to_cpup(&td->next_td));
-	printk(KERN_DEBUG "      buf_end  =  0x%x\n", le32_to_cpup(&td->buf_end));
+		(td_toggle & 1) ? "Data1 " : "Data0 ");
+	printk(KERN_DEBUG "        %s%d %s0x%x, %sAccessed, %sActive\n",
+		"ErrorCnt ", td_errcnt,
+		"ComplCode ", td_cc,
+		td_cc_accessed(*td) ? "" : "Not ",
+		td_active(*td) ? "" : "Not ");
+
+	printk(KERN_DEBUG "      cur_buf  =  0x%x\n", td->cur_buf);
+	printk(KERN_DEBUG "      next_td  =  0x%x\n", td->next_td);
+	printk(KERN_DEBUG "      buf_end  =  0x%x\n", td->buf_end);
 	printk(KERN_DEBUG "   ohci TD driver fields:\n");
-	printk(KERN_DEBUG "      flags    =  %x {", td->hcd_flags);
-	if (td_allocated(*td))
-		printk(" alloc");
-	if (td_dummy(*td))
-		printk(" dummy");
-	if (td_endofchain(*td))
-		printk(" endofchain");
-	if (!can_auto_free(*td))
-		printk(" noautofree");
-	printk("}\n");
 	printk(KERN_DEBUG "      data     =  %p\n", td->data);
-	printk(KERN_DEBUG "      cmpltd   =  %p\n", td->completed);
 	printk(KERN_DEBUG "      dev_id   =  %p\n", td->dev_id);
 	printk(KERN_DEBUG "      ed       =  %p\n", td->ed);
 	if (td->data != NULL) {
@@ -153,26 +137,6 @@
 } /* show_ohci_td() */
 
 
-void show_ohci_td_chain(struct ohci_td *td)
-{
-	struct ohci_td *cur_td;
-	if (td == NULL) return;
-
-	printk(KERN_DEBUG "+++ OHCI TD Chain %lx: +++\n", virt_to_bus(td));
-
-	cur_td = td;
-	for (;;) {
-		show_ohci_td(cur_td);
-		if (!cur_td->next_td) break;
-		cur_td = bus_to_virt(le32_to_cpup(&cur_td->next_td));
-		/* we can't trust -anything- we find inside of a dummy TD */
-		if (td_dummy(*cur_td)) break;
-	}
-
-	printk(KERN_DEBUG "--- End  TD Chain %lx. ---\n", virt_to_bus(td));
-} /* show_ohci_td_chain () */
-
-
 void show_ohci_device(struct ohci_device *dev)
 {
 	int idx;
@@ -202,14 +166,11 @@
 	printk(KERN_DEBUG "  ohci_hcca\n");
 
 	for (idx=0; idx<NUM_INTS; idx++) {
-		printk(KERN_DEBUG "    int_table[%2d]  == %x\n", idx,
-		       le32_to_cpup(hcca->int_table + idx));
+		printk(KERN_DEBUG "    int_table[%2d]  == %p\n", idx, hcca->int_table +idx);
 	}
 
-	printk(KERN_DEBUG "    frame_no          == %d\n",
-	       le16_to_cpup(&hcca->frame_no));
-	printk(KERN_DEBUG "    donehead          == 0x%08x\n",
-	       le32_to_cpup(&hcca->donehead));
+	printk(KERN_DEBUG "    frame_no          == %d\n", hcca->frame_no);
+	printk(KERN_DEBUG "    donehead          == 0x%08x\n", hcca->donehead);
 } /* show_ohci_hcca() */
 
 
diff -urN linux-2.2.12-pre1/drivers/usb/ohci.h linux-2.2.12-pre3/drivers/usb/ohci.h
--- linux-2.2.12-pre1/drivers/usb/ohci.h	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/ohci.h	1999-05-11 10:04:03.000000000 -0700
@@ -6,7 +6,7 @@
  *
  * (C) Copyright 1999 Gregory P. Smith <greg@electricrain.com>
  *
- * $Id: ohci.h,v 1.24 1999/05/16 10:18:26 greg Exp $
+ * $Id: ohci.h,v 1.15 1999/05/09 23:25:49 greg Exp $
  */
 
 #include <linux/list.h>
@@ -37,16 +37,11 @@
 	struct ohci_td *next_dl_td;	/* used during donelist processing */
 	void *data;			/* virt. address of the the buffer */
 	usb_device_irq completed;	/* Completion handler routine */
-	int hcd_flags;			/* Flags for the HCD: */
-		/* bit0: Is this TD allocated? */
-		/* bit1: Is this a dummy (end of list) TD? */
-		/* bit2: do NOT automatically free this TD on completion */
-		/* bit3: this is the last TD in a contiguious TD chain */
-
-	struct usb_device *usb_dev;	/* the owning device */
+	int allocated;			/* boolean: is this TD allocated? */
 
+	/* User or Device class driver specific fields */
 	void *dev_id;	/* user defined pointer passed to irq handler */
-} __attribute((aligned(32)));
+} __attribute((aligned(16)));
 
 #define OHCI_TD_ROUND	(1 << 18)	/* buffer rounding bit */
 #define OHCI_TD_D	(3 << 19)	/* direction of xfer: */
@@ -57,46 +52,25 @@
 #define td_set_dir_out(d)	((d) ? OHCI_TD_D_OUT : OHCI_TD_D_IN )
 #define OHCI_TD_IOC_DELAY (7 << 21)	/* frame delay allowed before int. */
 #define OHCI_TD_IOC_OFF	(OHCI_TD_IOC_DELAY)	/* no interrupt on complete */
-#define td_set_ioc_delay(frames)	(((frames) & 7) << 21)
 #define OHCI_TD_DT	(3 << 24)	/* data toggle bits */
 #define TOGGLE_AUTO	(0 << 24)	/* automatic (from the ED) */
 #define TOGGLE_DATA0	(2 << 24)	/* force Data0 */
 #define TOGGLE_DATA1	(3 << 24)	/* force Data1 */
 #define td_force_toggle(b)	(((b) | 2) << 24)
 #define OHCI_TD_ERRCNT	(3 << 26)	/* error count */
-#define td_errorcount(td)	((le32_to_cpup(&(td).info) >> 26) & 3)
-#define clear_td_errorcount(td)	((td)->info &= cpu_to_le32(~(__u32)OHCI_TD_ERRCNT))
+#define td_errorcount(td)	(((td).info >> 26) & 3)
 #define OHCI_TD_CC	(0xf << 28)	/* condition code */
 #define OHCI_TD_CC_GET(td_i) (((td_i) >> 28) & 0xf)
 #define OHCI_TD_CC_NEW	(OHCI_TD_CC)	/* set this on all unaccessed TDs! */
-#define td_cc_notaccessed(td)	((le32_to_cpup(&(td).info) >> 29) == 7)
-#define td_cc_accessed(td)	((le32_to_cpup(&(td).info) >> 29) != 7)
-#define td_cc_noerror(td)	(((le32_to_cpup(&(td).info)) & OHCI_TD_CC) == 0)
+#define td_cc_notaccessed(td)	(((td).info >> 29) == 7)
+#define td_cc_accessed(td)	(((td).info >> 29) != 7)
+#define td_cc_noerror(td)	((((td).info) & OHCI_TD_CC) == 0)
+#define td_active(td)	(!td_cc_noerror((td)) && (td_errorcount((td)) < 3))
 #define td_done(td)	(td_cc_noerror((td)) || (td_errorcount((td)) == 3))
 
-/*
- * Macros to use the td->hcd_flags field.
- */
-#define td_allocated(td)	((td).hcd_flags & 1)
-#define allocate_td(td)		((td)->hcd_flags |= 1)
-#define ohci_free_td(td)	((td)->hcd_flags &= ~(__u32)1)
-
-#define td_dummy(td)		((td).hcd_flags & 2)
-#define make_dumb_td(td)	((td)->hcd_flags |= 2)
-#define clear_dumb_td(td)	((td)->hcd_flags &= ~(__u32)2)
-
-#define td_endofchain(td)	((td).hcd_flags & (1 << 3))
-#define clear_td_endofchain(td)	((td)->hcd_flags &= ~(1 << 3))
-#define set_td_endofchain(td)	((td)->hcd_flags |= (1 << 3))
-
-/*
- * These control if the IRQ will call ohci_free_td after taking the TDs
- * off of the donelist (assuming the completion function does not ask
- * for the TD to be requeued).
- */
-#define can_auto_free(td)	(!((td).hcd_flags & 4))
-#define noauto_free_td(td)	((td)->hcd_flags |= 4)
-#define auto_free_td(td)	((td)->hcd_flags &= ~(__u32)4)
+#define td_allocated(td)	((td).allocated)
+#define allocate_td(td)		((td)->allocated = 1)
+#define ohci_free_td(td)	((td)->allocated = 0)
 
 
 /*
@@ -108,27 +82,13 @@
 	__u32 tail_td;	/* TD Queue tail pointer */
 	__u32 _head_td;	/* TD Queue head pointer, toggle carry & halted bits */
 	__u32 next_ed;	/* Next ED */
-
-	/* driver fields */
-	struct ohci_device *ohci_dev;
-	struct ohci_ed	*ed_chain;
 } __attribute((aligned(16)));
 
 /* get the head_td */
-#define ed_head_td(ed)	(le32_to_cpup(&(ed)->_head_td) & 0xfffffff0)
-#define ed_tail_td(ed)	(le32_to_cpup(&(ed)->tail_td))
+#define ed_head_td(ed)	((ed)->_head_td & 0xfffffff0)
 
-/* save the carry & halted flag while setting the head_td */
-#define set_ed_head_td(ed, td)	((ed)->_head_td = cpu_to_le32((td)) \
-				 | ((ed)->_head_td & cpu_to_le32(3)))
-
-/* Control the ED's halted and carry flags */
-#define ohci_halt_ed(ed)	((ed)->_head_td |= cpu_to_le32(1))
-#define ohci_unhalt_ed(ed)	((ed)->_head_td &= cpu_to_le32(~(__u32)1))
-#define ohci_ed_halted(ed)	((ed)->_head_td & cpu_to_le32(1))
-#define ohci_ed_set_carry(ed)	((ed)->_head_td |= cpu_to_le32(2))
-#define ohci_ed_clr_carry(ed)	((ed)->_head_td &= ~cpu_to_le32(2))
-#define ohci_ed_carry(ed)	((le32_to_cpup(&(ed)->_head_td) >> 1) & 1)
+/* save the carry flag while setting the head_td */
+#define set_ed_head_td(ed, td)	((ed)->_head_td = (td) | ((ed)->_head_td & 3))
 
 #define OHCI_ED_SKIP	(1 << 14)
 #define OHCI_ED_MPS	(0x7ff << 16)
@@ -148,17 +108,15 @@
 #define OHCI_ED_EN	(0xf << 7)
 #define OHCI_ED_FA	(0x7f)
 
-#define ed_get_en(ed)	((le32_to_cpup(&(ed)->status) & OHCI_ED_EN) >> 7)
-#define ed_get_fa(ed)	(le32_to_cpup(&(ed)->status) & OHCI_ED_FA)
 
-/* NOTE: bits 27-31 of the status dword are reserved for the HCD */
+/* NOTE: bits 27-31 of the status dword are reserved for the driver */
 /*
  * We'll use this status flag for to mark if an ED is in use by the
- * driver or not.  If the bit is set, it is being used.
+ * driver or not.  If the bit is set, it is used.
+ *
+ * FIXME: implement this!
  */
-#define ED_ALLOCATED	(1 << 31)
-#define ed_allocated(ed)	(le32_to_cpup(&(ed).status) & ED_ALLOCATED)
-#define allocate_ed(ed)		((ed)->status |= cpu_to_le32(ED_ALLOCATED))
+#define ED_USED	(1 << 31)
 
 /*
  * The HCCA (Host Controller Communications Area) is a 256 byte
@@ -220,21 +178,20 @@
 	struct ohci_td		td[NUM_TDS];	/* Transfer Descriptors */
 
 	unsigned long		data[DATA_BUF_LEN];
-} __attribute((aligned(32)));
+};
 
 /* .... */
 
-/*
- * These are the index of the placeholder EDs for the root hub to
- * build the interrupt transfer ED tree out of.
- */
 #define ED_INT_1	0
 #define ED_INT_2	1
 #define ED_INT_4	2
 #define ED_INT_8	3
 #define ED_INT_16	4
 #define ED_INT_32	5
+#define ED_CONTROL	6
+#define ED_BULK		7
 #define ED_ISO		ED_INT_1	/* same as 1ms interrupt queue */
+#define ED_FIRST_AVAIL  8		/* first non-reserved ED */
 
 /*
  * Given a period p in ms, convert it to the closest endpoint
@@ -253,9 +210,7 @@
  * This is the maximum number of root hub ports.  I don't think we'll
  * ever see more than two as that's the space available on an ATX
  * motherboard's case, but it could happen.  The OHCI spec allows for
- * up to 15... (which is insane given that they each need to supply up
- * to 500ma; that would be 7.5 amps!).  I have seen a PCI card with 4
- * downstream ports on it.
+ * up to 15... (which is insane!)
  * 
  * Although I suppose several "ports" could be connected directly to
  * internal laptop devices such as a keyboard, mouse, camera and
@@ -299,24 +254,15 @@
 	} roothub;
 } __attribute((aligned(32)));
 
-/*
- * These are used by internal ED managing functions as a
- * parameter to state the type of ED to deal with (when it matters).
- */
-#define HCD_ED_ISOC     (0)
-#define HCD_ED_INT      (1)
-#define HCD_ED_CONTROL  (2)
-#define HCD_ED_BULK     (3)
-
 /* 
  * Read a MMIO register and re-write it after ANDing with (m)
  */
-#define writel_mask(m, a) writel( (readl((unsigned long)(a))) & (__u32)(m), (unsigned long)(a) )
+#define writel_mask(m, a) writel( (readl((__u32)(a))) & (__u32)(m), (__u32)(a) )
 
 /*
  * Read a MMIO register and re-write it after ORing with (b)
  */
-#define writel_set(b, a) writel( (readl((unsigned long)(a))) | (__u32)(b), (unsigned long)(a) )
+#define writel_set(b, a) writel( (readl((__u32)(a))) | (__u32)(b), (__u32)(a) )
 
 
 #define PORT_CCS	(1)		/* port current connect status */
@@ -343,16 +289,6 @@
 #define OHCI_ROOT_CRWE	(1 << 31)	/* Clear RemoteWakeupEnable */
 
 /*
- * Root hub A register masks
- */
-#define OHCI_ROOT_A_NPS	(1 << 9)
-#define OHCI_ROOT_A_PSM	(1 << 8)
-
-/*
- * Root hub B register masks
- */
-
-/*
  * Interrupt register masks
  */
 #define OHCI_INTR_SO	(1)
@@ -398,15 +334,12 @@
 	struct list_head interrupt_list;	/* List of interrupt active TDs for this OHCI */
 };
 
-#define OHCI_TIMER		/* enable the OHCI timer */
-#define OHCI_TIMER_FREQ	(234)	/* ms between each root hub status check */
-
-#undef OHCI_RHSC_INT		/* Don't use root hub status interrupts! */
+#define OHCI_TIMER
+#define OHCI_TIMER_FREQ	(1)		/* frequency of OHCI status checks */
 
-/* Debugging code [ohci-debug.c] */
+/* Debugging code */
 void show_ohci_ed(struct ohci_ed *ed);
 void show_ohci_td(struct ohci_td *td);
-void show_ohci_td_chain(struct ohci_td *td);
 void show_ohci_status(struct ohci *ohci);
 void show_ohci_device(struct ohci_device *dev);
 void show_ohci_hcca(struct ohci_hcca *hcca);
diff -urN linux-2.2.12-pre1/drivers/usb/ohci-hcd.c linux-2.2.12-pre3/drivers/usb/ohci-hcd.c
--- linux-2.2.12-pre1/drivers/usb/ohci-hcd.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/ohci-hcd.c	1999-05-11 09:55:45.000000000 -0700
@@ -3,14 +3,12 @@
  *
  * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
  *
- * The OHCI HCD layer is a simple but nearly complete implementation of what 
- * the USB people would call a HCD  for the OHCI. 
+ * The OHCI HCD layer is a simple but nearly complete implementation of what the
+ * USB people would call a HCD  for the OHCI. 
  * (ISO comming soon, Bulk disabled, INT u. CTRL transfers enabled)
- * The layer on top of it, is for interfacing to the alternate-usb 
- * device-drivers.
+ * The layer on top of it, is for interfacing to the alternate-usb device-drivers.
  * 
- * [ This is based on Linus' UHCI code and gregs OHCI fragments 
- * (0.03c source tree). ]
+ * [ This is based on Linus' UHCI code and gregs OHCI fragments (0.03c source tree). ]
  * [ Open Host Controller Interface driver for USB. ]
  * [ (C) Copyright 1999 Linus Torvalds (uhci.c) ]
  * [ (C) Copyright 1999 Gregory P. Smith <greg@electricrain.com> ]
@@ -53,6 +51,9 @@
 
 #include "usb.h"
 #include "ohci-hcd.h"
+#include "inits.h" 
+
+ 
 
 #ifdef CONFIG_APM
 #include <linux/apm_bios.h>
@@ -61,9 +62,9 @@
 #endif
 
  
-static DECLARE_WAIT_QUEUE_HEAD(bulk_wakeup);
-static DECLARE_WAIT_QUEUE_HEAD(control_wakeup);
-static DECLARE_WAIT_QUEUE_HEAD(root_hub);
+
+static struct wait_queue *control_wakeup;         
+static struct wait_queue *root_hub = NULL;
  
 static __u8 cc_to_status[16] = { /* mapping of the OHCI CC to the UHCI status codes; first guess */
 /* Activ, Stalled, Data Buffer Err, Babble Detected : NAK recvd, CRC/Timeout, Bitstuff, reservd */
@@ -102,7 +103,7 @@
 	OHCI_DEBUG( for(i=0; i < data_len; i++ ) printk(" %02x", ((__u8 *) data)[i]);)
 	OHCI_DEBUG( printk(" ret_status: %x\n", status); })
 	
- 	ret = handler(cc_to_status[status & 0xf], data, data_len, dev_id);
+ 	ret = handler(cc_to_status[status & 0xf], data, dev_id);
 	if(ret == 0) return 0; /* 0 .. do not requeue  */
 	if(status > 0) return -1; /* error occured do not requeue ? */
 	ohci_trans_req(ohci, ep_addr, 0, NULL, data, 8, (__OHCI_BAG) handler, (__OHCI_BAG) dev_id); /* requeue int request */
@@ -121,19 +122,7 @@
 	OHCI_DEBUG( printk(" ret_status: %x\n", status); })
     return 0;                       
 } 
-
-static int sohci_bulk_handler(void * ohci_in, unsigned int ep_addr, int ctrl_len, void * ctrl, void * data, int data_len, int status, __OHCI_BAG lw0, __OHCI_BAG lw)
-{  
-	*(int * )lw0 = status;
-	wake_up(&bulk_wakeup);
-
-	OHCI_DEBUG( { int i; printk("USB HC BULK<<<: %x:", ep_addr, ctrl_len);)
-	OHCI_DEBUG( printk(" data(%d):", data_len);) 
-	OHCI_DEBUG( for(i=0; i < data_len; i++ ) printk(" %02x", ((__u8 *) data)[i]);)
-	OHCI_DEBUG( printk(" ret_status: %x\n", status); })
-    return 0;                       
-}
-                                                           
+                                                             
 static int sohci_request_irq(struct usb_device *usb_dev, unsigned int pipe, usb_device_irq handler, int period, void *dev_id)
 {
 	struct ohci * ohci = usb_dev->bus->hcpriv;
@@ -156,7 +145,7 @@
 
 static int sohci_control_msg(struct usb_device *usb_dev, unsigned int pipe, void *cmd, void *data, int len)
 {
-	DECLARE_WAITQUEUE(wait, current);
+	struct wait_queue wait = { current, NULL }; 
 	struct ohci * ohci = usb_dev->bus->hcpriv;
 	int status;
 	union ep_addr_ ep_addr;
@@ -190,40 +179,6 @@
 	return cc_to_status[status & 0x0f];
 }
 
-static int sohci_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	struct ohci * ohci = usb_dev->bus->hcpriv;
-	int status;
-	union ep_addr_ ep_addr;
-
-    ep_addr.iep = 0;
-	ep_addr.bep.ep = ((pipe >> 15) & 0x0f) 		/* endpoint address */		
-				| (pipe  & 0x80)  				/* direction */
-				|  (11 << 5);					/* type = bulk*/
-	ep_addr.bep.fa	= ((pipe >> 8) & 0x7f);				/* device address */
-	
-	status = 0xf; /* CC not Accessed */
-	OHCI_DEBUG( { int i; printk("USB HC BULK>>>: %x:", ep_addr.iep);)
-	OHCI_DEBUG( printk(" data(%d):", len);) 
-	OHCI_DEBUG( for(i=0; i < len; i++ ) printk(" %02x", ((__u8 *) data)[i]);)
-	OHCI_DEBUG( printk("\n"); })
-	
-	usb_ohci_add_ep(ohci, ep_addr.iep, 0, 1, sohci_bulk_handler, 1 << ((pipe & 0x03) + 3) , (pipe >> 26) & 0x01);
-	
-	current->state = TASK_UNINTERRUPTIBLE;
-    add_wait_queue(&bulk_wakeup, &wait);   
- 
-	ohci_trans_req(ohci, ep_addr.iep, 0, NULL, data, len, (__OHCI_BAG) &status, 0);
-
-	schedule_timeout(HZ/10);
-
-    remove_wait_queue(&bulk_wakeup, &wait); 
-     
-    OHCI_DEBUG(printk("USB HC status::: %x\n", cc_to_status[status & 0x0f]);)
-     
-	return cc_to_status[status & 0x0f];
-}
 
 static int sohci_usb_deallocate(struct usb_device *usb_dev) {
     struct ohci_device *dev = usb_to_ohci(usb_dev); 
@@ -279,45 +234,11 @@
 	return usb_dev;
 }
 
-
-static void *sohci_alloc_isochronous (struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int maxsze, usb_device_irq completed, void *dev_id)
-{
-	return NULL;
-}
-
-static void sohci_delete_isochronous (struct usb_device *dev, void *_isodesc)
-{
-	return;
-}
-
-static int sohci_sched_isochronous (struct usb_device *usb_dev, void *_isodesc, void *_pisodesc)
-{
-	return USB_ST_NOTSUPPORTED;
-}
-
-static int sohci_unsched_isochronous (struct usb_device *usb_dev, void *_isodesc)
-{
-	return USB_ST_NOTSUPPORTED;
-}
-
-static int sohci_compress_isochronous (struct usb_device *usb_dev, void *_isodesc)
-{
-	return USB_ST_NOTSUPPORTED;
-}
-
-
 struct usb_operations sohci_device_operations = {
 	sohci_usb_allocate,
 	sohci_usb_deallocate,
 	sohci_control_msg,
-	sohci_bulk_msg,
 	sohci_request_irq,
-	NULL,	/* FIXME: should be release_irq/remove_irq */
-	sohci_alloc_isochronous,
-	sohci_delete_isochronous,
-	sohci_sched_isochronous,
-	sohci_unsched_isochronous,
-	sohci_compress_isochronous
 };
 
  
@@ -642,7 +563,7 @@
   }
   writel(0, &ohci->regs->ed_controlcurrent); /* reset CTRL list */
   writel(0, &ohci->regs->ed_bulkcurrent);    /* reset BULK list */
-  writel_set((0x03<<4), &ohci->regs->control);   /* start CTRL u. (BULK list) */ 
+  writel_set((0x01<<4), &ohci->regs->control);   /* start CTRL u. (BULK list) */ 
 
   spin_unlock_irqrestore(&usb_ed_lock, flags);
   
@@ -990,7 +911,6 @@
 {
    /*  int fminterval; */
     unsigned int mask;
-    int port_nr;
   /*  fminterval = readl(&ohci->regs->fminterval) & 0x3fff;
 	reset_hc(ohci); */
  
@@ -1002,19 +922,16 @@
 	/* | OHCI_INTR_SO | OHCI_INTR_UE |OHCI_INTR_RHSC |OHCI_INTR_SF|  
 		OHCI_INTR_FNO */
 		
-	if(readl(&ohci->regs->roothub.a) & 0x100) /* global power on */
- 		writel( 0x10000, &ohci->regs->roothub.status); /* root hub power on */
-	else { /* port power on */
- 		for(port_nr=0; port_nr < (ohci->regs->roothub.a & 0xff); port_nr++)
-	     		 writel(0x100, &ohci->regs->roothub.portstatus[port_nr]);
-	}
-	wait_ms(50); 		
+
 	 
 	writel((0x00), &ohci->regs->control); /* USB Reset BUS */
 	wait_ms(10);
 	  
-	writel((0xB7), &ohci->regs->control); /* USB Operational  */
- 		
+	writel((0x97), &ohci->regs->control); /* USB Operational  */
+	
+ 	writel( 0x10000, &ohci->regs->roothub.status); /* root hub power on */
+	wait_ms(50); 
+		
 	OHCI_DEBUG(printk("USB HC rstart_hc_operational: %x\n", readl(&ohci->regs->control)); )
  	OHCI_DEBUG(printk("USB HC roothubstata: %x \n", readl( &(ohci->regs->roothub.a) )); )
  	OHCI_DEBUG(printk("USB HC roothubstatb: %x \n", readl( &(ohci->regs->roothub.b) )); )
@@ -1031,15 +948,15 @@
 
 	struct usb_device * usb_dev;
 	struct ohci_device *dev;
-	struct ohci_device *tmp_root_hub= usb_to_ohci(ohci->bus->root_hub);
-	usb_dev = sohci_usb_allocate(tmp_root_hub->usb);
+
+	usb_dev = sohci_usb_allocate(ohci->root_hub->usb);
 	dev = usb_dev->hcpriv; 
 
 	dev->ohci = ohci; 
 
 	usb_connect(usb_dev);
 
-	tmp_root_hub->usb->children[0] = usb_dev;
+	ohci->root_hub->usb->children[0] = usb_dev;
 
 	usb_new_device(usb_dev);
 	}
@@ -1116,7 +1033,6 @@
 {
 	struct usb_device *usb_dev;
     struct ohci_device *dev;
-	struct ohci_device *tmp_root_hub=usb_to_ohci(ohci->bus->root_hub);
 	OHCI_DEBUG(printk("uhci_connect_change: called for %d stat %x\n", port_nr,readl(&ohci->regs->roothub.portstatus[port_nr]) );)
 
 	/*
@@ -1126,7 +1042,7 @@
 	 *
 	 * So start off by getting rid of any old devices..
 	 */
-	usb_disconnect(&tmp_root_hub->usb->children[port_nr]);
+	usb_disconnect(&ohci->root_hub->usb->children[port_nr]);
 
 	 if(!(readl(&ohci->regs->roothub.portstatus[port_nr]) & RH_PS_CCS)) {
 	 	writel(RH_PS_CCS, &ohci->regs->roothub.portstatus[port_nr]);
@@ -1136,11 +1052,11 @@
 	 * Ok, we got a new connection. Allocate a device to it,
 	 * and find out what it wants to do..
 	 */
-	usb_dev = sohci_usb_allocate(tmp_root_hub->usb);
+	usb_dev = sohci_usb_allocate(ohci->root_hub->usb);
 	dev = usb_dev->hcpriv; 
 	dev->ohci = ohci; 
 	usb_connect(dev->usb);
-	tmp_root_hub->usb->children[port_nr] = usb_dev;
+	ohci->root_hub->usb->children[port_nr] = usb_dev;
 	wait_ms(200); /* wait for powerup */
     /* reset port/device */
  	writel(RH_PS_PRS, &ohci->regs->roothub.portstatus[port_nr]); /* reset port */
@@ -1285,9 +1201,10 @@
 	if (!usb)
 		return NULL;
 
-	dev = usb_to_ohci(usb);
+	dev = ohci->root_hub = usb_to_ohci(usb);
+
 	usb->bus = bus;
-	bus->root_hub = usb;
+	/* bus->root_hub = ohci_to_usb(ohci->root_hub); */
 	dev->ohci = ohci;
 	
 	/* Initialize the root hub */
@@ -1306,11 +1223,10 @@
 static void release_ohci(struct ohci *ohci)
 {
 	int i;
-	struct ohci_device *tmp_root_hub=usb_to_ohci(ohci->bus->root_hub);
 	union ep_addr_ ep_addr;
 	ep_addr.iep = 0;
 	
-	OHCI_DEBUG(printk("USB HC release ohci \n"););
+    OHCI_DEBUG(printk("USB HC release ohci \n");)
     
 	if (ohci->irq >= 0) {
 		free_irq(ohci->irq, ohci);
@@ -1328,22 +1244,25 @@
 	ohci_rm_eds(ohci); /* remove eds */
 	
     /* disconnect all devices */    
-	if(ohci->bus->root_hub)
-		for(i = 0; i < tmp_root_hub->usb->maxchild; i++)
-			usb_disconnect(tmp_root_hub->usb->children + i);
+	if(ohci->root_hub)
+		for(i = 0; i < ohci->root_hub->usb->maxchild; i++)
+			  usb_disconnect(ohci->root_hub->usb->children + i);
 	    
-    usb_deregister_bus(ohci->bus);
-    USB_FREE(tmp_root_hub->usb);
-    USB_FREE(tmp_root_hub);
+    USB_FREE(ohci->root_hub->usb);
+    USB_FREE(ohci->root_hub);
     USB_FREE(ohci->bus);
     
 	/* unmap the IO address space */
 	iounmap(ohci->regs);
        
+	
 	free_pages((unsigned int) ohci->hc_area, 1);
 	
 }
 
+ 
+void cleanup_drivers(void);
+
 static int ohci_roothub_thread(void * __ohci)
 {
         struct ohci *ohci = (struct ohci *)__ohci;
@@ -1365,7 +1284,6 @@
 		start_hc(ohci);
 		writel( 0x10000, &ohci->regs->roothub.status);
 		wait_ms(50); /* root hub power on */
-	usb_register_bus(ohci->bus);
          do {
 #ifdef CONFIG_APM
 		if (apm_resume) {
@@ -1375,7 +1293,7 @@
 		}
 #endif
  	 
-		OHCI_DEBUG(printk("USB RH tasks: int: %x\n",ohci->intrstatus););
+         OHCI_DEBUG(printk("USB RH tasks: int: %x\n", ohci->intrstatus); )
 #ifndef VROOTHUB
 		/*	if (ohci->intrstatus & OHCI_INTR_RHSC)  */
 			{
@@ -1410,6 +1328,9 @@
         return 0;
 }
 
+
+ 
+
 /*
  * Increment the module usage count, start the control thread and
  * return success.
@@ -1507,6 +1428,21 @@
 }
 #endif
 
+
+ int usb_mouse_init(void); 
+#ifdef MODULE
+
+void cleanup_module(void)
+{
+#ifdef CONFIG_APM
+	apm_unregister_callback(&handle_apm_event);
+#endif
+}
+
+#define ohci_hcd_init init_module
+
+#endif
+
 #define PCI_CLASS_SERIAL_USB_OHCI 0x0C0310
 #define PCI_CLASS_SERIAL_USB_OHCI_PG 0x10
  
@@ -1524,6 +1460,16 @@
     if (retval < 0) break;
 
     
+#ifdef CONFIG_USB_MOUSE
+		usb_mouse_init();
+#endif
+#ifdef CONFIG_USB_KBD		
+		usb_kbd_init();
+#endif		
+		hub_init();
+#ifdef CONFIG_USB_AUDIO		
+		usb_audio_init();
+#endif		
 #ifdef CONFIG_APM
 		apm_register_callback(&handle_apm_event);
 #endif
@@ -1533,16 +1479,11 @@
   return retval;
 }
 
-#ifdef MODULE
-int init_module(void){
-	return ohci_hcd_init();
-}
-
-void cleanup_module(void)
+void cleanup_drivers(void)
 {
-#	ifdef CONFIG_APM
-	apm_unregister_callback(&handle_apm_event);
-#	endif
+	 hub_cleanup(); 
+#ifdef CONFIG_USB_MOUSE
+	 usb_mouse_cleanup();
+#endif
 }
-#endif //MODULE
 
diff -urN linux-2.2.12-pre1/drivers/usb/ohci-hcd.h linux-2.2.12-pre3/drivers/usb/ohci-hcd.h
--- linux-2.2.12-pre1/drivers/usb/ohci-hcd.h	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/ohci-hcd.h	1999-05-11 09:55:45.000000000 -0700
@@ -307,6 +307,7 @@
         struct usb_ohci_ed * ed_bulktail;       /* last endpoint of bulk list */
         struct usb_ohci_ed * ed_controltail;    /* last endpoint of control list */
         struct usb_ohci_ed * ed_isotail;        /* last endpoint of iso list */
+        struct ohci_device * root_hub;
         struct usb_ohci_ed ed_rh_ep0;
         struct usb_ohci_ed ed_rh_epi;
         struct ohci_rep_td *td_rh_epi;
diff -urN linux-2.2.12-pre1/drivers/usb/printer.c linux-2.2.12-pre3/drivers/usb/printer.c
--- linux-2.2.12-pre1/drivers/usb/printer.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/printer.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,420 +0,0 @@
-
-/* Driver for USB Printers
- * 
- * (C) Michael Gee (michael@linuxspecific.com) 1999
- * 
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/errno.h>
-#include <linux/miscdevice.h>
-#include <linux/random.h>
-#include <linux/poll.h>
-#include <linux/init.h>
-#include <linux/malloc.h>
-#include <linux/lp.h>
-
-#include <asm/spinlock.h>
-
-#include "usb.h"
-
-#define NAK_TIMEOUT (HZ)				/* stall wait for printer */
-#define MAX_RETRY_COUNT ((60*60*HZ)/NAK_TIMEOUT)	/* should not take 1 minute a page! */
-
-#ifndef USB_PRINTER_MAJOR
-#define USB_PRINTER_MAJOR 63
-#endif
-
-static int mymajor = USB_PRINTER_MAJOR;
-
-#define MAX_PRINTERS	8
-
-struct pp_usb_data {
-	struct usb_device 	*pusb_dev;
-	__u8			isopen;			/* nz if open */
-	__u8			noinput;		/* nz if no input stream */
-	__u8			minor;			/* minor number of device */
-	__u8			status;			/* last status from device */
-	int			maxin, maxout;		/* max transfer size in and out */
-	char			*obuf;			/* transfer buffer (out only) */
-	wait_queue_head_t	wait_q;			/* for timeouts */
-	unsigned int		last_error;		/* save for checking */
-};
-
-static struct pp_usb_data *minor_data[MAX_PRINTERS];
-
-#define PPDATA(x) ((struct pp_usb_data *)(x))
-
-unsigned char printer_read_status(struct pp_usb_data *p)
-{
-	__u8 status;
-	devrequest dr;
-	struct usb_device *dev = p->pusb_dev;
-
-	dr.requesttype = USB_TYPE_CLASS | USB_RT_INTERFACE | 0x80;
-	dr.request = 1;
-	dr.value = 0;
-	dr.index = 0;
-	dr.length = 1;
-	if (dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, &status, 1)) {
-		return 0;
-	}
-	return status;
-}
-
-static int printer_check_status(struct pp_usb_data *p)
-{
-	unsigned int last = p->last_error;
-	unsigned char status = printer_read_status(p);
-
-	if (status & LP_PERRORP)
-		/* No error. */
-		last = 0;
-	else if ((status & LP_POUTPA)) {
-		if (last != LP_POUTPA) {
-			last = LP_POUTPA;
-			printk(KERN_INFO "usblp%d out of paper\n", p->minor);
-		}
-	} else if (!(status & LP_PSELECD)) {
-		if (last != LP_PSELECD) {
-			last = LP_PSELECD;
-			printk(KERN_INFO "usblp%d off-line\n", p->minor);
-		}
-	} else {
-		if (last != LP_PERRORP) {
-			last = LP_PERRORP;
-			printk(KERN_INFO "usblp%d on fire\n", p->minor);
-		}
-	}
-
-	p->last_error = last;
-
-	return status;
-}
-
-void printer_reset(struct pp_usb_data *p)
-{
-	devrequest dr;
-	struct usb_device *dev = p->pusb_dev;
-
-	dr.requesttype = USB_TYPE_CLASS | USB_RECIP_OTHER;
-	dr.request = 2;
-	dr.value = 0;
-	dr.index = 0;
-	dr.length = 0;
-	dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0);
-}
-
-static int open_printer(struct inode * inode, struct file * file)
-{
-	struct pp_usb_data *p;
-
-	if(MINOR(inode->i_rdev) >= MAX_PRINTERS ||
-	   !minor_data[MINOR(inode->i_rdev)]) {
-		return -ENODEV;
-	}
-
-	p = minor_data[MINOR(inode->i_rdev)];
-	p->minor = MINOR(inode->i_rdev);
-
-	if (p->isopen++) {
-		return -EBUSY;
-	}
-	if (!(p->obuf = (char *)__get_free_page(GFP_KERNEL))) {
-		p->isopen = 0;
-		return -ENOMEM;
-	}
-
-	printer_check_status(p);
-
-
-	file->private_data = p;
-//	printer_reset(p);
-	init_waitqueue_head(&p->wait_q);
-	return 0;
-}
-
-static int close_printer(struct inode * inode, struct file * file)
-{
-	struct pp_usb_data *p = file->private_data;
-
-	free_page((unsigned long)p->obuf);
-	p->isopen = 0;
-	file->private_data = NULL;
-	if(!p->pusb_dev) {
-		minor_data[p->minor] = NULL;
-		kfree(p);
-
-		MOD_DEC_USE_COUNT;
-
-	}
-	return 0;
-}
-
-static ssize_t write_printer(struct file * file,
-       const char * buffer, size_t count, loff_t *ppos)
-{
-	struct pp_usb_data *p = file->private_data;
-	unsigned long copy_size;
-	unsigned long bytes_written = 0;
-	unsigned long partial;
-	int result;
-	int maxretry;
-
-	do {
-		char *obuf = p->obuf;
-		unsigned long thistime;
-
-		thistime = copy_size = (count > p->maxout) ? p->maxout : count;
-		if (copy_from_user(p->obuf, buffer, copy_size))
-			return -EFAULT;
-		maxretry = MAX_RETRY_COUNT;
-		while (thistime) {
-			if (!p->pusb_dev)
-				return -ENODEV;
-			if (signal_pending(current)) {
-				return bytes_written ? bytes_written : -EINTR;
-			}
-			result = p->pusb_dev->bus->op->bulk_msg(p->pusb_dev,
-					 usb_sndbulkpipe(p->pusb_dev, 1), obuf, thistime, &partial);
-			if (partial) {
-				obuf += partial;
-				thistime -= partial;
-				maxretry = MAX_RETRY_COUNT;
-			}
-			if (result == USB_ST_TIMEOUT) {	/* NAK - so hold for a while */
-				if(!maxretry--)
-					return -ETIME;
-                                interruptible_sleep_on_timeout(&p->wait_q, NAK_TIMEOUT);
-				continue;
-			} else if (!result && !partial) {
-				break;
-			}
-		};
-		if (result) {
-			/* whoops - let's reset and fail the request */
-//			printk("Whoops - %x\n", result);
-			printer_reset(p);
-			interruptible_sleep_on_timeout(&p->wait_q, 5*HZ);  /* let reset do its stuff */
-			return -EIO;
-		}
-		bytes_written += copy_size;
-		count -= copy_size;
-		buffer += copy_size;
-	} while ( count > 0 );
-
-	return bytes_written ? bytes_written : -EIO;
-}
-
-static ssize_t read_printer(struct file * file,
-       char * buffer, size_t count, loff_t *ppos)
-{
-	struct pp_usb_data *p = file->private_data;
-	int read_count;
-	int this_read;
-	char buf[64];
-	unsigned long partial;
-	int result;
-
-	if (p->noinput)
-		return -EINVAL;
-
-	read_count = 0;
-	while (count) {
-		if (signal_pending(current)) {
-			return read_count ? read_count : -EINTR;
-		}
-		if (!p->pusb_dev)
-			return -ENODEV;
-		this_read = (count > sizeof(buf)) ? sizeof(buf) : count;
-
-		result = p->pusb_dev->bus->op->bulk_msg(p->pusb_dev,
-			  usb_rcvbulkpipe(p->pusb_dev, 2), buf, this_read, &partial);
-
-		/* unlike writes, we don't retry a NAK, just stop now */
-		if (!result & partial)
-			count = this_read = partial;
-		else if (result)
-			return -EIO;
-
-		if (this_read) {
-			if (copy_to_user(buffer, p->obuf, this_read))
-				return -EFAULT;
-			count -= this_read;
-			read_count += this_read;
-			buffer += this_read;
-		}
-	}
-	return read_count;
-}
-
-static int printer_probe(struct usb_device *dev)
-{
-	struct usb_interface_descriptor *interface;
-	int i;
-
-	/*
-	 * FIXME - this will not cope with combined printer/scanners
-	 */
-	if ((dev->descriptor.bDeviceClass != 7 &&
-	     dev->descriptor.bDeviceClass != 0) ||
-	    dev->descriptor.bNumConfigurations != 1 ||
-	    dev->config[0].bNumInterfaces != 1) {
-		return -1;
-	}
-
-	interface = dev->config->altsetting->interface;
-
-	/* Lets be paranoid (for the moment)*/
-	if (interface->bInterfaceClass != 7 ||
-	    interface->bInterfaceSubClass != 1 ||
-	    (interface->bInterfaceProtocol != 2 && interface->bInterfaceProtocol != 1)||
-	    interface->bNumEndpoints > 2) {
-		return -1;
-	}
-
-	if (interface->endpoint[0].bEndpointAddress != 0x01 ||
-	    interface->endpoint[0].bmAttributes != 0x02 ||
-	    (interface->bNumEndpoints > 1 && (
-		    interface->endpoint[1].bEndpointAddress != 0x82 ||
-		    interface->endpoint[1].bmAttributes != 0x02))) {
-		return -1;
-	}
-
-	for (i=0; i<MAX_PRINTERS; i++) {
-		if (!minor_data[i])
-			break;
-	}
-	if (i >= MAX_PRINTERS) {
-		return -1;
-	}
-
-	printk(KERN_INFO "USB Printer found at address %d\n", dev->devnum);
-
-	if (!(dev->private = kmalloc(sizeof(struct pp_usb_data), GFP_KERNEL))) {
-		printk( KERN_DEBUG "usb_printer: no memory!\n");
-		return -1;
-	}
-
-	memset(dev->private, 0, sizeof(struct pp_usb_data));
-	minor_data[i] = PPDATA(dev->private);
-	minor_data[i]->minor = i;
-	minor_data[i]->pusb_dev = dev;
-	/* The max packet size can't be more than 64 (& will be 64 for
-	 * any decent bulk device); this calculation was silly.  -greg
-	 * minor_data[i]->maxout = interface->endpoint[0].wMaxPacketSize * 16;
-	 */
-	minor_data[i]->maxout = 8192;
-	if (minor_data[i]->maxout > PAGE_SIZE) {
-                minor_data[i]->maxout = PAGE_SIZE;
-	}
-	if (interface->bInterfaceProtocol != 2)
-		minor_data[i]->noinput = 1;
-	else {
-		minor_data[i]->maxin = interface->endpoint[1].wMaxPacketSize;
-	}
-
-        if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) {
-		printk(KERN_INFO "  Failed usb_set_configuration: printer\n");
-		return -1;
-	}
-#if 0
-	{
-		__u8 status;
-		__u8 ieee_id[64];
-		devrequest dr;
-
-		/* Lets get the device id if possible */
-		dr.requesttype = USB_TYPE_CLASS | USB_RT_INTERFACE | 0x80;
-		dr.request = 0;
-		dr.value = 0;
-		dr.index = 0;
-		dr.length = sizeof(ieee_id) - 1;
-		if (dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, ieee_id, sizeof(ieee_id)-1) == 0) {
-			if (ieee_id[1] < sizeof(ieee_id) - 1)
-				ieee_id[ieee_id[1]+2] = '\0';
-			else
-				ieee_id[sizeof(ieee_id)-1] = '\0';
-			printk(KERN_INFO "  Printer ID is %s\n", &ieee_id[2]);
-		}
-		status = printer_read_status(PPDATA(dev->private));
-		printk(KERN_INFO "  Status is %s,%s,%s\n",
-		       (status & 0x10) ? "Selected" : "Not Selected",
-		       (status & 0x20) ? "No Paper" : "Paper",
-		       (status & 0x08) ? "No Error" : "Error");
-	}
-#endif
-	return 0;
-}
-
-static void printer_disconnect(struct usb_device *dev)
-{
-	struct pp_usb_data *pp = dev->private;
-
-	if (pp->isopen) {
-		/* better let it finish - the release will do whats needed */
-		pp->pusb_dev = NULL;
-		return;
-	}
-	minor_data[pp->minor] = NULL;
-	kfree(pp);
-	dev->private = NULL;		/* just in case */
-	MOD_DEC_USE_COUNT;
-}
-
-static struct usb_driver printer_driver = {
-	"printer",
-	printer_probe,
-	printer_disconnect,
-	{ NULL, NULL }
-};
-
-static struct file_operations usb_printer_fops = {
-	NULL,		/* seek */
-	read_printer,
-	write_printer,
-	NULL,		/* readdir */
-	NULL,		/* poll - out for the moment */
-	NULL,		/* ioctl */
-	NULL,		/* mmap */
-	open_printer,
-	NULL,		/* flush ? */
-	close_printer,
-	NULL,
-	NULL
-};
-
-int usb_printer_init(void)
-{
-	int result;
-
-	MOD_INC_USE_COUNT;
-	
-	if ((result = register_chrdev(USB_PRINTER_MAJOR, "usblp", &usb_printer_fops)) < 0) {
-		printk(KERN_WARNING "usbprinter: Cannot register device\n");
-		return result;
-	}
-	if (mymajor == 0) {
-		mymajor = result;
-	}
-	usb_register(&printer_driver);
-	printk(KERN_INFO "USB Printer support registered.\n");
-	return 0;
-}
-
-#ifdef MODULE
-int init_module(void)
-{
-
-	return usb_printer_init();
-}
-
-void cleanup_module(void)
-{
-	usb_deregister(&printer_driver);
-	unregister_chrdev(mymajor, "usblp");
-}
-#endif
diff -urN linux-2.2.12-pre1/drivers/usb/procusb linux-2.2.12-pre3/drivers/usb/procusb
--- linux-2.2.12-pre1/drivers/usb/procusb	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/procusb	1969-12-31 16:00:00.000000000 -0800
@@ -1,41 +0,0 @@
-#!/usr/bin/perl
-
-# Reads /proc/bus/usb/devices and selectively lists and/or
-# interprets it.
-
-$DEVFILENAME = "/proc/bus/usb/devices";
-$PROGNAME = $0;
-
-$TAGS = $ARGV[0];		# save user TAGS
-if (length ($TAGS) == 0)
-{
-	print "usage: $PROGNAME tags\n";
-	print "  where 'tags' can be any number of 'TDPCIE' or 'A(LL)'\n";
-	exit 1;
-}
-
-$ALL = ($TAGS =~ /all/i) || ($TAGS =~ /a/i);
-
-# TBD: Check that $TAGS is valid.
-if (! $ALL)
-{
-}
-
-if (! open (DEVNUM, "<$DEVFILENAME"))
-{
-	print "$PROGNAME: cannot open '$DEVFILENAME'\n";
-	exit 1;
-}
-
-while ($line = <DEVNUM>)	# read a text line from DEVNUM
-{
-	if (($ALL) || ($line =~ /^[$TAGS]:/i))	# any of TAGS at beg. of line?
-	{
-		print "$line";	# still has newline char on it
-				# TBD: add more/paging functionality.
-	}
-} # end while DEVNUM
-
-close (DEVNUM);
-
-# END.
diff -urN linux-2.2.12-pre1/drivers/usb/proc_usb.c linux-2.2.12-pre3/drivers/usb/proc_usb.c
--- linux-2.2.12-pre1/drivers/usb/proc_usb.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/proc_usb.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,487 +0,0 @@
-/*
- * drivers/usb/proc_usb.c
- * (C) Copyright 1999 Randy Dunlap.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *************************************************************
- *
- * This is a /proc/bus/usb filesystem output module for USB.
- * It creates /proc/bus/usb/drivers and /proc/bus/usb/devices.
- *
- * /proc/bus/usb/devices contains USB topology, device, config, class,
- * interface, & endpoint data.
- *
- * I considered using /proc/bus/usb/devices/device# for each device
- * as it is attached or detached, but I didn't like this for some
- * reason -- maybe it's just too deep of a directory structure.
- * I also don't like looking in multiple places to gather and view
- * the data.  Having only one file for ./devices also prevents race
- * conditions that could arise if a program was reading device info
- * for devices that are being removed (unplugged).  (That is, the
- * program may find a directory for devnum_12 then try to open it,
- * but it was just unplugged, so the directory is now deleted.
- * But programs would just have to be prepared for situations like
- * this in any plug-and-play environment.)
- */
-
-#define __KERNEL__	1
-
-#include <linux/types.h>
-#include <asm/types.h>
-#include <linux/kernel.h>
-/* #include <linux/module.h> */
-#include <linux/fs.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-#include <linux/string.h>
-#include <linux/list.h>
-
-#include "usb.h"
-
-#define DUMP_LIMIT		(PAGE_SIZE - 100)
-	/* limit to only one memory page of output */
-
-#define MAX_TOPO_LEVEL		6
-
-
-static char *format_topo =
-/* T:  Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd If#=ddd MxCh=dd Driver=%s */
-  "T:  Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s If#=%3d MxCh=%2d Driver=%s\n";
-  
-static char *format_device1 =
-/* D:  Ver=xx.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd */
-  "D:  Ver=%2x.%02x Cls=%02x(%-5s) Sub=%02x Prot=%02x MxPS=%2d #Cfgs=%3d\n";
-
-static char *format_device2 =
-/* P:  Vendor=xxxx ProdID=xxxx Rev=xx.xx */
-  "P:  Vendor=%04x ProdID=%04x Rev=%2x.%02x\n";
-
-static char *format_config =
-/* C:  #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */
-  "C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA\n";
-  
-static char *format_iface =
-/* I:  If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx */
-  "I:  If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x\n";
-
-static char *format_endpt =
-/* E:  Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=dddms */
-  "E:  Ad=%02x(%c) Atr=%02x(%-4s) MxPS=%4d Ivl=%3dms\n";
-
-
-/*
- * Need access to the driver and USB bus lists.
- * extern struct list_head usb_driver_list;
- * extern struct list_head usb_bus_list;
- * However, these will come from functions that return ptrs to each of them.
- */
-
-extern struct list_head *usb_driver_get_list (void);
-extern struct list_head *usb_bus_get_list (void);
-
-extern struct proc_dir_entry *proc_bus;
-
-static struct proc_dir_entry *usbdir = NULL, *driversdir = NULL;
-static struct proc_dir_entry *devicesdir = NULL;
-
-struct class_info {
-	int class;
-	char *class_name;
-};
-
-struct class_info clas_info [] =
-{					/* max. 5 chars. per name string */
-	{USB_CLASS_PER_INTERFACE,	">ifc"},
-	{USB_CLASS_AUDIO,		"audio"},
-	{USB_CLASS_COMM,		"comm."},
-	{USB_CLASS_HID,			"HID"},
-	{USB_CLASS_HUB,			"hub"},
-	{USB_CLASS_PRINTER,		"print"},
-	{USB_CLASS_MASS_STORAGE,	"stor."},
-	{USB_CLASS_VENDOR_SPEC,		"vend."},
-	{-1,				"unk."}		/* leave as last */
-};
-
-/*****************************************************************/
-
-static char *class_decode (const int class)
-{
-	int	ix;
-
-	for (ix = 0; clas_info [ix].class != -1; ix++)
-		if (clas_info [ix].class == class)
-			break;
-
-	return (clas_info [ix].class_name);
-}
-static int usb_dump_endpoint_descriptor (const struct usb_endpoint_descriptor *desc,
-					char *buf, int *len)
-{
-	char *EndpointType [4] = {"Ctrl", "Isoc", "Bulk", "Int."};
-
-	*len += sprintf (buf + *len, format_endpt,
-		desc->bEndpointAddress,
-		(desc->bEndpointAddress & USB_DIR_IN) ? 'I' : 'O',
-		desc->bmAttributes,
-		EndpointType[desc->bmAttributes & 3],
-		desc->wMaxPacketSize,
-		desc->bInterval
-		);
-
-	return (*len >= DUMP_LIMIT) ? -1 : 0;
-}
-
-static int usb_dump_endpoint (const struct usb_endpoint_descriptor *endpoint,
-				char *buf, int *len)
-{
-	if (usb_dump_endpoint_descriptor (endpoint, buf, len) < 0)
-		return -1;
-
-	return 0;
-}
-
-static int usb_dump_interface_descriptor (const struct usb_interface_descriptor *desc,
-						char *buf, int *len)
-{
-	*len += sprintf (buf + *len, format_iface,
-		desc->bInterfaceNumber,
-		desc->bAlternateSetting,
-		desc->bNumEndpoints,
-		desc->bInterfaceClass,
-		class_decode (desc->bInterfaceClass),
-		desc->bInterfaceSubClass,
-		desc->bInterfaceProtocol
-		);
-
-	return (*len >= DUMP_LIMIT) ? -1 : 0;
-}
-
-static int usb_dump_interface (const struct usb_interface_descriptor *interface,
-				char *buf, int *len)
-{
-	int i;
-
-	if (usb_dump_interface_descriptor (interface, buf, len) < 0)
-		return -1;
-
-	for (i = 0; i < interface->bNumEndpoints; i++) {
-		if (usb_dump_endpoint (interface->endpoint + i, buf, len) < 0)
-			return -1;
-	}
-
-	return 0;
-}
-
-/* TBD:
- * 0. TBDs
- * 1. marking active config and ifaces (code lists all, but should mark
- *    which ones are active, if any)
- * 2. Add proc_usb_init() call from usb-core.c.
- * 3. proc_usb as a MODULE ?
- * 4. use __initfunc() ?
- * 5. add <halted> status to each endpoint line
- */
-
-static int usb_dump_config_descriptor (const struct usb_config_descriptor *desc,
-					const int active, char *buf, int *len)
-{
-	*len += sprintf (buf + *len, format_config,
-		active ? '*' : ' ',	/* mark active/actual/current cfg. */
-		desc->bNumInterfaces,
-		desc->bConfigurationValue,
-		desc->bmAttributes,
-		desc->MaxPower * 2
-		);
-
-	return (*len >= DUMP_LIMIT) ? -1 : 0;
-}
-
-static int usb_dump_config (const struct usb_config_descriptor *config,
-				const int active, char *buf, int *len)
-{
-	int i, j;
-	struct usb_alternate_setting *as;
-
-	if (!config) {		/* getting these some in 2.3.7; none in 2.3.6 */
-		*len += sprintf (buf + *len, "(null Cfg. desc.)\n");
-		return 0;
-	}
-
-	if (usb_dump_config_descriptor (config, active, buf, len) < 0)
-		return -1;
-
-	for (i = 0; i < config->num_altsetting; i++) {
-		as = config->altsetting + i;
-		if ((as) == NULL)
-			break;
-
-		for (j = 0; j < config->bNumInterfaces; j++)
-			if (usb_dump_interface (as->interface + j, buf, len) < 0)
-				return -1;
-	}
-
-	return 0;
-}
-
-/*
- * Dump the different USB descriptors.
- */
-static int usb_dump_device_descriptor (const struct usb_device_descriptor *desc,
-				char *buf, int *len)
-{
-	*len += sprintf (buf + *len, format_device1,
-			desc->bcdUSB >> 8, desc->bcdUSB & 0xff,
-			desc->bDeviceClass,
-			class_decode (desc->bDeviceClass),
-			desc->bDeviceSubClass,
-			desc->bDeviceProtocol,
-			desc->bMaxPacketSize0,
-			desc->bNumConfigurations
-			);
-	if (*len >= DUMP_LIMIT) return -1;
-
-	*len += sprintf (buf + *len, format_device2,
-			desc->idVendor, desc->idProduct,
-			desc->bcdDevice >> 8, desc->bcdDevice & 0xff
-			);
-
-	return (*len >= DUMP_LIMIT) ? -1 : 0;
-}
-
-static int usb_dump_desc (const struct usb_device *dev, char *buf, int *len)
-{
-	int i;
-
-	if (usb_dump_device_descriptor (&dev->descriptor, buf, len) < 0)
-		return -1;
-
-	for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
-		if (usb_dump_config (dev->config + i,
-			(dev->config + i) == dev->actconfig, /* active ? */
-			buf, len) < 0)
-				return -1;
-	}
-
-	return 0;
-}
-
-#ifdef PROC_EXTRA /* TBD: may want to add this code later */
-
-static int usb_dump_hub_descriptor (const struct usb_hub_descriptor * desc,
-					char *buf, int *len)
-{
-	int leng = USB_DT_HUB_NONVAR_SIZE;
-	unsigned char *ptr = (unsigned char *) desc;
-
-	*len += sprintf (buf + *len, "Interface:");
-
-	while (leng) {
-		*len += sprintf (buf + *len, " %02x", *ptr);
-		ptr++; leng--;
-	}
-	*len += sprintf (buf + *len, "\n");
-
-	return (*len >= DUMP_LIMIT) ? -1 : 0;
-}
-
-static int usb_dump_string (const struct usb_device *dev, char *id, int index,
-				char *buf, int *len)
-{
-	if (index <= dev->maxstring && dev->stringindex && dev->stringindex[index])
-		*len += sprintf (buf + *len, "%s: %s ", id, dev->stringindex[index]);
-
-	return (*len >= DUMP_LIMIT) ? -1 : 0;
-}
-
-#endif /* PROC_EXTRA */
-
-/*****************************************************************/
-
-static int usb_device_dump (char *buf, int *len,
-			const struct usb_device *usbdev,
-			int level, int index, int count)
-{
-	int	chix;
-	int	cnt = 0;
-	int	parent_devnum;
-
-	if (level > MAX_TOPO_LEVEL) return -1;
-
-	parent_devnum = usbdev->parent ? (usbdev->parent->devnum == -1) ? 0
-			: usbdev->parent->devnum : 0;
-		/*
-		 * So the root hub's parent is 0 and any device that is
-		 * plugged into the root hub has a parent of 0.
-		 */
-	*len += sprintf (buf + *len, format_topo,
-		level, parent_devnum, index, count,
-		usbdev->devnum,
-		usbdev->slow ? "1.5" : "12 ",
-		usbdev->ifnum, usbdev->maxchild,
-		usbdev->driver ? usbdev->driver->name :
-		(level == 0) ? "(root hub)" : "(none)"
-		);
-		/*
-		 * level = topology-tier level;
-		 * parent_devnum = parent device number;
-		 * index = parent's connector number;
-		 * count = device count at this level
-		 */
-
-	if (*len >= DUMP_LIMIT)
-		return -1;
-
-	if (usbdev->devnum > 0) {	/* for any except root hub */
-		if (usb_dump_desc (usbdev, buf, len) < 0)
-			return -1;
-	}
-
-	/* Now look at all of this device's children. */
-	for (chix = 0; chix < usbdev->maxchild; chix++) {
-		if (usbdev->children [chix]) {
-			if (usb_device_dump (buf, len,
-				usbdev->children [chix],
-				level + 1, chix, ++cnt) < 0)
-					return -1;
-		}
-	}
-
-	return 0;
-}
-
-static int usb_bus_list_dump (char *buf, int len)
-{
-	struct list_head *usb_bus_list = usb_bus_get_list ();
-	struct list_head *list = usb_bus_list->next;
-
-	len = 0;
-
-	/*
-	 * Go thru each usb_bus. Within each usb_bus: each usb_device.
-	 * Within each usb_device: all of its device & config. descriptors,
-	 * marking the currently active ones.
-	 */
-
-
-        while (list != usb_bus_list) {
-		struct usb_bus *bus = list_entry (list, struct usb_bus, bus_list);
-
-		if (usb_device_dump (buf, &len, bus->root_hub, 0, 0, 0)
-			< 0)
-			break;
-
-	        list = list->next;
-
-		if (len >= DUMP_LIMIT) {
-			len += sprintf (buf + len, "(truncated)\n");
-			break;
-		}
-        }
-
-	return (len);
-}
-
-static int usb_bus_list_dump_devices (char *buf, char **start, off_t offset,
-				int len, int *eof, void *data)
-{
-	return usb_bus_list_dump (buf, len);
-}
-
-/*
- * Dump usb_driver_list.
- *
- * We now walk the list of registered USB drivers.
- */
-static int usb_driver_list_dump (char *buf, char **start, off_t offset,
-				int len, int *eof, void *data)
-{
-	struct list_head *usb_driver_list = usb_driver_get_list ();
-	struct list_head *tmp = usb_driver_list->next;
-	int cnt = 0;
-
-	len = 0;
-
-	while (tmp != usb_driver_list) {
-		struct usb_driver *driver = list_entry (tmp, struct usb_driver,
-						       driver_list);
-		len += sprintf (buf + len, "%s\n", driver->name);
-		cnt++;
-		tmp = tmp->next;
-
-		if (len >= DUMP_LIMIT)
-		{
-			len += sprintf (buf + len, "(truncated)\n");
-			return (len);
-		}
-	}
-
-	if (!cnt)
-		len += sprintf (buf + len, "(none)\n");
-	return (len);
-}
-
-void proc_usb_cleanup (void)
-{
-	if (driversdir)
-		remove_proc_entry ("drivers", usbdir);
-	if (devicesdir)
-		remove_proc_entry ("devices", usbdir);
-	if (usbdir)
-		remove_proc_entry ("usb", proc_bus);
-}
-
-int proc_usb_init (void)
-{
-	usbdir = create_proc_entry ("usb", S_IFDIR, proc_bus);
-	if (!usbdir) {
-		printk ("proc_usb: cannot create /proc/bus/usb entry\n");
-		return -1;
-	}
-
-	driversdir = create_proc_entry ("drivers", 0, usbdir);
-	if (!driversdir) {
-		printk ("proc_usb: cannot create /proc/bus/usb/drivers entry\n");
-		proc_usb_cleanup ();
-		return -1;
-	}
-	driversdir->read_proc = usb_driver_list_dump;
-
-	devicesdir = create_proc_entry ("devices", 0, usbdir);
-	if (!devicesdir) {
-		printk ("proc_usb: cannot create /proc/bus/usb/devices entry\n");
-		proc_usb_cleanup ();
-		return -1;
-	}
-	devicesdir->read_proc = usb_bus_list_dump_devices;
-
-	return 0;
-}
-
-#ifdef PROCFS_MODULE /* TBD: support proc_fs MODULE ??? */
-
-int init_module (void)
-{
-	return proc_usb_init ();
-}
-
-void cleanup_module (void)
-{
-	proc_usb_cleanup ();
-}
-
-#endif /* PROCFS_MODULE */
-
-/* end proc_usb.c */
diff -urN linux-2.2.12-pre1/drivers/usb/README.ohci linux-2.2.12-pre3/drivers/usb/README.ohci
--- linux-2.2.12-pre1/drivers/usb/README.ohci	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/README.ohci	1999-05-11 10:04:03.000000000 -0700
@@ -1,50 +1,4 @@
-[This is the readme for ohci.c, ohci-debug.c and ohci.h]
-
-June 23, 1999 00:31:20 PST
-
-I now have bulk support in a reasonably working state.  The only
-device I have tested it with at the moment is my Epson Stylus 740
-printer.  I can print both small and large files.
-
-I have included code to support transfers of large amounts of data in
-either control or bulk transfers.  Check out the build_td_chain() and
-add_td_chain_to_ed() functions.
-
-TODO:
-
-~ Get Michael Gee's mass storage driver working with my donated
-  YE-Data floppy drive over OHCI.
-~ Drool on the Epson printer because its the new toy around the house.
-
-June 08, 1999 01:23:34
-
-Paul Mackerras went through the OHCI (& USB code) to fix most of the
-endianness issues so that the code now works on Linux-PPC.  He also
-simplified add_td_to_ed to be simpler & atomic to the hardware.
-
-May 16, 1999 16:20:54
-
-EDs are now allocated dynamically from their device's pool.  Root hub
-status changes should stop the infinite "no device connected" messages
-that occurred after removing a device.
-
-TODO:
-
-~ Add Isochronous transfer support.  These have their own special
-  format TDs to allow for several DMA data pointers.  Kinda neat, but
-  likely harder to use through a generic interface in practice.
-~ Support dynamic allocation & growth of the TD/ED pools.  Merge them
-  into global pools rather than a today's static per device allocation.
-
-KNOWN BUGS:
-
-~ Unplugging a hub causes khubd to Oops.  I don't think this is
-  directly related to OHCI, but due to the fact that the interrupt TD
-  for the hub is never stopped.  We need a usb_release_irq() that gets
-  called using the "IRQ handle" that should be returned by
-  usb_request_irq().
-
-May 09, 1999 16:25:58 PST
+May 09, 1999 16:25:58
 
 Cool, things are working "well" now.  (I'm not getting oops's from the
 OHCI code anyways.. ;).  I can attach a usb hub and mouse in any
@@ -55,5 +9,18 @@
 mouse movements/events.  That means the TD at least returns some data
 and requeues itself.
 
+Device attach/detach from the root hub is not working well.  Currently
+every interrupt checks for root hub status changes and frame number
+overflow interrupts are enabled.  This means you shouldn't have to
+wait more than 32-33 seconds for the change to occur, less if there is
+other activity.  (due to checking in the WDH caused interrupts)
+My OHCI controller [SiS 5598 motherboard] doesn't seem to play well
+with the RHSC interrupt so it has been disabled.  The ohci_timer
+should be polling but it not currently working, I haven't had time to
+look into that problem.
+
+However, when I tried telling X to use /dev/psaux for the mouse my
+machine locked up...
+
 - greg@electricrain.com
 
diff -urN linux-2.2.12-pre1/drivers/usb/stopusb linux-2.2.12-pre3/drivers/usb/stopusb
--- linux-2.2.12-pre1/drivers/usb/stopusb	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/stopusb	1999-05-11 10:04:03.000000000 -0700
@@ -1,11 +1,7 @@
 #!/bin/sh
 
-killall khubd
 killall ohci-control
-killall uhci-control
 
 sleep 2
 
-rmmod hub
 rmmod usb-ohci
-rmmod usb-uhci
diff -urN linux-2.2.12-pre1/drivers/usb/uhci.c linux-2.2.12-pre3/drivers/usb/uhci.c
--- linux-2.2.12-pre1/drivers/usb/uhci.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/uhci.c	1999-04-30 08:20:53.000000000 -0700
@@ -19,8 +19,6 @@
  */
 
 /* 4/4/1999 added data toggle for interrupt pipes -keryan */
-/* 5/16/1999 added global toggles for bulk and control */
-/* 6/25/1999 added fix for data toggles on bidirectional bulk endpoints */ 
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -32,15 +30,14 @@
 #include <linux/malloc.h>
 #include <linux/smp_lock.h>
 #include <linux/errno.h>
-#include <linux/unistd.h>
 
-#include <asm/uaccess.h>
 #include <asm/spinlock.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/system.h>
 
 #include "uhci.h"
+#include "inits.h"
 
 #ifdef CONFIG_APM
 #include <linux/apm_bios.h>
@@ -48,105 +45,33 @@
 static int apm_resume = 0;
 #endif
 
-static int uhci_debug = 1;
-
 #define compile_assert(x) do { switch (0) { case 1: case !(x): } } while (0)
 
-static DECLARE_WAIT_QUEUE_HEAD(uhci_configure);
+static struct wait_queue *uhci_configure = NULL;
 
 /*
- * Map status to standard result codes
- */
-static int uhci_map_status(int status, int dir_out)
-{
-    if (!status)
-    	    return USB_ST_NOERROR;
-    if (status & 0x02)				/* Bitstuff error*/
-    	    return USB_ST_BITSTUFF;
-    if (status & 0x04)	{			/* CRC/Timeout */
-	if (dir_out)
-    	    return USB_ST_NORESPONSE;
-	else
-	    return USB_ST_CRC;
-    }
-    if (status & 0x08)				/* NAK */
-    	    return USB_ST_TIMEOUT;
-    if (status & 0x10)				/* Babble */
-    	    return USB_ST_STALL;
-    if (status & 0x20)				/* Buffer error */
-    	    return USB_ST_BUFFERUNDERRUN;
-    if (status & 0x40)				/* Stalled */
-    	    return USB_ST_STALL;
-    if (status & 0x80)				/* Active */
-    	    return USB_ST_NOERROR;
-    return USB_ST_INTERNALERROR;
-}
-/*
  * Return the result of a TD..
  */
-static int uhci_td_result(struct uhci_device *dev, struct uhci_td *td, unsigned long *rval)
+static int uhci_td_result(struct uhci_device *dev, struct uhci_td *td)
 {
 	unsigned int status;
-	struct uhci_td *tmp = td->first;
-
-	if(rval)
-		*rval = 0;
 
-	/* locate the first failing td, if any */
-
-	do {
-		status = (tmp->status >> 16) & 0xff;
-		if (status) {
-			/* must reset the toggle on first error */
-    			if (uhci_debug) {
-			    printk("Set toggle from %x rval %ld\n", (unsigned int)tmp, rval ? *rval : 0);
-			}
-			usb_settoggle(dev->usb, usb_pipeendpoint(tmp->info), usb_pipeout(tmp->info), (tmp->info >> 19) & 1);
-			break;
-		} else {
-		    if(rval)
-			*rval += (tmp->status & 0x3ff) + 1;
-		}
-		if ((tmp->link & 1) || (tmp->link & 2))
-			break;
-		tmp = bus_to_virt(tmp->link & ~0xF);
-	} while (1);
-
-
-	if (!status)
-    		return USB_ST_NOERROR;
+	status = (td->status >> 16) & 0xff;
 
 	/* Some debugging code */
-	if (uhci_debug /* && (!usb_pipeendpoint(tmp->info) || !(status & 0x08))*/ ) {
+	if (status) {
 		int i = 10;
-
-		tmp = td->first;
-		printk("uhci_td_result() failed with status %x\n", status);
-		//show_status(dev->uhci);
+		struct uhci_td *tmp = dev->control_td;
+		printk("uhci_td_result() failed with status %d\n", status);
+		show_status(dev->uhci);
 		do {
 			show_td(tmp);
-			if ((tmp->link & 1) || (tmp->link & 2))
-				break;
-			tmp = bus_to_virt(tmp->link & ~0xF);
+			tmp++;
 			if (!--i)
 				break;
-		} while (1);
-	}
-
-	if (status & 0x40) {
-	    /* endpoint has stalled - mark it halted */
-
-	    usb_endpoint_halt(dev->usb, usb_pipeendpoint(tmp->info));
-	    return USB_ST_STALL;
-
-	}
-
-	if (status == 0x80) {
-	    /* still active */
-	    if (!rval)
-		return USB_ST_DATAUNDERRUN;
+		} while (tmp <= td);
 	}
-	return uhci_map_status(status, usb_pipeout(tmp->info));		
+	return status;		
 }
 
 /*
@@ -280,8 +205,8 @@
 
 static void uhci_qh_deallocate(struct uhci_qh *qh)
 {
-//	if (qh->element != 1)
-//		printk("qh %p leaving dangling entries? (%X)\n", qh, qh->element);
+	if (qh->element != 1)
+		printk("qh %p leaving dangling entries? (%X)\n", qh, qh->element);
 
 	qh->element = 1;
 	qh->link = 1;
@@ -298,10 +223,8 @@
 	for (; (inuse = test_and_set_bit(0, &td->inuse)) != 0 && td < &dev->td[UHCI_MAXTD]; td++)
 		;
 
-	if (!inuse) {
-    		td->inuse = 1;
+	if (!inuse)
 		return(td);
-	}
 
 	printk("ran out of td's for dev %p\n", dev);
 	return(NULL);
@@ -344,24 +267,19 @@
 	spin_unlock_irqrestore(&irqlist_lock, flags);
 }
 
-
 /*
  * Request a interrupt handler..
- *
- * Returns: a "handle pointer" that release_irq can use to stop this
- * interrupt.  (It's really a pointer to the TD).
  */
-static void* uhci_request_irq(struct usb_device *usb_dev, unsigned int pipe, usb_device_irq handler, int period, void *dev_id)
+static int uhci_request_irq(struct usb_device *usb_dev, unsigned int pipe, usb_device_irq handler, int period, void *dev_id)
 {
 	struct uhci_device *dev = usb_to_uhci(usb_dev);
-	struct uhci_device *root_hub=usb_to_uhci(dev->uhci->bus->root_hub);
 	struct uhci_td *td = uhci_td_allocate(dev);
 	struct uhci_qh *interrupt_qh = uhci_qh_allocate(dev);
 
 	unsigned int destination, status;
 
 	/* Destination: pipe destination with INPUT */
-	destination = (pipe & PIPE_DEVEP_MASK) | usb_packetid (pipe);
+	destination = (pipe & 0x0007ff00)  |  0x69;
 
 	/* Status:    slow/fast,      Interrupt,   Active,    Short Packet Detect     Infinite Errors */
 	status = (pipe & (1 << 26)) | (1 << 24) | (1 << 23)   |   (1 << 29)       |    (0 << 27);
@@ -371,314 +289,20 @@
 		       interrupt_qh->element);
 
 	td->link = 1;
-	td->status = status;
-	td->info = destination | ((usb_maxpacket(usb_dev, pipe) - 1) << 21) |
-		(usb_gettoggle(usb_dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)) << 19);
+	td->status = status;			/* In */
+	td->info = destination | (7 << 21);	/* 8 bytes of data */
 	td->buffer = virt_to_bus(dev->data);
-	td->first = td;
 	td->qh = interrupt_qh;
-	td->dev = usb_dev;
-
-	/* if period 0, insert into fast q */
-
-	if (period == 0) {
-		td->inuse |= 2;
-		interrupt_qh->skel = &root_hub->skel_int2_qh;
-	} else
-		interrupt_qh->skel = &root_hub->skel_int8_qh;
+	interrupt_qh->skel = &dev->uhci->root_hub->skel_int8_qh;
 
 	uhci_add_irq_list(dev->uhci, td, handler, dev_id);
 
 	uhci_insert_td_in_qh(interrupt_qh, td);
 
 	/* Add it into the skeleton */
-	uhci_insert_qh(interrupt_qh->skel, interrupt_qh);
-
-	return (void*)td;
-}
-
-/*
- * Remove running irq td from queues
- *
- * This function is not used anymore.
- */
-#if 0
-static int uhci_remove_irq(struct usb_device *usb_dev, unsigned int pipe, usb_device_irq handler, int period, void *dev_id)
-{
-    struct uhci_device *dev = usb_to_uhci(usb_dev);
-    struct uhci_device *root_hub=usb_to_uhci(dev->uhci->bus->root_hub);
-    struct uhci_td *td;
-    struct uhci_qh *interrupt_qh;
-    unsigned long flags;
-    struct list_head *head = &dev->uhci->interrupt_list;
-    struct list_head *tmp;
-
-    spin_lock_irqsave(&irqlist_lock, flags);
-
-    /* find the TD in the interrupt list */
-
-    tmp = head->next;
-    while (tmp != head) {
-	td = list_entry(tmp, struct uhci_td, irq_list);
-	if (td->dev_id == dev_id && td->completed == handler) {
-
-	    /* found the right one - let's remove it */
-
-	    /* notify removal */
-
-	    td->completed(USB_ST_REMOVED, NULL, 0, td->dev_id);
-
-	    /* this is DANGEROUS - not sure whether this is right */
-
-	    list_del(&td->irq_list);
-	    uhci_remove_td(td);
-	    interrupt_qh = td->qh;
-	    uhci_remove_qh(interrupt_qh->skel, interrupt_qh);
-	    uhci_td_deallocate(td);
-	    uhci_qh_deallocate(interrupt_qh);
-	    spin_unlock_irqrestore(&irqlist_lock, flags);
-	    return USB_ST_NOERROR;
-	}
-    }
-    spin_unlock_irqrestore(&irqlist_lock, flags);
-    return USB_ST_INTERNALERROR;
-}
-#endif
-
-/*
- * Release an interrupt handler previously allocated using
- * uhci_request_irq.  This function does no validity checking, so make
- * sure you're not releasing an already released handle as it may be
- * in use by something else..
- *
- * This function can NOT be called from an interrupt.
- */
-int uhci_release_irq(void* handle)
-{
-	struct uhci_td *td;
-	struct uhci_qh *interrupt_qh;
-	unsigned long flags;
-
-#ifdef UHCI_DEBUG
-	printk("usb-uhci: Releasing irq handle %p\n", handle);
-#endif
-
-	td = (struct uhci_td*)handle;
-	if (td == NULL)
-		return USB_ST_INTERNALERROR;
-
-	/* Remove it from the internal irq_list */
-	spin_lock_irqsave(&irqlist_lock, flags);
-	list_del(&td->irq_list);
-	spin_unlock_irqrestore(&irqlist_lock, flags);
-
-	/* Remove the interrupt TD and QH */
-	uhci_remove_td(td);
-	interrupt_qh = td->qh;
-	uhci_remove_qh(interrupt_qh->skel, interrupt_qh);
-
-	if (td->completed != NULL)
-		td->completed(USB_ST_REMOVED, NULL, 0, td->dev_id);
-
-	/* Free the TD and QH */
-	uhci_td_deallocate(td);
-	uhci_qh_deallocate(interrupt_qh);
-
-	return USB_ST_NOERROR;
-} /* uhci_release_irq() */
-
-
-/*
- * Isochronous thread operations
- */
-
-static int uhci_compress_isochronous(struct usb_device *usb_dev, void *_isodesc)
-{
-	struct uhci_iso_td *isodesc = (struct uhci_iso_td *)_isodesc;
-	char *data = isodesc->data;
-	int i, totlen = 0;
-
-	for (i = 0; i < isodesc->num; i++) {
-		char *cdata = bus_to_virt(isodesc->td[i].buffer & ~0xF);
-		int n = (isodesc->td[i].status + 1) & 0x7FF;
-
-		if ((cdata != data) && (n))
-			memmove(data, cdata, n);
-
-#if 0
-if (n && n != 960)
-	printk("underrun: %d %d\n", i, n);
-#endif
-if ((isodesc->td[i].status >> 16) & 0xFF)
-	printk("error: %d %X\n", i, (isodesc->td[i].status >> 16));
-
-		data += n;
-		totlen += n;
-	}
-
-	return totlen;
-}
-
-static int uhci_unschedule_isochronous(struct usb_device *usb_dev, void *_isodesc)
-{
-	struct uhci_device *dev = usb_to_uhci(usb_dev);
-	struct uhci *uhci = dev->uhci;
-	struct uhci_iso_td *isodesc = (struct uhci_iso_td *)_isodesc;
-	int i;
-
-	if ((isodesc->frame < 0) || (isodesc->frame > 1023))
-		return 1;
-
-	/* Remove from previous frames */
-	for (i = 0; i < isodesc->num; i++) {
-		/* Turn off Active and IOC bits */
-		isodesc->td[i].status &= ~(3 << 23);
-		uhci->fl->frame[(isodesc->frame + i) % 1024] = isodesc->td[i].link;
-	}
-
-	isodesc->frame = -1;
-
+	uhci_insert_qh(&dev->uhci->root_hub->skel_int8_qh, interrupt_qh);
 	return 0;
 }
-	
-/* td points to the one td we allocated for isochronous transfers */
-static int uhci_schedule_isochronous(struct usb_device *usb_dev, void *_isodesc, void *_pisodesc)
-{
-	struct uhci_device *dev = usb_to_uhci(usb_dev);
-	struct uhci *uhci = dev->uhci;
-	struct uhci_iso_td *isodesc = (struct uhci_iso_td *)_isodesc;
-	struct uhci_iso_td *pisodesc = (struct uhci_iso_td *)_pisodesc;
-	int frame, i;
-
-	if (isodesc->frame != -1) {
-		printk("isoc queue not removed\n");
-		uhci_unschedule_isochronous(usb_dev, isodesc);
-	}
-
-	/* Insert TD into list */
-	if (!pisodesc) {
-		frame = inw(uhci->io_addr + USBFRNUM) % 1024;
-		/* HACK: Start 2 frames from now */
-		frame = (frame + 2) % 1024;
-	} else
-		frame = (pisodesc->endframe + 1) % 1024;
-
-#if 0
-printk("scheduling first at frame %d\n", frame);
-#endif
-
-	for (i = 0; i < isodesc->num; i++) {
-		/* Active */
-		isodesc->td[i].status |= (1 << 23);
-		isodesc->td[i].backptr = &uhci->fl->frame[(frame + i) % 1024];
-		isodesc->td[i].link = uhci->fl->frame[(frame + i) % 1024];
-		uhci->fl->frame[(frame + i) % 1024] = virt_to_bus(&isodesc->td[i]);
-	}
-
-#if 0
-printk("last at frame %d\n", (frame + i - 1) % 1024);
-#endif
-
-	/* Interrupt */
-	isodesc->td[i - 1].status |= (1 << 24);
-
-	isodesc->frame = frame;
-	isodesc->endframe = (frame + isodesc->num - 1) % 1024;
-
-#if 0
-	return uhci_td_result(dev, td[num - 1]);
-#endif
-	return 0;
-}
-
-/*
- * Initialize isochronous queue
- */
-static void *uhci_allocate_isochronous(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int maxsze, usb_device_irq completed, void *dev_id)
-{
-	struct uhci_device *dev = usb_to_uhci(usb_dev);
-	unsigned long destination, status;
-	struct uhci_td *td;
-	struct uhci_iso_td *isodesc;
-	int i;
-
-	isodesc = kmalloc(sizeof(*isodesc), GFP_KERNEL);
-	if (!isodesc) {
-		printk("Couldn't allocate isodesc!\n");
-		return NULL;
-	}
-	memset(isodesc, 0, sizeof(*isodesc));
-
-	/* Carefully work around the non contiguous pages */
-	isodesc->num = (len / PAGE_SIZE) * (PAGE_SIZE / maxsze);
-	isodesc->td = kmalloc(sizeof(struct uhci_td) * isodesc->num, GFP_KERNEL);
-	isodesc->frame = isodesc->endframe = -1;
-	isodesc->data = data;
-	isodesc->maxsze = maxsze;
-	
-	if (!isodesc->td) {
-		printk("Couldn't allocate td's\n");
-		kfree(isodesc);
-		return NULL;
-	}
-
-	isodesc->frame = isodesc->endframe = -1;
-
-	/*
-	 * Build the DATA TD's
-	 */
-	i = 0;
-	do {
-		/* Build the TD for control status */
-		td = &isodesc->td[i];
-
-		/* The "pipe" thing contains the destination in bits 8--18 */
-		destination = (pipe & PIPE_DEVEP_MASK)
-			| usb_packetid (pipe);	/* add IN or OUT */
-
-		/* Status:    slow/fast,       Active,       Isochronous */
-		status = (pipe & (1 << 26)) | (1 << 23)   |   (1 << 25);
-
-		/*
-		 * Build the TD for the control request
-		 */
-		td->status = status;
-		td->info = destination | ((maxsze - 1) << 21);
-		td->buffer = virt_to_bus(data);
-		td->first = td;
-		td->backptr = NULL;
-
-		i++;
-
-		data += maxsze;
-
-		if (((int)data % PAGE_SIZE) + maxsze >= PAGE_SIZE)
-			data = (char *)(((int)data + maxsze) & ~(PAGE_SIZE - 1));
-		
-		len -= maxsze;
-	} while (i < isodesc->num);
-
-	/* IOC on the last TD */
-	td->status |= (1 << 24);
-	uhci_add_irq_list(dev->uhci, td, completed, dev_id);
-
-	return isodesc;
-}
-
-static void uhci_delete_isochronous(struct usb_device *usb_dev, void *_isodesc)
-{
-	struct uhci_iso_td *isodesc = (struct uhci_iso_td *)_isodesc;
-
-	/* If it's still scheduled, unschedule them */
-	if (isodesc->frame)
-		uhci_unschedule_isochronous(usb_dev, isodesc);
-
-	/* Remove it from the IRQ list */
-	uhci_remove_irq_list(&isodesc->td[isodesc->num - 1]);
-
-	kfree(isodesc->td);
-	kfree(isodesc);
-}
 
 /*
  * Control thread operations: we just mark the last TD
@@ -688,9 +312,9 @@
  * We need to remove the TD from the lists (both interrupt
  * list and TD lists) by hand if something bad happens!
  */
-static DECLARE_WAIT_QUEUE_HEAD(control_wakeup);
+static struct wait_queue *control_wakeup;
 
-static int uhci_control_completed(int status, void *buffer, int len, void *dev_id)
+static int uhci_control_completed(int status, void *buffer, void *dev_id)
 {
 	wake_up(&control_wakeup);
 	return 0;			/* Don't re-instate */
@@ -699,10 +323,10 @@
 /* td points to the last td in the list, which interrupts on completion */
 static int uhci_run_control(struct uhci_device *dev, struct uhci_td *first, struct uhci_td *last)
 {
-	DECLARE_WAITQUEUE(wait, current);
+	struct wait_queue wait = { current, NULL };
 	struct uhci_qh *ctrl_qh = uhci_qh_allocate(dev);
 	struct uhci_td *curtd;
-	struct uhci_device *root_hub=usb_to_uhci(dev->uhci->bus->root_hub);
+
 	current->state = TASK_UNINTERRUPTIBLE;
 	add_wait_queue(&control_wakeup, &wait);
 
@@ -730,18 +354,9 @@
 	uhci_insert_tds_in_qh(ctrl_qh, first, last);
 
 	/* Add it into the skeleton */
-	uhci_insert_qh(&root_hub->skel_control_qh, ctrl_qh);
+	uhci_insert_qh(&dev->uhci->root_hub->skel_control_qh, ctrl_qh);
 
-//	control should be full here...	
-//	printk("control\n");
-//	show_status(dev->uhci);
-//	show_queues(dev->uhci);
-
-	schedule_timeout(HZ*5);
-
-//	control should be empty here...	
-//	show_status(dev->uhci);
-//	show_queues(dev->uhci);
+	schedule_timeout(HZ/10);
 
 	remove_wait_queue(&control_wakeup, &wait);
 
@@ -753,11 +368,11 @@
 #endif
 
 	/* Remove it from the skeleton */
-	uhci_remove_qh(&root_hub->skel_control_qh, ctrl_qh);
+	uhci_remove_qh(&dev->uhci->root_hub->skel_control_qh, ctrl_qh);
 
 	uhci_qh_deallocate(ctrl_qh);
 
-	return uhci_td_result(dev, last, NULL);
+	return uhci_td_result(dev, last);
 }
 
 /*
@@ -781,21 +396,20 @@
  * information, that's just ridiculously high. Most
  * control messages have just a few bytes of data.
  */
-static int uhci_control_msg(struct usb_device *usb_dev, unsigned int pipe, devrequest *cmd, void *data, int len)
+static int uhci_control_msg(struct usb_device *usb_dev, unsigned int pipe, void *cmd, void *data, int len)
 {
 	struct uhci_device *dev = usb_to_uhci(usb_dev);
 	struct uhci_td *first, *td, *prevtd;
 	unsigned long destination, status;
 	int ret;
-	int maxsze = usb_maxpacket(usb_dev, pipe);
 
-	if (len > maxsze * 29)
+	if (len > usb_maxpacket(usb_dev->maxpacketsize) * 29)
 		printk("Warning, too much data for a control packet, crashing\n");
 
 	first = td = uhci_td_allocate(dev);
 
 	/* The "pipe" thing contains the destination in bits 8--18, 0x2D is SETUP */
-	destination = (pipe & PIPE_DEVEP_MASK) | 0x2D;
+	destination = (pipe & 0x0007ff00) | 0x2D;
 
 	/* Status:    slow/fast,       Active,    Short Packet Detect     Three Errors */
 	status = (pipe & (1 << 26)) | (1 << 23)   |   (1 << 29)       |    (3 << 27);
@@ -806,7 +420,6 @@
 	td->status = status;				/* Try forever */
 	td->info = destination | (7 << 21);		/* 8 bytes of data */
 	td->buffer = virt_to_bus(cmd);
-	td->first = td;
 
 	/*
 	 * If direction is "send", change the frame from SETUP (0x2D)
@@ -826,6 +439,7 @@
 	while (len > 0) {
 		/* Build the TD for control status */
 		int pktsze = len;
+		int maxsze = usb_maxpacket(pipe);
 
 		if (pktsze > maxsze)
 			pktsze = maxsze;
@@ -836,31 +450,27 @@
 		td->status = status;					/* Status */
 		td->info = destination | ((pktsze-1) << 21);		/* pktsze bytes of data */
 		td->buffer = virt_to_bus(data);
-		td->first = first;
 		td->backptr = &prevtd->link;
 
-		data += pktsze;
-		len -= pktsze;
-
 		prevtd = td;
 		td = uhci_td_allocate(dev);
 		prevtd->link = 4 | virt_to_bus(td);			/* Update previous TD */
 
+		data += maxsze;
+		len -= maxsze;
 	}
 
 	/*
-	 * Build the final TD for control status 
+	 * Build the final TD for control status
 	 */
 	destination ^= (0xE1 ^ 0x69);			/* OUT -> IN */
 	destination |= 1 << 19;				/* End in Data1 */
 
-	td->backptr = &prevtd->link;
-	td->status = (status /* & ~(3 << 27) */) | (1 << 24);	/* no limit on final packet */
-	td->info = destination | (UHCI_NULL_DATA_SIZE << 21);	/* 0 bytes of data */
-	td->buffer = 0;
-	td->first = first;
 	td->link = 1;					/* Terminate */
-
+	td->status = status | (1 << 24);		/* IOC */
+	td->info = destination | (0x7ff << 21);		/* 0 bytes of data */
+	td->buffer = 0;
+	td->backptr = &prevtd->link;
 
 	/* Start it up.. */
 	ret = uhci_run_control(dev, first, td);
@@ -885,192 +495,6 @@
 		} while (1);
 	}
 
-	if (uhci_debug && ret) {
-		__u8 *p = (__u8 *)cmd;
-
-		printk("Failed cmd - %02X %02X %02X %02X %02X %02X %02X %02X\n",
-		       p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
-	}
-	return ret;
-}
-
-
-/*
- * Bulk thread operations: we just mark the last TD
- * in a bulk thread as an interrupt TD, and wake up
- * the front-end on completion.
- *
- * We need to remove the TD from the lists (both interrupt
- * list and TD lists) by hand if something bad happens!
- */
-static DECLARE_WAIT_QUEUE_HEAD(bulk_wakeup);
-
-static int uhci_bulk_completed(int status, void *buffer, int len, void *dev_id)
-{
-	wake_up(&bulk_wakeup);
-	return 0;			/* Don't re-instate */
-}
-
-/* td points to the last td in the list, which interrupts on completion */
-static int uhci_run_bulk(struct uhci_device *dev, struct uhci_td *first, struct uhci_td *last, unsigned long *rval)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	struct uhci_qh *bulk_qh = uhci_qh_allocate(dev);
-	struct uhci_td *curtd;
-	struct uhci_device *root_hub=usb_to_uhci(dev->uhci->bus->root_hub);
-
-	current->state = TASK_UNINTERRUPTIBLE;
-	add_wait_queue(&bulk_wakeup, &wait);
-
-	uhci_add_irq_list(dev->uhci, last, uhci_bulk_completed, NULL);
-	
-	/* FIXME: This is kinda kludged */
-	/* Walk the TD list and update the QH pointer */
-	{
-	int maxcount = 100;
-
-	curtd = first;
-	do {
-		curtd->qh = bulk_qh;
-		if (curtd->link & 1)
-			break;
-
-		curtd = bus_to_virt(curtd->link & ~0xF);
-		if (!--maxcount) {
-			printk("runaway tds!\n");
-			break;
-		}
-	} while (1);
-	}
-
-	uhci_insert_tds_in_qh(bulk_qh, first, last);
-
-	/* Add it into the skeleton */
-	uhci_insert_qh(&root_hub->skel_bulk0_qh, bulk_qh);
-
-//	now we're in the queue... but don't ask WHAT is in there ;-(
-//	printk("bulk\n");
-//	show_status(dev->uhci);
-//	show_queues(dev->uhci);
-
-	schedule_timeout(HZ*5);
-//	show_status(dev->uhci);
-//	show_queues(dev->uhci);
-
-	//show_queue(first->qh);
-	remove_wait_queue(&bulk_wakeup, &wait);
-
-	/* Clean up in case it failed.. */
-	uhci_remove_irq_list(last);
-
-#if 0
-	printk("Looking for tds [%p, %p]\n", dev->control_td, td);
-#endif
-
-	/* Remove it from the skeleton */
-	uhci_remove_qh(&root_hub->skel_bulk0_qh, bulk_qh);
-
-	uhci_qh_deallocate(bulk_qh);
-
-	return uhci_td_result(dev, last, rval);
-}
-
-/*
- * Send or receive a bulk message on a pipe.
- *
- * Note that the "pipe" structure is set up to map
- * easily to the uhci destination fields.
- *
- * A bulk message is only built up from
- * the data phase
- *
- * The data phase can be an arbitrary number of TD's
- * although we currently had better not have more than
- * 31 TD's here.
- *
- * 31 TD's is a minimum of 248 bytes worth of bulk
- * information.
- */
-static int uhci_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, unsigned long *rval)
-{
-	struct uhci_device *dev = usb_to_uhci(usb_dev);
-	struct uhci_td *first, *td, *prevtd;
-	unsigned long destination, status;
-	int ret;
-	int maxsze = usb_maxpacket(usb_dev, pipe);
-
-	if (usb_endpoint_halted(usb_dev, usb_pipeendpoint(pipe)) &&
-	    usb_clear_halt(usb_dev, usb_pipeendpoint(pipe) | (pipe & 0x80)))
-		return USB_ST_STALL;
-
-	if (len > maxsze * 31)
-		printk("Warning, too much data for a bulk packet, crashing (%d/%d)\n", len, maxsze);
-
-	/* The "pipe" thing contains the destination in bits 8--18 */
-	destination = (pipe & PIPE_DEVEP_MASK) | usb_packetid (pipe);
-
-	/* Status:    slow/fast,       Active,    Short Packet Detect     Three Errors */
-	status = (pipe & (1 << 26)) | (1 << 23)   |   (1 << 29)       |    (3 << 27);
-
-	/*
-	 * Build the TDs for the bulk request
-	 */
-        first = td = uhci_td_allocate(dev);
-        prevtd = first; //This is fake, but at least it's not NULL
-	while (len > 0) {
-		/* Build the TD for control status */
-		int pktsze = len;
-
-		if (pktsze > maxsze)
-			pktsze = maxsze;
-
-		td->status = status;					/* Status */
-		td->info = destination | ((pktsze-1) << 21) |
-			 (usb_gettoggle(usb_dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)) << 19); /* pktsze bytes of data */
-		td->buffer = virt_to_bus(data);
-		td->backptr = &prevtd->link;
-		td->first = first;
-
-		data += maxsze;
-		len -= maxsze;
-
-		if (len > 0) {
-			prevtd = td;
-			td = uhci_td_allocate(dev);
-			prevtd->link = 4 | virt_to_bus(td);			/* Update previous TD */
-		}
-
-		/* Alternate Data0/1 (start with Data0) */
-		usb_dotoggle(usb_dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
-	}
-	td->link = 1;				/* Terminate */
-	td->status |= (1 << 24);		/* IOC */
-
-	/* CHANGE DIRECTION HERE! SAVE IT SOMEWHERE IN THE ENDPOINT!!! */
-
-	/* Start it up.. */
-	ret = uhci_run_bulk(dev, first, td, rval);
-
-	{
-		int maxcount = 100;
-		struct uhci_td *curtd = first;
-		unsigned int nextlink;
-
-		do {
-			nextlink = curtd->link;
-			uhci_remove_td(curtd);
-			uhci_td_deallocate(curtd);
-			if (nextlink & 1)	/* Tail? */
-				break;
-
-			curtd = bus_to_virt(nextlink & ~0xF);
-			if (!--maxcount) {
-				printk("runaway td's!?\n");
-				break;
-			}
-		} while (1);
-	}
-
 	return ret;
 }
 
@@ -1130,23 +554,19 @@
 	for (i = 0; i < UHCI_MAXTD; ++i) {
 		struct uhci_td *td = dev->td + i;
 
-		if (td->inuse & 1) {
-			uhci_remove_td(td);
+		/* And remove it from the irq list, if it's active */
+		if (td->status & (1 << 23))
+			uhci_remove_irq_list(td);
 
-			/* And remove it from the irq list, if it's active */
-			if (td->status & (1 << 23))
-				td->status &= ~(1 << 23);
-#if 0
-				uhci_remove_irq_list(td);
-#endif
-		}
+		if (td->inuse)
+			uhci_remove_td(td);
 	}
 
 	/* Remove the td from any queues */
 	for (i = 0; i < UHCI_MAXQH; ++i) {
 		struct uhci_qh *qh = dev->qh + i;
 
-		if (qh->inuse & 1)
+		if (qh->inuse)
 			uhci_remove_qh(qh->skel, qh);
 	}
 
@@ -1161,14 +581,7 @@
 	uhci_usb_allocate,
 	uhci_usb_deallocate,
 	uhci_control_msg,
-	uhci_bulk_msg,
 	uhci_request_irq,
-	uhci_release_irq,
-	uhci_allocate_isochronous,
-	uhci_delete_isochronous,
-	uhci_schedule_isochronous,
-	uhci_unschedule_isochronous,
-	uhci_compress_isochronous
 };
 
 /*
@@ -1210,7 +623,7 @@
 	struct usb_device *usb_dev;
 	struct uhci_device *dev;
 	unsigned short status;
-	struct uhci_device *root_hub=usb_to_uhci(uhci->bus->root_hub);
+
 	printk("uhci_connect_change: called for %d\n", nr);
 
 	/*
@@ -1220,7 +633,7 @@
 	 *
 	 * So start off by getting rid of any old devices..
 	 */
-	usb_disconnect(&root_hub->usb->children[nr]);
+	usb_disconnect(&uhci->root_hub->usb->children[nr]);
 
 	status = inw(port);
 
@@ -1235,17 +648,14 @@
 	 * Ok, we got a new connection. Allocate a device to it,
 	 * and find out what it wants to do..
 	 */
-	usb_dev = uhci_usb_allocate(root_hub->usb);
-	if (!usb_dev)
-		return;
-	
+	usb_dev = uhci_usb_allocate(uhci->root_hub->usb);
 	dev = usb_dev->hcpriv;
 
 	dev->uhci = uhci;
 
 	usb_connect(usb_dev);
 
-	root_hub->usb->children[nr] = usb_dev;
+	uhci->root_hub->usb->children[nr] = usb_dev;
 
 	wait_ms(200); /* wait for powerup */
 	uhci_reset_port(port);
@@ -1268,9 +678,8 @@
  */
 static void uhci_check_configuration(struct uhci *uhci)
 {
-	struct uhci_device * root_hub=usb_to_uhci(uhci->bus->root_hub);
 	unsigned int io_addr = uhci->io_addr + USBPORTSC1;
-	int maxchild = root_hub->usb->maxchild;
+	int maxchild = uhci->root_hub->usb->maxchild;
 	int nr = 0;
 
 	do {
@@ -1287,7 +696,6 @@
 {
 	struct list_head *head = &uhci->interrupt_list;
 	struct list_head *tmp;
-	int status;
 
 	spin_lock(&irqlist_lock);
 	tmp = head->next;
@@ -1297,41 +705,25 @@
 
 		next = tmp->next;
 
-		if (!((status = td->status) & (1 << 23)) ||  /* No longer active? */
-		    ((td->qh->element & ~15) && 
-		      !((status = uhci_link_to_td(td->qh->element)->status) & (1 <<23)) &&
-		      (status & 0x760000) /* is in error state (Stall, db, babble, timeout, bitstuff) */)) {	
+		if (!(td->status & (1 << 23))) {	/* No longer active? */
 			/* remove from IRQ list */
 			__list_del(tmp->prev, next);
 			INIT_LIST_HEAD(tmp);
-			if (td->completed(uhci_map_status(status, 0), bus_to_virt(td->buffer), -1, td->dev_id)) {
-				list_add(&td->irq_list, &uhci->interrupt_list);
+			if (td->completed(td->status, bus_to_virt(td->buffer), td->dev_id)) {
+				struct uhci_qh *interrupt_qh = td->qh;
 
-				if (!(td->status & (1 << 25))) {
-					struct uhci_qh *interrupt_qh = td->qh;
+				list_add(&td->irq_list, &uhci->interrupt_list);
+				td->info ^= 1 << 19; /* toggle between data0 and data1 */
+				td->status = (td->status & 0x2f000000) | (1 << 23) | (1 << 24);	/* active */
 
-					usb_dotoggle(td->dev, usb_pipeendpoint(td->info), usb_pipeout(td->info));
-					td->info &= ~(1 << 19); /* clear data toggle */
-					td->info |= usb_gettoggle(td->dev, usb_pipeendpoint(td->info), usb_pipeout(td->info)) << 19; /* toggle between data0 and data1 */
-					td->status = (td->status & 0x2f000000) | (1 << 23) | (1 << 24);	/* active */
-
-					/* Remove then readd? Is that necessary */
-					uhci_remove_td(td);
-					uhci_insert_td_in_qh(interrupt_qh, td);
-				}
-			} else if (td->inuse & 2) {
-				struct uhci_qh *interrupt_qh = td->qh;
-				/* marked for removal */
-				td->inuse &= ~2;
-				usb_dotoggle(td->dev, usb_pipeendpoint(td->info), usb_pipeout(td->info));
-				uhci_remove_qh(interrupt_qh->skel, interrupt_qh);
-				uhci_qh_deallocate(interrupt_qh);
-				uhci_td_deallocate(td);
+				/* Remove then readd? Is that necessary */
+				uhci_remove_td(td);
+				uhci_insert_td_in_qh(interrupt_qh, td);
 			}
 			/* If completed wants to not reactivate, then it's */
 			/* responsible for free'ing the TD's and QH's */
 			/* or another function (such as run_control) */
-		} 
+		}
 		tmp = next;
 	}
 	spin_unlock(&irqlist_lock);
@@ -1348,8 +740,7 @@
 static void uhci_root_hub_events(struct uhci *uhci, unsigned int io_addr)
 {
 	if (waitqueue_active(&uhci_configure)) {
-		struct uhci_device * root_hub=usb_to_uhci(uhci->bus->root_hub);
-		int ports = root_hub->usb->maxchild;
+		int ports = uhci->root_hub->usb->maxchild;
 		io_addr += USBPORTSC1;
 		do {
 			if (inw(io_addr) & USBPORTSC_CSC) {
@@ -1373,9 +764,6 @@
 	status = inw(io_addr + USBSTS);
 	outw(status, io_addr + USBSTS);
 
-//	if ((status & ~0x21) != 0)
-//		printk("interrupt: %X\n", status);
-
 	/* Walk the list of pending TD's to see which ones completed.. */
 	uhci_interrupt_notify(uhci);
 
@@ -1392,14 +780,13 @@
  */
 static void uhci_init_ticktd(struct uhci *uhci)
 {
-	struct uhci_device *dev = usb_to_uhci(uhci->bus->root_hub);
+	struct uhci_device *dev = uhci->root_hub;
 	struct uhci_td *td = uhci_td_allocate(dev);
 
 	td->link = 1;
 	td->status = (1 << 24);					/* interrupt on completion */
 	td->info = (15 << 21) | 0x7f69;				/* (ignored) input packet, 16 bytes, device 127 */
 	td->buffer = 0;
-	td->first = td;
 	td->qh = NULL;
 
 	uhci->fl->frame[0] = virt_to_bus(td);
@@ -1437,13 +824,12 @@
 		}
 	}
 
-
 	outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP, io_addr + USBINTR);
 	outw(0, io_addr + USBFRNUM);
 	outl(virt_to_bus(uhci->fl), io_addr + USBFLBASEADD);
 
 	/* Run and mark it configured with a 64-byte max packet */
-	outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, io_addr + USBCMD);
+	outw(USBCMD_RS | USBCMD_CF, io_addr + USBCMD);
 }
 
 /*
@@ -1484,12 +870,10 @@
 
 	/* We need exactly one page (per UHCI specs), how convenient */
 	uhci->fl = (void *)__get_free_page(GFP_KERNEL);
-	if (!uhci->fl)
-		goto au_free_uhci;
 
 	bus = kmalloc(sizeof(*bus), GFP_KERNEL);
 	if (!bus)
-		goto au_free_fl;
+		return NULL;
 
 	memset(bus, 0, sizeof(*bus));
 
@@ -1509,11 +893,12 @@
 	 */
 	usb = uhci_usb_allocate(NULL);
 	if (!usb)
-		goto au_free_bus;
+		return NULL;
+
+	dev = uhci->root_hub = usb_to_uhci(usb);
 
 	usb->bus = bus;
-	dev = usb_to_uhci(usb);
-	uhci->bus->root_hub=uhci_to_usb(dev);
+
 	/* Initialize the root hub */
 	/* UHCI specs says devices must have 2 ports, but goes on to say */
 	/* they may have more but give no way to determine how many they */
@@ -1580,18 +965,6 @@
 	}
 
 	return uhci;
-
-/*
- * error exits:
- */
-
-au_free_bus:
-	kfree (bus);
-au_free_fl:
-	free_page ((unsigned long)uhci->fl);
-au_free_uhci:
-	kfree (uhci);
-	return NULL;
 }
 
 
@@ -1606,9 +979,9 @@
 	}
 
 #if 0
-	if (uhci->bus->root_hub) {
-		uhci_usb_deallocate(uhci_to_usb(uhci->bus->root_hub));
-		uhci->bus->root_hub = NULL;
+	if (uhci->root_hub) {
+		uhci_usb_deallocate(uhci_to_usb(uhci->root_hub));
+		uhci->root_hub = NULL;
 	}
 #endif
 
@@ -1621,10 +994,11 @@
 	kfree(uhci);
 }
 
+void cleanup_drivers(void);
+
 static int uhci_control_thread(void * __uhci)
 {
 	struct uhci *uhci = (struct uhci *)__uhci;
-	struct uhci_device * root_hub =usb_to_uhci(uhci->bus->root_hub);
 
 	lock_kernel();
 	request_region(uhci->io_addr, 32, "usb-uhci");
@@ -1636,7 +1010,7 @@
 	printk("uhci_control_thread at %p\n", &uhci_control_thread);
 	exit_mm(current);
 	exit_files(current);
-	//exit_fs(current);
+	exit_fs(current);
 
 	strcpy(current->comm, "uhci-control");
 
@@ -1644,7 +1018,6 @@
 	 * Ok, all systems are go..
 	 */
 	start_hc(uhci);
-	usb_register_bus(uhci->bus);
 	for(;;) {
 		siginfo_t info;
 		int unsigned long signr;
@@ -1668,23 +1041,19 @@
 			if(signr == SIGUSR1) {
 				printk("UHCI queue dump:\n");
 				show_queues(uhci);
-			} else if (signr == SIGUSR2) {
-				uhci_debug = !uhci_debug;
-				printk("UHCI debug toggle = %x\n", uhci_debug);
 			} else {
 				break;
 			}
 		}
 	}
 
-	{
-	int i;
-	if(root_hub)
-		for(i = 0; i < root_hub->usb->maxchild; i++)
-			usb_disconnect(root_hub->usb->children + i);
-	}
+#if 0
+	if(uhci->root_hub)
+		for(i = 0; i < uhci->root_hub->usb->maxchild; i++)
+			usb_disconnect(uhci->root_hub->usb->children + i);
+#endif
 
-	usb_deregister_bus(uhci->bus);
+	cleanup_drivers();
 
 	reset_hc(uhci);
 	release_region(uhci->io_addr, 32);
@@ -1715,10 +1084,10 @@
 	retval = -EBUSY;
 	if (request_irq(irq, uhci_interrupt, SA_SHIRQ, "usb", uhci) == 0) {
 		int pid;
+
 		MOD_INC_USE_COUNT;
 		uhci->irq = irq;
-		pid = kernel_thread(uhci_control_thread, uhci,
-			CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+		pid = kernel_thread(uhci_control_thread, uhci, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
 		if (pid >= 0)
 			return 0;
 
@@ -1783,6 +1152,18 @@
 }
 #endif
 
+#ifdef MODULE
+
+void cleanup_module(void)
+{
+#ifdef CONFIG_APM
+	apm_unregister_callback(&handle_apm_event);
+#endif
+}
+
+#define uhci_init init_module
+
+#endif
 
 int uhci_init(void)
 {
@@ -1804,24 +1185,29 @@
 		if (retval < 0)
 			continue;
 
+#ifdef CONFIG_USB_MOUSE
+		usb_mouse_init();
+#endif
+#ifdef CONFIG_USB_KBD		
+		usb_kbd_init();
+#endif		
+		hub_init();
+#ifdef CONFIG_USB_AUDIO		
+		usb_audio_init();
+#endif		
 #ifdef CONFIG_APM
 		apm_register_callback(&handle_apm_event);
 #endif
+
 		return 0;
 	}
 	return retval;
 }
 
-#ifdef MODULE
-int init_module(void)
-{
-	return uhci_init();
-}
-
-void cleanup_module(void)
+void cleanup_drivers(void)
 {
-#ifdef CONFIG_APM
-	apm_unregister_callback(&handle_apm_event);
+	hub_cleanup();
+#ifdef CONFIG_USB_MOUSE
+	usb_mouse_cleanup();
 #endif
 }
-#endif //MODULE
diff -urN linux-2.2.12-pre1/drivers/usb/uhci-debug.c linux-2.2.12-pre3/drivers/usb/uhci-debug.c
--- linux-2.2.12-pre1/drivers/usb/uhci-debug.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/uhci-debug.c	1999-04-26 12:22:58.000000000 -0700
@@ -12,8 +12,6 @@
 
 void show_td(struct uhci_td * td)
 {
-	char *spid;
-
 	printk("%08x ", td->link);
 	printk("%se%d %s%s%s%s%s%s%s%s%s%sLength=%x ",
 		((td->status >> 29) & 1) ? "SPD " : "",
@@ -29,27 +27,12 @@
 		((td->status >> 18) & 1) ? "CRC/Timeo " : "",
 		((td->status >> 17) & 1) ? "BitStuff " : "",
 		td->status & 0x7ff);
-	switch (td->info & 0xff) {
-	case 0x2d:
-		spid = "SETUP";
-		break;
-	case 0xe1:
-		spid = "OUT";
-		break;
-	case 0x69:
-		spid = "IN";
-		break;
-	default:
-		spid = "?";
-		break;
-	}
-	printk("MaxLen=%x DT%d EndPt=%x Dev=%x, PID=%x(%s) ",
+	printk("MaxLen=%x %sEndPt=%x Dev=%x, PID=%x ",
 		td->info >> 21,
-		 ((td->info >> 19) & 1),
+		 ((td->info >> 19) & 1) ? "DT " : "",
 		 (td->info >> 15) & 15,
 		 (td->info >> 8) & 127,
-		 (td->info & 0xff),
-		 spid);
+		 td->info & 0xff);
 	printk("(buf=%08x)\n", td->buffer);
 }
 
@@ -131,7 +114,7 @@
 #if 0
 	printk("    link = %p, element = %p\n", qh->link, qh->element);
 #endif
-	if(!(qh->element & ~0xF)) {
+	if(!qh->element) {
 		printk("    td 0 = NULL\n");
 		return;
 	}
@@ -147,9 +130,9 @@
 int is_skeleton_qh(struct uhci *uhci, struct uhci_qh *qh)
 {
 	int j;
-	struct uhci_device * root_hub=usb_to_uhci(uhci->bus->root_hub);
+
 	for (j = 0; j < UHCI_MAXQH; j++)
-		if (qh == root_hub->qh + j)
+		if (qh == uhci->root_hub->qh + j)
 			return 1;
 
 	return 0;
@@ -165,16 +148,15 @@
 {
 	int i;
 	struct uhci_qh *qh;
-	struct uhci_device * root_hub=usb_to_uhci(uhci->bus->root_hub);
 
 	for (i = 0; i < UHCI_MAXQH; ++i) {
 		printk("  %s:\n", qh_names[i]);
 #if 0
-		printk("  qh #%d, %p\n", i, virt_to_bus(root_hub->qh + i));
+		printk("  qh #%d, %p\n", i, virt_to_bus(uhci->root_hub->qh + i));
 		show_queue(uhci->root_hub->qh + i);
 #endif
 
-		qh = uhci_link_to_qh(root_hub->qh[i].link);
+		qh = uhci_link_to_qh(uhci->root_hub->qh[i].link);
 		for (; qh; qh = uhci_link_to_qh(qh->link)) {
 			if (is_skeleton_qh(uhci, qh))
 				break;
@@ -183,3 +165,4 @@
 		}
 	}
 }
+
diff -urN linux-2.2.12-pre1/drivers/usb/uhci.h linux-2.2.12-pre3/drivers/usb/uhci.h
--- linux-2.2.12-pre1/drivers/usb/uhci.h	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/uhci.h	1999-04-28 11:14:03.000000000 -0700
@@ -53,8 +53,6 @@
 #define   USBPORTSC_PR		0x0200	/* Port Reset */
 #define   USBPORTSC_SUSP	0x1000	/* Suspend */
 
-#define UHCI_NULL_DATA_SIZE	0x7ff	/* for UHCI controller TD */
-
 struct uhci_qh {
 	unsigned int link;	/* Next queue */
 	unsigned int element;	/* Queue element pointer */
@@ -91,23 +89,10 @@
 	usb_device_irq completed;	/* Completion handler routine */
 	unsigned int *backptr;		/* Where to remove this from.. */
 	void *dev_id;
-	int inuse;			/* Inuse? (b0) Remove (b1)*/
+	int inuse;			/* Inuse? */
 	struct uhci_qh *qh;
-	struct uhci_td *first;
-	struct usb_device *dev;		/* the owning device */
 } __attribute__((aligned(32)));
 
-struct uhci_iso_td {
-	int num;
-	char *data;
-	int maxsze;
-
-	struct uhci_td *td;
-
-	int frame;
-	int endframe;
-};
-
 /*
  * Note the alignment requirements of the entries
  *
@@ -117,7 +102,7 @@
  */
 struct uhci;
 
-#define UHCI_MAXTD	64
+#define UHCI_MAXTD 64
 
 #define UHCI_MAXQH	16
 
@@ -139,11 +124,9 @@
  * The root hub pre-allocated QH's and TD's have
  * some special global uses..
  */
-#if 0
 #define control_td	td		/* Td's 0-30 */
 /* This is only for the root hub's TD list */
 #define tick_td		td[31]
-#endif
 
 /*
  * There are various standard queues. We set up several different
@@ -169,12 +152,12 @@
  * Linus:
  *
  *  generic-iso-QH  ->  dev1-iso-QH  ->  generic-irq-QH  ->  dev1-irq-QH  -> ...
- *       |                  |                  |                   |
- *      End             dev1-iso-TD1          End            dev1-irq-TD1
- *                          |
- *                      dev1-iso-TD2
- *                          |
- *                        ....
+ *       |                       |                  |                   |
+ *      End          dev1-iso-TD1          End            dev1-irq-TD1
+ *                       |
+ *                   dev1-iso-TD2
+ *                       |
+ *                      ....
  *
  * This may vary a bit (the UHCI docs don't explicitly say you can put iso
  * transfers in QH's and all of their pictures don't have that either) but
@@ -228,6 +211,8 @@
 	/* These are "standard" QH's for the entire bus */
 	struct uhci_qh qh[UHCI_MAXQH];
 #endif
+	struct uhci_device *root_hub;		/* Root hub device descriptor.. */
+
 	struct uhci_framelist *fl;		/* Frame list */
 	struct list_head interrupt_list;	/* List of interrupt-active TD's for this uhci */
 };
diff -urN linux-2.2.12-pre1/drivers/usb/usb.c linux-2.2.12-pre3/drivers/usb/usb.c
--- linux-2.2.12-pre1/drivers/usb/usb.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/usb.c	1999-05-07 15:16:04.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- * drivers/usb/usb.c
+ * driver/usb/usb.c
  *
  * (C) Copyright Linus Torvalds 1999
  *
@@ -36,7 +36,6 @@
  * 6		wLength		2	Count		Bytes for data
  */
 
-#include <linux/config.h>
 #include <linux/string.h>
 #include <linux/bitops.h>
 #include <linux/malloc.h>
@@ -47,138 +46,51 @@
  * We have a per-interface "registered driver" list.
  */
 static LIST_HEAD(usb_driver_list);
-static LIST_HEAD(usb_bus_list);
 
 int usb_register(struct usb_driver *new_driver)
 {
-	struct list_head *tmp = usb_bus_list.next;
 	/* Add it to the list of known drivers */
 	list_add(&new_driver->driver_list, &usb_driver_list);
 
 	/*
-         * We go through all existing devices, and see if any of them would
-         * be acceptable to the new driver.. This is done using a depth-first
-         * search for devices without a registered driver already, then 
-	 * running 'probe' with each of the drivers registered on every one 
-	 * of these.
+	 * We should go through all existing devices, and see if any of
+	 * them would be acceptable to the new driver.. Let's do that
+	 * in version 2.0.
 	 */
-        while (tmp!= &usb_bus_list) {
-		struct usb_bus * bus = list_entry(tmp,struct
-			usb_bus,bus_list);
-	        tmp=tmp->next;  
-		usb_check_support(bus->root_hub);
-        }
 	return 0;
 }
 
 void usb_deregister(struct usb_driver *driver)
 {
-      struct list_head *tmp = usb_bus_list.next;
-      /*first we remove the driver, to be sure it doesn't get used by
-       *another thread while we are stepping through removing entries
-       */
 	list_del(&driver->driver_list);
-      printk(KERN_INFO "usbcore: deregistering driver\n");
-      while (tmp!= &usb_bus_list) {
-              struct usb_bus * bus = list_entry(tmp,struct 
-            		usb_bus,bus_list);
-              tmp=tmp->next;
-              usb_driver_purge(driver,bus->root_hub);
-      }
-}
-
-/* This function is part of a depth-first search down the device tree,
- * removing any instances of a device driver.
- */
-void usb_driver_purge(struct usb_driver *driver,struct usb_device *dev)
-{
-       int i;
-       if (dev==NULL){
-               printk(KERN_ERR "null device being passed in!!!\n");
-               return;
-       }
-       for (i=0;i<USB_MAXCHILDREN;i++)
-               if (dev->children[i]!=NULL)
-                       usb_driver_purge(driver,dev->children[i]);
-       /*now we check this device*/
-       if(dev->driver==driver) {
-               /*
-                * Note: this is not the correct way to do this, this
-                * uninitializes and reinitializes EVERY driver
-                */
-               printk(KERN_ERR "disconnecting driverless device\n");
-               dev->driver->disconnect(dev);
-               dev->driver=NULL;
-               /* This will go back through the list looking for a driver
-                * that can handle the device
-		*/
-               usb_device_descriptor(dev);
-      }
-}
-
-/*
- * New functions for (de)registering a controller
- */
-void usb_register_bus(struct usb_bus *new_bus)
-{
-      /* Add it to the list of buses */
-      list_add(&new_bus->bus_list, &usb_bus_list);
-      printk(KERN_DEBUG "New bus registered\n");
-}
-
-void usb_deregister_bus(struct usb_bus *bus)
-{
-        /* NOTE: make sure that all the devices are removed by the
-         * controller code, as well as having it call this when cleaning
-	 * itself up
-         */
-	list_del(&bus->bus_list);
 }
 
 /*
- * This function is for doing a depth-first search for devices which
- * have support, for dynamic loading of driver modules.
- */
-void usb_check_support(struct usb_device *dev)
-{
-      int i;
-      if (dev==NULL)
-      {
-              printk(KERN_ERR "null device being passed in!!!\n");
-              return;
-      }
-      for (i=0;i<USB_MAXCHILDREN;i++)
-              if (dev->children[i]!=NULL)
-                      usb_check_support(dev->children[i]);
-      /*now we check this device*/
-      if (dev->driver==NULL)
-	      usb_device_descriptor(dev);
-}
-/*
  * This entrypoint gets called for each new device.
  *
  * We now walk the list of registered USB drivers,
  * looking for one that will accept this device as
  * his..
  */
-int usb_device_descriptor(struct usb_device *dev)
+void usb_device_descriptor(struct usb_device *dev)
 {
 	struct list_head *tmp = usb_driver_list.next;
 
 	while (tmp != &usb_driver_list) {
-		struct usb_driver *driver = list_entry(tmp, struct usb_driver,
-						       driver_list);
+		struct usb_driver *driver = list_entry(tmp, struct usb_driver, driver_list);
 		tmp = tmp->next;
 		if (driver->probe(dev))
 			continue;
 		dev->driver = driver;
-		return 1;
+		return;
 	}
+
 	/*
 	 * Ok, no driver accepted the device, so show the info
 	 * for debugging..
 	 */
-	return 0;
+	printk("Unknown new USB device:\n");
+	usb_show_device(dev);
 }
 
 /*
@@ -197,8 +109,8 @@
 
 		if (len < descindex)
 			return -1;
-		n_desc = le16_to_cpup((unsigned short *)ptr);
-		n_len = ptr[0];
+		n_desc = *(unsigned short *)ptr;
+		n_len = n_desc & 0xff;
 
 		if (n_desc == ((desctype << 8) + descindex))
 			break;
@@ -206,30 +118,28 @@
 		if (((n_desc >> 8)&0xFF) == desctype &&
 			n_len > descindex)
 		{
-			printk(KERN_DEBUG "bug: oversized descriptor.\n");
+			printk("bug: oversized descriptor.\n");
 			break;
 		}
 			
 		if (n_len < 2 || n_len > len)
 		{
-			printk(KERN_DEBUG "Short descriptor\n");
+			printk("Short descriptor.\n");
 			return -1;
 		}
-		printk(KERN_DEBUG
-		"Expected descriptor %02X/%02X, got %02X/%02X - skipping",
-			desctype, descindex, ptr[1], ptr[0]);
-		for (i = 0; i < n_len; i++) {
-			if (i % 16 == 0)
-				printk("\n" KERN_DEBUG);
-			printk(" %02x", ptr[i]);
-		}
-		printk("\n");
+		printk(
+		"Expected descriptor %02X/%02X, got %02X/%02X - skipping\n",
+			desctype, descindex,
+			(n_desc >> 8) & 0xFF, n_desc & 0xFF);
+		for (i = 0 ; i < n_len; i++)
+			printk("   %d %02x\n", i, ptr[i]);
 		len -= n_len;
 		ptr += n_len;
 		parsed += n_len;
 	}
 	
-	printk(KERN_DEBUG "Found %02X:%02X\n", desctype, descindex);
+	printk("Found %02X:%02X\n",
+		desctype, descindex);
 	return parsed;
 }
 
@@ -242,15 +152,9 @@
 {
 	int n_len = ptr[0];
 
-	if (len <= 0)
-		return -1;
-
 	if (n_len < 2 || n_len > len)
 	{
-		int i;
-		printk(KERN_DEBUG "Short descriptor. (%d, %d):\n", len, n_len);
-		for (i = 0; i < len; ++i)
-			printk(KERN_DEBUG " %d: %x\n", i, ptr[i]);
+		printk("Short descriptor.\n");
 		return -1;
 	}
 
@@ -263,16 +167,15 @@
 
 static int usb_parse_endpoint(struct usb_device *dev, struct usb_endpoint_descriptor *endpoint, unsigned char *ptr, int len)
 {
-	int parsed = usb_expect_descriptor(ptr, len, USB_DT_ENDPOINT, USB_DT_ENDPOINT_SIZE);
+	int parsed = usb_expect_descriptor(ptr, len, USB_DT_ENDPOINT, 7);
 	int i;
 
 	if (parsed < 0)
 		return parsed;
 	memcpy(endpoint, ptr + parsed, ptr[parsed]);
-	le16_to_cpus(&endpoint->wMaxPacketSize);
 
 	parsed += ptr[parsed];
-	len -= parsed;
+	len -= ptr[parsed];
 
 	while((i = usb_check_descriptor(ptr+parsed, len, 0x25))>=0)
 	{
@@ -287,7 +190,7 @@
 static int usb_parse_interface(struct usb_device *dev, struct usb_interface_descriptor *interface, unsigned char *ptr, int len)
 {
 	int i;
-	int parsed = usb_expect_descriptor(ptr, len, USB_DT_INTERFACE, USB_DT_INTERFACE_SIZE);
+	int parsed = usb_expect_descriptor(ptr, len, USB_DT_INTERFACE, 9);
 	int retval;
 
 	if (parsed < 0)
@@ -334,9 +237,7 @@
 
 static int usb_parse_config(struct usb_device *dev, struct usb_config_descriptor *config, unsigned char *ptr, int len)
 {
-	int i, j;
-	int retval;
-	struct usb_alternate_setting *as;
+	int i;
 	int parsed = usb_expect_descriptor(ptr, len, USB_DT_CONFIG, 9);
 
 	if (parsed < 0)
@@ -345,12 +246,6 @@
 	memcpy(config, ptr + parsed, *ptr);
 	len -= *ptr;
 	parsed += *ptr;
-	le16_to_cpus(&config->wTotalLength);
-
-	if (config->MaxPower == 200) {
-		printk(KERN_ERR "bNumInterfaces kludge\n");
-		config->bNumInterfaces += 3;
-	}
 
 	if (config->bNumInterfaces > USB_MAXINTERFACES)
 	{
@@ -359,59 +254,23 @@
 
 	}
 
-	config->altsetting = (struct usb_alternate_setting *)
-	        kmalloc(USB_MAXALTSETTING * sizeof(struct usb_alternate_setting), GFP_KERNEL);
-	if (config->altsetting == NULL) {
-	  printk(KERN_WARNING "usb: out of memory.\n");
-	  return -1;
-	}
-	config->act_altsetting = 0;
-	config->num_altsetting = 1;
-
-	config->altsetting->interface = (struct usb_interface_descriptor *)
+	config->interface = (struct usb_interface_descriptor *)
 		kmalloc(config->bNumInterfaces * sizeof(struct usb_interface_descriptor), GFP_KERNEL);
-	if(config->altsetting->interface==NULL)
+	if(config->interface==NULL)
 	{
 		printk(KERN_WARNING "usb: out of memory.\n");
 		return -1;	
 	}
-	memset(config->altsetting->interface, 
-	       0, config->bNumInterfaces*sizeof(struct usb_interface_descriptor));
+	memset(config->interface, 0, config->bNumInterfaces*sizeof(struct usb_interface_descriptor));
 	
 	for (i = 0; i < config->bNumInterfaces; i++) {
-		retval = usb_parse_interface(dev, config->altsetting->interface + i, ptr + parsed, len);
+		int retval = usb_parse_interface(dev, config->interface + i, ptr + parsed, len);
 		if (retval < 0)
 			return parsed; // HACK
 //			return retval;
 		parsed += retval;
 		len -= retval;
 	}
-
-	printk(KERN_DEBUG "parsed = %d len = %d\n", parsed, len);
-
-	// now parse for additional alternate settings
-	for (j = 1; j < USB_MAXALTSETTING; j++) {
-	  retval = usb_expect_descriptor(ptr + parsed, len, USB_DT_INTERFACE, 9);
-	  if (retval) 
-	    break;
-	  config->num_altsetting++;
-	  as = config->altsetting + j;
-	  as->interface = (struct usb_interface_descriptor *)
-	    kmalloc(config->bNumInterfaces * sizeof(struct usb_interface_descriptor), GFP_KERNEL);
-	  if (as->interface == NULL) {
-	    printk(KERN_WARNING "usb: out of memory.\n");
-	    return -1;
-	  }
-	  memset(as->interface, 0, config->bNumInterfaces * sizeof(struct usb_interface_descriptor));
-	  for (i = 0; i < config->bNumInterfaces; i++) {
-	    retval = usb_parse_interface(dev, as->interface + i, 
-					 ptr + parsed, len);
-	    if (retval < 0)
-	      return parsed;
-	    parsed += retval;
-	    len -= retval;
-	  }
-	}
 	return parsed;
 }
 
@@ -439,58 +298,34 @@
 		if (retval < 0)
 			return retval;
 		ptr += retval;
-		bytes -= retval;
+		bytes += retval;
 	}
-	if (bytes)
-		printk(KERN_WARNING "usb: %d bytes of extra configuration data left\n", bytes);
 	return 0;
 }
 
 void usb_destroy_configuration(struct usb_device *dev)
 {
-	int c, a, i;
+	int c, i;
 	struct usb_config_descriptor *cf;
-	struct usb_alternate_setting *as;
 	struct usb_interface_descriptor *ifp;
 	
 	if(dev->config==NULL)
 		return;
-
-	for(c = 0; c < dev->descriptor.bNumConfigurations; c++)
+	for(c=0;c<dev->descriptor.bNumConfigurations;c++)
 	{
-		cf = &dev->config[c];
-		if (cf->altsetting == NULL)
-		        break;
-		for (a = 0; a < cf->num_altsetting; a++)
+		cf=&dev->config[c];
+		if(cf->interface==NULL)
+			break;
+		for(i=0;i<cf->bNumInterfaces;i++)
 		{
-		        as = &cf->altsetting[a];
-			if (as->interface == NULL)
-			        break;
-			for(i=0;i<cf->bNumInterfaces;i++)
-			{
-			        ifp = &as->interface[i];
-				if(ifp->endpoint==NULL)
-				       break;
-				kfree(ifp->endpoint);
-			}
-			kfree(as->interface);
+			ifp=&cf->interface[i];
+			if(ifp->endpoint==NULL)
+				break;
+			kfree(ifp->endpoint);
 		}
-		kfree(cf->altsetting);
+		kfree(cf->interface);
 	}
 	kfree(dev->config);
-
-	for (i = 1; i < USB_MAXSTRINGS; ++i) {
-		if (dev->stringindex[i]) {
-			kfree(dev->stringindex[i]);
-			dev->stringindex[i] = 0;
-		}
-	}
-#if 0
-	if (dev->stringindex)
-		kfree(dev->stringindex);
-	if (dev->stringtable)
-		kfree(dev->stringtable);
-#endif
 }
 			
 void usb_init_root_hub(struct usb_device *dev)
@@ -511,7 +346,7 @@
 
 		*pdev = NULL;
 
-		printk(KERN_INFO "USB disconnect on device %d\n", dev->devnum);
+		printk("USB disconnect on device %d\n", dev->devnum);
 
 		if(dev->driver) dev->driver->disconnect(dev);
 
@@ -568,8 +403,6 @@
 int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size)
 {
 	devrequest dr;
-	int i = 5;
-	int result;
 
 	dr.requesttype = 0x80;
 	dr.request = USB_REQ_GET_DESCRIPTOR;
@@ -577,38 +410,12 @@
 	dr.index = 0;
 	dr.length = size;
 
-	while (i--) {
-		if (!(result = dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, buf, size))
-		    || result == USB_ST_STALL)
-			break;
-	}
-	return result;
-}
-
-int usb_get_string(struct usb_device *dev, unsigned short langid, unsigned char index, void *buf, int size)
-{
-	devrequest dr;
-
-	dr.requesttype = 0x80;
-	dr.request = USB_REQ_GET_DESCRIPTOR;
-	dr.value = (USB_DT_STRING << 8) + index;
-	dr.index = langid;
-	dr.length = size;
-
 	return dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, buf, size);
 }
 
 int usb_get_device_descriptor(struct usb_device *dev)
 {
-	int ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor,
-				     sizeof(dev->descriptor));
-	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);
-	}
-	return ret;
+	return usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, sizeof(dev->descriptor));
 }
 
 int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size)
@@ -650,19 +457,6 @@
 	return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0);
 }
 
-int usb_get_status (struct usb_device *dev, int type, int target, void *data)
-{
-	devrequest dr;
-
-	dr.requesttype = USB_DIR_IN | type;	/* USB_RECIP_DEVICE, _INTERFACE, or _ENDPOINT */
-	dr.request = USB_REQ_GET_STATUS;
-	dr.value = 0;
-	dr.index = target;
-	dr.length = 2;
-
-	return dev->bus->op->control_msg (dev, usb_rcvctrlpipe (dev,0), &dr, data, 2);
-}
-
 int usb_get_hub_status(struct usb_device *dev, void *data)
 {
 	devrequest dr;
@@ -740,120 +534,19 @@
 	return 0;
 }
 
-static void usb_set_maxpacket(struct usb_device *dev)
-{
-	int i;
-	struct usb_endpoint_descriptor *ep;
-	int act_as = dev->actconfig->act_altsetting;
-	struct usb_alternate_setting *as = dev->actconfig->altsetting + act_as;
-	struct usb_interface_descriptor *ip = as->interface;
-
-	for (i=0; i<dev->actconfig->bNumInterfaces; i++) {
-		if (as->interface[i].bInterfaceNumber == dev->ifnum) {
-			ip = &as->interface[i];
-			break;
-		}
-	}
-	ep = ip->endpoint;
-	for (i=0; i<ip->bNumEndpoints; i++) {
-		dev->epmaxpacket[ep[i].bEndpointAddress & 0x0f] = ep[i].wMaxPacketSize;
-	}
-}
-
-int usb_clear_halt(struct usb_device *dev, int endp)
-{
-	devrequest dr;
-	int result;
-	__u16 status;
-
-    	//if (!usb_endpoint_halted(dev, endp))
-	//	return 0;
-
-	dr.requesttype = USB_RT_ENDPOINT;
-	dr.request = USB_REQ_CLEAR_FEATURE;
-	dr.value = 0;
-	dr.index = endp;
-	dr.length = 0;
-
-	result = dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0);
-
-	/* dont clear if failed */
-	if (result) {
-	    return result;
-	}
-
-#if 1	/* lets be really tough */
-	dr.requesttype = 0x80 | USB_RT_ENDPOINT;
-	dr.request = USB_REQ_GET_STATUS;
-	dr.length = 2;
-	status = 0xffff;
-
-	result = dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, &status, 2);
-
-	if (result) {
-	    return result;
-	}
-	if (status & 1) {
-	    return 1;		/* still halted */
-	}
-#endif
-	usb_endpoint_running(dev, endp & 0x0f);
-
-	/* toggle is reset on clear */
-
-	usb_settoggle(dev, endp & 0x0f, ((endp >> 7) & 1) ^ 1, 0);
-
-	return 0;
-}
-
-int usb_set_interface(struct usb_device *dev, int interface, int alternate)
-{
-	devrequest dr;
-
-	dr.requesttype = 1;
-	dr.request = USB_REQ_SET_INTERFACE;
-	dr.value = alternate;
-	dr.index = interface;
-	dr.length = 0;
-
-	if (dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev, 0), &dr, NULL, 0))
-		return -1;
-
-	dev->ifnum = interface;
-	dev->actconfig->act_altsetting = alternate;
-	usb_set_maxpacket(dev);
-	return 0;
-}
-
 int usb_set_configuration(struct usb_device *dev, int configuration)
 {
 	devrequest dr;
-	int i;
-	struct usb_config_descriptor *cp = NULL;
-	
+
 	dr.requesttype = 0;
 	dr.request = USB_REQ_SET_CONFIGURATION;
 	dr.value = configuration;
 	dr.index = 0;
 	dr.length = 0;
 
-	for (i=0; i<dev->descriptor.bNumConfigurations; i++) {
-		if (dev->config[i].bConfigurationValue == configuration) {
-			cp = &dev->config[i];
-			break;
-		}
-	}
-	if (!cp) {
-		printk(KERN_INFO "usb: selecting invalid configuration %d\n", configuration);
-		return -1;
-	}
 	if (dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev, 0), &dr, NULL, 0))
 		return -1;
 
-	dev->actconfig = cp;
-	dev->toggle[0] = 0;
-	dev->toggle[1] = 0;
-	usb_set_maxpacket(dev);
 	return 0;
 }
 
@@ -876,139 +569,30 @@
 
 int usb_get_configuration(struct usb_device *dev)
 {
-	unsigned int cfgno;
+	unsigned int cfgno,size;
+	unsigned char buffer[400];
 	unsigned char * bufptr;
-	unsigned char * buffer;
-	int parse;
-
-	buffer = (unsigned char *) __get_free_page (GFP_KERNEL);
-	if (!buffer)
-		return -1;
-
-	bufptr = buffer;
-	for (cfgno = 0 ; cfgno < dev->descriptor.bNumConfigurations ; cfgno++) {
-		unsigned int size;
+	
+	bufptr=buffer;
+        for (cfgno=0;cfgno<dev->descriptor.bNumConfigurations;cfgno++) {
   		/* Get the first 8 bytes - guaranteed */
-	  	if (usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bufptr, 8)) {
-			__free_page ((struct page *) buffer);
+	  	if (usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bufptr, 8))
 	    		return -1;
-		}
 
   	  	/* Get the full buffer */
-	  	size = le16_to_cpup((unsigned short *)(bufptr+2));
-	  	if (bufptr+size > buffer+PAGE_SIZE) {
+	  	size = *(unsigned short *)(bufptr+2);
+	  	if (bufptr+size > buffer+sizeof(buffer))
+	  	{
 			printk(KERN_INFO "usb: truncated DT_CONFIG (want %d).\n", size);
-			size = buffer+PAGE_SIZE-bufptr;
+			size = buffer+sizeof(buffer)-bufptr;
 		}
-		if (usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bufptr, size)) {
-			__free_page ((struct page *) buffer);
+		if (usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bufptr, size))
 			return -1;
-		}
 			
 		/* Prepare for next configuration */
-		bufptr += size;
-	}
-	parse = usb_parse_configuration(dev, buffer, bufptr - buffer);
-	__free_page ((struct page *) buffer);
-	return parse;
-}
-
-#if 0
-int usb_get_stringtable(struct usb_device *dev)
-{
-	int i;
-	int maxindex;
-	int langid;
-	unsigned char buffer[256];
-	int totalchars;
-	struct usb_string_descriptor *sd = (struct usb_string_descriptor *)buffer;
-	char *string;
-	__u8 bLengths[USB_MAXSTRINGS+1];
-	int j;
-
-	dev->maxstring = 0;
-	if(usb_get_string(dev, 0, 0, buffer, 2) ||
-	   usb_get_string(dev, 0, 0, buffer, sd->bLength))
-		return -1;
-	/* we are going to assume that the first ID is good */
-	langid = le16_to_cpup(&sd->wData[0]);
-
-	/* whip through and find total length and max index */
-	for (maxindex = 1, totalchars = 0; maxindex<=USB_MAXSTRINGS; maxindex++) {
-		if(usb_get_string(dev, langid, maxindex, buffer, 2))
-			break;
-		totalchars += (sd->bLength - 2)/2 + 1;
-		bLengths[maxindex] = sd->bLength;
-	}
-	if (--maxindex <= 0)
-		return -1;
-
-	/* get space for strings and index */
-	dev->stringindex = kmalloc(sizeof(char *) * (maxindex+1), GFP_KERNEL);
-	if (!dev->stringindex)
-		return -1;
-	dev->stringtable = kmalloc(totalchars, GFP_KERNEL);
-	if (!dev->stringtable) {
-		kfree(dev->stringindex);
-		dev->stringindex = NULL;
-		return -1;
-	}
-
-	/* fill them in */
-	memset(dev->stringindex, 0, sizeof(char *) * (maxindex+1));
-	for (i=1, string = dev->stringtable; i <= maxindex; i++) {
-		if (usb_get_string(dev, langid, i, buffer, bLengths[i]))
-			continue;
-		dev->stringindex[i] = string;
-		for (j=0; j < (bLengths[i] - 2)/2; j++) {
-			*string++ = le16_to_cpup(&sd->wData[j]);
-		}
-		*string++ = '\0';
-	}
-	dev->maxstring = maxindex;
-	return 0;
-}
-#endif
-
-char *usb_string(struct usb_device *dev, int index)
-{
-	int len, i;
-	char *ptr;
-	union {
-		unsigned char buffer[256];
-		struct usb_string_descriptor desc;
-	} u;
-
-	if (index <= 0 || index >= USB_MAXSTRINGS)
-		return 0;
-	if (dev->stringindex[index] != 0)
-		return dev->stringindex[index];
-
-	if (dev->string_langid == 0) {
-		/* read string descriptor 0 */
-		if (usb_get_string(dev, 0, 0, u.buffer, 2) == 0
-		    && u.desc.bLength >= 4
-		    && usb_get_string(dev, 0, 0, u.buffer, 4) == 0)
-			dev->string_langid = le16_to_cpup(&u.desc.wData[0]);
-		dev->string_langid |= 0x10000;	/* so it's non-zero */
+		bufptr+=size;
 	}
-
-	if (usb_get_string(dev, dev->string_langid, index, u.buffer, 2)
-	    || usb_get_string(dev, dev->string_langid, index, u.buffer,
-			      u.desc.bLength))
-		return 0;
-
-	len = u.desc.bLength / 2;	/* includes terminating null */
-	ptr = kmalloc(len, GFP_KERNEL);
-	if (ptr == 0)
-		return 0;
-
-	for (i = 0; i < len - 1; ++i)
-		ptr[i] = le16_to_cpup(&u.desc.wData[i]);
-	ptr[i] = 0;
-
-	dev->stringindex[index] = ptr;
-	return ptr;
+	return usb_parse_configuration(dev, buffer, size);
 }
 
 /*
@@ -1020,34 +604,30 @@
 {
 	int addr, i;
 
-	printk(KERN_INFO "USB new device connect, assigned device number %d\n",
+	printk("USB new device connect, assigned device number %d\n",
 		dev->devnum);
 
 	dev->maxpacketsize = 0;		/* Default to 8 byte max packet size */
-        dev->epmaxpacket[0] = 8;
 
 	addr = dev->devnum;
 	dev->devnum = 0;
 
-#if 1
 	/* Slow devices */
 	for (i = 0; i < 5; i++) {
 		if (!usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, 8))
 			break;
 
-		printk(KERN_ERR "get_descriptor failed, waiting\n");
+		printk("get_descriptor failed, waiting\n");
 		wait_ms(200);
 	}
 	if (i == 5) {
-		printk(KERN_ERR "giving up\n");
+		printk("giving up\n");
 		return;
 	}
-#endif
 
 #if 0
 	printk("maxpacketsize: %d\n", dev->descriptor.bMaxPacketSize0);
 #endif
-	dev->epmaxpacket[0] = dev->descriptor.bMaxPacketSize0;
 	switch (dev->descriptor.bMaxPacketSize0) {
 		case 8: dev->maxpacketsize = 0; break;
 		case 16: dev->maxpacketsize = 1; break;
@@ -1060,98 +640,34 @@
 
 	dev->devnum = addr;
 
-#if 1
 	if (usb_set_address(dev)) {
-		printk(KERN_ERR "Unable to set address\n");
+		printk("Unable to set address\n");
 		/* FIXME: We should disable the port */
 		return;
 	}
-#else
-	usb_set_address(dev);
-#endif
 
 	wait_ms(10);	/* Let the SET_ADDRESS settle */
 
 	if (usb_get_device_descriptor(dev)) {
-		printk(KERN_ERR "Unable to get device descriptor\n");
+		printk("Unable to get device descriptor\n");
 		return;
 	}
 
 	if (usb_get_configuration(dev)) {
-		printk(KERN_ERR "Unable to get configuration\n");
+		printk("Unable to get configuration\n");
 		return;
 	}
 
-	/* usb_get_stringtable(dev); */
-
-	dev->actconfig = dev->config;
-	dev->ifnum = 0;
-	usb_set_maxpacket(dev);
-
-	usb_show_string(dev, "Manufacturer", dev->descriptor.iManufacturer);
-	usb_show_string(dev, "Product", dev->descriptor.iProduct);
-	usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber);
-
 #if 0
 	printk("Vendor: %X\n", dev->descriptor.idVendor);
 	printk("Product: %X\n", dev->descriptor.idProduct);
 #endif
 
-	if (usb_device_descriptor(dev)==0)
-	{
-		/*
-		 * Ok, no driver accepted the device, so show the info for
-		 * debugging
-		 */
-		printk (KERN_WARNING "Unknown new USB device:\n");
-		usb_show_device(dev);
-	}
+	usb_device_descriptor(dev);
 }
 
-void* usb_request_irq(struct usb_device *dev, unsigned int pipe, usb_device_irq handler, int period, void *dev_id)
+int usb_request_irq(struct usb_device *dev, unsigned int pipe, usb_device_irq handler, int period, void *dev_id)
 {
 	return dev->bus->op->request_irq(dev, pipe, handler, period, dev_id);
 }
 
-
-void *usb_allocate_isochronous (struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int maxsze, usb_device_irq completed, void *dev_id)
-{
-	return usb_dev->bus->op->alloc_isoc (usb_dev, pipe, data, len, maxsze, completed, dev_id);
-}
-
-void usb_delete_isochronous (struct usb_device *dev, void *_isodesc)
-{
-	return dev->bus->op->delete_isoc (dev, _isodesc);
-}
-
-int usb_schedule_isochronous (struct usb_device *usb_dev, void *_isodesc, void *_pisodesc)
-{
-	return usb_dev->bus->op->sched_isoc (usb_dev, _isodesc, _pisodesc);
-}
-
-int usb_unschedule_isochronous (struct usb_device *usb_dev, void *_isodesc)
-{
-	return usb_dev->bus->op->unsched_isoc (usb_dev, _isodesc);
-}
-
-int usb_compress_isochronous (struct usb_device *usb_dev, void *_isodesc)
-{
-	return usb_dev->bus->op->compress_isoc (usb_dev, _isodesc);
-}
-
-int usb_release_irq(struct usb_device *dev, void* handle)
-{
-	return dev->bus->op->release_irq(handle);
-}
-
-#ifdef CONFIG_PROC_FS
-struct list_head * usb_driver_get_list (void)
-{
-	return &usb_driver_list;
-}
-
-struct list_head * usb_bus_get_list (void)
-{
-	return &usb_bus_list;
-}
-#endif
diff -urN linux-2.2.12-pre1/drivers/usb/usb-core.c linux-2.2.12-pre3/drivers/usb/usb-core.c
--- linux-2.2.12-pre1/drivers/usb/usb-core.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/usb-core.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,103 +0,0 @@
-/*
- * driver/usb/usb-core.c
- *
- * (C) Copyright David Waite 1999
- * based on code from usb.c, by Linus Torvolds
- *
- * The purpose of this file is to pull any and all generic modular code from
- * usb.c and put it in a separate file. This way usb.c is kept as a generic
- * library, while this file handles starting drivers, etc.
- *
- */
-#include <linux/kernel.h>
-#include <linux/config.h>
-#include <linux/module.h>
-
-#include "inits.h"
-#include "usb.h"
-
-#ifndef CONFIG_USB_MODULE
-#	ifdef CONFIG_USB_UHCI
-		int uhci_init(void);
-#	endif
-#	ifdef CONFIG_USB_OHCI
-		int ohci_init(void);
-#	endif
-#	ifdef CONFIG_USB_OHCI_HCD
-		int ohci_hcd_init(void);
-#	endif
-#endif
-
-
-int usb_init(void)
-{
-#ifndef CONFIG_USB_MODULE
-#	ifdef CONFIG_USB_UHCI
-		uhci_init();
-#	endif
-#	ifdef CONFIG_USB_OHCI
-		ohci_init();
-#	endif
-#	ifdef CONFIG_USB_OHCI_HCD
-		ohci_hcd_init(); 
-#	endif
-#	ifdef CONFIG_USB_MOUSE
-		usb_mouse_init();
-#	endif
-#	ifdef CONFIG_USB_KBD
-		usb_kbd_init();
-#	endif
-#	ifdef CONFIG_USB_AUDIO
-		usb_audio_init();
-#	endif
-#	ifdef CONFIG_USB_ACM
-		usb_acm_init();
-#	endif
-#	ifdef CONFIG_USB_PRINTER
-		usb_printer_init();
-#	endif
-#	ifdef CONFIG_USB_CPIA
-		usb_cpia_init();
-#	endif
-#	ifdef CONFIG_USB_HUB
-		usb_hub_init();
-#	endif
-#	ifdef CONFIG_USB_SCSI
-		usb_scsi_init();
-#	endif
-#endif
-#ifdef CONFIG_USB_PROC
-	proc_usb_init ();
-#endif
-	return 0;
-}
-/*
- *  Clean up when unloading the module
- */
-void cleanup_drivers(void)
-{
-#ifdef CONFIG_USB_PROC
-	proc_usb_cleanup ();
-#endif
-#ifndef MODULE
-#	ifdef CONFIG_USB_HUB
-		usb_hub_cleanup();
-#	endif
-#	ifdef CONFIG_USB_MOUSE
-        	usb_mouse_cleanup();
-#	endif
-#endif
-}
-
-#ifdef MODULE
-int init_module(void)
-{
-	return usb_init();
-}
-void cleanup_module(void)
-{
-	cleanup_drivers();
-}
-#endif
-
-
diff -urN linux-2.2.12-pre1/drivers/usb/usb-debug.c linux-2.2.12-pre3/drivers/usb/usb-debug.c
--- linux-2.2.12-pre1/drivers/usb/usb-debug.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/usb-debug.c	1999-04-21 02:32:59.000000000 -0700
@@ -24,18 +24,11 @@
 
 static void usb_show_config(struct usb_config_descriptor *config)
 {
-  int i, j;
-  struct usb_alternate_setting *as;
+	int i;
 
-  usb_show_config_descriptor(config);
-  for (i = 0; i < config->num_altsetting; i++) {
-    as = config->altsetting + i;
-    if ((as) == NULL)
-      break;
-    printk("\n  Alternate Setting: %d\n", i);
-    for (j = 0 ; j < config->bNumInterfaces; j++)
-      usb_show_interface(as->interface + j);
-  }
+	usb_show_config_descriptor(config);
+	for (i = 0 ; i < config->bNumInterfaces; i++)
+		usb_show_interface(config->interface + i);
 }
 
 void usb_show_device(struct usb_device *dev)
@@ -53,21 +46,12 @@
  */
 void usb_show_device_descriptor(struct usb_device_descriptor *desc)
 {
-	printk("  Length              = %2d%s\n", desc->bLength,
-		desc->bLength == USB_DT_DEVICE_SIZE ? "" : " (!!!)");
-	printk("  DescriptorType      = %02x\n", desc->bDescriptorType);
-
-	printk("  USB version         = %x.%02x\n",
-		desc->bcdUSB >> 8, desc->bcdUSB & 0xff);
-	printk("  Vendor:Product      = %04x:%04x\n",
-		desc->idVendor, desc->idProduct);
-	printk("  MaxPacketSize0      = %d\n", desc->bMaxPacketSize0);
-	printk("  NumConfigurations   = %d\n", desc->bNumConfigurations);
-	printk("  Device version      = %x.%02x\n",
-		desc->bcdDevice >> 8, desc->bcdDevice & 0xff);
+	printk("  USB version %x.%02x\n", desc->bcdUSB >> 8, desc->bcdUSB & 0xff);
+	printk("  Vendor:  %04x\n", desc->idVendor);
+	printk("  Product: %04x\n", desc->idProduct);
+	printk("  Configurations: %d\n", desc->bNumConfigurations);
 
-	printk("  Device Class:SubClass:Protocol = %02x:%02x:%02x\n",
-		desc->bDeviceClass, desc->bDeviceSubClass, desc->bDeviceProtocol);
+	printk("  Device Class: %d\n", desc->bDeviceClass);
 	switch (desc->bDeviceClass) {
 	case 0:
 		printk("    Per-interface classes\n");
@@ -87,7 +71,7 @@
 {
 	printk("Configuration:\n");
 	printk("  bLength             = %4d%s\n", desc->bLength,
-		desc->bLength == USB_DT_CONFIG_SIZE ? "" : " (!!!)");
+		desc->bLength == 9 ? "" : " (!!!)");
 	printk("  bDescriptorType     =   %02x\n", desc->bDescriptorType);
 	printk("  wTotalLength        = %04x\n", desc->wTotalLength);
 	printk("  bNumInterfaces      =   %02x\n", desc->bNumInterfaces);
@@ -101,13 +85,14 @@
 {
 	printk("  Interface:\n");
 	printk("    bLength             = %4d%s\n", desc->bLength,
-		desc->bLength == USB_DT_INTERFACE_SIZE ? "" : " (!!!)");
+		desc->bLength == 9 ? "" : " (!!!)");
 	printk("    bDescriptorType     =   %02x\n", desc->bDescriptorType);
 	printk("    bInterfaceNumber    =   %02x\n", desc->bInterfaceNumber);
 	printk("    bAlternateSetting   =   %02x\n", desc->bAlternateSetting);
 	printk("    bNumEndpoints       =   %02x\n", desc->bNumEndpoints);
-	printk("    bInterface Class:SubClass:Protocol =   %02x:%02x:%02x\n",
-		desc->bInterfaceClass, desc->bInterfaceSubClass, desc->bInterfaceProtocol);
+	printk("    bInterfaceClass     =   %02x\n", desc->bInterfaceClass);
+	printk("    bInterfaceSubClass  =   %02x\n", desc->bInterfaceSubClass);
+	printk("    bInterfaceProtocol  =   %02x\n", desc->bInterfaceProtocol);
 	printk("    iInterface          =   %02x\n", desc->iInterface);
 }
 
@@ -116,7 +101,7 @@
 	char *EndpointType[4] = { "Control", "Isochronous", "Bulk", "Interrupt" };
 	printk("    Endpoint:\n");
 	printk("      bLength             = %4d%s\n", desc->bLength,
-		desc->bLength == USB_DT_ENDPOINT_SIZE ? "" : " (!!!)");
+		desc->bLength == 7 ? "" : " (!!!)");
 	printk("      bDescriptorType     =   %02x\n", desc->bDescriptorType);
 	printk("      bEndpointAddress    =   %02x (%s)\n", desc->bEndpointAddress,
 		(desc->bEndpointAddress & 0x80) ? "in" : "out");
@@ -139,10 +124,4 @@
 	printk("\n");
 }
 
-void usb_show_string(struct usb_device* dev, char *id, int index)
-{
-	char *p = usb_string(dev, index);
 
-	if (p != 0)
-		printk(KERN_INFO "%s: %s\n", id, p);
-}
diff -urN linux-2.2.12-pre1/drivers/usb/usb.h linux-2.2.12-pre3/drivers/usb/usb.h
--- linux-2.2.12-pre1/drivers/usb/usb.h	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/usb.h	1999-05-11 10:04:03.000000000 -0700
@@ -6,24 +6,6 @@
 #include <linux/list.h>
 #include <linux/sched.h>
 
-#include <linux/version.h>
-#if LINUX_VERSION_CODE < 0x020300
-#define DECLARE_WAIT_QUEUE_HEAD(w)	struct wait_queue *w = NULL
-#define DECLARE_WAITQUEUE(w,c)		struct wait_queue w = {(c), NULL}
-#define wait_queue_head_t		struct wait_queue *
-#define init_waitqueue_head(w)		*(w) = 0
-#define DECLARE_MUTEX_LOCKED(sem)	struct semaphore sem = MUTEX_LOCKED
-#endif
-
-extern int usb_hub_init(void);
-extern int usb_kbd_init(void);
-extern int usb_cpia_init(void);
-extern int usb_mouse_init(void);
-extern int usb_printer_init(void);
-
-extern void hub_cleanup(void);
-extern void usb_mouse_cleanup(void);
-
 static __inline__ void wait_ms(unsigned int ms)
 {
         current->state = TASK_UNINTERRUPTIBLE;
@@ -40,16 +22,9 @@
 } devrequest;
 
 /*
- * Device and/or Interface Class codes
+ * Class codes
  */
-#define USB_CLASS_PER_INTERFACE		0	/* for DeviceClass */
-#define USB_CLASS_AUDIO			1
-#define USB_CLASS_COMM			2
-#define USB_CLASS_HID			3
-#define USB_CLASS_PRINTER		7
-#define USB_CLASS_MASS_STORAGE		8
 #define USB_CLASS_HUB			9
-#define USB_CLASS_VENDOR_SPEC		0xff
 
 /*
  * Descriptor types
@@ -64,28 +39,6 @@
 #define USB_DT_HID			0x21
 
 /*
- * Descriptor sizes per descriptor type
- */
-#define USB_DT_DEVICE_SIZE		18
-#define USB_DT_CONFIG_SIZE		9
-#define USB_DT_INTERFACE_SIZE		9
-#define USB_DT_ENDPOINT_SIZE		7
-#define USB_DT_HUB_NONVAR_SIZE		7
-
-/*
- * USB Request Type and Endpoint Directions
- */
-#define USB_DIR_OUT			0
-#define USB_DIR_IN			0x80
-
-/*
- * USB Packet IDs (PIDs)
- */
-#define USB_PID_OUT			0xe1
-#define USB_PID_IN			0x69
-#define USB_PID_SETUP			0x2d
-
-/*
  * Standard requests
  */
 #define USB_REQ_GET_STATUS		0x00
@@ -134,32 +87,6 @@
 
 #define USB_RT_HIDD			(USB_TYPE_CLASS | USB_RECIP_INTERFACE)
 
-/* 
- * Status codes (these follow an OHCI controllers condition codes)
- */
-#define USB_ST_NOERROR		0x0
-#define USB_ST_CRC		0x1
-#define USB_ST_BITSTUFF		0x2
-#define USB_ST_DTMISMATCH	0x3	/* data toggle mismatch */
-#define USB_ST_STALL		0x4
-#define USB_ST_NORESPONSE	0x5	/* device not responding/handshaking */
-#define USB_ST_PIDCHECK		0x6	/* Check bits on PID failed */
-#define USB_ST_PIDUNDEF		0x7	/* PID unexpected/undefined */
-#define USB_ST_DATAOVERRUN	0x8
-#define USB_ST_DATAUNDERRUN	0x9
-#define USB_ST_RESERVED1	0xA
-#define USB_ST_RESERVED2	0xB
-#define USB_ST_BUFFEROVERRUN	0xC
-#define USB_ST_BUFFERUNDERRUN	0xD
-#define USB_ST_RESERVED3	0xE
-#define USB_ST_RESERVED4	0xF
-
-/* internal errors */
-#define USB_ST_REMOVED		0x100
-#define USB_ST_TIMEOUT		0x110
-#define USB_ST_INTERNALERROR	-1
-#define USB_ST_NOTSUPPORTED	-2
-
 /*
  * USB device number allocation bitmap. There's one bitmap
  * per USB tree.
@@ -176,10 +103,8 @@
  */
 
 #define USB_MAXCONFIG		8
-#define USB_MAXALTSETTING       5
 #define USB_MAXINTERFACES	32
 #define USB_MAXENDPOINTS	32
-#define USB_MAXSTRINGS		32
 
 struct usb_device_descriptor {
 	__u8  bLength;
@@ -225,11 +150,6 @@
 	void  *audio;
 };
 
-/* hack for alternate settings */
-struct usb_alternate_setting {
-        struct usb_interface_descriptor *interface;
-};
-
 /* Configuration descriptor information.. */
 struct usb_config_descriptor {
 	__u8  bLength;
@@ -240,16 +160,14 @@
 	__u8  iConfiguration;
 	__u8  bmAttributes;
 	__u8  MaxPower;
-        int act_altsetting;                /* active alternate setting */
-        int num_altsetting;                /* number of alternate settings */
-	struct usb_alternate_setting *altsetting;
+
+	struct usb_interface_descriptor *interface;
 };
 
 /* String descriptor */
 struct usb_string_descriptor {
 	__u8  bLength;
 	__u8  bDescriptorType;
-	__u16 wData[1];
 };
 
 /* Hub descriptor */
@@ -257,7 +175,7 @@
 	__u8  bLength;
 	__u8  bDescriptorType;
 	__u8  bNbrPorts;
-	__u8  wHubCharacteristics[2];	/* __u16 but not aligned! */
+	__u16 wHubCharacteristics;
 	__u8  bPwrOn2PwrGood;
 	__u8  bHubContrCurrent;
 	/* DeviceRemovable and PortPwrCtrlMask want to be variable-length 
@@ -282,28 +200,16 @@
  *         until we come up with a common meaning.
  *     void *buffer - This is a pointer to the data used in this
  *         USB transfer.
- *     int length - This is the number of bytes transferred in or out
- *         of the buffer by this transfer.  (-1 = unknown/unsupported)
  *     void *dev_id - This is a user defined pointer set when the IRQ
  *         is requested that is passed back.
- *
- *   Special Cases:
- *     if (status == USB_ST_REMOVED), don't trust buffer or len.
  */
-typedef int (*usb_device_irq)(int, void *, int, void *);
+typedef int (*usb_device_irq)(int, void *, void *);
 
 struct usb_operations {
 	struct usb_device *(*allocate)(struct usb_device *);
 	int (*deallocate)(struct usb_device *);
-	int (*control_msg)(struct usb_device *, unsigned int, devrequest *, void *, int);
-	int (*bulk_msg)(struct usb_device *, unsigned int, void *, int,unsigned long *);
-	void* (*request_irq)(struct usb_device *, unsigned int, usb_device_irq, int, void *);
-	int (*release_irq)(void* handle);
-	void *(*alloc_isoc)(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int maxsze, usb_device_irq completed, void *dev_id);
-	void (*delete_isoc)(struct usb_device *dev, void *_isodesc);
-	int (*sched_isoc)(struct usb_device *usb_dev, void *_isodesc, void *_pisodesc);
-	int (*unsched_isoc)(struct usb_device *usb_dev, void *_isodesc);
-	int (*compress_isoc)(struct usb_device *usb_dev, void *_isodesc);
+	int (*control_msg)(struct usb_device *, unsigned int, void *, void *, int);
+	int (*request_irq)(struct usb_device *, unsigned int, usb_device_irq, int, void *);
 };
 
 /*
@@ -313,7 +219,6 @@
 	struct usb_devmap devmap;       /* Device map */
 	struct usb_operations *op;      /* Operations (specific to the HC) */
 	struct usb_device *root_hub;    /* Root hub */
-	struct list_head bus_list;
 	void *hcpriv;                   /* Host Controller private data */
 };
 
@@ -321,28 +226,22 @@
 #define USB_MAXCHILDREN (8)
 
 struct usb_device {
-	int devnum;			/* Device number on USB bus */
-	int slow;			/* Slow device? */
-	int maxpacketsize;		/* Maximum packet size; encoded as 0,1,2,3 = 8,16,32,64 */
-	unsigned int toggle[2];		/* one bit for each endpoint ([0] = IN, [1] = OUT) */
-	unsigned int halted;		/* endpoint halts */
-	struct usb_config_descriptor *actconfig;/* the active configuration */
-	int epmaxpacket[16];		/* endpoint specific maximums */
-	int ifnum;			/* active interface number */
-	struct usb_bus *bus;		/* Bus we're apart of */
-	struct usb_driver *driver;	/* Driver */
-	struct usb_device_descriptor descriptor;/* Descriptor */
-	struct usb_config_descriptor *config;	/* All of the configs */
+	int devnum;						/* Device number on USB bus */
+	int slow;						/* Slow device? */
+	int maxpacketsize;					/* Maximum packet size */
+
+	struct usb_bus *bus;					/* Bus we're apart of */
+	struct usb_driver *driver;				/* Driver */
+	struct usb_device_descriptor descriptor;		/* Descriptor */
+	struct usb_config_descriptor *config;			/* All of the configs */
 	struct usb_device *parent;
-	char *stringindex[USB_MAXSTRINGS];	/* pointers to strings */
-	int string_langid;		/* language ID for strings */
   
 	/*
 	 * Child devices - these can be either new devices
 	 * (if this is a hub device), or different instances
 	 * of this same device.
 	 *
-	 * Each instance needs its own set of data structures.
+	 * Each instance needs its own set of data structuctures.
 	 */
 
 	int maxchild;			/* Number of ports if hub */
@@ -355,28 +254,14 @@
 extern int usb_register(struct usb_driver *);
 extern void usb_deregister(struct usb_driver *);
 
-extern void usb_register_bus(struct usb_bus *);
-extern void usb_deregister_bus(struct usb_bus *);
-
-extern void* usb_request_irq(struct usb_device *, unsigned int, usb_device_irq, int, void *);
-extern int usb_release_irq(struct usb_device *dev, void *handle);
+extern int usb_request_irq(struct usb_device *, unsigned int, usb_device_irq, int, void *);
 
 extern void usb_init_root_hub(struct usb_device *dev);
 extern void usb_connect(struct usb_device *dev);
 extern void usb_disconnect(struct usb_device **);
+extern void usb_device_descriptor(struct usb_device *dev);
 
-extern int usb_device_descriptor(struct usb_device *dev);
-void usb_check_support(struct usb_device *);
-void usb_driver_purge(struct usb_driver *,struct usb_device *);
 extern int  usb_parse_configuration(struct usb_device *dev, void *buf, int len);
-extern void usb_destroy_configuration(struct usb_device *dev);
-
-extern void *usb_allocate_isochronous (struct usb_device *usb_dev, unsigned int pipe, void *data, int len,
-					int maxsze, usb_device_irq completed, void *dev_id);
-extern void usb_delete_isochronous (struct usb_device *dev, void *_isodesc);
-extern int usb_schedule_isochronous (struct usb_device *usb_dev, void *_isodesc, void *_pisodesc);
-extern int usb_unschedule_isochronous (struct usb_device *usb_dev, void *_isodesc);
-extern int usb_compress_isochronous (struct usb_device *usb_dev, void *_isodesc);
 
 /*
  * Calling this entity a "pipe" is glorifying it. A USB pipe
@@ -397,47 +282,36 @@
  * Let's not fall in that trap. We'll just encode it as a simple
  * unsigned int. The encoding is:
  *
- *  - max size:		bits 0-1	(00 = 8, 01 = 16, 10 = 32, 11 = 64)
- *  - direction:	bit 7		(0 = Host-to-Device, 1 = Device-to-Host)
  *  - device:		bits 8-14
  *  - endpoint:		bits 15-18
  *  - Data0/1:		bit 19
- *  - speed:		bit 26		(0 = Full, 1 = Low Speed)
+ *  - direction:	bit 7		(0 = Host-to-Device, 1 = Device-to-Host)
+ *  - speed:		bit 26		(0 = High, 1 = Low Speed)
+ *  - max size:		bits 0-1	(00 = 8, 01 = 16, 10 = 32, 11 = 64)
  *  - pipe type:	bits 30-31	(00 = isochronous, 01 = interrupt, 10 = control, 11 = bulk)
  *
  * Why? Because it's arbitrary, and whatever encoding we select is really
- * up to us. This one happens to share a lot of bit positions with the UHCI
+ * up to us. This one happens to share a lot of bit positions with the UCHI
  * specification, so that much of the uhci driver can just mask the bits
  * appropriately.
  */
 
-#define usb_maxpacket(dev,pipe)	((dev)->epmaxpacket[usb_pipeendpoint(pipe)])
+#define usb_maxpacket(pipe)	(8 << ((pipe) & 3))
 #define usb_packetid(pipe)	(((pipe) & 0x80) ? 0x69 : 0xE1)
 
-#define usb_pipeout(pipe)	((((pipe) >> 7) & 1) ^ 1)
-#define usb_pipein(pipe)	(((pipe) >> 7) & 1)
 #define usb_pipedevice(pipe)	(((pipe) >> 8) & 0x7f)
-#define usb_pipe_endpdev(pipe)	(((pipe) >> 8) & 0x7ff)
 #define usb_pipeendpoint(pipe)	(((pipe) >> 15) & 0xf)
 #define usb_pipedata(pipe)	(((pipe) >> 19) & 1)
+#define usb_pipeout(pipe)	(((pipe) & 0x80) == 0)
 #define usb_pipeslow(pipe)	(((pipe) >> 26) & 1)
+
 #define usb_pipetype(pipe)	(((pipe) >> 30) & 3)
 #define usb_pipeisoc(pipe)	(usb_pipetype((pipe)) == 0)
 #define usb_pipeint(pipe)	(usb_pipetype((pipe)) == 1)
 #define usb_pipecontrol(pipe)	(usb_pipetype((pipe)) == 2)
 #define usb_pipebulk(pipe)	(usb_pipetype((pipe)) == 3)
 
-#define PIPE_DEVEP_MASK		0x0007ff00
-
-/* The D0/D1 toggle bits */
-#define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> ep) & 1)
-#define	usb_dotoggle(dev, ep, out)  ((dev)->toggle[out] ^= (1 << ep))
-#define usb_settoggle(dev, ep, out, bit) ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << ep)) | ((bit) << ep))
-
-/* Endpoint halt */
-#define usb_endpoint_halt(dev, ep) ((dev)->halted |= (1 << (ep)))
-#define usb_endpoint_running(dev, ep) ((dev)->halted &= ~(1 << (ep)))
-#define usb_endpoint_halted(dev, ep) ((dev)->halted & (1 << (ep)))
+#define usb_pipe_endpdev(pipe)	(((pipe) >> 8) & 0x7ff)
 
 static inline unsigned int __create_pipe(struct usb_device *dev, unsigned int endpoint)
 {
@@ -449,16 +323,14 @@
 	return (dev->slow << 26);
 }
 
-/* Create various pipes... */
+/* Create control pipes.. */
 #define usb_sndctrlpipe(dev,endpoint)	((2 << 30) | __create_pipe(dev,endpoint))
 #define usb_rcvctrlpipe(dev,endpoint)	((2 << 30) | __create_pipe(dev,endpoint) | 0x80)
-#define usb_sndisocpipe(dev,endpoint)	((0 << 30) | __create_pipe(dev,endpoint))
-#define usb_rcvisocpipe(dev,endpoint)	((0 << 30) | __create_pipe(dev,endpoint) | 0x80)
-#define usb_sndbulkpipe(dev,endpoint)	((3 << 30) | __create_pipe(dev,endpoint))
-#define usb_rcvbulkpipe(dev,endpoint)	((3 << 30) | __create_pipe(dev,endpoint) | 0x80)
 #define usb_snddefctrl(dev)		((2 << 30) | __default_pipe(dev))
 #define usb_rcvdefctrl(dev)		((2 << 30) | __default_pipe(dev) | 0x80)
 
+/* Create .. */
+
 /*
  * Send and receive control messages..
  */
@@ -470,18 +342,13 @@
 int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size);
 int usb_clear_port_feature(struct usb_device *dev, int port, int feature);
 int usb_set_port_feature(struct usb_device *dev, int port, int feature);
-int usb_get_status (struct usb_device *dev, int type, int target, void *data);
 int usb_get_hub_status(struct usb_device *dev, void *data);
 int usb_get_port_status(struct usb_device *dev, int port, void *data);
 int usb_get_protocol(struct usb_device *dev);
 int usb_set_protocol(struct usb_device *dev, int protocol);
-int usb_set_interface(struct usb_device *dev, int interface, int alternate);
 int usb_set_idle(struct usb_device *dev, int duration, int report_id);
-int usb_set_interface(struct usb_device *dev, int interface, int alternate);
 int usb_set_configuration(struct usb_device *dev, int configuration);
 int usb_get_report(struct usb_device *dev);
-char *usb_string(struct usb_device *dev, int index);
-int usb_clear_halt(struct usb_device *dev, int endp);
 
 /*
  * Debugging helpers..
@@ -492,7 +359,6 @@
 void usb_show_endpoint_descriptor(struct usb_endpoint_descriptor *);
 void usb_show_hub_descriptor(struct usb_hub_descriptor *);
 void usb_show_device(struct usb_device *);
-void usb_show_string(struct usb_device* dev, char *id, int index);
 
 /*
  * Audio parsing helpers
diff -urN linux-2.2.12-pre1/drivers/usb/usb_scsi.c linux-2.2.12-pre3/drivers/usb/usb_scsi.c
--- linux-2.2.12-pre1/drivers/usb/usb_scsi.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/usb_scsi.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1453 +0,0 @@
-
-/* Driver for USB scsi like devices
- * 
- * (C) Michael Gee (michael@linuxspecific.com) 1999
- *
- * This driver is scitzoid  - it makes a USB device appear as both a SCSI device
- * and a character device. The latter is only available if the device has an
- * interrupt endpoint, and is used specifically to receive interrupt events.
- *
- * In order to support various 'strange' devices, this module supports plug in
- * device specific filter modules, which can do their own thing when required.
- *
- * Further reference.
- *	This driver is based on the 'USB Mass Storage Class' document. This
- *	describes in detail the transformation of SCSI command blocks to the
- *	equivalent USB control and data transfer required.
- *	It is important to note that in a number of cases this class exhibits
- *	class-specific exemptions from the USB specification. Notably the
- *	usage of NAK, STALL and ACK differs from the norm, in that they are
- *	used to communicate wait, failed and OK on SCSI commands.
- *	Also, for certain devices, the interrupt endpoint is used to convey
- *	status of a command.
- *
- *	Basically, this stuff is WIERD!!
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/errno.h>
-#include <linux/miscdevice.h>
-#include <linux/random.h>
-#include <linux/poll.h>
-#include <linux/init.h>
-#include <linux/malloc.h>
-
-#include <asm/spinlock.h>
-#include <linux/smp_lock.h>
-
-#include <linux/blk.h>
-#include "../scsi/scsi.h"
-#include "../scsi/hosts.h"
-#include "../scsi/sd.h"
-
-#include "usb.h"
-#include "usb_scsi.h"
-
-/* direction table (what a pain) */
-
-unsigned char us_direction[256/8] = {
-
-#include "usb_scsi_dt.c"
-
-};
-
-/*
- * Per device data
- */
-
-static int my_host_number;
-
-int usbscsi_debug = 1;
-
-struct us_data {
-	struct us_data	*next;			/* next device */
-	struct usb_device 	*pusb_dev;
-	struct usb_scsi_filter  *filter;		/* filter driver */
-	void 			*fdata;			/* filter data */
-	unsigned int		flags;			/* from filter initially*/
-	__u8			ep_in;			/* in endpoint */
-	__u8			ep_out;			/* out ....... */
-	__u8			ep_int;			/* interrupt . */
-	__u8			subclass;		/* as in overview */
-	__u8			protocol;		/* .............. */
-	__u8			attention_done;		/* force attention on first command */
-	int (*pop)(Scsi_Cmnd *);			/* protocol specific do cmd */
-	int (*pop_reset)(struct us_data *);		/* ................. device reset */
-	GUID(guid);					/* unique dev id */
-	struct Scsi_Host	*host;			/* our dummy host data */
-	Scsi_Host_Template	*htmplt;		/* own host template */
-	int			host_number;		/* to find us */
-	int			host_no;		/* allocated by scsi */
-	int			fixedlength;		/* expand commands */
-	Scsi_Cmnd		*srb;			/* current srb */
-	int			action;			/* what to do */
-	wait_queue_head_t	waitq;			/* thread waits */
-	wait_queue_head_t	ip_waitq;		/* for CBI interrupts */
-	__u16			ip_data;		/* interrupt data */
-	int			ip_wanted;		/* needed */
-	int			pid;			/* control thread */
-	struct semaphore      	*notify; 		/* wait for thread to begin */
-};
-
-/*
- * kernel thread actions
- */
-
-#define US_ACT_COMMAND		1
-#define US_ACT_ABORT		2
-#define US_ACT_DEVICE_RESET	3
-#define US_ACT_BUS_RESET	4
-#define US_ACT_HOST_RESET	5
-
-static struct proc_dir_entry proc_usb_scsi =
-{
-    PROC_SCSI_USB_SCSI,
-    0,
-    NULL,
-    S_IFDIR | S_IRUGO | S_IXUGO,
-    2
-};
-
-static struct us_data *us_list;
-
-static struct usb_scsi_filter *filters;
-
-static int scsi_probe(struct usb_device *dev);
-static void scsi_disconnect(struct usb_device *dev);
-static struct usb_driver scsi_driver = {
-	"usb_scsi",
-	scsi_probe,
-	scsi_disconnect,
-	{ NULL, NULL }
-};
-
-/* Data handling, using SG if required */
-
-static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length)
-{
-    int max_size = usb_maxpacket(us->pusb_dev, pipe) * 16;
-    int this_xfer;
-    int result;
-    unsigned long partial;
-    int maxtry = 100;
-    while (length) {
-	this_xfer = length > max_size ? max_size : length;
-	length -= this_xfer;
-	do {
-	    /*US_DEBUGP("Bulk xfer %x(%d)\n", (unsigned int)buf, this_xfer);*/
-	    result = us->pusb_dev->bus->op->bulk_msg(us->pusb_dev, pipe, buf, 
-						    this_xfer, &partial);
-
-	    if (result != 0 || partial != this_xfer)
-		US_DEBUGP("bulk_msg returned %d xferred %lu/%d\n",
-			  result, partial, this_xfer);
-
-	    if (result == USB_ST_STALL) {
-		US_DEBUGP("clearing endpoing halt for pipe %x\n", pipe);
-		usb_clear_halt(us->pusb_dev,
-			       usb_pipeendpoint(pipe) | (pipe & 0x80));
-	    }
-
-	    /* we want to retry if the device reported NAK */
-	    if (result == USB_ST_TIMEOUT) {
-		if (partial != this_xfer) {
-		    return 0;	/* I do not like this */
-		}
-		if (!maxtry--)
-		    break;
-		this_xfer -= partial;
-		buf += partial;
-	    } else if (!result && partial != this_xfer) {
-		/* short data - assume end */
-		result = USB_ST_DATAUNDERRUN;
-		break;
-	    } else if (result == USB_ST_STALL && us->protocol == US_PR_CB) {
-		if (!maxtry--)
-		    break;
-		this_xfer -= partial;
-		buf += partial;
-	    } else
-		break;
-	} while ( this_xfer );
-	if (result)
-	    return result;
-	buf += this_xfer;
-    }
-    return 0;
-
-}
-
-static int us_transfer(Scsi_Cmnd *srb, int dir_in)
-{
-    struct us_data *us = (struct us_data *)srb->host_scribble;
-    int i;
-    int result = -1;
-    unsigned int pipe = dir_in ? usb_rcvbulkpipe(us->pusb_dev, us->ep_in) :
-	    usb_sndbulkpipe(us->pusb_dev, us->ep_out);
-
-    if (srb->use_sg) {
-	struct scatterlist *sg = (struct scatterlist *) srb->request_buffer;
-
-	for (i = 0; i < srb->use_sg; i++) {
-	    result = us_one_transfer(us, pipe, sg[i].address, sg[i].length);
-	    if (result)
-		break;
-	}
-    }
-    else
-	result = us_one_transfer(us, pipe,
-				 srb->request_buffer, srb->request_bufflen);
-
-    if (result)
-	US_DEBUGP("us_transfer returning error %d\n", result);
-    return result;
-}
-
-static unsigned int us_transfer_length(Scsi_Cmnd *srb)
-{
-    int i;
-    unsigned int total = 0;
-
-    /* always zero for some commands */
-    switch (srb->cmnd[0]) {
-    case SEEK_6:
-    case SEEK_10:
-    case REZERO_UNIT:
-    case ALLOW_MEDIUM_REMOVAL:
-    case START_STOP:
-    case TEST_UNIT_READY:
-	return 0;
-
-    default:
-	break;
-    }
-
-    if (srb->use_sg) {
-	struct scatterlist *sg = (struct scatterlist *) srb->request_buffer;
-
-	for (i = 0; i < srb->use_sg; i++) {
-	    total += sg[i].length;
-	}
-	return total;
-    }
-    else
-	return srb->request_bufflen;
-
-}
-
-static int pop_CBI_irq(int state, void *buffer, int len, void *dev_id)
-{
-    struct us_data *us = (struct us_data *)dev_id;
-
-    if (state != USB_ST_REMOVED) {
-	us->ip_data = le16_to_cpup((__u16 *)buffer);
-	if (us->ip_data != 0)
-	    US_DEBUGP("Interrupt Status %x\n", us->ip_data);
-    }
-    if (us->ip_wanted) {
-	us->ip_wanted = 0;
-	wake_up(&us->ip_waitq);
-    }
-
-    /* we dont want another interrupt */
-
-    return 0;
-}
-
-static int pop_CB_reset(struct us_data *us)
-{
-    unsigned char cmd[12];
-    devrequest dr;
-
-    US_DEBUGP("pop_CB_reset\n");
-    dr.requesttype = USB_TYPE_CLASS | USB_RT_INTERFACE;
-    dr.request = US_CBI_ADSC;
-    dr.value = 0;
-    dr.index = us->pusb_dev->ifnum;
-    dr.length = 12;
-    memset(cmd, -1, sizeof(cmd));
-    cmd[0] = SEND_DIAGNOSTIC;
-    cmd[1] = 4;
-    us->pusb_dev->bus->op->control_msg(us->pusb_dev, 
-					usb_sndctrlpipe(us->pusb_dev,0),
-					&dr, cmd, 12);
-
-    /* long wait for reset */
-
-    schedule_timeout(HZ*5);
-
-    US_DEBUGP("pop_CB_reset: clearing endpoint halt\n");
-    usb_clear_halt(us->pusb_dev, us->ep_in | 0x80);
-    usb_clear_halt(us->pusb_dev, us->ep_out);
-
-    US_DEBUGP("pop_CB_reset done\n");
-    return 0;
-}
-
-static int pop_CB_command(Scsi_Cmnd *srb, unsigned char *cmnd, int cmd_len)
-{
-    struct us_data *us = (struct us_data *)srb->host_scribble;
-    devrequest dr;
-    int result;
-    int retry = 5;
-    int done_start = 0;
-
-    while (retry--) {
-	dr.requesttype = USB_TYPE_CLASS | USB_RT_INTERFACE;
-	dr.request = US_CBI_ADSC;
-	dr.value = 0;
-	dr.index = us->pusb_dev->ifnum;
-	dr.length = cmd_len;
-
-	result = us->pusb_dev->bus->op->control_msg(us->pusb_dev, 
-					usb_sndctrlpipe(us->pusb_dev,0),
-					&dr, cmnd, cmd_len);
-
-	if (result && !done_start && (us->flags & US_FL_FIXED_COMMAND)
-	    && cmnd[0] == TEST_UNIT_READY
-	    && (us->subclass == US_SC_UFI /*|| us->subclass == US_SC_8070*/)) {
-	    /* as per spec try a start command, wait and retry */
-
-	    done_start++;
-	    cmnd[0] = START_STOP;
-	    cmnd[4] = 1;		/* start */
-	    result = us->pusb_dev->bus->op->control_msg(us->pusb_dev, 
-					usb_sndctrlpipe(us->pusb_dev,0),
-					&dr, cmnd, cmd_len);
-	    wait_ms(100);
-	    retry++;
-	    cmnd[0] = TEST_UNIT_READY;
-	    cmnd[4] = 0;
-	    continue;
-	}
-	if (result != USB_ST_TIMEOUT)
-	    break;
-    }
-    return result;
-}
-
-/*
- * Control/Bulk status handler
- */
-
-static int pop_CB_status(Scsi_Cmnd *srb)
-{
-    struct us_data *us = (struct us_data *)srb->host_scribble;
-    int result;
-    __u8 status[2];
-    devrequest dr;
-    int retry = 5;
-    void *irq_handle;
-
-    switch (us->protocol) {
-    case US_PR_CB:
-	/* get from control */
-
-	while (retry--) {
-	    dr.requesttype = 0x80 | USB_TYPE_STANDARD | USB_RT_DEVICE;
-	    dr.request = USB_REQ_GET_STATUS;
-	    dr.index = 0;
-	    dr.value = 0;
-	    dr.length = 2;
-	    result = us->pusb_dev->bus->op->control_msg(us->pusb_dev, 
-						  usb_rcvctrlpipe(us->pusb_dev,0),
-						  &dr, status, sizeof(status));
-	    if (result != USB_ST_TIMEOUT)
-		break;
-	}
-	if (result) {
-	    US_DEBUGP("Bad AP status request %d\n", result);
-	    return DID_ABORT << 16;
-	}
-	US_DEBUGP("Got AP status %x %x\n", status[0], status[1]);
-	if (srb->cmnd[0] != REQUEST_SENSE && srb->cmnd[0] != INQUIRY && 
-	    ( (status[0] & ~3) || status[1]))
-	    return (DID_OK << 16) | 2;
-	else
-	    return DID_OK << 16;
-	break;
-
-    case US_PR_CBI:
-	/* get from interrupt pipe */
-
-	/* add interrupt transfer, marked for removal */
-	us->ip_wanted = 1;
-	irq_handle = us->pusb_dev->bus->op->request_irq
-		(us->pusb_dev, usb_rcvctrlpipe(us->pusb_dev, us->ep_int),
-		 pop_CBI_irq, 0, (void *)us);
-	if (irq_handle == 0) {
-	    US_DEBUGP("No interrupt for CBI %x\n", result);
-	    return DID_ABORT << 16;
-	}
-	sleep_on(&us->ip_waitq);
-	if (us->ip_wanted) {
-	    US_DEBUGP("Did not get interrupt on CBI\n");
-	    us->ip_wanted = 0;
-	    return DID_ABORT << 16;
-	}
-
-	if (us->ip_data != 0)
-	    US_DEBUGP("Got interrupt data %x\n", us->ip_data);
-
-	/* sort out what it means */
-
-	if (us->subclass == US_SC_UFI) {
-	    /* gives us asc and ascq, as per request sense */
-
-	    if (srb->cmnd[0] == REQUEST_SENSE ||
-		srb->cmnd[0] == INQUIRY)
-		return DID_OK << 16;
-	    else
-		return (DID_OK << 16) + ((us->ip_data & 0xff) ? 2 : 0);
-	}
-	if (us->ip_data & 0xff) {
-	    US_DEBUGP("Bad CBI interrupt data %x\n", us->ip_data);
-	    return DID_ABORT << 16;
-	}
-	return (DID_OK << 16) + ((us->ip_data & 0x300) ? 2 : 0);
-    }
-    return DID_ERROR << 16;
-}
-
-/* Protocol command handlers */
-
-static int pop_CBI(Scsi_Cmnd *srb)
-{
-    struct us_data *us = (struct us_data *)srb->host_scribble;
-    unsigned char cmd[16];
-    unsigned char *cmdp;
-    int cmd_len, len;
-    int result;
-    unsigned char modebuf[260];
-    unsigned char *savebuf = srb->request_buffer;
-    int savelen = srb->request_bufflen;
-
-    /* first fix some commands */
-    cmdp = srb->cmnd;
-    cmd_len = srb->cmd_len;
-
-    if (us->flags & US_FL_FIXED_COMMAND) {
-	cmdp = cmd;
-	cmd_len = us->fixedlength;
-	memset(cmd, 0, cmd_len);
-
-	switch (srb->cmnd[0]) {
-	case WRITE_6:
-	case READ_6:
-	    cmd[0] = srb->cmnd[0] | 0x20;
-	    cmd[1] = srb->cmnd[1] & 0xE0;
-	    cmd[2] = 0;
-	    cmd[3] = srb->cmnd[1] & 0x1F;
-	    cmd[4] = srb->cmnd[2];
-	    cmd[5] = srb->cmnd[3];
-	    cmd[8] = srb->cmnd[4];
-	    break;
-
-	case MODE_SENSE:
-	    if (srb->use_sg > 0)
-		US_DEBUGP("MODE SENSE with use_sg=%d!!!\n", srb->use_sg);
-	    len = srb->cmnd[4] + 4;
-	    cmd[0] = srb->cmnd[0] | 0x40;	/* op code */
-	    cmd[1] = srb->cmnd[1];		/* LUN, various bits */
-	    cmd[2] = srb->cmnd[2];		/* page code */
-	    cmd[8] = len;			/* allocation length */
-	    cmd[7] = len >> 8;
-	    srb->request_buffer = modebuf;
-	    srb->request_bufflen = len;
-	    break;
-
-	case MODE_SELECT:
-	    if (srb->use_sg > 0)
-		US_DEBUGP("MODE SELECT with use_sg=%d!!!\n", srb->use_sg);
-	    len = srb->cmnd[4] + 4;
-	    memset(modebuf, 0, 8);
-	    modebuf[1] = savebuf[0];
-	    modebuf[2] = savebuf[1];
-	    modebuf[3] = savebuf[2];
-	    modebuf[7] = savebuf[3];
-	    if (len > 8)
-		memcpy(modebuf+8, savebuf+4, len-8);
-	    srb->request_buffer = modebuf;
-	    srb->request_bufflen = len;
-	    cmd[0] = srb->cmnd[0] | 0x40;
-	    cmd[1] = srb->cmnd[1];
-	    cmd[2] = srb->cmnd[2];
-	    cmd[8] = len;
-	    cmd[7] = len >> 8;
-	    break;
-
-	default:
-	    memcpy(cmd, srb->cmnd, srb->cmd_len);
-	    break;
-	}
-    }
-
-    /* run the command */
-    if ((result = pop_CB_command(srb, cmdp, cmd_len))) {
-	US_DEBUGP("CBI command %x\n", result);
-	if (result == USB_ST_STALL || result == USB_ST_TIMEOUT)	{
-	    return (DID_OK << 16) | 2;
-	}
-	return DID_ERROR << 16;
-    }
-
-    /* transfer the data */
-
-    if (us_transfer_length(srb)) {
-	result = us_transfer(srb, US_DIRECTION(srb->cmnd[0]));
-	if (result && result != USB_ST_DATAUNDERRUN && result != USB_ST_STALL) {
-	    US_DEBUGP("CBI  transfer %x\n", result);
-	    return DID_ERROR << 16;
-	}
-#if 0
-	else if (result == USB_ST_DATAUNDERRUN) {
-	    return DID_OK << 16;
-	}
-    } else {
-	if (!result) {
-	    return DID_OK << 16;
-	}
-#endif
-    }
-
-    if (us->flags & US_FL_FIXED_COMMAND) {
-	switch (srb->cmnd[0]) {
-	case MODE_SENSE:
-	    len = srb->cmnd[4];
-	    savebuf[0] = modebuf[1];
-	    savebuf[1] = modebuf[2];
-	    savebuf[2] = modebuf[3];
-	    savebuf[3] = modebuf[7];
-	    if (len > 4)
-		memcpy(savebuf+4, modebuf+8, len-4);
-	    /* fall through */
-	case MODE_SELECT:
-	    srb->request_buffer = savebuf;
-	    srb->request_bufflen = savelen;
-	    break;
-	}
-    }
-
-    /* get status */
-
-    return pop_CB_status(srb);
-}
-
-static int pop_Bulk_reset(struct us_data *us)
-{
-    devrequest dr;
-    int result;
-
-    dr.requesttype = USB_TYPE_CLASS | USB_RT_INTERFACE;
-    dr.request = US_BULK_RESET;
-    dr.value = US_BULK_RESET_HARD;
-    dr.index = 0;
-    dr.length = 0;
-
-    result = us->pusb_dev->bus->op->control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), &dr, NULL, 0);
-    if (result)
-	US_DEBUGP("Bulk hard reset failed %d\n", result);
-    usb_clear_halt(us->pusb_dev, us->ep_in | 0x80);
-    usb_clear_halt(us->pusb_dev, us->ep_out);
-
-    /* long wait for reset */
-
-    schedule_timeout(HZ*5);
-
-    return result;
-}
-/*
- * The bulk only protocol handler.
- * 	Uses the in and out endpoints to transfer commands and data (nasty)
- */
-static int pop_Bulk(Scsi_Cmnd *srb)
-{
-    struct us_data *us = (struct us_data *)srb->host_scribble;
-    struct bulk_cb_wrap bcb;
-    struct bulk_cs_wrap bcs;
-    int result;
-    unsigned long partial;
-    int stall;
-
-    /* set up the command wrapper */
-
-    bcb.Signature = US_BULK_CB_SIGN;
-    bcb.DataTransferLength = us_transfer_length(srb);;
-    bcb.Flags = US_DIRECTION(srb->cmnd[0]) << 7;
-    bcb.Tag = srb->serial_number;
-    bcb.Lun = 0;
-    memset(bcb.CDB, 0, sizeof(bcb.CDB));
-    memcpy(bcb.CDB, srb->cmnd, srb->cmd_len);
-    if (us->flags & US_FL_FIXED_COMMAND) {
-	bcb.Length = us->fixedlength;
-    } else {
-	bcb.Length = srb->cmd_len;
-    }
-
-    /* send it to out endpoint */
-
-    US_DEBUGP("Bulk command S %x T %x L %d F %d CL %d\n", bcb.Signature,
-	      bcb.Tag, bcb.DataTransferLength, bcb.Flags, bcb.Length);
-    result = us->pusb_dev->bus->op->bulk_msg(us->pusb_dev,
-		     usb_sndbulkpipe(us->pusb_dev, us->ep_out), &bcb, 
-					    US_BULK_CB_WRAP_LEN, &partial);
-    if (result) {
-	US_DEBUGP("Bulk command result %x\n", result);
-	return DID_ABORT << 16;
-    }
-
-    //return DID_BAD_TARGET << 16;
-    /* send/receive data */
-
-    if (bcb.DataTransferLength) {
-	result = us_transfer(srb, bcb.Flags);
-	if (result && result != USB_ST_DATAUNDERRUN && result != USB_ST_STALL) {
-	    US_DEBUGP("Bulk transfer result %x\n", result);
-	    return DID_ABORT << 16;
-	}
-    }
-
-    /* get status */
-
-
-    stall = 0;
-    do {
-	result = us->pusb_dev->bus->op->bulk_msg(us->pusb_dev,
-			 usb_rcvbulkpipe(us->pusb_dev, us->ep_in), &bcs, 
-						US_BULK_CS_WRAP_LEN, &partial);
-	if (result == USB_ST_STALL || result == USB_ST_TIMEOUT)
-	    stall++;
-	else
-	    break;
-    } while ( stall < 3);
-    if (result && result != USB_ST_DATAUNDERRUN) {
-	US_DEBUGP("Bulk status result = %x\n", result);
-	return DID_ABORT << 16;
-    }
-
-    /* check bulk status */
-
-    US_DEBUGP("Bulk status S %x T %x R %d V %x\n", bcs.Signature, bcs.Tag,
-	      bcs.Residue, bcs.Status);
-    if (bcs.Signature != US_BULK_CS_SIGN || bcs.Tag != bcb.Tag ||
-	bcs.Status > US_BULK_STAT_PHASE) {
-	US_DEBUGP("Bulk logical error\n");
-	return DID_ABORT << 16;
-    }
-    switch (bcs.Status) {
-    case US_BULK_STAT_OK:
-	return DID_OK << 16;
-
-    case US_BULK_STAT_FAIL:
-	/* check for underrun - dont report */
-	if (bcs.Residue)
-	    return DID_OK << 16;
-	//pop_Bulk_reset(us);
-	break;
-
-    case US_BULK_STAT_PHASE:
-	return DID_ERROR << 16;
-    }
-    return (DID_OK << 16) | 2;		/* check sense required */
-
-}
-
-/* Host functions */
-
-/* detect adapter (always true ) */
-static int us_detect(struct SHT *sht)
-{
-    /* FIXME - not nice at all, but how else ? */
-    struct us_data *us = (struct us_data *)sht->proc_dir;
-    char name[32];
-
-    sprintf(name, "usbscsi%d", us->host_number);
-    proc_usb_scsi.namelen = strlen(name);
-    proc_usb_scsi.name = kmalloc(proc_usb_scsi.namelen+1, GFP_KERNEL);
-    if (!proc_usb_scsi.name)
-	return 0;
-    strcpy((char *)proc_usb_scsi.name, name);
-    sht->proc_dir = kmalloc(sizeof(*sht->proc_dir), GFP_KERNEL);
-    if (!sht->proc_dir) {
-	kfree(proc_usb_scsi.name);
-	return 0;
-    }
-    *sht->proc_dir = proc_usb_scsi;
-    sht->name = proc_usb_scsi.name;
-    us->host = scsi_register(sht, sizeof(us));
-    if (us->host) {
-	us->host->hostdata[0] = (unsigned long)us;
-	us->host_no = us->host->host_no;
-	return 1;
-    }
-    kfree(proc_usb_scsi.name);
-    kfree(sht->proc_dir);
-    return 0;
-}
-
-/* release - must be here to stop scsi
- *	from trying to release IRQ etc.
- *	Kill off our data
- */
-static int us_release(struct Scsi_Host *psh)
-{
-    struct us_data *us = (struct us_data *)psh->hostdata[0];
-    struct us_data *prev = (struct us_data *)&us_list;
-
-    if (us->filter)
-	us->filter->release(us->fdata);
-    if (us->pusb_dev)
-	usb_deregister(&scsi_driver);
-
-    /* FIXME - leaves hanging host template copy */
-    /* (bacause scsi layer uses it after removal !!!) */
-    while(prev->next != us)
-	prev = prev->next;
-    prev->next = us->next;
-    return 0;
-}
-
-/* run command */
-static int us_command( Scsi_Cmnd *srb )
-{
-    US_DEBUGP("Bad use of us_command\n");
-
-    return DID_BAD_TARGET << 16;
-}
-
-/* run command */
-static int us_queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *))
-{
-    struct us_data *us = (struct us_data *)srb->host->hostdata[0];
-
-    /* US_DEBUGP("Command wakeup\n"); */
-    if (us->srb) {
-	/* busy */
-    }
-    srb->host_scribble = (unsigned char *)us;
-    us->srb = srb;
-    srb->scsi_done = done;
-    us->action = US_ACT_COMMAND;
-
-    /* wake up the process task */
-
-    wake_up_interruptible(&us->waitq);
-
-    return 0;
-}
-
-static int us_abort( Scsi_Cmnd *srb )
-{
-    return 0;
-}
-
-static int us_bus_reset( Scsi_Cmnd *srb )
-{
-    struct us_data *us = (struct us_data *)srb->host->hostdata[0];
-
-    us->pop_reset(us);
-    return SUCCESS;
-}
-
-static int us_host_reset( Scsi_Cmnd *srb )
-{
-    return 0;
-}
-
-
-#undef SPRINTF
-#define SPRINTF(args...) { if (pos < (buffer + length)) pos += sprintf (pos, ## args); }
-
-int usb_scsi_proc_info (char *buffer, char **start, off_t offset, int length, int hostno, int inout)
-{
-    struct us_data *us = us_list;
-    char *pos = buffer;
-    char *vendor;
-    char *product;
-    char *style = "";
-
-    /* find our data from hostno */
-
-    while (us) {
-	if (us->host_no == hostno)
-	    break;
-	us = us->next;
-    }
-
-    if (!us)
-	return -ESRCH;
-
-    /* null on outward */
-
-    if (inout)
-	return length;
-
-    if (!us->pusb_dev || !(vendor = usb_string(us->pusb_dev, us->pusb_dev->descriptor.iManufacturer)))
-	vendor = "?";
-    if (!us->pusb_dev || !(product = usb_string(us->pusb_dev, us->pusb_dev->descriptor.iProduct)))
-	product = "?";
-
-    switch (us->protocol) {
-    case US_PR_CB:
-	style = "Control/Bulk";
-	break;
-
-    case US_PR_CBI:
-	style = "Control/Bulk/Interrupt";
-	break;
-
-    case US_PR_ZIP:
-	style = "Bulk only";
-	break;
-
-    }
-    SPRINTF ("Host scsi%d: usb-scsi\n", hostno);
-    SPRINTF ("Device: %s %s - GUID " GUID_FORMAT "\n", vendor, product, GUID_ARGS(us->guid) );
-    SPRINTF ("Style: %s\n", style);
-
-    /*
-     * Calculate start of next buffer, and return value.
-     */
-    *start = buffer + offset;
-
-    if ((pos - buffer) < offset)
-	return (0);
-    else if ((pos - buffer - offset) < length)
-	return (pos - buffer - offset);
-    else
-	return (length);
-}
-
-/*
- * this defines our 'host'
- */
-
-static Scsi_Host_Template my_host_template = {
-    NULL,			/* next */
-    NULL,			/* module */
-    NULL,			/* proc_dir */
-    usb_scsi_proc_info,
-    NULL,			/* name - points to unique */
-    us_detect,
-    us_release,
-    NULL,			/* info */
-    NULL,			/* ioctl */
-    us_command,
-    us_queuecommand,
-    NULL,			/* eh_strategy */
-    us_abort,
-    us_bus_reset,
-    us_bus_reset,
-    us_host_reset,
-    NULL,			/* abort */
-    NULL,			/* reset */
-    NULL,			/* slave_attach */
-    NULL,			/* bios_param */
-    1,				/* can_queue */
-    -1,				/* this_id */
-    SG_ALL,			/* sg_tablesize */
-    1,				/* cmd_per_lun */
-    0,				/* present */
-    FALSE,			/* unchecked_isa_dma */
-    FALSE,			/* use_clustering */
-    TRUE,			/* use_new_eh_code */
-    TRUE			/* emulated */
-};
-
-static unsigned char sense_notready[] = {
-    0x70,			/* current error */
-    0x00,
-    0x02,			/* not ready */
-    0x00,
-    0x00,
-    10,				/* additional length */
-    0x00,
-    0x00,
-    0x00,
-    0x00,
-    0x04,			/* not ready */
-    0x03,			/* manual intervention */
-    0x00,
-    0x00,
-    0x00,
-    0x00
-};
-
-static int usbscsi_control_thread(void * __us)
-{
-    struct us_data *us = (struct us_data *)__us;
-    int action;
-
-    lock_kernel();
-
-    /*
-     * This thread doesn't need any user-level access,
-     * so get rid of all our resources..
-     */
-    exit_mm(current);
-    exit_files(current);
-    //exit_fs(current);
-
-    sprintf(current->comm, "usbscsi%d", us->host_number);
-    
-    unlock_kernel();
-
-    up(us->notify);
-
-    for(;;) {
-	    siginfo_t info;
-	    int unsigned long signr;
-
-	    interruptible_sleep_on(&us->waitq);
-
-	    action = us->action;
-	    us->action = 0;
-
-	    switch (action) {
-	    case US_ACT_COMMAND       :
-		if (us->srb->target || us->srb->lun) {
-		    /* bad device */
-		    US_DEBUGP( "Bad device number (%d/%d) or dev %x\n", us->srb->target, us->srb->lun, (unsigned int)us->pusb_dev);
-		    us->srb->result = DID_BAD_TARGET << 16;
-		} else if (!us->pusb_dev) {
-
-		    /* our device has gone - pretend not ready */
-
-		    if (us->srb->cmnd[0] == REQUEST_SENSE) {
-			memcpy(us->srb->request_buffer, sense_notready, sizeof(sense_notready));
-			us->srb->result = DID_OK << 16;
-		    } else {
-			us->srb->result = (DID_OK << 16) | 2;
-		    }
-		} else {
-		    /* US_DEBUG(us_show_command(us->srb)); */
-
-		    /* check for variable length - do properly if so */
-
-		    if (us->filter && us->filter->command)
-		        us->srb->result = us->filter->command(us->fdata, us->srb);
-		    else if (us->srb->cmnd[0] == START_STOP &&
-			     us->pusb_dev->descriptor.idProduct == 0x0001 &&
-			     us->pusb_dev->descriptor.idVendor == 0x04e6)
-			us->srb->result = DID_OK << 16;
-		    else {
-			unsigned int savelen = us->srb->request_bufflen;
-			unsigned int saveallocation;
-
-			switch (us->srb->cmnd[0]) {
-			case REQUEST_SENSE:
-			    if (us->srb->request_bufflen > 18)
-				us->srb->request_bufflen = 18;
-			    else
-				break;
-			    saveallocation = us->srb->cmnd[4];
-                            us->srb->cmnd[4] = 18;
-			    break;
-
-			case INQUIRY:
-			    if (us->srb->request_bufflen > 36)
-				us->srb->request_bufflen = 36;
-			    else
-				break;
-			    saveallocation = us->srb->cmnd[4];
-                            us->srb->cmnd[4] = 36;
-			    break;
-
-			case MODE_SENSE:
-			    if (us->srb->request_bufflen > 4)
-				us->srb->request_bufflen = 4;
-			    else
-				break;
-			    saveallocation = us->srb->cmnd[4];
-                            us->srb->cmnd[4] = 4;
-			    break;
-
-			case LOG_SENSE:
-			case MODE_SENSE_10:
-			    if (us->srb->request_bufflen > 8)
-				us->srb->request_bufflen = 8;
-			    else
-				break;
-			    saveallocation = (us->srb->cmnd[7] << 8) | us->srb->cmnd[8];
-                            us->srb->cmnd[7] = 0;
-                            us->srb->cmnd[8] = 8;
-			    break;
-
-			default:
-			    break;
-			}
-		        us->srb->result = us->pop(us->srb);
-
-			if (savelen != us->srb->request_bufflen &&
-			    us->srb->result == (DID_OK << 16)) {
-			    unsigned char *p = (unsigned char *)us->srb->request_buffer;
-			    unsigned int length;
-
-			    /* set correct length and retry */
-			    switch (us->srb->cmnd[0]) {
-			    case REQUEST_SENSE:
-				/* simply return 18 bytes */
-				p[7] = 10;
-				length = us->srb->request_bufflen;;
-				break;
-
-			    case INQUIRY:
-				length = p[4] + 5 > savelen ? savelen : p[4] + 5;
-				us->srb->cmnd[4] = length;
-				break;
-
-			    case MODE_SENSE:
-				length = p[0] + 4 > savelen ? savelen : p[0] + 4;
-				us->srb->cmnd[4] = 4;
-				break;
-
-			    case LOG_SENSE:
-				length = ((p[2] << 8) + p[3]) + 4 > savelen ? savelen : ((p[2] << 8) + p[3]) + 4;
-				us->srb->cmnd[7] = length >> 8;
-				us->srb->cmnd[8] = length;
-				break;
-
-			    case MODE_SENSE_10:
-				length = ((p[0] << 8) + p[1]) + 8 > savelen ? savelen : ((p[0] << 8) + p[1]) + 8;
-				us->srb->cmnd[7] = length >> 8;
-				us->srb->cmnd[8] = length;
-				break;
-			    }
-
-			    US_DEBUGP("Old/New length = %d/%d\n", savelen, length);
-
-			    if (us->srb->request_bufflen != length) {
-				us->srb->request_bufflen = length;
-				us->srb->result = us->pop(us->srb);
-			    }
-			    /* reset back to original values */
-
-			    us->srb->request_bufflen = savelen;
-			    switch (us->srb->cmnd[0]) {
-			    case REQUEST_SENSE:
-			    case INQUIRY:
-			    case MODE_SENSE:
-				us->srb->cmnd[4] = saveallocation;
-				break;
-
-			    case LOG_SENSE:
-			    case MODE_SENSE_10:
-				us->srb->cmnd[7] = saveallocation >> 8;
-				us->srb->cmnd[8] = saveallocation;
-				break;
-			    }
-			}
-			/* force attention on first command */
-			if (!us->attention_done) {
-			    US_DEBUGP("forcing unit attention\n");
-			    if (us->srb->cmnd[0] == REQUEST_SENSE) {
-				if (us->srb->result == (DID_OK << 16)) {
-				    unsigned char *p = (unsigned char *)us->srb->request_buffer;
-
-				    us->attention_done = 1;
-				    if ((p[2] & 0x0f) != UNIT_ATTENTION) {
-					p[2] = UNIT_ATTENTION;
-					p[12] = 0x29;	/* power on, reset or bus-reset */
-					p[13] = 0;
-				    }
-				}
-			    } else if (us->srb->cmnd[0] != INQUIRY &&
-				       us->srb->result == (DID_OK << 16)) {
-				us->srb->result |= 2;	/* force check condition */
-			    }
-			}
-		    }
-		}
-		if (us->srb->result) {
-		    US_DEBUG(us_show_command(us->srb));
-		    US_DEBUGP("scsi cmd done, result=%x\n", us->srb->result);
-		}
-		us->srb->scsi_done(us->srb);
-		us->srb = NULL;
-		break;
-
-	    case US_ACT_ABORT         :
-		break;
-
-	    case US_ACT_DEVICE_RESET  :
-		break;
-
-	    case US_ACT_BUS_RESET     :
-		break;
-
-	    case US_ACT_HOST_RESET    :
-		break;
-
-	    }
-
-	    if(signal_pending(current)) {
-		    /* sending SIGUSR1 makes us print out some info */
-		    spin_lock_irq(&current->sigmask_lock);
-		    signr = dequeue_signal(&current->blocked, &info);
-		    spin_unlock_irq(&current->sigmask_lock);
-
-		    if (signr == SIGUSR2) {
-			    printk("USBSCSI debug toggle\n");
-			    usbscsi_debug = !usbscsi_debug;
-		    } else {
-			    break;
-		    }
-	    }
-    }
-
-    MOD_DEC_USE_COUNT;
-
-    printk("usbscsi_control_thread exiting\n");
-
-    return 0;
-}	
-
-static int scsi_probe(struct usb_device *dev)
-{
-    struct usb_interface_descriptor *interface;
-    int i;
-    char *mf;		/* manufacturer */
-    char *prod;		/* product */
-    char *serial;		/* serial number */
-    struct us_data *ss = NULL;
-    struct usb_scsi_filter *filter = filters;
-    void *fdata = NULL;
-    unsigned int flags = 0;
-    GUID(guid);
-    struct us_data *prev;
-    Scsi_Host_Template *htmplt;
-    int protocol = 0;
-    int subclass = 0;
-
-    GUID_CLEAR(guid);
-    mf = usb_string(dev, dev->descriptor.iManufacturer);
-    prod = usb_string(dev, dev->descriptor.iProduct);
-    serial = usb_string(dev, dev->descriptor.iSerialNumber);
-
-    /* probe with filters first */
-
-    if (mf && prod)	{
-	    while (filter) {
-		    if ((fdata = filter->probe(dev, mf, prod, serial)) != NULL) {
-			    flags = filter->flags;
-			    printk(KERN_INFO "USB Scsi filter %s\n", filter->name);
-			    break;
-		    }
-		    filter = filter->next;
-	    }
-    }
-
-    /* generic devices next */
-
-    if (fdata == NULL) {
-
-	/* some exceptions */
-	if (dev->descriptor.idVendor == 0x04e6 &&
-	    dev->descriptor.idProduct == 0x0001) {
-	    /* shuttle E-USB */
-	    protocol = US_PR_CB;
-	    subclass = US_SC_8070;	/* an assumption */
-	} else if (dev->descriptor.bDeviceClass != 0 ||
-	    dev->config->altsetting->interface->bInterfaceClass != 8 ||
-	    dev->config->altsetting->interface->bInterfaceSubClass < US_SC_MIN ||
-	    dev->config->altsetting->interface->bInterfaceSubClass > US_SC_MAX) {
-	    return -1;
-	}
-
-	/* now check if we have seen it before */
-
-	if (dev->descriptor.iSerialNumber && 
-	    usb_string(dev, dev->descriptor.iSerialNumber) ) {
-	    make_guid(guid, dev->descriptor.idVendor, dev->descriptor.idProduct,
-		      usb_string(dev, dev->descriptor.iSerialNumber));
-	} else {
-	    make_guid(guid, dev->descriptor.idVendor, dev->descriptor.idProduct,
-		      "0");
-	}
-	for (ss = us_list; ss; ss = ss->next) {
-	    if (!ss->pusb_dev && GUID_EQUAL(guid, ss->guid))	{
-		US_DEBUGP("Found existing GUID " GUID_FORMAT "\n", GUID_ARGS(guid));
-		flags = ss->flags;
-		break;
-	    }
-	}
-    }
-
-    if (!ss) {
-	if ((ss = (struct us_data *)kmalloc(sizeof(*ss), GFP_KERNEL)) == NULL) {
-	    printk(KERN_WARNING USB_SCSI "Out of memory\n");
-	    if (filter)
-		    filter->release(fdata);
-	    return -1;
-	}
-	memset(ss, 0, sizeof(struct us_data));
-    }
-
-    interface = dev->config->altsetting->interface;
-    ss->filter = filter;
-    ss->fdata = fdata;
-    ss->flags = flags;
-    if (subclass) {
-	ss->subclass = subclass;
-	ss->protocol = protocol;
-    } else {
-	ss->subclass = interface->bInterfaceSubClass;
-	ss->protocol = interface->bInterfaceProtocol;
-    }
-    ss->attention_done = 0;
-
-    /* set the protocol op */
-
-    US_DEBUGP("Protocol ");
-    switch (ss->protocol) {
-    case US_PR_CB:
-	US_DEBUGPX("Control/Bulk\n");
-	ss->pop = pop_CBI;
-	ss->pop_reset = pop_CB_reset;
-	break;
-
-    case US_PR_CBI:
-	US_DEBUGPX("Control/Bulk/Interrupt\n");
-	ss->pop = pop_CBI;
-	ss->pop_reset = pop_CB_reset;
-	break;
-
-    default:
-	US_DEBUGPX("Bulk\n");
-	ss->pop = pop_Bulk;
-	ss->pop_reset = pop_Bulk_reset;
-	break;
-    }
-
-    /* 
-     * we are expecting a minimum of 2 endpoints - in and out (bulk)
-     * an optional interrupt is OK (necessary for CBI protocol)
-     * we will ignore any others
-     */
-
-    for (i = 0; i < interface->bNumEndpoints; i++) { 
-	    if (interface->endpoint[i].bmAttributes == 0x02) {
-		    if (interface->endpoint[i].bEndpointAddress & 0x80)
-			    ss->ep_in = interface->endpoint[i].bEndpointAddress & 0x0f;
-		    else
-			    ss->ep_out = interface->endpoint[i].bEndpointAddress & 0x0f;
-	    } else if (interface->endpoint[i].bmAttributes == 0x03) {
-		    ss->ep_int = interface->endpoint[i].bEndpointAddress & 0x0f;
-	    }
-    }
-    US_DEBUGP("Endpoints In %d Out %d Int %d\n", ss->ep_in, ss->ep_out, ss->ep_int);
-
-    /* exit if strange looking */
-
-    if (usb_set_configuration(dev, dev->config[0].bConfigurationValue) ||
-	usb_set_interface(dev, interface->bInterfaceNumber, 0) ||
-	!ss->ep_in || !ss->ep_out || (ss->protocol == US_PR_CBI && ss->ep_int == 0)) {
-	US_DEBUGP("Problems with device\n");
-	if (ss->host) {
-	    scsi_unregister_module(MODULE_SCSI_HA, ss->htmplt);
-	    kfree(ss->htmplt->name);
-	    kfree(ss->htmplt);
-	}
-	if (filter)
-		filter->release(fdata);
-	kfree(ss);
-	return -1;			/* no endpoints */
-    }
-
-    if (dev->config[0].iConfiguration && usb_string(dev, dev->config[0].iConfiguration))
-	US_DEBUGP("Configuration %s\n", usb_string(dev, dev->config[0].iConfiguration));
-    if (interface->iInterface && usb_string(dev, interface->iInterface))
-	US_DEBUGP("Interface %s\n", usb_string(dev, interface->iInterface));
-
-    ss->pusb_dev = dev;
-
-    /* Now generate a scsi host definition, and register with scsi above us */
-
-    if (!ss->host) {
-
-	/* make unique id if possible */
-
-	US_DEBUGP("New GUID " GUID_FORMAT "\n", GUID_ARGS(guid));
-	memcpy(ss->guid, guid, sizeof(guid));
-
-	/* set class specific stuff */
-
-	US_DEBUGP("SubClass ");
-	switch (ss->subclass) {
-	case US_SC_RBC:
-	    US_DEBUGPX("Reduced Block Commands\n");
-	    break;
-	case US_SC_8020:
-	    US_DEBUGPX("8020\n");
-	    break;
-	case US_SC_QIC:
-	    US_DEBUGPX("QIC157\n");
-	    break;
-	case US_SC_8070:
-	    US_DEBUGPX("8070\n");
-	    ss->flags |= US_FL_FIXED_COMMAND;
-	    ss->fixedlength = 12;
-	    break;
-	case US_SC_SCSI:
-	    US_DEBUGPX("Transparent SCSI\n");
-	    break;
-	case US_SC_UFI:
-	    US_DEBUGPX(" UFF\n");
-	    ss->flags |= US_FL_FIXED_COMMAND;
-	    ss->fixedlength = 12;
-	    break;
-
-	default:
-	    break;
-	}
-
-	/* create unique host template */
-
-	if ((htmplt = (Scsi_Host_Template *)kmalloc(sizeof(*ss->htmplt), GFP_KERNEL)) == NULL ) {
-	    printk(KERN_WARNING USB_SCSI "Out of memory\n");
-	    if (filter)
-		    filter->release(fdata);
-	    kfree(ss);
-	    return -1;
-	}
-	memcpy(htmplt, &my_host_template, sizeof(my_host_template));
-	ss->host_number = my_host_number++;
-
-
-	(struct us_data *)htmplt->proc_dir = ss;
-
-	if (dev->descriptor.idVendor == 0x04e6 &&
-	    dev->descriptor.idProduct == 0x0001) {
-	    devrequest dr;
-	    __u8 qstat[2];
-
-	    /* shuttle E-USB */
-	    dr.requesttype = 0xC0;
-	    dr.request = 1;
-	    dr.index = 0;
-	    dr.value = 0;
-	    dr.length = 0;
-	    ss->pusb_dev->bus->op->control_msg(ss->pusb_dev, usb_rcvctrlpipe(dev,0), &dr, qstat, 2);
-	    US_DEBUGP("C0 status %x %x\n", qstat[0], qstat[1]);
-	    init_waitqueue_head(&ss->ip_waitq);
-	    ss->pusb_dev->bus->op->request_irq(ss->pusb_dev, 
-						usb_rcvctrlpipe(ss->pusb_dev, ss->ep_int),
-						pop_CBI_irq, 0, (void *)ss);
-	    interruptible_sleep_on_timeout(&ss->ip_waitq, HZ*5);
-
-	} else if (ss->protocol == US_PR_CBI)
-	    init_waitqueue_head(&ss->ip_waitq);
-
-
-	/* start up our thread */
-
-	{
-	    DECLARE_MUTEX_LOCKED(sem);
-
-	    init_waitqueue_head(&ss->waitq);
-    
-	    ss->notify = &sem;
-	    ss->pid = kernel_thread(usbscsi_control_thread, ss,
-		    CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
-	    if (ss->pid < 0) {
-		printk(KERN_WARNING USB_SCSI "Unable to start control thread\n");
-		kfree(htmplt);
-		if (filter)
-			filter->release(fdata);
-		kfree(ss);
-		return -1;
-	    }
-
-	    /* wait for it to start */
-
-	    down(&sem);
-	}
-
-	/* now register - our detect function will be called */
-
-	scsi_register_module(MODULE_SCSI_HA, htmplt);
-
-	/* put us in the list */
-
-	prev = (struct us_data *)&us_list;
-	while (prev->next)
-	    prev = prev->next;
-	prev->next = ss;
-
-    }
-
-
-    printk(KERN_INFO "USB SCSI device found at address %d\n", dev->devnum);
-
-    dev->private = ss;
-    return 0;
-}
-
-static void scsi_disconnect(struct usb_device *dev)
-{
-	struct us_data *ss = dev->private;
-
-	if (!ss)
-	    return;
-	if (ss->filter)
-		ss->filter->release(ss->fdata);
-	ss->pusb_dev = NULL;
-	dev->private = NULL;		/* just in case */
-	MOD_DEC_USE_COUNT;
-}
-
-int usb_scsi_init(void)
-{
-
-	MOD_INC_USE_COUNT;
-#ifdef CONFIG_USB_HP4100
-	hp4100_init();
-#endif
-#ifdef CONFIG_USB_ZIP
-	usb_zip_init();
-#endif
-	usb_register(&scsi_driver);
-	printk(KERN_INFO "USB SCSI support registered.\n");
-	return 0;
-}
-
-
-int usb_scsi_register(struct usb_scsi_filter *filter)
-{
-	struct usb_scsi_filter *prev = (struct usb_scsi_filter *)&filters;
-
-	while (prev->next)
-		prev = prev->next;
-	prev->next = filter;
-	return 0;
-}
-
-void usb_scsi_deregister(struct usb_scsi_filter *filter)
-{
-	struct usb_scsi_filter *prev = (struct usb_scsi_filter *)&filters;
-
-	while (prev->next && prev->next != filter)
-		prev = prev->next;
-	if (prev->next)
-		prev->next = filter->next;
-}
-
-#ifdef MODULE
-int init_module(void)
-{
-
-	return usb_scsi_init();
-}
-
-void cleanup_module(void)
-{
-	unsigned int offset;
-
-	usb_deregister(&scsi_driver);
-}
-#endif
diff -urN linux-2.2.12-pre1/drivers/usb/usb_scsi_debug.c linux-2.2.12-pre3/drivers/usb/usb_scsi_debug.c
--- linux-2.2.12-pre1/drivers/usb/usb_scsi_debug.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/usb_scsi_debug.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,116 +0,0 @@
-
-/* Driver for USB scsi like devices
- * 
- * (C) Michael Gee (michael@linuxspecific.com) 1999
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/errno.h>
-#include <linux/miscdevice.h>
-#include <linux/random.h>
-#include <linux/poll.h>
-#include <linux/init.h>
-#include <linux/malloc.h>
-
-#include <asm/spinlock.h>
-
-#include <linux/blk.h>
-#include "../scsi/scsi.h"
-#include "../scsi/hosts.h"
-#include "../scsi/sd.h"
-
-#include "usb.h"
-#include "usb_scsi.h"
-
-void us_show_command(Scsi_Cmnd *srb)
-{
-    char *what;
-
-    switch (srb->cmnd[0]) {
-    case TEST_UNIT_READY: what = "TEST_UNIT_READY"; break;
-    case REZERO_UNIT: what = "REZERO_UNIT"; break;
-    case REQUEST_SENSE: what = "REQUEST_SENSE"; break;
-    case FORMAT_UNIT: what = "FORMAT_UNIT"; break;
-    case READ_BLOCK_LIMITS: what = "READ_BLOCK_LIMITS"; break;
-    case REASSIGN_BLOCKS: what = "REASSIGN_BLOCKS"; break;
-    case READ_6: what = "READ_6"; break;
-    case WRITE_6: what = "WRITE_6"; break;
-    case SEEK_6: what = "SEEK_6"; break;
-    case READ_REVERSE: what = "READ_REVERSE"; break;
-    case WRITE_FILEMARKS: what = "WRITE_FILEMARKS"; break;
-    case SPACE: what = "SPACE"; break;
-    case INQUIRY: what = "INQUIRY"; break;
-    case RECOVER_BUFFERED_DATA: what = "RECOVER_BUFFERED_DATA"; break;
-    case MODE_SELECT: what = "MODE_SELECT"; break;
-    case RESERVE: what = "RESERVE"; break;
-    case RELEASE: what = "RELEASE"; break;
-    case COPY: what = "COPY"; break;
-    case ERASE: what = "ERASE"; break;
-    case MODE_SENSE: what = "MODE_SENSE"; break;
-    case START_STOP: what = "START_STOP"; break;
-    case RECEIVE_DIAGNOSTIC: what = "RECEIVE_DIAGNOSTIC"; break;
-    case SEND_DIAGNOSTIC: what = "SEND_DIAGNOSTIC"; break;
-    case ALLOW_MEDIUM_REMOVAL: what = "ALLOW_MEDIUM_REMOVAL"; break;
-    case SET_WINDOW: what = "SET_WINDOW"; break;
-    case READ_CAPACITY: what = "READ_CAPACITY"; break;
-    case READ_10: what = "READ_10"; break;
-    case WRITE_10: what = "WRITE_10"; break;
-    case SEEK_10: what = "SEEK_10"; break;
-    case WRITE_VERIFY: what = "WRITE_VERIFY"; break;
-    case VERIFY: what = "VERIFY"; break;
-    case SEARCH_HIGH: what = "SEARCH_HIGH"; break;
-    case SEARCH_EQUAL: what = "SEARCH_EQUAL"; break;
-    case SEARCH_LOW: what = "SEARCH_LOW"; break;
-    case SET_LIMITS: what = "SET_LIMITS"; break;
-    case READ_POSITION: what = "READ_POSITION"; break;
-    case SYNCHRONIZE_CACHE: what = "SYNCHRONIZE_CACHE"; break;
-    case LOCK_UNLOCK_CACHE: what = "LOCK_UNLOCK_CACHE"; break;
-    case READ_DEFECT_DATA: what = "READ_DEFECT_DATA"; break;
-    case MEDIUM_SCAN: what = "MEDIUM_SCAN"; break;
-    case COMPARE: what = "COMPARE"; break;
-    case COPY_VERIFY: what = "COPY_VERIFY"; break;
-    case WRITE_BUFFER: what = "WRITE_BUFFER"; break;
-    case READ_BUFFER: what = "READ_BUFFER"; break;
-    case UPDATE_BLOCK: what = "UPDATE_BLOCK"; break;
-    case READ_LONG: what = "READ_LONG"; break;
-    case WRITE_LONG: what = "WRITE_LONG"; break;
-    case CHANGE_DEFINITION: what = "CHANGE_DEFINITION"; break;
-    case WRITE_SAME: what = "WRITE_SAME"; break;
-    case READ_TOC: what = "READ_TOC"; break;
-    case LOG_SELECT: what = "LOG_SELECT"; break;
-    case LOG_SENSE: what = "LOG_SENSE"; break;
-    case MODE_SELECT_10: what = "MODE_SELECT_10"; break;
-    case MODE_SENSE_10: what = "MODE_SENSE_10"; break;
-    case MOVE_MEDIUM: what = "MOVE_MEDIUM"; break;
-    case READ_12: what = "READ_12"; break;
-    case WRITE_12: what = "WRITE_12"; break;
-    case WRITE_VERIFY_12: what = "WRITE_VERIFY_12"; break;
-    case SEARCH_HIGH_12: what = "SEARCH_HIGH_12"; break;
-    case SEARCH_EQUAL_12: what = "SEARCH_EQUAL_12"; break;
-    case SEARCH_LOW_12: what = "SEARCH_LOW_12"; break;
-    case READ_ELEMENT_STATUS: what = "READ_ELEMENT_STATUS"; break;
-    case SEND_VOLUME_TAG: what = "SEND_VOLUME_TAG"; break;
-    case WRITE_LONG_2: what = "WRITE_LONG_2"; break;
-    default: break;
-    }
-    printk(KERN_DEBUG USB_SCSI "Command %s (%d bytes)\n", what, srb->cmd_len);
-    printk(KERN_DEBUG USB_SCSI "  %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
-	   srb->cmnd[0], srb->cmnd[1], srb->cmnd[2], srb->cmnd[3], srb->cmnd[4], srb->cmnd[5], 
-           srb->cmnd[6], srb->cmnd[7], srb->cmnd[8], srb->cmnd[9]);
-    printk(KERN_DEBUG USB_SCSI "  use_sg=%d buff=%p len=%d\n",
-	   srb->use_sg, srb->request_buffer, srb->request_bufflen);
-    if (srb->use_sg) {
-	struct scatterlist *sg = (struct scatterlist *) srb->request_buffer;
-	int i;
-	printk(KERN_DEBUG USB_SCSI "  ");
-	for (i = 0; i < srb->use_sg && i < 5; ++i)
-	    printk(" [%p %d]", sg[i].address, sg[i].length);
-	if (i < srb->use_sg)
-	    printk(" ...");
-	printk("\n");
-    }
-}
diff -urN linux-2.2.12-pre1/drivers/usb/usb_scsi_dt.c linux-2.2.12-pre3/drivers/usb/usb_scsi_dt.c
--- linux-2.2.12-pre1/drivers/usb/usb_scsi_dt.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/usb_scsi_dt.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,4 +0,0 @@
-0x28, 0x81, 0x14, 0x14, 0x20, 0x01, 0x90, 0x77, 
-0x0C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
diff -urN linux-2.2.12-pre1/drivers/usb/usb_scsi.h linux-2.2.12-pre3/drivers/usb/usb_scsi.h
--- linux-2.2.12-pre1/drivers/usb/usb_scsi.h	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/drivers/usb/usb_scsi.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,147 +0,0 @@
-/* Driver for USB scsi - include file
- * 
- * (C) Michael Gee (michael@linuxspecific.com) 1999
- *
- * This driver is scitzoid  - it make a USB scanner appear as both a SCSI device
- * and a character device. The latter is only available if the device has an
- * interrupt endpoint, and is used specifically to receive interrupt events.
- *
- * In order to support various 'strange' scanners, this module supports plug in
- * device specific filter modules, which can do their own thing when required.
- *
- */
-
-#include <linux/config.h>
-
-#define USB_SCSI "usbscsi: "
-
-extern int usbscsi_debug;
-
-#ifdef CONFIG_USB_SCSI_DEBUG
-void us_show_command(Scsi_Cmnd *srb);
-#define US_DEBUGP(x...) { if(usbscsi_debug) printk( KERN_DEBUG USB_SCSI ## x ); }
-#define US_DEBUGPX(x...) { if(usbscsi_debug) printk( ## x ); }
-#define US_DEBUG(x)  { if(usbscsi_debug) x; }
-#else
-#define US_DEBUGP(x...)
-#define US_DEBUGPX(x...)
-#define US_DEBUG(x)
-#endif
-
-/* bit set if input */
-extern unsigned char us_direction[256/8];
-#define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
-
-/* Sub Classes */
-
-#define US_SC_RBC	1		/* Typically, flash devices */
-#define US_SC_8020	2		/* CD-ROM */
-#define US_SC_QIC	3		/* QIC-157 Tapes */
-#define US_SC_UFI	4		/* Floppy */
-#define US_SC_8070	5		/* Removable media */
-#define US_SC_SCSI	6		/* Transparent */
-#define US_SC_MIN	US_SC_RBC
-#define US_SC_MAX	US_SC_SCSI
-
-/* Protocols */
-
-#define US_PR_CB	1		/* Control/Bulk w/o interrupt */
-#define US_PR_CBI	0		/* Control/Bulk/Interrupt */
-#define US_PR_ZIP	0x50		/* bulk only */
-/* #define US_PR_BULK	?? */
-
-/*
- * Bulk only data structures (Zip 100, for example)
- */
-
-struct bulk_cb_wrap {
-    __u32	Signature;		/* contains 'USBC' */
-    __u32	Tag;			/* unique per command id */
-    __u32	DataTransferLength;	/* size of data */
-    __u8	Flags;	       		/* direction in bit 0 */
-    __u8	Lun;			/* LUN normally 0 */
-    __u8	Length;			/* of of the CDB */
-    __u8	CDB[16];		/* max command */
-};
-
-#define US_BULK_CB_WRAP_LEN 	31
-#define US_BULK_CB_SIGN		0x43425355
-#define US_BULK_FLAG_IN		1
-#define US_BULK_FLAG_OUT	0
-
-struct bulk_cs_wrap {
-    __u32	Signature;		/* should = 'USBS' */
-    __u32	Tag;			/* same as original command */
-    __u32	Residue;		/* amount not transferred */
-    __u8	Status;			/* see below */
-    __u8	Filler[18];
-};
-
-#define US_BULK_CS_WRAP_LEN	31
-#define US_BULK_CS_SIGN		0x53425355
-#define US_BULK_STAT_OK		0
-#define US_BULK_STAT_FAIL	1
-#define US_BULK_STAT_PHASE	2
-
-#define US_BULK_RESET		0xff
-#define US_BULK_RESET_SOFT	1
-#define US_BULK_RESET_HARD	0
-
-/*
- * CBI style
- */
-
-#define US_CBI_ADSC		0
-
-/*
- * Filter device definitions
- */
-struct usb_scsi_filter {
-
-	struct usb_scsi_filter * next;	/* usb_scsi driver only */
-	char *name;			/* not really required */
-
-        unsigned int flags;                     			/* Filter flags */
-        void * (* probe) (struct usb_device *, char *, char *, char *);	/* probe device */
-	void (* release)(void *);					/* device gone */
-        int (* command)(void *, Scsi_Cmnd *);  /* all commands */
-};
-
-#define GUID(x) __u32 x[3]
-#define GUID_EQUAL(x, y) (x[0] == y[0] && x[1] == y[1] && x[2] == y[2])
-#define GUID_CLEAR(x) x[0] = x[1] = x[2] = 0;
-#define GUID_NONE(x) (!x[0] && !x[1] && !x[2])
-#define GUID_FORMAT "%08x%08x%08x"
-#define GUID_ARGS(x) x[0], x[1], x[2]
-
-static inline void make_guid( __u32 *pg, __u16 vendor, __u16 product, char *serial)
-{
-	pg[0] = (vendor << 16) | product;
-	pg[1] = pg[2] = 0;
-	while (*serial) {
-		pg[1] <<= 4;
-		pg[1] |= pg[2] >> 28;
-		pg[2] <<= 4;
-		if (*serial >= 'a')
-		    *serial -= 'a' - 'A';
-		pg[2] |= (*serial <= '9' && *serial >= '0') ? *serial - '0'
-						    	    : *serial - 'A' + 10;
-		serial++;
-	}
-}
-
-/* Flag definitions */
-#define US_FL_IP_STATUS		0x00000001		/* status uses interrupt */
-#define US_FL_FIXED_COMMAND	0x00000002		/* expand commands to fixed size */
-
-/*
- * Called by filters to register/unregister the mini driver
- *
- * WARNING - the supplied probe function may be called before exiting this fn
- */
-int usb_scsi_register(struct usb_scsi_filter *);
-void usb_scsi_deregister(struct usb_scsi_filter *);
-
-#ifdef CONFIG_USB_HP4100
-int hp4100_init(void);
-#endif
diff -urN linux-2.2.12-pre1/include/linux/fd.h linux-2.2.12-pre3/include/linux/fd.h
--- linux-2.2.12-pre1/include/linux/fd.h	1998-06-24 14:30:11.000000000 -0700
+++ linux-2.2.12-pre3/include/linux/fd.h	2003-08-15 15:06:49.000000000 -0700
@@ -216,7 +216,7 @@
 	/* Prevent "aliased" accesses. */
 	int fd_ref;
 	int fd_device;
-	int last_checked; /* when was the drive last checked for a disk 
+	unsigned long last_checked; /* when was the drive last checked for a disk 
 			   * change? */
 	
 	char *dmabuf;
diff -urN linux-2.2.12-pre1/include/net/tcp.h linux-2.2.12-pre3/include/net/tcp.h
--- linux-2.2.12-pre1/include/net/tcp.h	1999-08-09 12:05:13.000000000 -0700
+++ linux-2.2.12-pre3/include/net/tcp.h	2003-08-15 15:06:49.000000000 -0700
@@ -142,7 +142,8 @@
 				nonagle;
 
 	/* And these are ours. */
-	__u32			rcv_nxt,snd_nxt;
+	__u32			rcv_nxt, snd_nxt;
+	__u16			window;
 	struct tcp_func		*af_specific;
 	struct tcp_bind_bucket	*tb;
 	struct tcp_tw_bucket	*next_death;
diff -urN linux-2.2.12-pre1/net/ipv4/tcp_input.c linux-2.2.12-pre3/net/ipv4/tcp_input.c
--- linux-2.2.12-pre1/net/ipv4/tcp_input.c	1999-08-09 12:05:14.000000000 -0700
+++ linux-2.2.12-pre3/net/ipv4/tcp_input.c	2003-08-15 15:06:49.000000000 -0700
@@ -1006,7 +1006,8 @@
 			tcp_tw_reschedule(tw);
 	}
 	/* Ack old packets if necessary */ 
-	if (!after(TCP_SKB_CB(skb)->end_seq, tw->rcv_nxt)) 
+	if (!after(TCP_SKB_CB(skb)->end_seq, tw->rcv_nxt) &&
+	    (th->doff * 4) > len)
 		return TCP_TW_ACK; 
 	return 0; 
 }
@@ -1067,7 +1068,8 @@
 		tw->family	= sk->family;
 		tw->reuse	= sk->reuse;
 		tw->rcv_nxt	= sk->tp_pinfo.af_tcp.rcv_nxt;
-		tw->snd_nxt = sk->tp_pinfo.af_tcp.snd_nxt;
+		tw->snd_nxt     = sk->tp_pinfo.af_tcp.snd_nxt;
+		tw->window	= tcp_select_window(sk);
 		tw->af_specific	= sk->tp_pinfo.af_tcp.af_specific;
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
diff -urN linux-2.2.12-pre1/net/ipv4/tcp_ipv4.c linux-2.2.12-pre3/net/ipv4/tcp_ipv4.c
--- linux-2.2.12-pre1/net/ipv4/tcp_ipv4.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/net/ipv4/tcp_ipv4.c	2003-08-15 15:06:49.000000000 -0700
@@ -1026,7 +1026,7 @@
  *
  *  Assumes that the caller did basic address and flag checks.
  */
-static void tcp_v4_send_ack(struct sk_buff *skb, __u32 seq, __u32 ack)
+static void tcp_v4_send_ack(struct sk_buff *skb, __u32 seq, __u32 ack, __u16 window)
 {
 	struct tcphdr *th = skb->h.th;
 	struct tcphdr rth;
@@ -1042,6 +1042,8 @@
 	rth.ack_seq = ack; 
 	rth.ack = 1;
 
+	rth.window = htons(window);
+
 	memset(&arg, 0, sizeof arg); 
 	arg.iov[0].iov_base = (unsigned char *)&rth; 
 	arg.iov[0].iov_len  = sizeof rth;
@@ -1774,10 +1776,12 @@
 do_time_wait:
 	/* Sorry for the ugly switch. 2.3 will have a better solution. */ 
 	switch (tcp_timewait_state_process((struct tcp_tw_bucket *)sk,
-							   skb, th, skb->len)) {
+					   skb, th, skb->len)) {
 	case TCP_TW_ACK:
-		tcp_v4_send_ack(skb, ((struct tcp_tw_bucket *)sk)->snd_nxt,
-						((struct tcp_tw_bucket *)sk)->rcv_nxt); 
+		tcp_v4_send_ack(skb,
+				((struct tcp_tw_bucket *)sk)->snd_nxt,
+				((struct tcp_tw_bucket *)sk)->rcv_nxt,
+				((struct tcp_tw_bucket *)sk)->window);
 		goto discard_it; 
 	case TCP_TW_RST:
 		goto no_tcp_socket; 
diff -urN linux-2.2.12-pre1/net/ipv6/tcp_ipv6.c linux-2.2.12-pre3/net/ipv6/tcp_ipv6.c
--- linux-2.2.12-pre1/net/ipv6/tcp_ipv6.c	2003-08-15 15:06:49.000000000 -0700
+++ linux-2.2.12-pre3/net/ipv6/tcp_ipv6.c	2003-08-15 15:06:49.000000000 -0700
@@ -1121,7 +1121,7 @@
 	kfree_skb(buff);
 }
 
-static void tcp_v6_send_ack(struct sk_buff *skb, __u32 seq, __u32 ack)
+static void tcp_v6_send_ack(struct sk_buff *skb, __u32 seq, __u32 ack, __u16 window)
 {
 	struct tcphdr *th = skb->h.th, *t1; 
 	struct sk_buff *buff;
@@ -1144,6 +1144,8 @@
 	t1->seq = seq;
 	t1->ack_seq = ack; 
 
+	t1->window = htons(window);
+
 	buff->csum = csum_partial((char *)t1, sizeof(*t1), 0);
 
 	fl.nl_u.ip6_u.daddr = &skb->nh.ipv6h->saddr;
@@ -1461,10 +1463,12 @@
 
 do_time_wait:
 	switch (tcp_timewait_state_process((struct tcp_tw_bucket *)sk,
-									   skb, th, skb->len)) {
+					   skb, th, skb->len)) {
 	case TCP_TW_ACK:
-		tcp_v6_send_ack(skb, ((struct tcp_tw_bucket *)sk)->snd_nxt,
-						((struct tcp_tw_bucket *)sk)->rcv_nxt); 
+		tcp_v6_send_ack(skb,
+				((struct tcp_tw_bucket *)sk)->snd_nxt,
+				((struct tcp_tw_bucket *)sk)->rcv_nxt,
+				((struct tcp_tw_bucket *)sk)->window);
 		goto discard_it; 
 	case TCP_TW_RST:
 		goto no_tcp_socket;
