diff -ruN -xasm-m32r -xm32r linux-2.4.26.org/drivers/char/Config.in linux-2.4.26/drivers/char/Config.in
--- linux-2.4.26.org/drivers/char/Config.in	2004-02-18 22:36:31.000000000 +0900
+++ linux-2.4.26/drivers/char/Config.in	2004-03-22 10:56:06.000000000 +0900
@@ -12,7 +12,7 @@
    fi
 fi
 tristate 'Standard/generic (8250/16550 and compatible UARTs) serial support' CONFIG_SERIAL
-if [ "$CONFIG_SERIAL" = "y" ]; then
+if [ "$CONFIG_SERIAL" = "y" -o "$CONFIG_M32R_SERIAL" = "y" ]; then
    bool '  Support for console on serial port' CONFIG_SERIAL_CONSOLE
    if [ "$CONFIG_GSC_LASI" = "y" ]; then
       bool '   serial port on GSC support' CONFIG_SERIAL_GSC
diff -ruN -xasm-m32r -xm32r linux-2.4.26.org/drivers/char/serial.c linux-2.4.26/drivers/char/serial.c
--- linux-2.4.26.org/drivers/char/serial.c	2004-02-18 22:36:31.000000000 +0900
+++ linux-2.4.26/drivers/char/serial.c	2004-03-22 10:56:06.000000000 +0900
@@ -297,7 +297,11 @@
 	{ "unknown", 1, 0 }, 
 	{ "8250", 1, 0 }, 
 	{ "16450", 1, 0 }, 
+#ifndef CONFIG_PLAT_USRV
 	{ "16550", 1, 0 }, 
+#else	/* CONFIG_PLAT_USRV */
+	{ "16552D", 16, UART_CLEAR_FIFO | UART_USE_FIFO }, 
+#endif	/* CONFIG_PLAT_USRV */
 	{ "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO }, 
 	{ "cirrus", 1, 0 }, 	/* usurped by cyclades.c */
 	{ "ST16650", 1, UART_CLEAR_FIFO | UART_STARTECH }, 
@@ -3742,6 +3746,7 @@
 			state->type = PORT_16550A;
 			break;
 	}
+#ifndef CONFIG_PLAT_USRV
 	if (state->type == PORT_16550A) {
 		/* Check for Startech UART's */
 		serial_outp(info, UART_LCR, UART_LCR_DLAB);
@@ -3760,6 +3765,9 @@
 				autoconfig_startech_uarts(info, state, flags);
 		}
 	}
+#else	/* CONFIG_PLAT_USRV */
+	state->type = PORT_16550;
+#endif	/* CONFIG_PLAT_USRV */
 	if (state->type == PORT_16550A) {
 		/* Check for TI 16750 */
 		serial_outp(info, UART_LCR, save_lcr | UART_LCR_DLAB);
diff -ruN -xasm-m32r -xm32r linux-2.4.26.org/drivers/char/tty_io.c linux-2.4.26/drivers/char/tty_io.c
--- linux-2.4.26.org/drivers/char/tty_io.c	2004-04-14 22:05:29.000000000 +0900
+++ linux-2.4.26/drivers/char/tty_io.c	2004-04-28 19:34:38.000000000 +0900
@@ -2260,6 +2260,13 @@
  	mac_scc_console_init();
 #elif defined(CONFIG_PARISC)
 	pdc_console_init();
+#elif defined(CONFIG_M32R_USE_DBG_CONSOLE)
+	dbg_console_init();
+#if defined(CONFIG_PLAT_USRV) && !defined(CONFIG_SERIAL_MODULE)
+	serial_console_init();
+#endif
+#elif defined(CONFIG_M32R_PLD_SERIAL)
+	psio_console_init();
 #elif defined(CONFIG_SERIAL)
 	serial_console_init();
 #endif /* CONFIG_8xx */
diff -ruN -xasm-m32r -xm32r linux-2.4.26.org/drivers/input/keybdev.c linux-2.4.26/drivers/input/keybdev.c
--- linux-2.4.26.org/drivers/input/keybdev.c	2004-02-18 22:36:31.000000000 +0900
+++ linux-2.4.26/drivers/input/keybdev.c	2004-03-22 10:56:13.000000000 +0900
@@ -40,7 +40,7 @@
 #if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(__alpha__) || \
     defined(__mips__) || defined(CONFIG_SPARC64) || defined(CONFIG_SUPERH) || \
     defined(CONFIG_PPC) || defined(__mc68000__) || defined(__hppa__) || \
-    defined(__arm__)
+    defined(__arm__) || defined(__m32r__)
 
 static int x86_sysrq_alt = 0;
 #ifdef CONFIG_SPARC64
diff -ruN -xasm-m32r -xm32r linux-2.4.26.org/drivers/net/8390.c linux-2.4.26/drivers/net/8390.c
--- linux-2.4.26.org/drivers/net/8390.c	2003-11-29 03:26:20.000000000 +0900
+++ linux-2.4.26/drivers/net/8390.c	2004-03-22 10:56:15.000000000 +0900
@@ -221,6 +221,16 @@
 
 void ei_tx_timeout(struct net_device *dev)
 {
+#if defined(CONFIG_CHIP_M32700) && defined(CONFIG_SMP)
+	unsigned long flags, icucr;
+
+	printk(KERN_DEBUG "eth0 : timeout\n");
+	local_irq_save(flags);
+	icucr = inl(0x00eff200);
+	icucr |= 0x00000030;
+	outl(icucr, 0x00eff200);
+	local_irq_restore(flags);
+#else	/* not CONFIG_CHIP_M32700 || not CONFIG_SMP */
 	long e8390_base = dev->base_addr;
 	struct ei_device *ei_local = (struct ei_device *) dev->priv;
 	int txsr, isr, tickssofar = jiffies - dev->trans_start;
@@ -255,6 +265,7 @@
 	spin_unlock(&ei_local->page_lock);
 	enable_irq(dev->irq);
 	netif_wake_queue(dev);
+#endif	/* not CONFIG_CHIP_M32700 || not CONFIG_SMP */
 }
     
 /**
diff -ruN -xasm-m32r -xm32r linux-2.4.26.org/drivers/net/Makefile linux-2.4.26/drivers/net/Makefile
--- linux-2.4.26.org/drivers/net/Makefile	2004-04-14 22:05:30.000000000 +0900
+++ linux-2.4.26/drivers/net/Makefile	2004-04-28 10:36:54.000000000 +0900
@@ -142,6 +142,7 @@
 obj-$(CONFIG_WD80x3) += wd.o 8390.o
 obj-$(CONFIG_EL2) += 3c503.o 8390.o
 obj-$(CONFIG_NE2000) += ne.o 8390.o
+obj-$(CONFIG_MAPPI_NE2000) += 8390.o
 obj-$(CONFIG_NE2_MCA) += ne2.o 8390.o
 obj-$(CONFIG_HPLAN) += hp.o 8390.o
 obj-$(CONFIG_HPLAN_PLUS) += hp-plus.o 8390.o
diff -ruN -xasm-m32r -xm32r linux-2.4.26.org/drivers/net/Space.c linux-2.4.26/drivers/net/Space.c
--- linux-2.4.26.org/drivers/net/Space.c	2004-02-18 22:36:31.000000000 +0900
+++ linux-2.4.26/drivers/net/Space.c	2004-03-22 10:56:15.000000000 +0900
@@ -101,6 +101,12 @@
 extern int mac8390_probe(struct net_device *dev);
 extern int mac89x0_probe(struct net_device *dev);
 extern int mc32_probe(struct net_device *dev);
+#ifdef CONFIG_M32R_NE2000
+extern int mappi_ne_probe(struct net_device *dev);
+#endif /* CONFIG_MAPPI_NE2000 */
+#ifdef CONFIG_M32R_SMC91111
+extern int m32r_smc_init( struct net_device * );
+#endif /* CONFIG_M32R_SMC91111 */
   
 /* Detachable devices ("pocket adaptors") */
 extern int de600_probe(struct net_device *);
@@ -243,12 +249,18 @@
 #ifdef CONFIG_NE2000		/* ISA (use ne2k-pci for PCI cards) */
 	{ne_probe, 0},
 #endif
+#ifdef CONFIG_M32R_NE2000	/* ne2k for Mappi */
+	{mappi_ne_probe, 0},
+#endif
 #ifdef CONFIG_LANCE		/* ISA/VLB (use pcnet32 for PCI cards) */
 	{lance_probe, 0},
 #endif
 #ifdef CONFIG_SMC9194
 	{smc_init, 0},
 #endif
+#ifdef CONFIG_M32R_SMC91111	/* SMC91111 for M32R */
+	{m32r_smc_init, 0},
+#endif
 #ifdef CONFIG_SEEQ8005 
 	{seeq8005_probe, 0},
 #endif
diff -ruN -xasm-m32r -xm32r linux-2.4.26.org/drivers/net/wireless/hermes.h linux-2.4.26/drivers/net/wireless/hermes.h
--- linux-2.4.26.org/drivers/net/wireless/hermes.h	2003-08-25 20:44:42.000000000 +0900
+++ linux-2.4.26/drivers/net/wireless/hermes.h	2004-03-22 10:56:21.000000000 +0900
@@ -299,12 +299,21 @@
 } hermes_response_t;
 
 /* Register access convenience macros */
+#if defined(__m32r__)
+#define hermes_read_reg(hw, off) ((hw)->io_space ? \
+	le16_to_cpu(inw((hw)->iobase + ( (off) << (hw)->reg_spacing ))) : \
+	readw((hw)->iobase + ( (off) << (hw)->reg_spacing )))
+#define hermes_write_reg(hw, off, val) ((hw)->io_space ? \
+	outw_p(cpu_to_le16((val)), (hw)->iobase + ( (off) << (hw)->reg_spacing )) : \
+	writew((val), (hw)->iobase + ( (off) << (hw)->reg_spacing )))
+#else
 #define hermes_read_reg(hw, off) ((hw)->io_space ? \
 	inw((hw)->iobase + ( (off) << (hw)->reg_spacing )) : \
 	readw((hw)->iobase + ( (off) << (hw)->reg_spacing )))
 #define hermes_write_reg(hw, off, val) ((hw)->io_space ? \
 	outw_p((val), (hw)->iobase + ( (off) << (hw)->reg_spacing )) : \
 	writew((val), (hw)->iobase + ( (off) << (hw)->reg_spacing )))
+#endif
 
 #define hermes_read_regn(hw, name) (hermes_read_reg((hw), HERMES_##name))
 #define hermes_write_regn(hw, name, val) (hermes_write_reg((hw), HERMES_##name, (val)))
diff -ruN -xasm-m32r -xm32r linux-2.4.26.org/drivers/pcmcia/Config.in linux-2.4.26/drivers/pcmcia/Config.in
--- linux-2.4.26.org/drivers/pcmcia/Config.in	2004-02-18 22:36:31.000000000 +0900
+++ linux-2.4.26/drivers/pcmcia/Config.in	2004-03-22 10:56:21.000000000 +0900
@@ -29,6 +29,12 @@
    if [ "$CONFIG_8xx" = "y" ]; then
       dep_tristate '  M8xx support' CONFIG_PCMCIA_M8XX $CONFIG_PCMCIA
    fi
+   if [ "$CONFIG_PLAT_MAPPI" = "y" ]; then
+      dep_bool '  M32R pc card controller support' CONFIG_M32RPCC $CONFIG_PCMCIA
+      if [ "$CONFIG_M32RPCC" = "y" ]; then
+	bool '   Enable M32R PCC slot2' CONFIG_M32RPCC_SLOT2
+      fi
+   fi
    if [ "$CONFIG_SOC_AU1X00" = "y" ]; then
       dep_tristate '  Au1x00 PCMCIA support' CONFIG_PCMCIA_AU1X00 $CONFIG_PCMCIA 
       if [ "$CONFIG_PCMCIA_AU1X00" != "n" ]; then
diff -ruN -xasm-m32r -xm32r linux-2.4.26.org/drivers/pcmcia/Makefile linux-2.4.26/drivers/pcmcia/Makefile
--- linux-2.4.26.org/drivers/pcmcia/Makefile	2004-02-18 22:36:31.000000000 +0900
+++ linux-2.4.26/drivers/pcmcia/Makefile	2004-03-22 10:56:21.000000000 +0900
@@ -38,6 +38,9 @@
   ifeq ($(CONFIG_HD64465_PCMCIA),y)
     obj-y += hd64465_ss.o
   endif
+  ifeq ($(CONFIG_M32RPCC),y)
+    obj-y += m32r_pcc.o
+  endif
 else
   ifeq ($(CONFIG_PCMCIA),m)
     obj-m   := pcmcia_core.o ds.o
