Merge branch 'master' of git://git.denx.de/u-boot-ppc4xx
diff --git a/Makefile b/Makefile
index 536ccb3..ed6156f 100644
--- a/Makefile
+++ b/Makefile
@@ -230,12 +230,10 @@
 LIBS += drivers/qe/qe.a
 LIBS += cpu/mpc8xxx/ddr/libddr.a
 LIBS += cpu/mpc8xxx/lib8xxx.a
-TAG_SUBDIRS += cpu/mpc8xxx
 endif
 ifeq ($(CPU),mpc86xx)
 LIBS += cpu/mpc8xxx/ddr/libddr.a
 LIBS += cpu/mpc8xxx/lib8xxx.a
-TAG_SUBDIRS += cpu/mpc8xxx
 endif
 LIBS += drivers/rtc/librtc.a
 LIBS += drivers/serial/libserial.a
@@ -243,6 +241,7 @@
 LIBS += drivers/usb/gadget/libusb_gadget.a
 LIBS += drivers/usb/host/libusb_host.a
 LIBS += drivers/usb/musb/libusb_musb.a
+LIBS += drivers/usb/phy/libusb_phy.a
 LIBS += drivers/video/libvideo.a
 LIBS += drivers/watchdog/libwatchdog.a
 LIBS += common/libcommon.a
@@ -402,51 +401,19 @@
 depend dep:	$(TIMESTAMP_FILE) $(VERSION_FILE) $(obj)include/autoconf.mk
 		for dir in $(SUBDIRS) ; do $(MAKE) -C $$dir _depend ; done
 
+TAG_SUBDIRS = $(SUBDIRS)
+TAG_SUBDIRS += $(dir $(__LIBS))
 TAG_SUBDIRS += include
-TAG_SUBDIRS += lib_generic board/$(BOARDDIR)
-TAG_SUBDIRS += cpu/$(CPU)
-TAG_SUBDIRS += lib_$(ARCH)
-TAG_SUBDIRS += fs/cramfs
-TAG_SUBDIRS += fs/fat
-TAG_SUBDIRS += fs/fdos
-TAG_SUBDIRS += fs/jffs2
-TAG_SUBDIRS += fs/yaffs2
-TAG_SUBDIRS += net
-TAG_SUBDIRS += disk
-TAG_SUBDIRS += common
-TAG_SUBDIRS += drivers/bios_emulator
-TAG_SUBDIRS += drivers/block
-TAG_SUBDIRS += drivers/gpio
-TAG_SUBDIRS += drivers/hwmon
-TAG_SUBDIRS += drivers/i2c
-TAG_SUBDIRS += drivers/input
-TAG_SUBDIRS += drivers/misc
-TAG_SUBDIRS += drivers/mmc
-TAG_SUBDIRS += drivers/mtd
-TAG_SUBDIRS += drivers/mtd/nand
-TAG_SUBDIRS += drivers/mtd/onenand
-TAG_SUBDIRS += drivers/mtd/spi
-TAG_SUBDIRS += drivers/net
-TAG_SUBDIRS += drivers/net/sk98lin
-TAG_SUBDIRS += drivers/pci
-TAG_SUBDIRS += drivers/pcmcia
-TAG_SUBDIRS += drivers/qe
-TAG_SUBDIRS += drivers/rtc
-TAG_SUBDIRS += drivers/serial
-TAG_SUBDIRS += drivers/spi
-TAG_SUBDIRS += drivers/usb
-TAG_SUBDIRS += drivers/video
 
 tags ctags:
-		ctags -w -o $(obj)ctags `find $(SUBDIRS) $(TAG_SUBDIRS) \
-						-name '*.[ch]' -print`
+		ctags -w -o $(obj)ctags `find $(TAG_SUBDIRS) \
+						-name '*.[chS]' -print`
 
 etags:
-		etags -a -o $(obj)etags `find $(SUBDIRS) $(TAG_SUBDIRS) \
-						-name '*.[ch]' -print`
+		etags -a -o $(obj)etags `find $(TAG_SUBDIRS) \
+						-name '*.[chS]' -print`
 cscope:
-		find $(SUBDIRS) $(TAG_SUBDIRS) -name '*.[ch]' -print \
-						> cscope.files
+		find $(TAG_SUBDIRS) -name '*.[chS]' -print > cscope.files
 		cscope -b -q -k
 
 SYSTEM_MAP = \
diff --git a/board/apollon/apollon.c b/board/apollon/apollon.c
index 8964eba..4768f58 100644
--- a/board/apollon/apollon.c
+++ b/board/apollon/apollon.c
@@ -24,6 +24,7 @@
  * MA 02111-1307 USA
  */
 #include <common.h>
+#include <netdev.h>
 #include <asm/arch/omap2420.h>
 #include <asm/io.h>
 #include <asm/arch/bits.h>
@@ -94,7 +95,6 @@
  ********************************************************/
 int misc_init_r(void)
 {
-	ether_init();		/* better done here so timers are init'ed */
 	return (0);
 }
 
@@ -138,13 +138,14 @@
 }
 
 /*******************************************************************
- * Routine:ether_init
+ * Routine:board_eth_init
  * Description: take the Ethernet controller out of reset and wait
  *		   for the EEPROM load to complete.
  ******************************************************************/
-void ether_init(void)
+int board_eth_init(bd_t *bis)
 {
-#ifdef CONFIG_DRIVER_LAN91C96
+	int rc = 0;
+#ifdef CONFIG_LAN91C96
 	int cnt = 20;
 
 	__raw_writeb(0x03, OMAP2420_CTRL_BASE + 0x0f2);	/*protect->gpio74 */
@@ -171,10 +172,10 @@
 
 	mask_config_reg(ETH_CONTROL_REG, 0x01);
 	udelay(1000);
-
+	rc = lan91c96_initialize(0, CONFIG_LAN91C96_BASE);
 eth_reset_err_out:
-	return;
 #endif
+	return rc;
 }
 
 /**********************************************
diff --git a/board/assabet/assabet.c b/board/assabet/assabet.c
index 6f02db2..753c8d2 100644
--- a/board/assabet/assabet.c
+++ b/board/assabet/assabet.c
@@ -25,6 +25,7 @@
  */
 
 #include <common.h>
+#include <netdev.h>
 #include <SA-1100.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -117,3 +118,14 @@
 
 	return (0);
 }
+
+#ifdef CONFIG_CMD_NET
+int board_eth_init(bd_t *bis)
+{
+	int rc = 0;
+#ifdef CONFIG_LAN91C96
+	rc = lan91c96_initialize(0, CONFIG_LAN91C96_BASE);
+#endif
+	return rc;
+}
+#endif
diff --git a/board/bf527-ezkit/video.c b/board/bf527-ezkit/video.c
index 0b6b7b2..57652be 100644
--- a/board/bf527-ezkit/video.c
+++ b/board/bf527-ezkit/video.c
@@ -16,8 +16,6 @@
 #include <linux/types.h>
 #include <stdio_dev.h>
 
-int gunzip(void *, int, unsigned char *, unsigned long *);
-
 #define DMA_SIZE16	2
 
 #include <asm/mach-common/bits/ppi.h>
diff --git a/board/bf533-stamp/video.c b/board/bf533-stamp/video.c
index 28ffa61..939bd35 100644
--- a/board/bf533-stamp/video.c
+++ b/board/bf533-stamp/video.c
@@ -20,8 +20,6 @@
 #include <linux/types.h>
 #include <stdio_dev.h>
 
-int gunzip(void *, int, unsigned char *, unsigned long *);
-
 #define DMA_SIZE16	2
 
 #include <asm/mach-common/bits/ppi.h>
diff --git a/board/bf548-ezkit/video.c b/board/bf548-ezkit/video.c
index f4f1bec..10b08e2 100644
--- a/board/bf548-ezkit/video.c
+++ b/board/bf548-ezkit/video.c
@@ -16,8 +16,6 @@
 #include <linux/types.h>
 #include <stdio_dev.h>
 
-int gunzip(void *, int, unsigned char *, unsigned long *);
-
 #define DMA_SIZE16	2
 
 #include <asm/mach-common/bits/eppi.h>
diff --git a/board/cm-bf548/video.c b/board/cm-bf548/video.c
index 0787342..4097f09 100644
--- a/board/cm-bf548/video.c
+++ b/board/cm-bf548/video.c
@@ -16,8 +16,6 @@
 #include <linux/types.h>
 #include <stdio_dev.h>
 
-int gunzip(void *, int, unsigned char *, unsigned long *);
-
 #ifdef CONFIG_VIDEO
 
 #define DMA_SIZE16	2
diff --git a/board/dave/B2/B2.c b/board/dave/B2/B2.c
index ec742ad..096ebbd 100644
--- a/board/dave/B2/B2.c
+++ b/board/dave/B2/B2.c
@@ -25,6 +25,7 @@
  */
 
 #include <common.h>
+#include <netdev.h>
 #include <asm/hardware.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -125,3 +126,14 @@
 
 	return (0);
 }
+
+#ifdef CONFIG_CMD_NET
+int board_eth_init(bd_t *bis)
+{
+	int rc = 0;
+#ifdef CONFIG_LAN91C96
+	rc = lan91c96_initialize(0, CONFIG_LAN91C96_BASE);
+#endif
+	return rc;
+}
+#endif
diff --git a/board/dave/PPChameleonEVB/PPChameleonEVB.c b/board/dave/PPChameleonEVB/PPChameleonEVB.c
index 06de6e0..6bc70ef 100644
--- a/board/dave/PPChameleonEVB/PPChameleonEVB.c
+++ b/board/dave/PPChameleonEVB/PPChameleonEVB.c
@@ -33,9 +33,6 @@
 
 /* ------------------------------------------------------------------------- */
 
-/* Prototypes */
-int gunzip(void *, int, unsigned char *, unsigned long *);
-
 int board_early_init_f (void)
 {
 	out32(GPIO0_OR, CONFIG_SYS_NAND0_CE);                 /* set initial outputs     */
diff --git a/board/esd/apc405/apc405.c b/board/esd/apc405/apc405.c
index 409a054..72c0907 100644
--- a/board/esd/apc405/apc405.c
+++ b/board/esd/apc405/apc405.c
@@ -54,9 +54,6 @@
  */
 #include "../common/fpga.c"
 
-/* Prototypes */
-int gunzip(void *, int, unsigned char *, unsigned long *);
-
 #ifdef CONFIG_LCD_USED
 /* logo bitmap data - gzip compressed and generated by bin2c */
 unsigned char logo_bmp[] =
diff --git a/board/esd/ash405/ash405.c b/board/esd/ash405/ash405.c
index 5f0e67c..0615959 100644
--- a/board/esd/ash405/ash405.c
+++ b/board/esd/ash405/ash405.c
@@ -48,10 +48,6 @@
 #include "../common/fpga.c"
 
 
-/* Prototypes */
-int gunzip(void *, int, unsigned char *, unsigned long *);
-
-
 int board_early_init_f (void)
 {
 	/*
diff --git a/board/esd/cpci405/cpci405.c b/board/esd/cpci405/cpci405.c
index c29c876..24db883 100644
--- a/board/esd/cpci405/cpci405.c
+++ b/board/esd/cpci405/cpci405.c
@@ -89,7 +89,6 @@
 
 /* Prototypes */
 int cpci405_version(void);
-int gunzip(void *, int, unsigned char *, unsigned long *);
 void lxt971_no_sleep(void);
 
 int board_early_init_f(void)
diff --git a/board/esd/hh405/hh405.c b/board/esd/hh405/hh405.c
index 132531b..4251d51 100644
--- a/board/esd/hh405/hh405.c
+++ b/board/esd/hh405/hh405.c
@@ -251,10 +251,6 @@
 #include "../common/fpga.c"
 
 
-/* Prototypes */
-int gunzip(void *, int, unsigned char *, unsigned long *);
-
-
 /* logo bitmap data - gzip compressed and generated by bin2c */
 unsigned char logo_bmp_320[] =
 {
diff --git a/board/esd/pci405/pci405.c b/board/esd/pci405/pci405.c
index 34a1632..5364857 100644
--- a/board/esd/pci405/pci405.c
+++ b/board/esd/pci405/pci405.c
@@ -34,7 +34,6 @@
 DECLARE_GLOBAL_DATA_PTR;
 
 /* Prototypes */
-int gunzip(void *, int, unsigned char *, unsigned long *);
 int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 unsigned long fpga_done_state(void);
 unsigned long fpga_init_state(void);
diff --git a/board/esd/plu405/plu405.c b/board/esd/plu405/plu405.c
index fcffdf6..e385a78 100644
--- a/board/esd/plu405/plu405.c
+++ b/board/esd/plu405/plu405.c
@@ -46,9 +46,6 @@
  */
 #include "../common/fpga.c"
 
-/* Prototypes */
-int gunzip(void *, int, unsigned char *, unsigned long *);
-
 int board_early_init_f(void)
 {
 	/*
diff --git a/board/esd/tasreg/tasreg.c b/board/esd/tasreg/tasreg.c
index 1844442..bd9fb2f 100644
--- a/board/esd/tasreg/tasreg.c
+++ b/board/esd/tasreg/tasreg.c
@@ -29,7 +29,6 @@
 
 
 /* Prototypes */
-int gunzip(void *, int, unsigned char *, unsigned long *);
 int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len);
 int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len);
diff --git a/board/esd/voh405/voh405.c b/board/esd/voh405/voh405.c
index 3f81665..a5600de 100644
--- a/board/esd/voh405/voh405.c
+++ b/board/esd/voh405/voh405.c
@@ -48,10 +48,6 @@
 #include "../common/fpga.c"
 
 
-/* Prototypes */
-int gunzip(void *, int, unsigned char *, unsigned long *);
-
-
 /* logo bitmap data - gzip compressed and generated by bin2c */
 unsigned char logo_bmp_320[] =
 {
diff --git a/board/esd/wuh405/wuh405.c b/board/esd/wuh405/wuh405.c
index f2591d5..01966ee 100644
--- a/board/esd/wuh405/wuh405.c
+++ b/board/esd/wuh405/wuh405.c
@@ -46,10 +46,6 @@
 #include "../common/fpga.c"
 
 
-/* Prototypes */
-int gunzip(void *, int, unsigned char *, unsigned long *);
-
-
 int board_early_init_f (void)
 {
 	/*
diff --git a/board/gcplus/gcplus.c b/board/gcplus/gcplus.c
index 829b597..71607f2 100644
--- a/board/gcplus/gcplus.c
+++ b/board/gcplus/gcplus.c
@@ -25,6 +25,7 @@
  */
 
 #include <common.h>
+#include <netdev.h>
 #include <SA-1100.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -68,3 +69,14 @@
 
 	return (0);
 }
+
+#ifdef CONFIG_CMD_NET
+int board_eth_init(bd_t *bis)
+{
+	int rc = 0;
+#ifdef CONFIG_LAN91C96
+	rc = lan91c96_initialize(0, CONFIG_LAN91C96_BASE);
+#endif
+	return rc;
+}
+#endif
diff --git a/board/logicpd/zoom1/zoom1.c b/board/logicpd/zoom1/zoom1.c
index f4d3754..a144f52 100644
--- a/board/logicpd/zoom1/zoom1.c
+++ b/board/logicpd/zoom1/zoom1.c
@@ -31,6 +31,7 @@
  * MA 02111-1307 USA
  */
 #include <common.h>
+#include <netdev.h>
 #include <twl4030.h>
 #include <asm/io.h>
 #include <asm/arch/mux.h>
@@ -86,3 +87,14 @@
 	/* platform specific muxes */
 	MUX_ZOOM1_MDK();
 }
+
+#ifdef CONFIG_CMD_NET
+int board_eth_init(bd_t *bis)
+{
+	int rc = 0;
+#ifdef CONFIG_LAN91C96
+	rc = lan91c96_initialize(0, CONFIG_LAN91C96_BASE);
+#endif
+	return rc;
+}
+#endif
diff --git a/board/logicpd/zoom2/zoom2.c b/board/logicpd/zoom2/zoom2.c
index dadbeb6..21afc29 100644
--- a/board/logicpd/zoom2/zoom2.c
+++ b/board/logicpd/zoom2/zoom2.c
@@ -29,6 +29,7 @@
  * MA 02111-1307 USA
  */
 #include <common.h>
+#include <netdev.h>
 #ifdef CONFIG_STATUS_LED
 #include <status_led.h>
 #endif
@@ -177,3 +178,14 @@
 	/* platform specific muxes */
 	MUX_ZOOM2 ();
 }
+
+#ifdef CONFIG_CMD_NET
+int board_eth_init(bd_t *bis)
+{
+	int rc = 0;
+#ifdef CONFIG_LAN91C96
+	rc = lan91c96_initialize(0, CONFIG_LAN91C96_BASE);
+#endif
+	return rc;
+}
+#endif
diff --git a/board/logicpd/zoom2/zoom2_serial.c b/board/logicpd/zoom2/zoom2_serial.c
index a3d777d..ba58e39 100644
--- a/board/logicpd/zoom2/zoom2_serial.c
+++ b/board/logicpd/zoom2/zoom2_serial.c
@@ -86,6 +86,8 @@
 			quad_putc_dev (base, '\r');
 
 		NS16550_putc ((NS16550_t) base, c);
+	} else {
+		usbtty_putc(c);
 	}
 }
 
@@ -94,6 +96,8 @@
 	if (zoom2_debug_board_connected ()) {
 		while ((s != NULL) && (*s != '\0'))
 			quad_putc_dev (base, *s++);
+	} else {
+		usbtty_puts(s);
 	}
 }
 
@@ -101,16 +105,16 @@
 {
 	if (zoom2_debug_board_connected ())
 		return NS16550_getc ((NS16550_t) base);
-	else
-		return 0;
+
+	return usbtty_getc();
 }
 
 int quad_tstc_dev (unsigned long base)
 {
 	if (zoom2_debug_board_connected ())
 		return NS16550_tstc ((NS16550_t) base);
-	else
-		return 0;
+
+	return usbtty_tstc();
 }
 
 void quad_setbrg_dev (unsigned long base)
diff --git a/board/lubbock/lubbock.c b/board/lubbock/lubbock.c
index 5829170..d8d6ffb 100644
--- a/board/lubbock/lubbock.c
+++ b/board/lubbock/lubbock.c
@@ -26,6 +26,7 @@
  */
 
 #include <common.h>
+#include <netdev.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -68,3 +69,14 @@
 
 	return 0;
 }
+
+#ifdef CONFIG_CMD_NET
+int board_eth_init(bd_t *bis)
+{
+	int rc = 0;
+#ifdef CONFIG_LAN91C96
+	rc = lan91c96_initialize(0, CONFIG_LAN91C96_BASE);
+#endif
+	return rc;
+}
+#endif
diff --git a/board/mpl/common/common_util.c b/board/mpl/common/common_util.c
index 61af4ae..32bf244 100644
--- a/board/mpl/common/common_util.c
+++ b/board/mpl/common/common_util.c
@@ -48,7 +48,6 @@
 #define FIRM_START 0xFFF00000
 #endif
 
-extern int gunzip(void *, int, uchar *, unsigned long *);
 extern int mem_test(ulong start, ulong ramsize, int quiet);
 
 #define I2C_BACKUP_ADDR 0x7C00		/* 0x200 bytes for backup */
diff --git a/board/prodrive/pdnb3/pdnb3.c b/board/prodrive/pdnb3/pdnb3.c
index c323456..69f8f9b 100644
--- a/board/prodrive/pdnb3/pdnb3.c
+++ b/board/prodrive/pdnb3/pdnb3.c
@@ -29,7 +29,6 @@
 DECLARE_GLOBAL_DATA_PTR;
 
 /* Prototypes */
-int gunzip(void *, int, unsigned char *, unsigned long *);
 int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 
 /* predefine these here for FPGA programming (before including fpga.c) */
diff --git a/board/ti/omap1510inn/omap1510innovator.c b/board/ti/omap1510inn/omap1510innovator.c
index 8941209..2cb6062 100644
--- a/board/ti/omap1510inn/omap1510innovator.c
+++ b/board/ti/omap1510inn/omap1510innovator.c
@@ -30,6 +30,7 @@
  */
 
 #include <common.h>
+#include <netdev.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -127,3 +128,14 @@
 
 	return 0;
 }
+
+#ifdef CONFIG_CMD_NET
+int board_eth_init(bd_t *bis)
+{
+	int rc = 0;
+#ifdef CONFIG_LAN91C96
+	rc = lan91c96_initialize(0, CONFIG_LAN91C96_BASE);
+#endif
+	return rc;
+}
+#endif
diff --git a/board/ti/omap1610inn/omap1610innovator.c b/board/ti/omap1610inn/omap1610innovator.c
index 2e04ad4..44818bb 100644
--- a/board/ti/omap1610inn/omap1610innovator.c
+++ b/board/ti/omap1610inn/omap1610innovator.c
@@ -32,6 +32,7 @@
  */
 
 #include <common.h>
+#include <netdev.h>
 #if defined(CONFIG_OMAP1610)
 #include <./configs/omap1510.h>
 #endif
@@ -302,3 +303,14 @@
 
 	*SW_CLOCK_REQUEST |= UART1_48MHZ_ENABLE;
 }
+
+#ifdef CONFIG_CMD_NET
+int board_eth_init(bd_t *bis)
+{
+	int rc = 0;
+#ifdef CONFIG_LAN91C96
+	rc = lan91c96_initialize(0, CONFIG_LAN91C96_BASE);
+#endif
+	return rc;
+}
+#endif
diff --git a/board/ti/omap2420h4/omap2420h4.c b/board/ti/omap2420h4/omap2420h4.c
index 8d18239..1c98e1b 100644
--- a/board/ti/omap2420h4/omap2420h4.c
+++ b/board/ti/omap2420h4/omap2420h4.c
@@ -22,6 +22,7 @@
  * MA 02111-1307 USA
  */
 #include <common.h>
+#include <netdev.h>
 #include <asm/arch/omap2420.h>
 #include <asm/io.h>
 #include <asm/arch/bits.h>
@@ -842,3 +843,14 @@
 		}
 	}
 }
+
+#ifdef CONFIG_CMD_NET
+int board_eth_init(bd_t *bis)
+{
+	int rc = 0;
+#ifdef CONFIG_LAN91C96
+	rc = lan91c96_initialize(0, CONFIG_LAN91C96_BASE);
+#endif
+	return rc;
+}
+#endif
diff --git a/board/ti/omap5912osk/omap5912osk.c b/board/ti/omap5912osk/omap5912osk.c
index 6993b13..cbf451b 100644
--- a/board/ti/omap5912osk/omap5912osk.c
+++ b/board/ti/omap5912osk/omap5912osk.c
@@ -34,6 +34,7 @@
  */
 
 #include <common.h>
+#include <netdev.h>
 #if defined(CONFIG_OMAP1610)
 #include <./configs/omap1510.h>
 #endif
@@ -306,3 +307,14 @@
 
 	return (0);
 }
+
+#ifdef CONFIG_CMD_NET
+int board_eth_init(bd_t *bis)
+{
+	int rc = 0;
+#ifdef CONFIG_LAN91C96
+	rc = lan91c96_initialize(0, CONFIG_LAN91C96_BASE);
+#endif
+	return rc;
+}
+#endif
diff --git a/board/ti/omap730p2/omap730p2.c b/board/ti/omap730p2/omap730p2.c
index 309d667..954ced5 100644
--- a/board/ti/omap730p2/omap730p2.c
+++ b/board/ti/omap730p2/omap730p2.c
@@ -30,6 +30,7 @@
  */
 
 #include <common.h>
+#include <netdev.h>
 #if defined(CONFIG_OMAP730)
 #include <./configs/omap730.h>
 #endif
@@ -263,3 +264,14 @@
 	*MuxConfReg &= (0xFF1FFFFF);
 	*MuxConfReg &= (0xF1FFFFFF);
 }
+
+#ifdef CONFIG_CMD_NET
+int board_eth_init(bd_t *bis)
+{
+	int rc = 0;
+#ifdef CONFIG_LAN91C96
+	rc = lan91c96_initialize(0, CONFIG_LAN91C96_BASE);
+#endif
+	return rc;
+}
+#endif
diff --git a/board/ti/sdp3430/sdp.c b/board/ti/sdp3430/sdp.c
index 40cf26f..0d8e20d 100644
--- a/board/ti/sdp3430/sdp.c
+++ b/board/ti/sdp3430/sdp.c
@@ -22,6 +22,7 @@
  * MA 02111-1307 USA
  */
 #include <common.h>
+#include <netdev.h>
 #include <twl4030.h>
 #include <asm/io.h>
 #include <asm/arch/mux.h>
@@ -125,12 +126,13 @@
 #define ETH_CONTROL_REG		(CONFIG_LAN91C96_BASE + 0x30b)
 
 /**
- * @brief ether_init Take the Ethernet controller out of reset and wait
+ * @brief board_eth_init Take the Ethernet controller out of reset and wait
  * for the EEPROM load to complete.
  */
