Whamcloud - gitweb
land v0.9.1 on HEAD, in preparation for a 1.0.x branch
[fs/lustre-release.git] / lustre / kernel_patches / patches / kgdb_eth.patch
1 Index: linux-2.6.0-test1/arch/i386/kernel/kgdb_stub.c
2 ===================================================================
3 --- linux-2.6.0-test1.orig/arch/i386/kernel/kgdb_stub.c 2003-09-02 14:16:10.000000000 +0800
4 +++ linux-2.6.0-test1/arch/i386/kernel/kgdb_stub.c      2003-09-02 14:32:02.000000000 +0800
5 @@ -30,6 +30,7 @@
6   *
7   *  Written by:             Glenn Engel $
8   *  Updated by:             David Grothe <dave@gcom.com>
9 + *  Updated by:             Robert Walsh <rjwalsh@durables.org>
10   *  ModuleState:     Experimental $
11   *
12   *  NOTES:          See Below $
13 @@ -112,6 +113,7 @@
14  #include <asm/processor.h>
15  #include <linux/irq.h>
16  #include <asm/desc.h>
17 +#include <linux/inet.h>
18  
19  /************************************************************************
20   *
21 @@ -122,8 +124,16 @@
22  /* Thread reference */
23  typedef unsigned char threadref[8];
24  
25 -extern void putDebugChar(int); /* write a single character      */
26 -extern int getDebugChar(void); /* read and return a single char */
27 +extern int tty_putDebugChar(int);     /* write a single character      */
28 +extern int tty_getDebugChar(void);    /* read and return a single char */
29 +extern void tty_flushDebugChar(void); /* flush pending characters      */
30 +extern int eth_putDebugChar(int);     /* write a single character      */
31 +extern int eth_getDebugChar(void);    /* read and return a single char */
32 +extern void eth_flushDebugChar(void); /* flush pending characters      */
33 +extern void gdb_eth_set_trapmode(int);
34 +extern void gdb_eth_reply_arp(void);   /*send arp request */
35 +extern int gdb_eth_is_initializing;
36 +
37  
38  /************************************************************************/
39  /* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
40 @@ -264,6 +274,35 @@
41  }
42  
43  /*
44 + * I/O dispatch functions...
45 + * Based upon gdb_eth, either call the ethernet
46 + * handler or the serial one..
47 + */
48 +void putDebugChar(int c)
49 +{
50 +  if (gdb_eth == -1)
51 +       tty_putDebugChar(c);
52 +  else
53 +       eth_putDebugChar(c);
54 +}
55 +
56 +int getDebugChar(void)
57 +{
58 +  if (gdb_eth == -1)
59 +       return tty_getDebugChar();
60 +  else
61 +       return eth_getDebugChar();
62 +}
63 +
64 +void flushDebugChar(void)
65 +{
66 +    if (gdb_eth == -1)
67 +       tty_flushDebugChar();
68 +    else
69 +       eth_flushDebugChar();
70 +}
71 +
72 +/*
73   * Gdb calls functions by pushing agruments, including a return address 
74   * on the stack and the adjusting EIP to point to the function.         The 
75   * whole assumption in GDB is that we are on a different stack than the
76 @@ -389,7 +428,6 @@
77                 xmitcsum = -1;
78  
79                 count = 0;
80 -
81                 /* now, read until a # or end of buffer is found */
82                 while (count < BUFMAX) {
83                         ch = getDebugChar() & 0x7f;
84 @@ -429,6 +467,7 @@
85  
86         if (remote_debug)
87                 printk("R:%s\n", buffer);
88 +       flushDebugChar();
89  }
90  
91  /* send the packet in buffer.  */
92 @@ -441,25 +480,64 @@
93         char ch;
94  
95         /*  $<packet info>#<checksum>. */
96 -       do {
97 -               if (remote_debug)
98 -                       printk("T:%s\n", buffer);
99 -               putDebugChar('$');
100 -               checksum = 0;
101 -               count = 0;
102 -
103 -               while ((ch = buffer[count])) {
104 -                       putDebugChar(ch);
105 -                       checksum += ch;
106 -                       count += 1;
107 -               }
108  
109 -               putDebugChar('#');
110 -               putDebugChar(hexchars[checksum >> 4]);
111 -               putDebugChar(hexchars[checksum % 16]);
112 -
113 -       } while ((getDebugChar() & 0x7f) != '+');
114 +       if (gdb_eth == -1){
115 +               do {
116 +                       if (remote_debug)
117 +                               printk("T:%s\n", buffer);
118 +                       putDebugChar('$');
119 +                       checksum = 0;
120 +                       count = 0;
121 +
122 +                       while ((ch = buffer[count])) {
123 +                               putDebugChar(ch);
124 +                               checksum += ch;
125 +                               count += 1;
126 +                       }
127 +                       
128 +                       putDebugChar('#');
129 +                       putDebugChar(hexchars[checksum >> 4]);
130 +                       putDebugChar(hexchars[checksum % 16]);
131 +                       flushDebugChar();
132 +
133 +               } while ((getDebugChar() & 0x7f) != '+');
134 +       }else{
135 +       
136 +               /*for udp, we can not transfer too much bytes once */
137 +               /*we only transfer MAX_SEND_COUNT size byts each time */
138 +#define MAX_SEND_COUNT 30      
139 +               int send_count=0, i=0;
140 +               char send_buf[30];
141  
142 +               do {
143 +                       if (remote_debug)
144 +                               printk("T:%s\n", buffer);
145 +                       putDebugChar('$');
146 +                       checksum = 0;
147 +                       count = 0;
148 +                       send_count = 0; 
149 +                       while ((ch = buffer[count])) {
150 +                               if (send_count >= MAX_SEND_COUNT){
151 +                                       for(i=0; i < MAX_SEND_COUNT; i++){
152 +                                               putDebugChar(send_buf[i]);
153 +                                       }               
154 +                                       flushDebugChar();
155 +                                       send_count = 0;
156 +                               }else{
157 +                                       send_buf[send_count] = ch;
158 +                                       checksum += ch;
159 +                                       count ++;
160 +                                       send_count++;
161 +                               }
162 +                       }
163 +                       for(i=0; i < send_count; i++)
164 +                               putDebugChar(send_buf[i]);
165 +                       putDebugChar('#');
166 +                       putDebugChar(hexchars[checksum >> 4]);
167 +                       putDebugChar(hexchars[checksum % 16]);
168 +                       flushDebugChar();
169 +               } while ((getDebugChar() & 0x7f) != '+');
170 +       }
171  }
172  
173  static char remcomInBuffer[BUFMAX];
174 @@ -1143,6 +1221,13 @@
175                 print_regs(&regs);
176                 return (0);
177         }
178 +       /*
179 +        * If we're using eth mode, set the 'mode' in the netdevice.
180 +        */
181 +
182 +       if(gdb_eth != -1) {
183 +               gdb_eth_set_trapmode(1);
184 +       }
185  
186         kgdb_local_irq_save(flags);
187  
188 @@ -1156,8 +1241,8 @@
189          * NMI and will wait there for the following spin locks to be 
190          * released.
191          */
192 +       
193  #ifdef CONFIG_SMP
194 -
195  #if 0
196         if (cpu_callout_map & ~MAX_CPU_MASK) {
197                 printk("kgdb : too many cpus, possibly not mapped"
198 @@ -1372,6 +1457,7 @@
199         gdb_i386vector = exceptionVector;
200         gdb_i386errcode = err_code;
201         kgdb_info.called_from = __builtin_return_address(0);
202 +
203  #ifdef CONFIG_SMP
204         /*
205          * OK, we can now communicate, lets tell gdb about the sync.
206 @@ -1400,8 +1486,13 @@
207         remcomOutBuffer[2] = hexchars[signo % 16];
208         remcomOutBuffer[3] = 0;
209  
210 -       putpacket(remcomOutBuffer);
211 +       if (gdb_eth_is_initializing) {
212 +               gdb_eth_is_initializing = 0;
213 +       } else {
214 +               putpacket(remcomOutBuffer);
215 +       }
216  
217 +       gdb_eth_reply_arp();
218         while (1 == 1) {
219                 error = 0;
220                 remcomOutBuffer[0] = 0;
221 @@ -1419,7 +1510,9 @@
222                                remote_debug ? "on" : "off");
223                         break;
224                 case 'g':       /* return the value of the CPU registers */
225 +                       
226                         get_gdb_regs(usethread, &regs, gdb_regs);
227 +                       
228                         mem2hex((char *) gdb_regs,
229                                 remcomOutBuffer, NUMREGBYTES, 0);
230                         break;
231 @@ -1536,6 +1629,10 @@
232  
233                         newPC = regs.eip;
234  
235 +                       if (gdb_eth != -1) {
236 +                               gdb_eth_set_trapmode(0);
237 +                       }
238 +
239                         /* clear the trace bit */
240                         regs.eflags &= 0xfffffeff;
241  
242 @@ -1856,9 +1953,7 @@
243                 kgdb_local_irq_restore(flags);
244                 return (0);
245         }
246 -#if 0
247 -exit_just_unlock:
248 -#endif
249 +      exit_just_unlock:
250  #endif
251         /* Release kgdb spinlock */
252         KGDB_SPIN_UNLOCK(&kgdb_spinlock);
253 @@ -2213,3 +2308,72 @@
254  typedef int gdb_debug_hook(int exceptionVector,
255                            int signo, int err_code, struct pt_regs *linux_regs);
256  gdb_debug_hook *linux_debug_hook = &kgdb_handle_exception;     /* histerical reasons... */
257 +
258 +static int __init kgdb_opt_gdbeth(char *str)
259 +{
260 +       gdb_eth = simple_strtoul(str,NULL,10);
261 +       return 1;
262 +}
263 +
264 +static int __init kgdb_opt_gdbeth_remote(char *str)
265 +{
266 +       gdb_ethremote = in_aton(str);
267 +       return 1;
268 +}
269 +
270 +static int __init kgdb_opt_gdbeth_listen(char *str)
271 +{
272 +       gdb_listenport = simple_strtoul(str,NULL,10);
273 +       return 1;
274 +}
275 +
276 +static int __init kgdb_opt_gdbeth_hwaddr(char *str)
277 +{
278 +       int  i;
279 +       char *p;
280 +
281 +       p = str;
282 +       i = 0;
283 +       while(1)
284 +       {
285 +               unsigned int c;
286 +               sscanf(p, "%x:", &c);
287 +               gdb_sendhwaddr[i++] = c;
288 +               while((*p != 0) && (*p != ':'))
289 +                       p++;
290 +               if (*p == 0)
291 +                       break;
292 +               p++;
293 +       }
294 +
295 +       return 1;
296 +}
297 +static int __init kgdb_opt_gdbeth_rchwaddr(char *str)
298 +{
299 +       int  i;
300 +       char *p;
301 +
302 +       p = str;
303 +       i = 0;
304 +       while(1)
305 +       {
306 +               unsigned int c;
307 +               sscanf(p, "%x:", &c);
308 +               gdb_receivehwaddr[i++] = c;
309 +               while((*p != 0) && (*p != ':'))
310 +                       p++;
311 +               if (*p == 0)
312 +                       break;
313 +               p++;
314 +       }
315 +
316 +       return 1;
317 +}
318 +
319 +
320 +__setup("gdbeth=", kgdb_opt_gdbeth);
321 +__setup("gdbeth_remote=", kgdb_opt_gdbeth_remote);
322 +__setup("gdbeth_listenport=", kgdb_opt_gdbeth_listen);
323 +__setup("gdbeth_sendhwaddr=", kgdb_opt_gdbeth_hwaddr);
324 +__setup("gdbeth_receivehwaddr=", kgdb_opt_gdbeth_rchwaddr);
325 +
326 Index: linux-2.6.0-test1/arch/i386/lib/kgdb_serial.c
327 ===================================================================
328 --- linux-2.6.0-test1.orig/arch/i386/lib/kgdb_serial.c  2003-09-02 14:16:11.000000000 +0800
329 +++ linux-2.6.0-test1/arch/i386/lib/kgdb_serial.c       2003-09-02 14:32:02.000000000 +0800
330 @@ -155,12 +155,12 @@
331   * It will receive a limited number of characters of input
332   * from the gdb  host machine and save them up in a buffer.
333   *
334 - * When the gdb stub routine getDebugChar() is called it
335 + * When the gdb stub routine tty_getDebugChar() is called it
336   * draws characters out of the buffer until it is empty and
337   * then reads directly from the serial port.
338   *
339   * We do not attempt to write chars from the interrupt routine
340 - * since the stubs do all of that via putDebugChar() which
341 + * since the stubs do all of that via tty_putDebugChar() which
342   * writes one byte after waiting for the interface to become
343   * ready.
344   *
345 @@ -226,7 +226,7 @@
346  /*
347   * Hook an IRQ for KGDB.
348   *
349 - * This routine is called from putDebugChar, below.
350 + * This routine is called from tty_putDebugChar, below.
351   */
352  static int ints_disabled = 1;
353  int
354 @@ -331,7 +331,7 @@
355  }
356  
357  /*
358 - * getDebugChar
359 + * tty_getDebugChar
360   *
361   * This is a GDB stub routine. It waits for a character from the
362   * serial interface and then returns it.  If there is no serial
363 @@ -345,11 +345,11 @@
364  /* Caller takes needed protections */
365  
366  int
367 -getDebugChar(void)
368 +tty_getDebugChar(void)
369  {
370         volatile int chr, dum, time, end_time;
371  
372 -       dbprintk(("getDebugChar(port %x): ", gdb_async_info->port));
373 +       dbprintk(("tty_getDebugChar(port %x): ", gdb_async_info->port));
374  
375         if (gdb_async_info == NULL) {
376                 gdb_hook_interrupt(&local_info, 0);
377 @@ -375,7 +375,7 @@
378         dbprintk(("%c\n", chr > ' ' && chr < 0x7F ? chr : ' '));
379         return (chr);
380  
381 -}                              /* getDebugChar */
382 +}                              /* tty_getDebugChar */
383  
384  static int count = 3;
385  static spinlock_t one_at_atime = SPIN_LOCK_UNLOCKED;
386 @@ -383,6 +383,9 @@
387  static int __init
388  kgdb_enable_ints(void)
389  {
390 +       if (gdb_eth != -1) {
391 +               return 0;
392 +       }
393         if (gdb_async_info == NULL) {
394                 gdb_hook_interrupt(&local_info, 1);
395         }
396 @@ -444,7 +447,7 @@
397  }
398  
399  /*
400 - * putDebugChar
401 + * tty_putDebugChar
402   *
403   * This is a GDB stub routine. It waits until the interface is ready
404   * to transmit a char and then sends it.  If there is no serial
405 @@ -452,9 +455,9 @@
406   * pretended to send the char. Caller takes needed protections.
407   */
408  void
409 -putDebugChar(int chr)
410 +tty_putDebugChar(int chr)
411  {
412 -       dbprintk(("putDebugChar(port %x): chr=%02x '%c', ints_on=%d\n",
413 +       dbprintk(("tty_putDebugChar(port %x): chr=%02x '%c', ints_on=%d\n",
414                   gdb_async_info->port,
415                   chr,
416                   chr > ' ' && chr < 0x7F ? chr : ' ', ints_disabled ? 0 : 1));
417 @@ -480,6 +483,14 @@
418                 }
419         }
420  
421 -}                              /* putDebugChar */
422 +}                              /* tty_putDebugChar */
423 +
424 +/*
425 + * This does nothing for the serial port, since it doesn't buffer.
426 + */
427 +
428 +void tty_flushDebugChar(void)
429 +{
430 +}
431  
432  module_init(kgdb_enable_ints);
433 Index: linux-2.6.0-test1/include/linux/netdevice.h
434 ===================================================================
435 --- linux-2.6.0-test1.orig/include/linux/netdevice.h    2003-09-02 14:29:27.000000000 +0800
436 +++ linux-2.6.0-test1/include/linux/netdevice.h 2003-09-02 14:32:02.000000000 +0800
437 @@ -469,6 +469,11 @@
438  
439         /* statistics sub-directory */
440         struct kobject          stats_kobj;
441 +
442 +#ifdef CONFIG_KGDB
443 +       int                     kgdb_is_trapped;
444 +       void                    (*kgdb_net_poll_rx)(struct net_device *);
445 +#endif
446  };
447  
448  #define SET_MODULE_OWNER(dev) do { } while (0)
449 @@ -524,6 +529,11 @@
450  extern struct net_device       *dev_get_by_index(int ifindex);
451  extern struct net_device       *__dev_get_by_index(int ifindex);
452  extern int             dev_restart(struct net_device *dev);
453 +#ifdef CONFIG_KGDB
454 +int            gdb_eth_is_trapped(void);
455 +int            gdb_net_interrupt(struct sk_buff *skb);
456 +void           gdb_send_arp_request(void);
457 +#endif
458  
459  typedef int gifconf_func_t(struct net_device * dev, char * bufptr, int len);
460  extern int             register_gifconf(unsigned int family, gifconf_func_t * gifconf);
461 @@ -582,12 +592,20 @@
462  
463  static inline void netif_wake_queue(struct net_device *dev)
464  {
465 +#ifdef CONFIG_KGDB
466 +       if (gdb_eth_is_trapped())
467 +               return;
468 +#endif
469         if (test_and_clear_bit(__LINK_STATE_XOFF, &dev->state))
470                 __netif_schedule(dev);
471  }
472  
473  static inline void netif_stop_queue(struct net_device *dev)
474  {
475 +#ifdef CONFIG_KGDB
476 +       if (gdb_eth_is_trapped())
477 +               return;
478 +#endif
479         set_bit(__LINK_STATE_XOFF, &dev->state);
480  }
481  
482 Index: linux-2.6.0-test1/include/asm-i386/kgdb.h
483 ===================================================================
484 --- linux-2.6.0-test1.orig/include/asm-i386/kgdb.h      2003-09-02 14:16:20.000000000 +0800
485 +++ linux-2.6.0-test1/include/asm-i386/kgdb.h   2003-09-02 14:32:03.000000000 +0800
486 @@ -18,6 +18,16 @@
487  #ifndef BREAKPOINT
488  #define BREAKPOINT   asm("   int $3")
489  #endif
490 +
491 +extern int gdb_eth;
492 +extern unsigned gdb_ethremote;
493 +extern unsigned short gdb_listenport;
494 +extern unsigned char gdb_sendhwaddr[6];
495 +extern unsigned char gdb_receivehwaddr[6];
496 +
497 +extern int gdb_tty_hook(void);
498 +extern int gdb_eth_hook(void);
499 +
500  /*
501   * GDB debug stub (or any debug stub) can point the 'linux_debug_hook'
502   * pointer to its routine and it will be entered as the first thing
503 @@ -34,6 +44,7 @@
504  extern int kgdb_handle_exception(int trapno,
505                                  int signo, int err_code, struct pt_regs *regs);
506  extern int in_kgdb(struct pt_regs *regs);
507 +extern void kgdb_null(void);
508  
509  #ifdef CONFIG_KGDB_TS
510  void kgdb_tstamp(int line, char *source, int data0, int data1);
511 Index: linux-2.6.0-test1/drivers/net/e100/e100_main.c
512 ===================================================================
513 --- linux-2.6.0-test1.orig/drivers/net/e100/e100_main.c 2003-09-02 14:29:27.000000000 +0800
514 +++ linux-2.6.0-test1/drivers/net/e100/e100_main.c      2003-09-02 14:32:03.000000000 +0800
515 @@ -567,6 +567,15 @@
516  }
517  #endif
518  
519 +#ifdef CONFIG_KGDB
520 +static void e100_rx_poll(struct net_device *dev)
521 +{
522 +       disable_irq(dev->irq);
523 +       e100intr(dev->irq, (void *)dev, 0);
524 +       enable_irq(dev->irq);
525 +}
526 +#endif
527 +
528  static int __devinit
529  e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
530  {
531 @@ -662,7 +671,9 @@
532         dev->set_multicast_list = &e100_set_multi;
533         dev->set_mac_address = &e100_set_mac;
534         dev->do_ioctl = &e100_ioctl;
535 -
536 +#ifdef CONFIG_KGDB
537 +       dev->kgdb_net_poll_rx = e100_rx_poll;
538 +#endif
539         if (bdp->flags & USE_IPCB)
540         dev->features = NETIF_F_SG | NETIF_F_HW_CSUM |
541                         NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
542 Index: linux-2.6.0-test1/drivers/net/3c59x.c
543 ===================================================================
544 --- linux-2.6.0-test1.orig/drivers/net/3c59x.c  2003-09-02 14:29:27.000000000 +0800
545 +++ linux-2.6.0-test1/drivers/net/3c59x.c       2003-09-02 14:32:03.000000000 +0800
546 @@ -1063,6 +1063,22 @@
547         return rc;
548  }
549  
550 +#ifdef CONFIG_KGDB
551 +static void vortex_rx_poll(struct net_device *dev)
552 +{
553 +       disable_irq(dev->irq);
554 +       vortex_interrupt(dev->irq, (void *)dev, 0);
555 +       enable_irq(dev->irq);
556 +}
557 +
558 +static void boomerang_rx_poll(struct net_device *dev)
559 +{
560 +       disable_irq(dev->irq);
561 +       boomerang_interrupt(dev->irq, (void *)dev, 0);
562 +       enable_irq(dev->irq);
563 +}
564 +#endif
565 +
566  /*
567   * Start up the PCI/EISA device which is described by *gendev.
568   * Return 0 on success.
569 @@ -1449,6 +1465,14 @@
570         dev->set_multicast_list = set_rx_mode;
571         dev->tx_timeout = vortex_tx_timeout;
572         dev->watchdog_timeo = (watchdog * HZ) / 1000;
573 +#ifdef CONFIG_KGDB
574 +       if (vp->full_bus_master_tx) {
575 +               dev->kgdb_net_poll_rx = boomerang_rx_poll;
576 +       } else {
577 +               dev->kgdb_net_poll_rx = vortex_rx_poll;
578 +       }
579 +#endif
580 +
581  #ifdef HAVE_POLL_CONTROLLER
582         dev->poll_controller = &vorboom_poll;
583  #endif
584 Index: linux-2.6.0-test1/drivers/net/Makefile
585 ===================================================================
586 --- linux-2.6.0-test1.orig/drivers/net/Makefile 2003-07-14 11:32:32.000000000 +0800
587 +++ linux-2.6.0-test1/drivers/net/Makefile      2003-09-02 14:32:03.000000000 +0800
588 @@ -32,6 +32,8 @@
589  
590  obj-$(CONFIG_OAKNET) += oaknet.o 8390.o
591  
592 +obj-$(CONFIG_KGDB) += kgdb_eth.o
593 +
594  obj-$(CONFIG_DGRS) += dgrs.o
595  obj-$(CONFIG_RCPCI) += rcpci.o
596  obj-$(CONFIG_VORTEX) += 3c59x.o
597 Index: linux-2.6.0-test1/drivers/net/kgdb_eth.c
598 ===================================================================
599 --- linux-2.6.0-test1.orig/drivers/net/kgdb_eth.c       2003-09-02 14:32:02.000000000 +0800
600 +++ linux-2.6.0-test1/drivers/net/kgdb_eth.c    2003-09-02 21:41:42.000000000 +0800
601 @@ -0,0 +1,547 @@
602 +/*
603 + * Network interface GDB stub
604 + *
605 + * Written by San Mehat (nettwerk@biodome.org)
606 + * Based upon 'gdbserial' by David Grothe (dave@gcom.com)
607 + * and Scott Foehner (sfoehner@engr.sgi.com)
608 + *
609 + * Twiddled for 2.5 by Robert Walsh (rjwalsh@durables.org)
610 + *
611 + */
612
613 +#include <linux/module.h>
614 +#include <linux/errno.h>
615 +#include <linux/signal.h>
616 +#include <linux/sched.h>
617 +#include <linux/timer.h>
618 +#include <linux/interrupt.h>
619 +#include <linux/config.h>
620 +#include <linux/major.h>
621 +#include <linux/string.h>
622 +#include <linux/fcntl.h>
623 +#include <linux/termios.h>
624 +#include <linux/workqueue.h>
625 +#include <asm/kgdb.h>
626 +#include <linux/if_ether.h>
627 +#include <linux/netdevice.h>
628 +#include <linux/etherdevice.h>
629 +#include <linux/skbuff.h>
630 +#include <linux/delay.h>
631 +#include <net/tcp.h>
632 +#include <net/udp.h>
633 +
634 +#include <asm/system.h>
635 +#include <asm/io.h>
636 +#include <asm/segment.h>
637 +#include <asm/bitops.h>
638 +#include <asm/system.h>
639 +#include <asm/irq.h>
640 +#include <asm/atomic.h>
641 +
642 +#undef PRNT                            /* define for debug printing */
643 +
644 +#define        GDB_BUF_SIZE    512             /* power of 2, please */
645 +
646 +static char    gdb_buf[GDB_BUF_SIZE] ;
647 +static int     gdb_buf_in_inx ;
648 +static atomic_t        gdb_buf_in_cnt ;
649 +static int     gdb_buf_out_inx ;
650 +
651 +extern void    set_debug_traps(void) ;         /* GDB routine */
652 +extern void     breakpoint(void);
653 +
654 +unsigned int    gdb_ethremote = 0;
655 +unsigned short  gdb_listenport = 6443;
656 +unsigned short  gdb_sendport= 6442;
657 +int             gdb_eth = -1; /* Default tty mode */
658 +unsigned char   gdb_sendhwaddr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
659 +unsigned char   gdb_receivehwaddr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
660 +int             gdb_eth_is_initializing = 0;
661 +int            gdb_eth_debug = 0;
662 +
663 +struct net_device *gdb_netdevice = NULL;
664 +
665 +//static int      initialized = -1;
666 +//static struct work_struct irq_bp;
667 +
668 +static void bpwork_func(void *p)
669 +{
670 +    udelay(500);
671 +    BREAKPOINT;
672 +}
673 +
674 +static struct workqueue_struct *irq_bp;
675 +DECLARE_WORK(bpwork, bpwork_func, NULL);
676 +
677 +/*
678 + * Get a char if available, return -1 if nothing available.
679 + * Empty the receive buffer first, then look at the interface hardware.
680 + */
681 +static int read_char(void)
682 +{
683 +    
684 +    if (atomic_read(&gdb_buf_in_cnt) != 0) /* intr routine has q'd chars */
685 +    {
686 +       int chr ;
687 +
688 +       chr = gdb_buf[gdb_buf_out_inx++] ;
689 +       gdb_buf_out_inx &= (GDB_BUF_SIZE - 1) ;
690 +       atomic_dec(&gdb_buf_in_cnt) ;
691 +       return chr;
692 +    }
693 +    return -1; // no data
694 +} /* read_char */
695 +
696 +//static unsigned char daddr[6] = {0x00,0x06,0x25,0xA9,0x9F,0x6A};
697 +//static unsigned char daddr[6] = {0x00,0x50,0xFC,0xB8,0x22,0x03};
698 +//static unsigned char daddr[6] = {0x00,0x08,0x74,0x96,0x6D,0x9B};
699 +//static unsigned char daddr[6] = {0x00,0x07,0xE9,0xD4,0xBE,0x85};
700 +//static unsigned char daddr[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
701 +
702 +/*
703 + * Wait until the interface can accept a char, then write it.
704 + */
705 +static void write_buffer(char *buf, int len)
706 +{
707 +    int              total_len, eth_len, ip_len, udp_len;
708 +    struct in_device *in_dev;
709 +    struct sk_buff   *skb;
710 +    struct udphdr    *udph;
711 +    struct iphdr     *iph;
712 +    struct ethhdr    *eth;
713 +
714 +    if (!(in_dev = (struct in_device *) gdb_netdevice->ip_ptr)) 
715 +       panic("No in_device available for interface!\n");
716 +    if (!(in_dev->ifa_list))
717 +       panic("No interface address set for interface!\n");
718 +    udp_len = len + sizeof(struct udphdr);
719 +    ip_len = eth_len = udp_len + sizeof(struct iphdr);
720 +    total_len = eth_len + ETH_HLEN;
721 +
722 +    if (!(skb = alloc_skb(total_len, GFP_ATOMIC)))
723 +       return;
724 +
725 +    atomic_set(&skb->users, 1);
726 +    skb_reserve(skb, total_len - 1);
727 +
728 +    memcpy(skb->data , (unsigned char *) buf, len);
729 +    skb->len += len;
730 +
731 +    udph = (struct udphdr *) skb_push(skb, sizeof(*udph));
732 +    udph->source = htons(gdb_listenport);
733 +    udph->dest   = htons(gdb_sendport);
734 +    udph->len    = htons(udp_len);
735 +    udph->check  = 0;
736 +  
737 +    iph = (struct iphdr *)skb_push(skb, sizeof(*iph));
738 +    iph->version = 4;
739 +    iph->ihl     = 5;
740 +    iph->tos     = 0;
741 +    iph->tot_len = htons(ip_len);
742 +    iph->id      = 0;
743 +    iph->frag_off= 0;
744 +    iph->ttl     = 64;
745 +    iph->protocol= IPPROTO_UDP;
746 +    iph->check   = 0;
747 +    iph->saddr   = in_dev->ifa_list->ifa_address;
748 +    iph->daddr   = gdb_ethremote;
749 +    iph->check   = ip_fast_csum((unsigned char *)iph, iph->ihl);
750 +
751 +    eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
752 +    eth->h_proto = htons(ETH_P_IP);
753 +    memcpy(eth->h_source, gdb_sendhwaddr, gdb_netdevice->addr_len);
754 +//    memcpy(eth->h_dest, daddr, gdb_netdevice->addr_len);
755 +    memcpy(eth->h_dest, gdb_receivehwaddr, gdb_netdevice->addr_len);
756 +
757 +#if 0 
758 +repeat_poll:
759 +#endif
760 +    spin_lock(&gdb_netdevice->xmit_lock);
761 +    gdb_netdevice->xmit_lock_owner = smp_processor_id();
762 +#if 0 
763 +    if (netif_queue_stopped(gdb_netdevice))
764 +    {
765 +       gdb_netdevice->xmit_lock_owner = -1;
766 +       spin_unlock(&gdb_netdevice->xmit_lock);
767 +       gdb_netdevice->poll_controller(gdb_netdevice);
768 +       zap_completion_queue();
769 +       goto repeat_poll;
770 +    }
771 +#endif
772 +    gdb_netdevice->hard_start_xmit(skb, gdb_netdevice);
773 +    gdb_netdevice->xmit_lock_owner = -1;
774 +    spin_unlock(&gdb_netdevice->xmit_lock);
775 +
776 +   // kfree_skb(skb);
777 +} /* write_char */
778 +/* in interrupt state the target machine will not response the arp request */ 
779 +
780 +static struct sk_buff *send_skb = NULL;
781 +void gdb_eth_reply_arp(void)
782 +{
783 +       if (send_skb){
784 +#if 0 
785 +repeat_poll:
786 +#endif
787 +               spin_lock(&gdb_netdevice->xmit_lock);
788 +               gdb_netdevice->xmit_lock_owner = smp_processor_id();
789 +#if 0 
790 +               if (netif_queue_stopped(gdb_netdevice)){
791 +                       gdb_netdevice->xmit_lock_owner = -1;
792 +                       spin_unlock(&gdb_netdevice->xmit_lock);
793 +                       gdb_netdevice->poll_controller(gdb_netdevice);
794 +                       zap_completion_queue();
795 +                       goto repeat_poll;
796 +               }
797 +#endif
798 +               gdb_netdevice->hard_start_xmit(send_skb, gdb_netdevice);
799 +               gdb_netdevice->xmit_lock_owner = -1;
800 +               spin_unlock(&gdb_netdevice->xmit_lock);
801 +               send_skb = NULL;        
802 +       
803 +       }
804 +}
805 +static int make_arp_request( struct sk_buff *skb)
806 +{
807 +       struct arphdr *arp;
808 +       unsigned char *arp_ptr;
809 +       int type = ARPOP_REPLY;
810 +       int ptype = ETH_P_ARP;
811 +       u32 sip, tip;
812 +       unsigned char *sha, *tha;
813 +       struct in_device *in_dev = (struct in_device *) gdb_netdevice->ip_ptr; 
814 +       /*
815 +        *      No arp on this interface.
816 +        */
817 +       if (gdb_netdevice->flags &IFF_NOARP)
818 +               return 0;
819 +       if (!pskb_may_pull(skb, (sizeof(struct arphdr) +
820 +                                (2 * gdb_netdevice->addr_len) +
821 +                                (2 * sizeof(u32)))))
822 +               return 0;
823 +       
824 +       skb->h.raw = skb->nh.raw = skb->data;
825 +       arp = skb->nh.arph;
826 +
827 +       if ((arp->ar_hrd != htons(ARPHRD_ETHER) &&
828 +            arp->ar_hrd != htons(ARPHRD_IEEE802)) ||
829 +           arp->ar_pro != htons(ETH_P_IP))
830 +               return 0;
831 +
832 +/* Understand only these message types */
833 +
834 +       if (arp->ar_op != htons(ARPOP_REQUEST))
835 +               return 0;
836 +/*
837 + *     Extract fields
838 + */
839 +       arp_ptr= (unsigned char *)(arp+1);
840 +       sha     = arp_ptr;
841 +       arp_ptr += gdb_netdevice->addr_len;
842 +       memcpy(&sip, arp_ptr, 4);
843 +       arp_ptr += 4;
844 +       tha     = arp_ptr;
845 +       arp_ptr += gdb_netdevice->addr_len;
846 +       memcpy(&tip, arp_ptr, 4);
847 +       if (tip != in_dev->ifa_list->ifa_address){
848 +               return 0;
849 +       } 
850 +       if (gdb_ethremote != sip){
851 +               return 0;       
852 +       }
853 +/* 
854 + *     Check for bad requests for 127.x.x.x and requests for multicast
855 + *     addresses.  If this is one such, delete it.
856 + */
857 +       
858 +       if (LOOPBACK(tip) || MULTICAST(tip))
859 +               return 0;
860 +
861 +/*
862 + *      reply the arp request
863 + */    
864 +       send_skb = alloc_skb(sizeof(struct arphdr)+ 2*(gdb_netdevice->addr_len+4)
865 +                               + LL_RESERVED_SPACE(gdb_netdevice), GFP_ATOMIC);
866 +       if (send_skb == NULL)
867 +               return 0;
868 +
869 +       skb_reserve(send_skb, LL_RESERVED_SPACE(gdb_netdevice));
870 +       send_skb->nh.raw = send_skb->data;
871 +       arp = (struct arphdr *) skb_put(send_skb,sizeof(struct arphdr) + 2*(gdb_netdevice->addr_len+4));
872 +       send_skb->dev = gdb_netdevice;
873 +       send_skb->protocol = htons(ETH_P_ARP);
874 +       
875 +       /*
876 +        *      Fill the device header for the ARP frame
877 +        */
878 +       if (gdb_netdevice->hard_header &&
879 +           gdb_netdevice->hard_header(send_skb,  gdb_netdevice,  ptype, gdb_receivehwaddr, gdb_sendhwaddr, send_skb->len) < 0){
880 +               kfree_skb(send_skb);
881 +               return 0;
882 +       }
883 +       /*
884 +        * Fill out the arp protocol part.
885 +        *
886 +        * we only support ethernet device type, 
887 +        * which (according to RFC 1390) should always equal 1 (Ethernet).
888 +        */
889 +       arp->ar_hrd = htons(gdb_netdevice->type);
890 +       arp->ar_pro = htons(ETH_P_IP);
891 +
892 +       arp->ar_hln = gdb_netdevice->addr_len;
893 +       arp->ar_pln = 4;
894 +       arp->ar_op = htons(type);
895 +
896 +       arp_ptr=(unsigned char *)(arp+1);
897 +
898 +       memcpy(arp_ptr, gdb_netdevice->dev_addr, gdb_netdevice->addr_len); 
899 +       arp_ptr += gdb_netdevice->addr_len;
900 +       memcpy(arp_ptr, &tip, 4);
901 +       arp_ptr += 4;
902 +        memcpy(arp_ptr, gdb_sendhwaddr, gdb_netdevice->addr_len);
903 +       arp_ptr+=gdb_netdevice->addr_len;
904 +       memcpy(arp_ptr, &sip, 4);
905 +       return 0;
906 +}
907 +/*
908 + * Accept an skbuff from net_device layer and 
909 + * add the payload onto gdb buffer
910 + *
911 + * When the gdb stub routine getDebugChar() is called it
912 + * draws characters out of the buffer until it is empty and
913 + * then reads directly from the serial port.
914 + *
915 + * We do not attempt to write chars from the interrupt routine
916 + * since the stubs do all of that via putDebugChar() which
917 + * writes one byte after waiting for the interface to become
918 + * ready.
919 + *
920 + * The debug stubs like to run with interrupts disabled since,
921 + * after all, they run as a consequence of a breakpoint in
922 + * the kernel.
923 + *
924 + * NOTE: Return value of 1 means it was for us and is an
925 + * indication to the calling driver to destroy the sk_buff
926 + * and not send it up the stack
927 + */
928 +
929 +int gdb_net_interrupt(struct sk_buff *skb)
930 +{
931 +    unsigned char  chr;
932 +    struct iphdr   *iph = (struct iphdr*)skb->data;
933 +    struct udphdr  *udph= (struct udphdr*)(skb->data+(iph->ihl<<2));
934 +    unsigned char  *data = (unsigned char *) udph + sizeof(struct udphdr);
935 +    int            len;
936 +    int            i;
937 +
938 +    if ((gdb_eth != -1) && (!gdb_netdevice) &&
939 +       (iph->protocol == IPPROTO_UDP) &&
940 +       (be16_to_cpu(udph->dest) == gdb_listenport)) {
941 +       gdb_sendport = be16_to_cpu(udph->source);
942 +       
943 +        while(gdb_eth_is_initializing);
944 +       if(!gdb_netdevice)
945 +           gdb_eth_hook();
946 +       if (!gdb_netdevice) {
947 +           /* Lets not even try again. */
948 +           gdb_eth = -1;
949 +           return 0;
950 +       }
951 +    }
952 +    if (!gdb_netdevice) {
953 +       return 0;
954 +    }
955 +    if (skb->protocol == __constant_htons(ETH_P_ARP) && !send_skb){
956 +       make_arp_request(skb);
957 +       return 0;
958 +    }
959 +    if (iph->protocol != IPPROTO_UDP)
960 +       return 0;
961 +
962 +    if (be16_to_cpu(udph->dest) != gdb_listenport)
963 +       return 0;
964 +
965 +    len = be16_to_cpu(iph->tot_len) - (sizeof(struct udphdr) +
966 +                                      sizeof(struct iphdr));
967 +    for (i = 0; i < len; i++)
968 +    {
969 +       chr = *data++;
970 +       if (chr == 3)
971 +       {
972 +           queue_work(irq_bp, &bpwork);
973 +//         flush_workqueue(irq_bp);
974 +           continue;
975 +/*
976 +           if (!in_interrupt())
977 +           {
978 +               breakpoint();
979 +           }
980 +           else
981 +           {
982 +               schedule_work(&irq_bp); // XXX: is this really necessary??
983 +           }
984 +           continue;
985 +*/
986 +       }
987 +       if (atomic_read(&gdb_buf_in_cnt) >= GDB_BUF_SIZE)
988 +       {                               /* buffer overflow, clear it */
989 +           gdb_buf_in_inx = 0 ;
990 +           atomic_set(&gdb_buf_in_cnt, 0) ;
991 +           gdb_buf_out_inx = 0 ;
992 +           break ;
993 +       }
994 +       gdb_buf[gdb_buf_in_inx++] = chr ;
995 +       gdb_buf_in_inx &= (GDB_BUF_SIZE - 1) ;
996 +       atomic_inc(&gdb_buf_in_cnt) ;
997 +    }
998 +
999 +    return 1;
1000 +} /* gdb_interrupt */
1001 +
1002 +
1003 +int gdb_eth_hook(void)
1004 +{
1005 +    char gdb_netdev[16];
1006 +    extern void kgdb_respond_ok(void);
1007 +
1008 +    if (gdb_sendhwaddr[0] == 0xff)
1009 +       panic("ERROR! 'gdbeth_sendhwaddr' option not set!\n");
1010 +    if (gdb_receivehwaddr[0] == 0xff)
1011 +       panic("ERROR! 'gdbeth_receivehwaddr' option not set!\n");
1012 +    if (gdb_ethremote == 0)
1013 +       panic("ERROR! 'gdbeth_remote' option not set!\n");
1014 +
1015 +    sprintf(gdb_netdev,"eth%d",gdb_eth);
1016 +
1017 +#ifdef CONFIG_SMP
1018 +    if (num_online_cpus() > CONFIG_NO_KGDB_CPUS){ 
1019 +       printk("kgdb: too manu cpus. Cannot enable debugger with more than %d cpus\n", CONFIG_NO_KGDB_CPUS);
1020 +       return -1;
1021 +    }
1022 +#endif
1023 +    for (gdb_netdevice = dev_base;
1024 +        gdb_netdevice != NULL; 
1025 +        gdb_netdevice = gdb_netdevice->next){
1026 +       if (strncmp(gdb_netdevice->name, gdb_netdev, IFNAMSIZ) == 0)
1027 +           break;
1028 +    }
1029 +    if (!gdb_netdevice){
1030 +       printk("KGDB NET : Unable to find interface %s\n",gdb_netdev);
1031 +       return -ENODEV;
1032 +    }
1033 +
1034 +    /*
1035 +     * Call GDB routine to setup the exception vectors for the debugger
1036 +     */
1037 +    set_debug_traps() ;
1038 +
1039 +    /*
1040 +     * Call the breakpoint() routine in GDB to start the debugging
1041 +     * session.
1042 +     */
1043 +     if (gdb_eth_debug){
1044 +           printk(KERN_INFO "Waiting for remote gdb connection from %x on local port %d\n",
1045 +                  gdb_ethremote, gdb_listenport);
1046 +           printk(KERN_INFO "We are sending on port %d to %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
1047 +                  gdb_sendport,
1048 +                  gdb_sendhwaddr[0],
1049 +                  gdb_sendhwaddr[1],
1050 +                  gdb_sendhwaddr[2],
1051 +                  gdb_sendhwaddr[3],
1052 +                  gdb_sendhwaddr[4],
1053 +                  gdb_sendhwaddr[5]);
1054 +           printk("Connected.\n");
1055 +    }
1056 +    gdb_eth_is_initializing = 1;
1057 +    queue_work(irq_bp, &bpwork);
1058 +    return 0;
1059 +} /* gdb_hook_interrupt2 */
1060 +
1061 +/*
1062 + * getDebugChar
1063 + *
1064 + * This is a GDB stub routine.  It waits for a character from the
1065 + * serial interface and then returns it.  If there is no serial
1066 + * interface connection then it returns a bogus value which will
1067 + * almost certainly cause the system to hang.
1068 + */
1069 +int eth_getDebugChar(void)
1070 +{
1071 +    volatile int       chr ;
1072 +
1073 +    while((chr = read_char()) < 0)
1074 +    {
1075 +       if (send_skb){
1076 +               gdb_eth_reply_arp();    
1077 +        }
1078 +       if (gdb_netdevice->kgdb_net_poll_rx)
1079 +           gdb_netdevice->kgdb_net_poll_rx(gdb_netdevice);
1080 +       else
1081 +        {
1082 +           printk("KGDB NET: Error - Device %s is not supported!\n",
1083 +                  gdb_netdevice->name);
1084 +           panic("Please add support for kgdb net to this driver");
1085 +        }
1086 +    }
1087 +    return chr;
1088 +
1089 +} /* eth_getDebugChar */
1090 +
1091 +#define ETH_QUEUE_SIZE 256
1092 +static char eth_queue[ETH_QUEUE_SIZE];
1093 +static int outgoing_queue;
1094 +
1095 +void eth_flushDebugChar(void)
1096 +{
1097 +    if(outgoing_queue) {
1098 +       write_buffer(eth_queue, outgoing_queue);
1099 +
1100 +       outgoing_queue = 0;
1101 +    }
1102 +}
1103 +
1104 +static void put_char_on_queue(int chr)
1105 +{
1106 +    eth_queue[outgoing_queue++] = chr;
1107 +    if(outgoing_queue == ETH_QUEUE_SIZE)
1108 +    {
1109 +       eth_flushDebugChar();
1110 +    }
1111 +}
1112 +
1113 +/*
1114 + * eth_putDebugChar
1115 + *
1116 + * This is a GDB stub routine.  It waits until the interface is ready
1117 + * to transmit a char and then sends it.
1118 + */
1119 +void eth_putDebugChar(int chr)
1120 +{
1121 +    if (gdb_eth_debug)
1122 +       printk(KERN_INFO "eth_putDebugChar: chr=%02x '%c'\n", chr,
1123 +               chr > ' ' && chr < 0x7F ? chr : ' ') ;
1124 +    put_char_on_queue(chr) ;   /* this routine will wait */
1125 +} /* putDebugChar */
1126 +
1127 +void gdb_eth_set_trapmode(int mode)
1128 +{
1129 +    if (!gdb_netdevice)
1130 +       return;
1131 +    gdb_netdevice->kgdb_is_trapped = mode;
1132 +}
1133 +
1134 +int gdb_eth_is_trapped()
1135 +{
1136 +    if (!gdb_netdevice)
1137 +       return 0;
1138 +    return gdb_netdevice->kgdb_is_trapped;
1139 +}
1140 +
1141 +static int __init
1142 +kgdb_eth_init(void)
1143 +{
1144 +    irq_bp = create_workqueue("kgdb");
1145 +    return 0;
1146 +}
1147 +
1148 +module_init(kgdb_eth_init);
1149 Index: linux-2.6.0-test1/net/core/dev.c
1150 ===================================================================
1151 --- linux-2.6.0-test1.orig/net/core/dev.c       2003-09-02 14:29:27.000000000 +0800
1152 +++ linux-2.6.0-test1/net/core/dev.c    2003-09-02 14:32:03.000000000 +0800
1153 @@ -188,7 +188,9 @@
1154  extern int netdev_sysfs_init(void);
1155  extern int netdev_register_sysfs(struct net_device *);
1156  extern void netdev_unregister_sysfs(struct net_device *);
1157 -
1158 +#ifdef CONFIG_KGDB
1159 +extern int gdb_net_interrupt(struct sk_buff *skb);
1160 +#endif
1161  
1162  /*******************************************************************************
1163  
1164 @@ -1349,6 +1351,21 @@
1165         struct softnet_data *queue;
1166         unsigned long flags;
1167  
1168 +#ifdef CONFIG_KGDB
1169 +       /* See if kgdb_eth wants this packet */
1170 +       if (!gdb_net_interrupt(skb)) {
1171 +               /* No.. if we're 'trapped' then junk it */
1172 +               if (gdb_eth_is_trapped()) {
1173 +                       kfree_skb(skb);
1174 +                       return NET_RX_DROP;
1175 +               }
1176 +       } else {
1177 +               /* kgdb_eth ate the packet... drop it silently */
1178 +               kfree_skb(skb);
1179 +               return NET_RX_DROP;
1180 +       }
1181 +#endif
1182 +
1183  
1184         /*
1185          * The code is rearranged so that the path is the most