diff -ruN -xasm-m32r -xm32r linux-2.4.26.org/drivers/pcmcia/cistpl.c linux-2.4.26/drivers/pcmcia/cistpl.c
--- linux-2.4.26.org/drivers/pcmcia/cistpl.c	2004-02-18 22:36:31.000000000 +0900
+++ linux-2.4.26/drivers/pcmcia/cistpl.c	2004-03-22 10:56:21.000000000 +0900
@@ -1027,6 +1027,11 @@
 			       cistpl_cftable_entry_t *entry)
 {
     u_char *p, *q, features;
+#define MUST_ALIGNED
+#ifdef MUST_ALIGNED
+      u_short t;
+      u_char *tp = (u_char *)&t;
+#endif	
 
     p = tuple->TupleData;
     q = p + tuple->TupleDataLen;
@@ -1099,7 +1104,13 @@
 	break;
     case 0x20:
 	entry->mem.nwin = 1;
+#ifdef MUST_ALIGNED
+	tp[0]=*p;
+	tp[1]=*(p+1);
+	entry->mem.win[0].len = le16_to_cpu(t) << 8;
+#else
 	entry->mem.win[0].len = le16_to_cpu(*(u_short *)p) << 8;
+#endif
 	entry->mem.win[0].card_addr = 0;
 	entry->mem.win[0].host_addr = 0;
 	p += 2;
diff -ruN -xasm-m32r -xm32r linux-2.4.26.org/drivers/pcmcia/m32r_pcc.c linux-2.4.26/drivers/pcmcia/m32r_pcc.c
--- linux-2.4.26.org/drivers/pcmcia/m32r_pcc.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.4.26/drivers/pcmcia/m32r_pcc.c	2002-12-25 18:15:56.000000000 +0900
@@ -0,0 +1,978 @@
+/*======================================================================
+
+	Device driver for the PCMCIA functionality of M32R.
+
+======================================================================*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/timer.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/proc_fs.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/bitops.h>
+#include <asm/segment.h>
+#include <asm/system.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/ss.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/bulkmem.h>
+#include <pcmcia/cistpl.h>
+
+#include "cs_internal.h"
+#include "m32r_pcc.h"
+
+/* XXX: should be moved into asm/irq.h */
+#define PCC0_IRQ 24
+#define PCC1_IRQ 25
+
+#define CHAOS_PCC_DEBUG
+#ifdef CHAOS_PCC_DEBUG
+	static volatile u_short dummy_readbuf;
+#endif
+
+#define PCC_DEBUG_DBEX
+
+#define PCMCIA_DEBUG   3
+
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+MODULE_PARM(pc_debug, "i");
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(args)
+
+static const char *version =
+"m32r_pcc.c 0.001 2002/02/12 18:36:21 (Hiroyuki Kondo)";
+#else
+#define DEBUG(n, args...) do { } while (0)
+#endif
+
+/* Poll status interval -- 0 means default to interrupt */
+static int poll_interval = 0;
+
+static unsigned long pcc_access_timing = 0x51755175;
+
+typedef enum pcc_space { as_none = 0, as_comm, as_attr, as_io } pcc_as_t;
+
+typedef struct pcc_socket_info_t {
+	u_short			type, flags;
+	socket_cap_t	cap;
+ 	ioaddr_t		ioaddr;
+	u_long			mapaddr;
+	u_long			base;	/* PCC register base */
+	u_char			cs_irq, intr;
+	void			(*handler)(void *info, u_int events);
+	void			*info;
+	pccard_io_map	io_map[MAX_IO_WIN];
+	pccard_mem_map	mem_map[MAX_WIN];
+	u_char			io_win;
+	u_char			mem_win;
+	pcc_as_t		current_space;
+	u_char			last_iodbex;
+#ifdef CHAOS_PCC_DEBUG
+	u_char			last_iosize;
+#endif
+#ifdef CONFIG_PROC_FS
+	struct proc_dir_entry *proc;
+#endif
+} pcc_socket_info_t;
+
+static int pcc_sockets = 0;
+static pcc_socket_info_t socket[M32R_MAX_PCC] = {
+	{ 0, }, /* ... */
+};
+
+#define ISA_LOCK(n, f) do { } while (0)
+#define ISA_UNLOCK(n, f) do { } while (0)
+
+/*====================================================================*/
+
+static unsigned int pcc_get(u_short, unsigned int);
+static void pcc_set(u_short, unsigned int , unsigned int );
+
+static spinlock_t pcc_lock = SPIN_LOCK_UNLOCKED;
+
+void pcc_iorw(int sock, unsigned long port, void *buf, size_t size, size_t nmemb, int wr, int flag)
+{
+	u_long addr;
+	u_long flags;
+	int need_ex;
+#ifdef PCC_DEBUG_DBEX
+	int _dbex;
+#endif
+	pcc_socket_info_t *t = &socket[sock];
+#ifdef CHAOS_PCC_DEBUG
+	int map_changed = 0;
+#endif
+
+	/* Need lock ? */
+	spin_lock_irqsave(&pcc_lock, flags);
+
+	/*
+	 * Check if need dbex
+	 */
+	need_ex = (size > 1 && flag == 0) ? PCMOD_DBEX : 0;
+#ifdef PCC_DEBUG_DBEX
+	_dbex = need_ex;
+	need_ex = 0;
+#endif
+
+	/*
+	 * calculate access address
+	 */
+	addr = t->mapaddr + port - t->ioaddr + KSEG1; /* XXX */
+
+	/*
+	 * Check current mapping
+	 */
+	if (t->current_space != as_io || t->last_iodbex != need_ex) {
+
+		u_long cbsz;
+
+		/*
+		 * Disable first
+		 */
+		pcc_set(sock, PCCR, 0);
+
+		/*
+		 * Set mode and io address
+		 */
+		cbsz = (t->flags & MAP_16BIT) ? 0 : PCMOD_CBSZ;
+		pcc_set(sock, PCMOD, PCMOD_AS_IO | cbsz | need_ex);
+		pcc_set(sock, PCADR, addr & 0x1ff00000);
+
+		pcc_set(sock, PCATCR, pcc_access_timing);
+
+		/*
+		 * Enable and read it
+		 */
+		pcc_set(sock, PCCR, 1);
+
+#ifdef CHAOS_PCC_DEBUG
+#if 0
+		map_changed = (t->current_space == as_attr && size == 2); /* XXX */
+#else
+		map_changed = 1;
+#endif
+#endif
+		t->current_space = as_io;
+	}
+
+	/*
+	 * access to IO space
+	 */
+	if (size == 1) {
+		/* Byte */
+		unsigned char *bp = (unsigned char *)buf;
+
+#ifdef CHAOS_DEBUG
+		if (map_changed) {
+			dummy_readbuf = readb(addr);
+		}
+#endif
+		if (wr) {
+			/* write Byte */
+			while (nmemb--) {
+				writeb(*bp++, addr);
+			}
+		} else {
+			/* read Byte */
+			while (nmemb--) {
+	    		*bp++ = readb(addr);
+			}
+		}
+	} else {
+		/* Word */
+		unsigned short *bp = (unsigned short *)buf;
+
+#ifdef CHAOS_PCC_DEBUG
+		if (map_changed) {
+			dummy_readbuf = readw(addr);
+		}
+#endif
+		if (wr) {
+			/* write Word */
+			while (nmemb--) {
+#ifdef PCC_DEBUG_DBEX
+				if (_dbex) {
+					unsigned char *cp = (unsigned char *)bp;
+					unsigned short tmp;
+					tmp = cp[1] << 8 | cp[0];
+					writew(tmp, addr);
+					bp++;
+				} else 
+#endif
+				writew(*bp++, addr);
+	    	}
+	    } else {
+	    	/* read Word */
+	    	while (nmemb--) {
+#ifdef  PCC_DEBUG_DBEX
+				if (_dbex) {
+					unsigned char *cp = (unsigned char *)bp;
+					unsigned short tmp;
+					tmp = readw(addr);
+					cp[0] = tmp & 0xff;
+					cp[1] = (tmp >> 8) & 0xff;
+					bp++;
+				} else 
+#endif
+				*bp++ = readw(addr);
+	    	}
+	    }
+	}
+
+#if 1
+	/* addr is no longer used */
+	if ((addr = pcc_get(sock, PCIRC)) & PCIRC_BWERR) {
+	  printk("m32r_pcc: BWERR detected : port 0x%04lx : iosize %dbit\n",
+			 port, size * 8);
+	  pcc_set(sock, PCIRC, addr);
+	}
+#endif
+	/*
+	 * save state
+	 */
+	t->last_iosize = size;
+	t->last_iodbex = need_ex;
+
+	/* Need lock ? */
+	spin_unlock_irqrestore(&pcc_lock,flags);
+
+	return;
+}
+
+void pcc_ioread(int sock, unsigned long port, void *buf, size_t size, size_t nmemb, int flag) {
+	pcc_iorw(sock, port, buf, size, nmemb, 0, flag);
+}
+
+void pcc_iowrite(int sock, unsigned long port, void *buf, size_t size, size_t nmemb, int flag) {
+    pcc_iorw(sock, port, buf, size, nmemb, 1, flag);
+}
+
+/*====================================================================*/
+
+#define IS_ALIVE		0x8000
+
+typedef struct pcc_t {
+	char				*name;
+	u_short				flags;
+} pcc_t;
+
+static pcc_t pcc[] = {
+	{ "xnux2", 0 }, { "xnux2", 0 },
+};
+
+static void pcc_interrupt(int, void *, struct pt_regs *regs);
+
+/*====================================================================*/
+
+static struct timer_list poll_timer;
+
+static unsigned int pcc_get(u_short sock, unsigned int reg)
+{
+	return inl(socket[sock].base + reg);
+}
+
+
+static void pcc_set(u_short sock, unsigned int reg, unsigned int data)
+{
+  	outl(data, socket[sock].base + reg);
+}
+
+/*======================================================================
+
+	See if a card is present, powered up, in IO mode, and already
+	bound to a (non PC Card) Linux driver.  We leave these alone.
+
+	We make an exception for cards that seem to be serial devices.
+	
+======================================================================*/
+
+static int __init is_alive(u_short sock)
+{
+	unsigned int stat;
+	unsigned int f;
+	
+	stat = pcc_get(sock, PCIRC);
+	f = (stat & (PCIRC_CDIN1 | PCIRC_CDIN2)) >> 16;
+	if(!f){
+		printk("m32r_pcc: No Card is detected at socket %d : stat = 0x%08x\n",stat,sock);
+		return 0;
+	}
+	if(f!=3)
+		printk("m32r_pcc: Insertion fail (%.8x) at socket %d\n",stat,sock);
+	else
+		printk("m32r_pcc: Card is Inserted at socket %d(%.8x)\n",sock,stat);
+	return 0;
+}
+
+static void add_pcc_socket(ulong base, int irq, ulong mapaddr, ioaddr_t ioaddr)
+{
+  	pcc_socket_info_t *t = &socket[pcc_sockets];
+
+	/* add sockets */
+	t->ioaddr = ioaddr;
+	t->mapaddr = mapaddr;
+	t->base = base;
+#ifdef CHAOS_PCC_DEBUG
+	t->flags = MAP_16BIT;
+#else
+	t->flags = 0;
+#endif
+	if (is_alive(pcc_sockets))
+		t->flags |= IS_ALIVE;
+
+	/* pcc_set(sockets,PCCR,1); */
+	/* pcc_set(sockets,PCIRC,3); */
+
+	/* add pcc */
+	if (t->base > 0) {
+		request_region(t->base, 0x20, "m32r-pcc");
+	}
+
+	printk(KERN_INFO "  %s ", pcc[pcc_sockets].name);
+	printk("pcc at 0x%08lx\n", t->base);
+
+	/* Update socket interrupt information, capabilities */
+	t->cap.features |= (SS_CAP_PCCARD | SS_CAP_STATIC_MAP);
+	t->cap.map_size = M32R_PCC_MAPSIZE;
+	t->cap.io_offset = ioaddr; /*  */
+	t->cap.irq_mask = 0;
+	t->cap.pci_irq = 2 + pcc_sockets; /* XXX */
+
+	request_irq(irq, pcc_interrupt, 0, "m32r-pcc", pcc_interrupt);
+
+	pcc_sockets++;
+
+	return;
+}
+
+
+/*====================================================================*/
+
+static u_int pending_events[8];
+static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED;
+
+static void pcc_bh(void *dummy)
+{
+	u_int events;
+	int i;
+	DEBUG(4, "m32r: pcc_bh\n");
+
+	for (i=0; i < pcc_sockets; i++) {
+		spin_lock_irq(&pending_event_lock);
+		events = pending_events[i];
+		pending_events[i] = 0;
+		spin_unlock_irq(&pending_event_lock);
+	/* 
+	 * SS_DETECT events need a small delay here. The reason for this is that 
+	 * the "is there a card" electronics need time to see the card after the
+	 * "we have a card coming in" electronics have seen it. 
+	 */
+		if (events & SS_DETECT) 
+			mdelay(4);
+		if (socket[i].handler)
+			socket[i].handler(socket[i].info, events);
+	}
+}
+
+static struct tq_struct pcc_task = {
+		routine:		pcc_bh
+};
+
+static unsigned long last_detect_jiffies;
+
+static void pcc_interrupt(int irq, void *dev, struct pt_regs *regs)
+{
+	int i, j, irc;
+	u_int events, active;
+#ifdef CONFIG_ISA
+	u_long flags = 0;
+#endif
+	
+	DEBUG(4, "m32r: pcc_interrupt(%d)\n", irq);
+
+	for (j = 0; j < 20; j++) {
+		active = 0;
+		for (i = 0; i < pcc_sockets; i++) {
+			if ((socket[i].cs_irq != irq) &&
+				(socket[i].cap.pci_irq != irq))
+				continue;
+			irc = pcc_get(i, PCIRC);
+			irc >>=16;
+			DEBUG(2, "m32r-pcc:interrput: socket %d pcirc 0x%02x ", i, irc);
+			if ((irc == 0) || (!socket[i].handler) ) {
+				continue;
+			}
+			events = (irc ) ? SS_DETECT : 0;
+			
+			
+			/* Several sockets will send multiple "new card detected"
+			   events in rapid succession. However, the rest of the pcmcia expects 
+			   only one such event. We just ignore these events by having a
+			   timeout */
+
+			if (events) {
+				if ((jiffies - last_detect_jiffies)<(HZ/20)) 
+					events = 0;
+				last_detect_jiffies = jiffies;
+			}
+			events |= (pcc_get(i,PCCR) & PCCR_PCEN) ? SS_READY : 0;
+#if 0
+			if (i365_get(i, I365_INTCTL) & I365_PC_IOCARD)
+				events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0;
+			else {
+				events |= (csc & I365_CSC_BVD1) ? SS_BATDEAD : 0;
+				events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0;
+				events |= (csc & I365_CSC_READY) ? SS_READY : 0;
+			}
+			DEBUG(2, "m32r-pcc:interrput: socket %d event 0x%02x\n", i, events);
+#endif
+			DEBUG(2, " event 0x%02x\n", events);
+
+			if (events) {
+				spin_lock(&pending_event_lock);
+				pending_events[i] |= events;
+				spin_unlock(&pending_event_lock);
+				schedule_task(&pcc_task);
+			}
+			active |= events;
+			active = 0;
+		}
+		if (!active) break;
+	}
+	if (j == 20)
+		printk(KERN_NOTICE "m32r-pcc: infinite loop in interrupt handler\n");
+
+	DEBUG(4, "m32r-pcc: interrupt done\n");
+} /* pcc_interrupt */
+
+static void pcc_interrupt_wrapper(u_long data)
+{
+	pcc_interrupt(0, NULL, NULL);
+#if 1
+	poll_timer.expires = jiffies + poll_interval;
+	add_timer(&poll_timer);
+#endif
+}
+
+/*====================================================================*/
+
+static int _pcc_get_status(u_short sock, u_int *value)
+{
+	u_int status;
+	
+	status = pcc_get(sock,PCIRC);
+	*value = ((status & PCIRC_CDIN1) && (status & PCIRC_CDIN2))
+		? SS_DETECT : 0;
+		
+#if 0
+	if (i365_get(sock, I365_INTCTL) & I365_PC_IOCARD)
+		*value |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG;
+	else {
+		*value |= (status & I365_CS_BVD1) ? 0 : SS_BATDEAD;
+		*value |= (status & I365_CS_BVD2) ? 0 : SS_BATWARN;
+	}
+	*value |= (status & I365_CS_WRPROT) ? SS_WRPROT : 0;
+#endif
+	status = pcc_get(sock,PCCR);
+
+#if 0
+	*value |= (status & PCCR_PCEN) ? SS_READY : 0;
+#else
+	*value |= SS_READY; /* XXX: always */
+#endif
+
+	status = pcc_get(sock,PCCSIGCR);
+	*value |= (status & PCCSIGCR_VEN) ? SS_POWERON : 0;
+
+	DEBUG(3, "m32r-pcc: GetStatus(%d) = %#4.4x\n", sock, *value);
+	return 0;
+} /* _get_status */
+
+/*====================================================================*/
+
+static int _pcc_get_socket(u_short sock, socket_state_t *state)
+{
+#if 0
+	pcc_socket_info_t *t = &socket[sock];
+	u_char reg, vcc, vpp;
+	
+	reg = i365_get(sock, I365_POWER);
+	state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0;
+	state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0;
+
+	vcc = reg & I365_VCC_MASK; vpp = reg & I365_VPP1_MASK;
+	state->Vcc = state->Vpp = 0;
+	if (reg & I365_VCC_5V) {
+		state->Vcc = 50;
+		if (vpp == I365_VPP1_5V) state->Vpp = 50;
+		if (vpp == I365_VPP1_12V) state->Vpp = 120;
+	}
+
+	/* IO card, RESET flags, IO interrupt */
+	reg = i365_get(sock, I365_INTCTL);
+	state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET;
+	if (reg & I365_PC_IOCARD) state->flags |= SS_IOCARD;
+	state->io_irq = reg & I365_IRQ_MASK;
+	
+	/* Card status change mask */
+	reg = i365_get(sock, I365_CSCINT);
+	state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0;
+	if (state->flags & SS_IOCARD)
+		state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0;
+	else {
+		state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0;
+		state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0;
+		state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0;
+	}
+#endif
+	
+	DEBUG(3, "m32r-pcc: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
+		  "io_irq %d, csc_mask %#2.2x\n", sock, state->flags,
+		  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
+	return 0;
+} /* _get_socket */
+
+/*====================================================================*/
+
+static int _pcc_set_socket(u_short sock, socket_state_t *state)
+{
+	u_long reg = 0;
+	
+	DEBUG(3, "m32r-pcc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
+		  "io_irq %d, csc_mask %#2.2x)", sock, state->flags,
+		  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
+
+	if (state->Vcc) {
+		/*
+		 * 5V only
+		 */
+		if (state->Vcc == 50) {
+			reg |= PCCSIGCR_VEN;
+		} else {
+			return -EINVAL;
+		}
+	}
+
+	if (state->flags & SS_RESET) {
+		DEBUG(3, ":RESET");
+		reg |= PCCSIGCR_CRST;
+	}
+	if (state->flags & SS_OUTPUT_ENA){
+		DEBUG(3, ":OUTPUT_ENA");
+		/* bit clear */
+	} else {
+		reg |= PCCSIGCR_SEN;
+	}
+
+	pcc_set(sock,PCCSIGCR,reg);
+
+#ifdef PCMCIA_DEBUG
+	if(state->flags & SS_IOCARD){
+		DEBUG(3, ":IOCARD");
+	}
+	if (state->flags & SS_PWR_AUTO) {
+		DEBUG(3, ":PWR_AUTO");
+	}
+	if (state->csc_mask & SS_DETECT)
+		DEBUG(3, ":csc-SS_DETECT");
+	if (state->flags & SS_IOCARD) {
+		if (state->csc_mask & SS_STSCHG) 
+			DEBUG(3, ":STSCHG");
+	} else {
+		if (state->csc_mask & SS_BATDEAD)
+			DEBUG(3, ":BATDEAD");
+		if (state->csc_mask & SS_BATWARN)
+			DEBUG(3, ":BATWARN");
+		if (state->csc_mask & SS_READY)
+			DEBUG(3, ":READY");
+	}
+	DEBUG(3, "\n");
+#endif
+	return 0;
+} /* _set_socket */
+
+/*====================================================================*/
+
+static int _pcc_get_io_map(u_short sock, struct pccard_io_map *io)
+{
+	u_char map;
+	
+	map = io->map;
+
+	DEBUG(3, "m32r-pcc: GetIOMap(%d, %d) = %#2.2x, %d ns, "
+		  "%#4.4x-%#4.4x\n", sock, map, io->flags, io->speed,
+		  io->start, io->stop);
+	return 0;
+} /* _get_io_map */
+
+/*====================================================================*/
+
+static int _pcc_set_io_map(u_short sock, struct pccard_io_map *io)
+{
+	u_char map;
+	
+	DEBUG(3, "m32r-pcc: SetIOMap(%d, %d, %#2.2x, %d ns, "
+		  "%#4.4x-%#4.4x)\n", sock, io->map, io->flags,
+		  io->speed, io->start, io->stop);
+	map = io->map;
+
+	return 0;
+} /* _set_io_map */
+
+/*====================================================================*/
+
+static int _pcc_get_mem_map(u_short sock, struct pccard_mem_map *mem)
+{
+	int mode;
+	u_char map;
+	
+	map = mem->map;
+	mode = pcc_get(sock, PCMOD);
+
+	DEBUG(3, "m32r-pcc: GetMemMap(%d, %d) = %#2.2x, %d ns, %#5.5lx-%#5."
+		  "5lx, %#5.5x\n", sock, mem->map, mem->flags, mem->speed,
+		  mem->sys_start, mem->sys_stop, mem->card_start);
+	return 0;
+} /* _get_mem_map */
+
+/*====================================================================*/
+
+  
+static int _pcc_set_mem_map(u_short sock, struct pccard_mem_map *mem)
+{
+
+	u_char map = mem->map;
+	u_long mode;
+	u_long addr;
+	pcc_socket_info_t *t = &socket[sock];
+#ifdef CHAOS_PCC_DEBUG
+	pcc_as_t last = t->current_space;
+#endif
+
+	DEBUG(3, "m32r-pcc: SetMemMap(%d, %d, %#2.2x, %d ns, %#5.5lx-%#5.5"
+		  "lx, %#5.5x)\n", sock, map, mem->flags, mem->speed,
+		  mem->sys_start, mem->sys_stop, mem->card_start);
+
+	/*
+	 * sanity check
+	 */
+	if ((map > MAX_WIN) || (mem->card_start > 0x3ffffff) ||	 
+		(mem->sys_start > mem->sys_stop)) {
+		return -EINVAL;
+	}
+
+	/*
+	 * de-activate
+	 */
+	if ((mem->flags & MAP_ACTIVE) == 0) {
+		t->current_space = as_none;
+		return 0;
+	}
+
+	/*
+	 * Disable first
+	 */
+	pcc_set(sock, PCCR, 0);
+
+	/*
+	 * Set mode
+	 */
+	if (mem->flags & MAP_ATTRIB) {
+		mode = PCMOD_AS_ATTRIB | PCMOD_CBSZ;
+		t->current_space = as_attr;
+	} else {
+		mode = 0; /* common memory */
+		t->current_space = as_comm;
+	}
+	pcc_set(sock, PCMOD, mode);
+
+	/*
+	 * Set address
+	 */
+	addr = t->mapaddr + (mem->card_start & M32R_PCC_MAPMASK);
+	pcc_set(sock, PCADR, addr);
+
+	mem->sys_start = addr + mem->card_start;
+	mem->sys_stop = mem->sys_start + (M32R_PCC_MAPSIZE - 1);
+
+	/*
+	 * Set timing
+	 */
+	pcc_set(sock, PCATCR, pcc_access_timing);
+
+	/*
+	 * Enable again
+	 */
+	pcc_set(sock, PCCR, 1);
+
+#ifdef CHAOS_PCC_DEBUG
+#if 0
+	if (last != as_attr) {
+#else
+	if (1) {
+#endif
+
+		dummy_readbuf = *(u_char *)(addr + KSEG1);
+	}
+#endif
+
+	return 0;
+
+} /* _set_mem_map */
+
+/*======================================================================
+
+	Routines for accessing socket information and register dumps via
+	/proc/bus/pccard/...
+	
+======================================================================*/
+
+#ifdef CONFIG_PROC_FS
+
+static int proc_read_info(char *buf, char **start, off_t pos,
+				  int count, int *eof, void *data)
+{
+	pcc_socket_info_t *s = data;
+	char *p = buf;
+	p += sprintf(p, "type:	 %s\nbase addr:	0x%08lx\n",
+				 pcc[s->type].name, s->base);
+	return (p - buf);
+}
+
+static int proc_read_exca(char *buf, char **start, off_t pos,
+				  int count, int *eof, void *data)
+{
+#if 0
+	u_short sock = (pcc_socket_info_t *)data - socket;
+#endif
+	char *p = buf;
+	int i, top;
+	
+	ISA_LOCK(sock, flags);
+	top = 0x40;
+	for (i = 0; i < top; i += 4) {
+		if (i == 0x50) {
+			p += sprintf(p, "\n");
+			i = 0x100;
+		}
+#if 0
+		p += sprintf(p, "%02x %02x %02x %02x%s",
+			 i365_get(sock,i), i365_get(sock,i+1),
+			 i365_get(sock,i+2), i365_get(sock,i+3),
+			 ((i % 16) == 12) ? "\n" : " ");
+#endif
+	}
+	ISA_UNLOCK(sock, flags);
+	return (p - buf);
+}
+
+static void pcc_proc_setup(unsigned int sock, struct proc_dir_entry *base)
+{
+	pcc_socket_info_t *s = &socket[sock];
+
+	if (s->flags & IS_ALIVE)
+			return;
+
+	create_proc_read_entry("info", 0, base, proc_read_info, s);
+	create_proc_read_entry("exca", 0, base, proc_read_exca, s);
+	s->proc = base;
+}
+
+static void pcc_proc_remove(u_short sock)
+{
+	struct proc_dir_entry *base = socket[sock].proc;
+	if (base == NULL) return;
+	remove_proc_entry("info", base);
+	remove_proc_entry("exca", base);
+}
+
+#else
+
+#define pcc_proc_setup NULL
+
+#endif /* CONFIG_PROC_FS */
+
+/*====================================================================*/
+
+#define LOCKED(x) return x
+
+static int pcc_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void * info)
+{
+	DEBUG(4, "m32r-pcc: reg call\n");
+	socket[sock].handler = handler;
+	socket[sock].info = info;
+	if (handler == NULL) {
+		MOD_DEC_USE_COUNT;
+	} else {
+		MOD_INC_USE_COUNT;
+	}
+	return 0;
+} /* pcc_register_callback */
+
+static int pcc_inquire_socket(unsigned int sock, socket_cap_t *cap)
+{
+	*cap = socket[sock].cap;
+	return 0;
+} /* pcc_inquire_socket */
+
+static int pcc_get_status(unsigned int sock, u_int *value)
+{
+	if (socket[sock].flags & IS_ALIVE) {
+		*value = 0;
+		return -EINVAL;
+	}
+	LOCKED(_pcc_get_status(sock, value));
+}
+
+static int pcc_get_socket(unsigned int sock, socket_state_t *state)
+{
+	if (socket[sock].flags & IS_ALIVE)
+		return -EINVAL;
+	LOCKED(_pcc_get_socket(sock, state));
+}
+
+static int pcc_set_socket(unsigned int sock, socket_state_t *state)
+{
+	if (socket[sock].flags & IS_ALIVE)
+		return -EINVAL;
+
+	LOCKED(_pcc_set_socket(sock, state));
+}
+
+static int pcc_get_io_map(unsigned int sock, struct pccard_io_map *io)
+{
+	if (socket[sock].flags & IS_ALIVE)
+		return -EINVAL;
+	LOCKED(_pcc_get_io_map(sock, io));
+}
+
+static int pcc_set_io_map(unsigned int sock, struct pccard_io_map *io)
+{
+	if (socket[sock].flags & IS_ALIVE)
+		return -EINVAL;
+	LOCKED(_pcc_set_io_map(sock, io));
+}
+
+static int pcc_get_mem_map(unsigned int sock, struct pccard_mem_map *mem)
+{
+	if (socket[sock].flags & IS_ALIVE)
+		return -EINVAL;
+	LOCKED(_pcc_get_mem_map(sock, mem));
+}
+
+static int pcc_set_mem_map(unsigned int sock, struct pccard_mem_map *mem)
+{
+	if (socket[sock].flags & IS_ALIVE)
+		return -EINVAL;
+	LOCKED(_pcc_set_mem_map(sock, mem));
+}
+
+static int pcc_init(unsigned int s)
+{
+	DEBUG(4, "m32r-pcc: init call\n");
+	return 0;
+}
+
+static int pcc_suspend(unsigned int sock)
+{
+	return pcc_set_socket(sock, &dead_socket);
+}
+
+
+static struct pccard_operations pcc_operations = {
+	pcc_init,
+	pcc_suspend,
+	pcc_register_callback,
+	pcc_inquire_socket,
+	pcc_get_status,
+	pcc_get_socket,
+	pcc_set_socket,
+	pcc_get_io_map,
+	pcc_set_io_map,
+	pcc_get_mem_map,
+	pcc_set_mem_map,
+	pcc_proc_setup
+};
+
+/*====================================================================*/
+
+static int __init init_m32r_pcc(void)
+{
+	servinfo_t serv;
+	pcmcia_get_card_services_info(&serv);
+	if (serv.Revision != CS_RELEASE_CODE) {
+		printk(KERN_NOTICE "m32r-pcc: Card Services release "
+			   "does not match!\n");
+		return -1;
+	}
+
+	DEBUG(0, "%s\n", version);
+	printk(KERN_INFO "m32r PCC probe:\n");
+	pcc_sockets = 0;
+
+	add_pcc_socket(M32R_PCC0_BASE, PCC0_IRQ, M32R_PCC0_MAPBASE, 0x1000);
+
+#ifdef CONFIG_M32RPCC_SLOT2
+	add_pcc_socket(M32R_PCC1_BASE, PCC1_IRQ, M32R_PCC1_MAPBASE, 0x2000);
+#endif
+
+	if (pcc_sockets == 0) {
+		printk("not found.\n");
+		return -ENODEV;
+	}
+	/* Set up interrupt handler(s) */
+
+	if (register_ss_entry(pcc_sockets, &pcc_operations) != 0)
+		printk(KERN_NOTICE "m32r_pcc: register_ss_entry() failed\n");
+
+	/* Finally, schedule a polling interrupt */
+#if 0
+	poll_interval = HZ;
+#endif
+	if (poll_interval != 0) {
+		poll_timer.function = pcc_interrupt_wrapper;
+		poll_timer.data = 0;
+		init_timer(&poll_timer);
+		poll_timer.expires = jiffies + poll_interval;
+		add_timer(&poll_timer);
+	}
+
+	return 0;
+} /* init_m32r_pcc */
+
+static void __exit exit_m32r_pcc(void)
+{
+#ifdef CONFIG_PROC_FS
+	int i;
+	for (i = 0; i < pcc_sockets; i++) pcc_proc_remove(i);
+#endif
+	unregister_ss_entry(&pcc_operations);
+
+} /* exit_m32r_pcc */
+
+module_init(init_m32r_pcc);
+module_exit(exit_m32r_pcc);
+
+/*
+ ***  Emacs  Setting ***
+ * Local Variables:
+ * c-basic-offset:4
+ * tab-width:4
+ * End:
+ */
+
diff -ruN -xasm-m32r -xm32r linux-2.4.26.org/drivers/pcmcia/m32r_pcc.h linux-2.4.26/drivers/pcmcia/m32r_pcc.h
--- linux-2.4.26.org/drivers/pcmcia/m32r_pcc.h	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.4.26/drivers/pcmcia/m32r_pcc.h	2002-07-16 21:23:34.000000000 +0900
@@ -0,0 +1,70 @@
+/*
+ *  $Id: m32r_pcc.h,v 1.1 2002/07/16 12:23:34 sakugawa Exp $
+ *
+ * Copyright (C) 2001 by Hiroyuki Kondo
+ */
+
+
+
+#define M32R_MAX_PCC	2
+
+/*
+ * M32R PC Card Controler
+ */
+#define M32R_PCC0_BASE        0x00ef7000
+#define M32R_PCC1_BASE        0x00ef7020
+
+/*
+ * Register offsets
+ */
+#define PCCR            0x00
+#define PCADR           0x04
+#define PCMOD           0x08
+#define PCIRC           0x0c
+#define PCCSIGCR        0x10
+#define PCATCR          0x14
+
+/*
+ * PCCR
+ */
+#define PCCR_PCEN       (1UL<<(31-31))
+
+/*
+ * PCIRC
+ */
+#define PCIRC_BWERR     (1UL<<(31-7))
+#define PCIRC_CDIN1     (1UL<<(31-14))
+#define PCIRC_CDIN2     (1UL<<(31-15))
+#define PCIRC_BEIEN     (1UL<<(31-23))
+#define PCIRC_CIIEN     (1UL<<(31-30))
+#define PCIRC_COIEN     (1UL<<(31-31))
+
+/*
+ * PCCSIGCR
+ */
+#define PCCSIGCR_SEN    (1UL<<(31-3))
+#define PCCSIGCR_VEN    (1UL<<(31-7))
+#define PCCSIGCR_CRST   (1UL<<(31-15))
+#define PCCSIGCR_COCR   (1UL<<(31-31))
+
+/*
+ *
+ */
+#define PCMOD_AS_ATTRIB	(1UL<<(31-19))
+#define PCMOD_AS_IO	(1UL<<(31-18))
+
+#define PCMOD_CBSZ	(1UL<<(31-23)) /* set for 8bit */
+
+#define PCMOD_DBEX	(1UL<<(31-31)) /* set for excahnge */
+
+/*
+ * M32R PCC Map addr
+ */
+#define M32R_PCC0_MAPBASE        0x14000000
+#define M32R_PCC1_MAPBASE        0x16000000
+
+#define M32R_PCC_MAPMAX		 0x02000000
+
+#define M32R_PCC_MAPSIZE	 0x00001000 /* XXX */
+#define M32R_PCC_MAPMASK     	(~(M32R_PCC_MAPMAX-1))
+
diff -ruN -xasm-m32r -xm32r linux-2.4.26.org/drivers/usb/Config.in linux-2.4.26/drivers/usb/Config.in
--- linux-2.4.26.org/drivers/usb/Config.in	2004-02-18 22:36:31.000000000 +0900
+++ linux-2.4.26/drivers/usb/Config.in	2004-03-22 10:56:30.000000000 +0900
@@ -4,7 +4,14 @@
 mainmenu_option next_comment
 comment 'USB support'
 
-dep_tristate 'Support for USB' CONFIG_USB $CONFIG_PCI
+if [ "$CONFIG_PLAT_MAPPI2" = "y" -o "$CONFIG_PLAT_M32700UT" = "y" ];
+then
+  define_bool CONFIG_M32R_USB y
+fi
+
+  dep_tristate 'Support for USB' CONFIG_USB $CONFIG_M32R_USB
+
+
 if [ "$CONFIG_USB" = "y" -o  "$CONFIG_USB" = "m" ]; then
    bool '  USB verbose debug messages' CONFIG_USB_DEBUG
 
@@ -21,6 +28,7 @@
    comment 'USB Device Class drivers'
    dep_tristate '  USB Audio support' CONFIG_USB_AUDIO $CONFIG_USB $CONFIG_SOUND
    dep_tristate '    EMI 2|6 USB Audio interface support' CONFIG_USB_EMI26 $CONFIG_USB_AUDIO
+
    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
       if [ "$CONFIG_BLUEZ" = "n" ]; then
          dep_tristate '  USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB
diff -ruN -xasm-m32r -xm32r linux-2.4.26.org/drivers/usb/Makefile linux-2.4.26/drivers/usb/Makefile
--- linux-2.4.26.org/drivers/usb/Makefile	2004-02-18 22:36:31.000000000 +0900
+++ linux-2.4.26/drivers/usb/Makefile	2004-04-12 13:06:03.000000000 +0900
@@ -77,6 +77,16 @@
 	obj-y += host/usb-ohci.o
 endif
 
+subdir-$(CONFIG_USB_PHCI)	+= host
+ifeq ($(CONFIG_USB_PHCI),y)
+	obj-y += host/usb_phci.o
+endif
+
+subdir-$(CONFIG_USB_HAL_MAPPI2)	+= host
+ifeq ($(CONFIG_USB_HAL_MAPPI2),y)
+	obj-y += host/hal_mappi2.o
+endif
+
 subdir-$(CONFIG_USB_SL811HS_ALT)	+= host
 subdir-$(CONFIG_USB_SL811HS)	+= host
 
diff -ruN -xasm-m32r -xm32r linux-2.4.26.org/drivers/usb/hcd.c linux-2.4.26/drivers/usb/hcd.c
--- linux-2.4.26.org/drivers/usb/hcd.c	2004-04-14 22:05:32.000000000 +0900
+++ linux-2.4.26/drivers/usb/hcd.c	2004-04-28 11:27:03.000000000 +0900
@@ -1206,6 +1206,7 @@
 	if (urb->dev == hcd->bus->root_hub) {
 		status = rh_urb_enqueue (hcd, urb);
 	} else {
+#ifdef CONFIG_PCI
 		if (usb_pipecontrol (urb->pipe))
 			urb->setup_dma = pci_map_single (
 					hcd->pdev,
@@ -1220,6 +1221,7 @@
 					usb_pipein (urb->pipe)
 					    ? PCI_DMA_FROMDEVICE
 					    : PCI_DMA_TODEVICE);
+#endif
 		status = hcd->driver->urb_enqueue (hcd, urb, mem_flags);
 	}
 	return status;
@@ -1489,6 +1491,7 @@
 	// NOTE:  2.5 does this if !URB_NO_DMA_MAP transfer flag
 	
 	/* For 2.4, don't unmap bounce buffer if it's a root hub operation. */
+#ifdef CONFIG_PCI
 	if (usb_pipecontrol (urb->pipe) && !is_root_hub_operation)
 		pci_unmap_single (hcd->pdev, urb->setup_dma,
 				sizeof (struct usb_ctrlrequest),
@@ -1500,7 +1503,7 @@
 				usb_pipein (urb->pipe)
 				    ? PCI_DMA_FROMDEVICE
 				    : PCI_DMA_TODEVICE);
-
+#endif
 	/* pass ownership to the completion handler */
 	urb->complete (urb);
 }
diff -ruN -xasm-m32r -xm32r linux-2.4.26.org/drivers/usb/host/Config.in linux-2.4.26/drivers/usb/host/Config.in
--- linux-2.4.26.org/drivers/usb/host/Config.in	2003-11-29 03:26:20.000000000 +0900
+++ linux-2.4.26/drivers/usb/host/Config.in	2004-03-22 10:56:31.000000000 +0900
@@ -17,3 +17,6 @@
    dep_tristate '  SL811HS Alternate (x86, StrongARM, isosynchronous mode)' CONFIG_USB_SL811HS_ALT $CONFIG_USB $CONFIG_EXPERIMENTAL
    dep_tristate '  SL811HS (x86, StrongARM) support, old driver' CONFIG_USB_SL811HS $CONFIG_USB $CONFIG_EXPERIMENTAL
 fi
+dep_tristate '  ISP1362(Philips) support' CONFIG_USB_PHCI $CONFIG_USB
+dep_tristate '    M32R HAL support' CONFIG_USB_HAL_MAPPI2 $CONFIG_USB $CONFIG_USB_PHCI
+
diff -ruN -xasm-m32r -xm32r linux-2.4.26.org/drivers/usb/host/Makefile linux-2.4.26/drivers/usb/host/Makefile
--- linux-2.4.26.org/drivers/usb/host/Makefile	2003-11-29 03:26:20.000000000 +0900
+++ linux-2.4.26/drivers/usb/host/Makefile	2004-03-22 10:56:31.000000000 +0900
@@ -9,8 +9,10 @@
 obj-$(CONFIG_USB_UHCI_ALT)			+= uhci.o
 obj-$(CONFIG_USB_UHCI)				+= usb-uhci.o
 obj-$(CONFIG_USB_OHCI)				+= usb-ohci.o
-obj-$(CONFIG_USB_SL811HS_ALT)  			+= sl811.o
-obj-$(CONFIG_USB_SL811HS)  			+= hc_sl811.o
+obj-$(CONFIG_USB_SL811HS_ALT)			+= sl811.o
+obj-$(CONFIG_USB_SL811HS)			+= hc_sl811.o
+obj-$(CONFIG_USB_PHCI)				+= usb_phci.o
+obj-$(CONFIG_USB_HAL_MAPPI2)			+= hal_mappi2.o
 
 # Extract lists of the multi-part drivers.
 # The 'int-*' lists are the intermediate files used to build the multi's.
diff -ruN -xasm-m32r -xm32r linux-2.4.26.org/drivers/usb/host/usb_phci.c linux-2.4.26/drivers/usb/host/usb_phci.c
--- linux-2.4.26.org/drivers/usb/host/usb_phci.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.4.26/drivers/usb/host/usb_phci.c	2004-04-28 11:27:11.000000000 +0900
@@ -0,0 +1,5723 @@
+/*************************************************************
+ * Philips HCD (Host Controller Driver) for USB.
+ *
+ *	Original Host Controller driver code from Linux OS 2.4.5 Kernel and 
+ *  modified for Philips ISP1362 HCD
+ * 
+ * File Name:	usb_phci.c
+ *
+ * History:	
+ *
+ *	Version	Date		Author		Comments
+ * -------------------------------------------------
+ * 	1.0		09/23/02	SYARRA		Initial Release
+ *  1.1		11/22/02	SYARRA		Waiting in while loop for IsoTx
+ *									start of frame is changed (ISO_WAIT_FIX)
+ * 
+ *************************************************************/
+ 
+#include <linux/config.h>
+//#define MODULE
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>  /* for in_interrupt() */
+#undef DEBUG
+#include <linux/usb.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/unaligned.h>
+#include <asm/dma.h>
+
+#include "usb_phci.h"
+
+#include "../hcd.h"
+
+struct isp1362_dev	*isp1362_device = NULL;
+
+static int cc_to_error[16] = { 
+
+/* mapping of the OHCI CC status to error codes */ 
+	/* No  Error  */               USB_ST_NOERROR,
+	/* CRC Error  */               USB_ST_CRC,
+	/* Bit Stuff  */               USB_ST_BITSTUFF,
+	/* Data Togg  */               USB_ST_CRC,
+	/* Stall      */               USB_ST_STALL,
+	/* DevNotResp */               USB_ST_NORESPONSE,
+	/* PIDCheck   */               USB_ST_BITSTUFF,
+	/* UnExpPID   */               USB_ST_BITSTUFF,
+	/* DataOver   */               USB_ST_DATAOVERRUN,
+	/* DataUnder  */               USB_ST_DATAUNDERRUN,
+	/* reservd    */               USB_ST_NORESPONSE,
+	/* reservd    */               USB_ST_NORESPONSE,
+	/* BufferOver */               USB_ST_BUFFEROVERRUN,
+	/* BuffUnder  */               USB_ST_BUFFERUNDERRUN,
+	/* Not Access */               USB_ST_NORESPONSE,
+	/* Not Access */               USB_ST_NORESPONSE 
+};
+
+#define		phc_name					"PHCI-HC"	
+#if 1
+#define		PHCI_UNLINK_TIMEOUT			(HZ / 10)
+#else
+#define		PHCI_UNLINK_TIMEOUT			(HZ)
+#endif
+#define		DRIVER_AUTHOR	"Linux kernel 2.4.5 usb-ohci.c modified for Philips Semiconductors"
+#define		DRIVER_DESC	"USB Philips ISP1362 Host Controller Driver"
+
+/* Trace functions */
+#ifdef DEBUG
+void 	print_int_ed_list(phci_t	*phci);
+#endif
+
+#ifdef __PHCI_DEBUG_DETAIL__
+static	void 	phci_print_map_buffers(__u8	index);
+static	void 	phci_print_ptd_header(__u8	*header, __u32	pipe);
+static	void 	phci_print_hex_data(__u8	*data, __u32	length);
+static	void 	phci_print_hc_regs(phci_t	*phci, __u8	buff_type);
+static 	void 	phci_urb_print (struct urb * urb, char * str, int small);
+#endif /* __detail_debug__ */
+
+/* HC Register accessing functions decleration */
+void 	fnvPhciHcorWrite	(phci_t 	*phci,__u32 	uReg, __u32 	uRegData);
+void 	fnvPhciHcorRead	(phci_t 	*phci,__u32 	uReg, __u32 	*puRegData);
+void 	phci_reg_read16	(__u32	uReg, __u32 	*puRegData);
+void 	phci_reg_write16	(__u32 	uReg, __u32 	uRegData);
+
+/* HC RAM accessing functions decleration */
+void	fnvPhciRamRead(phci_t	*phci, __u32	length, __u32	direction, __u32	addr, __u8	*byte_data);
+void	fnvPhciRamWrite(phci_t	*phci, __u32	length, __u32	direction, __u32	addr, __u8	*byte_data);
+
+/* HC Initialization functions decleration */
+static	__u32 	fnvPhciHostReset	(phci_t 	*phci);
+static	void 	fnvHcIntEnable	(phci_t 	*phci);
+static	void 	fnvHcControlInit	(phci_t 	*phci);
+static	void 	fnvHcInterruptInit	(phci_t 	*phci);
+static	void 	fnvHcFmIntervalInit	(phci_t 	*phci);
+static	void 	fnvHcRhPower	(phci_t 	*phci);
+static	int	 	fnuPhciHostInit	(phci_t 	*phci);
+static	void	fnvHcRamBufferInit( phci_t	*phci) ;
+static	phci_t * __devinit 	hc_alloc_phci (struct isp1362_dev *dev);
+int __devinit 		hc_found_phci (struct isp1362_dev *dev) ;
+void 	hc_release_phci (phci_t * phci);
+
+/* HC Interrupt Functions */
+void 	phci_isr(struct isp1362_dev *dev, void *isr_data);
+
+static void 	fnvProcessAtlInt(phci_t	*phci);
+static void 	fnvProcessIntlInt(phci_t	*phci);
+static void 	fnvProcessIstlInt(phci_t	*phci);
+
+/* TD-PTD map function declerations */
+static	void 	phci_init_map_buffers(phci_t	*phci) ;
+static	void 	phci_get_td_ptd_index(ed_t	*ed);
+static	void 	phci_release_td_ptd_index(ed_t		*ed);
+static	void phci_move_pending_td_ptds(td_ptd_map_buff_t   *ptd_map_buff);
+static	void 	phci_fill_send_ptd(phci_t	*phci, __u32	send_ptd_bitmap,td_ptd_map_buff_t *ptd_map_buff);
+static	void 	phci_fill_send_isoc_ptd(phci_t	*phci, __u32	send_ptd_bitmap,td_ptd_map_buff_t *ptd_map_buff);
+static	void 	phci_submit_ed(phci_t	*phci,	ed_t	*ed) ;
+
+
+
+/* TD functions decleration */
+static 	void 	td_fill (unsigned int info, void * data, int len, struct urb * urb, int index);
+static 	void 	td_submit_urb (struct urb * urb);
+
+/* EP handling functions */
+static int 		ep_int_ballance (phci_t * phci, int interval, int load);
+static int 		ep_2_n_interval (int inter);
+static int 		ep_rev (int num_bits, int word);
+static int 		ep_link (phci_t * phci, ed_t * edi);
+static int 		ep_unlink (phci_t * phci, ed_t * ed);
+static void	 	ep_rm_ed (struct usb_device * usb_dev, ed_t * ed);
+static ed_t*	ep_add_ed (struct usb_device * usb_dev, unsigned int pipe, int interval, int load);
+
+/* Done List handling functions */
+static void 	dl_transfer_length(td_t * td);
+static void 	dl_del_urb (phci_t * phci, struct urb * urb);
+static void 	dl_del_list (phci_t  * phci, unsigned int frame);
+static td_t * 	dl_reverse_done_list (phci_t * phci, td_t *td_list);
+static void 	dl_done_list (phci_t * phci, td_t * td_list);
+
+/* Root Hub function declerations */
+int 			rh_send_irq (phci_t * phci, void * rh_data, int rh_len);
+static void 	rh_int_timer_do (unsigned long ptr);
+static int 		rh_init_int_timer (struct urb * urb);
+static int 		rh_submit_urb (struct urb * urb);
+static int 		rh_unlink_urb (struct urb * urb);
+
+/* URB support functions */
+
+static void phci_complete_add(struct phci *phci, struct urb *urb);
+static struct urb *phci_complete_get(struct phci *phci);
+static void phci_complete(struct phci *phci);
+
+static void 	urb_free_priv( struct phci	*hc, urb_priv_t	*urb_priv);
+static void 	urb_rm_priv_locked (struct urb	*urb);
+
+/* USB core (usb.c) interface functions */
+static int 		sphci_alloc_dev (struct usb_device *usb_dev);
+static int 		sphci_free_dev (struct usb_device *usb_dev);
+static int 		sphci_get_current_frame_number (struct usb_device *usb_dev);
+static int 		sphci_return_urb (struct phci *hc, struct urb * urb);
+static int 		sphci_submit_urb (struct urb	*urb);
+static int 		sphci_unlink_urb (struct urb	*urb);
+
+#ifdef CONFIG_USB_HCDC_OTG
+/* otg function declerations for OTG driver interface */
+int		phci_register_otg(phci_otg_data_t	*otg_data);
+void	phci_unregister_otg(phci_otg_data_t	*otg_data);
+void	phci_otg_port_control(void *priv, __u8	cmd, __u32 *data);
+#endif /* CONFIG_USB_HCDC_OTG */
+
+/* Global Variable decleration */
+static td_ptd_map_buff_t	td_ptd_map_buff[TD_PTD_TOTAL_BUFF_TYPES];	/* td-ptd map buffer for all 1362 buffers */
+static	__u8				td_ptd_pipe_x_buff_type[PIPE_BULK+1] = {	/* Pipe vs buffer type data structure */
+								TD_PTD_BUFF_TYPE_ISTL0, 					/* ISOC for ISTL0 */
+								TD_PTD_BUFF_TYPE_INTL,					/* INT	for INTL */
+								TD_PTD_BUFF_TYPE_ATL,					/* CONTROL for ATL */
+								TD_PTD_BUFF_TYPE_ATL					/* BULK for ATL */
+};
+static	__u8				atl_active_ptd_X_threshold_ptd[17] = {0,1,2,2,3,3,4,5,6,6,7,8,9,9,10,11,12};
+
+
+/*--------------------------------------------------------------*
+ * Host Controller operational registers write
+ *--------------------------------------------------------------*/
+void fnvPhciHcorWrite(phci_t *phci,__u32 uReg, __u32 uRegData) {
+
+	__u32	uData;
+
+	detail_debug(("fnvPhciHcorWrite(phci = 0x%p, uReg = 0x%x, uRegData = 0x%x)\n",phci, uReg, uRegData))
+
+	/* Check if the registers are controlled by software */
+	if ((uReg == uHcHcdControl ) || (uReg == (uHcHcdControl | 0x80))) {
+		phci->uHcHcdControl_hcd = uRegData;
+		return;
+	}
+
+	if ((uReg == uHcHcdCommandStatus) || (uReg == (uHcHcdCommandStatus | 0x80))) {
+		phci->uHcHcdCommandStatus_hcd = uRegData;
+		return;
+	}
+
+#ifdef CONFIG_USB_HCDC_OTG
+
+	/* In OTG mode, clear the internal connect status change bit */
+	if((uReg == (uHcRhPort1Status+OTG_HC_PORT_NO)) || (uReg == ((uHcRhPort1Status+OTG_HC_PORT_NO)|0x80))) {
+		if(uRegData & RH_PS_CSC) phci->otg_port_status &= ~(RH_PS_CSC);
+	}
+
+#endif /* CONFIG_USB_HCDC_OTG */
+
+
+	isp1362_command((uReg|0x80), isp1362_device);
+	uData = uRegData & 0x0000FFFF;
+	isp1362_write16(uData,isp1362_device);
+	uData = (uRegData & 0xFFFF0000) >> 16;
+	isp1362_write16(uData,isp1362_device);
+
+} /* fnvPhciHcorWrite() */
+
+
+/*--------------------------------------------------------------*
+ * Host Controller operational registers read
+ *--------------------------------------------------------------*/
+void fnvPhciHcorRead(phci_t *phci,__u32 uReg, __u32 *puRegData) {
+
+	__u32	uData;
+
+	detail_debug(("fnvPhciHcorRead(phci = 0x%p, uReg = 0x%x, puRegData = 0x%p)\n",phci, uReg, puRegData))
+
+	/* Service the HCD HC transfer control registers first */
+	if (uReg == uHcHcdControl ) {
+		*puRegData = phci->uHcHcdControl_hcd;
+		return;
+	}
+
+	if (uReg == uHcHcdCommandStatus) {
+		*puRegData = phci->uHcHcdCommandStatus_hcd;
+		return;
+	}
+
+	isp1362_command(uReg, isp1362_device);
+	uData = isp1362_read16(isp1362_device);
+	*puRegData = uData & 0x0000FFFF;
+	uData = isp1362_read16(isp1362_device);
+	*puRegData |= (uData & 0x0000FFFF) << 16;
+
+#ifdef CONFIG_USB_HCDC_OTG
+
+	/* In OTG mode mask the Connect status, connect status change bits from HC and give
+	 * internal values which are controlled by OTG module */
+
+	if(uReg == (uHcRhPort1Status+OTG_HC_PORT_NO)) {
+		*puRegData &= ~(RH_PS_CSC|RH_PS_CCS);
+		*puRegData |= (phci->otg_port_status & (RH_PS_CSC|RH_PS_CCS));
+	}
+
+#endif /* CONFIG_USB_HCDC_OTG */
+
+} /* fnvPhciHcorRead() */
+
+
+/*--------------------------------------------------------------*
+ * Host Controller registers read
+ *--------------------------------------------------------------*/
+void phci_reg_read16(__u32 uReg, __u32 *puRegData) {
+
+	__u32	uData;
+
+	detail_debug(("phci_reg_read16(uReg = 0x%x, puRegData = 0x%p)\n",uReg, puRegData))
+
+	isp1362_command(uReg,isp1362_device);
+	uData = isp1362_read16(isp1362_device);
+	*puRegData = uData;
+
+} /* phci_reg_read16() */
+
+
+/*--------------------------------------------------------------*
+ * Host Controller registers write
+ *--------------------------------------------------------------*/
+void phci_reg_write16(__u32 uReg, __u32 uRegData) {
+
+	detail_debug(("phci_reg_write16(uReg = 0x%x, uRegData = 0x%x)\n",uReg, uRegData))
+
+	isp1362_command((uReg|0x80), isp1362_device);
+	isp1362_write16(uRegData, isp1362_device);
+
+} /* phci_reg_write16() */
+
+
+
+/*--------------------------------------------------------------*
+ * Host Controller registers read 32 bit 
+ *--------------------------------------------------------------*/
+void phci_reg_read32(__u32 uReg, __u32 *puRegData) {
+
+	__u32	uData;
+
+	detail_debug(("phci_reg_read32(uReg = 0x%x, puRegData = 0x%p)\n",uReg, puRegData))
+
+	isp1362_command(uReg, isp1362_device);
+	uData = isp1362_read16(isp1362_device);
+	*puRegData = uData & 0x0000FFFF;
+	uData = isp1362_read16(isp1362_device);
+	*puRegData |= (uData & 0x0000FFFF) << 16;
+
+} /* phci_reg_read32() */
+
+
+/*--------------------------------------------------------------*
+ * Host Controller registers write 32 bit 
+ *--------------------------------------------------------------*/
+void phci_reg_write32(__u32 uReg, __u32 uRegData) {
+
+    __u32 	uData;
+
+	detail_debug(("phci_reg_write32(uReg = 0x%x, uRegData = 0x%x)\n",uReg, uRegData))
+    
+	isp1362_command((uReg|0x80), isp1362_device);
+	uData = uRegData & 0x0000FFFF;
+	isp1362_write16(uData,isp1362_device);
+	uData = (uRegData & 0xFFFF0000) >> 16;
+	isp1362_write16(uData,isp1362_device);
+	
+} /* phci_reg_write32() */
+
+#ifdef CONFIG_USB_PHCD_DMA
+void	fnvPhciRamWrite(phci_t	*phci, __u32	length, __u32	direction, __u32	addr, __u8	*byte_data) {
+
+	__u32		direct_addr_len;
+	__u16		dma_cnfg = 0;
+	__u32		int_reg;
+	unsigned int	flags;
+	__u32		original_length;
+
+	detail_debug(("fnvPhciRamWrite(length = %d, direction = %d, addr = 0x%x, byte_data = 0x%p)\n",length, direction, addr, byte_data))
+
+	if(!length || !byte_data) return;				/* If there is nothing to write , return back */
+
+	original_length = length;
+
+	if(length & 0x01)	length++;			/* Align length to even number */
+
+	/* fill the direct address length register with len+dir+addr */
+	direct_addr_len = addr & 0x7FFF;
+	direct_addr_len |= direction;
+	direct_addr_len |= (length << 16);
+
+	phci_reg_write32(REG_DIRECT_ADDR_LEN  ,direct_addr_len);  // writing the direct address length 
+
+	memcpy(phci->dma_buff, byte_data, original_length);
+
+	dma_cnfg = (DMA_BUFF_TYPE_DIR_ADDR | DMA_1CYCLE_BURST_LEN | DMA_COUNTER_ENABLE);	/* Disable DMA */
+	phci_reg_write16(REG_DMA_CNFG, dma_cnfg);
+
+	/* Clear EOT bit inthe interrupt register */
+	phci_reg_write16(REG_IRQ, EOT_INT);
+
+	save_flags(flags);
+	disable_dma(DMA4HC_CHNNL);
+	clear_dma_ff(DMA4HC_CHNNL);
+	set_dma_mode(DMA4HC_CHNNL,DMA_MODE_WRITE);
+	set_dma_addr(DMA4HC_CHNNL,virt_to_bus(phci->dma_buff));
+	set_dma_count(DMA4HC_CHNNL, length);
+
+	/* Enable PC DMA */
+	enable_dma(DMA4HC_CHNNL);
+	restore_flags(flags);
+
+	dma_cnfg |= (DMA_ENABLE | DMA_WRITE_SELECT) ;
+
+	/* Enable HC DMA */
+	phci_reg_write16(REG_DMA_CNFG, dma_cnfg);
+	
+	/* wait for End of transfer */
+	do {
+		isp1362_udelay(1);
+		phci_reg_read16(REG_IRQ, &int_reg);
+	} while(!(int_reg&EOT_INT));
+
+	/* Disable HC dma */
+	dma_cnfg &= ~(DMA_ENABLE | DMA_WRITE_SELECT) ;
+	phci_reg_write16(REG_DMA_CNFG, dma_cnfg);
+
+	return;
+}
+
+void	fnvPhciRamRead(phci_t	*phci, __u32	length, __u32	direction, __u32	addr, __u8	*byte_data) {
+
+	__u32		direct_addr_len;
+	__u16		dma_cnfg = 0;
+	__u32		int_reg;
+	unsigned int	flags;
+	__u32		original_length;
+
+	detail_debug(("fnvPhciRamRead(length = %d, direction = %d, addr = 0x%x, byte_data = 0x%p)\n",length, direction, addr, byte_data))
+
+	if(!length || !byte_data) return;				/* If there is nothing to write , return back */
+
+	original_length = length;
+
+	if(length & 0x01)	length++;			/* Align length to even number */
+
+	/* fill the direct address length register with len+dir+addr */
+	direct_addr_len = addr & 0x7FFF;
+	direct_addr_len |= direction;
+	direct_addr_len |= (length << 16);
+
+	phci_reg_write32(REG_DIRECT_ADDR_LEN  ,direct_addr_len);  // writing the direct address length 
+
+
+	dma_cnfg = (DMA_BUFF_TYPE_DIR_ADDR | DMA_1CYCLE_BURST_LEN | DMA_COUNTER_ENABLE);	/* Disable DMA */
+	phci_reg_write16(REG_DMA_CNFG, dma_cnfg);
+
+	/* Clear EOT bit inthe interrupt register */
+	phci_reg_write16(REG_IRQ, EOT_INT);
+
+	save_flags(flags);
+	disable_dma(DMA4HC_CHNNL);
+	clear_dma_ff(DMA4HC_CHNNL);
+	set_dma_mode(DMA4HC_CHNNL,DMA_MODE_READ);
+	set_dma_addr(DMA4HC_CHNNL,virt_to_bus(phci->dma_buff));
+	set_dma_count(DMA4HC_CHNNL, length);
+
+	/* Enable PC DMA */
+	enable_dma(DMA4HC_CHNNL);
+	restore_flags(flags);
+
+	dma_cnfg |= (DMA_ENABLE) ;
+
+	/* Enable HC DMA */
+	phci_reg_write16(REG_DMA_CNFG, dma_cnfg);
+
+	/* wait for End of transfer */
+	do {
+		isp1362_udelay(1);
+		phci_reg_read16(REG_IRQ, &int_reg);
+	} while(!(int_reg&EOT_INT));
+
+	/* Disable HC dma */
+	dma_cnfg &= ~(DMA_ENABLE) ;
+	phci_reg_write16(REG_DMA_CNFG, dma_cnfg);
+
+	memcpy(byte_data, phci->dma_buff, original_length);
+
+	return;
+}
+
+
+#else /* CONFIG_USB_PHCD_DMA */
+
+/*--------------------------------------------------------------*
+ * Host Controller ATL/INTL/ISTL buffer Write
+ *--------------------------------------------------------------*/
+void	fnvPhciRamWrite(phci_t	*phci, __u32	length, __u32	direction, __u32	addr, __u8	*byte_data) {
+
+	__u32		direct_addr_len, cnt;
+	__u16		lower_dword, higher_dword = 0;
+	__u32		*dword_buff = (__u32*)byte_data;
+	__u32		original_length, rem_length;
+
+	detail_debug(("fnvPhciRamWrite(length = %d, direction = %d, addr = 0x%x, byte_data = 0x%p)\n",length, direction, addr, byte_data))
+
+	if(!length || !byte_data) return;				/* If there is nothing to write , return back */
+
+	original_length = length;
+
+	rem_length = (length & (RAM_BUFF_ALIGNMENT-1));		/* 0, 1, 2, 3 */
+
+	/* Make length to RAM_BUFF_ALIGNMENT byte boundary */
+	while(length & (RAM_BUFF_ALIGNMENT-1)){
+		length++;
+	}
+
+	/* fill the direct address length register with len+dir+addr */
+	direct_addr_len = addr & 0x7FFF;
+	direct_addr_len |= direction;
+	direct_addr_len |= (length << 16);
+
+	phci_reg_write32(REG_DIRECT_ADDR_LEN  ,direct_addr_len);  // writing the direct address length 
+
+
+   	/* Receive data from direct address register on the data IO */
+	isp1362_command((REG_DIRECT_ADDR_DATA|0x80), isp1362_device);
+
+	length = original_length;
+
+	if(direction == HC_DIR_ADDR_INCREMENT) {
+		length >>= 2;								/* total number of double words = length/4 */
+		cnt = 0;
+		while( cnt < length) {
+#if 0 /* debug sakugawa */
+			lower_dword = dword_buff[cnt];			/* convert dword to 2 words */
+			higher_dword = (dword_buff[cnt++] >> 16);
+			isp1362_write16(lower_dword,isp1362_device);
+			isp1362_write16(higher_dword,isp1362_device);
+#else
+			lower_dword = dword_buff[cnt];			/* convert dword to 2 words */
+			higher_dword = (dword_buff[cnt++] >> 16);
+			isp1362_write16(cpu_to_le16(higher_dword),isp1362_device);
+			isp1362_write16(cpu_to_le16(lower_dword),isp1362_device);
+#endif
+
+		}
+		
+#if 0 /* NSS Debug */
+		if(rem_length) {
+			length <<= 2;
+			lower_dword = byte_data[length];
+
+#if 0 /* debug sakugawa */
+			if(rem_length > 1) lower_dword |= (byte_data[length+1] << 8);
+			if(rem_length > 2) higher_dword = byte_data[length+2];
+			isp1362_write16(lower_dword,isp1362_device);
+			isp1362_write16(higher_dword,isp1362_device);
+#else
+			/* atomawasi */
+			if(rem_length > 1) higher_dword |= (byte_data[length+1] << 8);
+			if(rem_length > 2) lower_dword = byte_data[length+2];
+			isp1362_write16(le16_to_cpu(lower_dword),isp1362_device);
+			isp1362_write16(le16_to_cpu(higher_dword),isp1362_device);
+#endif
+		}
+#else
+		if(rem_length) {
+			higher_dword = 0;
+			lower_dword = 0;
+
+			length <<= 2;
+			lower_dword = byte_data[length];
+
+			if(rem_length > 1) lower_dword |= (byte_data[length+1] << 8);
+			if(rem_length > 2) higher_dword = byte_data[length+2];
+			isp1362_write16(lower_dword,isp1362_device);
+			isp1362_write16(higher_dword,isp1362_device);
+		}
+#endif
+	}
+	return;
+} /* End of fnvPhciRamWrite */
+
+/*--------------------------------------------------------------*
+ * Host Controller ATL/INTL/ISTL buffer Read
+ *--------------------------------------------------------------*/
+void	fnvPhciRamRead(phci_t	*phci, __u32	length, __u32	direction, __u32	addr, __u8	*byte_data) {
+
+	__u32		direct_addr_len, cnt;
+	__u16		lower_dword, higher_dword;
+	__u32		*dword_buff = (__u32*)byte_data;
+	__u32		original_length, rem_length, dword;
+
+
+
+	if(!length || !byte_data) return;				/* If there is nothing to read, return back */
+
+	original_length = length;
+
+	rem_length = (length & (RAM_BUFF_ALIGNMENT-1));		/* 0, 1, 2, 3 */
+
+	/* Make length to RAM_BUFF_ALIGNMENT byte boundary */
+	while(length & (RAM_BUFF_ALIGNMENT-1)){
+		length++;
+	}
+//	ALIGN_RAM_BUFF_LENGTH(length);
+
+	/* fill the direct address length register with len+dir+addr */
+	direct_addr_len = addr & 0x7FFF;
+	direct_addr_len |= direction;
+	direct_addr_len |= (length << 16);
+
+	phci_reg_write32(REG_DIRECT_ADDR_LEN  ,direct_addr_len);  // writing the direct address length 
+
+
+   	/* Receive data from direct address register on the data IO */
+	isp1362_command(REG_DIRECT_ADDR_DATA, isp1362_device);
+
+	length = original_length;
+
+	if(direction == HC_DIR_ADDR_INCREMENT) {
+		length >>= 2;								/* total number of double words = length/4 */
+		cnt = 0;
+		while( cnt < length) {
+#if 0 /* debug sakugawa */
+
+			lower_dword = isp1362_read16(isp1362_device);
+			higher_dword = isp1362_read16(isp1362_device);
+
+		    dword_buff[cnt++] = lower_dword | (higher_dword << 16) ;	/* Combine lower and higher 16 bits and fill buffer */
+#else
+			lower_dword = isp1362_read16(isp1362_device);
+			higher_dword = isp1362_read16(isp1362_device);
+			dword_buff[cnt++] = le16_to_cpu(higher_dword) | (le16_to_cpu(lower_dword) <<16);
+#endif
+
+		}
+		
+		if(rem_length) {
+			length <<= 2;
+#if 0 /* debug sakugawa */	
+
+			lower_dword = isp1362_read16(isp1362_device);
+			higher_dword = isp1362_read16(isp1362_device);
+			
+			dword = lower_dword | (higher_dword << 16) ;	/* make the 32 bit double word */
+#else
+
+			lower_dword = isp1362_read16(isp1362_device);
+			higher_dword = isp1362_read16(isp1362_device);
+			dword = le16_to_cpu(higher_dword) | (le16_to_cpu(lower_dword) <<16);	
+#endif
+
+#if 0
+			byte_data[length] = (dword & 0xFF);		/* Copy the first remaining byte */
+#else
+			byte_data[length] = (dword & 0xFF000000) >> 24;		/* Copy the first remaining byte */
+#endif
+			cnt = 1;
+
+#if 0 
+			while(cnt < rem_length) {			/* Based on reming bytes copy the 2nd, 3rd bytes */
+				dword >>= 8;
+				byte_data[length+cnt] = (dword & 0xFF);
+				cnt++;
+			}
+#else
+			while(cnt < rem_length) {			/* Based on reming bytes copy the 2nd, 3rd bytes */
+				dword <<= 8;
+				byte_data[length+cnt] = (dword & 0xFF000000) >> 24;
+				cnt++;
+			}
+#endif
+		}
+	}
+	return;
+} /* End of fnvPhciRamRead */
+
+#endif /* CONFIG_USB_PHCD_DMA */
+
+/*--------------------------------------------------------------*
+ * Host Controller Ram buffer parameter initialization
+ *--------------------------------------------------------------*/
+void	fnvHcRamBufferInit( phci_t	*phci) {
+
+	__u8		ram_data[1024];
+	int		i;
+	__u32	data = 0;
+
+
+	/* Configure ISTL buffer */
+	phci_reg_write16(REG_ISTL_BUFF_LEN, HC_ISTL_BUFFER_LENGTH);			/* Istl buffer length */
+	phci_reg_write16(REG_ISTL_TOGGLE_RATE, HC_ISTL_DEF_TOGGLE_RATE);	/* Istl toggle rate */
+
+	/* Configure INTL buffer */
+	phci_reg_write16(REG_INTL_BUFF_LEN, HC_INTL_BUFFER_LENGTH);			/* Intl buffer length */
+	phci_reg_write16(REG_INTL_BLK_PL_SIZE, HC_INTL_BLK_PL_SIZE);		/* Intl payload block size */
+
+	/* Configure ATL buffer */
+	phci_reg_write16(REG_ATL_BUFF_LEN, HC_ATL_BUFFER_LENGTH);			/* Atl buffer length */
+	phci_reg_write16(REG_ATL_BLK_PL_SIZE, HC_ATL_BLK_PL_SIZE);			/* Atl payload block size */
+
+	data = 0x0001 << (TD_PTD_MAX_ATL_TDS);
+	phci_reg_write32(REG_ATL_PTD_LAST_PTD,data);						/* Set the last ATL ptd in HC */
+
+	data = (0x0001 << (TD_PTD_MAX_INTL_TDS));
+	phci_reg_write32(REG_INTL_PTD_LAST_PTD,data);						/* Update the last INTL ptd in HC */
+
+	phci_reg_write16(REG_ATL_THRESHOLD_TIMEOUT,HC_DEF_ATL_THRESHOLD_TIMEOUT);	/* set the atl threshold ptd timeout HC */
+
+
+	phci_reg_write32(REG_ATL_PTD_SKIP_MAP,0xFFFFFFFF);					/* Set all ptds to skip */
+	phci_reg_write32(REG_INTL_PTD_SKIP_MAP,0xFFFFFFFF);					/* Set all ptds to skip */
+	
+	
+	/* Initialize the RAM buffer with zeros */
+	for(i=0;i<1024;i++) { ram_data[i] = 0; }
+	for(i=0; i<(HC_RAM_SIZE/1024);i++) {
+		fnvPhciRamWrite( phci, 1024, HC_DIR_ADDR_INCREMENT, i*1024, ram_data);
+	}
+
+	return;
+} /* End of fnvHcRamBufferInit */
+
+/*--------------------------------------------------------------*
+ * Host Controller Initialization functions 
+ *--------------------------------------------------------------*/
+/*--------------------------------------------------------------*
+ * Host Controller Reset
+ *--------------------------------------------------------------*/
+__u32 fnvPhciHostReset(phci_t *phci) {
+
+	__u32 uData;
+	__u32 uI;
+	__u32 uRetVal;
+
+	func_debug(("fnuHostReset(phci = 0x%p)\n",phci))
+
+	/* Set the HostController Reset bit in command status register */
+ 	fnvPhciHcorRead(phci,uHcCommandStatus,&uData);
+
+ 	uData = HC_COMMAND_STATUS_HCR;
+
+ 	fnvPhciHcorWrite(phci,uHcCommandStatus, uData);
+
+	/* wait some time for HC to be reset */
+ 	for(uI=0;uI<5000;uI++) {
+  		fnvPhciHcorRead(phci,uHcCommandStatus,&uData);
+  		if((uData & HC_COMMAND_STATUS_HCR) == 0) break;
+ 	}
+
+ 	uRetVal = uData & HC_COMMAND_STATUS_HCR;
+
+ return uRetVal;
+
+} /* End of fnvPhciHostReset */
+
+/*--------------------------------------------------------------*
+ * Host Controller hardware Interrupt Initialization
+ *--------------------------------------------------------------*/
+void fnvHcIntEnable(phci_t *phci) {
+
+	__u32		uData;
+
+	func_debug(("fnvHcIntEnable(phci = 0x%p)\n",phci))
+
+	/* Clear all pending int. source */
+	uData = 0xFFFFFFFF;
+	phci_reg_write16(REG_IRQ, uData);
+
+	/* Enable int. according settings in host_conf.h */
+	uData = 0;			/* All int. are initially disabled */
+
+	uData |= ATL_INT;	/* Enable ATL interrupt */
+
+//	uData |= SOF_INT;	/* Enable ATL interrupt */
+
+	uData |= INTL_INT;	/* Enable INTL interrupt */
+
+	uData |= ISTL_0_INT;	/* Enable ITL interrupt */
+
+	uData |= ISTL_1_INT;	/* Enable ITL interrupt */
+
+	phci_reg_write16(REG_IRQ_MASK, uData);
+
+} /* End of fnvHcIntEnable() */
+
+/*--------------------------------------------------------------*
+ * Host Controller Control Register Initialization
+ *--------------------------------------------------------------*/
+void fnvHcControlInit(phci_t *phci) {
+
+	__u32 uData;
+	__u32 uHostConfigData;
+
+	func_debug(("fnvHcControlInit(phci = 0x%p)\n",phci))
+
+	uHostConfigData = 0;
+
+	/* Fill the control register of HC */
+	/* (1) Set the sate to operational */
+	uData = HC_STATE;
+	uHostConfigData &= (~HC_CONTROL_HCFS);
+	uHostConfigData |= (uData << 6);
+
+	/* (2)  Enable remote wakeup connection if opted */
+	uData = REMOTE_WAKEUP_CONN;
+	uHostConfigData &= (~HC_CONTROL_RWC);
+	if (uData == YES)
+		uHostConfigData |= HC_CONTROL_RWC;
+
+	/* (3)  Enable remote wakeup if opted */
+	uData = REMOTE_WAKEUP_ENABLE;
+	uHostConfigData &= (~HC_CONTROL_RWE);
+	if (uData == YES)
+		uHostConfigData |= HC_CONTROL_RWE;
+
+	fnvPhciHcorWrite(phci,uHcControl, uHostConfigData);
+
+
+	/* Configure the HCD transfer control registers uHcHcdControl and uHcHcdCommandStatus */
+	uHostConfigData = 0;			
+	uData = PERIODIC_LIST_ENABLE;				/* Periodic list Enable ? */
+	if (uData == YES)
+		uHostConfigData |= HC_CONTROL_PLE;
+
+	uData = ISO_ENABLE;							/* Isochronous transfer enabled  ? */
+	if (uData == YES)
+		uHostConfigData |= HC_CONTROL_IE;
+
+	uData = CONTROL_LIST_ENABLE;				/* Control trasnfer enabled ? */
+	if (uData == YES)
+		uHostConfigData |= HC_CONTROL_CLE;
+
+	uData = BULK_LIST_ENABLE;					/* Bulk Transfer Enabled ? */
+	if (uData == YES)
+		uHostConfigData |= HC_CONTROL_BLE;
+
+	/* Note: HC_CONTROL_TIP (Transfer In Progress) is alreday set to 0 */
+	phci->hc_control = (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_PLE | OHCI_USB_OPER ;
+
+	fnvPhciHcorWrite(phci,uHcHcdControl, uHostConfigData);
+
+} /* End of fnvHcControlInit() */
+
+/*--------------------------------------------------------------*
+ * Host Controller Interrupt Register Initialization
+ *--------------------------------------------------------------*/
+void fnvHcInterruptInit(phci_t *phci) {
+
+	__u32 uHostConfigData;
+
+	func_debug(("fnvHcInterruptInit(phci = 0x%p)\n",phci))
+
+	/* First of all, disable all interrupts */
+	uHostConfigData = HC_INTERRUPT_ALL;
+	fnvPhciHcorWrite(phci,uHcInterruptDisable, uHostConfigData);
+
+	uHostConfigData = 0;
+
+	/* Master Interrupt Enable */
+	uHostConfigData |= HC_INTERRUPT_MIE;
+
+	/* Write the configuration to uHcInterruptEnable register */
+	fnvPhciHcorWrite(phci,uHcInterruptEnable, uHostConfigData);
+
+
+} /* End of fnvHcInterruptInit() */
+
+/*--------------------------------------------------------------*
+ * Host Controller Frame Number interval Initialization
+ *--------------------------------------------------------------*/
+void fnvHcFmIntervalInit(phci_t *phci) {
+
+	__u32 uHostConfigData;
+
+	func_debug(("fnvHcFmIntervalInit(phci = 0x%p)\n",phci))
+
+	/* Determine the fram interval and the largest data size */
+	uHostConfigData = FRAME_INTERVAL | (FS_LARGEST_DATA << 16);
+
+	/* Write the configuration to uHcFmInterval register */
+	fnvPhciHcorWrite(phci,uHcFmInterval, uHostConfigData);
+
+} /* End of fnvHcFmIntervalInit() */
+
+
+/*--------------------------------------------------------------*
+ * Host Controller Roothub registers Initialization
+ *--------------------------------------------------------------*/
+void fnvHcRhPower(phci_t *phci) {
+
+	__u32 uData;
+	__u32 uHostConfigData;
+
+	func_debug(("fnvHcRhPower(phci = 0x%p)\n",phci))
+
+	/* Initialize the configuration data */
+	uHostConfigData = 0;
+
+	/* Enable or disable power switching */
+	uData = PORT_POWER_SWITCHING;
+
+	if (uData == NO)	/* No power switching; ports are always powered on when the HC is powered on */
+		uHostConfigData |= HC_RH_DESCRIPTORA_NPS;
+
+	else {
+
+		/********************************************************/
+		/* Power switching is enabled                           */
+		/* Program root hub in per-port switching mode          */
+		/********************************************************/
+		uHostConfigData |= HC_RH_DESCRIPTORA_PSM;
+
+	} /* else */
+
+
+	/* Port over current protection */
+	uData = OVER_CURRENT_PROTECTION;
+	if (uData == NO)					/* No over current protection */
+		uHostConfigData |= HC_RH_DESCRIPTORA_NOCP;
+
+	else
+		uData = PER_PORT_OVER_CURRENT_REPORT;
+		if (uData == YES)
+			uHostConfigData |= HC_RH_DESCRIPTORA_OCPM;
+
+	/* Set the power on to power good time */
+	uHostConfigData |= ((POWER_ON_TO_POWER_GOOD_TIME / 2) << 24);			/* Divided by 2, then move it into position */
+
+	fnvPhciHcorWrite(phci,uHcRhDescriptorA, uHostConfigData);
+
+	/* Set the global power to all the ports */
+        uHostConfigData = RH_HS_LPSC;
+        fnvPhciHcorWrite(phci,uHcRhStatus, uHostConfigData);
+
+	/* Wait till the POWER ON TO POWER GOOD time */
+        isp1362_mdelay(POWER_ON_TO_POWER_GOOD_TIME);
+
+
+	/* Set the HcRhDescriptorB register (13h) */
+	uHostConfigData = DEVICE_REMOVABLE;
+
+	if (PORT_POWER_SWITCHING == YES)
+		uHostConfigData |= 0xFFFF0000;		/* Set PPCM bits 31..16 to disable gang-mode power switching */
+
+	fnvPhciHcorWrite(phci,uHcRhDescriptorB, uHostConfigData);
+
+} /* End of fnvHcRhPower() */
+
+
+/*--------------------------------------------------------------*
+ * Host Controller Initialization
+ *--------------------------------------------------------------*/
+int	 fnuPhciHostInit(phci_t	*phci) {
+
+	struct usb_device 	*usb_dev;
+
+	func_debug(("fnuPhciHostInit(phci = 0x%p)\n",phci))
+
+	/* 1. Host Controller Extended Registers Initialization */
+	isp1362_set_hw_config(phci->phci_dev);
+
+	fnvHcIntEnable(phci);
+
+	fnvHcRamBufferInit(phci);
+
+	phci_init_map_buffers(phci);
+
+	fnvHcControlInit(phci);			 	/* Initialize HcControl register */
+	
+	phci->disabled = 0;
+
+	fnvHcInterruptInit(phci);			/* Initialize HcInterruptEnable/Disable registers */
+
+	fnvHcFmIntervalInit(phci);			/* Initialize HcFmInterval Register */
+
+	fnvHcRhPower(phci);					/* Root hub port power switching mode */
+
+	phci->rh.devnum = 0;				/* No root hub yet */
+
+	phci->p_ed_controlhead = NULL;		/* Initialize control & bulk list heads */
+	phci->p_ed_bulkhead = NULL;
+
+#ifndef CONFIG_USB_HCDC_OTG
+	/* Select the port 1 to HC by writing the OTG Control register
+	 * HC_DC_SEL to HC */
+	phci_reg_write16(0x62,0x0601);	
+#endif /* CONFIG_USB_HCDC_OTG */
+
+	/* Allocate data structure for root hub */
+	usb_dev = usb_alloc_dev ( NULL, phci->bus) ;
+	
+	if( !usb_dev ) {
+		phci->disabled = 1;
+		return -ENOMEM;
+	}
+
+	phci->bus->root_hub = usb_dev;
+
+	/* Connect the virtual hub to the usb bus, host stack will do all the enumeration,
+	   configuration etc.. */
+	usb_connect (usb_dev); 
+
+	if(usb_new_device(usb_dev) != 0) {
+		usb_free_dev(usb_dev);
+		phci->disabled = 1;
+		return -ENODEV;
+	}
+
+	return 0;
+} /* End of fnuPhciHostInit() */
+
+
+
+/*--------------------------------------------------------------*
+ * HC  TD-PTD functions 										* 
+ *--------------------------------------------------------------*/
+
+static __u8		td_ptd_buff_type_max_ptds[TD_PTD_TOTAL_BUFF_TYPES] = {
+	TD_PTD_MAX_ATL_TDS,
+	TD_PTD_MAX_INTL_TDS,
+	TD_PTD_MAX_ISTL_TDS,
+	TD_PTD_MAX_ISTL_TDS
+};
+
+static __u8		hc_ram_buff_port_reg[TD_PTD_TOTAL_BUFF_TYPES] = {
+	REG_ATL_BUFF_PORT,
+	REG_INTL_BUFF_PORT,
+	REG_ISTL0_BUFF_PORT,
+	REG_ISTL1_BUFF_PORT
+};
+
+static __u16	hc_ram_buff_lengths[TD_PTD_TOTAL_BUFF_TYPES] = {
+	HC_ATL_BUFFER_LENGTH,
+	HC_INTL_BUFFER_LENGTH,
+	HC_ISTL_BUFFER_LENGTH,
+	HC_ISTL_BUFFER_LENGTH
+};
+
+static __u16	hc_ram_buff_block_pl_size[TD_PTD_TOTAL_BUFF_TYPES] = {
+	HC_ATL_BLK_PL_SIZE,
+	HC_INTL_BLK_PL_SIZE,
+	HC_ISTL_BLK_PL_SIZE,
+	HC_ISTL_BLK_PL_SIZE
+};
+
+static __u16	hc_ram_buff_address[TD_PTD_TOTAL_BUFF_TYPES] = {
+	HC_ATL_ADDRESS,
+	HC_INTL_ADDRESS,
+	HC_ISTL_0_ADDRESS,
+	HC_ISTL_1_ADDRESS
+};
+
+#ifdef __PHCI_DEBUG_DETAIL__
+
+/*--------------------------------------------------------------*
+ * HC TD-PTD map buffers print functions 						* 
+ *--------------------------------------------------------------*/
+void phci_print_map_buffers(__u8	index) {
+	__u8	index1;
+	td_ptd_map_buff_t	*ptd_map_buff;
+
+	ptd_map_buff = &(td_ptd_map_buff[index]);
+	printk("buffer:: %p, buffer type:: %d\n",ptd_map_buff, ptd_map_buff->buffer_type);
+	printk("\tbuffer active_ptds:: %d \n\tbuffer total_ptds:: %d\n",ptd_map_buff->active_ptds, ptd_map_buff->total_ptds);
+	printk("\tbuffer max_ptds:: %d \n\tbuffer active_ptd_bitmap:: %x\n",ptd_map_buff->max_ptds, ptd_map_buff->active_ptd_bitmap);
+	printk("\tbuffer skip_ptd_bitmap:: %x \n\tbuffer ram_buff_addr:: %x \n",ptd_map_buff->skip_ptd_bitmap, ptd_map_buff->ram_buff_addr);
+
+	printk("\tbuffer buffer_length:: %d \n\tbuffer buffer_port:: %d\n",ptd_map_buff->regs.buffer_length, ptd_map_buff->regs.buffer_port);
+	printk("\tbuffer block_pl_size:: %d \n\tbuffer toggle_rate:: %d\n",ptd_map_buff->regs.block_pl_size, ptd_map_buff->regs.toggle_rate);
+	printk("\tbuffer last_ptd:: %d \n\tbuffer ptd_done_map:: %x\n",ptd_map_buff->regs.last_ptd, ptd_map_buff->regs.ptd_done_map);
+	printk("\tbuffer ptd_skip_map:: %x \n\tbuffer curr_active_ptd:: %d\n",ptd_map_buff->regs.ptd_skip_map, ptd_map_buff->regs.curr_active_ptd);
+	printk("\tbuffer threshold_count:: %d \n\tbuffer threshold_timeout:: %d\n",ptd_map_buff->regs.threshold_count, ptd_map_buff->regs.threshold_timeout);
+
+	for(index1=0; index1<ptd_map_buff->max_ptds;index1++){
+		printk("td_ptd_map = %p\n", &(ptd_map_buff->map_list[index1]));
+		printk("\t\tbuffer state:: %d \n\t\tbuffer total_bytes:: %d\n",ptd_map_buff->map_list[index1].state, ptd_map_buff->map_list[index1].total_bytes);
+		printk("\t\tbuffer ptd_bitmap:: %x \n\t\tbuffer td:: %p\n",ptd_map_buff->map_list[index1].ptd_bitmap, ptd_map_buff->map_list[index1].td);
+	}
+
+} /* phci_print_map_buffers */
+
+/*--------------------------------------------------------------*
+ * print buffer data in hex format functions 					* 
+ *--------------------------------------------------------------*/
+void phci_print_hex_data(__u8	*data, __u32	length) {
+	__u32	index;
+
+	for(index = 0; index < length; index++) {
+		if(index%8 == 0) printk("\n");
+		printk(" 0x%2x  ", data[index]);
+	}
+	printk("\n");
+	
+	return;
+}
+
+/*--------------------------------------------------------------*
+ * HC TD-PTD map buffers print functions 						* 
+ *--------------------------------------------------------------*/
+void phci_print_ptd_header(__u8	*header, __u32	pipe) {
+	
+	__u16	data;
+	
+#ifdef CONFIG_USB_PHCD_EVEN_SCH
+	__u8	poll_int;
+#endif /* CONFIG_USB_PHCD_EVEN_SCH */
+
+	printk("  0x%x  0x%x  0x%x  0x%x  0x%x  0x%x  0x%x  0x%x\n",header[0],header[1],header[2],header[3],header[4],header[5],header[6],header[7]);
+
+	printk("PTD_HEADER for pipe :: %s\n", ((pipe==PIPE_CONTROL) ? "CONTROL" : ((pipe == PIPE_INTERRUPT) ? "INTERRUPT" : ((pipe == PIPE_BULK) ? "BULK" : "ISOCHRONOUS"))));
+	data = ((header[1] & 0x03) << 8);
+	data |= header[0];
+	printk("     Actual Bytes: %d\n", data);
+	data = header[1];
+	printk("     CC: 0x%x     %s     toggle: %d\n", ((data & 0xF0)>>4), (data&0x8) ? "ACTIVE" : "NOT ACTIVE", (data&0x4)>>2);
+	data = ((header[3] & 0x03) << 8);
+	data |= header[2];
+	printk("     Max Packet Size: %d\n", data);
+	data = header[3];
+	if(pipe == PIPE_ISOCHRONOUS) {
+		printk("     EN: %x     %s    %s\n", ((data & 0xF0)>>4), (data&0x8) ? "LAST PTD" : "", (data&0x4) ? "LOW SPEED" : "FULL SPEED");
+	} else {
+		printk("     EN: %x     %s\n", ((data & 0xF0)>>4), (data&0x4) ? "LOW SPEED" : "FULL SPEED");
+	}
+	data = ((header[5] & 0x03) << 8);
+	data |= header[4];
+	printk("     Total Bytes: %d\n", data);
+	data = header[5];
+	if(pipe == PIPE_INTERRUPT) {
+		printk("     Dir:: %s\n", ( ((data & 0xC) == 0) ? "SETUP" : (((data & 0xC) == 0x4) ? "OUT" : "IN")));
+		data = header[6];
+#ifdef CONFIG_USB_PHCD_EVEN_SCH
+		poll_int = ((header[6] & 0xE0) >> 5) ;
+		printk("     Addr: %d     poll interval = %d milli seconds, start fn# = %d\n", data & 0x7F, ((poll_int == 0) ? 1 : ( (poll_int == 2) ? 2 : ((poll_int == 4) ? 4 : ((poll_int == 6) ? 8 : ((poll_int == 8) ? 16 : 32))))), (header[7] & 0x1F));
+#else
+		printk("     Addr: %d     poll interval = %d milli seconds\n", data & 0x7F, ((header[7] == 0) ? 1 : ( (header[7] == 2) ? 2 : ((header[7] == 4) ? 4 : ((header[7] == 6) ? 8 : ((header[7] == 8) ? 16 : 32))))));
+#endif /* CONFIG_USB_PHCD_EVEN_SCH */
+	} else if( pipe == PIPE_ISOCHRONOUS) {
+		printk("     Dir:: %s\n", ( ((data & 0xC) == 0) ? "SETUP" : (((data & 0xC) == 0x4) ? "OUT" : "IN")));
+		data = header[6];
+		printk("     Addr: %d     fn = 0x%x\n", data & 0x7F, header[7]);
+	} else {
+		if(data & 0x80) {
+			printk("     PAIRED  %s  Dir:: %s\n", (data & 0x40) ? "PONG" : "PING", ( ((data & 0xC) == 0) ? "SETUP" : (((data & 0xC) == 0x4) ? "OUT" : "IN")));
+		} else {
+			printk("     NOT PAIRED     Dir:: %s\n", ( ((data & 0xC) == 0) ? "SETUP" : (((data & 0xC) == 0x4) ? "OUT" : "IN")));
+		}
+		data = header[6];
+		printk("     Addr: %d\n", data & 0x7F);
+	}
+
+} /* phci_print_ptd_header */
+
+void phci_print_hc_regs(phci_t	*phci, __u8	buff_type) {
+	__u32	data_read = 0;
+
+	if(buff_type ==  TD_PTD_BUFF_TYPE_ATL) {
+		phci_reg_read16(REG_BUFF_STS,&data_read);
+		printk("Buffer Status = %x", data_read);
+		data_read = 0;
+		phci_reg_read16(REG_IRQ_MASK, &data_read);
+		printk("  Irq_mask = %x\n", data_read);
+		data_read = 0;
+		phci_reg_read16(REG_ISTL_BUFF_LEN, &data_read);
+		printk("  Istl Buffer_len = %x", data_read);
+		data_read = 0;
+		phci_reg_read16(REG_INTL_BUFF_LEN, &data_read);
+		printk("  INTL Buffer_len = %x", data_read);
+		data_read = 0;
+		phci_reg_read16(REG_ATL_BUFF_LEN, &data_read);
+		printk(" Buffer_len = %x", data_read);
+		data_read = 0;
+		phci_reg_read16(REG_ATL_BLK_PL_SIZE, &data_read);
+		printk("  Block_pl_size = %x\n", data_read);
+		data_read = 0;
+		phci_reg_read16(REG_ATL_THRESHOLD_COUNT,&data_read);
+		printk("threshold_count = %x", data_read);
+		data_read = 0;
+		phci_reg_read16(REG_ATL_THRESHOLD_TIMEOUT,&data_read);
+		printk("  threshold_timeout = %x\n", data_read);
+		data_read = 0;
+		phci_reg_read32(REG_ATL_PTD_DONE_MAP, &data_read);
+		printk("done_map = %x", data_read);
+		data_read = 0;
+		phci_reg_read32(REG_ATL_PTD_SKIP_MAP, &data_read);
+		printk("  skip_map %x\n", data_read); 
+		data_read = 0;
+		phci_reg_read32(REG_ATL_PTD_LAST_PTD,&data_read);		
+		printk("last_ptd_map %x", data_read);
+		data_read = 0;
+		phci_reg_read16(REG_ATL_CURR_ACTIVE_PTD,&data_read);		
+		printk("  curr_act_ptd %x\n", data_read);
+	} else if(buff_type ==  TD_PTD_BUFF_TYPE_INTL) {
+		phci_reg_read16(REG_BUFF_STS,&data_read);
+		printk("Buffer Status = %x", data_read);
+		data_read = 0;
+		phci_reg_read16(REG_IRQ_MASK, &data_read);
+		printk("  Irq_mask = %x\n", data_read);
+		data_read = 0;
+		phci_reg_read16(REG_ISTL_BUFF_LEN, &data_read);
+		printk("  Istl Buffer_len = %x", data_read);
+		data_read = 0;
+		phci_reg_read16(REG_INTL_BUFF_LEN, &data_read);
+		printk("  INTL Buffer_len = %x", data_read);
+		data_read = 0;
+		phci_reg_read16(REG_ATL_BUFF_LEN, &data_read);
+		printk(" Buffer_len = %x", data_read);
+		data_read = 0;
+		phci_reg_read16(REG_INTL_BLK_PL_SIZE, &data_read);
+		printk("  Block_pl_size = %x\n", data_read);
+		data_read = 0;
+		phci_reg_read32(REG_INTL_PTD_DONE_MAP, &data_read);
+		printk("done_map = %x", data_read);
+		data_read = 0;
+		phci_reg_read32(REG_INTL_PTD_SKIP_MAP, &data_read);
+		printk("  skip_map %x\n", data_read);
+		data_read = 0;
+		phci_reg_read32(REG_INTL_PTD_LAST_PTD,&data_read);		
+		printk("last_ptd_map %x", data_read);
+	}
+}
+
+void phci_urb_print (struct urb * urb, char * str, int small) {
+	unsigned int pipe= urb->pipe;
+	
+	if (!urb->dev || !urb->dev->bus) {
+		printk("%s URB: no dev", str);
+		return;
+	}
+	
+	if (urb->status != 0)
+	printk("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,flags:%4x,len:%d/%d,stat:%d(%x)", 
+			str,
+		 	sphci_get_current_frame_number (urb->dev), 
+		 	usb_pipedevice (pipe),
+		 	usb_pipeendpoint (pipe), 
+		 	usb_pipeout (pipe)? 'O': 'I',
+		 	usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"):
+		 		(usb_pipecontrol (pipe)? "CTRL": "BULK"),
+		 	urb->transfer_flags, 
+		 	urb->actual_length, 
+		 	urb->transfer_buffer_length,
+		 	urb->status, urb->status);
+
+	if (!small) {
+		int i, len;
+
+		if (usb_pipecontrol (pipe)) {
+			printk (KERN_DEBUG __FILE__ ": cmd(8):");
+			for (i = 0; i < 8 ; i++) 
+				printk (" %02x", ((__u8 *) urb->setup_packet) [i]);
+			printk ("\n");
+		}
+		if (urb->transfer_buffer_length > 0 && urb->transfer_buffer) {
+			printk (KERN_DEBUG __FILE__ ": data(%d/%d):", 
+				urb->actual_length, 
+				urb->transfer_buffer_length);
+			len = usb_pipeout (pipe)? 
+						urb->transfer_buffer_length: urb->actual_length;
+			for (i = 0; i < 16 && i < len; i++) 
+				printk (" %02x", ((__u8 *) urb->transfer_buffer) [i]);
+			printk ("%s stat:%d\n", i < len? "...": "", urb->status);
+		}
+	} 
+}
+#endif /* __PHCI_DEBUG_DETAIL__ */
+
+
+/*--------------------------------------------------------------*
+ * HC TD-PTD map buffers initialization functions 			* 
+ *--------------------------------------------------------------*/
+void phci_init_map_buffers(phci_t	*phci) {
+
+	td_ptd_map_buff_t	*ptd_map_buff;
+	__u8				buff_type, ptd_index;
+	__u32				bitmap;
+
+	func_debug(("phci_init_map_buffers(phci = 0x%p)\n",phci))
+	
+	/* initialize for each buffer type */
+	for(buff_type = 0; buff_type < TD_PTD_TOTAL_BUFF_TYPES; buff_type++) {
+	
+		ptd_map_buff = &(td_ptd_map_buff[buff_type]);
+
+		ptd_map_buff->buffer_type = buff_type;					/* Set buffer type */
+
+#ifdef CONFIG_USB_PHCD_PING_PONG
+		ptd_map_buff->ping_pong_status = 0;							/* Set ping pong status to not in use */
+		ptd_map_buff->ping_ptd_index = TD_PTD_INV_PTD_INDEX;		/* ping ptd index is invalid index */
+		ptd_map_buff->pong_ptd_index = TD_PTD_INV_PTD_INDEX;		/* pong ptd index is invalid index */
+#endif /* CONFIG_USB_PHCD_PING_PONG */
+
+		ptd_map_buff->active_ptds = 0;								/* active td's = 0 */
+		ptd_map_buff->total_ptds = 0;								/* total td's = 0 */
+		ptd_map_buff->max_ptds = td_ptd_buff_type_max_ptds[buff_type];	/* set maximum ptds for this buffer type */
+		ptd_map_buff->active_ptd_bitmap = 0;						/* no active ptds */
+		ptd_map_buff->skip_ptd_bitmap = 0xFFFFFFFF;					/* Skip all ptds */
+		ptd_map_buff->pending_ptd_bitmap = 0x00000000;				/* Initially no pending ptds */
+
+		bitmap = 0x00000001;
+
+		for(ptd_index = 0; ptd_index < ptd_map_buff->max_ptds; ptd_index++) {
+			ptd_map_buff->active_ptd_bitmask |= bitmap;
+			bitmap <<= 1;
+		}
+		
+		ptd_map_buff->ram_buff_addr = hc_ram_buff_address[buff_type];		/* Buffer lengths for each buffer */
+		ptd_map_buff->done_head = NULL;										/* No done ptd's */
+		ptd_map_buff->frame_number = INVALID_FRAME_NUMBER;					/* Invalid frame number */
+		
+		ptd_map_buff->regs.buffer_length = hc_ram_buff_lengths[buff_type];			/* Buffer lengths for each buffer */
+		ptd_map_buff->regs.buffer_port = hc_ram_buff_port_reg[buff_type];			/* Buffer accessing port register */
+		ptd_map_buff->regs.block_pl_size = hc_ram_buff_block_pl_size[buff_type];	/* Block pay load size */
+		ptd_map_buff->regs.toggle_rate = HC_ISTL_DEF_TOGGLE_RATE;					/* toggle rate for ISTL buffer */
+		ptd_map_buff->regs.last_ptd = 0;								/* Last PTD for ATL & INTL is zero */
+		ptd_map_buff->regs.ptd_done_map = 0;							/* No PTD is done */
+		ptd_map_buff->regs.ptd_skip_map = 0;							/* Skip all PTD */
+		ptd_map_buff->regs.curr_active_ptd = 0;							/* current active ptd is zero */
+		ptd_map_buff->regs.threshold_count = HC_DEF_ATL_THRESHOLD_COUNT;		/* Default ptd thereshold for ATL */
+		ptd_map_buff->regs.threshold_timeout = HC_DEF_ATL_THRESHOLD_TIMEOUT;	/* Default thereshold timeout for ATL */
+
+		/* For each ptd index of this buffer, set the fiedls */
+		bitmap = 0x00000001;
+//		for(ptd_index = 0; ptd_index < ptd_map_buff->max_ptds; ptd_index++)
+		for(ptd_index = 0; ptd_index < TD_PTD_MAX_BUFF_TDS; ptd_index++){
+			ptd_map_buff->map_list[ptd_index].state = TD_PTD_NEW;	/* Set the td_ptd as new */
+			ptd_map_buff->map_list[ptd_index].total_bytes = 0;		/* total bytes to 0 */
+			ptd_map_buff->map_list[ptd_index].ptd_bitmap = bitmap;	/* set the bitmap for this buffer */
+			ptd_map_buff->map_list[ptd_index].td = NULL;
+			ptd_map_buff->map_list[ptd_index].ed = NULL;
+			ptd_map_buff->map_list[ptd_index].ping_pong = TD_PTD_NO_PING_PONG;
+			ptd_map_buff->map_list[ptd_index].ram_addr = 0xFFFF;
+			bitmap <<= 1;
+
+		}/* for( ptd_index */
+
+	}	/* for(buff_type */
+
+} /* phci_init_map_buffers */
+
+
+/* This function is called when ep is linked to the oprational ep list.
+	It searches for the free td_ptd_index.
+	If the ping pong ptd is not set, sets the next free td_ptd_index to
+	pong ptd index */
+/*--------------------------------------------------------------*
+ * HC get td ptd index from TD-PTD map buffer					* 
+ *--------------------------------------------------------------*/
+void	phci_get_td_ptd_index(ed_t	*ed) {
+
+	__u8	buff_type = td_ptd_pipe_x_buff_type[ed->type];
+	__u8	td_ptd_index, index;
+	__u8	max_ptds;
+
+	td_ptd_map_buff_t	*ptd_map_buff = &(td_ptd_map_buff[buff_type]);
+
+	func_debug(("phci_get_td_ptd_index(ed = 0x%p)\n",ed))
+
+	/* ATL PTDs can wait */
+	max_ptds = (buff_type == TD_PTD_BUFF_TYPE_ATL) ? TD_PTD_MAX_BUFF_TDS : ptd_map_buff->max_ptds;
+
+
+	for(td_ptd_index = 0; td_ptd_index < max_ptds; td_ptd_index++) {	/* Find the first free slot */
+
+		if(ptd_map_buff->map_list[td_ptd_index].state == TD_PTD_NEW) {
+				/* Found a free slot */
+			if( ed->td_ptd_index == TD_PTD_INV_PTD_INDEX ) {
+				ed->td_ptd_index = td_ptd_index;
+			}
+#ifdef CONFIG_USB_PHCD_PING_PONG
+			else {
+				/* Might be a bulk pong ptd index (bulk, not already 
+				 * ping is running and not a pending one) */
+				if( (ed->type != PIPE_BULK) || 
+					(td_ptd_index >= ptd_map_buff->max_ptds) ||
+					(ptd_map_buff->ping_ptd_index != TD_PTD_INV_PTD_INDEX) )  {
+						break;
+				}
+
+				ptd_map_buff->ping_ptd_index =  ed->td_ptd_index;
+				ptd_map_buff->pong_ptd_index =  td_ptd_index;
+			}
+#endif /* CONFIG_USB_PHCD_PING_PONG */
+			
+			ptd_map_buff->map_list[td_ptd_index].state = TD_PTD_OPER;	/* put ptd_index to operational state */
+			ptd_map_buff->map_list[td_ptd_index].td = NULL;				/* No td transfer is in progress */
+			ptd_map_buff->map_list[td_ptd_index].ed = ed;				/* initialize the ed pointer */
+			ptd_map_buff->map_list[td_ptd_index].ping_pong = 0;			/* initialize the ping pong flag */
+			ptd_map_buff->total_ptds ++;								/* update # of total td's */
+		
+			if( ed->type == PIPE_ISOCHRONOUS) {				/* reserve additional indexes for ISTL buffer */
+				for(index=0; index < ptd_map_buff->regs.toggle_rate;index++) {   /* for serving till the toggle rate */
+					ptd_map_buff->map_list[td_ptd_index+index].state = TD_PTD_OPER;
+					ptd_map_buff->map_list[td_ptd_index+index].ed = ed;			/* initialize the ed pointer */
+				}
+				ptd_map_buff = &(td_ptd_map_buff[TD_PTD_BUFF_TYPE_ISTL1]);
+				for(index=0; index < ptd_map_buff->regs.toggle_rate;index++) {   /* for serving till the toggle rate */
+					ptd_map_buff->map_list[td_ptd_index+index].state = TD_PTD_OPER;
+					ptd_map_buff->map_list[td_ptd_index+index].ed = ed;			/* initialize the ed pointer */
+				}
+			}
+
+			break;
+		}
+	}
+	
+	return;
+} /* phci_get_td_ptd_index */
+
+
+/*--------------------------------------------------------------*
+ * HC release td ptd index from TD-PTD map buffer				* 
+ *--------------------------------------------------------------*/
+void phci_release_td_ptd_index(ed_t		*ed) {
+
+	__u8				td_ptd_index = ed->td_ptd_index;
+	__u8				buff_type = td_ptd_pipe_x_buff_type[ed->type];
+	td_ptd_map_buff_t   *ptd_map_buff;
+	td_ptd_map_buff_t   *ptd_map_buff1;
+	td_ptd_map_t		*ptd_map;
+	__u8				index;
+	__u32				ptd_bitmap = 0, skip_map;
+
+	func_debug(("phci_release_td_ptd_index(ed = 0x%p)\n",ed))
+
+
+	if( td_ptd_index != TD_PTD_INV_PTD_INDEX) {
+		ptd_map_buff = &(td_ptd_map_buff[buff_type]);
+	
+
+#ifdef CONFIG_USB_PHCD_PING_PONG
+		/* Check if this is ping pong ptd ed or not, if yes clear the pong ptd index also */
+		if( ed->type == PIPE_BULK && ptd_map_buff->ping_ptd_index == td_ptd_index){
+			ptd_map = &(ptd_map_buff->map_list[ptd_map_buff->pong_ptd_index]);
+
+			ptd_map_buff->total_ptds --;
+			if(ptd_map->td)	ptd_map_buff->active_ptds--;
+			ptd_map_buff->active_ptd_bitmap &= (~(ptd_map->ptd_bitmap));
+			ptd_map->state = TD_PTD_NEW;
+			ptd_map->td = NULL;
+			ptd_map->ed = NULL;
+			ptd_bitmap |= ptd_map->ptd_bitmap;
+
+			ptd_map_buff->ping_ptd_index = TD_PTD_INV_PTD_INDEX;
+			ptd_map_buff->pong_ptd_index = TD_PTD_INV_PTD_INDEX;
+			ptd_map_buff->ping_pong_status = 0;
+		}
+#endif /* CONFIG_USB_PHCD_PING_PONG */
+
+		ptd_map = &(ptd_map_buff->map_list[td_ptd_index]);
+
+		ptd_map_buff->total_ptds --;
+		if(ed->type == PIPE_ISOCHRONOUS) {
+
+			/* For isochronous pipe, clear all the td_ptd_index of toggle rate */
+			for(index = 0; index < ptd_map_buff->regs.toggle_rate; index++) {
+
+				ptd_map = &(ptd_map_buff->map_list[td_ptd_index+index]);
+				ptd_map_buff->active_ptd_bitmap &= (~(ptd_map->ptd_bitmap));
+				ptd_map->state = TD_PTD_NEW;
+				ptd_map->td = NULL;
+				ptd_map->ed = NULL;
+
+			}
+
+			ptd_map_buff1 = &(td_ptd_map_buff[TD_PTD_BUFF_TYPE_ISTL1]);
+
+			for(index = 0; index < ptd_map_buff->regs.toggle_rate; index++) {
+
+				ptd_map = &(ptd_map_buff1->map_list[td_ptd_index+index]);
+				ptd_map_buff1->active_ptd_bitmap &= (~(ptd_map->ptd_bitmap));
+				ptd_map->state = TD_PTD_NEW;
+				ptd_map->td = NULL;
+				ptd_map->ed = NULL;
+			}
+
+		} else {
+
+			if(ptd_map->td)	ptd_map_buff->active_ptds--;		/* this ed is deleted in between */
+
+			ptd_map_buff->active_ptd_bitmap &= (~(ptd_map->ptd_bitmap));
+			ptd_map->state = TD_PTD_NEW;
+			ptd_map->td = NULL;
+			ptd_map->ed = NULL;
+			ptd_bitmap |= ptd_map->ptd_bitmap;
+
+		}
+		ed->td_ptd_index = TD_PTD_INV_PTD_INDEX;
+
+		if(buff_type == TD_PTD_BUFF_TYPE_ATL) {
+			phci_reg_read32(REG_ATL_PTD_SKIP_MAP, &skip_map);	/* Read the ATL skip map */
+			skip_map |= ptd_map->ptd_bitmap;
+			phci_reg_write32(REG_ATL_PTD_SKIP_MAP,skip_map);	/* Skip all ptds */
+		}
+	}
+
+	return;
+
+} /* end of phci_release_td_ptd_index */
+
+/* Applicable only for ATL buffer */
+void phci_move_pending_td_ptds(td_ptd_map_buff_t   *ptd_map_buff) {
+	   
+	ed_t				*ed;
+	td_t				*td;
+	td_ptd_map_t		*ptd_map;
+	__u8				td_ptd_index;
+	
+
+	if(ptd_map_buff->pending_ptd_bitmap) {
+
+		/* There are some pending ptd maps that need to be moved to Active ptd map */
+
+		for(td_ptd_index = 0; td_ptd_index < TD_PTD_MAX_BUFF_TDS; td_ptd_index++) {
+			
+			ptd_map = &(ptd_map_buff->map_list[td_ptd_index]);
+
+			if(ptd_map->ptd_bitmap & ptd_map_buff->pending_ptd_bitmap) {
+				/* This PTD is pending */
+				if(td_ptd_index < ptd_map_buff->max_ptds) {
+					/* Just update the Active map */
+					ptd_map_buff->active_ptd_bitmap |= ptd_map->ptd_bitmap;
+					ptd_map_buff->pending_ptd_bitmap &= (~ptd_map->ptd_bitmap);
+				} else {
+					/* Check if there is room to accomodate this */
+					if((ptd_map_buff->active_ptd_bitmap & ptd_map_buff->active_ptd_bitmask) != 
+						ptd_map_buff->active_ptd_bitmask){
+
+						ed = ptd_map->ed;			/* Store ED and TD */
+						td = ptd_map->td;
+
+						phci_release_td_ptd_index(ed);
+						phci_get_td_ptd_index(ed);
+						ptd_map_buff->active_ptd_bitmap |= ptd_map_buff->map_list[ed->td_ptd_index].ptd_bitmap;
+						ptd_map_buff->pending_ptd_bitmap &= (~ptd_map->ptd_bitmap);
+
+					}
+					/* Otherwise wait for some one to come to get free */
+				}
+			}
+		}
+	}
+
+}
+
+/*--------------------------------------------------------------*
+ *--------------------------------------------------------------*
+ phci_fill_send_ptd::
+	
+	send_ptd_bitmap:		32bit map for the ptds to be sent
+	ptd_map_buff:	map buffer pointer of buffer to be written
+
+	Skip all the PTDs that are going to be filled by this function.
+
+	fill the ptd buffer and send it to HC
+
+	Fill into the HC buffer all the ptd's indicated by the bitmap
+	into their corresponding locations in the buffer.
+
+	Check and update the Last Ptd, thereshold level.
+
+	remove the skip map so that PTD's processing starts
+ *--------------------------------------------------------------*
+ *--------------------------------------------------------------*/
+void phci_fill_send_ptd(phci_t	*phci,__u32	send_ptd_bitmap,td_ptd_map_buff_t *ptd_map_buff) {
+
+	td_ptd_map_t		*td_ptd_map;
+	__u8				*ptd_payload = NULL;
+	__u8				ram_data[TD_PTD_MAX_BUFF_TDS];
+	__u8				byte_data = 0;
+	__u16				payload_bytes = 0;					/* ptd payload bytes */
+	__u16				total_bytes = HC_PTD_HEADER_SIZE;	/* ptd total bytes to be written to HC buffer */
+	__u32				active_ptd_bitmap = 0x0;
+	td_t				*td;
+	ed_t				*ed;
+	__u8				index = 0;
+
+	__u32				finished_map = send_ptd_bitmap;	
+	__u32				ram_addr;
+
+	__u32				data_read;
+
+
+#ifdef CONFIG_USB_PHCD_PING_PONG
+	__u8				ping_pong_flag = 0;
+#endif /* CONFIG_USB_PHCD_PING_PONG */
+
+#if 0
+	printk("phci_fill_send_ptd(phci = 0x%p, send_ptd_map = 0x%x, ptd_map_buff = 0x%p)\n",phci,send_ptd_bitmap, ptd_map_buff);
+#endif
+
+
+	if(!send_ptd_bitmap)	{
+
+		if(ptd_map_buff->buffer_type == TD_PTD_BUFF_TYPE_ATL) {
+			if(!ptd_map_buff->active_ptds){
+
+
+				/* No ptds are active */
+				ptd_map_buff->regs.threshold_count = 0;	/* Set the thereshol count from logic */
+				/* Update the same in HC */
+				phci_reg_write16(REG_ATL_THRESHOLD_COUNT,ptd_map_buff->regs.threshold_count);			
+				phci_reg_write32(REG_ATL_PTD_SKIP_MAP,0xFFFFFFFF);	/* Skip all ptds */
+				
+				phci_reg_read16(REG_BUFF_STS,&data_read);				/* Read the buffer status register */
+				data_read &= (~ATL_ACTIVE);							/* Deactivate ATL */
+				phci->hcd_operational_flags &= (~ATL_ACTIVE);
+				phci_reg_write16(REG_BUFF_STS,data_read);				/* Deactivate ATL buffers */
+
+			}
+		}
+
+		if(ptd_map_buff->buffer_type == TD_PTD_BUFF_TYPE_INTL) {
+
+			if(!ptd_map_buff->active_ptds){
+
+				phci_reg_write32(REG_INTL_PTD_SKIP_MAP,0xFFFFFFFF);/* Skip all ptds */
+				
+				phci_reg_read16(REG_BUFF_STS,&data_read);				/* Read the buffer status register */
+				data_read &= (~INTL_ACTIVE);						/* Deactivate ATL */
+				phci->hcd_operational_flags &= (~INTL_ACTIVE);
+				phci_reg_write16(REG_BUFF_STS,data_read);				/* Deactivate ATL/INTL buffers */
+			}
+		}
+		return;							/* If there is nothing to do, just return it */
+	}
+
+	/* Take care of pending ATL ptds */
+
+	if(ptd_map_buff->buffer_type == TD_PTD_BUFF_TYPE_ATL) {
+
+		ptd_map_buff->pending_ptd_bitmap |= (send_ptd_bitmap & (~ptd_map_buff->active_ptd_bitmask));
+		send_ptd_bitmap &= ptd_map_buff->active_ptd_bitmask;
+
+		if(!send_ptd_bitmap)	return;
+	}
+
+	switch(ptd_map_buff->buffer_type) {
+
+		case TD_PTD_BUFF_TYPE_INTL:
+
+
+			/* Skip the PTD's in ATL & INTL so that we can write the PTD's into the buffer */
+			phci_reg_read32(REG_INTL_PTD_SKIP_MAP, &(ptd_map_buff->regs.ptd_skip_map));	/* Read the ATL skip map */
+			ptd_map_buff->regs.ptd_skip_map |= send_ptd_bitmap;							/* Add the new ptds to be skipped */
+			phci_reg_write32(REG_INTL_PTD_SKIP_MAP,ptd_map_buff->regs.ptd_skip_map);	/* The HC don;t touch the ptds */
+			break;
+
+		case TD_PTD_BUFF_TYPE_ATL:
+
+			/* Skip the PTD's in ATL & INTL so that we can write the PTD's into the buffer */
+			phci_reg_read32(REG_ATL_PTD_SKIP_MAP, &(ptd_map_buff->regs.ptd_skip_map));		/* Read the ATL skip map */
+			ptd_map_buff->regs.ptd_skip_map |= send_ptd_bitmap;										/* Add the new ptds to be skipped */
+			phci_reg_write32(REG_ATL_PTD_SKIP_MAP,ptd_map_buff->regs.ptd_skip_map);			/* The HC don;t touch the ptds */
+			break;
+	}
+
+	for( index = 0; (index < ptd_map_buff->max_ptds) || (finished_map != 0); index++) {
+
+		td_ptd_map = &(ptd_map_buff->map_list[index]);
+		if(td_ptd_map->ptd_bitmap & finished_map) {				/* This ptd needs to be filled */
+	
+			/* Start filling the ram_data to send it to HC */
+
+			td = td_ptd_map->td;
+			ed = td->ed;
+
+			/* start filling the ptd header */
+			
+			total_bytes = HC_PTD_HEADER_SIZE;	/* ptd total bytes to be written to HC buffer, initialize to ptd header */
+
+			/**********************************************************************/
+			/* ptd_header[0]: 7..0		actual bytes(7...0)				0(always) */
+			/**********************************************************************/
+			ram_data[0] = 0;
+
+			/************************************************************************/
+			/* ptd_header[1]: 7..4		completion code(3...0)		1111 (always) 	*/
+			/* ptd_header[1]: 3		 	active(0)					1 (always) 		*/
+			/* ptd_header[1]: 2		 	toggle(0)					from ed&td 		*/
+			/* ptd_header[1]: 1..0		actual bytes(9..8)			0 (always)		*/
+			/************************************************************************/
+
+			ram_data[1] = (PTD_CC_MASK | PTD_ACTIVE);
+			if( td->hwINFO & HC_GTD_MLSB) {						/* fill toggle bit from td hw info */
+				ram_data[1] |= (((__u8)((td->hwINFO & HC_GTD_TLSB) >> 24)) << 2);
+			} else {												/* fill toggle bit from ed hw info */
+				ram_data[1] |= (((__u8)((ed->hwHeadP & HC_ED_TOGGLE) >> 1)) << 2);
+			}
+	
+			/**********************************************************************/
+			/* ptd_header[2]: 7..0		Max.PacketSize(7...0)		from ed MPS	  */
+			/**********************************************************************/
+
+			ram_data[2] = ((__u8)((ed->hwINFO & HC_ED_MPS) >> 16));
+
+
+			/************************************************************************/
+			/* ptd_header[3]: 7..4		End point number(3...0)		from ED EN		*/
+			/* ptd_header[3]: 3		 	reserved(0)					0 (always) 		*/
+			/* ptd_header[3]: 2		 	speed(0)					from ED			*/
+			/* ptd_header[3]: 1..0		Max.PacketSize(9..8)		from ED MPS		*/
+			/************************************************************************/
+
+			ram_data[3] = (((__u8)((ed->hwINFO & HC_ED_EN) >> 7)) << 4);
+
+			if(ed->hwINFO & HC_ED_SPD) {				/* Check if speed device or not */
+				ram_data[3] |= PTD_SPEED;
+			}
+
+			ram_data[3] |= (((__u8)((ed->hwINFO & HC_ED_MPS) >> 24)) & 0x03);
+	
+
+			/********************************************************************************/
+			/* ptd_header[4]: 7..0		Total Bytes(7...0)		from td cbp & be			*/
+			/* ptd_header[5]: 1..0 		total bytes(9..8)			from td cbp & be		*/
+			/********************************************************************************/
+
+			if(td->hwCBP) {
+				payload_bytes = td->hwBE - td->hwCBP + 1;				/* get the total bytes from td cbp & be */
+				ram_data[4] = (__u8)payload_bytes;
+				ram_data[5] = (__u8)(payload_bytes >> 8);
+			} else {			/* Null data packet */
+				payload_bytes = 0;
+				ram_data[4] = 0;
+				ram_data[5] = 0;
+			}
+	
+			/********************************************************************************/
+			/* ptd_header[5]: 7			paired(0)					from ping_pong input 	*/
+			/* ptd_header[5]: 6		 	ping_pong(0)				from ping_pong input 	*/
+			/* ptd_header[5]: 5..4	 	reserved(1..0)				00 always 				*/
+			/* ptd_header[5]: 3..2 		token direction(1..0)		from ed DIR 			*/
+			/* ptd_header[5]: 1..0 		total bytes(9..8)			already filled before 	*/
+			/********************************************************************************/
+
+#ifdef CONFIG_USB_PHCD_PING_PONG
+
+			if(td_ptd_map->ping_pong) ping_pong_flag = 1;
+
+			ram_data[5] |= td_ptd_map->ping_pong;
+
+#endif /* CONFIG_USB_PHCD_PING_PONG */
+
+			byte_data = (__u8)((ed->hwINFO & HC_ED_DIR) >> 11);
+			if(byte_data != OHCI_OUT && byte_data != OHCI_IN) {
+				byte_data = (__u8)((td->hwINFO & HC_GTD_DP) >> 19);
+			}
+
+			ram_data[5] |= (byte_data << 2);
+
+			/********************************************************************************/
+			/* ptd_header[6]: 7			format(0)					0	always 				*/
+			/* ptd_header[6]: 6..0	 	function address(6..0)		from ED FA				*/
+			/********************************************************************************/
+
+			ram_data[6] = ((__u8)(ed->hwINFO & HC_ED_FA));
+
+			/*************************************************************************************/
+			/* ptd_header[7]: 7..0	 	Frame Number/Int polling Interval(7..0)	poll_frame# input*/
+			/*************************************************************************************/
+			ram_data[7] = 0;
+
+			if(ed->type == PIPE_INTERRUPT) {
+				__u8	int_interval, byte;
+
+				int_interval = (ed->int_interval >> 1);
+				byte = 0;
+				while(int_interval) {int_interval >>= 1; byte++;}
+
+#ifdef CONFIG_USB_PHCD_EVEN_SCH
+				ram_data[7] = (byte << 5);				/* Check the last 5 bits of Interrupt polling interval */
+				ram_data[7] |= ed->int_branch ;
+#else
+				ram_data[7] = (byte << 1);				/* Always schedule on even frame */
+#endif /* CONFIG_USB_PHCD_EVEN_SCH */
+
+			}
+
+			/* start sendig the data for this ptd */
+
+			ram_addr = ptd_map_buff->ram_buff_addr+index*(ptd_map_buff->regs.block_pl_size + HC_PTD_HEADER_SIZE);
+			ptd_payload = (__u8*)(td->hwCBP);
+			
+			if( (byte_data != OHCI_IN ) && payload_bytes && ptd_payload ) {			/* Don's send data in case of IN token */
+				total_bytes += payload_bytes;
+				fnvPhciRamWrite(phci,payload_bytes, HC_DIR_ADDR_INCREMENT, (ram_addr+HC_PTD_HEADER_SIZE), ptd_payload);
+
+			}
+
+			if(ram_addr < 2*HC_ISTL_BUFFER_LENGTH) 
+				printk("Something bad is going to happen, trying to write at %x for A/INTL ptd's", ram_addr);
+
+			fnvPhciRamWrite(phci,HC_PTD_HEADER_SIZE, HC_DIR_ADDR_INCREMENT, ram_addr, ram_data);		/* Send the ptd header */
+
+
+			td_ptd_map->total_bytes = payload_bytes+HC_PTD_HEADER_SIZE;			/* Set the total bytes size for this td-ptd map */
+			ptd_map_buff->active_ptd_bitmap |= td_ptd_map->ptd_bitmap;			/* Set this ptd is active in active ptd map */
+			ptd_map_buff->active_ptds++;
+				
+			finished_map &= (~(td_ptd_map->ptd_bitmap));						/* Set this ptd as finished one */
+
+		}
+	}
+
+	switch(ptd_map_buff->buffer_type) {
+		case TD_PTD_BUFF_TYPE_ATL:
+			ptd_map_buff->regs.threshold_count = atl_active_ptd_X_threshold_ptd[ptd_map_buff->active_ptds] ;	/* Set the thereshol count from logic */
+
+#ifdef CONFIG_USB_PHCD_PING_PONG
+			/* PING PONG pair of PTDs will be treated as one PTD */
+			if(ptd_map_buff->regs.threshold_count) ptd_map_buff->regs.threshold_count -= ping_pong_flag;
+#endif /* CONFIG_USB_PHCD_PING_PONG */
+
+
+			phci_reg_write16(REG_ATL_THRESHOLD_COUNT,ptd_map_buff->regs.threshold_count);			/* Update the same in HC */
+
+			phci_reg_read16(REG_ATL_THRESHOLD_COUNT,&data_read);			/* Update the same in HC */
+
+			/* Set the Last PTD in ATL */
+			/* Calculate the last ptd in ATL */
+
+			active_ptd_bitmap = ptd_map_buff->active_ptd_bitmap;
+			ptd_map_buff->regs.last_ptd = 0x1;
+			active_ptd_bitmap >>= 1;
+
+			/*
+			 * Last PTD is already set at the time of initialization to the maximum TDs
+			 * So no need of dynamic update
+			 */
+#if 0
+			while(active_ptd_bitmap) {					/* right shift till active ptd bitmap becomes zero */
+				ptd_map_buff->regs.last_ptd <<= 1;
+				active_ptd_bitmap >>= 1;
+			}
+			phci_reg_write32(REG_ATL_PTD_LAST_PTD,ptd_map_buff->regs.last_ptd);		/* Update the last ATL ptd in HC */
+#endif
+
+
+
+
+		
+			/* Activate the PTD's in ATL so that we can start the PTD's in the buffer */
+			ptd_map_buff->regs.ptd_skip_map &= (~send_ptd_bitmap);									/* remove the skip on new ptd's */
+			phci_reg_write32(REG_ATL_PTD_SKIP_MAP,ptd_map_buff->regs.ptd_skip_map);			/* write into the skip map buffer */
+
+
+			phci_reg_read16(REG_BUFF_STS,&data_read);		/* Activate ATL buffer processing */
+
+			if(!(data_read & ATL_ACTIVE)) {
+				data_read |= ATL_ACTIVE;
+				phci->hcd_operational_flags |= ATL_ACTIVE;
+				phci_reg_write16(REG_BUFF_STS,data_read);		/* Activate ATL buffer processing */
+			}
+			break;
+
+	 	case TD_PTD_BUFF_TYPE_INTL:
+
+			active_ptd_bitmap = ptd_map_buff->active_ptd_bitmap;
+			ptd_map_buff->regs.last_ptd = 0x1;
+			active_ptd_bitmap >>= 1;
+
+			/* Activate the PTD's in INTL so that we can start the PTD's in the buffer */
+			ptd_map_buff->regs.ptd_skip_map &= (~send_ptd_bitmap);			/* remove the skip on new ptd's */
+			phci_reg_write32(REG_INTL_PTD_SKIP_MAP,ptd_map_buff->regs.ptd_skip_map);	/* write into the skip map buffer */
+	
+			phci_reg_read16(REG_BUFF_STS,&data_read);		/* Activate INTL buffer processing */
+
+			if(!(data_read & INTL_ACTIVE)) {
+				phci->hcd_operational_flags |= INTL_ACTIVE;
+				data_read |= INTL_ACTIVE;
+				phci_reg_write16(REG_BUFF_STS,data_read);		/* Activate INTL buffer processing */
+			}
+			phci_reg_read32(REG_INTL_PTD_SKIP_MAP,&ptd_map_buff->regs.ptd_skip_map);	/* write into the skip map buffer */
+
+			break;
+	}
+} /* phci_fill_send_ptd */
+
+/*--------------------------------------------------------------*
+ *--------------------------------------------------------------*
+ phci_fill_send_isoc_ptd::
+	
+	send_ptd_bitmap:		32bit map for the ptds to be sent
+	ptd_map_buff:	map buffer pointer of buffer to be written
+
+	fill the ptd buffer and send it to HC
+
+	Fill into the HC buffer all the ptd's indicated by the bitmap
+	into their corresponding locations in the buffer.
+
+	activate the corresponding istl buffer
+ *--------------------------------------------------------------*
+ *--------------------------------------------------------------*/
+void phci_fill_send_isoc_ptd(phci_t	*phci,__u32	send_ptd_bitmap,td_ptd_map_buff_t *ptd_map_buff) {
+
+	td_ptd_map_t		*td_ptd_map;
+	__u8				*ptd_payload = NULL;
+	__u8				ram_data[TD_PTD_MAX_BUFF_TDS];
+	__u8				byte_data = 0;
+	__u16				payload_bytes = 0;					/* ptd payload bytes */
+	__u16				total_bytes = HC_PTD_HEADER_SIZE;	/* ptd total bytes to be written to HC buffer */
+	td_t				*td;
+	ed_t				*ed;
+	__u8				index = 0;
+
+	__u32				finished_map = send_ptd_bitmap;	
+	__u32				ram_addr = ptd_map_buff->ram_buff_addr;
+	__u32				ram_buff_sts;
+
+	detail_debug(("phci_fill_send_isoc_ptd(phci = 0x%p, send_ptd_map = 0x%x, ptd_map_buff = 0x%p)\n",phci,send_ptd_bitmap, ptd_map_buff))
+
+
+	ptd_map_buff->active_ptd_bitmap = 0;			/* Set this ptd is active in active ptd map */
+
+	if(!send_ptd_bitmap)	return;							/* If there is nothing to do, just return it */
+
+
+	phci_reg_read16(REG_BUFF_STS, &ram_buff_sts);		/* Activate ITL buffer processing */
+
+	if(ptd_map_buff->buffer_type == TD_PTD_BUFF_TYPE_ISTL0) {
+		ram_buff_sts |= ISTL_0_BUFF_FULL;
+	} else {
+		ram_buff_sts |= ISTL_1_BUFF_FULL;
+	}
+
+	phci_reg_write16(REG_BUFF_STS,ram_buff_sts);		/* Activate ITL buffer processing */
+
+
+	for( index = 0; (index < ptd_map_buff->max_ptds) || (finished_map != 0); index++) {
+
+		td_ptd_map = &(ptd_map_buff->map_list[index]);
+		if(td_ptd_map->ptd_bitmap & finished_map) {				/* This ptd needs to be filled */
+	
+			/* Start filling the ram_data to send it to HC */
+
+			td = td_ptd_map->td;
+			ed = td->ed;
+
+	
+			/* start filling the ptd header */
+
+			total_bytes = HC_PTD_HEADER_SIZE;	/* ptd total bytes to be written to HC buffer, initialize to ptd header */
+			
+			/**********************************************************************/
+			/* ptd_header[0]: 7..0		actual bytes(7...0)				0(always) */
+			/**********************************************************************/
+			ram_data[0] = 0;
+
+			/************************************************************************/
+			/* ptd_header[1]: 7..4		completion code(3...0)		1111 (always) 	*/
+			/* ptd_header[1]: 3		 	active(0)					1 (always) 		*/
+			/* ptd_header[1]: 2		 	toggle(0)					always data0	*/
+			/* ptd_header[1]: 1..0		actual bytes(9..8)			0 (always)		*/
+			/************************************************************************/
+
+			/* for toggle bit of OUT its always DATA0, for IN it should accept either 
+			DATA0 & DATA1, we set now DATA0 and if the device gives DATA1 the HC should 
+			not crib such situation as error case. If HC gives data toggle error, sw
+			ignores the error */
+
+			ram_data[1] = (PTD_CC_MASK | PTD_ACTIVE);			
+	
+			/**********************************************************************/
+			/* ptd_header[2]: 7..0		Max.PacketSize(7...0)		from ed MPS   */
+			/**********************************************************************/
+
+			ram_data[2] = ((__u8)((ed->hwINFO & HC_ED_MPS) >> 16));
+
+
+			/************************************************************************/
+			/* ptd_header[3]: 7..4		End point number(3...0)		from ED EN		*/
+			/* ptd_header[3]: 3		 	last(0)						from finish map	*/
+			/* ptd_header[3]: 2		 	speed(0)					from ED			*/
+			/* ptd_header[3]: 1..0		Max.PacketSize(9..8)		from ED MPS		*/
+			/************************************************************************/
+
+			ram_data[3] = (((__u8)((ed->hwINFO & HC_ED_EN) >> 7)) << 4);
+
+			if(ed->hwINFO & HC_ED_SPD) {				/* Check if speed device or not */
+				ram_data[3] |= PTD_SPEED;
+			}
+
+			ram_data[3] |= (((__u8)((ed->hwINFO & HC_ED_MPS) >> 24)) & 0x03);
+
+		
+			/* As ptd's are finished, the finished map bits will go and finally for the last
+			ptd, finished map is the ptd_bitmap */
+			if( finished_map == td_ptd_map->ptd_bitmap) {
+				ram_data[3] |= PTD_LAST;
+			}
+	
+
+			/********************************************************************************/
+			/* ptd_header[4]: 7..0		Total Bytes(7...0)		from td cbp & be			*/
+			/* ptd_header[5]: 1..0 		total bytes(9..8)			from td cbp & be		*/
+			/********************************************************************************/
+
+			if(td->hwCBP) {
+				payload_bytes = td->hwBE - (td->hwCBP+(td->hwPSW[0] & 0x0FFF)) + 1; /* get the total bytes from td cbp & be & psw */
+				ram_data[4] = (__u8)payload_bytes;
+				ram_data[5] = (__u8)(payload_bytes >> 8);
+			} else {			/* Null data packet */
+				payload_bytes = 0;
+				ram_data[4] = 0;
+				ram_data[5] = 0;
+			}
+	
+			/********************************************************************************/
+			/* ptd_header[5]: 7			(0)							always 0				*/
+			/* ptd_header[5]: 6		 	(0)							always 0				*/
+			/* ptd_header[5]: 5..4	 	reserved(1..0)				00 always 				*/
+			/* ptd_header[5]: 3..2 		token direction(1..0)		from ed DIR 			*/
+			/* ptd_header[5]: 1..0 		total bytes(9..8)			already filled before 	*/
+			/********************************************************************************/
+
+			byte_data = (__u8)((ed->hwINFO & HC_ED_DIR) >> 11);
+
+			ram_data[5] |= (byte_data << 2);
+
+			/********************************************************************************/
+			/* ptd_header[6]: 7			format(1)					1	always for ISOC		*/
+			/* ptd_header[6]: 6..0	 	function address(6..0)		from ED FA				*/
+			/********************************************************************************/
+
+			ram_data[6] = ((__u8)(ed->hwINFO & HC_ED_FA));
+			ram_data[6] |= PTD_FORMAT;
+
+			/*************************************************************************************/
+			/* ptd_header[7]: 7..0	 	Frame Number/Int polling Interval(7..0)	poll_frame# input*/
+			/*************************************************************************************/
+			ram_data[7] = (td->hwINFO & 0xFF);
+
+			/* start sendig the data for this ptd */
+
+			ptd_payload = (__u8*)((td->hwCBP) + (td->hwPSW[0] & 0x0FFF));
+
+			if( (byte_data != OHCI_IN ) && payload_bytes && ptd_payload ) {				/* Don's send data in case of IN token */
+				total_bytes += payload_bytes;
+				fnvPhciRamWrite(phci,payload_bytes, HC_DIR_ADDR_INCREMENT, (ram_addr+HC_PTD_HEADER_SIZE), ptd_payload);
+			}
+
+
+			fnvPhciRamWrite(phci, HC_PTD_HEADER_SIZE, HC_DIR_ADDR_INCREMENT, ram_addr, ram_data);		/* Send the ptd header */
+
+			td_ptd_map->ram_addr = ram_addr;
+	
+			ALIGN_RAM_BUFF_LENGTH(payload_bytes);
+
+			td_ptd_map->total_bytes = payload_bytes+HC_PTD_HEADER_SIZE;			/* Set the total bytes size for this td-ptd map */
+			
+			if(ram_addr > 2*HC_ISTL_BUFFER_LENGTH) {
+				printk("Something bad is going to happen, Writing at %x for ISTL ptd's\n", ram_addr);
+			}
+
+			ram_addr += td_ptd_map->total_bytes;
+
+			ptd_map_buff->active_ptd_bitmap |= td_ptd_map->ptd_bitmap;			/* Set this ptd is active in active ptd map */
+			ptd_map_buff->active_ptds++;
+				
+			finished_map &= (~(td_ptd_map->ptd_bitmap));							/* Set this ptd as finished one */
+		}
+	}
+
+
+} /* phci_fill_send_isoc_ptd */
+
+/*--------------------------------------------------------------*
+ *--------------------------------------------------------------*
+ phci_submit_ed
+	phci:	phci data structure
+	ed:		endpoint descriptor data strucrure for which data transfer is initiated
+
+	control/bulk::
+	Check if there are any transfers are active for this ed
+	If no transfers, fill the first td into HC buffer
+	If ping-pong is enabled and if this is ping pong ed, send the pong buffer also
+	Set the ATL interrupt if not enabled
+	Set the atl last ptd, atl thereshold level and remove the skip bit for the ptds filled
+ *--------------------------------------------------------------*
+ *--------------------------------------------------------------*/
+void phci_submit_ed(phci_t	*phci,	ed_t	*ed) {
+
+	td_ptd_map_buff_t   *ptd_map_buff;
+	td_ptd_map_t		*td_ptd_map;
+	__u32				ptd_bitmap = 0;
+	__u8				td_ptd_index = ed->td_ptd_index;
+	td_t				*td;
+	__u32				irq_mask;
+	urb_priv_t			*urb_priv;
+
+	__u32				buff_sts;
+
+	/* Check if td_ptd_index is free */
+	/* If free fill it with setup stage td */
+	/* If this is ping pong ptd pair, fill data stage as ping pong */
+	/* if ATL interrupt is not set yet set it */
+	/* Check number of ptd's in the atl buffer, set last ptd, threshold ptd ...etc */
+			
+
+	switch(ed->type) {
+			
+		case PIPE_BULK:
+
+ 			ptd_map_buff = &(td_ptd_map_buff[TD_PTD_BUFF_TYPE_ATL]);
+
+ 			td_ptd_map = &(ptd_map_buff->map_list[td_ptd_index]);
+			
+			phci_reg_read16(REG_BUFF_STS, &buff_sts);
+			
+			if( td_ptd_map->state == TD_PTD_OPER && !(td_ptd_map->td) )	{
+				/* No td ptds are in progress for this ed */
+			
+				td = (td_t*)(ed->hwHeadP & 0xfffffff0);
+				ptd_bitmap |= td_ptd_map->ptd_bitmap;
+				td_ptd_map->ping_pong = TD_PTD_NO_PING_PONG;
+
+				if(!(buff_sts&ATL_ACTIVE)) td_ptd_map->td = td;
+				urb_priv = (urb_priv_t*)(td->urb->hcpriv);
+
+#ifdef CONFIG_USB_PHCD_PING_PONG
+
+				// Conditions to start ping pong ptd
+				// 1) This ed is reserved for ping pong mechanism
+				// 2) There are more than 1 PTD's to be serverd for this URB
+				// 3) ATL IS NOT Active or PING PONG is not PONG
+				//  	0					0			start
+				//		0					1			start (clear pingpong)
+				//		1					0			start
+				//		1					1			don't start (can not clear)
+				//		!(ATL_ACTIVE) || !(PING_PONG)
+				
+				
+				if((urb_priv->length > 1) && (!(buff_sts & ATL_ACTIVE) || 
+					!(buff_sts &  ACTIVE_PING_PONG_PAIR))) {
+
+					phci_get_td_ptd_index(ed); 	/* Get a pong-ptd index */
+					if(ptd_map_buff->pong_ptd_index == TD_PTD_INV_PTD_INDEX) printk("ha ha ha\n");
+					if(ptd_map_buff->ping_ptd_index ==  ed->td_ptd_index) {
+						if(buff_sts &  ACTIVE_PING_PONG_PAIR) 
+						{
+							/* Reset Hardware Ping Pong */
+							buff_sts |= RESET_PING_PONG;
+							phci_reg_write16(REG_BUFF_STS, buff_sts);		/* Clear the Reset bit so that we can 
+																	   able to clear in future */
+							buff_sts &= (~RESET_PING_PONG);
+							phci_reg_write16(REG_BUFF_STS, buff_sts);
+						}
+						ptd_map_buff->ping_pong_status = 0;	
+						/* Set PING to fill for ping ptd index */
+						td_ptd_map->ping_pong = TD_PTD_PING;
+						if(!(buff_sts&ATL_ACTIVE)) ptd_map_buff->ping_pong_status = TD_PTD_PING_FILLED;
+
+						/* Fill PONG ptd to the ATL buffer */
+						td_ptd_index = ptd_map_buff->pong_ptd_index;
+						td_ptd_map = &(ptd_map_buff->map_list[td_ptd_index]);
+						td = (td_t*)(td->hwNextTD & HC_GTD_NEXTTD);
+						if(!(buff_sts&ATL_ACTIVE)) td_ptd_map->td = td;
+						ptd_bitmap |= td_ptd_map->ptd_bitmap;
+						td_ptd_map->ping_pong = TD_PTD_PONG;
+						if(!(buff_sts&ATL_ACTIVE)) ptd_map_buff->ping_pong_status = TD_PTD_PONG_FILLED;
+					}
+				}
+
+#endif /* CONFIG_USB_PHCD_PING_PONG */
+
+				/* Fill PTD to the ATL buffer (No ping-pong) */
+				if(buff_sts & ATL_ACTIVE) {
+					ptd_map_buff->pending_ptd_bitmap |= ptd_bitmap;
+				} else {
+					phci_fill_send_ptd(phci, ptd_bitmap, ptd_map_buff);
+				}
+
+			} /* else {
+				some td's of this ed are already in progress, processing will be done later 
+			} */
+
+			phci->uHcHcdControl_hcd |= OHCI_BLF;
+			
+			break;
+		case PIPE_CONTROL:
+
+ 			ptd_map_buff = &(td_ptd_map_buff[TD_PTD_BUFF_TYPE_ATL]);
+
+ 			td_ptd_map = &(ptd_map_buff->map_list[td_ptd_index]);
+			
+			phci_reg_read16(REG_BUFF_STS, &buff_sts);
+			
+
+			if(td_ptd_map->state == TD_PTD_OPER && !(td_ptd_map->td) )	{		
+				/* No td ptds are in progress for this ed */
+			
+				/* Fill PTD to the ATL buffer (No ping-pong) */
+				if(buff_sts & ATL_ACTIVE) {
+					ptd_map_buff->pending_ptd_bitmap |= td_ptd_map->ptd_bitmap;
+				} else 
+				{
+				td_ptd_map->td = (td_t*)(ed->hwHeadP & 0xfffffff0);
+				phci_fill_send_ptd(phci, td_ptd_map->ptd_bitmap, ptd_map_buff);
+				}
+
+			} /* else {
+				some td's of this ed are already in progress, processing will be done later 
+			} */
+
+			phci->uHcHcdControl_hcd |= OHCI_CLF;
+			
+			break;
+
+		case PIPE_INTERRUPT:
+ 			ptd_map_buff = &(td_ptd_map_buff[TD_PTD_BUFF_TYPE_INTL]);
+
+ 			td_ptd_map = &(ptd_map_buff->map_list[td_ptd_index]);
+			
+			if(td_ptd_map->state == TD_PTD_OPER && !(td_ptd_map->td) )	{		
+				/* No td ptds are in progress for this ed */
+			
+				td_ptd_map->td = (td_t*)(ed->hwHeadP & 0xfffffff0);
+				phci_fill_send_ptd(phci,td_ptd_map->ptd_bitmap, ptd_map_buff);
+			}
+
+			break;
+
+		case PIPE_ISOCHRONOUS:
+				
+				if(td_ptd_map_buff[TD_PTD_BUFF_TYPE_ISTL1].frame_number == INVALID_FRAME_NUMBER) {
+					/* This is the first ed to start ISOC transfer, Sof is not switched on, start SOF */
+
+					phci_reg_read16(REG_IRQ_MASK, &irq_mask);
+					irq_mask |= SOF_INT;							/* Enable SOF processing */
+					phci_reg_write16(REG_IRQ_MASK, irq_mask);
+				}
+
+			break;
+	}
+
+} /* phci_submit_ed */
+
+
+/*--------------------------------------------------------------*
+ * ATL Interrupt Processing										* 
+ *--------------------------------------------------------------*/
+void fnvProcessAtlInt(phci_t	*phci) {
+
+	__u8				td_ptd_index = 0;
+	__u8				completion_code,byte_data;
+	__u32				ptd_bitmap;			/* HC 	done atl ptd map */
+	td_ptd_map_buff_t   *ptd_map_buff = &(td_ptd_map_buff[TD_PTD_BUFF_TYPE_ATL]);
+	td_ptd_map_t		*td_ptd_map;
+	td_t				*td;
+	ed_t				*ed;
+	__u8				ram_data[HC_ATL_BLK_SIZE];
+	__u32				ram_addr;
+	__u16				bytes;
+	__u32				uData1, uTotal;
+	__u8*				td_payload;
+	__u32				active_ptd_bitmap = 0;
+	__u32				active_ptdmap = 0;
+	__u32				hc_buff_sts = 0;
+	__u32				fn, fn_rem;
+
+	__u32				ping_pong_bitmap = 0x00;
+
+	__u32				td_head, td_tail;
+
+	/* Read the Atl Done PTD's map from the HC atl buffer */
+	phci_reg_read32(REG_ATL_PTD_DONE_MAP, &ptd_bitmap);
+
+	fnvPhciHcorRead(phci,uHcFmNumber, &fn);
+	fnvPhciHcorRead(phci,uHcFmRemaining, &fn_rem);
+
+	ptd_map_buff->regs.ptd_done_map = ptd_bitmap;
+	phci_reg_read32(REG_ATL_PTD_SKIP_MAP, &(ptd_map_buff->regs.ptd_skip_map));	/* Read the ATL skip map */
+	ptd_map_buff->regs.ptd_skip_map |= ptd_bitmap;			/* Add the done ptds to be skipped */
+	phci_reg_write32(REG_ATL_PTD_SKIP_MAP,ptd_map_buff->regs.ptd_skip_map);	/* The HC don;t touch the ptds */
+
+	ptd_bitmap = 0x00000001;
+
+	active_ptdmap = ptd_map_buff->regs.ptd_done_map;
+
+	phci_reg_read16(REG_BUFF_STS, &hc_buff_sts);
+
+#ifdef CONFIG_USB_PHCD_PING_PONG
+	/* Find if both ping and pong ptds are done, and the scanning sequesnce is pong-ping 
+     * if so we need to reverse the scanning sequence */
+
+	if(ptd_map_buff->ping_ptd_index != TD_PTD_INV_PTD_INDEX) {
+		/* Paired PTD sequence is ON, check if both are done */
+		ping_pong_bitmap = ptd_map_buff->map_list[ptd_map_buff->ping_ptd_index].ptd_bitmap;
+		ping_pong_bitmap |= ptd_map_buff->map_list[ptd_map_buff->pong_ptd_index].ptd_bitmap;
+
+		if( ((ping_pong_bitmap & ptd_map_buff->regs.ptd_done_map) == ping_pong_bitmap) &&
+			(ptd_map_buff->ping_pong_status & TD_PTD_PING_FILLED) )  {
+
+			/* Reverse the scan sequence */
+			ptd_bitmap <<= (TD_PTD_MAX_BUFF_TDS - 1);
+			td_ptd_index = TD_PTD_MAX_BUFF_TDS - 1;
+		} else {
+			/* normal scan sequence */
+			ping_pong_bitmap = 0x00;
+		}
+	}
+#endif /* CONFIG_USB_PHCD_PING_PONG */
+
+
+
+	while(ptd_map_buff->regs.ptd_done_map) {				/* If there are any done ptd's present */
+
+		if(ptd_map_buff->regs.ptd_done_map & ptd_bitmap) {	/* At this bitmap there is a done ptd */
+			td_ptd_map = &(ptd_map_buff->map_list[td_ptd_index]);
+				
+			ram_addr = ptd_map_buff->ram_buff_addr+td_ptd_index*(ptd_map_buff->regs.block_pl_size + HC_PTD_HEADER_SIZE);
+
+			/* Read the PTD header from the HC */
+			fnvPhciRamRead(phci, HC_PTD_HEADER_SIZE , HC_DIR_ADDR_INCREMENT, ram_addr, ram_data);
+
+			td = td_ptd_map->td;
+
+			if(td_ptd_map->state == TD_PTD_OPER && td) {				/* This PTD is done, do the necessary processing */
+			ptd_map_buff->active_ptds--;
+
+				ed = td->ed;											/* Get the ed of this td */
+				
+				/* Process completion code, and toggle bit */
+				byte_data = ram_data[1];
+				if ((byte_data & PTD_ACTIVE) == 0) {       /* Test if the PTD is still active */
+					/* Copy completion code to GTD */
+					completion_code = ((byte_data & PTD_COMPLETION_CODE) >> 4);
+
+					bytes = (ram_data[0]+((ram_data[1] & 0x3) << 8));	/* Get the actual bytes */
+
+
+					/* MOCK OHCI IN SOFTWARE */
+						
+					/* Check if there is any transmission error (pid check fail, data toggle mismatch, crc fail, bitstuffing or dev not responding)
+					and number of retries is not zero then process the PTD else go to transmission error processing */
+					if(!(--(td->retry_count)) || (completion_code != TD_PIDCHECKFAIL && 
+						completion_code != TD_CC_DATATOGGLEM && completion_code  != TD_CC_CRC && 
+						completion_code != TD_CC_BITSTUFFING && completion_code != TD_DEVNOTRESP)) 
+					{
+
+
+						td->hwINFO &= ~HC_GTD_CC; /* Clear the original CC */
+						td->hwINFO |= completion_code << 28; /* Move CC into position */
+
+						/* Data Toggle */
+						/* Copy the data toggle from PTD to ED and TD if there is no error or if under run or over run (for IN transfers),
+						for others it is treated as error and some error handling mechanism should be done */
+						if (completion_code == TD_CC_NOERROR || 
+						((completion_code == TD_DATAOVERRUN || completion_code == TD_DATAUNDERRUN) && (((ram_data[5] & PTD_DIR) >> 2) == OHCI_IN))) {
+							/* Get the data toggle bit from PTD in ATL */
+							uData1 = 0;
+							uData1 = (__u32) ((ram_data[1] & PTD_TOGGLE) >> 2);
+
+							/* Set the toggle bit same as the PTD in ATL */
+							td->hwINFO &= ~HC_GTD_TLSB;    /* Clear the toggle bit */
+							td->hwINFO |= (uData1 << 24);  /* Move it into position */
+	
+							ed->hwHeadP &= ~HC_ED_TOGGLE;		/* clear the toggle bit in ED */
+							ed->hwHeadP |= (uData1 << 1);		/* copy the ptd toggle bit here */
+
+						}
+
+
+						/*******************************/
+						/* Move TDs to done-queue list */
+						/*******************************/
+
+						/* Dequeue the current TD (the first TD in the TD queue from ED */
+						ed->hwHeadP &= ~HC_ED_HEADP; 							/* Clear the head pointer */
+						ed->hwHeadP |= (td->hwNextTD & HC_GTD_NEXTTD);
+
+						/* Move the TD to the head of done queue */
+						td->hwNextTD = (__u32)ptd_map_buff->done_head;
+						ptd_map_buff->done_head = td;
+
+						/* Take out the PID token from PTD byte 5 */
+						byte_data = (ram_data[5] & PTD_DIR) >> 2;
+
+						/* Move data returned from device to the buffer for IN transfer */
+						/* The data in case of under run as well as over run is valid and we have to copy the data to td buffer */
+						if ((byte_data == OHCI_IN) && ((completion_code == TD_CC_NOERROR) ||
+						(completion_code == TD_DATAUNDERRUN ) || (completion_code == TD_DATAOVERRUN))) {
+
+							td_payload = (__u8*) td->hwCBP; 						/* Starting address */
+
+							/* Get the actual number of transferred bytes */
+							uTotal = ((__u32) (ram_data[1] & PTD_ACTUAL_BYTES98)) << 8; 		/* Bit 9..8 */
+							uTotal |= (__u32) (ram_data[0]); 								/* Bit 7..0 */
+
+							if(uTotal && td_payload) {
+								fnvPhciRamRead(phci, uTotal, HC_DIR_ADDR_INCREMENT, (ram_addr+HC_PTD_HEADER_SIZE), td_payload);
+							}
+
+						} /* if (byData == OHCI_IN) */
+
+						/* Update the Current Buffer pointer.
+						if success:: make CBP = 0 to signal that complete TD is success.
+						if underrun/overrun, update it to the received bytes so that the application knows how many bytes are transfered */
+						if( completion_code == TD_CC_NOERROR) td->hwCBP = 0;    /* To signal that last byte has been transferred */
+						else if(byte_data == OHCI_IN && (completion_code == TD_DATAUNDERRUN || completion_code == TD_DATAOVERRUN) ) {
+							td->hwCBP += bytes;
+						}
+
+						/* If the buffer rounding bit is set, and its an under run case, we treat that as success */
+						if(completion_code == TD_DATAUNDERRUN && (td->hwINFO & TD_R))
+							completion_code = TD_CC_NOERROR;
+
+						/* For any error other than success we have to halt the End Point */
+						if(completion_code != TD_CC_NOERROR)
+							td->ed->hwHeadP |= 0x00000001;
+
+						if(completion_code) {
+							printk("ATL CC = 0x%d, bytes = %d, OUT:%d retry_count = %d at fn = %x, fn_rem =%x\n",completion_code,bytes,(((ram_data[5] & PTD_DIR) >> 2) == OHCI_OUT), td->retry_count, fn, fn_rem);
+						}
+
+					} else {
+						/* ERROR_HANDLING_FIX:: */
+						/* Allt the transmission error cases are handled here.  Inverse and copy the toggle bit, 
+						copy any data if present, update current buffer pointer and don't put this in done queue so that 
+						this td is scheduled for transfer again */
+						printk("ATL retry CC = 0x%d, bytes = %d, OUT:%d retry_count = %d at fn = %x, fn_rem =%x\n",completion_code,bytes,(((ram_data[5] & PTD_DIR) >> 2) == OHCI_OUT), td->retry_count, fn, fn_rem);
+
+						byte_data = (ram_data[5] & PTD_DIR) >> 2;
+						if(byte_data == OHCI_OUT|| (byte_data == OHCI_IN )) {			/* Assuming SETUP tokens does not have this problem */
+
+							/* Get the data toggle bit from PTD in ATL */
+							uData1 = 0;
+							uData1 = (__u32) ((ram_data[1] & PTD_TOGGLE) >> 2);
+
+							/* Set the toggle bit same as the PTD in ATL */
+							td->hwINFO &= ~HC_GTD_TLSB;    /* Clear the toggle bit */
+							td->hwINFO |= (uData1 << 24);  /* Move it into position */
+	
+							ed->hwHeadP &= ~HC_ED_TOGGLE;		/* Clear the ED toggle bit */
+							ed->hwHeadP |= (uData1 << 1);		/* Move the toggle bit to ED */
+
+							/* Copy the received bytes in case of IN Transfer */
+							if(byte_data == OHCI_IN) {
+								td_payload = (__u8*) td->hwCBP; 			/* Starting address */
+									
+								if(bytes && td_payload) {
+									fnvPhciRamRead(phci, bytes, HC_DIR_ADDR_INCREMENT, (ram_addr+HC_PTD_HEADER_SIZE), td_payload);
+								}
+							}
+							td->hwCBP += bytes;						/* Update the current buffer pointer */
+						}
+								
+					}
+					td_ptd_map->td = NULL;
+				} /* if ((byData & PTD_ACTIVE) == 0) */
+
+				byte_data = ram_data[1];    /* Byte 1 of PTD contains the PTD active bit */
+				if ((byte_data & PTD_ACTIVE)) {    /* Test if the PTD is still active */
+					/* Get the actual number of transferred bytes */
+					uTotal = 0;
+					uTotal = ((__u32) (ram_data[1] & PTD_ACTUAL_BYTES98)) << 8; /* Bit 9..8 */
+					uTotal |= (__u32) (ram_data[0]); /* Bit 7..0 */
+
+				} /* if ((byData & PTD_ACTIVE) == 1) */
+
+				
+#ifdef CONFIG_USB_PHCD_PING_PONG
+				if(td_ptd_map->ping_pong == TD_PTD_PONG) {
+					ptd_map_buff->ping_pong_status &= (~TD_PTD_PONG_FILLED);
+				}
+				if(td_ptd_map->ping_pong == TD_PTD_PING) {
+					ptd_map_buff->ping_pong_status &= (~TD_PTD_PING_FILLED);
+				}
+
+				td_ptd_map->ping_pong = TD_PTD_NO_PING_PONG;
+#endif /* CONFIG_USB_PHCD_PING_PONG */
+
+			} else {		/* the ed is deleted in between */
+							/* Do nothing for this ptd */
+			}
+
+			ptd_map_buff->regs.ptd_done_map &= (~(ptd_bitmap));
+		}
+		
+		if(ping_pong_bitmap) {
+			/* higner to lower ptd scanning */
+			td_ptd_index--;
+			ptd_bitmap >>= 1;
+		} else {	
+			/* lower to higner ptd scanning */
+			td_ptd_index++;
+			ptd_bitmap <<= 1;
+		}
+
+	} /* while( ptd_map_buff->regs.ptd_done_map ) */
+
+	/* Process the done-queue list */
+	dl_done_list( phci, dl_reverse_done_list(phci,ptd_map_buff->done_head));
+	ptd_map_buff->done_head = NULL;
+
+	
+	phci_move_pending_td_ptds(ptd_map_buff);
+
+	active_ptd_bitmap = ptd_map_buff->active_ptd_bitmap;
+
+	active_ptdmap = 0;
+
+	ptd_bitmap = 0x00000001;
+	td_ptd_index = 0;
+
+
+	if(ping_pong_bitmap) {
+		ptd_bitmap <<= (TD_PTD_MAX_BUFF_TDS - 1);
+		td_ptd_index = TD_PTD_MAX_BUFF_TDS - 1;
+	}
+	
+
+
+
+	/* Update the td's in the td-ptd list for scheduling */
+	while(active_ptd_bitmap) {
+	
+		td_ptd_map = &(ptd_map_buff->map_list[td_ptd_index]);
+
+
+		if((active_ptd_bitmap & ptd_bitmap) && !(td_ptd_map->td)) {			
+			/* This ptd needs to be scheduled */
+
+			ed = td_ptd_map->ed;			
+
+			td = (td_t*)(ed->hwHeadP & 0xfffffff0);
+		
+
+
+			td_head = (ed->hwHeadP & HC_ED_HEADP);
+			td_tail = (ed->hwTailP & HC_ED_TAILP);
+
+			if(td_head != td_tail)  {
+
+#ifdef CONFIG_USB_PHCD_PING_PONG
+	
+				if( (((urb_priv_t*)(td->urb->hcpriv))->length > 1) &&
+				   ( ((td_ptd_index == ptd_map_buff->ping_ptd_index) || 
+				 	(td_ptd_index == ptd_map_buff->pong_ptd_index))) ) {
+
+					if(td->retry_count == PTD_MAX_RETRY_COUNT) 
+					{
+						/* Fresh ptd's */
+
+						if( (td_ptd_index == ptd_map_buff->ping_ptd_index) && 
+							(!(ptd_map_buff->ping_pong_status & TD_PTD_PING_FILLED) )) {
+							/* If Ping is empty , so fill ping */
+								if(ptd_map_buff->ping_pong_status & TD_PTD_PONG_FILLED) {
+								/* Already Pong PTD is in progress, so skip this PTD */
+	
+									td = (td_t*)(td->hwNex