-static void ether_init(void)
+int board_eth_init(bd_t *bis)
 {
-#ifdef CONFIG_DRIVER_LAN91C96
+	int rc = 0;
+#ifdef CONFIG_LAN91C96
 	int cnt = 20;
 
 	writew(0x0, LAN_RESET_REGISTER);
@@ -155,10 +157,11 @@
 
 	writeb(readb(ETH_CONTROL_REG) & ~0x1, ETH_CONTROL_REG);
 	udelay(1000);
+	rc = lan91c96_initialize(0, CONFIG_LAN91C96_BASE);
 reset_err_out:
-	return;
 
 #endif
+	return rc;
 }
 
 /**
@@ -187,7 +190,6 @@
 	 *   VSIM  - off (init, variable) for MMC1.DAT[3..7], SIM
 	 *   VPLL2 - 1.8V
 	 */
-	ether_init();
 
 	return 0;
 }
diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c
index faa10a4..74ab24c 100644
--- a/common/cmd_bmp.c
+++ b/common/cmd_bmp.c
@@ -35,8 +35,6 @@
 static int bmp_info (ulong addr);
 static int bmp_display (ulong addr, int x, int y);
 
-int gunzip(void *, int, unsigned char *, unsigned long *);
-
 /*
  * Allocate and decompress a BMP image using gunzip().
  *
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index efd6aec..94ddac3 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -63,7 +63,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-extern int gunzip (void *dst, int dstlen, unsigned char *src, unsigned long *lenp);
 #ifndef CONFIG_SYS_BOOTM_LEN
 #define CONFIG_SYS_BOOTM_LEN	0x800000	/* use 8MByte as default max gunzip size */
 #endif
diff --git a/common/cmd_license.c b/common/cmd_license.c
index c6f272a..85a4871 100644
--- a/common/cmd_license.c
+++ b/common/cmd_license.c
@@ -29,7 +29,6 @@
 #include <command.h>
 #include <malloc.h>
 #include <license.h>
-int gunzip(void *, int, unsigned char *, unsigned long *);
 
 int do_license(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
diff --git a/common/cmd_mem.c b/common/cmd_mem.c
index a34b342..1839330 100644
--- a/common/cmd_mem.c
+++ b/common/cmd_mem.c
@@ -1225,8 +1225,6 @@
 #endif
 
 #ifdef CONFIG_CMD_UNZIP
-int  gunzip (void *, int, unsigned char *, unsigned long *);
-
 int do_unzip ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
 	unsigned long src, dst;
diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 7b8ee6b..9de515c 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -157,7 +157,7 @@
 {
 	if (dev->descriptor.bDescriptorType == USB_DT_DEVICE) {
 		printf("%d: %s,  USB Revision %x.%x\n", dev->devnum,
-		usb_get_class_desc(dev->config.if_desc[0].bInterfaceClass),
+		usb_get_class_desc(dev->config.if_desc[0].desc.bInterfaceClass),
 				   (dev->descriptor.bcdUSB>>8) & 0xff,
 				   dev->descriptor.bcdUSB & 0xff);
 
@@ -174,7 +174,7 @@
 		} else {
 			printf(" - Class: (from Interface) %s\n",
 			       usb_get_class_desc(
-				dev->config.if_desc[0].bInterfaceClass));
+				dev->config.if_desc[0].desc.bInterfaceClass));
 		}
 		printf(" - PacketSize: %d  Configurations: %d\n",
 			dev->descriptor.bMaxPacketSize0,
@@ -187,14 +187,14 @@
 
 }
 
