-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(®s);
- 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, ®s, 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