Whamcloud - gitweb
remove outdated patches
[fs/lustre-release.git] / lustre / kernel_patches / patches / kgdb_eth.patch
diff --git a/lustre/kernel_patches/patches/kgdb_eth.patch b/lustre/kernel_patches/patches/kgdb_eth.patch
deleted file mode 100644 (file)
index 5c8eaa2..0000000
+++ /dev/null
@@ -1,1185 +0,0 @@
-Index: linux-2.6.0-test1/arch/i386/kernel/kgdb_stub.c
-===================================================================
---- linux-2.6.0-test1.orig/arch/i386/kernel/kgdb_stub.c        2003-09-02 14:16:10.000000000 +0800
-+++ linux-2.6.0-test1/arch/i386/kernel/kgdb_stub.c     2003-09-02 14:32:02.000000000 +0800
-@@ -30,6 +30,7 @@
-  *
-  *  Written by:            Glenn Engel $
-  *  Updated by:            David Grothe <dave@gcom.com>
-+ *  Updated by:            Robert Walsh <rjwalsh@durables.org>
-  *  ModuleState:     Experimental $
-  *
-  *  NOTES:         See Below $
-@@ -112,6 +113,7 @@
- #include <asm/processor.h>
- #include <linux/irq.h>
- #include <asm/desc.h>
-+#include <linux/inet.h>
- /************************************************************************
-  *
-@@ -122,8 +124,16 @@
- /* Thread reference */
- typedef unsigned char threadref[8];
--extern void putDebugChar(int);        /* write a single character      */
--extern int getDebugChar(void);        /* read and return a single char */
-+extern int tty_putDebugChar(int);     /* write a single character      */
-+extern int tty_getDebugChar(void);    /* read and return a single char */
-+extern void tty_flushDebugChar(void); /* flush pending characters      */
-+extern int eth_putDebugChar(int);     /* write a single character      */
-+extern int eth_getDebugChar(void);    /* read and return a single char */
-+extern void eth_flushDebugChar(void); /* flush pending characters      */
-+extern void gdb_eth_set_trapmode(int);
-+extern void gdb_eth_reply_arp(void);   /*send arp request */
-+extern int gdb_eth_is_initializing;
-+
- /************************************************************************/
- /* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
-@@ -264,6 +274,35 @@
- }
- /*
-+ * I/O dispatch functions...
-+ * Based upon gdb_eth, either call the ethernet
-+ * handler or the serial one..
-+ */
-+void putDebugChar(int c)
-+{
-+  if (gdb_eth == -1)
-+      tty_putDebugChar(c);
-+  else
-+      eth_putDebugChar(c);
-+}
-+
-+int getDebugChar(void)
-+{
-+  if (gdb_eth == -1)
-+      return tty_getDebugChar();
-+  else
-+      return eth_getDebugChar();
-+}
-+
-+void flushDebugChar(void)
-+{
-+    if (gdb_eth == -1)
-+      tty_flushDebugChar();
-+    else
-+      eth_flushDebugChar();
-+}
-+
-+/*
-  * Gdb calls functions by pushing agruments, including a return address 
-  * on the stack and the adjusting EIP to point to the function.        The 
-  * whole assumption in GDB is that we are on a different stack than the
-@@ -389,7 +428,6 @@
-               xmitcsum = -1;
-               count = 0;
--
-               /* now, read until a # or end of buffer is found */
-               while (count < BUFMAX) {
-                       ch = getDebugChar() & 0x7f;
-@@ -429,6 +467,7 @@
-       if (remote_debug)
-               printk("R:%s\n", buffer);
-+      flushDebugChar();
- }
- /* send the packet in buffer.  */
-@@ -441,25 +480,64 @@
-       char ch;
-       /*  $<packet info>#<checksum>. */
--      do {
--              if (remote_debug)
--                      printk("T:%s\n", buffer);
--              putDebugChar('$');
--              checksum = 0;
--              count = 0;
--
--              while ((ch = buffer[count])) {
--                      putDebugChar(ch);
--                      checksum += ch;
--                      count += 1;
--              }
--              putDebugChar('#');
--              putDebugChar(hexchars[checksum >> 4]);
--              putDebugChar(hexchars[checksum % 16]);
--
--      } while ((getDebugChar() & 0x7f) != '+');
-+      if (gdb_eth == -1){
-+              do {
-+                      if (remote_debug)
-+                              printk("T:%s\n", buffer);
-+                      putDebugChar('$');
-+                      checksum = 0;
-+                      count = 0;
-+
-+                      while ((ch = buffer[count])) {
-+                              putDebugChar(ch);
-+                              checksum += ch;
-+                              count += 1;
-+                      }
-+                      
-+                      putDebugChar('#');
-+                      putDebugChar(hexchars[checksum >> 4]);
-+                      putDebugChar(hexchars[checksum % 16]);
-+                      flushDebugChar();
-+
-+              } while ((getDebugChar() & 0x7f) != '+');
-+      }else{
-+      
-+              /*for udp, we can not transfer too much bytes once */
-+              /*we only transfer MAX_SEND_COUNT size byts each time */
-+#define MAX_SEND_COUNT 30     
-+              int send_count=0, i=0;
-+              char send_buf[30];
-+              do {
-+                      if (remote_debug)
-+                              printk("T:%s\n", buffer);
-+                      putDebugChar('$');
-+                      checksum = 0;
-+                      count = 0;
-+                      send_count = 0; 
-+                      while ((ch = buffer[count])) {
-+                              if (send_count >= MAX_SEND_COUNT){
-+                                      for(i=0; i < MAX_SEND_COUNT; i++){
-+                                              putDebugChar(send_buf[i]);
-+                                      }               
-+                                      flushDebugChar();
-+                                      send_count = 0;
-+                              }else{
-+                                      send_buf[send_count] = ch;
-+                                      checksum += ch;
-+                                      count ++;
-+                                      send_count++;
-+                              }
-+                      }
-+                      for(i=0; i < send_count; i++)
-+                              putDebugChar(send_buf[i]);
-+                      putDebugChar('#');
-+                      putDebugChar(hexchars[checksum >> 4]);
-+                      putDebugChar(hexchars[checksum % 16]);
-+                      flushDebugChar();
-+              } while ((getDebugChar() & 0x7f) != '+');
-+      }
- }
- static char remcomInBuffer[BUFMAX];
-@@ -1143,6 +1221,13 @@
-               print_regs(&regs);
-               return (0);
-       }
-+      /*
-+       * If we're using eth mode, set the 'mode' in the netdevice.
-+       */
-+
-+      if(gdb_eth != -1) {
-+              gdb_eth_set_trapmode(1);
-+      }
-       kgdb_local_irq_save(flags);
-@@ -1156,8 +1241,8 @@
-        * NMI and will wait there for the following spin locks to be 
-        * released.
-        */
-+      
- #ifdef CONFIG_SMP
--
- #if 0
-       if (cpu_callout_map & ~MAX_CPU_MASK) {
-               printk("kgdb : too many cpus, possibly not mapped"
-@@ -1372,6 +1457,7 @@
-       gdb_i386vector = exceptionVector;
-       gdb_i386errcode = err_code;
-       kgdb_info.called_from = __builtin_return_address(0);
-+
- #ifdef CONFIG_SMP
-       /*
-        * OK, we can now communicate, lets tell gdb about the sync.
-@@ -1400,8 +1486,13 @@
-       remcomOutBuffer[2] = hexchars[signo % 16];
-       remcomOutBuffer[3] = 0;
--      putpacket(remcomOutBuffer);
-+      if (gdb_eth_is_initializing) {
-+              gdb_eth_is_initializing = 0;
-+      } else {
-+              putpacket(remcomOutBuffer);
-+      }
-+      gdb_eth_reply_arp();
-       while (1 == 1) {
-               error = 0;
-               remcomOutBuffer[0] = 0;
-@@ -1419,7 +1510,9 @@
-                              remote_debug ? "on" : "off");
-                       break;
-               case 'g':       /* return the value of the CPU registers */
-+                      
-                       get_gdb_regs(usethread, &regs, gdb_regs);
-+                      
-                       mem2hex((char *) gdb_regs,
-                               remcomOutBuffer, NUMREGBYTES, 0);
-                       break;
-@@ -1536,6 +1629,10 @@
-                       newPC = regs.eip;
-+                      if (gdb_eth != -1) {
-+                              gdb_eth_set_trapmode(0);
-+                      }
-+
-                       /* clear the trace bit */
-                       regs.eflags &= 0xfffffeff;
-@@ -1856,9 +1953,7 @@
-               kgdb_local_irq_restore(flags);
-               return (0);
-       }
--#if 0
--exit_just_unlock:
--#endif
-+      exit_just_unlock:
- #endif
-       /* Release kgdb spinlock */
-       KGDB_SPIN_UNLOCK(&kgdb_spinlock);
-@@ -2213,3 +2308,72 @@
- typedef int gdb_debug_hook(int exceptionVector,
-                          int signo, int err_code, struct pt_regs *linux_regs);
- gdb_debug_hook *linux_debug_hook = &kgdb_handle_exception;    /* histerical reasons... */
-+
-+static int __init kgdb_opt_gdbeth(char *str)
-+{
-+      gdb_eth = simple_strtoul(str,NULL,10);
-+      return 1;
-+}
-+
-+static int __init kgdb_opt_gdbeth_remote(char *str)
-+{
-+      gdb_ethremote = in_aton(str);
-+      return 1;
-+}
-+
-+static int __init kgdb_opt_gdbeth_listen(char *str)
-+{
-+      gdb_listenport = simple_strtoul(str,NULL,10);
-+      return 1;
-+}
-+
-+static int __init kgdb_opt_gdbeth_hwaddr(char *str)
-+{
-+      int  i;
-+      char *p;
-+
-+      p = str;
-+      i = 0;
-+      while(1)
-+      {
-+              unsigned int c;
-+              sscanf(p, "%x:", &c);
-+              gdb_sendhwaddr[i++] = c;
-+              while((*p != 0) && (*p != ':'))
-+                      p++;
-+              if (*p == 0)
-+                      break;
-+              p++;
-+      }
-+
-+      return 1;
-+}
-+static int __init kgdb_opt_gdbeth_rchwaddr(char *str)
-+{
-+      int  i;
-+      char *p;
-+
-+      p = str;
-+      i = 0;
-+      while(1)
-+      {
-+              unsigned int c;
-+              sscanf(p, "%x:", &c);
-+              gdb_receivehwaddr[i++] = c;
-+              while((*p != 0) && (*p != ':'))
-+                      p++;
-+              if (*p == 0)
-+                      break;
-+              p++;
-+      }
-+
-+      return 1;
-+}
-+
-+
-+__setup("gdbeth=", kgdb_opt_gdbeth);
-+__setup("gdbeth_remote=", kgdb_opt_gdbeth_remote);
-+__setup("gdbeth_listenport=", kgdb_opt_gdbeth_listen);
-+__setup("gdbeth_sendhwaddr=", kgdb_opt_gdbeth_hwaddr);
-+__setup("gdbeth_receivehwaddr=", kgdb_opt_gdbeth_rchwaddr);
-+
-Index: linux-2.6.0-test1/arch/i386/lib/kgdb_serial.c
-===================================================================
---- linux-2.6.0-test1.orig/arch/i386/lib/kgdb_serial.c 2003-09-02 14:16:11.000000000 +0800
-+++ linux-2.6.0-test1/arch/i386/lib/kgdb_serial.c      2003-09-02 14:32:02.000000000 +0800
-@@ -155,12 +155,12 @@
-  * It will receive a limited number of characters of input
-  * from the gdb  host machine and save them up in a buffer.
-  *
-- * When the gdb stub routine getDebugChar() is called it
-+ * When the gdb stub routine tty_getDebugChar() is called it
-  * draws characters out of the buffer until it is empty and
-  * then reads directly from the serial port.
-  *
-  * We do not attempt to write chars from the interrupt routine
-- * since the stubs do all of that via putDebugChar() which
-+ * since the stubs do all of that via tty_putDebugChar() which
-  * writes one byte after waiting for the interface to become
-  * ready.
-  *
-@@ -226,7 +226,7 @@
- /*
-  * Hook an IRQ for KGDB.
-  *
-- * This routine is called from putDebugChar, below.
-+ * This routine is called from tty_putDebugChar, below.
-  */
- static int ints_disabled = 1;
- int
-@@ -331,7 +331,7 @@
- }
- /*
-- * getDebugChar
-+ * tty_getDebugChar
-  *
-  * This is a GDB stub routine.        It waits for a character from the
-  * serial interface and then returns it.  If there is no serial
-@@ -345,11 +345,11 @@
- /* Caller takes needed protections */
- int
--getDebugChar(void)
-+tty_getDebugChar(void)
- {
-       volatile int chr, dum, time, end_time;
--      dbprintk(("getDebugChar(port %x): ", gdb_async_info->port));
-+      dbprintk(("tty_getDebugChar(port %x): ", gdb_async_info->port));
-       if (gdb_async_info == NULL) {
-               gdb_hook_interrupt(&local_info, 0);
-@@ -375,7 +375,7 @@
-       dbprintk(("%c\n", chr > ' ' && chr < 0x7F ? chr : ' '));
-       return (chr);
--}                             /* getDebugChar */
-+}                             /* tty_getDebugChar */
- static int count = 3;
- static spinlock_t one_at_atime = SPIN_LOCK_UNLOCKED;
-@@ -383,6 +383,9 @@
- static int __init
- kgdb_enable_ints(void)
- {
-+      if (gdb_eth != -1) {
-+              return 0;
-+      }
-       if (gdb_async_info == NULL) {
-               gdb_hook_interrupt(&local_info, 1);
-       }
-@@ -444,7 +447,7 @@
- }
- /*
-- * putDebugChar
-+ * tty_putDebugChar
-  *
-  * This is a GDB stub routine.        It waits until the interface is ready
-  * to transmit a char and then sends it.  If there is no serial
-@@ -452,9 +455,9 @@
-  * pretended to send the char.        Caller takes needed protections.
-  */
- void
--putDebugChar(int chr)
-+tty_putDebugChar(int chr)
- {
--      dbprintk(("putDebugChar(port %x): chr=%02x '%c', ints_on=%d\n",
-+      dbprintk(("tty_putDebugChar(port %x): chr=%02x '%c', ints_on=%d\n",
-                 gdb_async_info->port,
-                 chr,
-                 chr > ' ' && chr < 0x7F ? chr : ' ', ints_disabled ? 0 : 1));
-@@ -480,6 +483,14 @@
-               }
-       }
--}                             /* putDebugChar */
-+}                             /* tty_putDebugChar */
-+
-+/*
-+ * This does nothing for the serial port, since it doesn't buffer.
-+ */
-+
-+void tty_flushDebugChar(void)
-+{
-+}
- module_init(kgdb_enable_ints);
-Index: linux-2.6.0-test1/include/linux/netdevice.h
-===================================================================
---- linux-2.6.0-test1.orig/include/linux/netdevice.h   2003-09-02 14:29:27.000000000 +0800
-+++ linux-2.6.0-test1/include/linux/netdevice.h        2003-09-02 14:32:02.000000000 +0800
-@@ -469,6 +469,11 @@
-       /* statistics sub-directory */
-       struct kobject          stats_kobj;
-+
-+#ifdef CONFIG_KGDB
-+      int                     kgdb_is_trapped;
-+      void                    (*kgdb_net_poll_rx)(struct net_device *);
-+#endif
- };
- #define SET_MODULE_OWNER(dev) do { } while (0)
-@@ -524,6 +529,11 @@
- extern struct net_device      *dev_get_by_index(int ifindex);
- extern struct net_device      *__dev_get_by_index(int ifindex);
- extern int            dev_restart(struct net_device *dev);
-+#ifdef CONFIG_KGDB
-+int           gdb_eth_is_trapped(void);
-+int           gdb_net_interrupt(struct sk_buff *skb);
-+void          gdb_send_arp_request(void);
-+#endif
- typedef int gifconf_func_t(struct net_device * dev, char * bufptr, int len);
- extern int            register_gifconf(unsigned int family, gifconf_func_t * gifconf);
-@@ -582,12 +592,20 @@
- static inline void netif_wake_queue(struct net_device *dev)
- {
-+#ifdef CONFIG_KGDB
-+      if (gdb_eth_is_trapped())
-+              return;
-+#endif
-       if (test_and_clear_bit(__LINK_STATE_XOFF, &dev->state))
-               __netif_schedule(dev);
- }
- static inline void netif_stop_queue(struct net_device *dev)
- {
-+#ifdef CONFIG_KGDB
-+      if (gdb_eth_is_trapped())
-+              return;
-+#endif
-       set_bit(__LINK_STATE_XOFF, &dev->state);
- }
-Index: linux-2.6.0-test1/include/asm-i386/kgdb.h
-===================================================================
---- linux-2.6.0-test1.orig/include/asm-i386/kgdb.h     2003-09-02 14:16:20.000000000 +0800
-+++ linux-2.6.0-test1/include/asm-i386/kgdb.h  2003-09-02 14:32:03.000000000 +0800
-@@ -18,6 +18,16 @@
- #ifndef BREAKPOINT
- #define BREAKPOINT   asm("   int $3")
- #endif
-+
-+extern int gdb_eth;
-+extern unsigned gdb_ethremote;
-+extern unsigned short gdb_listenport;
-+extern unsigned char gdb_sendhwaddr[6];
-+extern unsigned char gdb_receivehwaddr[6];
-+
-+extern int gdb_tty_hook(void);
-+extern int gdb_eth_hook(void);
-+
- /*
-  * GDB debug stub (or any debug stub) can point the 'linux_debug_hook'
-  * pointer to its routine and it will be entered as the first thing
-@@ -34,6 +44,7 @@
- extern int kgdb_handle_exception(int trapno,
-                                int signo, int err_code, struct pt_regs *regs);
- extern int in_kgdb(struct pt_regs *regs);
-+extern void kgdb_null(void);
- #ifdef CONFIG_KGDB_TS
- void kgdb_tstamp(int line, char *source, int data0, int data1);
-Index: linux-2.6.0-test1/drivers/net/e100/e100_main.c
-===================================================================
---- linux-2.6.0-test1.orig/drivers/net/e100/e100_main.c        2003-09-02 14:29:27.000000000 +0800
-+++ linux-2.6.0-test1/drivers/net/e100/e100_main.c     2003-09-02 14:32:03.000000000 +0800
-@@ -567,6 +567,15 @@
- }
- #endif
-+#ifdef CONFIG_KGDB
-+static void e100_rx_poll(struct net_device *dev)
-+{
-+      disable_irq(dev->irq);
-+      e100intr(dev->irq, (void *)dev, 0);
-+      enable_irq(dev->irq);
-+}
-+#endif
-+
- static int __devinit
- e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
- {
-@@ -662,7 +671,9 @@
-       dev->set_multicast_list = &e100_set_multi;
-       dev->set_mac_address = &e100_set_mac;
-       dev->do_ioctl = &e100_ioctl;
--
-+#ifdef CONFIG_KGDB
-+      dev->kgdb_net_poll_rx = e100_rx_poll;
-+#endif
-       if (bdp->flags & USE_IPCB)
-       dev->features = NETIF_F_SG | NETIF_F_HW_CSUM |
-                       NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-Index: linux-2.6.0-test1/drivers/net/3c59x.c
-===================================================================
---- linux-2.6.0-test1.orig/drivers/net/3c59x.c 2003-09-02 14:29:27.000000000 +0800
-+++ linux-2.6.0-test1/drivers/net/3c59x.c      2003-09-02 14:32:03.000000000 +0800
-@@ -1063,6 +1063,22 @@
-       return rc;
- }
-+#ifdef CONFIG_KGDB
-+static void vortex_rx_poll(struct net_device *dev)
-+{
-+      disable_irq(dev->irq);
-+      vortex_interrupt(dev->irq, (void *)dev, 0);
-+      enable_irq(dev->irq);
-+}
-+
-+static void boomerang_rx_poll(struct net_device *dev)
-+{
-+      disable_irq(dev->irq);
-+      boomerang_interrupt(dev->irq, (void *)dev, 0);
-+      enable_irq(dev->irq);
-+}
-+#endif
-+
- /*
-  * Start up the PCI/EISA device which is described by *gendev.
-  * Return 0 on success.
-@@ -1449,6 +1465,14 @@
-       dev->set_multicast_list = set_rx_mode;
-       dev->tx_timeout = vortex_tx_timeout;
-       dev->watchdog_timeo = (watchdog * HZ) / 1000;
-+#ifdef CONFIG_KGDB
-+      if (vp->full_bus_master_tx) {
-+              dev->kgdb_net_poll_rx = boomerang_rx_poll;
-+      } else {
-+              dev->kgdb_net_poll_rx = vortex_rx_poll;
-+      }
-+#endif
-+
- #ifdef HAVE_POLL_CONTROLLER
-       dev->poll_controller = &vorboom_poll;
- #endif
-Index: linux-2.6.0-test1/drivers/net/Makefile
-===================================================================
---- linux-2.6.0-test1.orig/drivers/net/Makefile        2003-07-14 11:32:32.000000000 +0800
-+++ linux-2.6.0-test1/drivers/net/Makefile     2003-09-02 14:32:03.000000000 +0800
-@@ -32,6 +32,8 @@
- obj-$(CONFIG_OAKNET) += oaknet.o 8390.o
-+obj-$(CONFIG_KGDB) += kgdb_eth.o
-+
- obj-$(CONFIG_DGRS) += dgrs.o
- obj-$(CONFIG_RCPCI) += rcpci.o
- obj-$(CONFIG_VORTEX) += 3c59x.o
-Index: linux-2.6.0-test1/drivers/net/kgdb_eth.c
-===================================================================
---- linux-2.6.0-test1.orig/drivers/net/kgdb_eth.c      2003-09-02 14:32:02.000000000 +0800
-+++ linux-2.6.0-test1/drivers/net/kgdb_eth.c   2003-09-02 21:41:42.000000000 +0800
-@@ -0,0 +1,547 @@
-+/*
-+ * Network interface GDB stub
-+ *
-+ * Written by San Mehat (nettwerk@biodome.org)
-+ * Based upon 'gdbserial' by David Grothe (dave@gcom.com)
-+ * and Scott Foehner (sfoehner@engr.sgi.com)
-+ *
-+ * Twiddled for 2.5 by Robert Walsh (rjwalsh@durables.org)
-+ *
-+ */
-+ 
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/signal.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/interrupt.h>
-+#include <linux/config.h>
-+#include <linux/major.h>
-+#include <linux/string.h>
-+#include <linux/fcntl.h>
-+#include <linux/termios.h>
-+#include <linux/workqueue.h>
-+#include <asm/kgdb.h>
-+#include <linux/if_ether.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/skbuff.h>
-+#include <linux/delay.h>
-+#include <net/tcp.h>
-+#include <net/udp.h>
-+
-+#include <asm/system.h>
-+#include <asm/io.h>
-+#include <asm/segment.h>
-+#include <asm/bitops.h>
-+#include <asm/system.h>
-+#include <asm/irq.h>
-+#include <asm/atomic.h>
-+
-+#undef        PRNT                            /* define for debug printing */
-+
-+#define       GDB_BUF_SIZE    512             /* power of 2, please */
-+
-+static char   gdb_buf[GDB_BUF_SIZE] ;
-+static int    gdb_buf_in_inx ;
-+static atomic_t       gdb_buf_in_cnt ;
-+static int    gdb_buf_out_inx ;
-+
-+extern void   set_debug_traps(void) ;         /* GDB routine */
-+extern void     breakpoint(void);
-+
-+unsigned int    gdb_ethremote = 0;
-+unsigned short  gdb_listenport = 6443;
-+unsigned short  gdb_sendport= 6442;
-+int             gdb_eth = -1; /* Default tty mode */
-+unsigned char   gdb_sendhwaddr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
-+unsigned char   gdb_receivehwaddr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
-+int             gdb_eth_is_initializing = 0;
-+int           gdb_eth_debug = 0;
-+
-+struct net_device *gdb_netdevice = NULL;
-+
-+//static int      initialized = -1;
-+//static struct work_struct irq_bp;
-+
-+static void bpwork_func(void *p)
-+{
-+    udelay(500);
-+    BREAKPOINT;
-+}
-+
-+static struct workqueue_struct *irq_bp;
-+DECLARE_WORK(bpwork, bpwork_func, NULL);
-+
-+/*
-+ * Get a char if available, return -1 if nothing available.
-+ * Empty the receive buffer first, then look at the interface hardware.
-+ */
-+static int read_char(void)
-+{
-+    
-+    if (atomic_read(&gdb_buf_in_cnt) != 0) /* intr routine has q'd chars */
-+    {
-+      int chr ;
-+
-+      chr = gdb_buf[gdb_buf_out_inx++] ;
-+      gdb_buf_out_inx &= (GDB_BUF_SIZE - 1) ;
-+      atomic_dec(&gdb_buf_in_cnt) ;
-+      return chr;
-+    }
-+    return -1; // no data
-+} /* read_char */
-+
-+//static unsigned char daddr[6] = {0x00,0x06,0x25,0xA9,0x9F,0x6A};
-+//static unsigned char daddr[6] = {0x00,0x50,0xFC,0xB8,0x22,0x03};
-+//static unsigned char daddr[6] = {0x00,0x08,0x74,0x96,0x6D,0x9B};
-+//static unsigned char daddr[6] = {0x00,0x07,0xE9,0xD4,0xBE,0x85};
-+//static unsigned char daddr[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
-+
-+/*
-+ * Wait until the interface can accept a char, then write it.
-+ */
-+static void write_buffer(char *buf, int len)
-+{
-+    int              total_len, eth_len, ip_len, udp_len;
-+    struct in_device *in_dev;
-+    struct sk_buff   *skb;
-+    struct udphdr    *udph;
-+    struct iphdr     *iph;
-+    struct ethhdr    *eth;
-+
-+    if (!(in_dev = (struct in_device *) gdb_netdevice->ip_ptr)) 
-+      panic("No in_device available for interface!\n");
-+    if (!(in_dev->ifa_list))
-+      panic("No interface address set for interface!\n");
-+    udp_len = len + sizeof(struct udphdr);
-+    ip_len = eth_len = udp_len + sizeof(struct iphdr);
-+    total_len = eth_len + ETH_HLEN;
-+
-+    if (!(skb = alloc_skb(total_len, GFP_ATOMIC)))
-+      return;
-+
-+    atomic_set(&skb->users, 1);
-+    skb_reserve(skb, total_len - 1);
-+
-+    memcpy(skb->data , (unsigned char *) buf, len);
-+    skb->len += len;
-+
-+    udph = (struct udphdr *) skb_push(skb, sizeof(*udph));
-+    udph->source = htons(gdb_listenport);
-+    udph->dest   = htons(gdb_sendport);
-+    udph->len    = htons(udp_len);
-+    udph->check  = 0;
-+  
-+    iph = (struct iphdr *)skb_push(skb, sizeof(*iph));
-+    iph->version = 4;
-+    iph->ihl     = 5;
-+    iph->tos     = 0;
-+    iph->tot_len = htons(ip_len);
-+    iph->id      = 0;
-+    iph->frag_off= 0;
-+    iph->ttl     = 64;
-+    iph->protocol= IPPROTO_UDP;
-+    iph->check   = 0;
-+    iph->saddr   = in_dev->ifa_list->ifa_address;
-+    iph->daddr   = gdb_ethremote;
-+    iph->check   = ip_fast_csum((unsigned char *)iph, iph->ihl);
-+
-+    eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
-+    eth->h_proto = htons(ETH_P_IP);
-+    memcpy(eth->h_source, gdb_sendhwaddr, gdb_netdevice->addr_len);
-+//    memcpy(eth->h_dest, daddr, gdb_netdevice->addr_len);
-+    memcpy(eth->h_dest, gdb_receivehwaddr, gdb_netdevice->addr_len);
-+
-+#if 0 
-+repeat_poll:
-+#endif
-+    spin_lock(&gdb_netdevice->xmit_lock);
-+    gdb_netdevice->xmit_lock_owner = smp_processor_id();
-+#if 0 
-+    if (netif_queue_stopped(gdb_netdevice))
-+    {
-+      gdb_netdevice->xmit_lock_owner = -1;
-+      spin_unlock(&gdb_netdevice->xmit_lock);
-+      gdb_netdevice->poll_controller(gdb_netdevice);
-+      zap_completion_queue();
-+      goto repeat_poll;
-+    }
-+#endif
-+    gdb_netdevice->hard_start_xmit(skb, gdb_netdevice);
-+    gdb_netdevice->xmit_lock_owner = -1;
-+    spin_unlock(&gdb_netdevice->xmit_lock);
-+
-+   // kfree_skb(skb);
-+} /* write_char */
-+/* in interrupt state the target machine will not response the arp request */ 
-+
-+static struct sk_buff *send_skb = NULL;
-+void gdb_eth_reply_arp(void)
-+{
-+      if (send_skb){
-+#if 0 
-+repeat_poll:
-+#endif
-+              spin_lock(&gdb_netdevice->xmit_lock);
-+              gdb_netdevice->xmit_lock_owner = smp_processor_id();
-+#if 0 
-+              if (netif_queue_stopped(gdb_netdevice)){
-+                      gdb_netdevice->xmit_lock_owner = -1;
-+                      spin_unlock(&gdb_netdevice->xmit_lock);
-+                      gdb_netdevice->poll_controller(gdb_netdevice);
-+                      zap_completion_queue();
-+                      goto repeat_poll;
-+              }
-+#endif
-+              gdb_netdevice->hard_start_xmit(send_skb, gdb_netdevice);
-+              gdb_netdevice->xmit_lock_owner = -1;
-+              spin_unlock(&gdb_netdevice->xmit_lock);
-+              send_skb = NULL;        
-+      
-+      }
-+}
-+static int make_arp_request( struct sk_buff *skb)
-+{
-+      struct arphdr *arp;
-+      unsigned char *arp_ptr;
-+      int type = ARPOP_REPLY;
-+      int ptype = ETH_P_ARP;
-+      u32 sip, tip;
-+      unsigned char *sha, *tha;
-+      struct in_device *in_dev = (struct in_device *) gdb_netdevice->ip_ptr; 
-+      /*
-+       *      No arp on this interface.
-+       */
-+      if (gdb_netdevice->flags &IFF_NOARP)
-+              return 0;
-+      if (!pskb_may_pull(skb, (sizeof(struct arphdr) +
-+                               (2 * gdb_netdevice->addr_len) +
-+                               (2 * sizeof(u32)))))
-+              return 0;
-+      
-+      skb->h.raw = skb->nh.raw = skb->data;
-+      arp = skb->nh.arph;
-+
-+      if ((arp->ar_hrd != htons(ARPHRD_ETHER) &&
-+           arp->ar_hrd != htons(ARPHRD_IEEE802)) ||
-+          arp->ar_pro != htons(ETH_P_IP))
-+              return 0;
-+
-+/* Understand only these message types */
-+
-+      if (arp->ar_op != htons(ARPOP_REQUEST))
-+              return 0;
-+/*
-+ *    Extract fields
-+ */
-+      arp_ptr= (unsigned char *)(arp+1);
-+      sha     = arp_ptr;
-+      arp_ptr += gdb_netdevice->addr_len;
-+      memcpy(&sip, arp_ptr, 4);
-+      arp_ptr += 4;
-+      tha     = arp_ptr;
-+      arp_ptr += gdb_netdevice->addr_len;
-+      memcpy(&tip, arp_ptr, 4);
-+      if (tip != in_dev->ifa_list->ifa_address){
-+              return 0;
-+      } 
-+      if (gdb_ethremote != sip){
-+              return 0;       
-+      }
-+/* 
-+ *    Check for bad requests for 127.x.x.x and requests for multicast
-+ *    addresses.  If this is one such, delete it.
-+ */
-+      
-+      if (LOOPBACK(tip) || MULTICAST(tip))
-+              return 0;
-+
-+/*
-+ *      reply the arp request
-+ */   
-+      send_skb = alloc_skb(sizeof(struct arphdr)+ 2*(gdb_netdevice->addr_len+4)
-+                              + LL_RESERVED_SPACE(gdb_netdevice), GFP_ATOMIC);
-+      if (send_skb == NULL)
-+              return 0;
-+
-+      skb_reserve(send_skb, LL_RESERVED_SPACE(gdb_netdevice));
-+      send_skb->nh.raw = send_skb->data;
-+      arp = (struct arphdr *) skb_put(send_skb,sizeof(struct arphdr) + 2*(gdb_netdevice->addr_len+4));
-+      send_skb->dev = gdb_netdevice;
-+      send_skb->protocol = htons(ETH_P_ARP);
-+      
-+      /*
-+       *      Fill the device header for the ARP frame
-+       */
-+      if (gdb_netdevice->hard_header &&
-+          gdb_netdevice->hard_header(send_skb,  gdb_netdevice,  ptype, gdb_receivehwaddr, gdb_sendhwaddr, send_skb->len) < 0){
-+              kfree_skb(send_skb);
-+              return 0;
-+      }
-+      /*
-+       * Fill out the arp protocol part.
-+       *
-+       * we only support ethernet device type, 
-+       * which (according to RFC 1390) should always equal 1 (Ethernet).
-+       */
-+      arp->ar_hrd = htons(gdb_netdevice->type);
-+      arp->ar_pro = htons(ETH_P_IP);
-+
-+      arp->ar_hln = gdb_netdevice->addr_len;
-+      arp->ar_pln = 4;
-+      arp->ar_op = htons(type);
-+
-+      arp_ptr=(unsigned char *)(arp+1);
-+
-+      memcpy(arp_ptr, gdb_netdevice->dev_addr, gdb_netdevice->addr_len); 
-+      arp_ptr += gdb_netdevice->addr_len;
-+      memcpy(arp_ptr, &tip, 4);
-+      arp_ptr += 4;
-+        memcpy(arp_ptr, gdb_sendhwaddr, gdb_netdevice->addr_len);
-+      arp_ptr+=gdb_netdevice->addr_len;
-+      memcpy(arp_ptr, &sip, 4);
-+      return 0;
-+}
-+/*
-+ * Accept an skbuff from net_device layer and 
-+ * add the payload onto gdb buffer
-+ *
-+ * When the gdb stub routine getDebugChar() is called it
-+ * draws characters out of the buffer until it is empty and
-+ * then reads directly from the serial port.
-+ *
-+ * We do not attempt to write chars from the interrupt routine
-+ * since the stubs do all of that via putDebugChar() which
-+ * writes one byte after waiting for the interface to become
-+ * ready.
-+ *
-+ * The debug stubs like to run with interrupts disabled since,
-+ * after all, they run as a consequence of a breakpoint in
-+ * the kernel.
-+ *
-+ * NOTE: Return value of 1 means it was for us and is an
-+ * indication to the calling driver to destroy the sk_buff
-+ * and not send it up the stack
-+ */
-+
-+int gdb_net_interrupt(struct sk_buff *skb)
-+{
-+    unsigned char  chr;
-+    struct iphdr   *iph = (struct iphdr*)skb->data;
-+    struct udphdr  *udph= (struct udphdr*)(skb->data+(iph->ihl<<2));
-+    unsigned char  *data = (unsigned char *) udph + sizeof(struct udphdr);
-+    int            len;
-+    int            i;
-+
-+    if ((gdb_eth != -1) && (!gdb_netdevice) &&
-+      (iph->protocol == IPPROTO_UDP) &&
-+      (be16_to_cpu(udph->dest) == gdb_listenport)) {
-+      gdb_sendport = be16_to_cpu(udph->source);
-+      
-+        while(gdb_eth_is_initializing);
-+      if(!gdb_netdevice)
-+          gdb_eth_hook();
-+      if (!gdb_netdevice) {
-+          /* Lets not even try again. */
-+          gdb_eth = -1;
-+          return 0;
-+      }
-+    }
-+    if (!gdb_netdevice) {
-+      return 0;
-+    }
-+    if (skb->protocol == __constant_htons(ETH_P_ARP) && !send_skb){
-+      make_arp_request(skb);
-+      return 0;
-+    }
-+    if (iph->protocol != IPPROTO_UDP)
-+      return 0;
-+
-+    if (be16_to_cpu(udph->dest) != gdb_listenport)
-+      return 0;
-+
-+    len = be16_to_cpu(iph->tot_len) - (sizeof(struct udphdr) +
-+                                     sizeof(struct iphdr));
-+    for (i = 0; i < len; i++)
-+    {
-+      chr = *data++;
-+      if (chr == 3)
-+      {
-+          queue_work(irq_bp, &bpwork);
-+//        flush_workqueue(irq_bp);
-+          continue;
-+/*
-+          if (!in_interrupt())
-+          {
-+              breakpoint();
-+          }
-+          else
-+          {
-+              schedule_work(&irq_bp); // XXX: is this really necessary??
-+          }
-+          continue;
-+*/
-+      }
-+      if (atomic_read(&gdb_buf_in_cnt) >= GDB_BUF_SIZE)
-+      {                               /* buffer overflow, clear it */
-+          gdb_buf_in_inx = 0 ;
-+          atomic_set(&gdb_buf_in_cnt, 0) ;
-+          gdb_buf_out_inx = 0 ;
-+          break ;
-+      }
-+      gdb_buf[gdb_buf_in_inx++] = chr ;
-+      gdb_buf_in_inx &= (GDB_BUF_SIZE - 1) ;
-+      atomic_inc(&gdb_buf_in_cnt) ;
-+    }
-+
-+    return 1;
-+} /* gdb_interrupt */
-+
-+
-+int gdb_eth_hook(void)
-+{
-+    char gdb_netdev[16];
-+    extern void kgdb_respond_ok(void);
-+
-+    if (gdb_sendhwaddr[0] == 0xff)
-+      panic("ERROR! 'gdbeth_sendhwaddr' option not set!\n");
-+    if (gdb_receivehwaddr[0] == 0xff)
-+      panic("ERROR! 'gdbeth_receivehwaddr' option not set!\n");
-+    if (gdb_ethremote == 0)
-+      panic("ERROR! 'gdbeth_remote' option not set!\n");
-+
-+    sprintf(gdb_netdev,"eth%d",gdb_eth);
-+
-+#ifdef CONFIG_SMP
-+    if (num_online_cpus() > CONFIG_NO_KGDB_CPUS){ 
-+      printk("kgdb: too manu cpus. Cannot enable debugger with more than %d cpus\n", CONFIG_NO_KGDB_CPUS);
-+      return -1;
-+    }
-+#endif
-+    for (gdb_netdevice = dev_base;
-+       gdb_netdevice != NULL; 
-+       gdb_netdevice = gdb_netdevice->next){
-+      if (strncmp(gdb_netdevice->name, gdb_netdev, IFNAMSIZ) == 0)
-+          break;
-+    }
-+    if (!gdb_netdevice){
-+      printk("KGDB NET : Unable to find interface %s\n",gdb_netdev);
-+      return -ENODEV;
-+    }
-+
-+    /*
-+     * Call GDB routine to setup the exception vectors for the debugger
-+     */
-+    set_debug_traps() ;
-+
-+    /*
-+     * Call the breakpoint() routine in GDB to start the debugging
-+     * session.
-+     */
-+     if (gdb_eth_debug){
-+          printk(KERN_INFO "Waiting for remote gdb connection from %x on local port %d\n",
-+                 gdb_ethremote, gdb_listenport);
-+          printk(KERN_INFO "We are sending on port %d to %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
-+                 gdb_sendport,
-+                 gdb_sendhwaddr[0],
-+                 gdb_sendhwaddr[1],
-+                 gdb_sendhwaddr[2],
-+                 gdb_sendhwaddr[3],
-+                 gdb_sendhwaddr[4],
-+                 gdb_sendhwaddr[5]);
-+          printk("Connected.\n");
-+    }
-+    gdb_eth_is_initializing = 1;
-+    queue_work(irq_bp, &bpwork);
-+    return 0;
-+} /* gdb_hook_interrupt2 */
-+
-+/*
-+ * getDebugChar
-+ *
-+ * This is a GDB stub routine.  It waits for a character from the
-+ * serial interface and then returns it.  If there is no serial
-+ * interface connection then it returns a bogus value which will
-+ * almost certainly cause the system to hang.
-+ */
-+int eth_getDebugChar(void)
-+{
-+    volatile int      chr ;
-+
-+    while((chr = read_char()) < 0)
-+    {
-+      if (send_skb){
-+              gdb_eth_reply_arp();    
-+        }
-+      if (gdb_netdevice->kgdb_net_poll_rx)
-+          gdb_netdevice->kgdb_net_poll_rx(gdb_netdevice);
-+      else
-+        {
-+          printk("KGDB NET: Error - Device %s is not supported!\n",
-+                 gdb_netdevice->name);
-+          panic("Please add support for kgdb net to this driver");
-+        }
-+    }
-+    return chr;
-+
-+} /* eth_getDebugChar */
-+
-+#define ETH_QUEUE_SIZE 256
-+static char eth_queue[ETH_QUEUE_SIZE];
-+static int outgoing_queue;
-+
-+void eth_flushDebugChar(void)
-+{
-+    if(outgoing_queue) {
-+      write_buffer(eth_queue, outgoing_queue);
-+
-+      outgoing_queue = 0;
-+    }
-+}
-+
-+static void put_char_on_queue(int chr)
-+{
-+    eth_queue[outgoing_queue++] = chr;
-+    if(outgoing_queue == ETH_QUEUE_SIZE)
-+    {
-+      eth_flushDebugChar();
-+    }
-+}
-+
-+/*
-+ * eth_putDebugChar
-+ *
-+ * This is a GDB stub routine.  It waits until the interface is ready
-+ * to transmit a char and then sends it.
-+ */
-+void eth_putDebugChar(int chr)
-+{
-+    if (gdb_eth_debug)
-+      printk(KERN_INFO "eth_putDebugChar: chr=%02x '%c'\n", chr,
-+              chr > ' ' && chr < 0x7F ? chr : ' ') ;
-+    put_char_on_queue(chr) ;  /* this routine will wait */
-+} /* putDebugChar */
-+
-+void gdb_eth_set_trapmode(int mode)
-+{
-+    if (!gdb_netdevice)
-+      return;
-+    gdb_netdevice->kgdb_is_trapped = mode;
-+}
-+
-+int gdb_eth_is_trapped()
-+{
-+    if (!gdb_netdevice)
-+      return 0;
-+    return gdb_netdevice->kgdb_is_trapped;
-+}
-+
-+static int __init
-+kgdb_eth_init(void)
-+{
-+    irq_bp = create_workqueue("kgdb");
-+    return 0;
-+}
-+
-+module_init(kgdb_eth_init);
-Index: linux-2.6.0-test1/net/core/dev.c
-===================================================================
---- linux-2.6.0-test1.orig/net/core/dev.c      2003-09-02 14:29:27.000000000 +0800
-+++ linux-2.6.0-test1/net/core/dev.c   2003-09-02 14:32:03.000000000 +0800
-@@ -188,7 +188,9 @@
- extern int netdev_sysfs_init(void);
- extern int netdev_register_sysfs(struct net_device *);
- extern void netdev_unregister_sysfs(struct net_device *);
--
-+#ifdef CONFIG_KGDB
-+extern int gdb_net_interrupt(struct sk_buff *skb);
-+#endif
- /*******************************************************************************
-@@ -1349,6 +1351,21 @@
-       struct softnet_data *queue;
-       unsigned long flags;
-+#ifdef CONFIG_KGDB
-+      /* See if kgdb_eth wants this packet */
-+      if (!gdb_net_interrupt(skb)) {
-+              /* No.. if we're 'trapped' then junk it */
-+              if (gdb_eth_is_trapped()) {
-+                      kfree_skb(skb);
-+                      return NET_RX_DROP;
-+              }
-+      } else {
-+              /* kgdb_eth ate the packet... drop it silently */
-+              kfree_skb(skb);
-+              return NET_RX_DROP;
-+      }
-+#endif
-+
-       /*
-        * The code is rearranged so that the path is the most