-void usb_display_conf_desc(struct usb_config_descriptor *config,
+void usb_display_conf_desc(struct usb_configuration_descriptor *config,
 			   struct usb_device *dev)
 {
 	printf("   Configuration: %d\n", config->bConfigurationValue);
 	printf("   - Interfaces: %d %s%s%dmA\n", config->bNumInterfaces,
 	       (config->bmAttributes & 0x40) ? "Self Powered " : "Bus Powered ",
 	       (config->bmAttributes & 0x20) ? "Remote Wakeup " : "",
-		config->MaxPower*2);
+		config->bMaxPower*2);
 	if (config->iConfiguration) {
 		printf("   - ");
 		usb_display_string(dev, config->iConfiguration);
@@ -246,16 +246,16 @@
 /* main routine to diasplay the configs, interfaces and endpoints */
 void usb_display_config(struct usb_device *dev)
 {
-	struct usb_config_descriptor *config;
-	struct usb_interface_descriptor *ifdesc;
+	struct usb_config *config;
+	struct usb_interface *ifdesc;
 	struct usb_endpoint_descriptor *epdesc;
 	int i, ii;
 
 	config = &dev->config;
-	usb_display_conf_desc(config, dev);
+	usb_display_conf_desc(&config->desc, dev);
 	for (i = 0; i < config->no_of_if; i++) {
 		ifdesc = &config->if_desc[i];
-		usb_display_if_desc(ifdesc, dev);
+		usb_display_if_desc(&ifdesc->desc, dev);
 		for (ii = 0; ii < ifdesc->no_of_ep; ii++) {
 			epdesc = &ifdesc->ep_desc[ii];
 			usb_display_ep_desc(epdesc);
@@ -319,9 +319,9 @@
 	pre[index++] = has_child ? '|' : ' ';
 	pre[index] = 0;
 	printf(" %s (%s, %dmA)\n", usb_get_class_desc(
-					dev->config.if_desc[0].bInterfaceClass),
+					dev->config.if_desc[0].desc.bInterfaceClass),
 					portspeed(dev->speed),
-					dev->config.MaxPower * 2);
+					dev->config.desc.bMaxPower * 2);
 	if (strlen(dev->mf) || strlen(dev->prod) || strlen(dev->serial))
 		printf(" %s  %s %s %s\n", pre, dev->mf, dev->prod, dev->serial);
 	printf(" %s\n", pre);
@@ -642,6 +642,28 @@
 			return 1;
 		}
 	}
+	if (strcmp(argv[1], "write") == 0) {
+		if (usb_stor_curr_dev < 0) {
+			printf("no current device selected\n");
+			return 1;
+		}
+		if (argc == 5) {
+			unsigned long addr = simple_strtoul(argv[2], NULL, 16);
+			unsigned long blk  = simple_strtoul(argv[3], NULL, 16);
+			unsigned long cnt  = simple_strtoul(argv[4], NULL, 16);
+			unsigned long n;
+			printf("\nUSB write: device %d block # %ld, count %ld"
+				" ... ", usb_stor_curr_dev, blk, cnt);
+			stor_dev = usb_stor_get_dev(usb_stor_curr_dev);
+			n = stor_dev->block_write(usb_stor_curr_dev, blk, cnt,
+						(ulong *)addr);
+			printf("%ld blocks write: %s\n", n,
+				(n == cnt) ? "OK" : "ERROR");
+			if (n == cnt)
+				return 0;
+			return 1;
+		}
+	}
 	if (strncmp(argv[1], "dev", 3) == 0) {
 		if (argc == 3) {
 			int dev = (int)simple_strtoul(argv[2], NULL, 10);
@@ -687,6 +709,8 @@
 	" devices\n"
 	"usb read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n"
 	"    to memory address `addr'"
+	"usb write addr blk# cnt - write `cnt' blocks starting at block `blk#'\n"
+	"    from memory address `addr'"
 );
 
 
diff --git a/common/usb.c b/common/usb.c
index 87fca70..eef4b34 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -299,8 +299,8 @@
 {
 	int i, ii;
 
-	for (i = 0; i < dev->config.bNumInterfaces; i++)
-		for (ii = 0; ii < dev->config.if_desc[i].bNumEndpoints; ii++)
+	for (i = 0; i < dev->config.desc.bNumInterfaces; i++)
+		for (ii = 0; ii < dev->config.if_desc[i].desc.bNumEndpoints; ii++)
 			usb_set_maxpacket_ep(dev,
 					  &dev->config.if_desc[i].ep_desc[ii]);
 
@@ -330,14 +330,14 @@
 		return -1;
 	}
 	memcpy(&dev->config, buffer, buffer[0]);
-	le16_to_cpus(&(dev->config.wTotalLength));
+	le16_to_cpus(&(dev->config.desc.wTotalLength));
 	dev->config.no_of_if = 0;
 
-	index = dev->config.bLength;
+	index = dev->config.desc.bLength;
 	/* Ok the first entry must be a configuration entry,
 	 * now process the others */
 	head = (struct usb_descriptor_header *) &buffer[index];
-	while (index + 1 < dev->config.wTotalLength) {
+	while (index + 1 < dev->config.desc.wTotalLength) {
 		switch (head->bDescriptorType) {
 		case USB_DT_INTERFACE:
 			if (((struct usb_interface_descriptor *) \
@@ -350,7 +350,7 @@
 				dev->config.if_desc[ifno].no_of_ep = 0;
 				dev->config.if_desc[ifno].num_altsetting = 1;
 				curr_if_num =
-				     dev->config.if_desc[ifno].bInterfaceNumber;
+				     dev->config.if_desc[ifno].desc.bInterfaceNumber;
 			} else {
 				/* found alternate setting for the interface */
 				dev->config.if_desc[ifno].num_altsetting++;
@@ -440,10 +440,9 @@
 {
 	int result;
 	unsigned int tmp;
-	struct usb_config_descriptor *config;
+	struct usb_configuration_descriptor *config;
 
-
-	config = (struct usb_config_descriptor *)&buffer[0];
+	config = (struct usb_configuration_descriptor *)&buffer[0];
 	result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 9);
 	if (result < 9) {
 		if (result < 0)
@@ -489,11 +488,11 @@
  */
 int usb_set_interface(struct usb_device *dev, int interface, int alternate)
 {
-	struct usb_interface_descriptor *if_face = NULL;
+	struct usb_interface *if_face = NULL;
 	int ret, i;
 
-	for (i = 0; i < dev->config.bNumInterfaces; i++) {
-		if (dev->config.if_desc[i].bInterfaceNumber == interface) {
+	for (i = 0; i < dev->config.desc.bNumInterfaces; i++) {
+		if (dev->config.if_desc[i].desc.bInterfaceNumber == interface) {
 			if_face = &dev->config.if_desc[i];
 			break;
 		}
@@ -897,7 +896,7 @@
 	usb_parse_config(dev, &tmpbuf[0], 0);
 	usb_set_maxpacket(dev);
 	/* we set the default configuration here */
-	if (usb_set_configuration(dev, dev->config.bConfigurationValue)) {
+	if (usb_set_configuration(dev, dev->config.desc.bConfigurationValue)) {
 		printf("failed to set default configuration " \
 			"len %d, status %lX\n", dev->act_len, dev->status);
 		return -1;
@@ -1347,21 +1346,21 @@
 
 int usb_hub_probe(struct usb_device *dev, int ifnum)
 {
-	struct usb_interface_descriptor *iface;
+	struct usb_interface *iface;
 	struct usb_endpoint_descriptor *ep;
 	int ret;
 
 	iface = &dev->config.if_desc[ifnum];
 	/* Is it a hub? */
-	if (iface->bInterfaceClass != USB_CLASS_HUB)
+	if (iface->desc.bInterfaceClass != USB_CLASS_HUB)
 		return 0;
 	/* Some hubs have a subclass of 1, which AFAICT according to the */
 	/*  specs is not defined, but it works */
-	if ((iface->bInterfaceSubClass != 0) &&
-	    (iface->bInterfaceSubClass != 1))
+	if ((iface->desc.bInterfaceSubClass != 0) &&
+	    (iface->desc.bInterfaceSubClass != 1))
 		return 0;
 	/* Multiple endpoints? What kind of mutant ninja-hub is this? */
-	if (iface->bNumEndpoints != 1)
+	if (iface->desc.bNumEndpoints != 1)
 		return 0;
 	ep = &iface->ep_desc[0];
 	/* Output endpoint? Curiousier and curiousier.. */
diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index b458d77..9957dcc 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -229,7 +229,7 @@
 
 static void usb_kbd_setled(struct usb_device *dev)
 {
-	struct usb_interface_descriptor *iface;
+	struct usb_interface *iface;
 	iface = &dev->config.if_desc[0];
 	leds=0;
 	if(scroll_lock!=0)
@@ -242,7 +242,7 @@
 		leds|=1;
 	usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 		USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
-		0x200, iface->bInterfaceNumber,(void *)&leds, 1, 0);
+		0x200, iface->desc.bInterfaceNumber, (void *)&leds, 1, 0);
 
 }
 
@@ -348,17 +348,21 @@
 /* probes the USB device dev for keyboard type */
 static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum)
 {
-	struct usb_interface_descriptor *iface;
+	struct usb_interface *iface;
 	struct usb_endpoint_descriptor *ep;
 	int pipe,maxp;
 
 	if (dev->descriptor.bNumConfigurations != 1) return 0;
 	iface = &dev->config.if_desc[ifnum];
 
-	if (iface->bInterfaceClass != 3) return 0;
-	if (iface->bInterfaceSubClass != 1) return 0;
-	if (iface->bInterfaceProtocol != 1) return 0;
-	if (iface->bNumEndpoints != 1) return 0;
+	if (iface->desc.bInterfaceClass != 3)
+		return 0;
+	if (iface->desc.bInterfaceSubClass != 1)
+		return 0;
+	if (iface->desc.bInterfaceProtocol != 1)
+		return 0;
+	if (iface->desc.bNumEndpoints != 1)
+		return 0;
 
 	ep = &iface->ep_desc[0];
 
@@ -367,9 +371,9 @@
 	USB_KBD_PRINTF("USB KBD found set protocol...\n");
 	/* ok, we found a USB Keyboard, install it */
 	/* usb_kbd_get_hid_desc(dev); */
-	usb_set_protocol(dev, iface->bInterfaceNumber, 0);
+	usb_set_protocol(dev, iface->desc.bInterfaceNumber, 0);
 	USB_KBD_PRINTF("USB KBD found set idle...\n");
-	usb_set_idle(dev, iface->bInterfaceNumber, REPEAT_RATE, 0);
+	usb_set_idle(dev, iface->desc.bInterfaceNumber, REPEAT_RATE, 0);
 	memset(&new[0], 0, 8);
 	memset(&old[0], 0, 8);
 	repeat_delay=0;
diff --git a/common/usb_storage.c b/common/usb_storage.c
index 19613f2..a8642c9 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -168,6 +168,8 @@
 		      struct us_data *ss);
 unsigned long usb_stor_read(int device, unsigned long blknr,
 			    unsigned long blkcnt, void *buffer);
+unsigned long usb_stor_write(int device, unsigned long blknr,
+			     unsigned long blkcnt, const void *buffer);
 struct usb_device * usb_get_dev_index(int index);
 void uhci_show_temp_int_td(void);
 
@@ -227,6 +229,7 @@
 		usb_dev_desc[i].dev = i;
 		usb_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
 		usb_dev_desc[i].block_read = usb_stor_read;
+		usb_dev_desc[i].block_write = usb_stor_write;
 	}
 
 	usb_max_devs = 0;
@@ -964,6 +967,22 @@
 	return ss->transport(srb, ss);
 }
 
+static int usb_write_10(ccb *srb, struct us_data *ss, unsigned long start,
+			unsigned short blocks)
+{
+	memset(&srb->cmd[0], 0, 12);
+	srb->cmd[0] = SCSI_WRITE10;
+	srb->cmd[2] = ((unsigned char) (start >> 24)) & 0xff;
+	srb->cmd[3] = ((unsigned char) (start >> 16)) & 0xff;
+	srb->cmd[4] = ((unsigned char) (start >> 8)) & 0xff;
+	srb->cmd[5] = ((unsigned char) (start)) & 0xff;
+	srb->cmd[7] = ((unsigned char) (blocks >> 8)) & 0xff;
+	srb->cmd[8] = (unsigned char) blocks & 0xff;
+	srb->cmdlen = 12;
+	USB_STOR_PRINTF("write10: start %lx blocks %x\n", start, blocks);
+	return ss->transport(srb, ss);
+}
+
 
 #ifdef CONFIG_USB_BIN_FIXUP
 /*
@@ -1065,12 +1084,92 @@
 	return blkcnt;
 }
 
+#define USB_MAX_WRITE_BLK 20
+
+unsigned long usb_stor_write(int device, unsigned long blknr,
+				unsigned long blkcnt, const void *buffer)
+{
+	unsigned long start, blks, buf_addr;
+	unsigned short smallblks;
+	struct usb_device *dev;
+	int retry, i;
+	ccb *srb = &usb_ccb;
+
+	if (blkcnt == 0)
+		return 0;
+
+	device &= 0xff;
+	/* Setup  device */
+	USB_STOR_PRINTF("\nusb_write: dev %d \n", device);
+	dev = NULL;
+	for (i = 0; i < USB_MAX_DEVICE; i++) {
+		dev = usb_get_dev_index(i);
+		if (dev == NULL)
+			return 0;
+		if (dev->devnum == usb_dev_desc[device].target)
+			break;
+	}
+
+	usb_disable_asynch(1); /* asynch transfer not allowed */
+
+	srb->lun = usb_dev_desc[device].lun;
+	buf_addr = (unsigned long)buffer;
+	start = blknr;
+	blks = blkcnt;
+	if (usb_test_unit_ready(srb, (struct us_data *)dev->privptr)) {
+		printf("Device NOT ready\n   Request Sense returned %02X %02X"
+		       " %02X\n", srb->sense_buf[2], srb->sense_buf[12],
+			srb->sense_buf[13]);
+		return 0;
+	}
+
+	USB_STOR_PRINTF("\nusb_write: dev %d startblk %lx, blccnt %lx"
+			" buffer %lx\n", device, start, blks, buf_addr);
+
+	do {
+		/* If write fails retry for max retry count else
+		 * return with number of blocks written successfully.
+		 */
+		retry = 2;
+		srb->pdata = (unsigned char *)buf_addr;
+		if (blks > USB_MAX_WRITE_BLK)
+			smallblks = USB_MAX_WRITE_BLK;
+		else
+			smallblks = (unsigned short) blks;
+retry_it:
+		if (smallblks == USB_MAX_WRITE_BLK)
+			usb_show_progress();
+		srb->datalen = usb_dev_desc[device].blksz * smallblks;
+		srb->pdata = (unsigned char *)buf_addr;
+		if (usb_write_10(srb, (struct us_data *)dev->privptr, start,
+		    smallblks)) {
+			USB_STOR_PRINTF("Write ERROR\n");
+			usb_request_sense(srb, (struct us_data *)dev->privptr);
+			if (retry--)
+				goto retry_it;
+			blkcnt -= blks;
+			break;
+		}
+		start += smallblks;
+		blks -= smallblks;
+		buf_addr += srb->datalen;
+	} while (blks != 0);
+
+	USB_STOR_PRINTF("usb_write: end startblk %lx, blccnt %x buffer %lx\n",
+			start, smallblks, buf_addr);
+
+	usb_disable_asynch(0); /* asynch transfer allowed */
+	if (blkcnt >= USB_MAX_WRITE_BLK)
+		printf("\n");
+	return blkcnt;
+
+}
 
 /* Probe to see if a new device is actually a Storage device */
 int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
 		      struct us_data *ss)
 {
-	struct usb_interface_descriptor *iface;
+	struct usb_interface *iface;
 	int i;
 	unsigned int flags = 0;
 
@@ -1094,9 +1193,9 @@
 #endif
 
 	if (dev->descriptor.bDeviceClass != 0 ||
-			iface->bInterfaceClass != USB_CLASS_MASS_STORAGE ||
-			iface->bInterfaceSubClass < US_SC_MIN ||
-			iface->bInterfaceSubClass > US_SC_MAX) {
+			iface->desc.bInterfaceClass != USB_CLASS_MASS_STORAGE ||
+			iface->desc.bInterfaceSubClass < US_SC_MIN ||
+			iface->desc.bInterfaceSubClass > US_SC_MAX) {
 		/* if it's not a mass storage, we go no further */
 		return 0;
 	}
@@ -1119,8 +1218,8 @@
 		ss->subclass = subclass;
 		ss->protocol = protocol;
 	} else {
-		ss->subclass = iface->bInterfaceSubClass;
-		ss->protocol = iface->bInterfaceProtocol;
+		ss->subclass = iface->desc.bInterfaceSubClass;
+		ss->protocol = iface->desc.bInterfaceProtocol;
 	}
 
 	/* set the handler pointers based on the protocol */
@@ -1153,7 +1252,7 @@
 	 * An optional interrupt is OK (necessary for CBI protocol).
 	 * We will ignore any others.
 	 */
-	for (i = 0; i < iface->bNumEndpoints; i++) {
+	for (i = 0; i < iface->desc.bNumEndpoints; i++) {
 		/* is it an BULK endpoint? */
 		if ((iface->ep_desc[i].bmAttributes &
 		     USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
@@ -1178,7 +1277,7 @@
 		  ss->ep_in, ss->ep_out, ss->ep_int);
 
 	/* Do some basic sanity checks, and bail if we find a problem */
-	if (usb_set_interface(dev, iface->bInterfaceNumber, 0) ||
+	if (usb_set_interface(dev, iface->desc.bInterfaceNumber, 0) ||
 	    !ss->ep_in || !ss->ep_out ||
 	    (ss->protocol == US_PR_CBI && ss->ep_int == 0)) {
 		USB_STOR_PRINTF("Problems with device\n");
diff --git a/cpu/ppc4xx/usbdev.c b/cpu/ppc4xx/usbdev.c
index 5bb4f3c..fe398af 100644
--- a/cpu/ppc4xx/usbdev.c
+++ b/cpu/ppc4xx/usbdev.c
@@ -21,7 +21,7 @@
 {
 	/*will hold the packet received */
 	struct usb_device_descriptor usb_device_packet;
-	struct usb_config_descriptor usb_config_packet;
+	struct usb_configuration_descriptor usb_config_packet;
 	struct usb_string_descriptor usb_string_packet;
 	struct devrequest setup_packet;
 	unsigned int *setup_packet_pt;
@@ -99,7 +99,7 @@
 				usb_config_packet.bConfigurationValue = 1;
 				usb_config_packet.iConfiguration = 0;
 				usb_config_packet.bmAttributes = 0x40;
-				usb_config_packet.MaxPower = 0;
+				usb_config_packet.bMaxPower = 0;
 
 				/*put packet in fifo */
 				packet_pt = (unsigned char *)&usb_config_packet;
diff --git a/drivers/bios_emulator/Makefile b/drivers/bios_emulator/Makefile
index dd9c102..feba4da 100644
--- a/drivers/bios_emulator/Makefile
+++ b/drivers/bios_emulator/Makefile
@@ -23,6 +23,7 @@
 
 CFLAGS += $(EXTRA_CFLAGS)
 HOSTCFLAGS += $(EXTRA_CFLAGS)
+CPPFLAGS += $(EXTRA_CFLAGS)
 
 all:	$(LIB)
 
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index fc9887b..904727e 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -44,7 +44,7 @@
 COBJS-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o
 COBJS-$(CONFIG_KIRKWOOD_EGIGA) += kirkwood_egiga.o
 COBJS-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o
-COBJS-$(CONFIG_DRIVER_LAN91C96) += lan91c96.o
+COBJS-$(CONFIG_LAN91C96) += lan91c96.o
 COBJS-$(CONFIG_MACB) += macb.o
 COBJS-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o
 COBJS-$(CONFIG_MPC5xxx_FEC) += mpc5xxx_fec.o
diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c
index 73dd335..a7fef56 100644
--- a/drivers/net/dm9000x.c
+++ b/drivers/net/dm9000x.c
@@ -75,7 +75,7 @@
 #define DM9000_DMP_PACKET(func,packet,length)  \
 	do { \
 		int i; 							\
-		printf(func ": length: %d\n", length);			\
+		printf("%s: length: %d\n", func, length);		\
 		for (i = 0; i < length; i++) {				\
 			if (i % 8 == 0)					\
 				printf("\n%s: %02x: ", func, i);	\
diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c
index 7f9f783..2825342 100644
--- a/drivers/net/e1000.c
+++ b/drivers/net/e1000.c
@@ -79,6 +79,7 @@
 	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_COPPER},
 	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_FIBER},
 	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_FIBER},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546GB_COPPER},
 	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM_LOM},
 	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541ER},
 	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541GI_LF},
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index ad07307..19116f2 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -450,6 +450,7 @@
 	 */
 	if (fec_rbd_init(fec, FEC_RBD_NUM, FEC_MAX_PKT_SIZE) < 0) {
 		free(fec->base_ptr);
+		fec->base_ptr = NULL;
 		return -ENOMEM;
 	}
 	fec_tbd_init(fec);
diff --git a/drivers/net/lan91c96.c b/drivers/net/lan91c96.c
index 65565bc..90e4002 100644
--- a/drivers/net/lan91c96.c
+++ b/drivers/net/lan91c96.c
@@ -60,6 +60,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <malloc.h>
 #include "lan91c96.h"
 #include <net.h>
 
@@ -108,11 +109,7 @@
  *
  *------------------------------------------------------------------------
  */
-#define CARDNAME "LAN91C96"
-
-#define SMC_BASE_ADDRESS CONFIG_LAN91C96_BASE
-
-#define SMC_DEV_NAME "LAN91C96"
+#define DRIVER_NAME "LAN91C96"
 #define SMC_ALLOC_MAX_TRY 5
 #define SMC_TX_TIMEOUT 30
 
@@ -124,64 +121,12 @@
 #undef USE_32_BIT
 #endif
 
-/*-----------------------------------------------------------------
- *
- *  The driver can be entered at any of the following entry points.
- *
- *-----------------------------------------------------------------
- */
-
-extern int eth_init (bd_t * bd);
-extern void eth_halt (void);
-extern int eth_rx (void);
-extern int eth_send (volatile void *packet, int length);
-#if 0
-static int smc_hw_init (void);
-#endif
-
-/*
- * This is called by  register_netdev().  It is responsible for
- * checking the portlist for the SMC9000 series chipset.  If it finds
- * one, then it will initialize the device, find the hardware information,
- * and sets up the appropriate device parameters.
- * NOTE: Interrupts are *OFF* when this procedure is called.
- *
- * NB:This shouldn't be static since it is referred to externally.
- */
-int smc_init (void);
-
-/*
- * This is called by  unregister_netdev().  It is responsible for
- * cleaning up before the driver is finally unregistered and discarded.
- */
-void smc_destructor (void);
-
-/*
- * The kernel calls this function when someone wants to use the device,
- * typically 'ifconfig ethX up'.
- */
-static int smc_open (bd_t *bd);
-
-
-/*
- * This is called by the kernel in response to 'ifconfig ethX down'.  It
- * is responsible for cleaning up everything that the open routine
- * does, and maybe putting the card into a powerdown state.
- */
-static int smc_close (void);
-
-/*
- * This is a separate procedure to handle the receipt of a packet, to
- * leave the interrupt code looking slightly cleaner
- */
-static int smc_rcv (void);
-
 /* See if a MAC address is defined in the current environment. If so use it. If not
  . print a warning and set the environment and other globals with the default.
  . If an EEPROM is present it really should be consulted.
 */
-int smc_get_ethaddr(bd_t *bd);
-int get_rom_mac(unsigned char *v_rom_mac);
+static int smc_get_ethaddr(bd_t *bd, struct eth_device *dev);
+static int get_rom_mac(struct eth_device *dev, unsigned char *v_rom_mac);
 
 /* ------------------------------------------------------------
  * Internal routines
@@ -195,7 +140,7 @@
  * the default mac address.
  */
 
-void smc_set_mac_addr (const unsigned char *addr)
+static void smc_set_mac_addr(const unsigned char *addr)
 {
 	int i;
 
@@ -203,46 +148,22 @@
 		smc_mac_addr[i] = addr[i];
 	}
 }
-
-/*
- * smc_get_macaddr is no longer used. If you want to override the default
- * mac address, call smc_get_mac_addr as a part of the board initialisation.
- */
-
-#if 0
-void smc_get_macaddr (byte * addr)
-{
-	/* MAC ADDRESS AT FLASHBLOCK 1 / OFFSET 0x10 */
-	unsigned char *dnp1110_mac = (unsigned char *) (0xE8000000 + 0x20010);
-	int i;
-
-
-	for (i = 0; i < 6; i++) {
-		addr[0] = *(dnp1110_mac + 0);
-		addr[1] = *(dnp1110_mac + 1);
-		addr[2] = *(dnp1110_mac + 2);
-		addr[3] = *(dnp1110_mac + 3);
-		addr[4] = *(dnp1110_mac + 4);
-		addr[5] = *(dnp1110_mac + 5);
-	}
-}
-#endif /* 0 */
 
 /***********************************************
  * Show available memory                       *
  ***********************************************/
-void dump_memory_info (void)
+void dump_memory_info(struct eth_device *dev)
 {
 	word mem_info;
 	word old_bank;
 
-	old_bank = SMC_inw (LAN91C96_BANK_SELECT) & 0xF;
+	old_bank = SMC_inw(dev, LAN91C96_BANK_SELECT) & 0xF;
 
-	SMC_SELECT_BANK (0);
-	mem_info = SMC_inw (LAN91C96_MIR);
+	SMC_SELECT_BANK(dev, 0);
+	mem_info = SMC_inw(dev, LAN91C96_MIR);
 	PRINTK2 ("Memory: %4d available\n", (mem_info >> 8) * 2048);
 
-	SMC_SELECT_BANK (old_bank);
+	SMC_SELECT_BANK(dev, old_bank);
 }
 
 /*
@@ -252,28 +173,15 @@
 static void print_packet (byte *, int);
 #endif
 
-/* #define tx_done(dev) 1 */
-
-
-/* this does a soft reset on the device */
-static void smc_reset (void);
-
-/* Enable Interrupts, Receive, and Transmit */
-static void smc_enable (void);
-
-/* this puts the device in an inactive state */
-static void smc_shutdown (void);
-
-
-static int poll4int (byte mask, int timeout)
+static int poll4int (struct eth_device *dev, byte mask, int timeout)
 {
 	int tmo = get_timer (0) + timeout * CONFIG_SYS_HZ;
 	int is_timeout = 0;
-	word old_bank = SMC_inw (LAN91C96_BANK_SELECT);
+	word old_bank = SMC_inw(dev, LAN91C96_BANK_SELECT);
 
 	PRINTK2 ("Polling...\n");
-	SMC_SELECT_BANK (2);
-	while ((SMC_inw (LAN91C96_INT_STATS) & mask) == 0) {
+	SMC_SELECT_BANK(dev, 2);
+	while ((SMC_inw(dev, LAN91C96_INT_STATS) & mask) == 0) {
 		if (get_timer (0) >= tmo) {
 			is_timeout = 1;
 			break;
@@ -281,7 +189,7 @@
 	}
 
 	/* restore old bank selection */
-	SMC_SELECT_BANK (old_bank);
+	SMC_SELECT_BANK(dev, old_bank);
 
 	if (is_timeout)
 		return 1;
@@ -290,7 +198,7 @@
 }
 
 /*
- * Function: smc_reset( void )
+ * Function: smc_reset
  * Purpose:
  *	This sets the SMC91111 chip to its normal state, hopefully from whatever
  *	mess that any other DOS driver has put it in.
@@ -306,28 +214,28 @@
  *	5.  clear all interrupts
  *
 */
-static void smc_reset (void)
+static void smc_reset(struct eth_device *dev)
 {
-	PRINTK2 ("%s:smc_reset\n", SMC_DEV_NAME);
+	PRINTK2("%s:smc_reset\n", dev->name);
 
 	/* This resets the registers mostly to defaults, but doesn't
 	   affect EEPROM.  That seems unnecessary */
-	SMC_SELECT_BANK (0);
-	SMC_outw (LAN91C96_RCR_SOFT_RST, LAN91C96_RCR);
+	SMC_SELECT_BANK(dev, 0);
+	SMC_outw(dev, LAN91C96_RCR_SOFT_RST, LAN91C96_RCR);
 
 	udelay (10);
 
 	/* Disable transmit and receive functionality */
-	SMC_outw (0, LAN91C96_RCR);
-	SMC_outw (0, LAN91C96_TCR);
+	SMC_outw(dev, 0, LAN91C96_RCR);
+	SMC_outw(dev, 0, LAN91C96_TCR);
 
 	/* set the control register */
-	SMC_SELECT_BANK (1);
-	SMC_outw (SMC_inw (LAN91C96_CONTROL) | LAN91C96_CTR_BIT_8,
+	SMC_SELECT_BANK(dev, 1);
+	SMC_outw(dev, SMC_inw(dev, LAN91C96_CONTROL) | LAN91C96_CTR_BIT_8,
 			  LAN91C96_CONTROL);
 
 	/* Disable all interrupts */
-	SMC_outb (0, LAN91C96_INT_MASK);
+	SMC_outb(dev, 0, LAN91C96_INT_MASK);
 }
 
 /*
@@ -338,24 +246,24 @@
  *	2.  Enable the transmitter
  *	3.  Enable the receiver
 */
-static void smc_enable ()
+static void smc_enable(struct eth_device *dev)
 {
-	PRINTK2 ("%s:smc_enable\n", SMC_DEV_NAME);
-	SMC_SELECT_BANK (0);
+	PRINTK2("%s:smc_enable\n", dev->name);
+	SMC_SELECT_BANK(dev, 0);
 
 	/* Initialize the Memory Configuration Register. See page
 	   49 of the LAN91C96 data sheet for details. */
-	SMC_outw (LAN91C96_MCR_TRANSMIT_PAGES, LAN91C96_MCR);
+	SMC_outw(dev, LAN91C96_MCR_TRANSMIT_PAGES, LAN91C96_MCR);
 
 	/* Initialize the Transmit Control Register */
-	SMC_outw (LAN91C96_TCR_TXENA, LAN91C96_TCR);
+	SMC_outw(dev, LAN91C96_TCR_TXENA, LAN91C96_TCR);
 	/* Initialize the Receive Control Register
 	 * FIXME:
 	 * The promiscuous bit set because I could not receive ARP reply
 	 * packets from the server when I send a ARP request. It only works
 	 * when I set the promiscuous bit
 	 */
-	SMC_outw (LAN91C96_RCR_RXEN | LAN91C96_RCR_PRMS, LAN91C96_RCR);
+	SMC_outw(dev, LAN91C96_RCR_RXEN | LAN91C96_RCR_PRMS, LAN91C96_RCR);
 }
 
 /*
@@ -372,18 +280,18 @@
  *	the manual says that it will wake up in response to any I/O requests
  *	in the register space.   Empirical results do not show this working.
  */
-static void smc_shutdown ()
+static void smc_shutdown(struct eth_device *dev)
 {
-	PRINTK2 (CARDNAME ":smc_shutdown\n");
+	PRINTK2("%s:smc_shutdown\n", dev->name);
 
 	/* no more interrupts for me */
-	SMC_SELECT_BANK (2);
-	SMC_outb (0, LAN91C96_INT_MASK);
+	SMC_SELECT_BANK(dev, 2);
+	SMC_outb(dev, 0, LAN91C96_INT_MASK);
 
 	/* and tell the card to stay away from that nasty outside world */
-	SMC_SELECT_BANK (0);
-	SMC_outb (0, LAN91C96_RCR);
-	SMC_outb (0, LAN91C96_TCR);
+	SMC_SELECT_BANK(dev, 0);
+	SMC_outb(dev, 0, LAN91C96_RCR);
+	SMC_outb(dev, 0, LAN91C96_TCR);
 }
 
 
@@ -405,7 +313,8 @@
  *	Enable the transmit interrupt, so I know if it failed
  *	Free the kernel data if I actually sent it.
  */
-static int smc_send_packet (volatile void *packet, int packet_length)
+static int smc_send_packet(struct eth_device *dev, volatile void *packet,
+		int packet_length)
 {
 	byte packet_no;
 	unsigned long ioaddr;
@@ -417,7 +326,7 @@
 	byte status;
 
 
-	PRINTK3 ("%s:smc_hardware_send_packet\n", SMC_DEV_NAME);
+	PRINTK3("%s:smc_hardware_send_packet\n", dev->name);
 
 	length = ETH_ZLEN < packet_length ? packet_length : ETH_ZLEN;
 
@@ -437,30 +346,31 @@
 	numPages >>= 8;				/* Divide by 256 */
 
 	if (numPages > 7) {
-		printf ("%s: Far too big packet error. \n", SMC_DEV_NAME);
+		printf("%s: Far too big packet error. \n", dev->name);
 		return 0;
 	}
 
 	/* now, try to allocate the memory */
 
-	SMC_SELECT_BANK (2);
-	SMC_outw (LAN91C96_MMUCR_ALLOC_TX | numPages, LAN91C96_MMU);
+	SMC_SELECT_BANK(dev, 2);
+	SMC_outw(dev, LAN91C96_MMUCR_ALLOC_TX | numPages, LAN91C96_MMU);
 
   again:
 	try++;
 	time_out = MEMORY_WAIT_TIME;
 	do {
-		status = SMC_inb (LAN91C96_INT_STATS);
+		status = SMC_inb(dev, LAN91C96_INT_STATS);
 		if (status & LAN91C96_IST_ALLOC_INT) {
 
-			SMC_outb (LAN91C96_IST_ALLOC_INT, LAN91C96_INT_STATS);
+			SMC_outb(dev, LAN91C96_IST_ALLOC_INT,
+					LAN91C96_INT_STATS);
 			break;
 		}
 	} while (--time_out);
 
 	if (!time_out) {
 		PRINTK2 ("%s: memory allocation, try %d failed ...\n",
-				 SMC_DEV_NAME, try);
+				 dev->name, try);
 		if (try < SMC_ALLOC_MAX_TRY)
 			goto again;
 		else
@@ -468,30 +378,30 @@
 	}
 
 	PRINTK2 ("%s: memory allocation, try %d succeeded ...\n",
-			 SMC_DEV_NAME, try);
+			 dev->name, try);
 
 	/* I can send the packet now.. */
 
-	ioaddr = SMC_BASE_ADDRESS;
+	ioaddr = dev->iobase;
 
 	buf = (byte *) packet;
 
 	/* If I get here, I _know_ there is a packet slot waiting for me */
-	packet_no = SMC_inb (LAN91C96_ARR);
+	packet_no = SMC_inb(dev, LAN91C96_ARR);
 	if (packet_no & LAN91C96_ARR_FAILED) {
 		/* or isn't there?  BAD CHIP! */
-		printf ("%s: Memory allocation failed. \n", SMC_DEV_NAME);
+		printf("%s: Memory allocation failed. \n", dev->name);
 		return 0;
 	}
 
 	/* we have a packet address, so tell the card to use it */
-	SMC_outb (packet_no, LAN91C96_PNR);
+	SMC_outb(dev, packet_no, LAN91C96_PNR);
 
 	/* point to the beginning of the packet */
-	SMC_outw (LAN91C96_PTR_AUTO_INCR, LAN91C96_POINTER);
+	SMC_outw(dev, LAN91C96_PTR_AUTO_INCR, LAN91C96_POINTER);
 
-	PRINTK3 ("%s: Trying to xmit packet of length %x\n",
-			 SMC_DEV_NAME, length);
+	PRINTK3("%s: Trying to xmit packet of length %x\n",
+			 dev->name, length);
 
 #if SMC_DEBUG > 2
 	printf ("Transmitting Packet\n");
@@ -501,11 +411,11 @@
 	/* send the packet length ( +6 for status, length and ctl byte )
 	   and the status word ( set to zeros ) */
 #ifdef USE_32_BIT
-	SMC_outl ((length + 6) << 16, LAN91C96_DATA_HIGH);
+	SMC_outl(dev, (length + 6) << 16, LAN91C96_DATA_HIGH);
 #else
-	SMC_outw (0, LAN91C96_DATA_HIGH);
+	SMC_outw(dev, 0, LAN91C96_DATA_HIGH);
 	/* send the packet length ( +6 for status words, length, and ctl */
-	SMC_outw ((length + 6), LAN91C96_DATA_HIGH);
+	SMC_outw(dev, (length + 6), LAN91C96_DATA_HIGH);
 #endif /* USE_32_BIT */
 
 	/* send the actual data
@@ -516,54 +426,52 @@
 	 * almost as much time as is saved?
 	 */
 #ifdef USE_32_BIT
-	SMC_outsl (LAN91C96_DATA_HIGH, buf, length >> 2);
+	SMC_outsl(dev, LAN91C96_DATA_HIGH, buf, length >> 2);
 	if (length & 0x2)
-		SMC_outw (*((word *) (buf + (length & 0xFFFFFFFC))),
+		SMC_outw(dev, *((word *) (buf + (length & 0xFFFFFFFC))),
 				  LAN91C96_DATA_HIGH);
 #else
-	SMC_outsw (LAN91C96_DATA_HIGH, buf, (length) >> 1);
+	SMC_outsw(dev, LAN91C96_DATA_HIGH, buf, (length) >> 1);
 #endif /* USE_32_BIT */
 
 	/* Send the last byte, if there is one.   */
 	if ((length & 1) == 0) {
-		SMC_outw (0, LAN91C96_DATA_HIGH);
+		SMC_outw(dev, 0, LAN91C96_DATA_HIGH);
 	} else {
-		SMC_outw (buf[length - 1] | 0x2000, LAN91C96_DATA_HIGH);
+		SMC_outw(dev, buf[length - 1] | 0x2000, LAN91C96_DATA_HIGH);
 	}
 
 	/* and let the chipset deal with it */
-	SMC_outw (LAN91C96_MMUCR_ENQUEUE, LAN91C96_MMU);
+	SMC_outw(dev, LAN91C96_MMUCR_ENQUEUE, LAN91C96_MMU);
 
 	/* poll for TX INT */
-	if (poll4int (LAN91C96_MSK_TX_INT, SMC_TX_TIMEOUT)) {
+	if (poll4int (dev, LAN91C96_MSK_TX_INT, SMC_TX_TIMEOUT)) {
 		/* sending failed */
-		PRINTK2 ("%s: TX timeout, sending failed...\n", SMC_DEV_NAME);
+		PRINTK2("%s: TX timeout, sending failed...\n", dev->name);
 
 		/* release packet */
-		SMC_outw (LAN91C96_MMUCR_RELEASE_TX, LAN91C96_MMU);
+		SMC_outw(dev, LAN91C96_MMUCR_RELEASE_TX, LAN91C96_MMU);
 
 		/* wait for MMU getting ready (low) */
-		while (SMC_inw (LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY) {
+		while (SMC_inw(dev, LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
 			udelay (10);
-		}
 
-		PRINTK2 ("MMU ready\n");
+		PRINTK2("MMU ready\n");
 
 
 		return 0;
 	} else {
 		/* ack. int */
-		SMC_outw (LAN91C96_IST_TX_INT, LAN91C96_INT_STATS);
+		SMC_outw(dev, LAN91C96_IST_TX_INT, LAN91C96_INT_STATS);
 
-		PRINTK2 ("%s: Sent packet of length %d \n", SMC_DEV_NAME, length);
+		PRINTK2("%s: Sent packet of length %d \n", dev->name, length);
 
 		/* release packet */
-		SMC_outw (LAN91C96_MMUCR_RELEASE_TX, LAN91C96_MMU);
+		SMC_outw(dev, LAN91C96_MMUCR_RELEASE_TX, LAN91C96_MMU);
 
 		/* wait for MMU getting ready (low) */
-		while (SMC_inw (LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY) {
+		while (SMC_inw(dev, LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
 			udelay (10);
-		}
 
 		PRINTK2 ("MMU ready\n");
 	}
@@ -571,20 +479,6 @@
 	return length;
 }
 
-/*-------------------------------------------------------------------------
- * smc_destructor( struct net_device * dev )
- *   Input parameters:
- *	dev, pointer to the device structure
- *
- *   Output:
- *	None.
- *--------------------------------------------------------------------------
- */
-void smc_destructor ()
-{
-	PRINTK2 (CARDNAME ":smc_destructor\n");
-}
-
 
 /*
  * Open and Initialize the board
@@ -592,20 +486,20 @@
  * Set up everything, reset the card, etc ..
  *
  */
-static int smc_open (bd_t *bd)
+static int smc_open(bd_t *bd, struct eth_device *dev)
 {
 	int i, err;			/* used to set hw ethernet address */
 
-	PRINTK2 ("%s:smc_open\n", SMC_DEV_NAME);
+	PRINTK2("%s:smc_open\n", dev->name);
 
 	/* reset the hardware */
 
-	smc_reset ();
-	smc_enable ();
+	smc_reset(dev);
+	smc_enable(dev);
 
-	SMC_SELECT_BANK (1);
-
-	err = smc_get_ethaddr (bd);	/* set smc_mac_addr, and sync it with u-boot globals */
+	SMC_SELECT_BANK(dev, 1);
+	/* set smc_mac_addr, and sync it with u-boot globals */
+	err = smc_get_ethaddr(bd, dev);
 	if (err < 0)
 		return -1;
 #ifdef USE_32_BIT
@@ -614,11 +508,11 @@
 
 		address = smc_mac_addr[i + 1] << 8;
 		address |= smc_mac_addr[i];
-		SMC_outw (address, LAN91C96_IA0 + i);
+		SMC_outw(dev, address, LAN91C96_IA0 + i);
 	}
 #else
 	for (i = 0; i < 6; i++)
-		SMC_outb (smc_mac_addr[i], LAN91C96_IA0 + i);
+		SMC_outb(dev, smc_mac_addr[i], LAN91C96_IA0 + i);
 #endif
 	return 0;
 }
@@ -635,7 +529,7 @@
  * o otherwise, read in the packet
  *-------------------------------------------------------------
  */
-static int smc_rcv ()
+static int smc_rcv(struct eth_device *dev)
 {
 	int packet_number;
 	word status;
@@ -647,26 +541,26 @@
 #endif
 
 
-	SMC_SELECT_BANK (2);
-	packet_number = SMC_inw (LAN91C96_FIFO);
+	SMC_SELECT_BANK(dev, 2);
+	packet_number = SMC_inw(dev, LAN91C96_FIFO);
 
 	if (packet_number & LAN91C96_FIFO_RXEMPTY) {
 		return 0;
 	}
 
-	PRINTK3 ("%s:smc_rcv\n", SMC_DEV_NAME);
+	PRINTK3("%s:smc_rcv\n", dev->name);
 	/*  start reading from the start of the packet */
-	SMC_outw (LAN91C96_PTR_READ | LAN91C96_PTR_RCV |
+	SMC_outw(dev, LAN91C96_PTR_READ | LAN91C96_PTR_RCV |
 			  LAN91C96_PTR_AUTO_INCR, LAN91C96_POINTER);
 
 	/* First two words are status and packet_length */
 #ifdef USE_32_BIT
-	stat_len = SMC_inl (LAN91C96_DATA_HIGH);
+	stat_len = SMC_inl(dev, LAN91C96_DATA_HIGH);
 	status = stat_len & 0xffff;
 	packet_length = stat_len >> 16;
 #else
-	status = SMC_inw (LAN91C96_DATA_HIGH);
-	packet_length = SMC_inw (LAN91C96_DATA_HIGH);
+	status = SMC_inw(dev, LAN91C96_DATA_HIGH);
+	packet_length = SMC_inw(dev, LAN91C96_DATA_HIGH);
 #endif
 
 	packet_length &= 0x07ff;	/* mask off top bits */
@@ -690,13 +584,14 @@
 		   to send the DWORDs or the bytes first, or some
 		   mixture.  A mixture might improve already slow PIO
 		   performance  */
-		SMC_insl (LAN91C96_DATA_HIGH, NetRxPackets[0], packet_length >> 2);
+		SMC_insl(dev, LAN91C96_DATA_HIGH, NetRxPackets[0],
+				packet_length >> 2);
 		/* read the left over bytes */
 		if (packet_length & 3) {
 			int i;
 
 			byte *tail = (byte *) (NetRxPackets[0] + (packet_length & ~3));
-			dword leftover = SMC_inl (LAN91C96_DATA_HIGH);
+			dword leftover = SMC_inl(dev, LAN91C96_DATA_HIGH);
 
 			for (i = 0; i < (packet_length & 3); i++)
 				*tail++ = (byte) (leftover >> (8 * i)) & 0xff;
@@ -704,13 +599,14 @@
 #else
 		PRINTK3 (" Reading %d words and %d byte(s) \n",
 				 (packet_length >> 1), packet_length & 1);
-		SMC_insw (LAN91C96_DATA_HIGH, NetRxPackets[0], packet_length >> 1);
+		SMC_insw(dev, LAN91C96_DATA_HIGH, NetRxPackets[0],
+				packet_length >> 1);
 
 #endif /* USE_32_BIT */
 
 #if	SMC_DEBUG > 2
 		printf ("Receiving Packet\n");
-		print_packet (NetRxPackets[0], packet_length);
+		print_packet((byte *)NetRxPackets[0], packet_length);
 #endif
 	} else {
 		/* error ... */
@@ -718,13 +614,13 @@
 		is_error = 1;
 	}
 
-	while (SMC_inw (LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
+	while (SMC_inw(dev, LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
 		udelay (1);		/* Wait until not busy */
 
 	/*  error or good, tell the card to get rid of this packet */
-	SMC_outw (LAN91C96_MMUCR_RELEASE_RX, LAN91C96_MMU);
+	SMC_outw(dev, LAN91C96_MMUCR_RELEASE_RX, LAN91C96_MMU);
 
-	while (SMC_inw (LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
+	while (SMC_inw(dev, LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
 		udelay (1);		/* Wait until not busy */
 
 	if (!is_error) {
@@ -745,18 +641,18 @@
  * an 'ifconfig ethX down'
  *
  -----------------------------------------------------*/
-static int smc_close ()
+static int smc_close(struct eth_device *dev)
 {
-	PRINTK2 ("%s:smc_close\n", SMC_DEV_NAME);
+	PRINTK2("%s:smc_close\n", dev->name);
 
 	/* clear everything */
-	smc_shutdown ();
+	smc_shutdown(dev);
 
 	return 0;
 }
 
 #if SMC_DEBUG > 2
-static void print_packet (byte * buf, int length)
+static void print_packet(byte *buf, int length)
 {
 #if 0
 	int i;
@@ -792,86 +688,40 @@
 }
 #endif /* SMC_DEBUG > 2 */
 
-int eth_init (bd_t * bd)
-{
-	return (smc_open(bd));
-}
-
-void eth_halt ()
+static int  lan91c96_init(struct eth_device *dev, bd_t *bd)
 {
-	smc_close ();
+	return smc_open(bd, dev);
 }
 
-int eth_rx ()
+static void lan91c96_halt(struct eth_device *dev)
 {
-	return smc_rcv ();
+	smc_close(dev);
 }
 
-int eth_send (volatile void *packet, int length)
+static int lan91c96_recv(struct eth_device *dev)
 {
-	return smc_send_packet (packet, length);
+	return smc_rcv(dev);
 }
 
-
-#if 0
-/*-------------------------------------------------------------------------
- * smc_hw_init()
- *
- *   Function:
- *      Reset and enable the device, check if the I/O space location
- *      is correct
- *
- *   Input parameters:
- *      None
- *
- *   Output:
- *	0 --> success
- *	1 --> error
- *--------------------------------------------------------------------------
- */
-static int smc_hw_init ()
+static int lan91c96_send(struct eth_device *dev, volatile void *packet,
+		int length)
 {
-	unsigned short status_test;
-
-	/* The attribute register of the LAN91C96 is located at address
-	   0x0e000000 on the lubbock platform */
-	volatile unsigned *attaddr = (unsigned *) (0x0e000000);
-
-	/* first reset, then enable the device. Sequence is critical */
-	attaddr[LAN91C96_ECOR] |= LAN91C96_ECOR_SRESET;
-	udelay (100);
-	attaddr[LAN91C96_ECOR] &= ~LAN91C96_ECOR_SRESET;
-	attaddr[LAN91C96_ECOR] |= LAN91C96_ECOR_ENABLE;
-
-	/* force 16-bit mode */
-	attaddr[LAN91C96_ECSR] &= ~LAN91C96_ECSR_IOIS8;
-	udelay (100);
-
-	/* check if the I/O address is correct, the upper byte of the
-	   bank select register should read 0x33 */
-
-	status_test = SMC_inw (LAN91C96_BANK_SELECT);
-	if ((status_test & 0xFF00) != 0x3300) {
-		printf ("Failed to initialize ethernetchip\n");
-		return 1;
-	}
-	return 0;
+	return smc_send_packet(dev, packet, length);
 }
-#endif /* 0 */
 
-/* smc_get_ethaddr (bd_t * bd)
+/* smc_get_ethaddr
  *
  * This checks both the environment and the ROM for an ethernet address. If
  * found, the environment takes precedence.
  */
 
-int smc_get_ethaddr (bd_t * bd)
+static int smc_get_ethaddr(bd_t *bd, struct eth_device *dev)
 {
 	uchar v_mac[6];
 
 	if (!eth_getenv_enetaddr("ethaddr", v_mac)) {
 		/* get ROM mac value if any */
-		if (!get_rom_mac(v_mac)) {
+		if (!get_rom_mac(dev, v_mac)) {
 			printf("\n*** ERROR: ethaddr is NOT set !!\n");
 			return -1;
 		}
@@ -888,7 +738,7 @@
  * Note, this has omly been tested for the OMAP730 P2.
  */
 
-int get_rom_mac (unsigned char *v_rom_mac)
+static int get_rom_mac(struct eth_device *dev, unsigned char *v_rom_mac)
 {
 #ifdef HARDCODE_MAC	/* used for testing or to supress run time warnings */
 	char hw_mac_addr[] = { 0x02, 0x80, 0xad, 0x20, 0x31, 0xb8 };
@@ -897,11 +747,75 @@
 	return (1);
 #else
 	int i;
-	SMC_SELECT_BANK (1);
+	SMC_SELECT_BANK(dev, 1);
 	for (i=0; i<6; i++)
 	{
-		v_rom_mac[i] = SMC_inb (LAN91C96_IA0 + i);
+		v_rom_mac[i] = SMC_inb(dev, LAN91C96_IA0 + i);
 	}
 	return (1);
 #endif
 }
+
+/* Structure to detect the device IDs */
+struct id_type {
+	u8 id;
+	char *name;
+};
+static struct id_type supported_chips[] = {
+	{0, ""}, /* Dummy entry to prevent id check failure */
+	{9, "LAN91C110"},
+	{8, "LAN91C100FD"},
+	{7, "LAN91C100"},
+	{5, "LAN91C95"},
+	{4, "LAN91C94/LAN91C96"},
+	{3, "LAN91C90/LAN91C92"},
+};
+/* lan91c96_detect_chip
+ * See:
+ * http://www.embeddedsys.com/subpages/resources/images/documents/LAN91C96_datasheet.pdf
+ * page 71 - that is the closest we get to detect this device
+ */
+static int lan91c96_detect_chip(struct eth_device *dev)
+{
+	u8 chip_id;
+	int r;
+	SMC_SELECT_BANK(dev, 3);
+	chip_id = SMC_inw(dev, 0xA) & LAN91C96_REV_REVID;
+	SMC_SELECT_BANK(dev, 0);
+	for (r = 0; r < sizeof(supported_chips) / sizeof(struct id_type); r++)
+		if (chip_id == supported_chips[r].id)
+			return r;
+	return 0;
+}
+
+int lan91c96_initialize(u8 dev_num, int base_addr)
+{
+	struct eth_device *dev;
+	int r = 0;
+
+	dev = malloc(sizeof(*dev));
+	if (!dev) {
+		free(dev);
+		return 0;
+	}
+	memset(dev, 0, sizeof(*dev));
+
+	dev->iobase = base_addr;
+
+	/* Try to detect chip. Will fail if not present. */
+	r = lan91c96_detect_chip(dev);
+	if (!r) {
+		free(dev);
+		return 0;
+	}
+	get_rom_mac(dev, dev->enetaddr);
+
+	dev->init = lan91c96_init;
+	dev->halt = lan91c96_halt;
+	dev->send = lan91c96_send;
+	dev->recv = lan91c96_recv;
+	sprintf(dev->name, "%s-%hu", supported_chips[r].name, dev_num);
+
+	eth_register(dev);
+	return 0;
+}
diff --git a/drivers/net/lan91c96.h b/drivers/net/lan91c96.h
index 5beddda..6fbb0e3 100644
--- a/drivers/net/lan91c96.h
+++ b/drivers/net/lan91c96.h
@@ -46,14 +46,6 @@
 #include <asm/io.h>
 #include <config.h>
 
-/*
- * This function may be called by the board specific initialisation code
- * in order to override the default mac address.
- */
-
-void smc_set_mac_addr(const unsigned char *addr);
-
-
 /* I want some simple types */
 
 typedef unsigned char			byte;
@@ -86,66 +78,71 @@
 #define	SMC_IO_SHIFT	0
 #endif
 
-#define	SMCREG(r)	(SMC_BASE_ADDRESS+((r)<<SMC_IO_SHIFT))
+#define	SMCREG(edev, r)	((edev)->iobase+((r)<<SMC_IO_SHIFT))
 
-#define	SMC_inl(r)	(*((volatile dword *)SMCREG(r)))
-#define	SMC_inw(r)	(*((volatile word *)SMCREG(r)))
-#define SMC_inb(p) ({ \
+#define	SMC_inl(edev, r)	(*((volatile dword *)SMCREG(edev, r)))
+#define	SMC_inw(edev, r)	(*((volatile word *)SMCREG(edev, r)))
+#define SMC_inb(edev, p) ({ \
 	unsigned int __p = p; \
-	unsigned int __v = SMC_inw(__p & ~1); \
+	unsigned int __v = SMC_inw(edev, __p & ~1); \
 	if (__p & 1) __v >>= 8; \
 	else __v &= 0xff; \
 	__v; })
 
-#define	SMC_outl(d,r)	(*((volatile dword *)SMCREG(r)) = d)
-#define	SMC_outw(d,r)	(*((volatile word *)SMCREG(r)) = d)
-#define	SMC_outb(d,r)	({	word __d = (byte)(d);  \
-				word __w = SMC_inw((r)&~1);  \
+#define	SMC_outl(edev, d, r)	(*((volatile dword *)SMCREG(edev, r)) = d)
+#define	SMC_outw(edev, d, r)	(*((volatile word *)SMCREG(edev, r)) = d)
+#define	SMC_outb(edev, d, r)	({	word __d = (byte)(d);  \
+				word __w = SMC_inw(edev, (r)&~1);  \
 				__w &= ((r)&1) ? 0x00FF : 0xFF00;  \
 				__w |= ((r)&1) ? __d<<8 : __d;  \
-				SMC_outw(__w,(r)&~1);  \
+				SMC_outw(edev, __w, (r)&~1);  \
 			})
 
-#define SMC_outsl(r,b,l)	({	int __i; \
+#define SMC_outsl(edev, r, b, l)	({	int __i; \
 					dword *__b2; \
 					__b2 = (dword *) b; \
 					for (__i = 0; __i < l; __i++) { \
-					    SMC_outl( *(__b2 + __i), r ); \
+						SMC_outl(edev, *(__b2 + __i),\
+							r); \
 					} \
 				})
 
-#define SMC_outsw(r,b,l)	({	int __i; \
+#define SMC_outsw(edev, r, b, l)	({	int __i; \
 					word *__b2; \
 					__b2 = (word *) b; \
 					for (__i = 0; __i < l; __i++) { \
-					    SMC_outw( *(__b2 + __i), r ); \
+						SMC_outw(edev, *(__b2 + __i),\
+							r); \
 					} \
 				})
 
-#define SMC_insl(r,b,l)		({	int __i ;  \
+#define SMC_insl(edev, r, b, l)		({	int __i ;  \
 					dword *__b2;  \
 					__b2 = (dword *) b;  \
 					for (__i = 0; __i < l; __i++) {  \
-					  *(__b2 + __i) = SMC_inl(r);  \
-					  SMC_inl(0);  \
+						*(__b2 + __i) = SMC_inl(edev,\
+							r);  \
+						SMC_inl(edev, 0);  \
 					};  \
 				})
 
-#define SMC_insw(r,b,l)		({	int __i ;  \
+#define SMC_insw(edev, r, b, l)		({	int __i ;  \
 					word *__b2;  \
 					__b2 = (word *) b;  \
 					for (__i = 0; __i < l; __i++) {  \
-					  *(__b2 + __i) = SMC_inw(r);  \
-					  SMC_inw(0);  \
+						*(__b2 + __i) = SMC_inw(edev,\
+							r);  \
+						SMC_inw(edev, 0);  \
 					};  \
 				})
 
-#define SMC_insb(r,b,l)		({	int __i ;  \
+#define SMC_insb(edev, r, b, l)		({	int __i ;  \
 					byte *__b2;  \
 					__b2 = (byte *) b;  \
 					for (__i = 0; __i < l; __i++) {  \
-					  *(__b2 + __i) = SMC_inb(r);  \
-					  SMC_inb(0);  \
+						*(__b2 + __i) = SMC_inb(edev,\
+							r);  \
+						SMC_inb(edev, 0);  \
 					};  \
 				})
 
@@ -155,40 +152,35 @@
  * We have only 16 Bit PCMCIA access on Socket 0
  */
 
-#define	SMC_inw(r)	(*((volatile word *)(SMC_BASE_ADDRESS+(r))))
-#define  SMC_inb(r)	(((r)&1) ? SMC_inw((r)&~1)>>8 : SMC_inw(r)&0xFF)
+#define	SMC_inw(edev, r)	(*((volatile word *)((edev)->iobase+(r))))
+#define  SMC_inb(edev, r)	(((r)&1) ? SMC_inw(edev, (r)&~1)>>8 :\
+					SMC_inw(edev, r)&0xFF)
 
-#define	SMC_outw(d,r)	(*((volatile word *)(SMC_BASE_ADDRESS+(r))) = d)
-#define	SMC_outb(d,r)	({	word __d = (byte)(d);  \
-				word __w = SMC_inw((r)&~1);  \
+#define	SMC_outw(edev, d, r)	(*((volatile word *)((edev)->iobase+(r))) = d)
+#define	SMC_outb(edev, d, r)	({	word __d = (byte)(d);  \
+				word __w = SMC_inw(edev, (r)&~1);  \
 				__w &= ((r)&1) ? 0x00FF : 0xFF00;  \
 				__w |= ((r)&1) ? __d<<8 : __d;  \
-				SMC_outw(__w,(r)&~1);  \
+				SMC_outw(edev, __w, (r)&~1);  \
 			})
-#if 0
-#define	SMC_outsw(r,b,l)	outsw(SMC_BASE_ADDRESS+(r), (b), (l))
-#else
-#define SMC_outsw(r,b,l)	({	int __i; \
+#define SMC_outsw(edev, r, b, l)	({	int __i; \
 					word *__b2; \
 					__b2 = (word *) b; \
 					for (__i = 0; __i < l; __i++) { \
-					    SMC_outw( *(__b2 + __i), r); \
+						SMC_outw(edev, *(__b2 + __i),\
+							r); \
 					} \
 				})
-#endif
 
-#if 0
-#define	SMC_insw(r,b,l)	insw(SMC_BASE_ADDRESS+(r), (b), (l))
-#else
-#define SMC_insw(r,b,l)	({	int __i ;  \
+#define SMC_insw(edev, r, b, l)	({	int __i ;  \
 					word *__b2;  \
 					__b2 = (word *) b;  \
 					for (__i = 0; __i < l; __i++) {  \
-					  *(__b2 + __i) = SMC_inw(r);  \
-					  SMC_inw(0);  \
+						*(__b2 + __i) = SMC_inw(edev,\
+							r);  \
+						SMC_inw(edev, 0);  \
 					};  \
 				})
-#endif
 
 #endif
 
@@ -608,25 +600,25 @@
 
 /* select a register bank, 0 to 3  */
 
-#define SMC_SELECT_BANK(x)  { SMC_outw( x, LAN91C96_BANK_SELECT ); }
+#define SMC_SELECT_BANK(edev, x)  { SMC_outw(edev, x, LAN91C96_BANK_SELECT); }
 
 /* this enables an interrupt in the interrupt mask register */
-#define SMC_ENABLE_INT(x) {\
+#define SMC_ENABLE_INT(edev, x) {\
 		unsigned char mask;\
-		SMC_SELECT_BANK(2);\
-		mask = SMC_inb( LAN91C96_INT_MASK );\
+		SMC_SELECT_BANK(edev, 2);\
+		mask = SMC_inb(edev, LAN91C96_INT_MASK);\
 		mask |= (x);\
-		SMC_outb( mask, LAN91C96_INT_MASK ); \
+		SMC_outb(edev, mask, LAN91C96_INT_MASK); \
 }
 
 /* this disables an interrupt from the interrupt mask register */
 
-#define SMC_DISABLE_INT(x) {\
+#define SMC_DISABLE_INT(edev, x) {\
 		unsigned char mask;\
-		SMC_SELECT_BANK(2);\
-		mask = SMC_inb( LAN91C96_INT_MASK );\
+		SMC_SELECT_BANK(edev, 2);\
+		mask = SMC_inb(edev, LAN91C96_INT_MASK);\
 		mask &= ~(x);\
-		SMC_outb( mask, LAN91C96_INT_MASK ); \
+		SMC_outb(edev, mask, LAN91C96_INT_MASK); \
 }
 
 /*----------------------------------------------------------------------
diff --git a/drivers/serial/usbtty.h b/drivers/serial/usbtty.h
index f746d63..6b6c4a1 100644
--- a/drivers/serial/usbtty.h
+++ b/drivers/serial/usbtty.h
@@ -29,6 +29,8 @@
 #include <usb/mpc8xx_udc.h>
 #elif defined(CONFIG_OMAP1510)
 #include <usb/omap1510_udc.h>
+#elif defined(CONFIG_MUSB_UDC)
+#include <usb/musb_udc.h>
 #elif defined(CONFIG_PXA27X)
 #include <usb/pxa27x_udc.h>
 #endif
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 324c308..ba85991 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -96,7 +96,7 @@
 				 * UE_DIR_IN | EHCI_INTR_ENDPT
 				 */
 		3,		/* bmAttributes: UE_INTERRUPT */
-		8, 0,		/* wMaxPacketSize */
+		8,		/* wMaxPacketSize */
 		255		/* bInterval */
 	},
 };
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile
index 09e0a5f..f2ccd9f 100644
--- a/drivers/usb/musb/Makefile
+++ b/drivers/usb/musb/Makefile
@@ -26,7 +26,9 @@
 LIB	:= $(obj)libusb_musb.a
 
 COBJS-$(CONFIG_MUSB_HCD) += musb_hcd.o musb_core.o
+COBJS-$(CONFIG_MUSB_UDC) += musb_udc.o musb_core.o
 COBJS-$(CONFIG_USB_DAVINCI) += davinci.o
+COBJS-$(CONFIG_USB_OMAP3) += omap3.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index ec57fc8..22f3dba 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -32,7 +32,9 @@
  */
 void musb_start(void)
 {
+#if defined(CONFIG_MUSB_HCD)
 	u8 devctl;
+#endif
 
 	/* disable all interrupts */
 	writew(0, &musbr->intrtxe);
@@ -74,9 +76,10 @@
 			/* Configure fifo size and fifo base address */
 			writeb(idx, &musbr->txfifosz);
 			writew(fifoaddr >> 3, &musbr->txfifoadd);
+
+			csr = readw(&musbr->txcsr);
 #if defined(CONFIG_MUSB_HCD)
 			/* clear the data toggle bit */
-			csr = readw(&musbr->txcsr);
 			writew(csr | MUSB_TXCSR_CLRDATATOG, &musbr->txcsr);
 #endif
 			/* Flush fifo if required */
@@ -87,9 +90,10 @@
 			/* Configure fifo size and fifo base address */
 			writeb(idx, &musbr->rxfifosz);
 			writew(fifoaddr >> 3, &musbr->rxfifoadd);
+
+			csr = readw(&musbr->rxcsr);
 #if defined(CONFIG_MUSB_HCD)
 			/* clear the data toggle bit */
-			csr = readw(&musbr->rxcsr);
 			writew(csr | MUSB_RXCSR_CLRDATATOG, &musbr->rxcsr);
 #endif
 			/* Flush fifo if required */
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index f9da3f0..15c7f49 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -40,6 +40,36 @@
 
 #define MUSB_EP0_FIFOSIZE	64	/* This is non-configurable */
 
+/* EP0 */
+struct musb_ep0_regs {
+	u16	reserved4;
+	u16	csr0;
+	u16	reserved5;
+	u16	reserved6;
+	u16	count0;
+	u8	host_type0;
+	u8	host_naklimit0;
+	u8	reserved7;
+	u8	reserved8;
+	u8	reserved9;
+	u8	configdata;
+};
+
+/* EP 1-15 */
+struct musb_epN_regs {
+	u16	txmaxp;
+	u16	txcsr;
+	u16	rxmaxp;
+	u16	rxcsr;
+	u16	rxcount;
+	u8	txtype;
+	u8	txinterval;
+	u8	rxtype;
+	u8	rxinterval;
+	u8	reserved0;
+	u8	fifosize;
+};
+
 /* Mentor USB core register overlay structure */
 struct musb_regs {
 	/* common registers */
@@ -97,6 +127,16 @@
 		u8	rxhubaddr;
 		u8	rxhubport;
 	} tar[16];
+	/*
+	 * end point registers
+	 * ep0 elements are valid when array index is 0
+	 * otherwise epN is valid
+	 */
+	union musb_ep_regs {
+		struct musb_ep0_regs ep0;
+		struct musb_epN_regs epN;
+	} ep[16];
+
 } __attribute__((aligned(32)));
 
 /*
diff --git a/drivers/usb/musb/musb_debug.h b/drivers/usb/musb/musb_debug.h
new file mode 100644
index 0000000..62380ff
--- /dev/null
+++ b/drivers/usb/musb/musb_debug.h
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2009 Wind River Systems, Inc.
+ * Tom Rix <Tom.Rix@windriver.com>
+ *
+ * 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
+ */
+
+/* Define MUSB_DEBUG before including this file to get debug macros */
+#ifdef MUSB_DEBUG
+
+#define MUSB_FLAGS_PRINT(v, x, y)		\
+  if (((v) & MUSB_##x##_##y))			\
+		serial_printf("\t\t"#y"\n")
+
+static inline void musb_print_pwr(u8 b)
+{
+	serial_printf("\tpower   0x%2.2x\n", b);
+	MUSB_FLAGS_PRINT(b, POWER, ISOUPDATE);
+	MUSB_FLAGS_PRINT(b, POWER, SOFTCONN);
+	MUSB_FLAGS_PRINT(b, POWER, HSENAB);
+	MUSB_FLAGS_PRINT(b, POWER, HSMODE);
+	MUSB_FLAGS_PRINT(b, POWER, RESET);
+	MUSB_FLAGS_PRINT(b, POWER, RESUME);
+	MUSB_FLAGS_PRINT(b, POWER, SUSPENDM);
+	MUSB_FLAGS_PRINT(b, POWER, ENSUSPEND);
+}
+
+static inline void musb_print_csr0(u16 w)
+{
+	serial_printf("\tcsr0    0x%4.4x\n", w);
+	MUSB_FLAGS_PRINT(w, CSR0, FLUSHFIFO);
+	MUSB_FLAGS_PRINT(w, CSR0_P, SVDSETUPEND);
+	MUSB_FLAGS_PRINT(w, CSR0_P, SVDRXPKTRDY);
+	MUSB_FLAGS_PRINT(w, CSR0_P, SENDSTALL);
+	MUSB_FLAGS_PRINT(w, CSR0_P, SETUPEND);
+	MUSB_FLAGS_PRINT(w, CSR0_P, DATAEND);
+	MUSB_FLAGS_PRINT(w, CSR0_P, SENTSTALL);
+	MUSB_FLAGS_PRINT(w, CSR0, TXPKTRDY);
+	MUSB_FLAGS_PRINT(w, CSR0, RXPKTRDY);
+}
+
+static inline void musb_print_intrusb(u8 b)
+{
+	serial_printf("\tintrusb 0x%2.2x\n", b);
+	MUSB_FLAGS_PRINT(b, INTR, VBUSERROR);
+	MUSB_FLAGS_PRINT(b, INTR, SESSREQ);
+	MUSB_FLAGS_PRINT(b, INTR, DISCONNECT);
+	MUSB_FLAGS_PRINT(b, INTR, CONNECT);
+	MUSB_FLAGS_PRINT(b, INTR, SOF);
+	MUSB_FLAGS_PRINT(b, INTR, RESUME);
+	MUSB_FLAGS_PRINT(b, INTR, SUSPEND);
+
+	if (b & MUSB_INTR_BABBLE)
+		serial_printf("\t\tMUSB_INTR_RESET or MUSB_INTR_BABBLE\n");
+
+}
+
+static inline void musb_print_intrtx(u16 w)
+{
+	serial_printf("\tintrtx 0x%4.4x\n", w);
+}
+
+static inline void musb_print_intrrx(u16 w)
+{
+	serial_printf("\tintrx 0x%4.4x\n", w);
+}
+
+static inline void musb_print_devctl(u8 b)
+{
+	serial_printf("\tdevctl  0x%2.2x\n", b);
+	if (b & MUSB_DEVCTL_BDEVICE)
+		serial_printf("\t\tB device\n");
+	else
+		serial_printf("\t\tA device\n");
+	if (b & MUSB_DEVCTL_FSDEV)
+		serial_printf("\t\tFast Device -(host mode)\n");
+	if (b & MUSB_DEVCTL_LSDEV)
+		serial_printf("\t\tSlow Device -(host mode)\n");
+	if (b & MUSB_DEVCTL_HM)
+		serial_printf("\t\tHost mode\n");
+	else
+		serial_printf("\t\tPeripherial mode\n");
+	if (b & MUSB_DEVCTL_HR)
+		serial_printf("\t\tHost request started(B device)\n");
+	else
+		serial_printf("\t\tHost request finished(B device)\n");
+	if (b & MUSB_DEVCTL_BDEVICE) {
+		if (b & MUSB_DEVCTL_SESSION)
+			serial_printf("\t\tStart of session(B device)\n");
+		else
+			serial_printf("\t\tEnd of session(B device)\n");
+	} else {
+		if (b & MUSB_DEVCTL_SESSION)
+			serial_printf("\t\tStart of session(A device)\n");
+		else
+			serial_printf("\t\tEnd of session(A device)\n");
+	}
+}
+
+static inline void musb_print_config(u8 b)
+{
+	serial_printf("\tconfig 0x%2.2x\n", b);
+	if (b & MUSB_CONFIGDATA_MPRXE)
+		serial_printf("\t\tAuto combine rx bulk packets\n");
+	if (b & MUSB_CONFIGDATA_MPTXE)
+		serial_printf("\t\tAuto split tx bulk packets\n");
+	if (b & MUSB_CONFIGDATA_BIGENDIAN)
+		serial_printf("\t\tBig Endian ordering\n");
+	else
+		serial_printf("\t\tLittle Endian ordering\n");
+	if (b & MUSB_CONFIGDATA_HBRXE)
+		serial_printf("\t\tHigh speed rx iso endpoint\n");
+	if (b & MUSB_CONFIGDATA_HBTXE)
+		serial_printf("\t\tHigh speed tx iso endpoint\n");
+	if (b & MUSB_CONFIGDATA_DYNFIFO)
+		serial_printf("\t\tDynamic fifo sizing\n");
+	if (b & MUSB_CONFIGDATA_SOFTCONE)
+		serial_printf("\t\tSoft Connect\n");
+	if (b & MUSB_CONFIGDATA_UTMIDW)
+		serial_printf("\t\t16 bit data width\n");
+	else
+		serial_printf("\t\t8 bit data width\n");
+}
+
+static inline void musb_print_rxmaxp(u16 w)
+{
+	serial_printf("\trxmaxp  0x%4.4x\n", w);
+}
+
+static inline void musb_print_rxcsr(u16 w)
+{
+	serial_printf("\trxcsr   0x%4.4x\n", w);
+	MUSB_FLAGS_PRINT(w, RXCSR, AUTOCLEAR);
+	MUSB_FLAGS_PRINT(w, RXCSR, DMAENAB);
+	MUSB_FLAGS_PRINT(w, RXCSR, DISNYET);
+	MUSB_FLAGS_PRINT(w, RXCSR, PID_ERR);
+	MUSB_FLAGS_PRINT(w, RXCSR, DMAMODE);
+	MUSB_FLAGS_PRINT(w, RXCSR, CLRDATATOG);
+	MUSB_FLAGS_PRINT(w, RXCSR, FLUSHFIFO);
+	MUSB_FLAGS_PRINT(w, RXCSR, DATAERROR);
+	MUSB_FLAGS_PRINT(w, RXCSR, FIFOFULL);
+	MUSB_FLAGS_PRINT(w, RXCSR, RXPKTRDY);
+	MUSB_FLAGS_PRINT(w, RXCSR_P, SENTSTALL);
+	MUSB_FLAGS_PRINT(w, RXCSR_P, SENDSTALL);
+	MUSB_FLAGS_PRINT(w, RXCSR_P, OVERRUN);
+
+	if (w & MUSB_RXCSR_P_ISO)
+		serial_printf("\t\tiso mode\n");
+	else
+		serial_printf("\t\tbulk mode\n");
+
+}
+
+static inline void musb_print_txmaxp(u16 w)
+{
+	serial_printf("\ttxmaxp  0x%4.4x\n", w);
+}
+
+static inline void musb_print_txcsr(u16 w)
+{
+	serial_printf("\ttxcsr   0x%4.4x\n", w);
+	MUSB_FLAGS_PRINT(w, TXCSR, TXPKTRDY);
+	MUSB_FLAGS_PRINT(w, TXCSR, FIFONOTEMPTY);
+	MUSB_FLAGS_PRINT(w, TXCSR, FLUSHFIFO);
+	MUSB_FLAGS_PRINT(w, TXCSR, CLRDATATOG);
+	MUSB_FLAGS_PRINT(w, TXCSR_P, UNDERRUN);
+	MUSB_FLAGS_PRINT(w, TXCSR_P, SENTSTALL);
+	MUSB_FLAGS_PRINT(w, TXCSR_P, SENDSTALL);
+
+	if (w & MUSB_TXCSR_MODE)
+		serial_printf("\t\tTX mode\n");
+	else
+		serial_printf("\t\tRX mode\n");
+}
+
+#else
+
+/* stubs */
+
+#define musb_print_pwr(b)
+#define musb_print_csr0(w)
+#define musb_print_intrusb(b)
+#define musb_print_intrtx(w)
+#define musb_print_intrrx(w)
+#define musb_print_devctl(b)
+#define musb_print_config(b)
+#define musb_print_rxmaxp(w)
+#define musb_print_rxcsr(w)
+#define musb_print_txmaxp(w)
+#define musb_print_txcsr(w)
+
+#endif /* MUSB_DEBUG */
diff --git a/drivers/usb/musb/musb_hcd.c b/drivers/usb/musb/musb_hcd.c
index 4ca94cb..555d2dc 100644
--- a/drivers/usb/musb/musb_hcd.c
+++ b/drivers/usb/musb/musb_hcd.c
@@ -803,7 +803,7 @@
 {
 	struct stdio_dev *dev;
 	struct usb_device *usb_kbd_dev;
-	struct usb_interface_descriptor *iface;
+	struct usb_interface *iface;
 	struct usb_endpoint_descriptor *ep;
 	int pipe;
 	int maxp;
diff --git a/drivers/usb/musb/musb_udc.c b/drivers/usb/musb/musb_udc.c
new file mode 100644
index 0000000..fc43cf4
--- /dev/null
+++ b/drivers/usb/musb/musb_udc.c
@@ -0,0 +1,963 @@
+/*
+ * Copyright (c) 2009 Wind River Systems, Inc.
+ * Tom Rix <Tom.Rix@windriver.com>
+ *
+ * This file is a rewrite of the usb device part of
+ * repository git.omapzoom.org/repo/u-boot.git, branch master,
+ * file cpu/omap3/fastboot.c
+ *
+ * This is the unique part of its copyright :
+ *
+ * -------------------------------------------------------------------------
+ *
+ * (C) Copyright 2008 - 2009
+ * Windriver, <www.windriver.com>
+ * Tom Rix <Tom.Rix@windriver.com>
+ *
+ * -------------------------------------------------------------------------
+ *
+ * The details of connecting the device to the uboot usb device subsystem
+ * came from the old omap3 repository www.sakoman.net/u-boot-omap3.git,
+ * branch omap3-dev-usb, file drivers/usb/usbdcore_musb.c
+ *
+ * This is the unique part of its copyright :
+ *
+ * -------------------------------------------------------------------------
+ *
+ * (C) Copyright 2008 Texas Instruments Incorporated.
+ *
+ * Based on
+ * u-boot OMAP1510 USB drivers (drivers/usbdcore_omap1510.c)
+ * twl4030 init based on linux (drivers/i2c/chips/twl4030_usb.c)
+ *
+ * Author: Diego Dompe (diego.dompe@ridgerun.com)
+ *         Atin Malaviya (atin.malaviya@gmail.com)
+ *
+ * -------------------------------------------------------------------------
+ *
+ * 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
+ */
+
+#include <common.h>
+#include <usb/musb_udc.h>
+#include "../gadget/ep0.h"
+#include "musb_core.h"
+#if defined(CONFIG_USB_OMAP3)
+#include "omap3.h"
+#elif defined(CONFIG_USB_DAVINCI)
+#include "davinci.h"
+#endif
+
+/* Define MUSB_DEBUG for debugging */
+/* #define MUSB_DEBUG */
+#include "musb_debug.h"
+
+#define MAX_ENDPOINT 15
+
+#define GET_ENDPOINT(dev,ep)						\
+(((struct usb_device_instance *)(dev))->bus->endpoint_array + ep)
+
+#define SET_EP0_STATE(s)						\
+do {									\
+	if ((0 <= (s)) && (SET_ADDRESS >= (s))) {			\
+		if ((s) != ep0_state) {					\
+			if ((debug_setup) && (debug_level > 1))		\
+				serial_printf("INFO : Changing state "  \
+					      "from %s to %s in %s at " \
+					      "line %d\n",		\
+					      ep0_state_strings[ep0_state],\
+					      ep0_state_strings[s],	\
+					      __PRETTY_FUNCTION__,	\
+					      __LINE__);		\
+			ep0_state = s;					\
+		}							\
+	} else {							\
+		if (debug_level > 0)					\
+			serial_printf("Error at %s %d with setting "	\
+				      "state %d is invalid\n",		\
+				      __PRETTY_FUNCTION__, __LINE__, s); \
+	}								\
+} while (0)
+
+/* static implies these initialized to 0 or NULL */
+static int debug_setup;
+static int debug_level;
+static struct musb_epinfo epinfo[MAX_ENDPOINT * 2];
+static enum ep0_state_enum {
+	IDLE = 0,
+	TX,
+	RX,
+	SET_ADDRESS
+} ep0_state = IDLE;
+static char *ep0_state_strings[4] = {
+	"IDLE",
+	"TX",
+	"RX",
+	"SET_ADDRESS",
+};
+
+static struct urb *ep0_urb;
+struct usb_endpoint_instance *ep0_endpoint;
+static struct usb_device_instance *udc_device;
+static int enabled;
+
+#ifdef MUSB_DEBUG
+static void musb_db_regs(void)
+{
+	u8 b;
+	u16 w;
+
+	b = readb(&musbr->faddr);
+	serial_printf("\tfaddr   0x%2.2x\n", b);
+
+	b = readb(&musbr->power);
+	musb_print_pwr(b);
+
+	w = readw(&musbr->ep[0].ep0.csr0);
+	musb_print_csr0(w);
+
+	b = readb(&musbr->devctl);
+	musb_print_devctl(b);
+
+	b = readb(&musbr->ep[0].ep0.configdata);
+	musb_print_config(b);
+
+	w = readw(&musbr->frame);
+	serial_printf("\tframe   0x%4.4x\n", w);
+
+	b = readb(&musbr->index);
+	serial_printf("\tindex   0x%2.2x\n", b);
+
+	w = readw(&musbr->ep[1].epN.rxmaxp);
+	musb_print_rxmaxp(w);
+
+	w = readw(&musbr->ep[1].epN.rxcsr);
+	musb_print_rxcsr(w);
+
+	w = readw(&musbr->ep[1].epN.txmaxp);
+	musb_print_txmaxp(w);
+
+	w = readw(&musbr->ep[1].epN.txcsr);
+	musb_print_txcsr(w);
+}
+#else
+#define musb_db_regs()
+#endif /* DEBUG_MUSB */
+
+static void musb_peri_softconnect(void)
+{
+	u8 power, devctl;
+	u8 intrusb;
+	u16 intrrx, intrtx;
+
+	/* Power off MUSB */
+	power = readb(&musbr->power);
+	power &= ~MUSB_POWER_SOFTCONN;
+	writeb(power, &musbr->power);
+
+	/* Read intr to clear */
+	intrusb = readb(&musbr->intrusb);
+	intrrx = readw(&musbr->intrrx);
+	intrtx = readw(&musbr->intrtx);
+
+	udelay(1000 * 1000); /* 1 sec */
+
+	/* Power on MUSB */
+	power = readb(&musbr->power);
+	power |= MUSB_POWER_SOFTCONN;
+	/*
+	 * The usb device interface is usb 1.1
+	 * Disable 2.0 high speed by clearring the hsenable bit.
+	 */
+	power &= ~MUSB_POWER_HSENAB;
+	writeb(power, &musbr->power);
+
+	/* Check if device is in b-peripheral mode */
+	devctl = readb(&musbr->devctl);
+	if (!(devctl & MUSB_DEVCTL_BDEVICE) ||
+	    (devctl & MUSB_DEVCTL_HM)) {
+		serial_printf("ERROR : Unsupport USB mode\n");
+		serial_printf("Check that mini-B USB cable is attached "
+			      "to the device\n");
+	}
+
+	if (debug_setup && (debug_level > 1))
+		musb_db_regs();
+}
+
+static void musb_peri_reset(void)
+{
+	if ((debug_setup) && (debug_level > 1))
+		serial_printf("INFO : %s reset\n", __PRETTY_FUNCTION__);
+
+	if (ep0_endpoint)
+		ep0_endpoint->endpoint_address = 0xff;
+
+	/* Sync sw and hw addresses */
+	writeb(udc_device->address, &musbr->faddr);
+
+	SET_EP0_STATE(IDLE);
+}
+
+static void musb_peri_resume(void)
+{
+	/* noop */
+}
+
+static void musb_peri_ep0_stall(void)
+{
+	u16 csr0;
+
+	csr0 = readw(&musbr->ep[0].ep0.csr0);
+	csr0 |= MUSB_CSR0_P_SENDSTALL;
+	writew(csr0, &musbr->ep[0].ep0.csr0);
+	if ((debug_setup) && (debug_level > 1))
+		serial_printf("INFO : %s stall\n", __PRETTY_FUNCTION__);
+}
+
+static void musb_peri_ep0_ack_req(void)
+{
+	u16 csr0;
+
+	csr0 = readw(&musbr->ep[0].ep0.csr0);
+	csr0 |= MUSB_CSR0_P_SVDRXPKTRDY;
+	writew(csr0, &musbr->ep[0].ep0.csr0);
+}
+
+static void musb_ep0_tx_ready(void)
+{
+	u16 csr0;
+
+	csr0 = readw(&musbr->ep[0].ep0.csr0);
+	csr0 |= MUSB_CSR0_TXPKTRDY;
+	writew(csr0, &musbr->ep[0].ep0.csr0);
+}
+
+static void musb_ep0_tx_ready_and_last(void)
+{
+	u16 csr0;
+
+	csr0 = readw(&musbr->ep[0].ep0.csr0);
+	csr0 |= (MUSB_CSR0_TXPKTRDY | MUSB_CSR0_P_DATAEND);
+	writew(csr0, &musbr->ep[0].ep0.csr0);
+}
+
+static void musb_peri_ep0_last(void)
+{
+	u16 csr0;
+
+	csr0 = readw(&musbr->ep[0].ep0.csr0);
+	csr0 |= MUSB_CSR0_P_DATAEND;
+	writew(csr0, &musbr->ep[0].ep0.csr0);
+}
+
+static void musb_peri_ep0_set_address(void)
+{
+	u8 faddr;
+	writeb(udc_device->address, &musbr->faddr);
+
+	/* Verify */
+	faddr = readb(&musbr->faddr);
+	if (udc_device->address == faddr) {
+		SET_EP0_STATE(IDLE);
+		usbd_device_event_irq(udc_device, DEVICE_ADDRESS_ASSIGNED, 0);
+		if ((debug_setup) && (debug_level > 1))
+			serial_printf("INFO : %s Address set to %d\n",
+				      __PRETTY_FUNCTION__, udc_device->address);
+	} else {
+		if (debug_level > 0)
+			serial_printf("ERROR : %s Address missmatch "
+				      "sw %d vs hw %d\n",
+				      __PRETTY_FUNCTION__,
+				      udc_device->address, faddr);
+	}
+}
+
+static void musb_peri_rx_ack(unsigned int ep)
+{
+	u16 peri_rxcsr;
+
+	peri_rxcsr = readw(&musbr->ep[ep].epN.rxcsr);
+	peri_rxcsr &= ~MUSB_RXCSR_RXPKTRDY;
+	writew(peri_rxcsr, &musbr->ep[ep].epN.rxcsr);
+}
+
+static void musb_peri_tx_ready(unsigned int ep)
+{
+	u16 peri_txcsr;
+
+	peri_txcsr = readw(&musbr->ep[ep].epN.txcsr);
+	peri_txcsr |= MUSB_TXCSR_TXPKTRDY;
+	writew(peri_txcsr, &musbr->ep[ep].epN.txcsr);
+}
+
+static void musb_peri_ep0_zero_data_request(int err)
+{
+	musb_peri_ep0_ack_req();
+
+	if (err) {
+		musb_peri_ep0_stall();
+		SET_EP0_STATE(IDLE);
+	} else {
+
+		musb_peri_ep0_last();
+
+		/* USBD state */
+		switch (ep0_urb->device_request.bRequest) {
+		case USB_REQ_SET_ADDRESS:
+			if ((debug_setup) && (debug_level > 1))
+				serial_printf("INFO : %s received set "
+					      "address\n", __PRETTY_FUNCTION__);
+			break;
+
+		case USB_REQ_SET_CONFIGURATION:
+			if ((debug_setup) && (debug_level > 1))
+				serial_printf("INFO : %s Configured\n",
+					      __PRETTY_FUNCTION__);
+			usbd_device_event_irq(udc_device, DEVICE_CONFIGURED, 0);
+			break;
+		}
+
+		/* EP0 state */
+		if (USB_REQ_SET_ADDRESS == ep0_urb->device_request.bRequest) {
+			SET_EP0_STATE(SET_ADDRESS);
+		} else {
+			SET_EP0_STATE(IDLE);
+		}
+	}
+}
+
+static void musb_peri_ep0_rx_data_request(void)
+{
+	/*
+	 * This is the completion of the data OUT / RX
+	 *
+	 * Host is sending data to ep0 that is not
+	 * part of setup.  This comes from the cdc_recv_setup
+	 * op that is device specific.
+	 *
+	 */
+	musb_peri_ep0_ack_req();
+
+	ep0_endpoint->rcv_urb = ep0_urb;
+	ep0_urb->actual_length = 0;
+	SET_EP0_STATE(RX);
+}
+
+static void musb_peri_ep0_tx_data_request(int err)
+{
+	if (err) {
+		musb_peri_ep0_stall();
+		SET_EP0_STATE(IDLE);
+	} else {
+		musb_peri_ep0_ack_req();
+
+		ep0_endpoint->tx_urb = ep0_urb;
+		ep0_endpoint->sent = 0;
+		SET_EP0_STATE(TX);
+	}
+}
+
+static void musb_peri_ep0_idle(void)
+{
+	u16 count0;
+	int err;
+	u16 csr0;
+
+	/*
+	 * Verify addresses
+	 * A lot of confusion can be caused if the address
+	 * in software, udc layer, does not agree with the
+	 * hardware.  Since the setting of the hardware address
+	 * must be set after the set address request, the
+	 * usb state machine is out of sync for a few frame.
+	 * It is a good idea to run this check when changes
+	 * are made to the state machine.
+	 */
+	if ((debug_level > 0) &&
+	    (ep0_state != SET_ADDRESS)) {
+		u8 faddr;
+
+		faddr = readb(&musbr->faddr);
+		if (udc_device->address != faddr) {
+			serial_printf("ERROR : %s addresses do not"
+				      "match sw %d vs hw %d\n",
+				      __PRETTY_FUNCTION__,
+				      udc_device->address, faddr);
+			udelay(1000 * 1000);
+			hang();
+		}
+	}
+
+	csr0 = readw(&musbr->ep[0].ep0.csr0);
+
+	if (!(MUSB_CSR0_RXPKTRDY & csr0))
+		goto end;
+
+	count0 = readw(&musbr->ep[0].ep0.count0);
+	if (count0 == 0)
+		goto end;
+
+	if (count0 != 8) {
+		if ((debug_setup) && (debug_level > 1))
+			serial_printf("WARN : %s SETUP incorrect size %d\n",
+				      __PRETTY_FUNCTION__, count0);
+		musb_peri_ep0_stall();
+		goto end;
+	}
+
+	read_fifo(0, count0, &ep0_urb->device_request);
+
+	if (debug_level > 2)
+		print_usb_device_request(&ep0_urb->device_request);
+
+	if (ep0_urb->device_request.wLength == 0) {
+		err = ep0_recv_setup(ep0_urb);
+
+		/* Zero data request */
+		musb_peri_ep0_zero_data_request(err);
+	} else {
+		/* Is data coming or going ? */
+		u8 reqType = ep0_urb->device_request.bmRequestType;
+
+		if (USB_REQ_DEVICE2HOST == (reqType & USB_REQ_DIRECTION_MASK)) {
+			err = ep0_recv_setup(ep0_urb);
+			/* Device to host */
+			musb_peri_ep0_tx_data_request(err);
+		} else {
+			/*
+			 * Host to device
+			 *
+			 * The RX routine will call ep0_recv_setup
+			 * when the data packet has arrived.
+			 */
+			musb_peri_ep0_rx_data_request();
+		}
+	}
+
+end:
+	return;
+}
+
+static void musb_peri_ep0_rx(void)
+{
+	/*
+	 * This is the completion of the data OUT / RX
+	 *
+	 * Host is sending data to ep0 that is not
+	 * part of setup.  This comes from the cdc_recv_setup
+	 * op that is device specific.
+	 *
+	 * Pass the data back to driver ep0_recv_setup which
+	 * should give the cdc_recv_setup the chance to handle
+	 * the rx
+	 */
+	u16 csr0;
+	u16 count0;
+
+	if (debug_level > 3) {
+		if (0 != ep0_urb->actual_length) {
+			serial_printf("%s finished ? %d of %d\n",
+				      __PRETTY_FUNCTION__,
+				      ep0_urb->actual_length,
+				      ep0_urb->device_request.wLength);
+		}
+	}
+
+	if (ep0_urb->device_request.wLength == ep0_urb->actual_length) {
+		musb_peri_ep0_last();
+		SET_EP0_STATE(IDLE);
+		ep0_recv_setup(ep0_urb);
+		return;
+	}
+
+	csr0 = readw(&musbr->ep[0].ep0.csr0);
+	if (!(MUSB_CSR0_RXPKTRDY & csr0))
+		return;
+
+	count0 = readw(&musbr->ep[0].ep0.count0);
+
+	if (count0) {
+		struct usb_endpoint_instance *endpoint;
+		u32 length;
+		u8 *data;
+
+		endpoint = ep0_endpoint;
+		if (endpoint && endpoint->rcv_urb) {
+			struct urb *urb = endpoint->rcv_urb;
+			unsigned int remaining_space = urb->buffer_length -
+				urb->actual_length;
+
+			if (remaining_space) {
+				int urb_bad = 0; /* urb is good */
+
+				if (count0 > remaining_space)
+					length = remaining_space;
+				else
+					length = count0;
+
+				data = (u8 *) urb->buffer_data;
+				data += urb->actual_length;
+
+				/* The common musb fifo reader */
+				read_fifo(0, length, data);
+
+				musb_peri_ep0_ack_req();
+
+				/*
+				 * urb's actual_length is updated in
+				 * usbd_rcv_complete
+				 */
+				usbd_rcv_complete(endpoint, length, urb_bad);
+
+			} else {
+				if (debug_level > 0)
+					serial_printf("ERROR : %s no space in "
+						      "rcv buffer\n",
+						      __PRETTY_FUNCTION__);
+			}
+		} else {
+			if (debug_level > 0)
+				serial_printf("ERROR : %s problem with "
+					      "endpoint\n",
+					      __PRETTY_FUNCTION__);
+		}
+	} else {
+		if (debug_level > 0)
+			serial_printf("ERROR : %s with nothing to do\n",
+				      __PRETTY_FUNCTION__);
+	}
+}
+
+static void musb_peri_ep0_tx(void)
+{
+	u16 csr0;
+	int transfer_size = 0;
+	unsigned int p, pm;
+
+	csr0 = readw(&musbr->ep[0].ep0.csr0);
+
+	/* Check for pending tx */
+	if (csr0 & MUSB_CSR0_TXPKTRDY)
+		goto end;
+
+	/* Check if this is the last packet sent */
+	if (ep0_endpoint->sent >= ep0_urb->actual_length) {
+		SET_EP0_STATE(IDLE);
+		goto end;
+	}
+
+	transfer_size = ep0_urb->actual_length - ep0_endpoint->sent;
+	/* Is the transfer size negative ? */
+	if (transfer_size <= 0) {
+		if (debug_level > 0)
+			serial_printf("ERROR : %s problem with the"
+				      " transfer size %d\n",
+				      __PRETTY_FUNCTION__,
+				      transfer_size);
+		SET_EP0_STATE(IDLE);
+		goto end;
+	}
+
+	/* Truncate large transfers to the fifo size */
+	if (transfer_size > ep0_endpoint->tx_packetSize)
+		transfer_size = ep0_endpoint->tx_packetSize;
+
+	write_fifo(0, transfer_size, &ep0_urb->buffer[ep0_endpoint->sent]);
+	ep0_endpoint->sent += transfer_size;
+
+	/* Done or more to send ? */
+	if (ep0_endpoint->sent >= ep0_urb->actual_length)
+		musb_ep0_tx_ready_and_last();
+	else
+		musb_ep0_tx_ready();
+
+	/* Wait a bit */
+	pm = 10;
+	for (p = 0; p < pm; p++) {
+		csr0 = readw(&musbr->ep[0].ep0.csr0);
+		if (!(csr0 & MUSB_CSR0_TXPKTRDY))
+			break;
+
+		/* Double the delay. */
+		udelay(1 << pm);
+	}
+
+	if ((ep0_endpoint->sent >= ep0_urb->actual_length) && (p < pm))
+		SET_EP0_STATE(IDLE);
+
+end:
+	return;
+}
+
+static void musb_peri_ep0(void)
+{
+	u16 csr0;
+
+	if (SET_ADDRESS == ep0_state)
+		return;
+
+	csr0 = readw(&musbr->ep[0].ep0.csr0);
+
+	/* Error conditions */
+	if (MUSB_CSR0_P_SENTSTALL & csr0) {
+		csr0 &= ~MUSB_CSR0_P_SENTSTALL;
+		writew(csr0, &musbr->ep[0].ep0.csr0);
+		SET_EP0_STATE(IDLE);
+	}
+	if (MUSB_CSR0_P_SETUPEND & csr0) {
+		csr0 |= MUSB_CSR0_P_SVDSETUPEND;
+		writew(csr0, &musbr->ep[0].ep0.csr0);
+		SET_EP0_STATE(IDLE);
+		if ((debug_setup) && (debug_level > 1))
+			serial_printf("WARN: %s SETUPEND\n",
+				      __PRETTY_FUNCTION__);
+	}
+
+	/* Normal states */
+	if (IDLE == ep0_state)
+		musb_peri_ep0_idle();
+
+	if (TX == ep0_state)
+		musb_peri_ep0_tx();
+
+	if (RX == ep0_state)
+		musb_peri_ep0_rx();
+}
+
+static void musb_peri_rx_ep(unsigned int ep)
+{
+	u16 peri_rxcount = readw(&musbr->ep[ep].epN.rxcount);
+
+	if (peri_rxcount) {
+		struct usb_endpoint_instance *endpoint;
+		u32 length;
+		u8 *data;
+
+		endpoint = GET_ENDPOINT(udc_device, ep);
+		if (endpoint && endpoint->rcv_urb) {
+			struct urb *urb = endpoint->rcv_urb;
+			unsigned int remaining_space = urb->buffer_length -
+				urb->actual_length;
+
+			if (remaining_space) {
+				int urb_bad = 0; /* urb is good */
+
+				if (peri_rxcount > remaining_space)
+					length = remaining_space;
+				else
+					length = peri_rxcount;
+
+				data = (u8 *) urb->buffer_data;
+				data += urb->actual_length;
+
+				/* The common musb fifo reader */
+				read_fifo(ep, length, data);
+
+				musb_peri_rx_ack(ep);
+
+				/*
+				 * urb's actual_length is updated in
+				 * usbd_rcv_complete
+				 */
+				usbd_rcv_complete(endpoint, length, urb_bad);
+
+			} else {
+				if (debug_level > 0)
+					serial_printf("ERROR : %s %d no space "
+						      "in rcv buffer\n",
+						      __PRETTY_FUNCTION__, ep);
+			}
+		} else {
+			if (debug_level > 0)
+				serial_printf("ERROR : %s %d problem with "
+					      "endpoint\n",
+					      __PRETTY_FUNCTION__, ep);
+		}
+
+	} else {
+		if (debug_level > 0)
+			serial_printf("ERROR : %s %d with nothing to do\n",
+				      __PRETTY_FUNCTION__, ep);
+	}
+}
+
+static void musb_peri_rx(u16 intr)
+{
+	unsigned int ep;
+
+	/* Check for EP0 */
+	if (0x01 & intr)
+		musb_peri_ep0();
+
+	for (ep = 1; ep < 16; ep++) {
+		if ((1 << ep) & intr)
+			musb_peri_rx_ep(ep);
+	}
+}
+
+static void musb_peri_tx(u16 intr)
+{
+	/* Check for EP0 */
+	if (0x01 & intr)
+		musb_peri_ep0_tx();
+
+	/*
+	 * Use this in the future when handling epN tx
+	 *
+	 * u8 ep;
+	 *
+	 * for (ep = 1; ep < 16; ep++) {
+	 *	if ((1 << ep) & intr) {
+	 *		/ * handle tx for this endpoint * /
+	 *	}
+	 * }
+	 */
+}
+
+void udc_irq(void)
+{
+	/* This is a high freq called function */
+	if (enabled) {
+		u8 intrusb;
+
+		intrusb = readb(&musbr->intrusb);
+
+		/*
+		 * See drivers/usb/gadget/mpc8xx_udc.c for
+		 * state diagram going from detached through
+		 * configuration.
+		 */
+		if (MUSB_INTR_RESUME & intrusb) {
+			usbd_device_event_irq(udc_device,
+					      DEVICE_BUS_ACTIVITY, 0);
+			musb_peri_resume();
+		}
+
+		musb_peri_ep0();
+
+		if (MUSB_INTR_RESET & intrusb) {
+			usbd_device_event_irq(udc_device, DEVICE_RESET, 0);
+			musb_peri_reset();
+		}
+
+		if (MUSB_INTR_DISCONNECT & intrusb) {
+			/* cable unplugged from hub/host */
+			usbd_device_event_irq(udc_device, DEVICE_RESET, 0);
+			musb_peri_reset();
+			usbd_device_event_irq(udc_device, DEVICE_HUB_RESET, 0);
+		}
+
+		if (MUSB_INTR_SOF & intrusb) {
+			usbd_device_event_irq(udc_device,
+					      DEVICE_BUS_ACTIVITY, 0);
+			musb_peri_resume();
+		}
+
+		if (MUSB_INTR_SUSPEND & intrusb) {
+			usbd_device_event_irq(udc_device,
+					      DEVICE_BUS_INACTIVE, 0);
+		}
+
+		if (ep0_state != SET_ADDRESS) {
+			u16 intrrx, intrtx;
+
+			intrrx = readw(&musbr->intrrx);
+			intrtx = readw(&musbr->intrtx);
+
+			if (intrrx)
+				musb_peri_rx(intrrx);
+
+			if (intrtx)
+				musb_peri_tx(intrtx);
+		} else {
+			if (MUSB_INTR_SOF & intrusb) {
+				u8 faddr;
+				faddr = readb(&musbr->faddr);
+				/*
+				 * Setting of the address can fail.
+				 * Normally it succeeds the second time.
+				 */
+				if (udc_device->address != faddr)
+					musb_peri_ep0_set_address();
+			}
+		}
+	}
+}
+
+void udc_set_nak(int ep_num)
+{
+	/* noop */
+}
+
+void udc_unset_nak(int ep_num)
+{
+	/* noop */
+}
+
+int udc_endpoint_write(struct usb_endpoint_instance *endpoint)
+{
+	int ret = 0;
+
+	/* Transmit only if the hardware is available */
+	if (endpoint->tx_urb && endpoint->state == 0) {
+		unsigned int ep = endpoint->endpoint_address &
+			USB_ENDPOINT_NUMBER_MASK;
+
+		u16 peri_txcsr = readw(&musbr->ep[ep].epN.txcsr);
+
+		/* Error conditions */
+		if (peri_txcsr & MUSB_TXCSR_P_UNDERRUN) {
+			peri_txcsr &= ~MUSB_TXCSR_P_UNDERRUN;
+			writew(peri_txcsr, &musbr->ep[ep].epN.txcsr);
+		}
+
+		if (debug_level > 1)
+			musb_print_txcsr(peri_txcsr);
+
+		/* Check if a packet is waiting to be sent */
+		if (!(peri_txcsr & MUSB_TXCSR_TXPKTRDY)) {
+			u32 length;
+			u8 *data;
+			struct urb *urb = endpoint->tx_urb;
+			unsigned int remaining_packet = urb->actual_length -
+				endpoint->sent;
+
+			if (endpoint->tx_packetSize < remaining_packet)
+				length = endpoint->tx_packetSize;
+			else
+				length = remaining_packet;
+
+			data = (u8 *) urb->buffer;
+			data += endpoint->sent;
+
+			/* common musb fifo function */
+			write_fifo(ep, length, data);
+
+			musb_peri_tx_ready(ep);
+
+			endpoint->last = length;
+			/* usbd_tx_complete will take care of updating 'sent' */
+			usbd_tx_complete(endpoint);
+		}
+	} else {
+		if (debug_level > 0)
+			serial_printf("ERROR : %s Problem with urb %p "
+				      "or ep state %d\n",
+				      __PRETTY_FUNCTION__,
+				      endpoint->tx_urb, endpoint->state);
+	}
+
+	return ret;
+}
+
+void udc_setup_ep(struct usb_device_instance *device, unsigned int id,
+		  struct usb_endpoint_instance *endpoint)
+{
+	if (0 == id) {
+		/* EP0 */
+		ep0_endpoint = endpoint;
+		ep0_endpoint->endpoint_address = 0xff;
+		ep0_urb = usbd_alloc_urb(device, endpoint);
+	} else if (MAX_ENDPOINT >= id) {
+		int ep_addr;
+
+		/* Check the direction */
+		ep_addr = endpoint->endpoint_address;
+		if (USB_DIR_IN == (ep_addr & USB_ENDPOINT_DIR_MASK)) {
+			/* IN */
+			epinfo[(id * 2) + 1].epsize = endpoint->tx_packetSize;
+		} else {
+			/* OUT */
+			epinfo[id * 2].epsize = endpoint->rcv_packetSize;
+		}
+
+		musb_configure_ep(&epinfo[0],
+				  sizeof(epinfo) / sizeof(struct musb_epinfo));
+	} else {
+		if (debug_level > 0)
+			serial_printf("ERROR : %s endpoint request %d "
+				      "exceeds maximum %d\n",
+				      __PRETTY_FUNCTION__, id, MAX_ENDPOINT);
+	}
+}
+
+void udc_connect(void)
+{
+	/* noop */
+}
+
+void udc_disconnect(void)
+{
+	/* noop */
+}
+
+void udc_enable(struct usb_device_instance *device)
+{
+	/* Save the device structure pointer */
+	udc_device = device;
+
+	enabled = 1;
+}
+
+void udc_disable(void)
+{
+	enabled = 0;
+}
+
+void udc_startup_events(struct usb_device_instance *device)
+{
+	/* The DEVICE_INIT event puts the USB device in the state STATE_INIT. */
+	usbd_device_event_irq(device, DEVICE_INIT, 0);
+
+	/*
+	 * The DEVICE_CREATE event puts the USB device in the state
+	 * STATE_ATTACHED.
+	 */
+	usbd_device_event_irq(device, DEVICE_CREATE, 0);
+
+	/* Resets the address to 0 */
+	usbd_device_event_irq(device, DEVICE_RESET, 0);
+
+	udc_enable(device);
+}
+
+int udc_init(void)
+{
+	int ret;
+	int ep_loop;
+
+	ret = musb_platform_init();
+	if (ret < 0)
+		goto end;
+
+	/* Configure all the endpoint FIFO's and start usb controller */
+	musbr = musb_cfg.regs;
+
+	/* Initialize the endpoints */
+	for (ep_loop = 0; ep_loop < MAX_ENDPOINT * 2; ep_loop++) {
+		epinfo[ep_loop].epnum = (ep_loop / 2) + 1;
+		epinfo[ep_loop].epdir = ep_loop % 2; /* OUT, IN */
+		epinfo[ep_loop].epsize = 0;
+	}
+
+	musb_peri_softconnect();
+
+	ret = 0;
+end:
+
+	return ret;
+}
diff --git a/drivers/usb/musb/omap3.c b/drivers/usb/musb/omap3.c
new file mode 100644
index 0000000..ea98c3c
--- /dev/null
+++ b/drivers/usb/musb/omap3.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2009 Wind River Systems, Inc.
+ * Tom Rix <Tom.Rix@windriver.com>
+ *
+ * This is file is based on
+ * repository git.gitorious.org/u-boot-omap3/mainline.git,
+ * branch omap3-dev-usb, file drivers/usb/host/omap3530_usb.c
+ *
+ * This is the unique part of its copyright :
+ *
+ * ------------------------------------------------------------------------
+ *
+ * Copyright (c) 2009 Texas Instruments
+ *
+ * ------------------------------------------------------------------------
+ *
+ * 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
+ */
+
+#include <twl4030.h>
+#include "omap3.h"
+
+static int platform_needs_initialization = 1;
+
+struct musb_config musb_cfg = {
+	(struct	musb_regs *)MENTOR_USB0_BASE,
+	OMAP3_USB_TIMEOUT,
+	0
+};
+
+/*
+ * OMAP3 USB OTG registers.
+ */
+struct omap3_otg_regs {
+	u32	revision;
+	u32	sysconfig;
+	u32	sysstatus;
+	u32	interfsel;
+	u32	simenable;
+	u32	forcestdby;
+};
+
+static struct omap3_otg_regs *otg;
+
+#define OMAP3_OTG_SYSCONFIG_SMART_STANDBY_MODE		0x2000
+#define OMAP3_OTG_SYSCONFIG_NO_STANDBY_MODE		0x1000
+#define OMAP3_OTG_SYSCONFIG_SMART_IDLE_MODE		0x0010
+#define OMAP3_OTG_SYSCONFIG_NO_IDLE_MODE		0x0008
+#define OMAP3_OTG_SYSCONFIG_ENABLEWAKEUP		0x0004
+#define OMAP3_OTG_SYSCONFIG_SOFTRESET			0x0002
+#define OMAP3_OTG_SYSCONFIG_AUTOIDLE			0x0001
+
+#define OMAP3_OTG_SYSSTATUS_RESETDONE			0x0001
+
+#define OMAP3_OTG_INTERFSEL_OMAP			0x0001
+
+#define OMAP3_OTG_FORCESTDBY_STANDBY			0x0001
+
+
+#ifdef DEBUG_MUSB_OMAP3
+static void musb_db_otg_regs(void)
+{
+	u32 l;
+	l = readl(&otg->revision);
+	serial_printf("OTG_REVISION 0x%x\n", l);
+	l = readl(&otg->sysconfig);
+	serial_printf("OTG_SYSCONFIG 0x%x\n", l);
+	l = readl(&otg->sysstatus);
+	serial_printf("OTG_SYSSTATUS 0x%x\n", l);
+	l = readl(&otg->interfsel);
+	serial_printf("OTG_INTERFSEL 0x%x\n", l);
+	l = readl(&otg->forcestdby);
+	serial_printf("OTG_FORCESTDBY 0x%x\n", l);
+}
+#endif
+
+int musb_platform_init(void)
+{
+	int ret = -1;
+
+	if (platform_needs_initialization) {
+		u32 stdby;
+
+		/*
+		 * OMAP3EVM uses ISP1504 phy and so
+		 * twl4030 related init is not required.
+		 */
+#ifdef CONFIG_TWL4030_USB
+		if (twl4030_usb_ulpi_init()) {
+			serial_printf("ERROR: %s Could not initialize PHY\n",
+				__PRETTY_FUNCTION__);
+			goto end;
+		}
+#endif
+		otg = (struct omap3_otg_regs *)OMAP3_OTG_BASE;
+
+		/* Set OTG to always be on */
+		writel(OMAP3_OTG_SYSCONFIG_NO_STANDBY_MODE |
+		       OMAP3_OTG_SYSCONFIG_NO_IDLE_MODE, &otg->sysconfig);
+
+		/* Set the interface */
+		writel(OMAP3_OTG_INTERFSEL_OMAP, &otg->interfsel);
+
+		/* Clear force standby */
+		stdby = readl(&otg->forcestdby);
+		stdby &= ~OMAP3_OTG_FORCESTDBY_STANDBY;
+		writel(stdby, &otg->forcestdby);
+
+		platform_needs_initialization = 0;
+	}
+
+	ret = platform_needs_initialization;
+end:
+	return ret;
+
+}
+
+void musb_platform_deinit(void)
+{
+	/* noop */
+}
diff --git a/drivers/usb/musb/omap3.h b/drivers/usb/musb/omap3.h
new file mode 100644
index 0000000..20fc9d2
--- /dev/null
+++ b/drivers/usb/musb/omap3.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2009 Wind River Systems, Inc.
+ * Tom Rix <Tom.Rix@windriver.com>
+ *
+ * This file is based on the file drivers/usb/musb/davinci.h
+ *
+ * This is the unique part of its copyright:
+ *
+ * --------------------------------------------------------------------
+ *
+ * Copyright (c) 2008 Texas Instruments
+ * Author: Thomas Abraham t-abraham@ti.com, Texas Instruments
+ *
+ * --------------------------------------------------------------------
+ *
+ * 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
+ */
+#ifndef _MUSB_OMAP3_H_
+#define _MUSB_OMAP3_H_
+
+#include "musb_core.h"
+
+/* Base address of MUSB registers */
+#define MENTOR_USB0_BASE (OMAP34XX_CORE_L4_IO_BASE + 0xAB000)
+
+/* Base address of OTG registers */
+#define OMAP3_OTG_BASE (MENTOR_USB0_BASE + 0x400)
+
+/* Timeout for USB module */
+#define OMAP3_USB_TIMEOUT 0x3FFFFFF
+
+int musb_platform_init(void);
+
+#endif /* _MUSB_OMAP3_H */
+
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
new file mode 100644
index 0000000..200b907
--- /dev/null
+++ b/drivers/usb/phy/Makefile
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2009 Wind River Systems, Inc.
+# Tom Rix <Tom.Rix@windriver.com>
+#
+# 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
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	:= $(obj)libusb_phy.a
+
+COBJS-$(CONFIG_TWL4030_USB) += twl4030.o
+COBJS-y := twl4030.o
+
+COBJS	:= $(COBJS-y)
+SRCS	:= $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+
+all:	$(LIB)
+
+$(LIB):	$(obj).depend $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/usb/phy/twl4030.c b/drivers/usb/phy/twl4030.c
new file mode 100644
index 0000000..54d2e61
--- /dev/null
+++ b/drivers/usb/phy/twl4030.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2009 Wind River Systems, Inc.
+ * Tom Rix <Tom.Rix@windriver.com>
+ *
+ * This is file is based on
+ * repository git.gitorious.org/u-boot-omap3/mainline.git,
+ * branch omap3-dev-usb, file drivers/usb/gadget/twl4030_usb.c
+ *
+ * This is the unique part of its copyright :
+ *
+ * ------------------------------------------------------------------------
+ *
+ *  * (C) Copyright 2009 Atin Malaviya (atin.malaviya@gmail.com)
+ *
+ * Based on: twl4030_usb.c in linux 2.6 (drivers/i2c/chips/twl4030_usb.c)
+ * Copyright (C) 2004-2007 Texas Instruments
+ * Copyright (C) 2008 Nokia Corporation
+ * Contact: Felipe Balbi <felipe.balbi@nokia.com>
+ *
+ * Author: Atin Malaviya (atin.malaviya@gmail.com)
+ *
+ * ------------------------------------------------------------------------
+ *
+ * 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
+ */
+
+#include <twl4030.h>
+
+/* Defines for bits in registers */
+#define OPMODE_MASK		(3 << 3)
+#define XCVRSELECT_MASK		(3 << 0)
+#define CARKITMODE		(1 << 2)
+#define OTG_ENAB		(1 << 5)
+#define PHYPWD			(1 << 0)
+#define CLOCKGATING_EN		(1 << 2)
+#define CLK32K_EN		(1 << 1)
+#define REQ_PHY_DPLL_CLK	(1 << 0)
+#define PHY_DPLL_CLK		(1 << 0)
+
+static int twl4030_usb_write(u8 address, u8 data)
+{
+	int ret;
+
+	ret = twl4030_i2c_write_u8(TWL4030_CHIP_USB, data, address);
+	if (ret != 0)
+		printf("TWL4030:USB:Write[0x%x] Error %d\n", address, ret);
+
+	return ret;
+}
+
+static int twl4030_usb_read(u8 address)
+{
+	u8 data;
+	int ret;
+
+	ret = twl4030_i2c_read_u8(TWL4030_CHIP_USB, &data, address);
+	if (ret == 0)
+		ret = data;
+	else
+		printf("TWL4030:USB:Read[0x%x] Error %d\n", address, ret);
+
+	return ret;
+}
+
+static void twl4030_usb_ldo_init(void)
+{
+	/* Enable writing to power configuration registers */
+	twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, 0xC0,
+			     TWL4030_PM_MASTER_PROTECT_KEY);
+	twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, 0x0C,
+			     TWL4030_PM_MASTER_PROTECT_KEY);
+
+	/* put VUSB3V1 LDO in active state */
+	twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x00,
+			     TWL4030_PM_RECEIVER_VUSB_DEDICATED2);
+
+	/* input to VUSB3V1 LDO is from VBAT, not VBUS */
+	twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x14,
+			     TWL4030_PM_RECEIVER_VUSB_DEDICATED1);
+
+	/* turn on 3.1V regulator */
+	twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x20,
+			     TWL4030_PM_RECEIVER_VUSB3V1_DEV_GRP);
+	twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x00,
+			     TWL4030_PM_RECEIVER_VUSB3V1_TYPE);
+
+	/* turn on 1.5V regulator */
+	twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x20,
+			     TWL4030_PM_RECEIVER_VUSB1V5_DEV_GRP);
+	twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x00,
+			     TWL4030_PM_RECEIVER_VUSB1V5_TYPE);
+
+	/* turn on 1.8V regulator */
+	twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x20,
+			     TWL4030_PM_RECEIVER_VUSB1V8_DEV_GRP);
+	twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x00,
+			     TWL4030_PM_RECEIVER_VUSB1V8_TYPE);
+
+	/* disable access to power configuration registers */
+	twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, 0x00,
+			     TWL4030_PM_MASTER_PROTECT_KEY);
+}
+
+static void twl4030_phy_power(void)
+{
+	u8 pwr, clk;
+
+	/* Power the PHY */
+	pwr = twl4030_usb_read(TWL4030_USB_PHY_PWR_CTRL);
+	pwr &= ~PHYPWD;
+	twl4030_usb_write(TWL4030_USB_PHY_PWR_CTRL, pwr);
+	/* Enable clocks */
+	clk = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL);
+	clk |= CLOCKGATING_EN | CLK32K_EN;
+	twl4030_usb_write(TWL4030_USB_PHY_CLK_CTRL, clk);
+}
+
+/*
+ * Initiaze the ULPI interface
+ * ULPI : Universal Transceiver Macrocell Low Pin Interface
+ * An interface between the USB link controller like musb and the
+ * the PHY or transceiver that drives the actual bus.
+ */
+int twl4030_usb_ulpi_init(void)
+{
+	long timeout = 1000 * 1000; /* 1 sec */;
+	u8 clk, sts, pwr;
+
+	/* twl4030 ldo init */
+	twl4030_usb_ldo_init();
+
+	/* Enable the twl4030 phy */
+	twl4030_phy_power();
+
+	/* Enable DPLL to access PHY registers over I2C */
+	clk = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL);
+	clk |= REQ_PHY_DPLL_CLK;
+	twl4030_usb_write(TWL4030_USB_PHY_CLK_CTRL, clk);
+
+	/* Check if the PHY DPLL is locked */
+	sts = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL_STS);
+	while (!(sts & PHY_DPLL_CLK) && 0 < timeout) {
+		udelay(10);
+		sts = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL_STS);
+		timeout -= 10;
+	}
+
+	/* Final check */
+	sts = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL_STS);
+	if (!(sts & PHY_DPLL_CLK)) {
+		printf("Error:TWL4030:USB Timeout setting PHY DPLL clock\n");
+		return -1;
+	}
+
+	/*
+	 * There are two circuit blocks attached to the PHY,
+	 * Carkit and USB OTG.  Disable Carkit and enable USB OTG
+	 */
+	twl4030_usb_write(TWL4030_USB_IFC_CTRL_CLR, CARKITMODE);
+	pwr = twl4030_usb_read(TWL4030_USB_POWER_CTRL);
+	pwr |= OTG_ENAB;
+	twl4030_usb_write(TWL4030_USB_POWER_CTRL_SET, pwr);
+
+	/* Clear the opmode bits to ensure normal encode */
+	twl4030_usb_write(TWL4030_USB_FUNC_CTRL_CLR, OPMODE_MASK);
+
+	/* Clear the xcvrselect bits to enable the high speed transeiver */
+	twl4030_usb_write(TWL4030_USB_FUNC_CTRL_CLR, XCVRSELECT_MASK);
+
+	/* Let ULPI control the DPLL clock */
+	clk = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL);
+	clk &= ~REQ_PHY_DPLL_CLK;
+	twl4030_usb_write(TWL4030_USB_PHY_CLK_CTRL, clk);
+
+	return 0;
+}
diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c
index 16d6689..c07a26e 100644
--- a/drivers/video/cfb_console.c
+++ b/drivers/video/cfb_console.c
@@ -403,8 +403,6 @@
 	    { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff } };
 
 
