From: wangdi Date: Thu, 19 Aug 2004 17:01:21 +0000 (+0000) Subject: remove outdated patches X-Git-Tag: v1_7_100~1949 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=a80554998cf89545ceb765d90680a1a37e4de86d remove outdated patches --- diff --git a/lustre/kernel_patches/patches/dump_netdev.patch b/lustre/kernel_patches/patches/dump_netdev.patch deleted file mode 100644 index cd8ec53..0000000 --- a/lustre/kernel_patches/patches/dump_netdev.patch +++ /dev/null @@ -1,340 +0,0 @@ - drivers/net/3c59x.c | 27 +++++++++++++++++++++++++++ - drivers/net/e100/e100_main.c | 19 +++++++++++++++++++ - drivers/net/e1000/e1000_main.c | 13 +++++++++++++ - drivers/net/eepro100.c | 21 +++++++++++++++++++++ - drivers/net/smc-ultra.c | 11 +++++++++++ - drivers/net/tlan.c | 14 +++++++++++++- - drivers/net/tulip/tulip_core.c | 22 ++++++++++++++++++++++ - include/linux/netdevice.h | 3 +++ - net/core/dev.c | 18 ++++++++++++++++-- - 9 files changed, 145 insertions(+), 3 deletions(-) - ---- linux-2.6.0-test1/drivers/net/3c59x.c~dump_netdev 2003-07-22 01:14:04.000000000 -0600 -+++ linux-2.6.0-test1-braam/drivers/net/3c59x.c 2003-07-22 01:15:10.000000000 -0600 -@@ -900,6 +900,7 @@ static void set_rx_mode(struct net_devic - static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); - static void vortex_tx_timeout(struct net_device *dev); - static void acpi_set_WOL(struct net_device *dev); -+static void vorboom_poll(struct net_device *dev); - - /* This driver uses 'options' to pass the media type, full-duplex flag, etc. */ - /* Option count limit only -- unlimited interfaces are supported. */ -@@ -1448,6 +1449,9 @@ static int __devinit vortex_probe1(struc - dev->set_multicast_list = set_rx_mode; - dev->tx_timeout = vortex_tx_timeout; - dev->watchdog_timeo = (watchdog * HZ) / 1000; -+#ifdef HAVE_POLL_CONTROLLER -+ dev->poll_controller = &vorboom_poll; -+#endif - if (pdev) { - vp->pm_state_valid = 1; - pci_save_state(VORTEX_PCI(vp), vp->power_state); -@@ -2438,6 +2442,29 @@ handler_exit: - return IRQ_HANDLED; - } - -+#ifdef HAVE_POLL_CONTROLLER -+ -+/* -+ * Polling 'interrupt' - used by things like netconsole to send skbs -+ * without having to re-enable interrupts. It's not called while -+ * the interrupt routine is executing. -+ */ -+ -+static void vorboom_poll (struct net_device *dev) -+{ -+ struct vortex_private *vp = (struct vortex_private *)dev->priv; -+ -+ disable_irq(dev->irq); -+ if (vp->full_bus_master_tx) -+ boomerang_interrupt(dev->irq, dev, 0); -+ else -+ vortex_interrupt(dev->irq, dev, 0); -+ enable_irq(dev->irq); -+} -+ -+#endif -+ -+ - static int vortex_rx(struct net_device *dev) - { - struct vortex_private *vp = (struct vortex_private *)dev->priv; ---- linux-2.6.0-test1/drivers/net/e100/e100_main.c~dump_netdev 2003-07-13 21:34:02.000000000 -0600 -+++ linux-2.6.0-test1-braam/drivers/net/e100/e100_main.c 2003-07-22 01:14:38.000000000 -0600 -@@ -551,6 +551,22 @@ e100_trigger_SWI(struct e100_private *bd - readw(&(bdp->scb->scb_status)); /* flushes last write, read-safe */ - } - -+#ifdef HAVE_POLL_CONTROLLER -+ -+/* -+ * Polling 'interrupt' - used by things like netconsole to send skbs -+ * without having to re-enable interrupts. It's not called while -+ * the interrupt routine is executing. -+ */ -+static void -+e100_poll(struct net_device *dev) -+{ -+ disable_irq(dev->irq); -+ e100intr(dev->irq, dev, NULL); -+ enable_irq(dev->irq); -+} -+#endif -+ - static int __devinit - e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent) - { -@@ -569,6 +585,9 @@ e100_found1(struct pci_dev *pcid, const - - SET_MODULE_OWNER(dev); - -+#ifdef HAVE_POLL_CONTROLLER -+ dev->poll_controller = &e100_poll; -+#endif - if (first_time) { - first_time = false; - printk(KERN_NOTICE "%s - version %s\n", ---- linux-2.6.0-test1/drivers/net/e1000/e1000_main.c~dump_netdev 2003-07-13 21:32:43.000000000 -0600 -+++ linux-2.6.0-test1-braam/drivers/net/e1000/e1000_main.c 2003-07-22 01:14:38.000000000 -0600 -@@ -138,6 +138,7 @@ static void e1000_leave_82542_rst(struct - static inline void e1000_rx_checksum(struct e1000_adapter *adapter, - struct e1000_rx_desc *rx_desc, - struct sk_buff *skb); -+static void e1000_Poll(struct net_device *dev); - static void e1000_tx_timeout(struct net_device *dev); - static void e1000_tx_timeout_task(struct net_device *dev); - static void e1000_smartspeed(struct e1000_adapter *adapter); -@@ -402,6 +403,9 @@ e1000_probe(struct pci_dev *pdev, - - adapter->bd_number = cards_found; - -+#ifdef HAVE_POLL_CONTROLLER -+ netdev->poll_controller = &e1000_Poll; -+#endif - /* setup the private structure */ - - if(e1000_sw_init(adapter)) -@@ -1700,6 +1704,15 @@ e1000_xmit_frame(struct sk_buff *skb, st - return 0; - } - -+#ifdef HAVE_POLL_CONTROLLER -+static void e1000_Poll(struct net_device *dev) -+{ -+ disable_irq(dev->irq); -+ e1000_intr(dev->irq, dev, NULL); -+ enable_irq(dev->irq); -+} -+#endif -+ - /** - * e1000_tx_timeout - Respond to a Tx Hang - * @netdev: network interface device structure ---- linux-2.6.0-test1/drivers/net/eepro100.c~dump_netdev 2003-07-13 21:35:52.000000000 -0600 -+++ linux-2.6.0-test1-braam/drivers/net/eepro100.c 2003-07-22 01:14:38.000000000 -0600 -@@ -543,6 +543,7 @@ static void speedo_refill_rx_buffers(str - static int speedo_rx(struct net_device *dev); - static void speedo_tx_buffer_gc(struct net_device *dev); - static irqreturn_t speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs); -+static void poll_speedo (struct net_device *dev); - static int speedo_close(struct net_device *dev); - static struct net_device_stats *speedo_get_stats(struct net_device *dev); - static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -@@ -885,6 +886,9 @@ static int __devinit speedo_found1(struc - dev->get_stats = &speedo_get_stats; - dev->set_multicast_list = &set_rx_mode; - dev->do_ioctl = &speedo_ioctl; -+#ifdef HAVE_POLL_CONTROLLER -+ dev->poll_controller = &poll_speedo; -+#endif - - if (register_netdevice(dev)) - goto err_free_unlock; -@@ -1675,6 +1679,23 @@ static irqreturn_t speedo_interrupt(int - return IRQ_RETVAL(handled); - } - -+#ifdef HAVE_POLL_CONTROLLER -+ -+/* -+ * Polling 'interrupt' - used by things like netconsole to send skbs -+ * without having to re-enable interrupts. It's not called while -+ * the interrupt routine is executing. -+ */ -+ -+static void poll_speedo (struct net_device *dev) -+{ -+ disable_irq(dev->irq); -+ speedo_interrupt (dev->irq, dev, NULL); -+ enable_irq(dev->irq); -+} -+ -+#endif -+ - static inline struct RxFD *speedo_rx_alloc(struct net_device *dev, int entry) - { - struct speedo_private *sp = (struct speedo_private *)dev->priv; ---- linux-2.6.0-test1/drivers/net/smc-ultra.c~dump_netdev 2003-07-13 21:30:47.000000000 -0600 -+++ linux-2.6.0-test1-braam/drivers/net/smc-ultra.c 2003-07-22 01:14:38.000000000 -0600 -@@ -122,6 +122,14 @@ MODULE_DEVICE_TABLE(isapnp, ultra_device - #define ULTRA_IO_EXTENT 32 - #define EN0_ERWCNT 0x08 /* Early receive warning count. */ - -+ -+static void ultra_poll(struct net_device *dev) -+{ -+ disable_irq(dev->irq); -+ ei_interrupt(dev->irq, dev, NULL); -+ enable_irq(dev->irq); -+} -+ - /* Probe for the Ultra. This looks like a 8013 with the station - address PROM at I/O ports +8 to +13, with a checksum - following. -@@ -134,6 +142,9 @@ int __init ultra_probe(struct net_device - - SET_MODULE_OWNER(dev); - -+#ifdef HAVE_POLL_CONTROLLER -+ dev->poll_controller = &ultra_poll; -+#endif - if (base_addr > 0x1ff) /* Check a single specified location. */ - return ultra_probe1(dev, base_addr); - else if (base_addr != 0) /* Don't probe at all. */ ---- linux-2.6.0-test1/drivers/net/tlan.c~dump_netdev 2003-07-13 21:30:42.000000000 -0600 -+++ linux-2.6.0-test1-braam/drivers/net/tlan.c 2003-07-22 01:14:38.000000000 -0600 -@@ -345,6 +345,8 @@ static int TLan_EeSendByte( u16, u8, int - static void TLan_EeReceiveByte( u16, u8 *, int ); - static int TLan_EeReadByte( struct net_device *, u8, u8 * ); - -+static void TLan_Poll(struct net_device *); -+ - - static void - TLan_StoreSKB( struct tlan_list_tag *tag, struct sk_buff *skb) -@@ -890,6 +892,9 @@ static int TLan_Init( struct net_device - dev->get_stats = &TLan_GetStats; - dev->set_multicast_list = &TLan_SetMulticastList; - dev->do_ioctl = &TLan_ioctl; -+#ifdef HAVE_POLL_CONTROLLER -+ dev->poll_controller = &TLan_Poll; -+#endif - dev->tx_timeout = &TLan_tx_timeout; - dev->watchdog_timeo = TX_TIMEOUT; - -@@ -1173,7 +1178,14 @@ static irqreturn_t TLan_HandleInterrupt( - return IRQ_HANDLED; - } /* TLan_HandleInterrupts */ - -- -+#ifdef HAVE_POLL_CONTROLLER -+static void TLan_Poll(struct net_device *dev) -+{ -+ disable_irq(dev->irq); -+ TLan_HandleInterrupt(dev->irq, dev, NULL); -+ enable_irq(dev->irq); -+} -+#endif - - - /*************************************************************** ---- linux-2.6.0-test1/drivers/net/tulip/tulip_core.c~dump_netdev 2003-07-13 21:34:48.000000000 -0600 -+++ linux-2.6.0-test1-braam/drivers/net/tulip/tulip_core.c 2003-07-22 01:14:38.000000000 -0600 -@@ -245,6 +245,7 @@ static void tulip_down(struct net_device - static struct net_device_stats *tulip_get_stats(struct net_device *dev); - static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); - static void set_rx_mode(struct net_device *dev); -+static void poll_tulip(struct net_device *dev); - - - -@@ -1630,6 +1631,9 @@ static int __devinit tulip_init_one (str - dev->get_stats = tulip_get_stats; - dev->do_ioctl = private_ioctl; - dev->set_multicast_list = set_rx_mode; -+#ifdef HAVE_POLL_CONTROLLER -+ dev->poll_controller = &poll_tulip; -+#endif - - if (register_netdev(dev)) - goto err_out_free_ring; -@@ -1787,6 +1791,24 @@ static void __devexit tulip_remove_one ( - } - - -+#ifdef HAVE_POLL_CONTROLLER -+ -+/* -+ * Polling 'interrupt' - used by things like netconsole to send skbs -+ * without having to re-enable interrupts. It's not called while -+ * the interrupt routine is executing. -+ */ -+ -+static void poll_tulip (struct net_device *dev) -+{ -+ disable_irq(dev->irq); -+ tulip_interrupt (dev->irq, dev, NULL); -+ enable_irq(dev->irq); -+} -+ -+#endif -+ -+ - static struct pci_driver tulip_driver = { - .name = DRV_NAME, - .id_table = tulip_pci_tbl, ---- linux-2.6.0-test1/include/linux/netdevice.h~dump_netdev 2003-07-22 01:14:05.000000000 -0600 -+++ linux-2.6.0-test1-braam/include/linux/netdevice.h 2003-07-22 01:14:38.000000000 -0600 -@@ -446,6 +446,9 @@ struct net_device - unsigned char *haddr); - int (*neigh_setup)(struct net_device *dev, struct neigh_parms *); - int (*accept_fastpath)(struct net_device *, struct dst_entry*); -+#define HAVE_POLL_CONTROLLER -+ void (*poll_controller)(struct net_device *dev); -+ int (*rx_hook)(struct sk_buff *skb); - - /* bridge stuff */ - struct net_bridge_port *br_port; ---- linux-2.6.0-test1/net/core/dev.c~dump_netdev 2003-07-22 01:14:05.000000000 -0600 -+++ linux-2.6.0-test1-braam/net/core/dev.c 2003-07-22 01:14:38.000000000 -0600 -@@ -1349,8 +1349,6 @@ int netif_rx(struct sk_buff *skb) - struct softnet_data *queue; - unsigned long flags; - -- if (!skb->stamp.tv_sec) -- do_gettimeofday(&skb->stamp); - - /* - * The code is rearranged so that the path is the most -@@ -1360,6 +1358,13 @@ int netif_rx(struct sk_buff *skb) - this_cpu = smp_processor_id(); - queue = &__get_cpu_var(softnet_data); - -+ if (skb->dev->rx_hook) -+ goto rx_hook; -+rx_hook_continue: -+ -+ if (!skb->stamp.tv_sec ) -+ do_gettimeofday(&skb->stamp); -+ - netdev_rx_stat[this_cpu].total++; - if (queue->input_pkt_queue.qlen <= netdev_max_backlog) { - if (queue->input_pkt_queue.qlen) { -@@ -1402,6 +1407,15 @@ drop: - - kfree_skb(skb); - return NET_RX_DROP; -+rx_hook: -+ { -+ int ret; -+ -+ ret = skb->dev->rx_hook(skb); -+ if (ret == NET_RX_DROP) -+ goto drop; -+ goto rx_hook_continue; -+ } - } - - /* Deliver skb to an old protocol, which is not threaded well - -_ diff --git a/lustre/kernel_patches/patches/dump_netdev_over_netpoll.patch b/lustre/kernel_patches/patches/dump_netdev_over_netpoll.patch deleted file mode 100644 index b93e2f9..0000000 --- a/lustre/kernel_patches/patches/dump_netdev_over_netpoll.patch +++ /dev/null @@ -1,761 +0,0 @@ -Index: linux-2.6.0-test6/drivers/dump/dump_netdev.c -=================================================================== ---- linux-2.6.0-test6.orig/drivers/dump/dump_netdev.c 2003-10-07 16:08:57.000000000 +0800 -+++ linux-2.6.0-test6/drivers/dump/dump_netdev.c 2003-10-09 17:36:18.000000000 +0800 -@@ -14,6 +14,7 @@ - * - * Copyright (C) 2001 Ingo Molnar - * Copyright (C) 2002 International Business Machines Corp. -+ * Rewrited with netpoll by wangdi - * - * This code is released under version 2 of the GNU GPL. - */ -@@ -26,29 +27,19 @@ - #include - #include - #include -+#include - - #include - - static int startup_handshake; - static int page_counter; --static struct net_device *dump_ndev; - static struct in_device *dump_in_dev; --static u16 source_port, target_port; --static u32 source_ip, target_ip; --static unsigned char daddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff} ; --static spinlock_t dump_skb_lock = SPIN_LOCK_UNLOCKED; --static int dump_nr_skbs; --static struct sk_buff *dump_skb; - static unsigned long flags_global; - static int netdump_in_progress; - static char device_name[IFNAMSIZ]; -+int new_req = 0; -+static req_t req; - --/* -- * security depends on the trusted path between the netconsole -- * server and netconsole client, since none of the packets are -- * encrypted. The random magic number protects the protocol -- * against spoofing. -- */ - static u64 dump_magic; - - #define MAX_UDP_CHUNK 1460 -@@ -64,300 +55,28 @@ - #define MAX_SKB_SIZE \ - (MAX_UDP_CHUNK + sizeof(struct udphdr) + \ - sizeof(struct iphdr) + sizeof(struct ethhdr)) -+static char send_buffer[MAX_UDP_CHUNK]; - --static void --dump_refill_skbs(void) --{ -- struct sk_buff *skb; -- unsigned long flags; -- -- spin_lock_irqsave(&dump_skb_lock, flags); -- while (dump_nr_skbs < DUMP_MAX_SKBS) { -- skb = alloc_skb(MAX_SKB_SIZE, GFP_ATOMIC); -- if (!skb) -- break; -- if (dump_skb) -- skb->next = dump_skb; -- else -- skb->next = NULL; -- dump_skb = skb; -- dump_nr_skbs++; -- } -- spin_unlock_irqrestore(&dump_skb_lock, flags); --} -- --static struct --sk_buff * dump_get_skb(void) --{ -- struct sk_buff *skb; -- unsigned long flags; -- -- spin_lock_irqsave(&dump_skb_lock, flags); -- skb = dump_skb; -- if (skb) { -- dump_skb = skb->next; -- skb->next = NULL; -- dump_nr_skbs--; -- } -- spin_unlock_irqrestore(&dump_skb_lock, flags); -- -- return skb; --} -- --/* -- * Zap completed output skbs. -- */ --static void --zap_completion_queue(void) --{ -- int count; -- unsigned long flags; -- int cpu = smp_processor_id(); -- struct softnet_data *softnet_data; -- -- -- softnet_data = &__get_cpu_var(softnet_data); -- count=0; -- if (softnet_data[cpu].completion_queue) { -- struct sk_buff *clist; -- -- local_irq_save(flags); -- clist = softnet_data[cpu].completion_queue; -- softnet_data[cpu].completion_queue = NULL; -- local_irq_restore(flags); -- -- while (clist != NULL) { -- struct sk_buff *skb = clist; -- clist = clist->next; -- __kfree_skb(skb); -- count++; -- if (count > 10000) -- printk("Error in sk list\n"); -- } -- } --} -- --static void --dump_send_skb(struct net_device *dev, const char *msg, unsigned int msg_len, -- reply_t *reply) --{ -- int once = 1; -- int total_len, eth_len, ip_len, udp_len, count = 0; -- struct sk_buff *skb; -- struct udphdr *udph; -- struct iphdr *iph; -- struct ethhdr *eth; -- -- udp_len = msg_len + HEADER_LEN + sizeof(*udph); -- ip_len = eth_len = udp_len + sizeof(*iph); -- total_len = eth_len + ETH_HLEN; -- --repeat_loop: -- zap_completion_queue(); -- if (dump_nr_skbs < DUMP_MAX_SKBS) -- dump_refill_skbs(); -- -- skb = alloc_skb(total_len, GFP_ATOMIC); -- if (!skb) { -- skb = dump_get_skb(); -- if (!skb) { -- count++; -- if (once && (count == 1000000)) { -- printk("possibly FATAL: out of netconsole " -- "skbs!!! will keep retrying.\n"); -- once = 0; -- } -- dev->poll_controller(dev); -- goto repeat_loop; -- } -- } -- -- atomic_set(&skb->users, 1); -- skb_reserve(skb, total_len - msg_len - HEADER_LEN); -- skb->data[0] = NETCONSOLE_VERSION; -- -- put_unaligned(htonl(reply->nr), (u32 *) (skb->data + 1)); -- put_unaligned(htonl(reply->code), (u32 *) (skb->data + 5)); -- put_unaligned(htonl(reply->info), (u32 *) (skb->data + 9)); -- -- memcpy(skb->data + HEADER_LEN, msg, msg_len); -- skb->len += msg_len + HEADER_LEN; -- -- udph = (struct udphdr *) skb_push(skb, sizeof(*udph)); -- udph->source = source_port; -- udph->dest = target_port; -- 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 = source_ip; -- iph->daddr = target_ip; -- 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, dev->dev_addr, dev->addr_len); -- memcpy(eth->h_dest, daddr, dev->addr_len); -+extern void handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty); -+static void dump_rx_hook(struct netpoll *np, int port, char *msg, int len); - -- count=0; --repeat_poll: -- spin_lock(&dev->xmit_lock); -- dev->xmit_lock_owner = smp_processor_id(); -- -- count++; -- -- -- if (netif_queue_stopped(dev)) { -- dev->xmit_lock_owner = -1; -- spin_unlock(&dev->xmit_lock); -- -- dev->poll_controller(dev); -- zap_completion_queue(); -- -- -- goto repeat_poll; -- } -- -- dev->hard_start_xmit(skb, dev); -- -- dev->xmit_lock_owner = -1; -- spin_unlock(&dev->xmit_lock); --} -- --static unsigned short --udp_check(struct udphdr *uh, int len, unsigned long saddr, unsigned long daddr, -- unsigned long base) --{ -- return csum_tcpudp_magic(saddr, daddr, len, IPPROTO_UDP, base); --} -- --static int --udp_checksum_init(struct sk_buff *skb, struct udphdr *uh, -- unsigned short ulen, u32 saddr, u32 daddr) --{ -- if (uh->check == 0) { -- skb->ip_summed = CHECKSUM_UNNECESSARY; -- } else if (skb->ip_summed == CHECKSUM_HW) { -- skb->ip_summed = CHECKSUM_UNNECESSARY; -- if (!udp_check(uh, ulen, saddr, daddr, skb->csum)) -- return 0; -- skb->ip_summed = CHECKSUM_NONE; -- } -- if (skb->ip_summed != CHECKSUM_UNNECESSARY) -- skb->csum = csum_tcpudp_nofold(saddr, daddr, ulen, -- IPPROTO_UDP, 0); -- /* Probably, we should checksum udp header (it should be in cache -- * in any case) and data in tiny packets (< rx copybreak). -- */ -- return 0; --} -- --static __inline__ int --__udp_checksum_complete(struct sk_buff *skb) --{ -- return (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, -- skb->csum)); --} -- --static __inline__ --int udp_checksum_complete(struct sk_buff *skb) --{ -- return skb->ip_summed != CHECKSUM_UNNECESSARY && -- __udp_checksum_complete(skb); --} -- --int new_req = 0; --static req_t req; -+static struct netpoll np = { -+ .name = "netdumpoe", -+ .dev_name = "eth0", -+ .rx_hook = dump_rx_hook, -+ .local_port = 0, -+ .remote_port = 0, -+ .remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, -+}; - --static int --dump_rx_hook(struct sk_buff *skb) -+static void dump_rx_hook(struct netpoll *np, int port, char *msg, int len) - { -- int proto; -- struct iphdr *iph; -- struct udphdr *uh; -- __u32 len, saddr, daddr, ulen; - req_t *__req; -- -- /* -- * First check if were are dumping or doing startup handshake, if -- * not quickly return. -- */ -+ - if (!netdump_in_progress) -- return NET_RX_SUCCESS; -+ goto out; -+ __req = (req_t *)msg; - -- if (skb->dev->type != ARPHRD_ETHER) -- goto out; -- -- proto = ntohs(skb->mac.ethernet->h_proto); -- if (proto != ETH_P_IP) -- goto out; -- -- if (skb->pkt_type == PACKET_OTHERHOST) -- goto out; -- -- if (skb_shared(skb)) -- goto out; -- -- /* IP header correctness testing: */ -- iph = (struct iphdr *)skb->data; -- if (!pskb_may_pull(skb, sizeof(struct iphdr))) -- goto out; -- -- if (iph->ihl < 5 || iph->version != 4) -- goto out; -- -- if (!pskb_may_pull(skb, iph->ihl*4)) -- goto out; -- -- if (ip_fast_csum((u8 *)iph, iph->ihl) != 0) -- goto out; -- -- len = ntohs(iph->tot_len); -- if (skb->len < len || len < iph->ihl*4) -- goto out; -- -- saddr = iph->saddr; -- daddr = iph->daddr; -- if (iph->protocol != IPPROTO_UDP) -- goto out; -- -- if (source_ip != daddr) -- goto out; -- -- if (target_ip != saddr) -- goto out; -- -- len -= iph->ihl*4; -- uh = (struct udphdr *)(((char *)iph) + iph->ihl*4); -- ulen = ntohs(uh->len); -- -- if (ulen != len || ulen < (sizeof(*uh) + sizeof(*__req))) -- goto out; -- -- if (udp_checksum_init(skb, uh, ulen, saddr, daddr) < 0) -- goto out; -- -- if (udp_checksum_complete(skb)) -- goto out; -- -- if (source_port != uh->dest) -- goto out; -- -- if (target_port != uh->source) -- goto out; -- -- __req = (req_t *)(uh + 1); - if ((ntohl(__req->command) != COMM_GET_MAGIC) && - (ntohl(__req->command) != COMM_HELLO) && - (ntohl(__req->command) != COMM_START_WRITE_NETDUMP_ACK) && -@@ -372,11 +91,27 @@ - req.nr = ntohl(__req->nr); - new_req = 1; - out: -- return NET_RX_DROP; -+ return; - } - - static void --dump_send_mem(struct net_device *dev, req_t *req, const char* buff, size_t len) -+dump_send_skb(const char *msg, unsigned int msg_len, reply_t *reply) -+{ -+ /*copy the msg to send buffer*/ -+ send_buffer[0] = NETCONSOLE_VERSION; -+ -+ put_unaligned(htonl(reply->nr), (u32 *) (send_buffer + 1)); -+ put_unaligned(htonl(reply->code), (u32 *) (send_buffer + 5)); -+ put_unaligned(htonl(reply->info), (u32 *) (send_buffer + 9)); -+ memcpy(send_buffer + 1 + sizeof(reply_t), msg, msg_len); -+ -+ if (!np.dev) -+ return; -+ netpoll_send_udp(&np, send_buffer, (msg_len + 1 + sizeof(reply_t))); -+} -+ -+static void -+dump_send_mem( req_t *req, const char* buff, size_t len) - { - int i; - -@@ -392,7 +127,7 @@ - unsigned int offset = i*1024; - reply.code = REPLY_MEM; - reply.info = offset; -- dump_send_skb(dev, buff + offset, 1024, &reply); -+ dump_send_skb(buff + offset, 1024, &reply); - } - } - static void dump_do_sysrq(int key) -@@ -400,9 +135,16 @@ - struct pt_regs regs; - - get_current_regs(®s); -- handle_sysrq(key, ®s, NULL, NULL); -+ handle_sysrq(key, ®s, NULL); - } - -+static void netdump_netpoll_poll(struct netpoll *np) -+{ -+ /*FIXME netpoll_set_trap(0) may have impacts to other parts */ -+ netpoll_set_trap(1); -+ netpoll_poll(np); -+ netpoll_set_trap(0); -+} - /* - * This function waits for the client to acknowledge the receipt - * of the netdump startup reply, with the possibility of packets -@@ -433,24 +175,27 @@ - - /* send 300 handshake packets before declaring failure */ - for (i = 0; i < 300; i++) { -- dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply); -- -+ dump_send_skb(tmp, strlen(tmp), &reply); -+#if 0 - /* wait 1 sec */ -+ udelay(100); -+ netpoll_poll(&np); -+ if (new_req) -+ break; -+ } -+#endif - for (j = 0; j < 10000; j++) { - udelay(100); -- dump_ndev->poll_controller(dump_ndev); -- zap_completion_queue(); -+ netdump_netpoll_poll(&np); - if (new_req) - break; - } -- - /* - * if there is no new request, try sending the handshaking - * packet again - */ - if (!new_req) - continue; -- - /* - * check if the new request is of the expected type, - * if so, return, else try sending the handshaking -@@ -504,10 +249,12 @@ - repeatCounter = 0; - total_loop = 0; - while (1) { -- if (!new_req) { -- dump_ndev->poll_controller(dump_ndev); -- zap_completion_queue(); -+ while (!new_req) { -+ netdump_netpoll_poll(&np); -+ if (new_req) -+ break; - } -+#if 0 - if (!new_req) { - repeatCounter++; - -@@ -532,13 +279,15 @@ - repeatCounter = 0; - counter = 0; - total_loop = 0; -+#endif -+ - new_req = 0; - switch (req.command) { - case COMM_NONE: - break; - - case COMM_SEND_MEM: -- dump_send_mem(dump_ndev, &req, buff, len); -+ dump_send_mem(&req, buff, len); - break; - - case COMM_EXIT: -@@ -549,10 +298,11 @@ - case COMM_HELLO: - sprintf(tmp, "Hello, this is netdump version " - "0.%02d\n", NETCONSOLE_VERSION); -+ - reply.code = REPLY_HELLO; - reply.nr = req.nr; - reply.info = net_dev->curr_offset; -- dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply); -+ dump_send_skb(tmp, strlen(tmp), &reply); - break; - - case COMM_GET_PAGE_SIZE: -@@ -560,7 +310,7 @@ - reply.code = REPLY_PAGE_SIZE; - reply.nr = req.nr; - reply.info = PAGE_SIZE; -- dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply); -+ dump_send_skb(tmp, strlen(tmp), &reply); - break; - - case COMM_GET_NR_PAGES: -@@ -569,15 +319,14 @@ - reply.info = num_physpages; - reply.info = page_counter; - sprintf(tmp, "Number of pages: %ld\n", num_physpages); -- dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply); -+ dump_send_skb(tmp, strlen(tmp), &reply); - break; - - case COMM_GET_MAGIC: - reply.code = REPLY_MAGIC; - reply.nr = req.nr; - reply.info = NETCONSOLE_VERSION; -- dump_send_skb(dump_ndev, (char *)&dump_magic, -- sizeof(dump_magic), &reply); -+ dump_send_skb((char *)&dump_magic, sizeof(dump_magic), &reply); - break; - case COMM_SYSRQ: - dump_do_sysrq(req.from); -@@ -585,7 +334,7 @@ - reply.nr = req.nr; - reply.info = req.from; - sprintf(tmp, "SYSRQ command %d \n", req.from); -- dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply); -+ dump_send_skb(tmp, strlen(tmp), &reply); - break; - default: - reply.code = REPLY_ERROR; -@@ -593,7 +342,7 @@ - reply.info = req.command; - sprintf(tmp, "Got unknown command code %d!\n", - req.command); -- dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply); -+ dump_send_skb(tmp, strlen(tmp), &reply); - break; - } - } -@@ -605,45 +354,45 @@ - static int - dump_validate_config(void) - { -- source_ip = dump_in_dev->ifa_list->ifa_local; -- if (!source_ip) { -+#if 0 -+ np.local_ip = dump_in_dev->ifa_list->ifa_local; -+ if (!np.local_ip) { - printk("network device %s has no local address, " - "aborting.\n", device_name); - return -1; - } -- --#define IP(x) ((unsigned char *)&source_ip)[x] -+#endif -+#define IP(x) ((unsigned char *)&np.local_ip)[x] - printk("Source %d.%d.%d.%d", IP(0), IP(1), IP(2), IP(3)); - #undef IP - -- if (!source_port) { -+ if (!np.local_port) { - printk("source_port parameter not specified, aborting.\n"); - return -1; - } -- printk(":%i\n", source_port); -- source_port = htons(source_port); -+ printk(":%i\n", np.local_port); - -- if (!target_ip) { -+ if (!np.remote_ip) { - printk("target_ip parameter not specified, aborting.\n"); - return -1; - } - --#define IP(x) ((unsigned char *)&target_ip)[x] -+#define IP(x) ((unsigned char *)&np.remote_ip)[x] - printk("Target %d.%d.%d.%d", IP(0), IP(1), IP(2), IP(3)); - #undef IP - -- if (!target_port) { -+ if (!np.remote_port) { - printk("target_port parameter not specified, aborting.\n"); - return -1; - } -- printk(":%i\n", target_port); -- target_port = htons(target_port); -+ printk(":%i\n", np.remote_port); - - printk("Target Ethernet Address %02x:%02x:%02x:%02x:%02x:%02x", -- daddr[0], daddr[1], daddr[2], daddr[3], daddr[4], daddr[5]); -+ np.remote_mac[0], np.remote_mac[1], np.remote_mac[2], -+ np.remote_mac[3], np.remote_mac[4], np.remote_mac[5]); - -- if ((daddr[0] & daddr[1] & daddr[2] & daddr[3] & daddr[4] & -- daddr[5]) == 255) -+ if ((np.remote_mac[0] & np.remote_mac[1] & np.remote_mac[2] & -+ np.remote_mac[3] & np.remote_mac[4] & np.remote_mac[5]) == 255) - printk("(Broadcast)"); - printk("\n"); - return 0; -@@ -659,31 +408,24 @@ - dump_net_open(struct dump_dev *net_dev, unsigned long arg) - { - int retval = 0; -- -+#if 0 - /* get the interface name */ - if (copy_from_user(device_name, (void *)arg, IFNAMSIZ)) - return -EFAULT; - -- if (!(dump_ndev = dev_get_by_name(device_name))) { -+ if (!(np.dev = dev_get_by_name(device_name))) { - printk("network device %s does not exist, aborting.\n", - device_name); - return -ENODEV; - } -- -- if (!dump_ndev->poll_controller) { -- printk("network device %s does not implement polling yet, " -- "aborting.\n", device_name); -- retval = -1; /* return proper error */ -- goto err1; -- } -- -- if (!(dump_in_dev = in_dev_get(dump_ndev))) { -+#endif -+ if (!(dump_in_dev = in_dev_get(np.dev))) { - printk("network device %s is not an IP protocol device, " - "aborting.\n", device_name); - retval = -EINVAL; - goto err1; - } -- -+ - if ((retval = dump_validate_config()) < 0) - goto err2; - -@@ -694,7 +436,7 @@ - err2: - in_dev_put(dump_in_dev); - err1: -- dev_put(dump_ndev); -+ dev_put(np.dev); - return retval; - } - -@@ -707,8 +449,8 @@ - { - if (dump_in_dev) - in_dev_put(dump_in_dev); -- if (dump_ndev) -- dev_put(dump_ndev); -+ if (np.dev) -+ dev_put(np.dev); - return 0; - } - -@@ -720,7 +462,6 @@ - dump_net_silence(struct dump_dev *net_dev) - { - local_irq_save(flags_global); -- dump_ndev->rx_hook = dump_rx_hook; - startup_handshake = 1; - net_dev->curr_offset = 0; - printk("Dumping to network device %s on CPU %d ...\n", device_name, -@@ -740,7 +481,7 @@ - reply_t reply; - char tmp[200]; - -- if (!dump_ndev) -+ if (!np.dev) - return (0); - - sprintf(tmp, "NETDUMP end.\n"); -@@ -748,11 +489,10 @@ - reply.code = REPLY_END_NETDUMP; - reply.nr = 0; - reply.info = 0; -- dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply); -+ dump_send_skb(tmp, strlen(tmp), &reply); - } - printk("NETDUMP END!\n"); - local_irq_restore(flags_global); -- dump_ndev->rx_hook = NULL; - startup_handshake = 0; - return 0; - } -@@ -809,18 +549,19 @@ - static int - dump_net_ioctl(struct dump_dev *net_dev, unsigned int cmd, unsigned long arg) - { -+ #if 0 - switch (cmd) { - case DIOSTARGETIP: -- target_ip = arg; -+ np.remote_ip = arg; - break; - case DIOSTARGETPORT: -- target_port = (u16)arg; -+ np.remote_port = (u16)arg; - break; - case DIOSSOURCEPORT: -- source_port = (u16)arg; -+ np.local_port = (u16)arg; - break; - case DIOSETHADDR: -- return copy_from_user(daddr, (void *)arg, 6); -+ return copy_from_user(np.remote_mac, (void *)arg, 6); - break; - case DIOGTARGETIP: - case DIOGTARGETPORT: -@@ -830,6 +571,7 @@ - default: - return -EINVAL; - } -+ #endif - return 0; - } - -@@ -851,17 +593,28 @@ - .curr_offset = 0 - }; - -+static int option_setup(char *opt) -+{ -+ return netpoll_parse_options(&np, opt); -+} -+ -+__setup("netdumpoe=", option_setup); -+ -+ - static int __init - dump_netdev_init(void) - { - default_dump_netdev.curr_offset = 0; - -+ if(!np.remote_ip || netpoll_setup(&np)) -+ return 1; -+ - if (dump_register_device(&default_dump_netdev) < 0) { - printk("network dump device driver registration failed\n"); - return -1; - } - printk("network device driver for LKCD registered\n"); -- -+ - get_random_bytes(&dump_magic, sizeof(dump_magic)); - return 0; - } -@@ -870,6 +623,7 @@ - dump_netdev_cleanup(void) - { - dump_unregister_device(&default_dump_netdev); -+ netpoll_cleanup(&np); - } - - MODULE_AUTHOR("LKCD Development Team "); diff --git a/lustre/kernel_patches/patches/export-netpoll.patch b/lustre/kernel_patches/patches/export-netpoll.patch deleted file mode 100644 index 6d309417..0000000 --- a/lustre/kernel_patches/patches/export-netpoll.patch +++ /dev/null @@ -1,16 +0,0 @@ -Index: linux-2.6.0-test5/net/core/netpoll.c -=================================================================== ---- linux-2.6.0-test5.orig/net/core/netpoll.c 2003-09-26 15:42:10.000000000 +0800 -+++ linux-2.6.0-test5/net/core/netpoll.c 2003-09-26 15:42:32.000000000 +0800 -@@ -630,3 +630,11 @@ - { - trapped = trap; - } -+EXPORT_SYMBOL(netpoll_set_trap); -+EXPORT_SYMBOL(netpoll_trap); -+EXPORT_SYMBOL(netpoll_parse_options); -+EXPORT_SYMBOL(netpoll_setup); -+EXPORT_SYMBOL(netpoll_cleanup); -+EXPORT_SYMBOL(netpoll_send_skb); -+EXPORT_SYMBOL(netpoll_send_udp); -+EXPORT_SYMBOL(netpoll_poll); diff --git a/lustre/kernel_patches/patches/kgdb-over-netpoll.patch b/lustre/kernel_patches/patches/kgdb-over-netpoll.patch deleted file mode 100644 index 2f7548a..0000000 --- a/lustre/kernel_patches/patches/kgdb-over-netpoll.patch +++ /dev/null @@ -1,1072 +0,0 @@ - l-mpm/Documentation/i386/kgdb/kgdbeth.txt | 88 +---- - l-mpm/arch/i386/kernel/irq.c | 10 - l-mpm/arch/i386/kernel/kgdb_stub.c | 107 +----- - l-mpm/arch/i386/lib/kgdb_serial.c | 2 - l-mpm/drivers/net/Makefile | 5 - l-mpm/drivers/net/kgdb_eth.c | 464 ++++-------------------------- - l-mpm/include/asm-i386/kgdb.h | 11 - l-mpm/net/core/dev.c | 4 - 8 files changed, 129 insertions(+), 562 deletions(-) - -Index: linux-2.6.0-test6/drivers/net/kgdb_eth.c -=================================================================== ---- linux-2.6.0-test6.orig/drivers/net/kgdb_eth.c 2003-10-12 13:12:22.000000000 +0800 -+++ linux-2.6.0-test6/drivers/net/kgdb_eth.c 2003-10-12 13:12:25.000000000 +0800 -@@ -7,36 +7,26 @@ - * - * Twiddled for 2.6 by Robert Walsh - * and wangdi . -+ * -+ * Refactored for netpoll API by Matt Mackall -+ * - */ - --#include --#include --#include - #include --#include - #include - #include --#include - #include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -+#include - - #include -+#include - #include --#include - #include - #include - #include - #include - -+ - #define GDB_BUF_SIZE 512 /* power of 2, please */ - - static char kgdb_buf[GDB_BUF_SIZE] ; -@@ -44,26 +34,28 @@ - static atomic_t kgdb_buf_in_cnt ; - static int kgdb_buf_out_inx ; - -+#define ETH_QUEUE_SIZE 256 -+static char eth_queue[ETH_QUEUE_SIZE]; -+static int outgoing_queue; -+ - extern void set_debug_traps(void) ; /* GDB routine */ - extern void breakpoint(void); - --unsigned int kgdb_remoteip = 0; --unsigned short kgdb_listenport = 6443; --unsigned short kgdb_sendport= 6442; --int kgdb_eth = -1; /* Default tty mode */ --unsigned char kgdb_remotemac[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; --unsigned char kgdb_localmac[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; --volatile int kgdb_eth_is_initializing = 0; --int kgdb_eth_need_breakpoint[NR_CPUS]; -+int kgdboe = 0; /* Default tty mode */ -+int kgdb_eth_need_breakpoint[NR_CPUS]; - --struct net_device *kgdb_netdevice = NULL; -+static void rx_hook(struct netpoll *np, int port, char *msg, int len); - --/* -- * 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) -+static struct netpoll np = { -+ .name = "kgdboe", -+ .dev_name = "eth0", -+ .rx_hook = rx_hook, -+ .local_port = 6443, -+ .remote_port = 6442, -+ .remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, -+}; -+ -+static int read_char(void) - { - /* intr routine has queued chars */ - if (atomic_read(&kgdb_buf_in_cnt) != 0) -@@ -79,287 +71,32 @@ - return -1; /* no data */ - } - --/* -- * Wait until the interface can accept a char, then write it. -- */ --static void --write_buffer(char *buf, int len) -+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 *) kgdb_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))) { -+ if (!np.dev) - return; -- } -- -- atomic_set(&skb->users, 1); -- skb_reserve(skb, total_len - len); -- -- memcpy(skb->data, (unsigned char *) buf, len); -- skb->len += len; -- -- udph = (struct udphdr *) skb_push(skb, sizeof(*udph)); -- udph->source = htons(kgdb_listenport); -- udph->dest = htons(kgdb_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 = kgdb_remoteip; -- 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, kgdb_localmac, kgdb_netdevice->addr_len); -- memcpy(eth->h_dest, kgdb_remotemac, kgdb_netdevice->addr_len); -- --repeat: -- spin_lock(&kgdb_netdevice->xmit_lock); -- kgdb_netdevice->xmit_lock_owner = smp_processor_id(); -- -- if (netif_queue_stopped(kgdb_netdevice)) { -- kgdb_netdevice->xmit_lock_owner = -1; -- spin_unlock(&kgdb_netdevice->xmit_lock); -- -- kgdb_netdevice->poll_controller(kgdb_netdevice); -- goto repeat; -- } -- -- kgdb_netdevice->hard_start_xmit(skb, kgdb_netdevice); -- kgdb_netdevice->xmit_lock_owner = -1; -- spin_unlock(&kgdb_netdevice->xmit_lock); -+ netpoll_send_udp(&np, buf, len); - } - - /* -- * In the interrupt state the target machine will not respond to any -- * arp requests, so handle them here. -- */ -- --static struct sk_buff *send_skb = NULL; -- --void --kgdb_eth_reply_arp(void) --{ -- if (send_skb) { -- spin_lock(&kgdb_netdevice->xmit_lock); -- kgdb_netdevice->xmit_lock_owner = smp_processor_id(); -- kgdb_netdevice->hard_start_xmit(send_skb, kgdb_netdevice); -- kgdb_netdevice->xmit_lock_owner = -1; -- spin_unlock(&kgdb_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 *) kgdb_netdevice->ip_ptr; -- -- /* No arp on this interface */ -- -- if (kgdb_netdevice->flags & IFF_NOARP) { -- return 0; -- } -- -- if (!pskb_may_pull(skb, (sizeof(struct arphdr) + -- (2 * kgdb_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 += kgdb_netdevice->addr_len; -- memcpy(&sip, arp_ptr, 4); -- arp_ptr += 4; -- tha = arp_ptr; -- arp_ptr += kgdb_netdevice->addr_len; -- memcpy(&tip, arp_ptr, 4); -- -- if (tip != in_dev->ifa_list->ifa_address) { -- return 0; -- } -- -- if (kgdb_remoteip != 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 to the ARP request */ -- -- send_skb = alloc_skb(sizeof(struct arphdr) + 2 * (kgdb_netdevice->addr_len + 4) + LL_RESERVED_SPACE(kgdb_netdevice), GFP_ATOMIC); -- -- if (send_skb == NULL) { -- return 0; -- } -- -- skb_reserve(send_skb, LL_RESERVED_SPACE(kgdb_netdevice)); -- send_skb->nh.raw = send_skb->data; -- arp = (struct arphdr *) skb_put(send_skb, sizeof(struct arphdr) + 2 * (kgdb_netdevice->addr_len + 4)); -- send_skb->dev = kgdb_netdevice; -- send_skb->protocol = htons(ETH_P_ARP); -- -- /* Fill the device header for the ARP frame */ -- -- if (kgdb_netdevice->hard_header && -- kgdb_netdevice->hard_header(send_skb, kgdb_netdevice, ptype, -- kgdb_remotemac, kgdb_localmac, -- 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(kgdb_netdevice->type); -- arp->ar_pro = htons(ETH_P_IP); -- -- arp->ar_hln = kgdb_netdevice->addr_len; -- arp->ar_pln = 4; -- arp->ar_op = htons(type); -- -- arp_ptr=(unsigned char *)(arp + 1); -- -- memcpy(arp_ptr, kgdb_netdevice->dev_addr, kgdb_netdevice->addr_len); -- arp_ptr += kgdb_netdevice->addr_len; -- memcpy(arp_ptr, &tip, 4); -- arp_ptr += 4; -- memcpy(arp_ptr, kgdb_localmac, kgdb_netdevice->addr_len); -- arp_ptr += kgdb_netdevice->addr_len; -- memcpy(arp_ptr, &sip, 4); -- return 0; --} -- -- --/* - * Accept an skbuff from net_device layer and add the payload onto - * kgdb buffer -- * -- * When the kgdb 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 --kgdb_net_interrupt(struct sk_buff *skb) -+static void rx_hook(struct netpoll *np, int port, char *msg, int len) - { -- 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 ((kgdb_eth != -1) && (!kgdb_netdevice) && -- (iph->protocol == IPPROTO_UDP) && -- (be16_to_cpu(udph->dest) == kgdb_listenport)) { -- kgdb_sendport = be16_to_cpu(udph->source); -- -- while (kgdb_eth_is_initializing) -- ; -- if (!kgdb_netdevice) -- kgdb_eth_hook(); -- if (!kgdb_netdevice) { -- /* Lets not even try again. */ -- kgdb_eth = -1; -- return 0; -- } -- } -- if (!kgdb_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; -- } -+ int i, chr; - -- if (be16_to_cpu(udph->dest) != kgdb_listenport) { -- return 0; -- } -+ np->remote_port = port; - -- len = (be16_to_cpu(iph->tot_len) - -- (sizeof(struct udphdr) + sizeof(struct iphdr))); -+ /* Is this gdb trying to attach? */ -+ if (!netpoll_trap() && len == 8 && !strncmp(msg, "$Hc-1#09", 8)) -+ kgdb_schedule_breakpoint(); - - for (i = 0; i < len; i++) { -- chr = data[i]; -- if (chr == 3) { -- kgdb_eth_need_breakpoint[smp_processor_id()] = 1; -- continue; -- } -+ chr = msg[i]; -+ if (chr == 3) -+ kgdb_schedule_breakpoint(); -+ - if (atomic_read(&kgdb_buf_in_cnt) >= GDB_BUF_SIZE) { - /* buffer overflow, clear it */ - kgdb_buf_in_inx = 0; -@@ -371,112 +108,54 @@ - kgdb_buf_in_inx &= (GDB_BUF_SIZE - 1); - atomic_inc(&kgdb_buf_in_cnt); - } -- -- if (!kgdb_netdevice->kgdb_is_trapped) { -- /* -- * If a new gdb instance is trying to attach, we need to -- * break here. -- */ -- if (!strncmp(data, "$Hc-1#09", 8)) -- kgdb_eth_need_breakpoint[smp_processor_id()] = 1; -- } -- return 1; - } --EXPORT_SYMBOL(kgdb_net_interrupt); - --int --kgdb_eth_hook(void) -+static int option_setup(char *opt) - { -- char kgdb_netdev[16]; -- extern void kgdb_respond_ok(void); -- -- if (kgdb_remotemac[0] == 0xff) { -- panic("ERROR! 'gdbeth_remotemac' option not set!\n"); -- } -- if (kgdb_localmac[0] == 0xff) { -- panic("ERROR! 'gdbeth_localmac' option not set!\n"); -- } -- if (kgdb_remoteip == 0) { -- panic("ERROR! 'gdbeth_remoteip' option not set!\n"); -- } -+ return netpoll_parse_options(&np, opt); -+} - -- sprintf(kgdb_netdev,"eth%d",kgdb_eth); -+__setup("kgdboe=", option_setup); - -+static int init_kgdboe(void) -+{ - #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 (kgdb_netdevice = dev_base; -- kgdb_netdevice != NULL; -- kgdb_netdevice = kgdb_netdevice->next) { -- if (strncmp(kgdb_netdevice->name, kgdb_netdev, IFNAMSIZ) == 0) { -- break; -- } -- } -- if (!kgdb_netdevice) { -- printk("KGDB NET : Unable to find interface %s\n",kgdb_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. -- */ -- kgdb_eth_is_initializing = 1; -- kgdb_eth_need_breakpoint[smp_processor_id()] = 1; -+ if(!np.remote_ip || netpoll_setup(&np)) -+ return 1; -+ -+ kgdboe = 1; -+ -+ printk(KERN_INFO "kgdb: debugging over ethernet enabled\n"); -+ - return 0; - } - --/* -- * 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) -+int eth_getDebugChar(void) - { -- volatile int chr; -+ int chr; - -- while ((chr = read_char()) < 0) { -- if (send_skb) { -- kgdb_eth_reply_arp(); -- } -- if (kgdb_netdevice->poll_controller) { -- kgdb_netdevice->poll_controller(kgdb_netdevice); -- } else { -- printk("KGDB NET: Error - Device %s is not supported!\n", kgdb_netdevice->name); -- panic("Please add support for kgdb net to this driver"); -- } -- } -+ while ((chr = read_char()) < 0) -+ netpoll_poll(&np); - return chr; - } - --#define ETH_QUEUE_SIZE 256 --static char eth_queue[ETH_QUEUE_SIZE]; --static int outgoing_queue; -- --void --eth_flushDebugChar(void) -+void eth_flushDebugChar(void) - { - if(outgoing_queue) { - write_buffer(eth_queue, outgoing_queue); -- - outgoing_queue = 0; - } - } - --static void --put_char_on_queue(int chr) -+static void put_char_on_queue(int chr) - { - eth_queue[outgoing_queue++] = chr; - if(outgoing_queue == ETH_QUEUE_SIZE) -@@ -485,33 +164,26 @@ - } - } - --/* -- * 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) -+void eth_putDebugChar(int chr) - { - put_char_on_queue(chr); /* this routine will wait */ - } - --void --kgdb_eth_set_trapmode(int mode) -+void kgdb_schedule_breakpoint(void) - { -- if (!kgdb_netdevice) { -- return; -- } -- kgdb_netdevice->kgdb_is_trapped = mode; -+ kgdb_eth_need_breakpoint[smp_processor_id()] = 1; - } - --int --kgdb_eth_is_trapped() -+void kgdb_process_breakpoint(void) - { -- if (!kgdb_netdevice) { -- return 0; -+ /* -+ * Handle a breakpoint queued from inside network driver code -+ * to avoid reentrancy issues -+ */ -+ if (kgdb_eth_need_breakpoint[smp_processor_id()]) { -+ kgdb_eth_need_breakpoint[smp_processor_id()] = 0; -+ BREAKPOINT; - } -- return kgdb_netdevice->kgdb_is_trapped; - } --EXPORT_SYMBOL(kgdb_eth_is_trapped); -+ -+module_init(init_kgdboe); -Index: linux-2.6.0-test6/arch/i386/kernel/kgdb_stub.c -=================================================================== ---- linux-2.6.0-test6.orig/arch/i386/kernel/kgdb_stub.c 2003-10-12 13:12:22.000000000 +0800 -+++ linux-2.6.0-test6/arch/i386/kernel/kgdb_stub.c 2003-10-12 18:57:21.625083056 +0800 -@@ -120,6 +120,7 @@ - #include - #include - #include -+#include - - /************************************************************************ - * -@@ -136,10 +137,6 @@ - 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 kgdb_eth_set_trapmode(int); --extern void kgdb_eth_reply_arp(void); /*send arp request */ --extern volatile int kgdb_eth_is_initializing; -- - - /************************************************************************/ - /* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/ -@@ -281,13 +278,13 @@ - - /* - * I/O dispatch functions... -- * Based upon kgdb_eth, either call the ethernet -+ * Based upon kgdboe, either call the ethernet - * handler or the serial one.. - */ - void - putDebugChar(int c) - { -- if (kgdb_eth == -1) { -+ if (!kgdboe) { - tty_putDebugChar(c); - } else { - eth_putDebugChar(c); -@@ -297,7 +294,7 @@ - int - getDebugChar(void) - { -- if (kgdb_eth == -1) { -+ if (!kgdboe) { - return tty_getDebugChar(); - } else { - return eth_getDebugChar(); -@@ -307,7 +304,7 @@ - void - flushDebugChar(void) - { -- if (kgdb_eth == -1) { -+ if (!kgdboe) { - tty_flushDebugChar(); - } else { - eth_flushDebugChar(); -@@ -494,66 +491,24 @@ - - /* $#. */ - -- if (kgdb_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 bytes each time -- */ -- --#define MAX_SEND_COUNT 30 -- -- int send_count = 0, i = 0; -- char send_buf[MAX_SEND_COUNT]; -+ 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(); - -- 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) != '+'); -- } -+ } while ((getDebugChar() & 0x7f) != '+'); - } - - static char remcomInBuffer[BUFMAX]; -@@ -1142,9 +1097,9 @@ - */ - in_kgdb_entry_log[cpu]++; - in_kgdb_here_log[cpu] = regs; -- if (cpu == spinlock_cpu || waiting_cpus[cpu].task) { -+ if (cpu == spinlock_cpu || waiting_cpus[cpu].task) - goto exit_in_kgdb; -- } -+ - /* - * For protection of the initilization of the spin locks by kgdb - * it locks the kgdb spinlock before it gets the wait locks set -@@ -1153,16 +1108,18 @@ - * sequence where the wait lock is removed prior to the kgdb lock - * so if kgdb gets unlocked, we just exit. - */ -+ - while (spin_is_locked(&kgdb_spinlock) && - !spin_is_locked(waitlocks + cpu)) ; -- if (!spin_is_locked(&kgdb_spinlock)) { -+ if (!spin_is_locked(&kgdb_spinlock)) - goto exit_in_kgdb; -- } -+ - waiting_cpus[cpu].task = current; - waiting_cpus[cpu].pid = (current->pid) ? : (PID_MAX + cpu); - waiting_cpus[cpu].regs = regs; - - spin_unlock_wait(waitlocks + cpu); -+ - /* - * log departure of this cpu - */ -@@ -1281,9 +1238,8 @@ - - __asm__("movl %%cr2,%0":"=r" (address)); - -- if (kgdb_eth != -1) { -- kgdb_eth_set_trapmode(1); -- } -+ if (kgdboe) -+ netpoll_set_trap(1); - - kgdb_local_irq_save(flags); - -@@ -1338,10 +1294,12 @@ - if (num_online_cpus() > 1) { - int me_in_kgdb = in_kgdb_entry_log[smp_processor_id()]; - smp_send_nmi_allbutself(); -+ - while (i < num_online_cpus() && time != end_time) { - int j; - for (j = 0; j < MAX_NO_CPUS; j++) { - if (waiting_cpus[j].task && -+ waiting_cpus[j].task != NOCPU && - !cpu_logged_in[j]) { - i++; - cpu_logged_in[j] = 1; -@@ -1526,13 +1484,8 @@ - remcomOutBuffer[2] = hexchars[signo % 16]; - remcomOutBuffer[3] = 0; - -- if (kgdb_eth_is_initializing) { -- kgdb_eth_is_initializing = 0; -- } else { -- putpacket(remcomOutBuffer); -- } -+ putpacket(remcomOutBuffer); - -- kgdb_eth_reply_arp(); - while (1 == 1) { - error = 0; - remcomOutBuffer[0] = 0; -@@ -1689,10 +1642,6 @@ - - newPC = regs.eip; - -- if (kgdb_eth != -1) { -- kgdb_eth_set_trapmode(0); -- } -- - /* clear the trace bit */ - regs.eflags &= 0xfffffeff; - -@@ -1724,6 +1673,10 @@ - } - } - } -+ -+ if (kgdboe) -+ netpoll_set_trap(0); -+ - correct_hw_break(); - asm volatile ("movl %0, %%db6\n"::"r" (0)); - goto exit_kgdb; -@@ -2430,63 +2383,3 @@ - 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_kgdbeth(char *str) --{ -- kgdb_eth = simple_strtoul(str, NULL, 10); -- return 1; --} -- --static int __init kgdb_opt_kgdbeth_remoteip(char *str) --{ -- kgdb_remoteip = in_aton(str); -- return 1; --} -- --static int __init kgdb_opt_kgdbeth_listenport(char *str) --{ -- kgdb_listenport = simple_strtoul(str, NULL, 10); -- kgdb_sendport = kgdb_listenport - 1; -- return 1; --} -- --static int __init parse_hw_addr(char *str, unsigned char *addr) --{ -- int i; -- char *p; -- -- p = str; -- i = 0; -- while(1) -- { -- unsigned int c; -- -- sscanf(p, "%x:", &c); -- addr[i++] = c; -- while((*p != 0) && (*p != ':')) { -- p++; -- } -- if (*p == 0) { -- break; -- } -- p++; -- } -- -- return 1; --} -- --static int __init kgdb_opt_kgdbeth_remotemac(char *str) --{ -- return parse_hw_addr(str, kgdb_remotemac); --} --static int __init kgdb_opt_kgdbeth_localmac(char *str) --{ -- return parse_hw_addr(str, kgdb_localmac); --} -- -- --__setup("gdbeth=", kgdb_opt_kgdbeth); --__setup("gdbeth_remoteip=", kgdb_opt_kgdbeth_remoteip); --__setup("gdbeth_listenport=", kgdb_opt_kgdbeth_listenport); --__setup("gdbeth_remotemac=", kgdb_opt_kgdbeth_remotemac); --__setup("gdbeth_localmac=", kgdb_opt_kgdbeth_localmac); -- -Index: linux-2.6.0-test6/arch/i386/lib/kgdb_serial.c -=================================================================== ---- linux-2.6.0-test6.orig/arch/i386/lib/kgdb_serial.c 2003-10-12 13:12:22.000000000 +0800 -+++ linux-2.6.0-test6/arch/i386/lib/kgdb_serial.c 2003-10-12 13:12:25.000000000 +0800 -@@ -386,7 +386,7 @@ - static int __init - kgdb_enable_ints(void) - { -- if (kgdb_eth != -1) { -+ if (kgdboe) { - return 0; - } - if (gdb_async_info == NULL) { -Index: linux-2.6.0-test6/drivers/net/Makefile -=================================================================== ---- linux-2.6.0-test6.orig/drivers/net/Makefile 2003-10-12 13:12:22.000000000 +0800 -+++ linux-2.6.0-test6/drivers/net/Makefile 2003-10-12 13:12:25.000000000 +0800 -@@ -32,8 +32,6 @@ - - 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 -@@ -109,6 +107,8 @@ - ifeq ($(CONFIG_SLIP_COMPRESSED),y) - obj-$(CONFIG_SLIP) += slhc.o - endif -+# Must come after all NICs it might use -+obj-$(CONFIG_KGDB) += kgdb_eth.o - - obj-$(CONFIG_DUMMY) += dummy.o - obj-$(CONFIG_DE600) += de600.o -Index: linux-2.6.0-test6/include/asm-i386/kgdb.h -=================================================================== ---- linux-2.6.0-test6.orig/include/asm-i386/kgdb.h 2003-10-12 13:12:23.000000000 +0800 -+++ linux-2.6.0-test6/include/asm-i386/kgdb.h 2003-10-12 13:12:25.000000000 +0800 -@@ -21,17 +21,13 @@ - - struct sk_buff; - --extern int kgdb_eth; --extern unsigned kgdb_remoteip; --extern unsigned short kgdb_listenport; --extern unsigned short kgdb_sendport; --extern unsigned char kgdb_remotemac[6]; --extern unsigned char kgdb_localmac[6]; - extern int kgdb_eth_need_breakpoint[]; -+extern int kgdboe; -+extern void kgdb_schedule_breakpoint(void); -+extern void kgdb_process_breakpoint(void); - - extern int kgdb_tty_hook(void); - extern int kgdb_eth_hook(void); --extern int gdb_net_interrupt(struct sk_buff *skb); - - /* - * GDB debug stub (or any debug stub) can point the 'linux_debug_hook' -Index: linux-2.6.0-test6/Documentation/i386/kgdb/kgdbeth.txt -=================================================================== ---- linux-2.6.0-test6.orig/Documentation/i386/kgdb/kgdbeth.txt 2003-10-12 13:12:22.000000000 +0800 -+++ linux-2.6.0-test6/Documentation/i386/kgdb/kgdbeth.txt 2003-10-12 13:12:25.000000000 +0800 -@@ -6,16 +6,20 @@ - - Robert Walsh (2.6 port) - wangdi (2.6 port) -+Matt Mackall (netpoll api) - San Mehat (original 2.4 code) - - - Introduction - ------------ - --KGDB supports debugging over ethernet. Only a limited set of ethernet --devices are supported right now, but adding support for new devices --should not be too complicated. See "New Devices" below for details. -- -+KGDB supports debugging over ethernet (kgdboe) via polling of a given -+network interface. Most cards should be supported automatically. -+Debugging facilities are available as soon as the network driver and -+kgdboe have initialized. Unfortunately, this is too late in the boot -+process for debugging some issues, but works quite well for many -+others. This should not interfere with normal network usage and -+doesn't require a dedicated NIC. - - Terminology - ----------- -@@ -29,33 +33,25 @@ - Usage - ----- - --You need to use the following command-line options on the TARGET kernel: -- -- gdbeth=DEVICENUM -- gdbeth_remoteip=HOSTIPADDR -- gdbeth_remotemac=REMOTEMAC -- gdbeth_localmac=LOCALMAC -- --kgdbeth=DEVICENUM sets the ethernet device number to listen on for --debugging packets. e.g. kgdbeth=0 listens on eth0. -- --kgdbeth_remoteip=HOSTIPADDR sets the IP address of the HOST machine. --Only packets originating from this IP address will be accepted by the --debugger. e.g. kgdbeth_remoteip=192.168.2.2 -+You need to use the following command-line option on the TARGET kernel: - --kgdbeth_remotemac=REMOTEMAC sets the ethernet address of the HOST machine. --e.g. kgdbeth_remotemac=00:07:70:12:4E:F5 -+ kgdboe=[tgt-port]@/[dev],[host-port]@/[host-macaddr] - --kgdbeth_localmac=LOCALMAC sets the ethernet address of the TARGET machine. --e.g. kgdbeth_localmac=00:10:9F:18:21:3C -+ where -+ tgt-port source for UDP packets (defaults to 6443) -+ tgt-ip source IP to use (interface address) -+ dev network interface (eth0) -+ host-port HOST UDP port (6442) (not really used) -+ host-ip IP address for HOST machine -+ host-macaddr ethernet MAC address for HOST (ff:ff:ff:ff:ff:ff) - --You can also set the following command-line option on the TARGET kernel: -+ examples: - -- kgdbeth_listenport=PORT -+ kgdboe=7000@192.168.0.1/wlan0,7001@192.168.0.2/00:05:3C:04:47:5D -+ kgdboe=@192.168.0.1/,@192.168.0.2/ - --kgdbeth_listenport sets the UDP port to listen on for gdb debugging --packets. The default value is "6443". e.g. kgdbeth_listenport=7654 --causes the kernel to listen on UDP port 7654 for debugging packets. -+Only packets originating from the configured HOST IP address will be -+accepted by the debugger. - - On the HOST side, run gdb as normal and use a remote UDP host as the - target: -@@ -72,47 +68,16 @@ - - You can now continue as if you were debugging over a serial line. - --Observations -------------- -- --I've used this with NFS and various other network applications (ssh, --etc.) and it's doesn't appear to interfere with their operation in --any way. It doesn't seem to effect the NIC it uses - i.e. you don't --need a dedicated NIC for this. -- - Limitations - ----------- - --In the inital release of this code you _must_ break into the system with the --debugger by hand, early after boot, as described above. -- --Otherwise, the first time the kernel tries to enter the debugger (say, via an --oops or a BUG), the kgdb stub will doublefault and die because things aren't --fully set up yet. -- --Supported devices ------------------- -- --Right now, the following drivers are supported: -- -- e100 driver (drivers/net/e100/*) -- 3c59x driver (drivers/net/3c59x.c) -- -- --New devices ------------- -- --Supporting a new device is straightforward. Just add a "poll" routine to --the driver and hook it into the poll_controller field in the netdevice --structure. For an example, look in drivers/net/3c59x.c and search --for CONFIG_KGDB (two places.) -- --The poll routine is usually quite simple - it's usually enough to just --disable interrupts, call the device's interrupt routine and re-enable --interrupts again. -- -+The current release of this code is exclusive of using kgdb on a -+serial interface, so you must boot without the kgdboe option to use -+serial debugging. Trying to debug the network driver while using it -+will prove interesting. - - Bug reports - ----------- - --Send bug reports to Robert Walsh . -+Send bug reports to Robert Walsh Matt -+Mackall and wangdi . diff --git a/lustre/kernel_patches/patches/kgdb_eth.patch b/lustre/kernel_patches/patches/kgdb_eth.patch deleted file mode 100644 index 5c8eaa2..0000000 --- a/lustre/kernel_patches/patches/kgdb_eth.patch +++ /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 -+ * Updated by: Robert Walsh - * ModuleState: Experimental $ - * - * NOTES: See Below $ -@@ -112,6 +113,7 @@ - #include - #include - #include -+#include - - /************************************************************************ - * -@@ -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; - - /* $#. */ -- 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 diff --git a/lustre/kernel_patches/patches/netpoll-core.patch b/lustre/kernel_patches/patches/netpoll-core.patch deleted file mode 100644 index bd55424..0000000 --- a/lustre/kernel_patches/patches/netpoll-core.patch +++ /dev/null @@ -1,854 +0,0 @@ - l-mpm/arch/i386/kernel/irq.c | 15 - l-mpm/include/asm-i386/irq.h | 1 - l-mpm/include/linux/netdevice.h | 22 - - l-mpm/include/linux/netpoll.h | 37 ++ - l-mpm/net/Kconfig | 3 - l-mpm/net/core/Makefile | 1 - l-mpm/net/core/dev.c | 22 - - l-mpm/net/core/netpoll.c | 632 ++++++++++++++++++++++++++++++++++++++++ - 8 files changed, 707 insertions(+), 26 deletions(-) - -Index: linux-2.6.0-test6/net/core/netpoll.c -=================================================================== ---- linux-2.6.0-test6.orig/net/core/netpoll.c 2003-10-07 16:08:51.000000000 +0800 -+++ linux-2.6.0-test6/net/core/netpoll.c 2003-10-09 20:40:07.769057232 +0800 -@@ -0,0 +1,633 @@ -+/* -+ * Common framework for low-level network console, dump, and debugger code -+ * -+ * Sep 8 2003 Matt Mackall -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * We maintain a small pool of fully-sized skbs, to make sure the -+ * message gets out even in extreme OOM situations. -+ */ -+ -+#define MAX_SKBS 32 -+#define MAX_UDP_CHUNK 1460 -+ -+static spinlock_t skb_list_lock = SPIN_LOCK_UNLOCKED; -+static int nr_skbs; -+static struct sk_buff *skbs; -+ -+static spinlock_t rx_list_lock = SPIN_LOCK_UNLOCKED; -+static LIST_HEAD(rx_list); -+ -+static int trapped; -+ -+#define MAX_SKB_SIZE \ -+ (MAX_UDP_CHUNK + sizeof(struct udphdr) + \ -+ sizeof(struct iphdr) + sizeof(struct ethhdr)) -+ -+static int checksum_udp(struct sk_buff *skb, struct udphdr *uh, -+ unsigned short ulen, u32 saddr, u32 daddr) -+{ -+ if (uh->check == 0) -+ return 0; -+ -+ if (skb->ip_summed == CHECKSUM_HW) -+ return csum_tcpudp_magic( -+ saddr, daddr, ulen, IPPROTO_UDP, skb->csum); -+ -+ skb->csum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0); -+ -+ return csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)); -+} -+ -+void netpoll_poll(struct netpoll *np) -+{ -+ int budget = 1; -+ -+ if(!np || !np->dev || !(np->dev->flags & IFF_UP)) -+ return; -+ -+ disable_irq(np->dev->irq); -+ -+ /* Process pending work on NIC */ -+ np->irqfunc(np->dev->irq, np->dev, 0); -+ -+ /* If scheduling is stopped, tickle NAPI bits */ -+ if(trapped && np->dev->poll && -+ test_bit(__LINK_STATE_RX_SCHED, &np->dev->state)) -+ np->dev->poll(np->dev, &budget); -+ -+ enable_irq(np->dev->irq); -+} -+ -+static void refill_skbs(void) -+{ -+ struct sk_buff *skb; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&skb_list_lock, flags); -+ while (nr_skbs < MAX_SKBS) { -+ skb = alloc_skb(MAX_SKB_SIZE, GFP_ATOMIC); -+ if (!skb) -+ break; -+ -+ skb->next = skbs; -+ skbs = skb; -+ nr_skbs++; -+ } -+ spin_unlock_irqrestore(&skb_list_lock, flags); -+} -+ -+static void zap_completion_queue(void) -+{ -+ unsigned long flags; -+ struct softnet_data *sd = &get_cpu_var(softnet_data); -+ -+ if (sd->completion_queue) { -+ struct sk_buff *clist; -+ -+ local_irq_save(flags); -+ clist = sd->completion_queue; -+ sd->completion_queue = NULL; -+ local_irq_restore(flags); -+ -+ while (clist != NULL) { -+ struct sk_buff *skb = clist; -+ clist = clist->next; -+ __kfree_skb(skb); -+ } -+ } -+ -+ put_cpu_var(softnet_data); -+} -+ -+static struct sk_buff * find_skb(struct netpoll *np, int len, int reserve) -+{ -+ int once = 1, count = 0; -+ unsigned long flags; -+ struct sk_buff *skb = NULL; -+ -+repeat: -+ zap_completion_queue(); -+ if (nr_skbs < MAX_SKBS) -+ refill_skbs(); -+ -+ skb = alloc_skb(len, GFP_ATOMIC); -+ -+ if (!skb) { -+ spin_lock_irqsave(&skb_list_lock, flags); -+ skb = skbs; -+ if (skb) -+ skbs = skb->next; -+ skb->next = NULL; -+ nr_skbs--; -+ spin_unlock_irqrestore(&skb_list_lock, flags); -+ } -+ -+ if(!skb) { -+ count++; -+ if (once && (count == 1000000)) { -+ printk("out of netpoll skbs!\n"); -+ once = 0; -+ } -+ netpoll_poll(np); -+ goto repeat; -+ } -+ -+ atomic_set(&skb->users, 1); -+ skb_reserve(skb, reserve); -+ return skb; -+} -+ -+void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) -+{ -+ int status; -+ -+repeat: -+ if(!np || !np->dev || !(np->dev->flags & IFF_UP)) { -+ __kfree_skb(skb); -+ return; -+ } -+ -+ spin_lock(&np->dev->xmit_lock); -+ np->dev->xmit_lock_owner = smp_processor_id(); -+ -+ if (netif_queue_stopped(np->dev)) { -+ np->dev->xmit_lock_owner = -1; -+ spin_unlock(&np->dev->xmit_lock); -+ -+ netpoll_poll(np); -+ zap_completion_queue(); -+ goto repeat; -+ } -+ -+ status = np->dev->hard_start_xmit(skb, np->dev); -+ np->dev->xmit_lock_owner = -1; -+ spin_unlock(&np->dev->xmit_lock); -+ -+ /* transmit busy */ -+ if(status) -+ goto repeat; -+} -+ -+void netpoll_send_udp(struct netpoll *np, const char *msg, int len) -+{ -+ int total_len, eth_len, ip_len, udp_len; -+ struct sk_buff *skb; -+ struct udphdr *udph; -+ struct iphdr *iph; -+ struct ethhdr *eth; -+ -+ udp_len = len + sizeof(*udph); -+ ip_len = eth_len = udp_len + sizeof(*iph); -+ total_len = eth_len + ETH_HLEN; -+ -+ skb = find_skb(np, total_len, total_len - len); -+ if (!skb) -+ return; -+ -+ memcpy(skb->data, msg, len); -+ skb->len += len; -+ -+ udph = (struct udphdr *) skb_push(skb, sizeof(*udph)); -+ udph->source = htons(np->local_port); -+ udph->dest = htons(np->remote_port); -+ 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 = htonl(np->local_ip); -+ iph->daddr = htonl(np->remote_ip); -+ 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, np->local_mac, 6); -+ memcpy(eth->h_dest, np->remote_mac, 6); -+ -+ netpoll_send_skb(np, skb); -+} -+ -+static void arp_reply(struct sk_buff *skb) -+{ -+ struct in_device *in_dev = (struct in_device *) skb->dev->ip_ptr; -+ struct arphdr *arp; -+ unsigned char *arp_ptr, *sha, *tha; -+ int size, type = ARPOP_REPLY, ptype = ETH_P_ARP; -+ u32 sip, tip; -+ struct sk_buff *send_skb; -+ unsigned long flags; -+ struct list_head *p; -+ struct netpoll *np = 0; -+ -+ spin_lock_irqsave(&rx_list_lock, flags); -+ list_for_each(p, &rx_list) { -+ np = list_entry(p, struct netpoll, rx_list); -+ if ( np->dev == skb->dev ) -+ break; -+ np = 0; -+ } -+ spin_unlock_irqrestore(&rx_list_lock, flags); -+ -+ if (!np) return; -+ -+ /* No arp on this interface */ -+ if (!in_dev || skb->dev->flags & IFF_NOARP) -+ return; -+ -+ if (!pskb_may_pull(skb, (sizeof(struct arphdr) + -+ (2 * skb->dev->addr_len) + -+ (2 * sizeof(u32))))) -+ return; -+ -+ 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) || -+ arp->ar_op != htons(ARPOP_REQUEST)) -+ return; -+ -+ arp_ptr= (unsigned char *)(arp+1); -+ sha = arp_ptr; -+ arp_ptr += skb->dev->addr_len; -+ memcpy(&sip, arp_ptr, 4); -+ arp_ptr += 4; -+ tha = arp_ptr; -+ arp_ptr += skb->dev->addr_len; -+ memcpy(&tip, arp_ptr, 4); -+ -+ /* Should we ignore arp? */ -+ if (tip != in_dev->ifa_list->ifa_address || -+ LOOPBACK(tip) || MULTICAST(tip)) -+ return; -+ -+ -+ size = sizeof(struct arphdr) + 2 * (skb->dev->addr_len + 4); -+ send_skb = find_skb(np, size + LL_RESERVED_SPACE(np->dev), -+ LL_RESERVED_SPACE(np->dev)); -+ -+ if (!send_skb) -+ return; -+ -+ send_skb->nh.raw = send_skb->data; -+ arp = (struct arphdr *) skb_put(send_skb, size); -+ send_skb->dev = skb->dev; -+ send_skb->protocol = htons(ETH_P_ARP); -+ -+ /* Fill the device header for the ARP frame */ -+ -+ if (np->dev->hard_header && -+ np->dev->hard_header(send_skb, skb->dev, ptype, -+ np->remote_mac, np->local_mac, -+ send_skb->len) < 0) { -+ kfree_skb(send_skb); -+ return; -+ } -+ -+ /* -+ * 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(np->dev->type); -+ arp->ar_pro = htons(ETH_P_IP); -+ arp->ar_hln = np->dev->addr_len; -+ arp->ar_pln = 4; -+ arp->ar_op = htons(type); -+ -+ arp_ptr=(unsigned char *)(arp + 1); -+ memcpy(arp_ptr, np->dev->dev_addr, np->dev->addr_len); -+ arp_ptr += np->dev->addr_len; -+ memcpy(arp_ptr, &tip, 4); -+ arp_ptr += 4; -+ memcpy(arp_ptr, np->local_mac, np->dev->addr_len); -+ arp_ptr += np->dev->addr_len; -+ memcpy(arp_ptr, &sip, 4); -+ -+ netpoll_send_skb(np, send_skb); -+} -+ -+static int rx_hook(struct sk_buff *skb) -+{ -+ int proto, len, ulen; -+ struct iphdr *iph; -+ struct udphdr *uh; -+ struct netpoll *np; -+ struct list_head *p; -+ unsigned long flags; -+ int rx_hook_called = 0; -+ -+ if (skb->dev->type != ARPHRD_ETHER) -+ goto out; -+ -+ /* check if netpoll clients need ARP */ -+ if (skb->protocol == __constant_htons(ETH_P_ARP) && trapped) { -+ arp_reply(skb); -+ return 1; -+ } -+ -+ proto = ntohs(skb->mac.ethernet->h_proto); -+ if (proto != ETH_P_IP) -+ goto out; -+ if (skb->pkt_type == PACKET_OTHERHOST) -+ goto out; -+ if (skb_shared(skb)) -+ goto out; -+ -+ iph = (struct iphdr *)skb->data; -+ if (!pskb_may_pull(skb, sizeof(struct iphdr))) -+ goto out; -+ if (iph->ihl < 5 || iph->version != 4) -+ goto out; -+ if (!pskb_may_pull(skb, iph->ihl*4)) -+ goto out; -+ if (ip_fast_csum((u8 *)iph, iph->ihl) != 0) -+ goto out; -+ -+ len = ntohs(iph->tot_len); -+ if (skb->len < len || len < iph->ihl*4) -+ goto out; -+ -+ if (iph->protocol != IPPROTO_UDP) -+ goto out; -+ -+ len -= iph->ihl*4; -+ uh = (struct udphdr *)(((char *)iph) + iph->ihl*4); -+ ulen = ntohs(uh->len); -+ -+ if (ulen != len) -+ goto out; -+ if (checksum_udp(skb, uh, ulen, iph->saddr, iph->daddr) < 0) -+ goto out; -+ -+ spin_lock_irqsave(&rx_list_lock, flags); -+ list_for_each(p, &rx_list) { -+ np = list_entry(p, struct netpoll, rx_list); -+ if (np->dev && np->dev != skb->dev) -+ continue; -+ if (np->local_ip && np->local_ip != ntohl(iph->daddr)) -+ continue; -+ if (np->remote_ip && np->remote_ip != ntohl(iph->saddr)) -+ continue; -+ if (np->local_port && np->local_port != ntohs(uh->dest)) -+ continue; -+ -+ if (np->rx_hook){ -+ np->rx_hook(np, ntohs(uh->source), -+ (char *)(uh+1), ulen-sizeof(uh)-4); -+ rx_hook_called = 1; -+ } -+ } -+ spin_unlock_irqrestore(&rx_list_lock, flags); -+ -+ if (rx_hook_called) -+ return 1; -+out: -+ return trapped; -+} -+ -+int netpoll_parse_options(struct netpoll *np, char *opt) -+{ -+ char *cur=opt, *delim; -+ -+ if(*cur != '@') { -+ if ((delim = strchr(cur, '@')) == NULL) -+ goto parse_failed; -+ *delim=0; -+ np->local_port=simple_strtol(cur, 0, 10); -+ cur=delim; -+ } -+ cur++; -+ printk(KERN_INFO "%s: local port %d\n", np->name, np->local_port); -+ -+ if(*cur != '/') { -+ if ((delim = strchr(cur, '/')) == NULL) -+ goto parse_failed; -+ *delim=0; -+ np->local_ip=ntohl(in_aton(cur)); -+ cur=delim; -+ -+ printk(KERN_INFO "%s: local IP %d.%d.%d.%d\n", -+ np->name, HIPQUAD(np->local_ip)); -+ } -+ cur++; -+ -+ if ( *cur != ',') { -+ /* parse out dev name */ -+ if ((delim = strchr(cur, ',')) == NULL) -+ goto parse_failed; -+ *delim=0; -+ strlcpy(np->dev_name, cur, sizeof(np->dev_name)); -+ cur=delim; -+ } -+ cur++; -+ -+ printk(KERN_INFO "%s: interface %s\n", np->name, np->dev_name); -+ -+ if ( *cur != '@' ) { -+ /* dst port */ -+ if ((delim = strchr(cur, '@')) == NULL) -+ goto parse_failed; -+ *delim=0; -+ np->remote_port=simple_strtol(cur, 0, 10); -+ cur=delim; -+ } -+ cur++; -+ printk(KERN_INFO "%s: remote port %d\n", np->name, np->remote_port); -+ -+ /* dst ip */ -+ if ((delim = strchr(cur, '/')) == NULL) -+ goto parse_failed; -+ *delim=0; -+ np->remote_ip=ntohl(in_aton(cur)); -+ cur=delim+1; -+ -+ printk(KERN_INFO "%s: remote IP %d.%d.%d.%d\n", -+ np->name, HIPQUAD(np->remote_ip)); -+ -+ if( *cur != 0 ) -+ { -+ /* MAC address */ -+ if ((delim = strchr(cur, ':')) == NULL) -+ goto parse_failed; -+ *delim=0; -+ np->remote_mac[0]=simple_strtol(cur, 0, 16); -+ cur=delim+1; -+ if ((delim = strchr(cur, ':')) == NULL) -+ goto parse_failed; -+ *delim=0; -+ np->remote_mac[1]=simple_strtol(cur, 0, 16); -+ cur=delim+1; -+ if ((delim = strchr(cur, ':')) == NULL) -+ goto parse_failed; -+ *delim=0; -+ np->remote_mac[2]=simple_strtol(cur, 0, 16); -+ cur=delim+1; -+ if ((delim = strchr(cur, ':')) == NULL) -+ goto parse_failed; -+ *delim=0; -+ np->remote_mac[3]=simple_strtol(cur, 0, 16); -+ cur=delim+1; -+ if ((delim = strchr(cur, ':')) == NULL) -+ goto parse_failed; -+ *delim=0; -+ np->remote_mac[4]=simple_strtol(cur, 0, 16); -+ cur=delim+1; -+ np->remote_mac[5]=simple_strtol(cur, 0, 16); -+ } -+ -+ printk(KERN_INFO "%s: remote ethernet address " -+ "%02x:%02x:%02x:%02x:%02x:%02x\n", -+ np->name, -+ np->remote_mac[0], -+ np->remote_mac[1], -+ np->remote_mac[2], -+ np->remote_mac[3], -+ np->remote_mac[4], -+ np->remote_mac[5]); -+ -+ return 0; -+ -+ parse_failed: -+ printk(KERN_INFO "%s: couldn't parse config at %s!\n", -+ np->name, cur); -+ return -1; -+} -+ -+int netpoll_setup(struct netpoll *np) -+{ -+ struct net_device *ndev = NULL; -+ struct in_device *in_dev; -+ struct irqaction *a; -+ -+ if (np->dev_name) -+ ndev = dev_get_by_name(np->dev_name); -+ if (!ndev) { -+ printk(KERN_ERR "%s: %s doesn't exist, aborting.\n", -+ np->name, np->dev_name); -+ return -1; -+ } -+ -+ if (!(ndev->flags & IFF_UP)) { -+ unsigned short oflags; -+ unsigned long jiff; -+ -+ printk(KERN_INFO "%s: device %s not up yet, forcing it\n", -+ np->name, np->dev_name); -+ -+ oflags = ndev->flags; -+ -+ rtnl_shlock(); -+ if (dev_change_flags(ndev, oflags | IFF_UP) < 0) { -+ printk(KERN_ERR "%s: failed to open %s\n", -+ np->name, np->dev_name); -+ rtnl_shunlock(); -+ return -1; -+ } -+ rtnl_shunlock(); -+ -+ jiff = jiffies + 6*HZ; -+ while(!netif_carrier_ok(ndev)) { -+ if (!time_before(jiffies, jiff)) { -+ printk(KERN_NOTICE -+ "%s: timeout waiting for carrier\n", -+ np->name); -+ break; -+ } -+ cond_resched(); -+ } -+ -+ } -+ -+ if (!memcmp(np->local_mac, "\0\0\0\0\0\0", 6) && ndev->dev_addr) -+ memcpy(np->local_mac, ndev->dev_addr, 6); -+ -+ if (!np->local_ip) -+ { -+ in_dev = in_dev_get(ndev); -+ -+ if (!in_dev) { -+ printk(KERN_ERR "%s: no IP address for %s, aborting\n", -+ np->name, np->dev_name); -+ return -1; -+ } -+ -+ np->local_ip = ntohl(in_dev->ifa_list->ifa_local); -+ in_dev_put(in_dev); -+ printk(KERN_INFO "%s: local IP %d.%d.%d.%d\n", -+ np->name, HIPQUAD(np->local_ip)); -+ } -+ -+ a=find_irq_action(ndev->irq, ndev); -+ if (!a) { -+ printk(KERN_ERR "%s: couldn't find irq handler for %s, " -+ "aborting\n", np->name, np->dev_name); -+ return -1; -+ } -+ -+ np->irqfunc = a->handler; -+ np->dev = ndev; -+ -+ if(np->rx_hook) { -+ unsigned long flags; -+ -+ np->dev->rx_hook = rx_hook; -+ -+ spin_lock_irqsave(&rx_list_lock, flags); -+ list_add(&np->rx_list, &rx_list); -+ spin_unlock_irqrestore(&rx_list_lock, flags); -+ } -+ -+ return 0; -+} -+ -+void netpoll_cleanup(struct netpoll *np) -+{ -+ if(np->rx_hook) { -+ unsigned long flags; -+ -+ spin_lock_irqsave(&rx_list_lock, flags); -+ list_del(&np->rx_list); -+ np->dev->rx_hook = 0; -+ spin_unlock_irqrestore(&rx_list_lock, flags); -+ } -+ -+ np->dev = 0; -+} -+ -+int netpoll_trap() -+{ -+ return trapped; -+} -+ -+void netpoll_set_trap(int trap) -+{ -+ trapped = trap; -+} -Index: linux-2.6.0-test6/include/linux/netpoll.h -=================================================================== ---- linux-2.6.0-test6.orig/include/linux/netpoll.h 2003-10-07 16:08:51.000000000 +0800 -+++ linux-2.6.0-test6/include/linux/netpoll.h 2003-10-07 16:08:51.000000000 +0800 -@@ -0,0 +1,37 @@ -+/* -+ * Common code for low-level network console, dump, and debugger code -+ * -+ * Derived from netconsole, kgdb-over-ethernet, and netdump patches -+ */ -+ -+#ifndef _LINUX_NETPOLL_H -+#define _LINUX_NETPOLL_H -+ -+#include -+#include -+#include -+ -+struct netpoll; -+ -+struct netpoll { -+ struct net_device *dev; -+ char dev_name[16], *name; -+ irqreturn_t (*irqfunc)(int, void *, struct pt_regs *); -+ void (*rx_hook)(struct netpoll *, int, char *, int); -+ u32 local_ip, remote_ip; -+ u16 local_port, remote_port; -+ unsigned char local_mac[6], remote_mac[6]; -+ struct list_head rx_list; -+}; -+ -+void netpoll_poll(struct netpoll *np); -+void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb); -+void netpoll_send_udp(struct netpoll *np, const char *msg, int len); -+int netpoll_parse_options(struct netpoll *np, char *opt); -+int netpoll_setup(struct netpoll *np); -+int netpoll_trap(void); -+void netpoll_set_trap(int trap); -+void netpoll_cleanup(struct netpoll *np); -+ -+ -+#endif -Index: linux-2.6.0-test6/net/core/Makefile -=================================================================== ---- linux-2.6.0-test6.orig/net/core/Makefile 2003-09-28 08:51:03.000000000 +0800 -+++ linux-2.6.0-test6/net/core/Makefile 2003-10-07 16:08:51.000000000 +0800 -@@ -13,3 +13,4 @@ - obj-$(CONFIG_NET_DIVERT) += dv.o - obj-$(CONFIG_NET_PKTGEN) += pktgen.o - obj-$(CONFIG_NET_RADIO) += wireless.o -+obj-$(CONFIG_NETPOLL) += netpoll.o -Index: linux-2.6.0-test6/net/Kconfig -=================================================================== ---- linux-2.6.0-test6.orig/net/Kconfig 2003-09-28 08:50:07.000000000 +0800 -+++ linux-2.6.0-test6/net/Kconfig 2003-10-09 20:36:23.429162080 +0800 -@@ -670,4 +670,7 @@ - - source "net/bluetooth/Kconfig" - -+config NETPOLL -+ def_bool KGDB -+ - endmenu -Index: linux-2.6.0-test6/include/linux/netdevice.h -=================================================================== ---- linux-2.6.0-test6.orig/include/linux/netdevice.h 2003-10-07 16:08:42.000000000 +0800 -+++ linux-2.6.0-test6/include/linux/netdevice.h 2003-10-07 16:08:51.000000000 +0800 -@@ -452,13 +452,13 @@ - unsigned char *haddr); - int (*neigh_setup)(struct net_device *dev, struct neigh_parms *); - int (*accept_fastpath)(struct net_device *, struct dst_entry*); -+#ifdef CONFIG_NETPOLL -+ int (*rx_hook)(struct sk_buff *skb); -+#endif - - /* bridge stuff */ - struct net_bridge_port *br_port; - --#ifdef CONFIG_KGDB -- int kgdb_is_trapped; --#endif - #ifdef CONFIG_NET_POLL_CONTROLLER - void (*poll_controller)(struct net_device *); - #endif -@@ -537,10 +537,8 @@ - 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 --extern int kgdb_eth_is_trapped(void); --extern int kgdb_net_interrupt(struct sk_buff *skb); --extern void kgdb_send_arp_request(void); -+#ifdef CONFIG_NETPOLL -+extern int netpoll_trap(void); - #endif - - typedef int gifconf_func_t(struct net_device * dev, char * bufptr, int len); -@@ -600,10 +598,9 @@ - - static inline void netif_wake_queue(struct net_device *dev) - { --#ifdef CONFIG_KGDB -- if (kgdb_eth_is_trapped()) { -+#ifdef CONFIG_NETPOLL -+ if (netpoll_trap()) - return; -- } - #endif - if (test_and_clear_bit(__LINK_STATE_XOFF, &dev->state)) - __netif_schedule(dev); -@@ -611,10 +608,9 @@ - - static inline void netif_stop_queue(struct net_device *dev) - { --#ifdef CONFIG_KGDB -- if (kgdb_eth_is_trapped()) { -+#ifdef CONFIG_NETPOLL -+ if (netpoll_trap()) - return; -- } - #endif - set_bit(__LINK_STATE_XOFF, &dev->state); - } -Index: linux-2.6.0-test6/net/core/dev.c -=================================================================== ---- linux-2.6.0-test6.orig/net/core/dev.c 2003-10-07 16:08:42.000000000 +0800 -+++ linux-2.6.0-test6/net/core/dev.c 2003-10-09 20:36:23.436161016 +0800 -@@ -1352,16 +1352,8 @@ - struct softnet_data *queue; - unsigned long flags; - --#ifdef CONFIG_KGDB -- /* See if kgdb_eth wants this packet */ -- if (!kgdb_net_interrupt(skb)) { -- /* No.. if we're 'trapped' then junk it */ -- if (kgdb_eth_is_trapped()) { -- kfree_skb(skb); -- return NET_RX_DROP; -- } -- } else { -- /* kgdb_eth ate the packet... drop it silently */ -+#ifdef CONFIG_NETPOLL -+ if (skb->dev->rx_hook && skb->dev->rx_hook(skb)) { - kfree_skb(skb); - return NET_RX_DROP; - } -@@ -1556,6 +1548,13 @@ - int ret = NET_RX_DROP; - unsigned short type = skb->protocol; - -+#ifdef CONFIG_NETPOLL -+ if (skb->dev->rx_hook && skb->dev->rx_hook(skb)) { -+ kfree_skb(skb); -+ return NET_RX_DROP; -+ } -+#endif -+ - if (!skb->stamp.tv_sec) - do_gettimeofday(&skb->stamp); - -Index: linux-2.6.0-test6/include/asm-i386/irq.h -=================================================================== ---- linux-2.6.0-test6.orig/include/asm-i386/irq.h 2003-09-28 08:50:36.000000000 +0800 -+++ linux-2.6.0-test6/include/asm-i386/irq.h 2003-10-07 16:08:51.000000000 +0800 -@@ -24,6 +24,7 @@ - extern void disable_irq_nosync(unsigned int); - extern void enable_irq(unsigned int); - extern void release_x86_irqs(struct task_struct *); -+struct irqaction *find_irq_action(unsigned int irq, void *dev_id); - - #ifdef CONFIG_X86_LOCAL_APIC - #define ARCH_HAS_NMI_WATCHDOG /* See include/linux/nmi.h */ -Index: linux-2.6.0-test6/arch/i386/kernel/irq.c -=================================================================== ---- linux-2.6.0-test6.orig/arch/i386/kernel/irq.c 2003-10-07 16:08:34.000000000 +0800 -+++ linux-2.6.0-test6/arch/i386/kernel/irq.c 2003-10-09 20:36:23.433161472 +0800 -@@ -396,7 +396,6 @@ - } - spin_unlock_irqrestore(&desc->lock, flags); - } -- - /* - * do_IRQ handles all normal device IRQ's (the special - * SMP cross-CPU interrupts have their own specific -@@ -896,6 +895,21 @@ - return 0; - } - -+struct irqaction *find_irq_action(unsigned int irq, void *dev_id) -+{ -+ struct irqaction *a, *r=0; -+ -+ spin_lock_irq(&irq_desc[irq].lock); -+ for(a=irq_desc[irq].action; a; a=a->next) { -+ if(a->dev_id == dev_id) { -+ r=a; -+ break; -+ } -+ } -+ spin_unlock_irq(&irq_desc[irq].lock); -+ return r; -+} -+ - static struct proc_dir_entry * root_irq_dir; - static struct proc_dir_entry * irq_dir [NR_IRQS]; - diff --git a/lustre/kernel_patches/patches/netpoll-pcnet32.patch b/lustre/kernel_patches/patches/netpoll-pcnet32.patch deleted file mode 100644 index f0ad313..0000000 --- a/lustre/kernel_patches/patches/netpoll-pcnet32.patch +++ /dev/null @@ -1,45 +0,0 @@ - drivers/net/pcnet32.c | 16 ++++++++++++++++ - 1 files changed, 16 insertions(+) - -diff -puN drivers/net/pcnet32.c~kgdbeth-pcnet32-support drivers/net/pcnet32.c ---- linux-2.6.0-test6-mm/drivers/net/pcnet32.c~kgdbeth-pcnet32-support 2003-10-06 00:45:54.000000000 +0400 -+++ linux-2.6.0-test6-mm-alexey/drivers/net/pcnet32.c 2003-10-06 00:54:55.000000000 +0400 -@@ -331,6 +331,9 @@ static int pcnet32_init_ring(struct net - static int pcnet32_start_xmit(struct sk_buff *, struct net_device *); - static int pcnet32_rx(struct net_device *); - static void pcnet32_tx_timeout (struct net_device *dev); -+#ifdef CONFIG_NET_POLL_CONTROLLER -+static void pcnet32_rx_poll(struct net_device *); -+#endif - static irqreturn_t pcnet32_interrupt(int, void *, struct pt_regs *); - static int pcnet32_close(struct net_device *); - static struct net_device_stats *pcnet32_get_stats(struct net_device *); -@@ -806,6 +809,10 @@ pcnet32_probe1(unsigned long ioaddr, uns - dev->tx_timeout = pcnet32_tx_timeout; - dev->watchdog_timeo = (5*HZ); - -+#ifdef CONFIG_NET_POLL_CONTROLLER -+ dev->poll_controller = pcnet32_rx_poll; -+#endif -+ - lp->next = pcnet32_dev; - pcnet32_dev = dev; - -@@ -1152,6 +1159,15 @@ pcnet32_start_xmit(struct sk_buff *skb, - return 0; - } - -+#ifdef CONFIG_NET_POLL_CONTROLLER -+static void pcnet32_rx_poll(struct net_device *dev) -+{ -+ disable_irq(dev->irq); -+ pcnet32_interrupt(dev->irq, (void *)dev, 0); -+ enable_irq(dev->irq); -+} -+#endif -+ - /* The PCNET32 interrupt handler. */ - static irqreturn_t - pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs) - -_