-int gunzip(void *, int, unsigned char *, unsigned long *);
-
 /******************************************************************************/
 
 static void video_drawchars (int xx, int yy, unsigned char *s, int count)
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 06772af..0af471a 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -2140,7 +2140,4 @@
 /* todo: Move these to a common U-Boot header */
 int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
 			  unsigned char *out, size_t *out_len);
-
-int zunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp,
-						int stoponerr, int offset);
 #endif /* !__UBIFS_H__ */
diff --git a/include/common.h b/include/common.h
index 00b5434..07897f6 100644
--- a/include/common.h
+++ b/include/common.h
@@ -612,6 +612,11 @@
 ulong	ticks2usec    (unsigned long ticks);
 int	init_timebase (void);
 
+/* lib_generic/gunzip.c */
+int gunzip(void *, int, unsigned char *, unsigned long *);
+int zunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp,
+						int stoponerr, int offset);
+
 /* lib_generic/time.c */
 void	udelay        (unsigned long);
 
diff --git a/include/configs/B2.h b/include/configs/B2.h
index e5439f3..f51a261 100644
--- a/include/configs/B2.h
+++ b/include/configs/B2.h
@@ -58,7 +58,7 @@
 /*
  * Hardware drivers
  */
-#define CONFIG_DRIVER_LAN91C96
+#define CONFIG_LAN91C96
 #define CONFIG_LAN91C96_BASE		0x04000300 /* base address         */
 #define CONFIG_SMC_USE_32_BIT
 #undef  CONFIG_SHOW_ACTIVITY
@@ -98,7 +98,7 @@
 #define CONFIG_CMD_EEPROM
 #define CONFIG_CMD_I2C
 
-
+#define CONFIG_NET_MULTI
 #define CONFIG_BOOTDELAY	5
 #define CONFIG_ETHADDR	00:50:c2:1e:af:fb
 #define CONFIG_BOOTARGS  "setenv bootargs root=/dev/ram ip=192.168.0.70:::::eth0:off \
diff --git a/include/configs/apollon.h b/include/configs/apollon.h
index adab454..ed14f7a 100644
--- a/include/configs/apollon.h
+++ b/include/configs/apollon.h
@@ -88,7 +88,8 @@
 /*
  * SMC91c96 Etherent
  */
-#define	CONFIG_DRIVER_LAN91C96
+#define CONFIG_NET_MULTI
+#define	CONFIG_LAN91C96
 #define	CONFIG_LAN91C96_BASE	(APOLLON_CS1_BASE+0x300)
 #define	CONFIG_LAN91C96_EXT_PHY
 
diff --git a/include/configs/assabet.h b/include/configs/assabet.h
index 8c5b84c..d17d4bd 100644
--- a/include/configs/assabet.h
+++ b/include/configs/assabet.h
@@ -53,7 +53,8 @@
 /*
  * Hardware drivers
  */
-#define CONFIG_DRIVER_LAN91C96	/* we have an SMC9194 on-board */
+#define CONFIG_NET_MULTI
+#define CONFIG_LAN91C96	/* we have an SMC9194 on-board */
 #define CONFIG_LAN91C96_BASE	0x18000000
 
 /*
diff --git a/include/configs/gcplus.h b/include/configs/gcplus.h
index 85db4f5..41294b9 100644
--- a/include/configs/gcplus.h
+++ b/include/configs/gcplus.h
@@ -66,7 +66,8 @@
 /*
  * Hardware drivers
  */
-#define CONFIG_DRIVER_LAN91C96	/* we have an SMC9194 on-board */
+#define CONFIG_NET_MULTI
+#define CONFIG_LAN91C96	/* we have an SMC9194 on-board */
 #define CONFIG_LAN91C96_BASE	0x100e0000
 
 /*
diff --git a/include/configs/lubbock.h b/include/configs/lubbock.h
index 43913ca..0a69210 100644
--- a/include/configs/lubbock.h
+++ b/include/configs/lubbock.h
@@ -58,7 +58,8 @@
 /*
  * Hardware drivers
  */
-#define CONFIG_DRIVER_LAN91C96
+#define CONFIG_NET_MULTI
+#define CONFIG_LAN91C96
 #define CONFIG_LAN91C96_BASE 0x0C000000
 
 /*
diff --git a/include/configs/omap1510inn.h b/include/configs/omap1510inn.h
index 8408209..b0ebafd 100644
--- a/include/configs/omap1510inn.h
+++ b/include/configs/omap1510inn.h
@@ -60,7 +60,8 @@
 #define CONFIG_SMC9196_BASE 0x08000300
 #define CONFIG_SMC9196_EXT_PHY
 */
-#define CONFIG_DRIVER_LAN91C96
+#define CONFIG_NET_MULTI
+#define CONFIG_LAN91C96
 #define CONFIG_LAN91C96_BASE 0x08000300
 #define CONFIG_LAN91C96_EXT_PHY
 
diff --git a/include/configs/omap1610h2.h b/include/configs/omap1610h2.h
index 42e0198..0bbb5b3 100644
--- a/include/configs/omap1610h2.h
+++ b/include/configs/omap1610h2.h
@@ -57,7 +57,8 @@
 /*
  * Hardware drivers
  */
-#define CONFIG_DRIVER_LAN91C96
+#define CONFIG_NET_MULTI
+#define CONFIG_LAN91C96
 #define CONFIG_LAN91C96_BASE 0x04000300
 #define CONFIG_LAN91C96_EXT_PHY
 
diff --git a/include/configs/omap1610inn.h b/include/configs/omap1610inn.h
index 22c873e..832dd42 100644
--- a/include/configs/omap1610inn.h
+++ b/include/configs/omap1610inn.h
@@ -58,7 +58,8 @@
  */
 /*
 */
-#define CONFIG_DRIVER_LAN91C96
+#define CONFIG_NET_MULTI
+#define CONFIG_LAN91C96
 #define CONFIG_LAN91C96_BASE 0x04000300
 #define CONFIG_LAN91C96_EXT_PHY
 
diff --git a/include/configs/omap2420h4.h b/include/configs/omap2420h4.h
index 9c18842..6ab4438 100644
--- a/include/configs/omap2420h4.h
+++ b/include/configs/omap2420h4.h
@@ -81,7 +81,8 @@
 /*
  * SMC91c96 Etherent
  */
-#define CONFIG_DRIVER_LAN91C96
+#define CONFIG_NET_MULTI
+#define CONFIG_LAN91C96
 #define CONFIG_LAN91C96_BASE     (H4_CS1_BASE+0x300)
 #define CONFIG_LAN91C96_EXT_PHY
 
diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h
index a6fe5e1..4fe3bd8 100644
--- a/include/configs/omap3_beagle.h
+++ b/include/configs/omap3_beagle.h
@@ -100,6 +100,21 @@
 /* DDR - I use Micron DDR */
 #define CONFIG_OMAP3_MICRON_DDR		1
 
+/* USB */
+#define CONFIG_MUSB_UDC			1
+#define CONFIG_USB_OMAP3		1
+#define CONFIG_TWL4030_USB		1
+
+/* USB device configuration */
+#define CONFIG_USB_DEVICE		1
+#define CONFIG_USB_TTY			1
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV	1
+/* Change these to suit your needs */
+#define CONFIG_USBD_VENDORID		0x0451
+#define CONFIG_USBD_PRODUCTID		0x5678
+#define CONFIG_USBD_MANUFACTURER	"Texas Instruments"
+#define CONFIG_USBD_PRODUCT_NAME	"Beagle"
+
 /* commands to include */
 #include <config_cmd_default.h>
 
@@ -164,6 +179,7 @@
 
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"loadaddr=0x82000000\0" \
+	"usbtty=cdc_acm\0" \
 	"console=ttyS2,115200n8\0" \
 	"vram=12M\0" \
 	"dvimode=1024x768MR-16@60\0" \
diff --git a/include/configs/omap3_evm.h b/include/configs/omap3_evm.h
index 00093f8..630b00f 100644
--- a/include/configs/omap3_evm.h
+++ b/include/configs/omap3_evm.h
@@ -104,6 +104,44 @@
 /* DDR - I use Micron DDR */
 #define CONFIG_OMAP3_MICRON_DDR		1
 
+/* USB
+ * Enable CONFIG_MUSB_HCD for Host functionalities MSC, keyboard
+ * Enable CONFIG_MUSB_UDD for Device functionalities.
+ */
+#define CONFIG_USB_OMAP3		1
+#define CONFIG_MUSB_HCD			1
+/* #define CONFIG_MUSB_UDC		1 */
+
+#ifdef CONFIG_USB_OMAP3
+
+#ifdef CONFIG_MUSB_HCD
+#define CONFIG_CMD_USB
+
+#define CONFIG_USB_STORAGE
+#define CONGIG_CMD_STORAGE
+#define CONFIG_CMD_FAT
+
+#ifdef CONFIG_USB_KEYBOARD
+#define CONFIG_SYS_USB_EVENT_POLL
+#define CONFIG_PREBOOT "usb start"
+#endif /* CONFIG_USB_KEYBOARD */
+
+#endif /* CONFIG_MUSB_HCD */
+
+#ifdef CONFIG_MUSB_UDC
+/* USB device configuration */
+#define CONFIG_USB_DEVICE		1
+#define CONFIG_USB_TTY			1
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV	1
+/* Change these to suit your needs */
+#define CONFIG_USBD_VENDORID		0x0451
+#define CONFIG_USBD_PRODUCTID		0x5678
+#define CONFIG_USBD_MANUFACTURER	"Texas Instruments"
+#define CONFIG_USBD_PRODUCT_NAME	"EVM"
+#endif /* CONFIG_MUSB_UDC */
+
+#endif /* CONFIG_USB_OMAP3 */
+
 /* commands to include */
 #include <config_cmd_default.h>
 
@@ -160,6 +198,7 @@
 
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"loadaddr=0x82000000\0" \
+	"usbtty=cdc_acm\0" \
 	"console=ttyS2,115200n8\0" \
 	"mmcargs=setenv bootargs console=${console} " \
 		"root=/dev/mmcblk0p2 rw " \
diff --git a/include/configs/omap3_sdp3430.h b/include/configs/omap3_sdp3430.h
index d91c8ff..fa2ad53 100644
--- a/include/configs/omap3_sdp3430.h
+++ b/include/configs/omap3_sdp3430.h
@@ -203,7 +203,8 @@
  */
 #if defined(CONFIG_CMD_NET)
 
-#define CONFIG_DRIVER_LAN91C96
+#define CONFIG_NET_MULTI
+#define CONFIG_LAN91C96
 #define CONFIG_LAN91C96_BASE	DEBUG_BASE
 #define CONFIG_LAN91C96_EXT_PHY
 
diff --git a/include/configs/omap3_zoom1.h b/include/configs/omap3_zoom1.h
index ef7a28b..fa58281 100644
--- a/include/configs/omap3_zoom1.h
+++ b/include/configs/omap3_zoom1.h
@@ -101,6 +101,21 @@
 /* DDR - I use Micron DDR */
 #define CONFIG_OMAP3_MICRON_DDR		1
 
+/* USB */
+#define CONFIG_MUSB_UDC			1
+#define CONFIG_USB_OMAP3		1
+#define CONFIG_TWL4030_USB		1
+
+/* USB device configuration */
+#define CONFIG_USB_DEVICE		1
+#define CONFIG_USB_TTY			1
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV	1
+/* Change these to suit your needs */
+#define CONFIG_USBD_VENDORID		0x0451
+#define CONFIG_USBD_PRODUCTID		0x5678
+#define CONFIG_USBD_MANUFACTURER	"Texas Instruments"
+#define CONFIG_USBD_PRODUCT_NAME	"Zoom1"
+
 /* commands to include */
 #include <config_cmd_default.h>
 
@@ -160,6 +175,7 @@
 
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"loadaddr=0x82000000\0" \
+	"usbtty=cdc_acm\0" \
 	"console=ttyS2,115200n8\0" \
 	"videomode=1024x768@60,vxres=1024,vyres=768\0" \
 	"videospec=omapfb:vram:2M,vram:4M\0" \
diff --git a/include/configs/omap3_zoom2.h b/include/configs/omap3_zoom2.h
index 2b07666..7a8beb8 100644
--- a/include/configs/omap3_zoom2.h
+++ b/include/configs/omap3_zoom2.h
@@ -125,6 +125,20 @@
 #define CONFIG_OMAP3_GPIO_3 /* board revision */
 #define CONFIG_OMAP3_GPIO_5 /* debug board detection, ZOOM2_LED_BLUE */
 
+/* USB */
+#define CONFIG_MUSB_UDC			1
+#define CONFIG_USB_OMAP3		1
+#define CONFIG_TWL4030_USB		1
+
+/* USB device configuration */
+#define CONFIG_USB_DEVICE		1
+#define CONFIG_USB_TTY			1
+/* Change these to suit your needs */
+#define CONFIG_USBD_VENDORID		0x0451
+#define CONFIG_USBD_PRODUCTID		0x5678
+#define CONFIG_USBD_MANUFACTURER	"Texas Instruments"
+#define CONFIG_USBD_PRODUCT_NAME	"Zoom2"
+
 /* commands to include */
 #include <config_cmd_default.h>
 
@@ -170,6 +184,9 @@
 /* Environment information */
 #define CONFIG_BOOTDELAY		10
 
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"usbtty=cdc_acm\0" \
+
 /*
  * Miscellaneous configurable options
  */
diff --git a/include/configs/omap5912osk.h b/include/configs/omap5912osk.h
index d0ce9dc..bc660e3 100644
--- a/include/configs/omap5912osk.h
+++ b/include/configs/omap5912osk.h
@@ -61,7 +61,8 @@
  */
 /*
 */
-#define CONFIG_DRIVER_LAN91C96
+#define CONFIG_NET_MULTI
+#define CONFIG_LAN91C96
 #define CONFIG_LAN91C96_BASE 0x04800300
 #define CONFIG_LAN91C96_EXT_PHY
 
diff --git a/include/configs/omap730p2.h b/include/configs/omap730p2.h
index 32a9b23..a6a8a02 100644
--- a/include/configs/omap730p2.h
+++ b/include/configs/omap730p2.h
@@ -65,7 +65,8 @@
  * Hardware drivers
  */
 
-#define CONFIG_DRIVER_LAN91C96
+#define CONFIG_NET_MULTI
+#define CONFIG_LAN91C96
 #define CONFIG_LAN91C96_BASE	   0x04000300
 #define CONFIG_LAN91C96_EXT_PHY
 
diff --git a/include/configs/pleb2.h b/include/configs/pleb2.h
index 635ef71..9e69411 100644
--- a/include/configs/pleb2.h
+++ b/include/configs/pleb2.h
@@ -56,8 +56,10 @@
  */
 
 /* None - PLEB 2 doesn't have any of this.
-   #define CONFIG_DRIVER_LAN91C96
-   #define CONFIG_LAN91C96_BASE 0x0C000000 */
+	#define CONFIG_NET_MULTI
+	#define CONFIG_LAN91C96
+	#define CONFIG_LAN91C96_BASE 0x0C000000
+ */
 
 /*
  * select serial console configuration
diff --git a/include/netdev.h b/include/netdev.h
index a91368e..a9d5ec9 100644
--- a/include/netdev.h
+++ b/include/netdev.h
@@ -57,6 +57,7 @@
 void gt6426x_eth_initialize(bd_t *bis);
 int inca_switch_initialize(bd_t *bis);
 int kirkwood_egiga_initialize(bd_t *bis);
+int lan91c96_initialize(u8 dev_num, int base_addr);
 int macb_eth_initialize(int id, void *regs, unsigned int phy_addr);
 int mcdmafec_initialize(bd_t *bis);
 int mcffec_initialize(bd_t *bis);
diff --git a/include/pci_ids.h b/include/pci_ids.h
index d783c5b..edfdc1e 100644
--- a/include/pci_ids.h
+++ b/include/pci_ids.h
@@ -1828,6 +1828,7 @@
 #define PCI_DEVICE_ID_INTEL_82546EB_COPPER	0x1010
 #define PCI_DEVICE_ID_INTEL_82545EM_FIBER	0x1011
 #define PCI_DEVICE_ID_INTEL_82546EB_FIBER	0x1012
+#define PCI_DEVICE_ID_INTEL_82546GB_COPPER	0x1079
 #define PCI_DEVICE_ID_INTEL_82540EM_LOM		0x1015
 #define PCI_DEVICE_ID_INTEL_82545GM_COPPER	0x1026
 #define PCI_DEVICE_ID_INTEL_82559		0x1030
diff --git a/include/serial.h b/include/serial.h
index bbda3f0..f2638ec 100644
--- a/include/serial.h
+++ b/include/serial.h
@@ -66,4 +66,22 @@
 extern int serial_assign(char * name);
 extern void serial_reinit_all(void);
 
+/* For usbtty */
+#ifdef CONFIG_USB_TTY
+
+extern int usbtty_getc(void);
+extern void usbtty_putc(const char c);
+extern void usbtty_puts(const char *str);
+extern int usbtty_tstc(void);
+
+#else
+
+/* stubs */
+#define usbtty_getc() 0
+#define usbtty_putc(a)
+#define usbtty_puts(a)
+#define usbtty_tstc() 0
+
+#endif /* CONFIG_USB_TTY */
+
 #endif
diff --git a/include/twl4030.h b/include/twl4030.h
index f260ecb..feaec47 100644
--- a/include/twl4030.h
+++ b/include/twl4030.h
@@ -342,21 +342,129 @@
 #define TWL4030_KEYPAD_CTRL_SOFT_NRST			(1 << 0)
 
 /* USB */
-#define TWL4030_USB_FUNC_CTRL				(0x04)
-#define TWL4030_USB_OPMODE_MASK				(3 << 3)
-#define TWL4030_USB_XCVRSELECT_MASK			(3 << 0)
-#define TWL4030_USB_IFC_CTRL				(0x07)
-#define TWL4030_USB_CARKITMODE				(1 << 2)
-#define TWL4030_USB_POWER_CTRL				(0xAC)
-#define TWL4030_USB_OTG_ENAB				(1 << 5)
-#define TWL4030_USB_PHY_PWR_CTRL			(0xFD)
-#define TWL4030_USB_PHYPWD				(1 << 0)
-#define TWL4030_USB_PHY_CLK_CTRL			(0xFE)
-#define TWL4030_USB_CLOCKGATING_EN			(1 << 2)
-#define TWL4030_USB_CLK32K_EN				(1 << 1)
-#define TWL4030_USB_REQ_PHY_DPLL_CLK			(1 << 0)
-#define TWL4030_USB_PHY_CLK_CTRL_STS			(0xFF)
-#define TWL4030_USB_PHY_DPLL_CLK			(1 << 0)
+#define TWL4030_USB_VENDOR_ID_LO			0x00
+#define TWL4030_USB_VENDOR_ID_HI			0x01
+#define TWL4030_USB_PRODUCT_ID_LO			0x02
+#define TWL4030_USB_PRODUCT_ID_HI			0x03
+#define TWL4030_USB_FUNC_CTRL				0x04
+#define TWL4030_USB_FUNC_CTRL_SET			0x05
+#define TWL4030_USB_FUNC_CTRL_CLR			0x06
+#define TWL4030_USB_IFC_CTRL				0x07
+#define TWL4030_USB_IFC_CTRL_SET			0x08
+#define TWL4030_USB_IFC_CTRL_CLR			0x09
+#define TWL4030_USB_OTG_CTRL				0x0A
+#define TWL4030_USB_OTG_CTRL_SET			0x0B
+#define TWL4030_USB_OTG_CTRL_CLR			0x0C
+#define TWL4030_USB_USB_INT_EN_RISE			0x0D
+#define TWL4030_USB_USB_INT_EN_RISE_SET			0x0E
+#define TWL4030_USB_USB_INT_EN_RISE_CLR			0x0F
+#define TWL4030_USB_USB_INT_EN_FALL			0x10
+#define TWL4030_USB_USB_INT_EN_FALL_SET			0x11
+#define TWL4030_USB_USB_INT_EN_FALL_CLR			0x12
+#define TWL4030_USB_USB_INT_STS				0x13
+#define TWL4030_USB_USB_INT_LATCH			0x14
+#define TWL4030_USB_DEBUG				0x15
+#define TWL4030_USB_SCRATCH_REG				0x16
+#define TWL4030_USB_SCRATCH_REG_SET			0x17
+#define TWL4030_USB_SCRATCH_REG_CLR			0x18
+#define TWL4030_USB_CARKIT_CTRL				0x19
+#define TWL4030_USB_CARKIT_CTRL_SET			0x1A
+#define TWL4030_USB_CARKIT_CTRL_CLR			0x1B
+#define TWL4030_USB_CARKIT_INT_DELAY			0x1C
+#define TWL4030_USB_CARKIT_INT_EN			0x1D
+#define TWL4030_USB_CARKIT_INT_EN_SET			0x1E
+#define TWL4030_USB_CARKIT_INT_EN_CLR			0x1F
+#define TWL4030_USB_CARKIT_INT_STS			0x20
+#define TWL4030_USB_CARKIT_INT_LATCH			0x21
+#define TWL4030_USB_CARKIT_PLS_CTRL			0x22
+#define TWL4030_USB_CARKIT_PLS_CTRL_SET			0x23
+#define TWL4030_USB_CARKIT_PLS_CTRL_CLR			0x24
+#define TWL4030_USB_TRANS_POS_WIDTH			0x25
+#define TWL4030_USB_TRANS_NEG_WIDTH			0x26
+#define TWL4030_USB_RCV_PLTY_RECOVERY			0x27
+#define TWL4030_USB_MCPC_CTRL				0x30
+#define TWL4030_USB_MCPC_CTRL_SET			0x31
+#define TWL4030_USB_MCPC_CTRL_CLR			0x32
+#define TWL4030_USB_MCPC_IO_CTRL			0x33
+#define TWL4030_USB_MCPC_IO_CTRL_SET			0x34
+#define TWL4030_USB_MCPC_IO_CTRL_CLR			0x35
+#define TWL4030_USB_MCPC_CTRL2				0x36
+#define TWL4030_USB_MCPC_CTRL2_SET			0x37
+#define TWL4030_USB_MCPC_CTRL2_CLR			0x38
+#define TWL4030_USB_OTHER_FUNC_CTRL			0x80
+#define TWL4030_USB_OTHER_FUNC_CTRL_SET			0x81
+#define TWL4030_USB_OTHER_FUNC_CTRL_CLR			0x82
+#define TWL4030_USB_OTHER_IFC_CTRL			0x83
+#define TWL4030_USB_OTHER_IFC_CTRL_SET			0x84
+#define TWL4030_USB_OTHER_IFC_CTRL_CLR			0x85
+#define TWL4030_USB_OTHER_INT_EN_RISE_SET		0x87
+#define TWL4030_USB_OTHER_INT_EN_RISE_CLR		0x88
+#define TWL4030_USB_OTHER_INT_EN_FALL			0x89
+#define TWL4030_USB_OTHER_INT_EN_FALL_SET		0x8A
+#define TWL4030_USB_OTHER_INT_EN_FALL_CLR		0x8B
+#define TWL4030_USB_OTHER_INT_STS			0x8C
+#define TWL4030_USB_OTHER_INT_LATCH			0x8D
+#define TWL4030_USB_ID_STATUS				0x96
+#define TWL4030_USB_CARKIT_SM_1_INT_EN			0x97
+#define TWL4030_USB_CARKIT_SM_1_INT_EN_SET		0x98
+#define TWL4030_USB_CARKIT_SM_1_INT_EN_CLR		0x99
+#define TWL4030_USB_CARKIT_SM_1_INT_STS			0x9A
+#define TWL4030_USB_CARKIT_SM_1_INT_LATCH		0x9B
+#define TWL4030_USB_CARKIT_SM_2_INT_EN			0x9C
+#define TWL4030_USB_CARKIT_SM_2_INT_EN_SET		0x9D
+#define TWL4030_USB_CARKIT_SM_2_INT_EN_CLR		0x9E
+#define TWL4030_USB_CARKIT_SM_2_INT_STS			0x9F
+#define TWL4030_USB_CARKIT_SM_2_INT_LATCH		0xA0
+#define TWL4030_USB_CARKIT_SM_CTRL			0xA1
+#define TWL4030_USB_CARKIT_SM_CTRL_SET			0xA2
+#define TWL4030_USB_CARKIT_SM_CTRL_CLR			0xA3
+#define TWL4030_USB_CARKIT_SM_CMD			0xA4
+#define TWL4030_USB_CARKIT_SM_CMD_SET			0xA5
+#define TWL4030_USB_CARKIT_SM_CMD_CLR			0xA6
+#define TWL4030_USB_CARKIT_SM_CMD_STS			0xA7
+#define TWL4030_USB_CARKIT_SM_STATUS			0xA8
+#define TWL4030_USB_CARKIT_SM_ERR_STATUS		0xAA
+#define TWL4030_USB_CARKIT_SM_CTRL_STATE		0xAB
+#define TWL4030_USB_POWER_CTRL				0xAC
+#define TWL4030_USB_POWER_CTRL_SET			0xAD
+#define TWL4030_USB_POWER_CTRL_CLR			0xAE
+#define TWL4030_USB_OTHER_IFC_CTRL2			0xAF
+#define TWL4030_USB_OTHER_IFC_CTRL2_SET			0xB0
+#define TWL4030_USB_OTHER_IFC_CTRL2_CLR			0xB1
+#define TWL4030_USB_REG_CTRL_EN				0xB2
+#define TWL4030_USB_REG_CTRL_EN_SET			0xB3
+#define TWL4030_USB_REG_CTRL_EN_CLR			0xB4
+#define TWL4030_USB_REG_CTRL_ERROR			0xB5
+#define TWL4030_USB_OTHER_FUNC_CTRL2			0xB8
+#define TWL4030_USB_OTHER_FUNC_CTRL2_SET		0xB9
+#define TWL4030_USB_OTHER_FUNC_CTRL2_CLR		0xBA
+#define TWL4030_USB_CARKIT_ANA_CTRL			0xBB
+#define TWL4030_USB_CARKIT_ANA_CTRL_SET			0xBC
+#define TWL4030_USB_CARKIT_ANA_CTRL_CLR			0xBD
+#define TWL4030_USB_VBUS_DEBOUNCE			0xC0
+#define TWL4030_USB_ID_DEBOUNCE				0xC1
+#define TWL4030_USB_TPH_DP_CON_MIN			0xC2
+#define TWL4030_USB_TPH_DP_CON_MAX			0xC3
+#define TWL4030_USB_TCR_DP_CON_MIN			0xC4
+#define TWL4030_USB_TCR_DP_CON_MAX			0xC5
+#define TWL4030_USB_TPH_DP_PD_SHORT			0xC6
+#define TWL4030_USB_TPH_CMD_DLY				0xC7
+#define TWL4030_USB_TPH_DET_RST				0xC8
+#define TWL4030_USB_TPH_AUD_BIAS			0xC9
+#define TWL4030_USB_TCR_UART_DET_MIN			0xCA
+#define TWL4030_USB_TCR_UART_DET_MAX			0xCB
+#define TWL4030_USB_TPH_ID_INT_PW			0xCD
+#define TWL4030_USB_TACC_ID_INT_WAIT			0xCE
+#define TWL4030_USB_TACC_ID_INT_PW			0xCF
+#define TWL4030_USB_TPH_CMD_WAIT			0xD0
+#define TWL4030_USB_TPH_ACK_WAIT			0xD1
+#define TWL4030_USB_TPH_DP_DISC_DET			0xD2
+#define TWL4030_USB_VBAT_TIMER				0xD3
+#define TWL4030_USB_CARKIT_4W_DEBUG			0xE0
+#define TWL4030_USB_CARKIT_5W_DEBUG			0xE1
+#define TWL4030_USB_PHY_PWR_CTRL			0xFD
+#define TWL4030_USB_PHY_CLK_CTRL			0xFE
+#define TWL4030_USB_PHY_CLK_CTRL_STS			0xFF
 
 /*
  * Convience functions to read and write from TWL4030
@@ -398,4 +506,9 @@
  */
 void twl4030_led_init(void);
 
+/*
+ * USB
+ */
+int twl4030_usb_ulpi_init(void);
+
 #endif /* TWL4030_H */
diff --git a/include/usb.h b/include/usb.h
index 7c47098..1cc3e42 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -27,6 +27,7 @@
 #define _USB_H_
 
 #include <usb_defs.h>
+#include <usbdescriptors.h>
 
 /* Everything is aribtrary */
 #define USB_ALTSETTINGALLOC		4
@@ -41,13 +42,6 @@
 
 #define USB_CNTL_TIMEOUT 100 /* 100ms timeout */
 
-/* String descriptor */
-struct usb_string_descriptor {
-	unsigned char	bLength;
-	unsigned char	bDescriptorType;
-	unsigned short	wData[1];
-} __attribute__ ((packed));
-
 /* device request (setup) */
 struct devrequest {
 	unsigned char	requesttype;
@@ -61,49 +55,11 @@
 struct usb_descriptor_header {
 	unsigned char	bLength;
 	unsigned char	bDescriptorType;
-} __attribute__ ((packed));
-
-/* Device descriptor */
-struct usb_device_descriptor {
-	unsigned char	bLength;
-	unsigned char	bDescriptorType;
-	unsigned short	bcdUSB;
-	unsigned char	bDeviceClass;
-	unsigned char	bDeviceSubClass;
-	unsigned char	bDeviceProtocol;
-	unsigned char	bMaxPacketSize0;
-	unsigned short	idVendor;
-	unsigned short	idProduct;
-	unsigned short	bcdDevice;
-	unsigned char	iManufacturer;
-	unsigned char	iProduct;
-	unsigned char	iSerialNumber;
-	unsigned char	bNumConfigurations;
 } __attribute__ ((packed));
 
-/* Endpoint descriptor */
-struct usb_endpoint_descriptor {
-	unsigned char	bLength;
-	unsigned char	bDescriptorType;
-	unsigned char	bEndpointAddress;
-	unsigned char	bmAttributes;
-	unsigned short	wMaxPacketSize;
-	unsigned char	bInterval;
-	unsigned char	bRefresh;
-	unsigned char	bSynchAddress;
-} __attribute__ ((packed)) __attribute__ ((aligned(2)));
-
-/* Interface descriptor */
-struct usb_interface_descriptor {
-	unsigned char	bLength;
-	unsigned char	bDescriptorType;
-	unsigned char	bInterfaceNumber;
-	unsigned char	bAlternateSetting;
-	unsigned char	bNumEndpoints;
-	unsigned char	bInterfaceClass;
-	unsigned char	bInterfaceSubClass;
-	unsigned char	bInterfaceProtocol;
-	unsigned char	iInterface;
+/* Interface */
+struct usb_interface {
+	struct usb_interface_descriptor desc;
 
 	unsigned char	no_of_ep;
 	unsigned char	num_altsetting;
@@ -112,20 +68,12 @@
 	struct usb_endpoint_descriptor ep_desc[USB_MAXENDPOINTS];
 } __attribute__ ((packed));
 
-
-/* Configuration descriptor information.. */
-struct usb_config_descriptor {
-	unsigned char	bLength;
-	unsigned char	bDescriptorType;
-	unsigned short	wTotalLength;
-	unsigned char	bNumInterfaces;
-	unsigned char	bConfigurationValue;
-	unsigned char	iConfiguration;
-	unsigned char	bmAttributes;
-	unsigned char	MaxPower;
+/* Configuration information.. */
+struct usb_config {
+	struct usb_configuration_descriptor desc;
 
 	unsigned char	no_of_if;	/* number of interfaces */
-	struct usb_interface_descriptor if_desc[USB_MAXINTERFACES];
+	struct usb_interface if_desc[USB_MAXINTERFACES];
 } __attribute__ ((packed));
 
 enum {
@@ -156,7 +104,7 @@
 
 	int configno;			/* selected config number */
 	struct usb_device_descriptor descriptor; /* Device Descriptor */
-	struct usb_config_descriptor config; /* config descriptor */
+	struct usb_config config; /* config descriptor */
 
 	int have_langid;		/* whether string_langid is valid yet */
 	int string_langid;		/* language ID for strings */
@@ -183,7 +131,8 @@
 #if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || \
 	defined(CONFIG_USB_EHCI) || defined(CONFIG_USB_OHCI_NEW) || \
 	defined(CONFIG_USB_SL811HS) || defined(CONFIG_USB_ISP116X_HCD) || \
-	defined(CONFIG_USB_R8A66597_HCD) || defined(CONFIG_USB_DAVINCI)
+	defined(CONFIG_USB_R8A66597_HCD) || defined(CONFIG_USB_DAVINCI) || \
+	defined(CONFIG_USB_OMAP3)
 
 int usb_lowlevel_init(void);
 int usb_lowlevel_stop(void);
diff --git a/include/usb/musb_udc.h b/include/usb/musb_udc.h
new file mode 100644
index 0000000..ef37dbb
--- /dev/null
+++ b/include/usb/musb_udc.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2009 Wind River Systems, Inc.
+ * Tom Rix <Tom.Rix@windriver.com>
+ *
+ * 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
+ */
+#ifndef __MUSB_UDC_H__
+#define __MUSB_UDC_H__
+
+#include <usbdevice.h>
+
+/* UDC level routines */
+void udc_irq(void);
+void udc_set_nak(int ep_num);
+void udc_unset_nak(int ep_num);
+int udc_endpoint_write(struct usb_endpoint_instance *endpoint);
+void udc_setup_ep(struct usb_device_instance *device, unsigned int id,
+		  struct usb_endpoint_instance *endpoint);
+void udc_connect(void);
+void udc_disconnect(void);
+void udc_enable(struct usb_device_instance *device);
+void udc_disable(void);
+void udc_startup_events(struct usb_device_instance *device);
+int udc_init(void);
+
+/* usbtty */
+#ifdef CONFIG_USB_TTY
+
+#define EP0_MAX_PACKET_SIZE	64 /* MUSB_EP0_FIFOSIZE */
+#define UDC_INT_ENDPOINT	1
+#define UDC_INT_PACKET_SIZE	64
+#define UDC_OUT_ENDPOINT	2
+#define UDC_OUT_PACKET_SIZE	64
+#define UDC_IN_ENDPOINT		3
+#define UDC_IN_PACKET_SIZE	64
+#define UDC_BULK_PACKET_SIZE	64
+
+#endif /* CONFIG_USB_TTY */
+
+#endif /* __MUSB_UDC_H__ */
+
diff --git a/include/usbdescriptors.h b/include/usbdescriptors.h
index a752097..2dec3b9 100644
--- a/include/usbdescriptors.h
+++ b/include/usbdescriptors.h
@@ -504,4 +504,30 @@
 
 } __attribute__ ((packed));
 
+#ifdef DEBUG
+static inline void print_device_descriptor(struct usb_device_descriptor *d)
+{
+	serial_printf("usb device descriptor \n");
+	serial_printf("\tbLength %2.2x\n", d->bLength);
+	serial_printf("\tbDescriptorType %2.2x\n", d->bDescriptorType);
+	serial_printf("\tbcdUSB %4.4x\n", d->bcdUSB);
+	serial_printf("\tbDeviceClass %2.2x\n", d->bDeviceClass);
+	serial_printf("\tbDeviceSubClass %2.2x\n", d->bDeviceSubClass);
+	serial_printf("\tbDeviceProtocol %2.2x\n", d->bDeviceProtocol);
+	serial_printf("\tbMaxPacketSize0 %2.2x\n", d->bMaxPacketSize0);
+	serial_printf("\tidVendor %4.4x\n", d->idVendor);
+	serial_printf("\tidProduct %4.4x\n", d->idProduct);
+	serial_printf("\tbcdDevice %4.4x\n", d->bcdDevice);
+	serial_printf("\tiManufacturer %2.2x\n", d->iManufacturer);
+	serial_printf("\tiProduct %2.2x\n", d->iProduct);
+	serial_printf("\tiSerialNumber %2.2x\n", d->iSerialNumber);
+	serial_printf("\tbNumConfigurations %2.2x\n", d->bNumConfigurations);
+}
+
+#else
+
+/* stubs */
+#define print_device_descriptor(d)
+
+#endif /* DEBUG */
 #endif
diff --git a/include/usbdevice.h b/include/usbdevice.h
index 206dbbc..4171636 100644
--- a/include/usbdevice.h
+++ b/include/usbdevice.h
@@ -663,4 +663,107 @@
 void usbd_rcv_complete(struct usb_endpoint_instance *endpoint, int len, int urb_bad);
 void usbd_tx_complete (struct usb_endpoint_instance *endpoint);
 
+/* These are macros used in debugging */
+#ifdef DEBUG
+static inline void print_urb(struct urb *u)
+{
+	serial_printf("urb %p\n", (u));
+	serial_printf("\tendpoint %p\n", u->endpoint);
+	serial_printf("\tdevice %p\n", u->device);
+	serial_printf("\tbuffer %p\n", u->buffer);
+	serial_printf("\tbuffer_length %d\n", u->buffer_length);
+	serial_printf("\tactual_length %d\n", u->actual_length);
+	serial_printf("\tstatus %d\n", u->status);
+	serial_printf("\tdata %d\n", u->data);
+}
+
+static inline void print_usb_device_request(struct usb_device_request *r)
+{
+	serial_printf("usb request\n");
+	serial_printf("\tbmRequestType 0x%2.2x\n", r->bmRequestType);
+	if ((r->bmRequestType & USB_REQ_DIRECTION_MASK) == 0)
+		serial_printf("\t\tDirection : To device\n");
+	else
+		serial_printf("\t\tDirection : To host\n");
+	if ((r->bmRequestType & USB_TYPE_STANDARD) == USB_TYPE_STANDARD)
+		serial_printf("\t\tType      : Standard\n");
+	if ((r->bmRequestType & USB_TYPE_CLASS) == USB_TYPE_CLASS)
+		serial_printf("\t\tType      : Standard\n");
+	if ((r->bmRequestType & USB_TYPE_VENDOR) == USB_TYPE_VENDOR)
+		serial_printf("\t\tType      : Standard\n");
+	if ((r->bmRequestType & USB_TYPE_RESERVED) == USB_TYPE_RESERVED)
+		serial_printf("\t\tType      : Standard\n");
+	if ((r->bmRequestType & USB_REQ_RECIPIENT_MASK) ==
+	    USB_REQ_RECIPIENT_DEVICE)
+		serial_printf("\t\tRecipient : Device\n");
+	if ((r->bmRequestType & USB_REQ_RECIPIENT_MASK) ==
+	    USB_REQ_RECIPIENT_INTERFACE)
+		serial_printf("\t\tRecipient : Interface\n");
+	if ((r->bmRequestType & USB_REQ_RECIPIENT_MASK) ==
+	    USB_REQ_RECIPIENT_ENDPOINT)
+		serial_printf("\t\tRecipient : Endpoint\n");
+	if ((r->bmRequestType & USB_REQ_RECIPIENT_MASK) ==
+	    USB_REQ_RECIPIENT_OTHER)
+		serial_printf("\t\tRecipient : Other\n");
+	serial_printf("\tbRequest      0x%2.2x\n", r->bRequest);
+	if (r->bRequest == USB_REQ_GET_STATUS)
+		serial_printf("\t\tGET_STATUS\n");
+	else if (r->bRequest == USB_REQ_SET_ADDRESS)
+		serial_printf("\t\tSET_ADDRESS\n");
+	else if (r->bRequest == USB_REQ_SET_FEATURE)
+		serial_printf("\t\tSET_FEATURE\n");
+	else if (r->bRequest == USB_REQ_GET_DESCRIPTOR)
+		serial_printf("\t\tGET_DESCRIPTOR\n");
+	else if (r->bRequest == USB_REQ_SET_CONFIGURATION)
+		serial_printf("\t\tSET_CONFIGURATION\n");
+	else if (r->bRequest == USB_REQ_SET_INTERFACE)
+		serial_printf("\t\tUSB_REQ_SET_INTERFACE\n");
+	else
+		serial_printf("\tUNKNOWN %d\n", r->bRequest);
+	serial_printf("\twValue        0x%4.4x\n", r->wValue);
+	if (r->bRequest == USB_REQ_GET_DESCRIPTOR) {
+		switch (r->wValue >> 8) {
+		case USB_DESCRIPTOR_TYPE_DEVICE:
+			serial_printf("\tDEVICE\n");
+			break;
+		case USB_DESCRIPTOR_TYPE_CONFIGURATION:
+			serial_printf("\tCONFIGURATION\n");
+			break;
+		case USB_DESCRIPTOR_TYPE_STRING:
+			serial_printf("\tSTRING\n");
+			break;
+		case USB_DESCRIPTOR_TYPE_INTERFACE:
+			serial_printf("\tINTERFACE\n");
+			break;
+		case USB_DESCRIPTOR_TYPE_ENDPOINT:
+			serial_printf("\tENDPOINT\n");
+			break;
+		case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER:
+			serial_printf("\tDEVICE_QUALIFIER\n");
+			break;
+		case USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION:
+			serial_printf("\tOTHER_SPEED_CONFIGURATION\n");
+			break;
+		case USB_DESCRIPTOR_TYPE_INTERFACE_POWER:
+			serial_printf("\tINTERFACE_POWER\n");
+			break;
+		case USB_DESCRIPTOR_TYPE_HID:
+			serial_printf("\tHID\n");
+			break;
+		case USB_DESCRIPTOR_TYPE_REPORT:
+			serial_printf("\tREPORT\n");
+			break;
+		default:
+			serial_printf("\tUNKNOWN TYPE\n");
+			break;
+		}
+	}
+	serial_printf("\twIndex        0x%4.4x\n", r->wIndex);
+	serial_printf("\twLength       0x%4.4x\n", r->wLength);
+}
+#else
+/* stubs */
+#define print_urb(u)
+#define print_usb_device_request(r)
+#endif /* DEBUG */
 #endif
diff --git a/lib_generic/gunzip.c b/lib_generic/gunzip.c
index d59a448..d2b7ad4 100644
--- a/lib_generic/gunzip.c
+++ b/lib_generic/gunzip.c
@@ -36,11 +36,8 @@
 #define RESERVED		0xe0
 #define DEFLATED		8
 
-int gunzip(void *, int, unsigned char *, unsigned long *);
 void *zalloc(void *, unsigned, unsigned);
 void zfree(void *, void *, unsigned);
-int zunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp,
-						int stoponerr, int offset);
 
 void *zalloc(void *x, unsigned items, unsigned size)
 {
diff --git a/net/Makefile b/net/Makefile
index ff87d87..4f819dd 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -27,14 +27,14 @@
 
 LIB	= $(obj)libnet.a
 
-COBJS-y += bootp.o
+COBJS-$(CONFIG_CMD_NET)  += bootp.o
 COBJS-$(CONFIG_CMD_DNS)  += dns.o
-COBJS-y += eth.o
-COBJS-y += net.o
-COBJS-y += nfs.o
-COBJS-y += rarp.o
+COBJS-$(CONFIG_CMD_NET)  += eth.o
+COBJS-$(CONFIG_CMD_NET)  += net.o
+COBJS-$(CONFIG_CMD_NFS)  += nfs.o
+COBJS-$(CONFIG_CMD_NET)  += rarp.o
 COBJS-$(CONFIG_CMD_SNTP) += sntp.o
-COBJS-y += tftp.o
+COBJS-$(CONFIG_CMD_NET)  += tftp.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/net/bootp.c b/net/bootp.c
index 3093852..e679f8b 100644
--- a/net/bootp.c
+++ b/net/bootp.c
@@ -20,8 +20,6 @@
 
 #define BOOTP_VENDOR_MAGIC	0x63825363	/* RFC1048 Magic Cookie		*/
 
-#if defined(CONFIG_CMD_NET)
-
 #define TIMEOUT		5000UL	/* Milliseconds before trying BOOTP again */
 #ifndef CONFIG_NET_RETRY_COUNT
 # define TIMEOUT_COUNT	5		/* # of timeouts before giving up  */
@@ -948,5 +946,3 @@
 	BootpRequest();
 }
 #endif	/* CONFIG_CMD_DHCP */
-
-#endif	/* CONFIG_CMD_NET */
diff --git a/net/eth.c b/net/eth.c
index 9b50312..b650a20 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -26,7 +26,6 @@
 #include <net.h>
 #include <miiphy.h>
 
-#ifdef CONFIG_CMD_NET
 void eth_parse_enetaddr(const char *addr, uchar *enetaddr)
 {
 	char *end;
@@ -60,9 +59,8 @@
 	sprintf(enetvar, index ? "eth%daddr" : "ethaddr", index);
 	return eth_getenv_enetaddr(enetvar, enetaddr);
 }
-#endif
 
-#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI)
+#ifdef CONFIG_NET_MULTI
 
 /*
  * CPU and board-specific Ethernet initializations.  Aliased function
@@ -492,7 +490,8 @@
 {
 	return (eth_current ? eth_current->name : "unknown");
 }
-#elif defined(CONFIG_CMD_NET) && !defined(CONFIG_NET_MULTI)
+
+#else /* !CONFIG_NET_MULTI */
 
 #warning Ethernet driver is deprecated.  Please update to use CONFIG_NET_MULTI
 
diff --git a/net/net.c b/net/net.c
index fd13cd9..595abd9 100644
--- a/net/net.c
+++ b/net/net.c
@@ -96,8 +96,6 @@
 #include "dns.h"
 #endif
 
-#if defined(CONFIG_CMD_NET)
-
 DECLARE_GLOBAL_DATA_PTR;
 
 #ifndef	CONFIG_ARP_TIMEOUT
@@ -1872,8 +1870,6 @@
 	*dst = '\0';
 }
 
-#endif
-
 #if defined(CONFIG_CMD_NFS) || defined(CONFIG_CMD_SNTP) || defined(CONFIG_CMD_DNS)
 /*
  * make port a little random, but use something trivial to compute
diff --git a/net/nfs.c b/net/nfs.c
index 4017c3e..d11bb4c 100644
--- a/net/nfs.c
+++ b/net/nfs.c
@@ -29,8 +29,6 @@
 #include "nfs.h"
 #include "bootp.h"
 
-#if defined(CONFIG_CMD_NET) && defined(CONFIG_CMD_NFS)
-
 #define HASHES_PER_LINE 65	/* Number of "loading" hashes per line	*/
 #define NFS_RETRY_COUNT 30
 #define NFS_TIMEOUT 2000UL
@@ -755,5 +753,3 @@
 
 	NfsSend ();
 }
-
-#endif
diff --git a/net/rarp.c b/net/rarp.c
index d37981b..9444c03 100644
--- a/net/rarp.c
+++ b/net/rarp.c
@@ -29,8 +29,6 @@
 #include "rarp.h"
 #include "tftp.h"
 
-#if defined(CONFIG_CMD_NET)
-
 #define TIMEOUT		5000UL	/* Milliseconds before trying BOOTP again */
 #ifndef	CONFIG_NET_RETRY_COUNT
 # define TIMEOUT_COUNT	5		/* # of timeouts before giving up  */
@@ -116,5 +114,3 @@
 	NetSetTimeout(TIMEOUT, RarpTimeout);
 	NetSetHandler(RarpHandler);
 }
-
-#endif
diff --git a/net/tftp.c b/net/tftp.c
index cc60a3b..a02463b 100644
--- a/net/tftp.c
+++ b/net/tftp.c
@@ -10,8 +10,6 @@
 #include "tftp.h"
 #include "bootp.h"
 
-#if defined(CONFIG_CMD_NET)
-
 #define WELL_KNOWN_PORT	69		/* Well known TFTP port #		*/
 #define TIMEOUT		5000UL		/* Millisecs to timeout for lost pkt */
 #ifndef	CONFIG_NET_RETRY_COUNT
@@ -47,6 +45,16 @@
 ulong TftpRRQTimeoutMSecs = TIMEOUT;
 int TftpRRQTimeoutCountMax = TIMEOUT_COUNT;
 
+enum {
+	TFTP_ERR_UNDEFINED           = 0,
+	TFTP_ERR_FILE_NOT_FOUND      = 1,
+	TFTP_ERR_ACCESS_DENIED       = 2,
+	TFTP_ERR_DISK_FULL           = 3,
+	TFTP_ERR_UNEXPECTED_OPCODE   = 4,
+	TFTP_ERR_UNKNOWN_TRANSFER_ID  = 5,
+	TFTP_ERR_FILE_ALREADY_EXISTS = 6,
+};
+
 static IPaddr_t TftpServerIP;
 static int	TftpServerPort;		/* The UDP port at their end		*/
 static int	TftpOurPort;		/* The UDP port at our end		*/
@@ -472,11 +480,27 @@
 	case TFTP_ERROR:
 		printf ("\nTFTP error: '%s' (%d)\n",
 					pkt + 2, ntohs(*(ushort *)pkt));
-		puts ("Starting again\n\n");
+
+		switch (ntohs(*(ushort *)pkt)) {
+		case TFTP_ERR_FILE_NOT_FOUND:
+		case TFTP_ERR_ACCESS_DENIED:
+			puts("Not retrying...\n");
+			eth_halt();
+			NetState = NETLOOP_FAIL;
+			break;
+		case TFTP_ERR_UNDEFINED:
+		case TFTP_ERR_DISK_FULL:
+		case TFTP_ERR_UNEXPECTED_OPCODE:
+		case TFTP_ERR_UNKNOWN_TRANSFER_ID:
+		case TFTP_ERR_FILE_ALREADY_EXISTS:
+		default:
+			puts("Starting again\n\n");
 #ifdef CONFIG_MCAST_TFTP
-		mcast_cleanup();
+			mcast_cleanup();
 #endif
-		NetStartAgain ();
+			NetStartAgain();
+			break;
+		}
 		break;
 	}
 }
@@ -690,5 +714,3 @@
 }
 
 #endif /* Multicast TFTP */
-
-#endif