* Re: [patch] NE2000 [not found] <Pine.LNX.4.21.0010300344130.6792-100000@web.sajt.cz> @ 2000-10-29 20:08 ` Jeff Garzik 2000-10-29 20:34 ` Alan Cox 2000-10-30 9:17 ` [patch] NE2000 Paul Gortmaker 0 siblings, 2 replies; 32+ messages in thread From: Jeff Garzik @ 2000-10-29 20:08 UTC (permalink / raw) To: pavel rabel; +Cc: linux-net, p_gortmaker, netdev, Linux Kernel Mailing List pavel rabel wrote: > There are three drivers for n2k cards. One is MCA only, one is PCI only, > and the then the third one (ne.c) is both ISA and PCI. I think the ISA > driver should be ISA only, as is described in Documentation and in config > help. So I removed PCI code from ne.c to have ISA only driver. It > gets a bit smaller, although I am not sure whether more code can be > removed. This change sounds ok to me, if noone else objects. (I added to the CC a bit) I saw that code, and was thinking about doing the same thing myself. ne2k-pci.c definitely has changes which are not included in ne.c, and it seems silly to duplicate ne2000 PCI support. Regards, Jeff P.S. Pavel, for the future, patches made with "diff -u" are preferred. -- Jeff Garzik | "Mind if I drive?" -Sam Building 1024 | "Not if you don't mind me clawing at the MandrakeSoft | dash and shrieking like a cheerleader." | -Max - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [patch] NE2000 2000-10-29 20:08 ` [patch] NE2000 Jeff Garzik @ 2000-10-29 20:34 ` Alan Cox 2000-10-30 10:57 ` Jorge Nerin 2000-10-30 9:17 ` [patch] NE2000 Paul Gortmaker 1 sibling, 1 reply; 32+ messages in thread From: Alan Cox @ 2000-10-29 20:34 UTC (permalink / raw) To: Jeff Garzik Cc: pavel rabel, linux-net, p_gortmaker, netdev, Linux Kernel Mailing List > This change sounds ok to me, if noone else objects. (I added to the CC > a bit) I saw that code, and was thinking about doing the same thing > myself. ne2k-pci.c definitely has changes which are not included in > ne.c, and it seems silly to duplicate ne2000 PCI support. Unless there are any cards that need the bug workarounds in ne.c for use on PCI then I see no problem. I've not heard of any. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [patch] NE2000 2000-10-29 20:34 ` Alan Cox @ 2000-10-30 10:57 ` Jorge Nerin 2000-10-31 13:54 ` changed section attributes Petko Manolov [not found] ` <39FFE612.2688A5AD@yahoo.com> 0 siblings, 2 replies; 32+ messages in thread From: Jorge Nerin @ 2000-10-30 10:57 UTC (permalink / raw) To: Alan Cox Cc: Jeff Garzik, pavel rabel, linux-net, p_gortmaker, netdev, Linux Kernel Mailing List Alan Cox wrote: > > > This change sounds ok to me, if noone else objects. (I added to the CC > > a bit) I saw that code, and was thinking about doing the same thing > > myself. ne2k-pci.c definitely has changes which are not included in > > ne.c, and it seems silly to duplicate ne2000 PCI support. > > Unless there are any cards that need the bug workarounds in ne.c for use > on PCI then I see no problem. I've not heard of any. > Ok, I reported it several times, but it gets ignored. I have a Realtek 8029 (ne2k-pci), and with both drivers ne and ne2k-pci I can easily get it stuck by doing a ping -f to a host in the local net, and sometimes it happens doing copies to/from nfs shared resources. rmmod & insmod don't cure the problem, it seems that no interrupts are delivered from the card, and there are no log messages, so a reboot is needed to restore net access. System is dual 2x200mmx 96Mb ide discs no interrupts shared, and as far as I can remember all kernel from 2.2.x, 2.3.x up to 2.4.0-testx exhibit this problem. -- Jorge Nerin <comandante@zaralinux.com> - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* changed section attributes 2000-10-30 10:57 ` Jorge Nerin @ 2000-10-31 13:54 ` Petko Manolov 2000-10-31 14:15 ` Keith Owens [not found] ` <39FFE612.2688A5AD@yahoo.com> 1 sibling, 1 reply; 32+ messages in thread From: Petko Manolov @ 2000-10-31 13:54 UTC (permalink / raw) To: linux-kernel; +Cc: Alan Cox Hi there, I noticed that when i changed to binutils 2.10.91 (Debian,woody) i start to see messages like: "Warning: Ignoring changed section attributes for .modinfo" Chasing down the problem appeared that section modinfo is declared for the first time as ".section .modinfo" without any attributes. This is done by the including of linux/module.h. The next declaration is ".section .modinfo,"a",@progbits". And assembler moans on that line number. Changing the declaration in linux/module.h to ".modinfo,"a"" fixed the problem, but i noticed that the author said that "we want .modinfo to not be allocated" I wonder why? I already tried to allocate it (.modinfo,"a" in module.h) and it seems to work. Any ideas? Petkan - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: changed section attributes 2000-10-31 13:54 ` changed section attributes Petko Manolov @ 2000-10-31 14:15 ` Keith Owens 2000-10-31 14:29 ` Petko Manolov 0 siblings, 1 reply; 32+ messages in thread From: Keith Owens @ 2000-10-31 14:15 UTC (permalink / raw) To: Petko Manolov; +Cc: linux-kernel, Alan Cox On Tue, 31 Oct 2000 15:54:05 +0200, Petko Manolov <petkan@dce.bg> wrote: >"Warning: Ignoring changed section attributes for .modinfo" > >Changing the declaration in linux/module.h to ".modinfo,"a"" >fixed the problem, but i noticed that the author said that >"we want .modinfo to not be allocated" Historically that was the only way of preventing the .modinfo section from being included in modules when they were loaded into the kernel. An alternative is to allow .modinfo to be allocated and have modutils treat it as non-allocated. This feature was added to modutils 2.3.19 on October 22 (bleeding edge toolchains for IA64 are "fun") so anybody who is annoyed by the warning messages can apply this patch. Index: 0-test10-pre7.1/include/linux/module.h --- 0-test10-pre7.1/include/linux/module.h Tue, 31 Oct 2000 08:28:16 +1100 kaos (linux-2.4/W/33_module.h 1.1.2.1.2.1.2.1.2.1.1.1 644) +++ 0-test10-pre7.1(w)/include/linux/module.h Wed, 01 Nov 2000 01:13:22 +1100 kaos (linux-2.4/W/33_module.h 1.1.2.1.2.1.2.1.2.1.1.1 644) @@ -218,11 +218,6 @@ MODULE_GENERIC_TABLE(type##_device,name) /* not put to .modinfo section to avoid section type conflicts */ -/* The attributes of a section are set the first time the section is - seen; we want .modinfo to not be allocated. */ - -__asm__(".section .modinfo\n\t.previous"); - /* Define the module variable, and usage macros. */ extern struct module __this_module; Index: 0-test10-pre7.1/Documentation/Changes --- 0-test10-pre7.1/Documentation/Changes Fri, 27 Oct 2000 22:11:48 +1100 kaos (linux-2.4/G/c/25_Changes 1.1.1.4.1.6 644) +++ 0-test10-pre7.1(w)/Documentation/Changes Wed, 01 Nov 2000 01:13:03 +1100 kaos (linux-2.4/G/c/25_Changes 1.1.1.4.1.6 644) @@ -52,7 +52,7 @@ o Gnu make 3.77 # make --version o binutils 2.9.1.0.25 # ld -v o util-linux 2.10o # kbdrate -v -o modutils 2.3.18 # insmod -V +o modutils 2.3.19 # insmod -V o e2fsprogs 1.19 # tune2fs --version o pcmcia-cs 3.1.21 # cardmgr -V o PPP 2.4.0 # pppd --version @@ -284,7 +284,7 @@ Modutils -------- -o <ftp://ftp.kernel.org/pub/linux/utils/kernel/modutils/v2.3/modutils-2.3.18.tar.bz2> +o <ftp://ftp.kernel.org/pub/linux/utils/kernel/modutils/v2.3/modutils-2.3.19.tar.bz2> Mkinitrd -------- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: changed section attributes 2000-10-31 14:15 ` Keith Owens @ 2000-10-31 14:29 ` Petko Manolov 2000-10-31 14:34 ` Keith Owens 0 siblings, 1 reply; 32+ messages in thread From: Petko Manolov @ 2000-10-31 14:29 UTC (permalink / raw) To: Keith Owens; +Cc: linux-kernel, Alan Cox Keith Owens wrote: > > >Changing the declaration in linux/module.h to ".modinfo,"a"" > >fixed the problem, but i noticed that the author said that > >"we want .modinfo to not be allocated" > > Historically that was the only way of preventing the .modinfo section > from being included in modules when they were loaded into the kernel. > An alternative is to allow .modinfo to be allocated and have modutils > treat it as non-allocated. This feature was added to modutils 2.3.19 > on October 22 (bleeding edge toolchains for IA64 are "fun") so anybody > who is annoyed by the warning messages can apply this patch. [snip] > -/* The attributes of a section are set the first time the section is > - seen; we want .modinfo to not be allocated. */ > - > -__asm__(".section .modinfo\n\t.previous"); > - > /* Define the module variable, and usage macros. */ > extern struct module __this_module; This is exactly what i did (excluding removing of the comment ;-) I wonder why the compiler decides to add ".section .modinfo,"a",@progbits" May be this is the thing which should be fixed. Petkan - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: changed section attributes 2000-10-31 14:29 ` Petko Manolov @ 2000-10-31 14:34 ` Keith Owens 2000-10-31 14:41 ` Petko Manolov 0 siblings, 1 reply; 32+ messages in thread From: Keith Owens @ 2000-10-31 14:34 UTC (permalink / raw) To: Petko Manolov; +Cc: linux-kernel, Alan Cox On Tue, 31 Oct 2000 16:29:16 +0200, Petko Manolov <petkan@dce.bg> wrote: >I wonder why the compiler decides to add ".section >.modinfo,"a",@progbits" >May be this is the thing which should be fixed. That is just gcc speak for section .modinfo is marked as allocated, type progbits. Read the ELF standard if you want to know more. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: changed section attributes 2000-10-31 14:34 ` Keith Owens @ 2000-10-31 14:41 ` Petko Manolov 0 siblings, 0 replies; 32+ messages in thread From: Petko Manolov @ 2000-10-31 14:41 UTC (permalink / raw) To: Keith Owens; +Cc: linux-kernel, Alan Cox Keith Owens wrote: > > On Tue, 31 Oct 2000 16:29:16 +0200, > Petko Manolov <petkan@dce.bg> wrote: > >I wonder why the compiler decides to add ".section > >.modinfo,"a",@progbits" > >May be this is the thing which should be fixed. > > That is just gcc speak for section .modinfo is marked as allocated, > type progbits. Read the ELF standard if you want to know more. I already red the info as pages, but the description was too brief. If this is default gcc behavior then it seems that changing to latest modutils is the only option ;-) I wonder if Linus will apply your patch. best, Petkan - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
[parent not found: <39FFE612.2688A5AD@yahoo.com>]
* Re: [patch] NE2000 [not found] ` <39FFE612.2688A5AD@yahoo.com> @ 2000-11-03 17:45 ` Jorge Nerin 2000-11-04 5:28 ` Andrew Morton 2000-11-06 7:06 ` ping -f kills ne2k (was:[patch] NE2000) Paul Gortmaker 0 siblings, 2 replies; 32+ messages in thread From: Jorge Nerin @ 2000-11-03 17:45 UTC (permalink / raw) To: Paul Gortmaker, Linux Kernel Mailing List, Linux SMP Mailing List Paul Gortmaker wrote: > > Jorge Nerin wrote: > > > > > Ok, I reported it several times, but it gets ignored. I have a Realtek > > 8029 (ne2k-pci), and with both drivers ne and ne2k-pci I can easily get > > it stuck by doing a ping -f to a host in the local net, and sometimes it > > happens doing copies to/from nfs shared resources. > > > > rmmod & insmod don't cure the problem, it seems that no interrupts are > > delivered from the card, and there are no log messages, so a reboot is > > needed to restore net access. > > > > System is dual 2x200mmx 96Mb ide discs no interrupts shared, and as far > > as I can remember all kernel from 2.2.x, 2.3.x up to 2.4.0-testx exhibit > > this problem. > > Any messages from the driver whatsoever? Does running a non-SMP > kernel make the problem go away? > > Paul. > Well, I have tried it with 2.4.0-test10, both SMP and non-SMP, and the result is a little confusing. Under SMP a ping -s 50000 -f other_host takes down the network access with no messages (ne2k-pci), and no possibility of being restored without a reboot. Under UP the same command works ok, but after a while the dots stop for 30sec, then ping prints an 'E' and the dots continue. strace revealed this: sendmsg(4, {msg_name(16)={sin_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("192.168.1.20")}}, msg_iov(1)=[{"\10\0\305~|\23\231\0\v\317\2:\177\236\r\0\10\t\n\v\f\r"..., 50008}], msg_controllen=0, msg_flags=0}, 0x800) = 50008 <30.016855> ping has been waiting for sendmsg to end for 30 seconds! I don't know if this could be caused by filling the network buffers, and then waiting a while while the nic sends it out. As the packet size increases (the -s option) the stops are more frequent, there is still activity on the network, but I don't know if they are my packets or the replies. When ping is stopped it's stuck in sock_wait_for_wmem, and when it's running it's (usually) in wait_for_packet. So I think that it could be a little window near sock_wait_for_wmem that could be SMP insecure wich is affecting me. The code of sock_wait_for_wmem in 2.4.0-test10 is this: static long sock_wait_for_wmem(struct sock * sk, long timeo) { DECLARE_WAITQUEUE(wait, current); clear_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags); add_wait_queue(sk->sleep, &wait); for (;;) { if (signal_pending(current)) break; set_bit(SOCK_NOSPACE, &sk->socket->flags); set_current_state(TASK_INTERRUPTIBLE); if (atomic_read(&sk->wmem_alloc) < sk->sndbuf) break; if (sk->shutdown & SEND_SHUTDOWN) break; if (sk->err) break; timeo = schedule_timeout(timeo); } __set_current_state(TASK_RUNNING); remove_wait_queue(sk->sleep, &wait); return timeo; } Does someone see something SMP insecure? Perhaps I'm totally wrong, this could also be somewhere in the interrupt handling, don't know. -- Jorge Nerin <comandante@zaralinux.com> - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [patch] NE2000 2000-11-03 17:45 ` [patch] NE2000 Jorge Nerin @ 2000-11-04 5:28 ` Andrew Morton 2000-11-06 11:34 ` Jorge Nerin 2000-11-06 18:46 ` kuznet 2000-11-06 7:06 ` ping -f kills ne2k (was:[patch] NE2000) Paul Gortmaker 1 sibling, 2 replies; 32+ messages in thread From: Andrew Morton @ 2000-11-04 5:28 UTC (permalink / raw) To: Jorge Nerin Cc: Paul Gortmaker, Linux Kernel Mailing List, Linux SMP Mailing List Jorge Nerin wrote: > > ... > So I think that it could be a little window near sock_wait_for_wmem that > could be SMP insecure wich is affecting me. > > The code of sock_wait_for_wmem in 2.4.0-test10 is this: > > static long sock_wait_for_wmem(struct sock * sk, long timeo) > { > DECLARE_WAITQUEUE(wait, current); > > clear_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags); > add_wait_queue(sk->sleep, &wait); > for (;;) { > if (signal_pending(current)) > break; > set_bit(SOCK_NOSPACE, &sk->socket->flags); > set_current_state(TASK_INTERRUPTIBLE); > if (atomic_read(&sk->wmem_alloc) < sk->sndbuf) > break; > if (sk->shutdown & SEND_SHUTDOWN) > break; > if (sk->err) > break; > timeo = schedule_timeout(timeo); > } > __set_current_state(TASK_RUNNING); > remove_wait_queue(sk->sleep, &wait); > return timeo; > } > > Does someone see something SMP insecure? Perhaps I'm totally wrong, this > could also be somewhere in the interrupt handling, don't know. No, that code is correct, provided (current->state == TASK_RUNNING) on entry. If it isn't, there's a race window which can cause lost wakeups. As a check you could add: if ((current->state & (TASK_INTERRUPTIBLE|TASK_UNINTERRUPTIBLE)) == 0) BUG(); to the start of this function. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [patch] NE2000 2000-11-04 5:28 ` Andrew Morton @ 2000-11-06 11:34 ` Jorge Nerin 2000-11-06 18:40 ` kuznet 2000-11-06 18:46 ` kuznet 1 sibling, 1 reply; 32+ messages in thread From: Jorge Nerin @ 2000-11-06 11:34 UTC (permalink / raw) To: Andrew Morton Cc: Paul Gortmaker, Linux Kernel Mailing List, Linux SMP Mailing List Andrew Morton wrote: > > Jorge Nerin wrote: > > > > ... > > So I think that it could be a little window near sock_wait_for_wmem that > > could be SMP insecure wich is affecting me. > > > > The code of sock_wait_for_wmem in 2.4.0-test10 is this: > > > > static long sock_wait_for_wmem(struct sock * sk, long timeo) > > { > > DECLARE_WAITQUEUE(wait, current); > > > > clear_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags); > > add_wait_queue(sk->sleep, &wait); > > for (;;) { > > if (signal_pending(current)) > > break; > > set_bit(SOCK_NOSPACE, &sk->socket->flags); > > set_current_state(TASK_INTERRUPTIBLE); > > if (atomic_read(&sk->wmem_alloc) < sk->sndbuf) > > break; > > if (sk->shutdown & SEND_SHUTDOWN) > > break; > > if (sk->err) > > break; > > timeo = schedule_timeout(timeo); > > } > > __set_current_state(TASK_RUNNING); > > remove_wait_queue(sk->sleep, &wait); > > return timeo; > > } > > > > Does someone see something SMP insecure? Perhaps I'm totally wrong, this > > could also be somewhere in the interrupt handling, don't know. > > No, that code is correct, provided (current->state == TASK_RUNNING) > on entry. If it isn't, there's a race window which can cause > lost wakeups. As a check you could add: > > if ((current->state & (TASK_INTERRUPTIBLE|TASK_UNINTERRUPTIBLE)) == 0) > BUG(); > > to the start of this function. OK, added, the function now looks like this: static long sock_wait_for_wmem(struct sock * sk, long timeo) { DECLARE_WAITQUEUE(wait, current); if ((current->state & (TASK_INTERRUPTIBLE|TASK_UNINTERRUPTIBLE)) == 0) BUG(); clear_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags); add_wait_queue(sk->sleep, &wait); for (;;) { if (signal_pending(current)) break; set_bit(SOCK_NOSPACE, &sk->socket->flags); set_current_state(TASK_INTERRUPTIBLE); if (atomic_read(&sk->wmem_alloc) < sk->sndbuf) break; if (sk->shutdown & SEND_SHUTDOWN) break; if (sk->err) break; timeo = schedule_timeout(timeo); } __set_current_state(TASK_RUNNING); remove_wait_queue(sk->sleep, &wait); return timeo; } I have to put it _after_ DECLARE_WAITQUEUE in order to compile, if I put it before it says me that wait is undeclared :-? Well recompile, reboot, and got caugth by BUG(), after some tests. [root@quartz ~]# ping -f -s 15000 pp_head PING pp_head.pp.redvip.net (192.168.1.20) from 192.168.1.3 : 15000(15028) bytes of data. ..............invalid operand: 0000 CPU: 0 EIP: 0010:[<c0195b30>] EFLAGS: 00010296 eax: 0000001a ebx: c2604000 ecx: c021e2e8 edx: c0266440 esi: c26eeba0 edi: c26eeba0 ebp: 7fffffff esp: c2605c88 ds: 0018 es: 0018 ss: 0018 Process ping (pid: 2202, stackpage=c2605000) Stack: c02047a5 c02049eb 000002d2 7fffffff c26eeba0 c2604000 00000000 c26c4024 01234567 c2604000 00000000 00000000 01234567 c2604000 00000000 00000000 c0195c99 c26eeba0 7fffffff c26c4024 c264d0c0 c26c4010 000005dc 00000000 Call Trace: [<c02047a5>] [<c02049eb>] [<c0195c99>] [<c01aa692>] [<c01aaa1e>] [<c01c0180>] [<c01c04de>] [<c01c0180>] [<c01c6f48>] [<c01c6f86>] [<c0192fad>] [<c01c6f48>] [<c01941b8>] [<c0193ee6>] [<c0165c9a>] [<c016e602>] [<c01945fc>] [<c0109477>] Code: 0f 0b 83 c4 0c 8b 87 50 03 00 00 f0 0f ba 70 04 00 8d 4c 24 Violación de segmento [root@quartz ~]# Nov 6 12:00:07 quartz kernel: kernel BUG at sock.c:722! Nov 6 12:00:07 quartz kernel: invalid operand: 0000 Nov 6 12:00:07 quartz kernel: CPU: 0 Nov 6 12:00:07 quartz kernel: EIP: 0010:[sock_wait_for_wmem+104/244] Nov 6 12:00:07 quartz kernel: EFLAGS: 00010296 Nov 6 12:00:07 quartz kernel: eax: 0000001a ebx: c2604000 ecx: c021e2e8 edx: c0266440 Nov 6 12:00:07 quartz kernel: esi: c26eeba0 edi: c26eeba0 ebp: 7fffffff esp: c2605c88 Nov 6 12:00:07 quartz kernel: ds: 0018 es: 0018 ss: 0018 Nov 6 12:00:07 quartz kernel: Process ping (pid: 2202, stackpage=c2605000) Nov 6 12:00:07 quartz kernel: Stack: c02047a5 c02049eb 000002d2 7fffffff c26eeba0 c2604000 00000000 c26c4024 Nov 6 12:00:07 quartz kernel: 01234567 c2604000 00000000 00000000 01234567 c2604000 00000000 00000000 Nov 6 12:00:07 quartz kernel: c0195c99 c26eeba0 7fffffff c26c4024 c264d0c0 c26c4010 000005dc 00000000 Nov 6 12:00:07 quartz kernel: Call Trace: [vga_con+2501/10176] [vga_con+3083/10176] [sock_alloc_send_skb+221/300] [ip_build_xmit_slow+378/1208] [ip_build_xmit+78/816] [raw_getfrag+0/36] [raw_sendmsg+642/752] Nov 6 12:00:07 quartz kernel: [raw_getfrag+0/36] [inet_sendmsg+0/68] [inet_sendmsg+62/68] [sock_sendmsg+129/164] [inet_sendmsg+0/68] [sys_sendmsg+380/464] [sys_recvfrom+238/256] [set_cursor+110/132] Nov 6 12:00:07 quartz kernel: [write_chan+462/488] [sys_socketcall+460/484] [system_call+55/64] Nov 6 12:00:07 quartz kernel: Code: 0f 0b 83 c4 0c 8b 87 50 03 00 00 f0 0f ba 70 04 00 8d 4c 24 Nov 6 12:06:11 quartz kernel: kernel BUG at sock.c:722! Nov 6 12:06:11 quartz kernel: invalid operand: 0000 Nov 6 12:06:11 quartz kernel: CPU: 1 Nov 6 12:06:11 quartz kernel: EIP: 0010:[sock_wait_for_wmem+104/244] Nov 6 12:06:11 quartz kernel: EFLAGS: 00010296 Nov 6 12:06:11 quartz kernel: eax: 0000001a ebx: c1f54000 ecx: c021e2e8 edx: c0266440 Nov 6 12:06:11 quartz kernel: esi: c3cd6100 edi: c3cd6100 ebp: 7fffffff esp: c1f55c88 Nov 6 12:06:11 quartz kernel: ds: 0018 es: 0018 ss: 0018 Nov 6 12:06:11 quartz kernel: Process ping (pid: 2993, stackpage=c1f55000) Nov 6 12:06:11 quartz kernel: Stack: c02047a5 c02049eb 000002d2 7fffffff c3cd6100 c1f54000 00000000 c2648824 Nov 6 12:06:11 quartz kernel: 01234567 c1f54000 00000000 00000000 01234567 c1f54000 00000000 00000000 Nov 6 12:06:11 quartz kernel: c0195c99 c3cd6100 7fffffff c2648824 c260c2c0 c2648810 000005dc 00000000 Nov 6 12:06:11 quartz kernel: Call Trace: [vga_con+2501/10176] [vga_con+3083/10176] [sock_alloc_send_skb+221/300] [ip_build_xmit_slow+378/1208] [ip_build_xmit+78/816] [raw_getfrag+0/36] [raw_sendmsg+642/752] Nov 6 12:06:11 quartz kernel: [raw_getfrag+0/36] [inet_sendmsg+0/68] [inet_sendmsg+62/68] [sock_sendmsg+129/164] [inet_sendmsg+0/68] [sys_sendmsg+380/464] [sys_recvfrom+238/256] [set_cursor+110/132] Nov 6 12:06:11 quartz kernel: [write_chan+462/488] [sys_socketcall+460/484] [system_call+55/64] Nov 6 12:06:11 quartz kernel: Code: 0f 0b 83 c4 0c 8b 87 50 03 00 00 f0 0f ba 70 04 00 8d 4c 24 Nov 6 12:06:11 quartz kernel: NET: 6 messages suppressed. Nov 6 12:06:11 quartz kernel: NAT: 0 dropping untracked packet c26984a0 1 192.168.1.20 -> 192.168.1.3 Nov 6 12:06:11 quartz kernel: NAT: 0 dropping untracked packet c2828a80 1 192.168.1.20 -> 192.168.1.3 Nov 6 12:06:11 quartz kernel: NAT: 0 dropping untracked packet c265d560 1 192.168.1.20 -> 192.168.1.3 Nov 6 12:06:11 quartz kernel: NAT: 0 dropping untracked packet c2828a80 1 192.168.1.20 -> 192.168.1.3 Nov 6 12:06:11 quartz kernel: NAT: 0 dropping untracked packet c53bc820 1 192.168.1.20 -> 192.168.1.3 Nov 6 12:06:11 quartz kernel: NAT: 0 dropping untracked packet c264d780 1 192.168.1.20 -> 192.168.1.3 Nov 6 12:06:41 quartz kernel: kernel BUG at sock.c:722! Nov 6 12:06:41 quartz kernel: invalid operand: 0000 Nov 6 12:06:41 quartz kernel: CPU: 1 Nov 6 12:06:41 quartz kernel: EIP: 0010:[sock_wait_for_wmem+104/244] Nov 6 12:06:41 quartz kernel: EFLAGS: 00010296 Nov 6 12:06:41 quartz kernel: eax: 0000001a ebx: c1f54000 ecx: c021e2e8 edx: c0266440 Nov 6 12:06:41 quartz kernel: esi: c3cd6800 edi: c3cd6800 ebp: 7fffffff esp: c1f55c88 Nov 6 12:06:41 quartz kernel: ds: 0018 es: 0018 ss: 0018 Nov 6 12:06:41 quartz kernel: Process ping (pid: 2994, stackpage=c1f55000) Nov 6 12:06:41 quartz kernel: Stack: c02047a5 c02049eb 000002d2 7fffffff c3cd6800 c1f54000 00000000 c2644824 Nov 6 12:06:41 quartz kernel: 01234567 c1f54000 00000000 00000000 01234567 c1f54000 00000000 00000000 Nov 6 12:06:41 quartz kernel: c0195c99 c3cd6800 7fffffff c2644824 c5b8be60 c2644810 000005dc 00000000 Nov 6 12:06:41 quartz kernel: Call Trace: [vga_con+2501/10176] [vga_con+3083/10176] [sock_alloc_send_skb+221/300] [ip_build_xmit_slow+378/1208] [ip_build_xmit+78/816] [raw_getfrag+0/36] [raw_sendmsg+642/752] Nov 6 12:06:41 quartz kernel: [raw_getfrag+0/36] [inet_sendmsg+0/68] [inet_sendmsg+62/68] [sock_sendmsg+129/164] [inet_sendmsg+0/68] [sys_sendmsg+380/464] [sys_recvfrom+238/256] [kfree_skbmem+40/140] Nov 6 12:06:41 quartz kernel: [__kfree_skb+369/376] [nfsd:__insmod_nfsd_O/lib/modules/2.4.0-test10-ne2k/kernel/fs/nfs+-289558/96] [nfsd:__insmod_nfsd_O/lib/modules/2.4.0-test10-ne2k/kernel/fs/nfs+-288860/96] [qdisc_restart+108/376] [net_tx_action+194/300] [sys_socketcall+460/484] [system_call+55/64] Nov 6 12:06:41 quartz kernel: Code: 0f 0b 83 c4 0c 8b 87 50 03 00 00 f0 0f ba 70 04 00 8d 4c 24 Sorry, I can't pass it througth ksymoops because it doesn't work for me in later kernels (RH 6.9.5) it says Fatal Error (re_compile) - Invalid range end, and I have recompiled it. So I have to give you the results of sysklogd. As a side note I have to say that after those BUG the net is still working, and I have those rules added in init scripts: modprobe -k ip_tables modprobe -k iptable_nat insmod -k ipt_MASQUERADE iptables -t nat -A POSTROUTING -o ppp+ -j MASQUERADE iptables -A FORWARD -i ppp+ -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A FORWARD -o ppp+ -j ACCEPT echo 0 >/proc/sys/net/ipv4/tcp_ecn Under heavy packet load in these tests I see that NAT messages about dropped packets. More tests as requested. -- Jorge Nerin <comandante@zaralinux.com> - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [patch] NE2000 2000-11-06 11:34 ` Jorge Nerin @ 2000-11-06 18:40 ` kuznet 0 siblings, 0 replies; 32+ messages in thread From: kuznet @ 2000-11-06 18:40 UTC (permalink / raw) To: Jorge Nerin; +Cc: linux-kernel Hello! > if ((current->state & (TASK_INTERRUPTIBLE|TASK_UNINTERRUPTIBLE)) > == 0) > BUG(); The Puzzle... 8) It is truly impossible. Alexey - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [patch] NE2000 2000-11-04 5:28 ` Andrew Morton 2000-11-06 11:34 ` Jorge Nerin @ 2000-11-06 18:46 ` kuznet 2000-11-06 22:32 ` Andrew Morton 2000-11-07 2:40 ` Andrew Morton 1 sibling, 2 replies; 32+ messages in thread From: kuznet @ 2000-11-06 18:46 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel Hello! > No, that code is correct, provided (current->state == TASK_RUNNING) > on entry. If it isn't, there's a race window which can cause > lost wakeups. As a check you could add: > > if ((current->state & (TASK_INTERRUPTIBLE|TASK_UNINTERRUPTIBLE)) == 0) > BUG(); Though it really cannot happen and really happens, as we have seen... 8) In any case, Andrew, where is the race, when we enter in sleeping state? Wakeup is not lost, it is just not required when we are not going to schedule and force task to running state. I still do not see how it is possible that task runs in sleeping state. Apparently, set_current_state is forgotten somewhere. Do you see, where? 8) Alexey - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [patch] NE2000 2000-11-06 18:46 ` kuznet @ 2000-11-06 22:32 ` Andrew Morton 2000-11-08 16:45 ` kuznet 2000-11-07 2:40 ` Andrew Morton 1 sibling, 1 reply; 32+ messages in thread From: Andrew Morton @ 2000-11-06 22:32 UTC (permalink / raw) To: kuznet; +Cc: Andrew Morton, linux-kernel kuznet@ms2.inr.ac.ru wrote: > > Hello! > > > No, that code is correct, provided (current->state == TASK_RUNNING) > > on entry. If it isn't, there's a race window which can cause > > lost wakeups. As a check you could add: > > > > if ((current->state & (TASK_INTERRUPTIBLE|TASK_UNINTERRUPTIBLE)) == 0) > > BUG(); > > Though it really cannot happen and really happens, as we have seen... 8) > > In any case, Andrew, where is the race, when we enter in sleeping state? > Wakeup is not lost, it is just not required when we are not going > to schedule and force task to running state. set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(...); /* window here */ set_current_state(TASK_INTERRUPTIBLE); schedule(); If there's a wakeup by another CPU (or this CPU in an interrupt) in that window, current->state will get switched to TASK_RUNNING. Then it's immediately overwritten and we go to sleep. Lost wakeup. > I still do not see how it is possible that task runs in sleeping state. > Apparently, set_current_state is forgotten somewhere. Do you see, where? 8) Nope. Is Jorge running SMP? - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [patch] NE2000 2000-11-06 22:32 ` Andrew Morton @ 2000-11-08 16:45 ` kuznet 0 siblings, 0 replies; 32+ messages in thread From: kuznet @ 2000-11-08 16:45 UTC (permalink / raw) To: Andrew Morton; +Cc: andrewm, linux-kernel Hello! > > In any case, Andrew, where is the race, when we enter in sleeping state? > > Wakeup is not lost, it is just not required when we are not going > > to schedule and force task to running state. > > set_current_state(TASK_INTERRUPTIBLE); > add_wait_queue(...); > /* window here */ > set_current_state(TASK_INTERRUPTIBLE); > schedule(); > > If there's a wakeup by another CPU (or this CPU in an interrupt) in > that window, current->state will get switched to TASK_RUNNING. > > Then it's immediately overwritten and we go to sleep. Lost wakeup. Look into code yet. It looks sort of different. Again: > > Wakeup is not lost, it is just not required when we are not going > > to schedule and force task to running state. So that it is right not depening on anything. Alexey - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [patch] NE2000 2000-11-06 18:46 ` kuznet 2000-11-06 22:32 ` Andrew Morton @ 2000-11-07 2:40 ` Andrew Morton 2000-11-08 20:31 ` kuznet 1 sibling, 1 reply; 32+ messages in thread From: Andrew Morton @ 2000-11-07 2:40 UTC (permalink / raw) To: kuznet; +Cc: Andrew Morton, linux-kernel kuznet@ms2.inr.ac.ru wrote: > > Hello! > > > No, that code is correct, provided (current->state == TASK_RUNNING) > > on entry. If it isn't, there's a race window which can cause > > lost wakeups. As a check you could add: > > > > if ((current->state & (TASK_INTERRUPTIBLE|TASK_UNINTERRUPTIBLE)) == 0) > > BUG(); > > Though it really cannot happen and really happens, as we have seen... 8) > > In any case, Andrew, where is the race, when we enter in sleeping state? > Wakeup is not lost, it is just not required when we are not going > to schedule and force task to running state. > > I still do not see how it is possible that task runs in sleeping state. > Apparently, set_current_state is forgotten somewhere. Do you see, where? 8) > OK, there are a few areas which look fishy. Calling __lock_sock when we're getting ready to wait on a different waitqueue looks like a rather risky area. We have a single task which is on two waitqueues. Consider the case of tcp_data_wait(): add_wait_queue(sk->sleep) set_current_state(TASK_INTERRUPTIBLE); release_sock(sk); if (...) /* Suppose this evaluates to false */ schedule_timeout(); lock_sock(); __lock_sock() { add_wait_queue_exclusive(sk->lock.wq); /* Window 1: What does a wake_up(sk->sleep) do here? */ current->state = TASK_EXCLUSIVE | TASK_UNINTERRUPTIBLE; /* Window 2: Bad things happen here */ schedule(); If someone does a wakeup(sk->sleep) in Window 2 in __lock_sock() the wakeup code will think that the task is sleeping on sk->sleep in state TASK_EXCLUSIVE|TASK_UNINTERRUPTIBLE, when in fact it is not. So a wakeup which _should_ have gone to a different exclusive task actually goes to this one. This is fantastically hard to hit because of the direction of the waitqueue scan. If the wakeup on sk->sleep happens during Window 1 it will be completely lost, but that's OK because this task is not yet TASK_EXCLUSIVE (providing the write ordering behaves as we want?) If a wakeup on sk->lock.wq happens during Window 1 it will be completely lost. wait_for_connect() and wait_for_tcp_memory() play similar games with lock_sock() whereby they can appear to be on two waitqueues at the same time. And again, because lock_sock() uses TASK_EXCLUSIVE a wake_up on sk->sleep could choose this task instead of a TASK_EXCLUSIVE task which is _really_ sleeping on sk->sleep. Now, this may not be a problem in practise, and in fact the above may not be bugs because I missed something. But I suggest you have a think about it. My brain is starting to hurt. But none of these explain Jorge's problem. How he got to where he did in !TASK_RUNNING. Plus the possible lock_sock problems just look too damn hard to hit to explain Jorge's repeatability. It may be useful to put a Pentium hardware watchpoint onto current->state. Does kdb support those? Can sock_fasync() be called when we're on a waitqueue, not in state TASK_RUNNING and prior to schedule()? inet_wait_for_connect() is OK. wait_for_tcp_connect() is OK. tcp_close() is OK. Also, are you sure that all occurrences of current->state = <whatever>; are still safe on weakly ordered CPUs? (Not that this would explain Jorge's problem). hmm.. khttpd tries to do wake-one, but interruptible_sleep_on_timeout() confounds it. Bummer. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [patch] NE2000 2000-11-07 2:40 ` Andrew Morton @ 2000-11-08 20:31 ` kuznet 2000-11-09 1:18 ` David S. Miller 2000-11-09 1:27 ` David S. Miller 0 siblings, 2 replies; 32+ messages in thread From: kuznet @ 2000-11-08 20:31 UTC (permalink / raw) To: Andrew Morton; +Cc: andrewm, Dave Miller, linux-kernel Hello! [ Dave, please, look! I will strain brains this night too. Indeed, this sounds dubious. ] No, Andrew, this is surely not related to either of puzzles even if it is really buggy place. ping does not use either tcp or socket lock. 8) > Can sock_fasync() be called when we're on a waitqueue, not in > state TASK_RUNNING and prior to schedule()? No top level syscalls can be called in either state but running. That funny BUG() proves the opposite, but this must not happen in any case. At least, I still cannot reproduce this here. 8) Alexey > OK, there are a few areas which look fishy. > > Calling __lock_sock when we're getting ready to wait > on a different waitqueue looks like a rather risky area. > We have a single task which is on two waitqueues. > > Consider the case of tcp_data_wait(): > > add_wait_queue(sk->sleep) > set_current_state(TASK_INTERRUPTIBLE); > release_sock(sk); > if (...) /* Suppose this evaluates to false */ > schedule_timeout(); > lock_sock(); > > __lock_sock() > { > add_wait_queue_exclusive(sk->lock.wq); > /* Window 1: What does a wake_up(sk->sleep) do here? */ > current->state = TASK_EXCLUSIVE | TASK_UNINTERRUPTIBLE; > /* Window 2: Bad things happen here */ > schedule(); > > If someone does a wakeup(sk->sleep) in Window 2 in > __lock_sock() the wakeup code will think that the > task is sleeping on sk->sleep in state > TASK_EXCLUSIVE|TASK_UNINTERRUPTIBLE, > when in fact it is not. So a wakeup which _should_ have gone to > a different exclusive task actually goes to this one. This is > fantastically hard to hit because of the direction of the > waitqueue scan. > > If the wakeup on sk->sleep happens during Window 1 > it will be completely lost, but that's OK because > this task is not yet TASK_EXCLUSIVE (providing the > write ordering behaves as we want?) > > If a wakeup on sk->lock.wq happens during Window 1 > it will be completely lost. > > wait_for_connect() and wait_for_tcp_memory() play similar > games with lock_sock() whereby they can appear to be on > two waitqueues at the same time. And again, because > lock_sock() uses TASK_EXCLUSIVE a wake_up on sk->sleep > could choose this task instead of a TASK_EXCLUSIVE task > which is _really_ sleeping on sk->sleep. > > Now, this may not be a problem in practise, and in fact the > above may not be bugs because I missed something. But I suggest you > have a think about it. My brain is starting to hurt. > > But none of these explain Jorge's problem. How he got to where > he did in !TASK_RUNNING. Plus the possible lock_sock problems > just look too damn hard to hit to explain Jorge's repeatability. > > It may be useful to put a Pentium hardware watchpoint onto > current->state. Does kdb support those? > > Can sock_fasync() be called when we're on a waitqueue, not in > state TASK_RUNNING and prior to schedule()? > > inet_wait_for_connect() is OK. > wait_for_tcp_connect() is OK. > tcp_close() is OK. > > Also, are you sure that all occurrences of > > current->state = <whatever>; > > are still safe on weakly ordered CPUs? (Not that this > would explain Jorge's problem). > > hmm.. khttpd tries to do wake-one, but > interruptible_sleep_on_timeout() confounds it. > Bummer. > - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [patch] NE2000 2000-11-08 20:31 ` kuznet @ 2000-11-09 1:18 ` David S. Miller 2000-11-09 1:27 ` David S. Miller 1 sibling, 0 replies; 32+ messages in thread From: David S. Miller @ 2000-11-09 1:18 UTC (permalink / raw) To: kuznet; +Cc: morton, andrewm, linux-kernel From: kuznet@ms2.inr.ac.ru Date: Wed, 8 Nov 2000 23:31:28 +0300 (MSK) [ Dave, please, look! I will strain brains this night too. Indeed, this sounds dubious. ] It is true disaster to be on multiple wait queues at once. There are no doubts. No, Andrew, this is surely not related to either of puzzles even if it is really buggy place. ping does not use either tcp or socket lock. 8) (BTW, this BUG() case sounds like memory corruption, not logic bug in the code. BUTTT there was hard error in test9, but fixed in test10, about wakeups. It would set task running state back to TASK_RUNNING outside of runqueue lock, then add task to runqueue with lock held. I assume test10 was tried already though.) Yes, these multiple wait-queue cases must be repaired. BTW, look at fs/pipe.c:pipe_wait(), whoever wrote this understood, even though second wait queue hides behind semaphore :-))) Consider next the case of being on some wait queue, and touching user space, taking fault and sleeping on disk I/O or low memory. This issue could have very far reaching consequences. I will think about this some more. Later, David S. Miller davem@redhat.com - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [patch] NE2000 2000-11-08 20:31 ` kuznet 2000-11-09 1:18 ` David S. Miller @ 2000-11-09 1:27 ` David S. Miller 2000-11-09 11:20 ` David S. Miller 2000-11-09 18:03 ` kuznet 1 sibling, 2 replies; 32+ messages in thread From: David S. Miller @ 2000-11-09 1:27 UTC (permalink / raw) To: kuznet; +Cc: morton, andrewm, linux-kernel From: kuznet@ms2.inr.ac.ru Date: Wed, 8 Nov 2000 23:31:28 +0300 (MSK) [ Dave, please, look! I will strain brains this night too. Indeed, this sounds dubious. ] Alexey! Even someone understood all this already, look to include/net/sock.h SOCK_SLEEP_{PRE,POST} macros :-) I will compose a patch to fix all this. Later, David S. Miller davem@redhat.com - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [patch] NE2000 2000-11-09 1:27 ` David S. Miller @ 2000-11-09 11:20 ` David S. Miller 2000-11-10 1:45 ` Tom Leete 2000-11-09 18:03 ` kuznet 1 sibling, 1 reply; 32+ messages in thread From: David S. Miller @ 2000-11-09 11:20 UTC (permalink / raw) To: andrewm; +Cc: linux-kernel Date: Thu, 09 Nov 2000 21:53:42 +1100 From: Andrew Morton <andrewm@uow.edu.au> "David S. Miller" wrote: > I will compose a patch to fix all this. I've quickly been through just about all of the kernel wrt waitqueues. My analysis was in error, BEWARE! Being on multiple wait queues at once is just fine. I verified this with Linus tonight. The problem case is in mixing TASK_EXCLUSIVE and non-TASK_EXCLUSIVE sleeps, that is what can actually cause problems. Everything else is fine. Anyways, the (untested) patch below should cure the lock_sock() cases. --- ./net/ipv4/af_inet.c.~1~ Tue Oct 24 14:26:18 2000 +++ ./net/ipv4/af_inet.c Wed Nov 8 17:28:47 2000 @@ -543,24 +543,27 @@ { DECLARE_WAITQUEUE(wait, current); - __set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(sk->sleep, &wait); - /* Basic assumption: if someone sets sk->err, he _must_ * change state of the socket from TCP_SYN_*. * Connect() does not allow to get error notifications * without closing the socket. */ while ((1<<sk->state)&(TCPF_SYN_SENT|TCPF_SYN_RECV)) { + __set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(sk->sleep, &wait); + release_sock(sk); - timeo = schedule_timeout(timeo); + + if ((1<<sk->state)&(TCPF_SYN_SENT|TCPF_SYN_RECV)) + timeo = schedule_timeout(timeo); + + __set_current_state(TASK_RUNNING); + remove_wait_queue(sk->sleep, &wait); + lock_sock(sk); if (signal_pending(current) || !timeo) break; - set_current_state(TASK_INTERRUPTIBLE); } - __set_current_state(TASK_RUNNING); - remove_wait_queue(sk->sleep, &wait); return timeo; } --- ./net/ipv4/tcp.c.~1~ Fri Oct 6 15:45:41 2000 +++ ./net/ipv4/tcp.c Wed Nov 8 17:35:31 2000 @@ -826,10 +826,12 @@ release_sock(sk); *timeo_p = schedule_timeout(*timeo_p); - lock_sock(sk); __set_task_state(tsk, TASK_RUNNING); remove_wait_queue(sk->sleep, &wait); + + lock_sock(sk); + sk->tp_pinfo.af_tcp.write_pending--; } return 0; @@ -854,24 +856,31 @@ clear_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags); - add_wait_queue(sk->sleep, &wait); for (;;) { set_bit(SOCK_NOSPACE, &sk->socket->flags); + add_wait_queue(sk->sleep, &wait); set_current_state(TASK_INTERRUPTIBLE); - if (signal_pending(current)) - break; - if (tcp_memory_free(sk) && !vm_wait) - break; - if (sk->shutdown & SEND_SHUTDOWN) - break; - if (sk->err) + if (signal_pending(current) || + (tcp_memory_free(sk) && !vm_wait) || + (sk->shutdown & SEND_SHUTDOWN) || + sk->err) { + current->state = TASK_RUNNING; + remove_wait_queue(sk->sleep, &wait); break; + } + release_sock(sk); + if (!tcp_memory_free(sk) || vm_wait) current_timeo = schedule_timeout(current_timeo); + + current->state = TASK_RUNNING; + remove_wait_queue(sk->sleep, &wait); + lock_sock(sk); + if (vm_wait) { if (timeo != MAX_SCHEDULE_TIMEOUT && (timeo -= vm_wait-current_timeo) < 0) @@ -881,8 +890,6 @@ timeo = current_timeo; } } - current->state = TASK_RUNNING; - remove_wait_queue(sk->sleep, &wait); return timeo; } @@ -1266,7 +1273,6 @@ DECLARE_WAITQUEUE(wait, current); add_wait_queue(sk->sleep, &wait); - __set_current_state(TASK_INTERRUPTIBLE); set_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags); @@ -1275,11 +1281,12 @@ if (skb_queue_empty(&sk->receive_queue)) timeo = schedule_timeout(timeo); + remove_wait_queue(sk->sleep, &wait); + __set_current_state(TASK_RUNNING); + lock_sock(sk); clear_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags); - remove_wait_queue(sk->sleep, &wait); - __set_current_state(TASK_RUNNING); return timeo; } @@ -1826,19 +1833,23 @@ struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, current); - add_wait_queue(sk->sleep, &wait); - do { + add_wait_queue(sk->sleep, &wait); set_current_state(TASK_INTERRUPTIBLE); - if (!closing(sk)) + if (!closing(sk)) { + tsk->state = TASK_RUNNING; + remove_wait_queue(sk->sleep, &wait); break; + } release_sock(sk); + timeout = schedule_timeout(timeout); + + tsk->state = TASK_RUNNING; + remove_wait_queue(sk->sleep, &wait); + lock_sock(sk); } while (!signal_pending(tsk) && timeout); - - tsk->state = TASK_RUNNING; - remove_wait_queue(sk->sleep, &wait); } adjudge_to_death: @@ -2009,12 +2020,17 @@ * our exclusiveness temporarily when we get woken up without * having to remove and re-insert us on the wait queue. */ - add_wait_queue_exclusive(sk->sleep, &wait); for (;;) { + add_wait_queue_exclusive(sk->sleep, &wait); current->state = TASK_EXCLUSIVE | TASK_INTERRUPTIBLE; + release_sock(sk); if (sk->tp_pinfo.af_tcp.accept_queue == NULL) timeo = schedule_timeout(timeo); + + current->state = TASK_RUNNING; + remove_wait_queue(sk->sleep, &wait); + lock_sock(sk); err = 0; if (sk->tp_pinfo.af_tcp.accept_queue) @@ -2029,8 +2045,6 @@ if (!timeo) break; } - current->state = TASK_RUNNING; - remove_wait_queue(sk->sleep, &wait); return err; } - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [patch] NE2000 2000-11-09 11:20 ` David S. Miller @ 2000-11-10 1:45 ` Tom Leete 0 siblings, 0 replies; 32+ messages in thread From: Tom Leete @ 2000-11-10 1:45 UTC (permalink / raw) To: David S. Miller; +Cc: andrewm, linux-kernel "David S. Miller" wrote: > > Date: Thu, 09 Nov 2000 21:53:42 +1100 > From: Andrew Morton <andrewm@uow.edu.au> > > "David S. Miller" wrote: > > I will compose a patch to fix all this. > > I've quickly been through just about all of the kernel wrt > waitqueues. > > My analysis was in error, BEWARE! > > Being on multiple wait queues at once is just fine. I verified this > with Linus tonight. > > The problem case is in mixing TASK_EXCLUSIVE and non-TASK_EXCLUSIVE > sleeps, that is what can actually cause problems. > > Everything else is fine. Anyways, the (untested) patch below should > cure the lock_sock() cases. > > --- ./net/ipv4/af_inet.c.~1~ Tue Oct 24 14:26:18 2000 > +++ ./net/ipv4/af_inet.c Wed Nov 8 17:28:47 2000 [...] > --- ./net/ipv4/tcp.c.~1~ Fri Oct 6 15:45:41 2000 > +++ ./net/ipv4/tcp.c Wed Nov 8 17:35:31 2000 This touches the places where I saw hangs, so I'm testing. Too soon to have statistics, but with this patch I have observed no more failures to wake (what I referred to as "soft hangs"). I have seen a total I/O lockup, but no info escapes to indicate its source. No NMI wakeup available, maybe I should rig a pushbutton. Tom - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [patch] NE2000 2000-11-09 1:27 ` David S. Miller 2000-11-09 11:20 ` David S. Miller @ 2000-11-09 18:03 ` kuznet 2000-11-09 18:01 ` Steve Whitehouse 1 sibling, 1 reply; 32+ messages in thread From: kuznet @ 2000-11-09 18:03 UTC (permalink / raw) To: David S. Miller; +Cc: morton, andrewm, linux-kernel Hello! > Alexey! Even someone understood all this already, look > to include/net/sock.h SOCK_SLEEP_{PRE,POST} macros :-) > > I will compose a patch to fix all this. O! But who was this wiseman? 8) Alexey - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [patch] NE2000 2000-11-09 18:03 ` kuznet @ 2000-11-09 18:01 ` Steve Whitehouse 0 siblings, 0 replies; 32+ messages in thread From: Steve Whitehouse @ 2000-11-09 18:01 UTC (permalink / raw) To: kuznet; +Cc: David S. Miller, morton, andrewm, linux-kernel Hi, I have to own up and say that it was me :-) you'll see that DECnet is the only protocol to use these macros at the moment. I'm sure though that I only copied what IPv4 was doing at the time, along with the hints I had from yourself and Dave, Steve. > > Hello! > > > Alexey! Even someone understood all this already, look > > to include/net/sock.h SOCK_SLEEP_{PRE,POST} macros :-) > > > > I will compose a patch to fix all this. > > O! But who was this wiseman? 8) > > Alexey > - > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > Please read the FAQ at http://www.tux.org/lkml/ > - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: ping -f kills ne2k (was:[patch] NE2000) 2000-11-03 17:45 ` [patch] NE2000 Jorge Nerin 2000-11-04 5:28 ` Andrew Morton @ 2000-11-06 7:06 ` Paul Gortmaker 2000-11-06 20:08 ` Jorge Nerin 1 sibling, 1 reply; 32+ messages in thread From: Paul Gortmaker @ 2000-11-06 7:06 UTC (permalink / raw) To: Jorge Nerin; +Cc: Linux Kernel Mailing List, Linux SMP Mailing List [-- Attachment #1: Type: text/plain, Size: 1068 bytes --] > > Well, I have tried it with 2.4.0-test10, both SMP and non-SMP, and the > result is a little confusing. > > Under SMP a ping -s 50000 -f other_host takes down the network access > with no messages (ne2k-pci), and no possibility of being restored > without a reboot. > > Under UP the same command works ok, but after a while the dots stop for > 30sec, then ping prints an 'E' and the dots continue. strace revealed > this: Another suggestion - if you have your heart set on using ping as your network stress tool, you may want to try using multiple instances of MTU sized pings versus a single "ping -s 50000". In this way you aren't involving any IP frag code and its associated bean counting - giving us one less factor to consider. Oh, and since you get a silent failure, maybe you would be interested in testing this patch I was (originally) saving for 2.5.x. -- It adds watchdog transmit timeout functionality to 8390.c (which is used by the ne2k-pci driver). Last time I updated it was a couple of months ago, but nothing has changed since then. Paul. [-- Attachment #2: 2400-t5-8390-diff0 --] [-- Type: text/plain, Size: 5623 bytes --] --- linux~/drivers/net/8390.c Fri Jul 7 03:45:36 2000 +++ linux/drivers/net/8390.c Sat Jul 22 04:56:51 2000 @@ -38,6 +38,7 @@ Paul Gortmaker : add kmod support for auto-loading of the 8390 module by all drivers that require it. Alan Cox : Spinlocking work, added 'BUG_83C690' + Paul Gortmaker : Separate out Tx timeout code from Tx path. Sources: The National Semiconductor LAN Databook, and the 3Com 3c503 databook. @@ -105,6 +106,7 @@ /* Index to functions. */ static void ei_tx_intr(struct net_device *dev); static void ei_tx_err(struct net_device *dev); +static void ei_tx_timeout(struct net_device *dev); static void ei_receive(struct net_device *dev); static void ei_rx_overrun(struct net_device *dev); @@ -161,6 +163,13 @@ printk(KERN_EMERG "%s: ei_open passed a non-existent device!\n", dev->name); return -ENXIO; } + + /* The card I/O part of the driver (e.g. 3c503) can hook a Tx timeout + wrapper that does e.g. media check & then calls ei_tx_timeout. */ + if (dev->tx_timeout == NULL) + dev->tx_timeout = ei_tx_timeout; + if (dev->watchdog_timeo <= 0) + dev->watchdog_timeo = TX_TIMEOUT; /* * Grab the page lock so we own the register set, then call @@ -200,89 +209,66 @@ } /** - * ei_start_xmit - begin packet transmission - * @skb: packet to be sent - * @dev: network device to which packet is sent + * ei_tx_timeout - handle transmit time out condition + * @dev: network device which has apparently fallen asleep * - * Sends a packet to an 8390 network device. + * Called by kernel when device never acknowledges a transmit has + * completed (or failed) - i.e. never posted a Tx related interrupt. */ - -static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) + +void ei_tx_timeout(struct net_device *dev) { long e8390_base = dev->base_addr; struct ei_device *ei_local = (struct ei_device *) dev->priv; - int length, send_length, output_page; + int txsr, isr, tickssofar = jiffies - dev->trans_start; unsigned long flags; - /* - * If it has been too long since the last Tx, we assume the - * board has died and kick it. - */ - - if (netif_queue_stopped(dev)) { - /* Do timeouts, just like the 8003 driver. */ - int txsr; - int isr; - int tickssofar = jiffies - dev->trans_start; - - /* - * Need the page lock. Now see what went wrong. This bit is - * fast. - */ - - spin_lock_irqsave(&ei_local->page_lock, flags); - txsr = inb(e8390_base+EN0_TSR); - if (tickssofar < TX_TIMEOUT || (tickssofar < (TX_TIMEOUT+5) && ! (txsr & ENTSR_PTX))) - { - spin_unlock_irqrestore(&ei_local->page_lock, flags); - return 1; - } - - ei_local->stat.tx_errors++; - isr = inb(e8390_base+EN0_ISR); - if (!netif_running(dev)) { - spin_unlock_irqrestore(&ei_local->page_lock, flags); - printk(KERN_WARNING "%s: xmit on stopped card\n", dev->name); - return 1; - } - - /* - * Note that if the Tx posted a TX_ERR interrupt, then the - * error will have been handled from the interrupt handler - * and not here. Error statistics are handled there as well. - */ + ei_local->stat.tx_errors++; - printk(KERN_DEBUG "%s: Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d.\n", - dev->name, (txsr & ENTSR_ABT) ? "excess collisions." : - (isr) ? "lost interrupt?" : "cable problem?", txsr, isr, tickssofar); + spin_lock_irqsave(&ei_local->page_lock, flags); + txsr = inb(e8390_base+EN0_TSR); + isr = inb(e8390_base+EN0_ISR); + spin_unlock_irqrestore(&ei_local->page_lock, flags); - if (!isr && !ei_local->stat.tx_packets) - { - /* The 8390 probably hasn't gotten on the cable yet. */ - ei_local->interface_num ^= 1; /* Try a different xcvr. */ - } + printk(KERN_DEBUG "%s: Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d.\n", + dev->name, (txsr & ENTSR_ABT) ? "excess collisions." : + (isr) ? "lost interrupt?" : "cable problem?", txsr, isr, tickssofar); - /* - * Play shuffle the locks, a reset on some chips takes a few - * mS. We very rarely hit this point. - */ - - spin_unlock_irqrestore(&ei_local->page_lock, flags); + if (!isr && !ei_local->stat.tx_packets) + { + /* The 8390 probably hasn't gotten on the cable yet. */ + ei_local->interface_num ^= 1; /* Try a different xcvr. */ + } - /* Ugly but a reset can be slow, yet must be protected */ + /* Ugly but a reset can be slow, yet must be protected */ - disable_irq_nosync(dev->irq); - spin_lock(&ei_local->page_lock); + disable_irq_nosync(dev->irq); + spin_lock(&ei_local->page_lock); - /* Try to restart the card. Perhaps the user has fixed something. */ - ei_reset_8390(dev); - NS8390_init(dev, 1); + /* Try to restart the card. Perhaps the user has fixed something. */ + ei_reset_8390(dev); + NS8390_init(dev, 1); - spin_unlock(&ei_local->page_lock); - enable_irq(dev->irq); - dev->trans_start = jiffies; - } + spin_unlock(&ei_local->page_lock); + enable_irq(dev->irq); + netif_wake_queue(dev); +} +/** + * ei_start_xmit - begin packet transmission + * @skb: packet to be sent + * @dev: network device to which packet is sent + * + * Sends a packet to an 8390 network device. + */ + +static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + long e8390_base = dev->base_addr; + struct ei_device *ei_local = (struct ei_device *) dev->priv; + int length, send_length, output_page; + unsigned long flags; + length = skb->len; /* Mask interrupts from the ethercard. @@ -1147,6 +1133,7 @@ EXPORT_SYMBOL(ei_open); EXPORT_SYMBOL(ei_close); EXPORT_SYMBOL(ei_interrupt); +EXPORT_SYMBOL(ei_tx_timeout); EXPORT_SYMBOL(ethdev_init); EXPORT_SYMBOL(NS8390_init); ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: ping -f kills ne2k (was:[patch] NE2000) 2000-11-06 7:06 ` ping -f kills ne2k (was:[patch] NE2000) Paul Gortmaker @ 2000-11-06 20:08 ` Jorge Nerin 2000-11-09 15:11 ` Jorge Nerin 0 siblings, 1 reply; 32+ messages in thread From: Jorge Nerin @ 2000-11-06 20:08 UTC (permalink / raw) To: Paul Gortmaker; +Cc: Linux Kernel Mailing List, Linux SMP Mailing List Paul Gortmaker wrote: > > > > > Well, I have tried it with 2.4.0-test10, both SMP and non-SMP, and the > > result is a little confusing. > > > > Under SMP a ping -s 50000 -f other_host takes down the network access > > with no messages (ne2k-pci), and no possibility of being restored > > without a reboot. > > > > Under UP the same command works ok, but after a while the dots stop for > > 30sec, then ping prints an 'E' and the dots continue. strace revealed > > this: > > Another suggestion - if you have your heart set on using ping > as your network stress tool, you may want to try using multiple > instances of MTU sized pings versus a single "ping -s 50000". > In this way you aren't involving any IP frag code and its associated > bean counting - giving us one less factor to consider. > > Oh, and since you get a silent failure, maybe you would be interested > in testing this patch I was (originally) saving for 2.5.x. -- It adds > watchdog transmit timeout functionality to 8390.c (which is used by > the ne2k-pci driver). Last time I updated it was a couple of months > ago, but nothing has changed since then. > > Paul. > Tested with ping -f -s 1400 (1400 in order not to reach 1500) It took about half an hour and more than one million packets, but I finally took the net down, with 12 concurrent pings. To eliminate factors I have deleted all the NAT rules wich gave messages about dropped packets, and unloaded all the iptables modules. I have to make the test without the test check in sock_wait_for_wmem: if ((current->state & (TASK_INTERRUPTIBLE|TASK_UNINTERRUPTIBLE)) == 0) BUG(); Because as I said in a previous msg it gave me BUG()s very early in the tests, and I still had network access. If someone has a better sugestion as a nic stress tool I can try it, but now I only have two ways of reaching this limits, ping -f of big packets, and sometimes (only 4 or 5) during a copy of a large file over NFS, but it's not a easy way to cause this. -- Jorge Nerin <comandante@zaralinux.com> - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: ping -f kills ne2k (was:[patch] NE2000) 2000-11-06 20:08 ` Jorge Nerin @ 2000-11-09 15:11 ` Jorge Nerin 0 siblings, 0 replies; 32+ messages in thread From: Jorge Nerin @ 2000-11-09 15:11 UTC (permalink / raw) To: Paul Gortmaker, Linux Kernel Mailing List, Linux SMP Mailing List Jorge Nerin wrote: > > Paul Gortmaker wrote: > > > > > > > > Well, I have tried it with 2.4.0-test10, both SMP and non-SMP, and the > > > result is a little confusing. > > > > > > Under SMP a ping -s 50000 -f other_host takes down the network access > > > with no messages (ne2k-pci), and no possibility of being restored > > > without a reboot. > > > > > > Under UP the same command works ok, but after a while the dots stop for > > > 30sec, then ping prints an 'E' and the dots continue. strace revealed > > > this: > > > > Another suggestion - if you have your heart set on using ping > > as your network stress tool, you may want to try using multiple > > instances of MTU sized pings versus a single "ping -s 50000". > > In this way you aren't involving any IP frag code and its associated > > bean counting - giving us one less factor to consider. > > > > Oh, and since you get a silent failure, maybe you would be interested > > in testing this patch I was (originally) saving for 2.5.x. -- It adds > > watchdog transmit timeout functionality to 8390.c (which is used by > > the ne2k-pci driver). Last time I updated it was a couple of months > > ago, but nothing has changed since then. > > > > Paul. > > > > Tested with ping -f -s 1400 (1400 in order not to reach 1500) > It took about half an hour and more than one million packets, but I > finally took the net down, with 12 concurrent pings. > > To eliminate factors I have deleted all the NAT rules wich gave messages > about dropped packets, and unloaded all the iptables modules. > > I have to make the test without the test check in sock_wait_for_wmem: > if ((current->state & (TASK_INTERRUPTIBLE|TASK_UNINTERRUPTIBLE)) > == 0) > BUG(); > > Because as I said in a previous msg it gave me BUG()s very early in the > tests, and I still had network access. > > If someone has a better sugestion as a nic stress tool I can try it, but > now I only have two ways of reaching this limits, ping -f of big > packets, and sometimes (only 4 or 5) during a copy of a large file over > NFS, but it's not a easy way to cause this. > > -- > Jorge Nerin > <comandante@zaralinux.com> Well, now it's kernel 2.4.0-test11-pre1 + 8390nmi, and the same conditions, about 8 pings concurrent, and this time it took only 202k packets to take the ne2k-pci down, but this time the watchdog says: Nov 9 16:00:52 quartz kernel: NETDEV WATCHDOG: eth0: transmit timed out Nov 9 16:00:52 quartz kernel: eth0: Tx timed out, lost interrupt? TSR=0x3, ISR=0x3, t=1792. Nov 9 16:00:54 quartz kernel: NETDEV WATCHDOG: eth0: transmit timed out Nov 9 16:00:54 quartz kernel: eth0: Tx timed out, lost interrupt? TSR=0x3, ISR=0x3, t=117. Nov 9 16:00:56 quartz kernel: NETDEV WATCHDOG: eth0: transmit timed out Nov 9 16:00:56 quartz kernel: eth0: Tx timed out, lost interrupt? TSR=0x3, ISR=0x3, t=117. Nov 9 16:00:58 quartz kernel: NETDEV WATCHDOG: eth0: transmit timed out Nov 9 16:00:58 quartz kernel: eth0: Tx timed out, lost interrupt? TSR=0x3, ISR=0x3, t=117. Nov 9 16:01:00 quartz kernel: NETDEV WATCHDOG: eth0: transmit timed out Nov 9 16:01:00 quartz kernel: eth0: Tx timed out, lost interrupt? TSR=0x3, ISR=0x3, t=117. Nov 9 16:01:02 quartz kernel: NETDEV WATCHDOG: eth0: transmit timed out Nov 9 16:01:02 quartz kernel: eth0: Tx timed out, lost interrupt? TSR=0x3, ISR=0x3, t=117. And never comes alive again. -- Jorge Nerin <comandante@zaralinux.com> - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [patch] NE2000 2000-10-29 20:08 ` [patch] NE2000 Jeff Garzik 2000-10-29 20:34 ` Alan Cox @ 2000-10-30 9:17 ` Paul Gortmaker 2000-10-30 14:58 ` pavel rabel 2000-10-30 19:29 ` Jeff Garzik 1 sibling, 2 replies; 32+ messages in thread From: Paul Gortmaker @ 2000-10-30 9:17 UTC (permalink / raw) To: Jeff Garzik; +Cc: pavel rabel, linux-net, netdev, Linux Kernel Mailing List Jeff Garzik wrote: > > pavel rabel wrote: > > help. So I removed PCI code from ne.c to have ISA only driver. It > > This change sounds ok to me, if noone else objects. (I added to the CC > a bit) I saw that code, and was thinking about doing the same thing > myself. ne2k-pci.c definitely has changes which are not included in > ne.c, and it seems silly to duplicate ne2000 PCI support. Actually if you look at the archives (ID 39A3A608.1F984C60@yahoo.com) you will see that I've stated this will be done for 2.5 a couple of months ago. (Which is also why PCI support in ne.c hasn't tracked that of ne2k-pci.c - I want to avoid encouraging new PCI users of ne.c) There is no urgency in trying to squeeze a patch like this in the back door of a 2.4.0 release. For example, there are people out there now who are using the ne.c driver to run both ISA and PCI cards in the same box without having to use 2 different drivers. We can wait until 2.5.0 to break their .config file. [ I've several other 8390 related patches I've been sitting on - trying to not contribute to the delay of 2.4.0 unless explicitly asked, such as the 8390.h get_module_symbol deletion. Other 8390 patches I have are a separated Tx timeout for 8390.c, kill off dev->rmem_start/end and use ioremap() where required, and replace old check/request_region() with code that makes use of the newer resource structures. ] Good to know people are still keeping an eye out for dead code though... Thanks, Paul. _________________________________________________________ Do You Yahoo!? Get your free @yahoo.com address at http://mail.yahoo.com - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [patch] NE2000 2000-10-30 9:17 ` [patch] NE2000 Paul Gortmaker @ 2000-10-30 14:58 ` pavel rabel 2000-10-30 19:29 ` Jeff Garzik 1 sibling, 0 replies; 32+ messages in thread From: pavel rabel @ 2000-10-30 14:58 UTC (permalink / raw) To: Paul Gortmaker; +Cc: Jeff Garzik, linux-net, netdev, Linux Kernel Mailing List On Mon, 30 Oct 2000, Paul Gortmaker wrote: > There is no urgency in trying to squeeze a patch like this in the back > door of a 2.4.0 release. For example, there are people out there now > who are using the ne.c driver to run both ISA and PCI cards in the same > box without having to use 2 different drivers. We can wait until 2.5.0 > to break their .config file. I am not quite sure how it will work when you try to use both ne.c and ne2k-pci drivers in the same box. Which driver will be used for PCI card? Maybe people with both cards are forced to use inferior driver for PCI card. Pavel Rabel - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [patch] NE2000 2000-10-30 9:17 ` [patch] NE2000 Paul Gortmaker 2000-10-30 14:58 ` pavel rabel @ 2000-10-30 19:29 ` Jeff Garzik 2000-11-01 5:31 ` Paul Gortmaker 1 sibling, 1 reply; 32+ messages in thread From: Jeff Garzik @ 2000-10-30 19:29 UTC (permalink / raw) To: Paul Gortmaker; +Cc: pavel rabel, linux-net, netdev, Linux Kernel Mailing List [-- Attachment #1: Type: text/plain, Size: 1059 bytes --] Paul Gortmaker wrote: > There is no urgency in trying to squeeze a patch like this in the back > door of a 2.4.0 release. For example, there are people out there now > who are using the ne.c driver to run both ISA and PCI cards in the same > box without having to use 2 different drivers. We can wait until 2.5.0 > to break their .config file. IMNSHO this is a bug, though... Do a diff of the key 8390 interface routines in ne.c, and ne2k-pci.c. Ignoring the inb_p and outb_p differences, there are distinct advantages to using ne2k-pci.c on with an NE2000 PCI board. Since ne2k-pci.c supports all boards ne.c does, and includes some fixes that ne.c does not, it seems like removing the PCI support in ne.c is a bug fix change. It looks like ne2k-pci.c does need a HZ scaling fixing from ne.c though... Jeff -- Jeff Garzik | "Mind if I drive?" -Sam Building 1024 | "Not if you don't mind me clawing at the MandrakeSoft | dash and shrieking like a cheerleader." | -Max [-- Attachment #2: ne2000.diff --] [-- Type: text/plain, Size: 10910 bytes --] --- /g/g/tmp/1 Mon Oct 30 14:22:41 2000 +++ /g/g/tmp/2 Mon Oct 30 14:22:58 2000 @@ -1,60 +1,61 @@ /* Hard reset the card. This used to pause for the same period that a 8390 reset command required, but that shouldn't be necessary. */ - -static void ne_reset_8390(struct net_device *dev) +static void +ne2k_pci_reset_8390(struct net_device *dev) { unsigned long reset_start_time = jiffies; - if (ei_debug > 1) - printk(KERN_DEBUG "resetting the 8390 t=%ld...", jiffies); + if (debug > 1) printk("%s: Resetting the 8390 t=%ld...", + dev->name, jiffies); - /* DON'T change these to inb_p/outb_p or reset will fail on clones. */ outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET); ei_status.txing = 0; ei_status.dmaing = 0; /* This check _should_not_ be necessary, omit eventually. */ - while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0) - if (jiffies - reset_start_time > 2*HZ/100) { - printk(KERN_WARNING "%s: ne_reset_8390() did not complete.\n", dev->name); + while ((inb(NE_BASE+EN0_ISR) & ENISR_RESET) == 0) + if (jiffies - reset_start_time > 2) { + printk("%s: ne2k_pci_reset_8390() did not complete.\n", dev->name); break; } - outb_p(ENISR_RESET, NE_BASE + EN0_ISR); /* Ack intr. */ + outb(ENISR_RESET, NE_BASE + EN0_ISR); /* Ack intr. */ } /* Grab the 8390 specific header. Similar to the block_input routine, but we don't need to be concerned with ring wrap as the header will be at the start of a page, so we optimize accordingly. */ -static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +static void +ne2k_pci_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { - int nic_base = dev->base_addr; - /* This *shouldn't* happen. If it does, it's the last thing you'll see */ + long nic_base = dev->base_addr; - if (ei_status.dmaing) - { - printk(KERN_EMERG "%s: DMAing conflict in ne_get_8390_hdr " + /* This *shouldn't* happen. If it does, it's the last thing you'll see */ + if (ei_status.dmaing) { + printk("%s: DMAing conflict in ne2k_pci_get_8390_hdr " "[DMAstat:%d][irqlock:%d].\n", dev->name, ei_status.dmaing, ei_status.irqlock); return; } ei_status.dmaing |= 0x01; - outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); - outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); - outb_p(0, nic_base + EN0_RCNTHI); - outb_p(0, nic_base + EN0_RSARLO); /* On page boundary */ - outb_p(ring_page, nic_base + EN0_RSARHI); - outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); + outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); + outb(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); + outb(0, nic_base + EN0_RCNTHI); + outb(0, nic_base + EN0_RSARLO); /* On page boundary */ + outb(ring_page, nic_base + EN0_RSARHI); + outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); - if (ei_status.word16) + if (ei_status.ne2k_flags & ONLY_16BIT_IO) { insw(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1); - else - insb(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)); + } else { + *(u32*)hdr = le32_to_cpu(inl(NE_BASE + NE_DATAPORT)); + le16_to_cpus(&hdr->count); + } - outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ + outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ ei_status.dmaing &= ~0x01; } @@ -63,172 +64,116 @@ The NEx000 doesn't share the on-board packet memory -- you have to put the packet out through the "remote DMA" dataport using outb. */ -static void ne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) +static void +ne2k_pci_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { -#ifdef NE_SANITY_CHECK - int xfer_count = count; -#endif - int nic_base = dev->base_addr; + long nic_base = dev->base_addr; char *buf = skb->data; /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - if (ei_status.dmaing) - { - printk(KERN_EMERG "%s: DMAing conflict in ne_block_input " + if (ei_status.dmaing) { + printk("%s: DMAing conflict in ne2k_pci_block_input " "[DMAstat:%d][irqlock:%d].\n", dev->name, ei_status.dmaing, ei_status.irqlock); return; } ei_status.dmaing |= 0x01; - outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); - outb_p(count & 0xff, nic_base + EN0_RCNTLO); - outb_p(count >> 8, nic_base + EN0_RCNTHI); - outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO); - outb_p(ring_offset >> 8, nic_base + EN0_RSARHI); - outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); - if (ei_status.word16) - { + if (ei_status.ne2k_flags & ONLY_32BIT_IO) + count = (count + 3) & 0xFFFC; + outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); + outb(count & 0xff, nic_base + EN0_RCNTLO); + outb(count >> 8, nic_base + EN0_RCNTHI); + outb(ring_offset & 0xff, nic_base + EN0_RSARLO); + outb(ring_offset >> 8, nic_base + EN0_RSARHI); + outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); + + if (ei_status.ne2k_flags & ONLY_16BIT_IO) { insw(NE_BASE + NE_DATAPORT,buf,count>>1); - if (count & 0x01) - { + if (count & 0x01) { buf[count-1] = inb(NE_BASE + NE_DATAPORT); -#ifdef NE_SANITY_CHECK - xfer_count++; -#endif } } else { - insb(NE_BASE + NE_DATAPORT, buf, count); + insl(NE_BASE + NE_DATAPORT, buf, count>>2); + if (count & 3) { + buf += count & ~3; + if (count & 2) + *((u16*)buf)++ = le16_to_cpu(inw(NE_BASE + NE_DATAPORT)); + if (count & 1) + *buf = inb(NE_BASE + NE_DATAPORT); } - -#ifdef NE_SANITY_CHECK - /* This was for the ALPHA version only, but enough people have - been encountering problems so it is still here. If you see - this message you either 1) have a slightly incompatible clone - or 2) have noise/speed problems with your bus. */ - - if (ei_debug > 1) - { - /* DMA termination address check... */ - int addr, tries = 20; - do { - /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here - -- it's broken for Rx on some cards! */ - int high = inb_p(nic_base + EN0_RSARHI); - int low = inb_p(nic_base + EN0_RSARLO); - addr = (high << 8) + low; - if (((ring_offset + xfer_count) & 0xff) == low) - break; - } while (--tries > 0); - if (tries <= 0) - printk(KERN_WARNING "%s: RX transfer address mismatch," - "%#4.4x (expected) vs. %#4.4x (actual).\n", - dev->name, ring_offset + xfer_count, addr); } -#endif - outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ + + outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ ei_status.dmaing &= ~0x01; } -static void ne_block_output(struct net_device *dev, int count, +static void +ne2k_pci_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page) { - int nic_base = NE_BASE; + long nic_base = NE_BASE; unsigned long dma_start; -#ifdef NE_SANITY_CHECK - int retries = 0; -#endif - /* Round the count up for word writes. Do we need to do this? - What effect will an odd byte count have on the 8390? - I should check someday. */ - - if (ei_status.word16 && (count & 0x01)) + /* On little-endian it's always safe to round the count up for + word writes. */ + if (ei_status.ne2k_flags & ONLY_32BIT_IO) + count = (count + 3) & 0xFFFC; + else + if (count & 0x01) count++; /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - if (ei_status.dmaing) - { - printk(KERN_EMERG "%s: DMAing conflict in ne_block_output." + if (ei_status.dmaing) { + printk("%s: DMAing conflict in ne2k_pci_block_output." "[DMAstat:%d][irqlock:%d]\n", dev->name, ei_status.dmaing, ei_status.irqlock); return; } ei_status.dmaing |= 0x01; /* We should already be in page 0, but to be safe... */ - outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); - -#ifdef NE_SANITY_CHECK -retry: -#endif + outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); #ifdef NE8390_RW_BUGFIX /* Handle the read-before-write bug the same way as the Crynwr packet driver -- the NatSemi method doesn't work. Actually this doesn't always work either, but if you have problems with your NEx000 this is better than nothing! */ - - outb_p(0x42, nic_base + EN0_RCNTLO); - outb_p(0x00, nic_base + EN0_RCNTHI); - outb_p(0x42, nic_base + EN0_RSARLO); - outb_p(0x00, nic_base + EN0_RSARHI); - outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); - /* Make certain that the dummy read has occurred. */ - udelay(6); + outb(0x42, nic_base + EN0_RCNTLO); + outb(0x00, nic_base + EN0_RCNTHI); + outb(0x42, nic_base + EN0_RSARLO); + outb(0x00, nic_base + EN0_RSARHI); + outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); #endif - - outb_p(ENISR_RDC, nic_base + EN0_ISR); + outb(ENISR_RDC, nic_base + EN0_ISR); /* Now the normal output. */ - outb_p(count & 0xff, nic_base + EN0_RCNTLO); - outb_p(count >> 8, nic_base + EN0_RCNTHI); - outb_p(0x00, nic_base + EN0_RSARLO); - outb_p(start_page, nic_base + EN0_RSARHI); - - outb_p(E8390_RWRITE+E8390_START, nic_base + NE_CMD); - if (ei_status.word16) { + outb(count & 0xff, nic_base + EN0_RCNTLO); + outb(count >> 8, nic_base + EN0_RCNTHI); + outb(0x00, nic_base + EN0_RSARLO); + outb(start_page, nic_base + EN0_RSARHI); + outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD); + if (ei_status.ne2k_flags & ONLY_16BIT_IO) { outsw(NE_BASE + NE_DATAPORT, buf, count>>1); } else { - outsb(NE_BASE + NE_DATAPORT, buf, count); + outsl(NE_BASE + NE_DATAPORT, buf, count>>2); + if (count & 3) { + buf += count & ~3; + if (count & 2) + outw(cpu_to_le16(*((u16*)buf)++), NE_BASE + NE_DATAPORT); + } } dma_start = jiffies; -#ifdef NE_SANITY_CHECK - /* This was for the ALPHA version only, but enough people have - been encountering problems so it is still here. */ - - if (ei_debug > 1) - { - /* DMA termination address check... */ - int addr, tries = 20; - do { - int high = inb_p(nic_base + EN0_RSARHI); - int low = inb_p(nic_base + EN0_RSARLO); - addr = (high << 8) + low; - if ((start_page << 8) + count == addr) - break; - } while (--tries > 0); - - if (tries <= 0) - { - printk(KERN_WARNING "%s: Tx packet transfer address mismatch," - "%#4.4x (expected) vs. %#4.4x (actual).\n", - dev->name, (start_page << 8) + count, addr); - if (retries++ == 0) - goto retry; - } - } -#endif - - while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0) - if (jiffies - dma_start > 2*HZ/100) { /* 20ms */ - printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name); - ne_reset_8390(dev); + while ((inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) + if (jiffies - dma_start > 2) { /* Avoid clock roll-over. */ + printk("%s: timeout waiting for Tx RDC.\n", dev->name); + ne2k_pci_reset_8390(dev); NS8390_init(dev,1); break; } - outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ + outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ ei_status.dmaing &= ~0x01; return; } ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [patch] NE2000 2000-10-30 19:29 ` Jeff Garzik @ 2000-11-01 5:31 ` Paul Gortmaker 2000-11-01 8:23 ` Donald Becker 2000-11-01 13:27 ` Jeff Garzik 0 siblings, 2 replies; 32+ messages in thread From: Paul Gortmaker @ 2000-11-01 5:31 UTC (permalink / raw) To: Jeff Garzik; +Cc: pavel rabel, linux-net, netdev, Linux Kernel Mailing List Jeff Garzik wrote: > > Paul Gortmaker wrote: > > There is no urgency in trying to squeeze a patch like this in the back > > door of a 2.4.0 release. For example, there are people out there now > > who are using the ne.c driver to run both ISA and PCI cards in the same > > box without having to use 2 different drivers. We can wait until 2.5.0 > > to break their .config file. > > IMNSHO this is a bug, though... Maybe I wasn't 100% clear - these are people who have intentionally chosen to do so. (There is probably a slight icache benefit in sharing the same driver like this, FWIW....) > Since ne2k-pci.c supports all boards ne.c does, and includes some fixes > that ne.c does not, it seems like removing the PCI support in ne.c is a > bug fix change. If you want to roll it into the merge (and can get it past Linus) then please feel free to do so - I'll be glad to cross it off my list sooner as opposed to later. In addition to removing all remains of PCI support from ne.c this patch also has three trivial changes that were also in my queue for ne.c. 1) Two new ID signatures added to the bad_clone_list 2) int base_addr promoted to unsigned int base_addr in ne_probe, as required for SuperH CPU systems that have ne2000 cards. 3) ISA PnP card info printk'd *before* the actual probe, and not after (just in case the probe silently hangs or whatever). Paul. --- 2400-t10/linux-g/drivers/net/ne.c~ Tue Jul 11 02:29:10 2000 +++ 2400-t10/linux-g/drivers/net/ne.c Wed Nov 1 00:02:17 2000 @@ -29,6 +29,7 @@ occur after memory is allocated for dev->priv. Deallocated memory last in cleanup_modue() Richard Guenther : Added support for ISAPnP cards + Paul Gortmaker : Discontinued PCI support - use ne2k-pci.c instead. */ @@ -43,7 +44,6 @@ #include <linux/kernel.h> #include <linux/sched.h> #include <linux/errno.h> -#include <linux/pci.h> #include <linux/isapnp.h> #include <linux/init.h> #include <linux/delay.h> @@ -75,23 +75,6 @@ }; #endif -#ifdef CONFIG_PCI -/* Ack! People are making PCI ne2000 clones! Oh the horror, the horror... */ -static struct { unsigned short vendor, dev_id; char *name; } -pci_clone_list[] __initdata = { - {PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8029, "Realtek 8029" }, - {PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940, "Winbond 89C940" }, - {PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_RL2000, "Compex ReadyLink 2000" }, - {PCI_VENDOR_ID_KTI, PCI_DEVICE_ID_KTI_ET32P2, "KTI ET32P2" }, - {PCI_VENDOR_ID_NETVIN, PCI_DEVICE_ID_NETVIN_NV5000SC, "NetVin NV5000" }, - {PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C926, "VIA 82C926 Amazon" }, - {PCI_VENDOR_ID_SURECOM, PCI_DEVICE_ID_SURECOM_NE34, "SureCom NE34"}, - {0,} -}; - -static int probe_pci = 1; -#endif - static struct { unsigned short vendor, function; char *name; } isapnp_clone_list[] __initdata = { {ISAPNP_VENDOR('E','D','I'), ISAPNP_FUNCTION(0x0216), "NN NE2000" }, @@ -114,7 +97,9 @@ {"ET-100","ET-200", {0x00, 0x45, 0x54}}, /* YANG and YA clone */ {"COMPEX","COMPEX16",{0x00,0x80,0x48}}, /* Broken ISA Compex cards */ {"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */ - {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */ + {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */ + {"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */ + {"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */ {0,} }; #endif @@ -132,15 +117,9 @@ #define NESM_START_PG 0x40 /* First page of TX buffer */ #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ -/* Non-zero only if the current card is a PCI with BIOS-set IRQ. */ -static unsigned int pci_irq_line = 0; - int ne_probe(struct net_device *dev); static int ne_probe1(struct net_device *dev, int ioaddr); static int ne_probe_isapnp(struct net_device *dev); -#ifdef CONFIG_PCI -static int ne_probe_pci(struct net_device *dev); -#endif static int ne_open(struct net_device *dev); static int ne_close(struct net_device *dev); @@ -180,16 +159,9 @@ {"ne", ne_probe1, NE_IO_EXTENT, netcard_portlist}; #else -/* - * Note that at boot, this probe only picks up one card at a time, even for - * multiple PCI ne2k cards. Use "ether=0,0,eth1" if you have a second PCI - * ne2k card. This keeps things consistent regardless of the bus type of - * the card. - */ - int __init ne_probe(struct net_device *dev) { - int base_addr = dev ? dev->base_addr : 0; + unsigned int base_addr = dev ? dev->base_addr : 0; /* First check any supplied i/o locations. User knows best. <cough> */ if (base_addr > 0x1ff) /* Check a single specified location. */ @@ -197,12 +169,6 @@ else if (base_addr != 0) /* Don't probe at all. */ return -ENXIO; -#ifdef CONFIG_PCI - /* Then look for any installed PCI clones */ - if (probe_pci && pci_present() && (ne_probe_pci(dev) == 0)) - return 0; -#endif - /* Then look for any installed ISAPnP clones */ if (isapnp_present() && (ne_probe_isapnp(dev) == 0)) return 0; @@ -222,43 +188,6 @@ } #endif -#ifdef CONFIG_PCI -static int __init ne_probe_pci(struct net_device *dev) -{ - int i; - - for (i = 0; pci_clone_list[i].vendor != 0; i++) { - struct pci_dev *pdev = NULL; - unsigned int pci_ioaddr = 0; - - while ((pdev = pci_find_device(pci_clone_list[i].vendor, pci_clone_list[i].dev_id, pdev))) { - if (pci_enable_device(pdev)) - continue; - pci_ioaddr = pci_resource_start (pdev, 0); - /* Avoid already found cards from previous calls */ - if (check_region(pci_ioaddr, NE_IO_EXTENT)) - continue; - pci_irq_line = pdev->irq; - if (pci_irq_line) break; /* Found it */ - } - if (!pdev) - continue; - printk(KERN_INFO "ne.c: PCI BIOS reports %s at i/o %#x, irq %d.\n", - pci_clone_list[i].name, - pci_ioaddr, pci_irq_line); - printk("*\n* Use of the PCI-NE2000 driver with this card is recommended!\n*\n"); - if (ne_probe1(dev, pci_ioaddr) != 0) { /* Shouldn't happen. */ - printk(KERN_ERR "ne.c: Probe of PCI card at %#x failed.\n", pci_ioaddr); - pci_irq_line = 0; - return -ENXIO; - } - pci_irq_line = 0; - return 0; - } - return -ENODEV; -} -#endif /* CONFIG_PCI */ - static int __init ne_probe_isapnp(struct net_device *dev) { int i; @@ -275,14 +204,18 @@ continue; if (idev->activate(idev)) continue; - pci_irq_line = idev->irq_resource[0].start; /* if no irq, search for next */ - if (!pci_irq_line) + if (idev->irq_resource[0].start == 0) continue; /* found it */ - if (ne_probe1(dev, idev->resource[0].start) != 0) { /* Shouldn't happen. */ - printk(KERN_ERR "ne.c: Probe of ISAPnP card at %#lx failed.\n", - idev->resource[0].start); + dev->base_addr = idev->resource[0].start; + dev->irq = idev->irq_resource[0].start; + printk(KERN_INFO "ne.c: ISAPnP reports %s at i/o %#lx, irq %d.\n", + isapnp_clone_list[i].name, + + dev->base_addr, dev->irq); + if (ne_probe1(dev, dev->base_addr) != 0) { /* Shouldn't happen. */ + printk(KERN_ERR "ne.c: Probe of ISAPnP card at %#lx failed.\n", dev->base_addr); return -ENXIO; } ei_status.priv = (unsigned long)idev; @@ -290,9 +223,6 @@ } if (!idev) continue; - printk(KERN_INFO "ne.c: ISAPnP reports %s at i/o %#lx, irq %d.\n", - isapnp_clone_list[i].name, - dev->base_addr, dev->irq); return 0; } @@ -403,20 +333,10 @@ wordlength = 1; } - /* At this point, wordlength *only* tells us if the SA_prom is doubled - up or not because some broken PCI cards don't respect the byte-wide - request in program_seq above, and hence don't have doubled up values. - These broken cards would otherwise be detected as an ne1000. */ - - if (wordlength == 2) - for (i = 0; i < 16; i++) - SA_prom[i] = SA_prom[i+i]; - - if (pci_irq_line || ioaddr >= 0x400) - wordlength = 2; /* Catch broken PCI cards mentioned above. */ - if (wordlength == 2) { + for (i = 0; i < 16; i++) + SA_prom[i] = SA_prom[i+i]; /* We must set the 8390 for word mode. */ outb_p(0x49, ioaddr + EN0_DCFG); start_page = NESM_START_PG; @@ -473,9 +393,6 @@ #endif } - if (pci_irq_line) - dev->irq = pci_irq_line; - if (dev->irq < 2) { autoirq_setup(0); @@ -509,8 +426,7 @@ share and the board will usually be enabled. */ { - int irqval = request_irq(dev->irq, ei_interrupt, - pci_irq_line ? SA_SHIRQ : 0, name, dev); + int irqval = request_irq(dev->irq, ei_interrupt, 0, name, dev); if (irqval) { printk (" unable to get IRQ %d (irqval=%d).\n", dev->irq, irqval); kfree(dev->priv); @@ -823,10 +739,6 @@ MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_NE_CARDS) "i"); MODULE_PARM(bad, "1-" __MODULE_STRING(MAX_NE_CARDS) "i"); -#ifdef CONFIG_PCI -MODULE_PARM(probe_pci, "i"); -#endif - /* This is set up so that no ISA autoprobe takes place. We can't guarantee that the ne2k probe is the last 8390 based probe to take place (as it is at boot) and so the probe will get confused by any other 8390 cards. @@ -855,7 +767,7 @@ if (io[this_dev] != 0) printk(KERN_WARNING "ne.c: No NE*000 card found at i/o = %#x\n", io[this_dev]); else - printk(KERN_NOTICE "ne.c: No PCI cards found. Use \"io=0xNNN\" value(s) for ISA cards.\n"); + printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\" value(s) for ISA cards.\n"); unload_8390_module(); return -ENXIO; } _________________________________________________________ Do You Yahoo!? Get your free @yahoo.com address at http://mail.yahoo.com - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [patch] NE2000 2000-11-01 5:31 ` Paul Gortmaker @ 2000-11-01 8:23 ` Donald Becker 2000-11-01 13:27 ` Jeff Garzik 1 sibling, 0 replies; 32+ messages in thread From: Donald Becker @ 2000-11-01 8:23 UTC (permalink / raw) To: Paul Gortmaker Cc: Jeff Garzik, pavel rabel, linux-net, netdev, Linux Kernel Mailing List On Wed, 1 Nov 2000, Paul Gortmaker wrote: > Jeff Garzik wrote: > > Paul Gortmaker wrote: > > > There is no urgency in trying to squeeze a patch like this in the back > > > door of a 2.4.0 release. For example, there are people out there now > > > who are using the ne.c driver to run both ISA and PCI cards in the same > > > box without having to use 2 different drivers. We can wait until 2.5.0 > > > to break their .config file. > > > > IMNSHO this is a bug, though... .. > If you want to roll it into the merge (and can get it past Linus) then > please feel free to do so - I'll be glad to cross it off my list sooner > as opposed to later. If the ne* drivers are going to be updated, you might want to add in the full-duplex support of the latest ne2k-pci.c driver at ftp://www.scyld.com/pub/network/ne2k-pci.c Donald Becker becker@scyld.com Scyld Computing Corporation http://www.scyld.com 410 Severn Ave. Suite 210 Second Generation Beowulf Clusters Annapolis MD 21403 410-990-9993 - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [patch] NE2000 2000-11-01 5:31 ` Paul Gortmaker 2000-11-01 8:23 ` Donald Becker @ 2000-11-01 13:27 ` Jeff Garzik 1 sibling, 0 replies; 32+ messages in thread From: Jeff Garzik @ 2000-11-01 13:27 UTC (permalink / raw) To: Paul Gortmaker Cc: pavel rabel, linux-net, netdev, Linux Kernel Mailing List, Donald Becker [-- Attachment #1: Type: text/plain, Size: 1318 bytes --] Paul, Ok, here's what I have. Included are your changes, as well as drivers/net/ne.c: * use probe_irq_on/off instead of autoirq_xxx (autoirq is going away) * request_region first thing in ne_probe1, before any hardware interaction takes place. Eliminates any potential resource races. Also eliminates a call to check_region. * Trim trailing whitespace drivers/net/ne2k-pci.c: * Merge Becker version 1.02 ne2k-pci.c, which adds forced full duplex support, and also several cosmetic changes where merely serve to bring the kernel's ne2k-pci.c closer to Becker's version (ie. makes the diff smaller). * Just call BUG() if we don't have a net_device in ne2k_pci_remove_one * Correct pci_module_init return code handling As an aside, for 2.5.x, would it be possible to merge all the common ne2000 code (block_input/output, etc.) from the various ne2k drivers? As it stands there exists ne.c, ne2.c, ne2k-pci.c, and pcnet_cs.c, all of which do pretty much the same thing at their core. [and AFAICS, all but pcnet_cs might easily call a common ne2k library] Regards, Jeff -- Jeff Garzik | "Mind if I drive?" -Sam Building 1024 | "Not if you don't mind me clawing at the MandrakeSoft | dash and shrieking like a cheerleader." | -Max [-- Attachment #2: ne.patch --] [-- Type: text/plain, Size: 27653 bytes --] Index: drivers/net/ne.c =================================================================== RCS file: /cvsroot/gkernel/linux_2_4/drivers/net/ne.c,v retrieving revision 1.1.1.4 diff -u -r1.1.1.4 ne.c --- drivers/net/ne.c 2000/10/31 21:21:49 1.1.1.4 +++ drivers/net/ne.c 2000/11/01 13:24:36 @@ -29,21 +29,22 @@ occur after memory is allocated for dev->priv. Deallocated memory last in cleanup_modue() Richard Guenther : Added support for ISAPnP cards - + Paul Gortmaker : Discontinued PCI support - use ne2k-pci.c instead. + */ /* Routines for the NatSemi-based designs (NE[12]000). */ -static const char *version = - "ne.c:v1.10 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; +static const char version1[] = +"ne.c:v1.10 9/23/94 Donald Becker (becker@scyld.com)\n"; +static const char version2[] = +"Last modified Nov 1, 2000 by Paul Gortmaker\n"; #include <linux/module.h> -#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/errno.h> -#include <linux/pci.h> #include <linux/isapnp.h> #include <linux/init.h> #include <linux/delay.h> @@ -70,28 +71,11 @@ /* A zero-terminated list of I/O addresses to be probed at boot. */ #ifndef MODULE -static unsigned int netcard_portlist[] __initdata = { +static unsigned int netcard_portlist[] __initdata = { 0x300, 0x280, 0x320, 0x340, 0x360, 0x380, 0 }; #endif -#ifdef CONFIG_PCI -/* Ack! People are making PCI ne2000 clones! Oh the horror, the horror... */ -static struct { unsigned short vendor, dev_id; char *name; } -pci_clone_list[] __initdata = { - {PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8029, "Realtek 8029" }, - {PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940, "Winbond 89C940" }, - {PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_RL2000, "Compex ReadyLink 2000" }, - {PCI_VENDOR_ID_KTI, PCI_DEVICE_ID_KTI_ET32P2, "KTI ET32P2" }, - {PCI_VENDOR_ID_NETVIN, PCI_DEVICE_ID_NETVIN_NV5000SC, "NetVin NV5000" }, - {PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C926, "VIA 82C926 Amazon" }, - {PCI_VENDOR_ID_SURECOM, PCI_DEVICE_ID_SURECOM_NE34, "SureCom NE34"}, - {0,} -}; - -static int probe_pci = 1; -#endif - static struct { unsigned short vendor, function; char *name; } isapnp_clone_list[] __initdata = { {ISAPNP_VENDOR('E','D','I'), ISAPNP_FUNCTION(0x0216), "NN NE2000" }, @@ -114,7 +98,9 @@ {"ET-100","ET-200", {0x00, 0x45, 0x54}}, /* YANG and YA clone */ {"COMPEX","COMPEX16",{0x00,0x80,0x48}}, /* Broken ISA Compex cards */ {"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */ - {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */ + {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */ + {"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */ + {"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */ {0,} }; #endif @@ -132,15 +118,9 @@ #define NESM_START_PG 0x40 /* First page of TX buffer */ #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ -/* Non-zero only if the current card is a PCI with BIOS-set IRQ. */ -static unsigned int pci_irq_line = 0; - int ne_probe(struct net_device *dev); static int ne_probe1(struct net_device *dev, int ioaddr); static int ne_probe_isapnp(struct net_device *dev); -#ifdef CONFIG_PCI -static int ne_probe_pci(struct net_device *dev); -#endif static int ne_open(struct net_device *dev); static int ne_close(struct net_device *dev); @@ -175,16 +155,9 @@ E2010 starts at 0x100 and ends at 0x4000. E2010-x starts at 0x100 and ends at 0xffff. */ -/* - * Note that at boot, this probe only picks up one card at a time, even for - * multiple PCI ne2k cards. Use "ether=0,0,eth1" if you have a second PCI - * ne2k card. This keeps things consistent regardless of the bus type of - * the card. - */ - int __init ne_probe(struct net_device *dev) { - int base_addr = dev ? dev->base_addr : 0; + unsigned int base_addr = dev ? dev->base_addr : 0; /* First check any supplied i/o locations. User knows best. <cough> */ if (base_addr > 0x1ff) /* Check a single specified location. */ @@ -192,12 +165,6 @@ else if (base_addr != 0) /* Don't probe at all. */ return -ENXIO; -#ifdef CONFIG_PCI - /* Then look for any installed PCI clones */ - if (probe_pci && pci_present() && (ne_probe_pci(dev) == 0)) - return 0; -#endif - /* Then look for any installed ISAPnP clones */ if (isapnp_present() && (ne_probe_isapnp(dev) == 0)) return 0; @@ -206,8 +173,6 @@ /* Last resort. The semi-risky ISA auto-probe. */ for (base_addr = 0; netcard_portlist[base_addr] != 0; base_addr++) { int ioaddr = netcard_portlist[base_addr]; - if (check_region(ioaddr, NE_IO_EXTENT)) - continue; if (ne_probe1(dev, ioaddr) == 0) return 0; } @@ -216,47 +181,10 @@ return -ENODEV; } -#ifdef CONFIG_PCI -static int __init ne_probe_pci(struct net_device *dev) -{ - int i; - - for (i = 0; pci_clone_list[i].vendor != 0; i++) { - struct pci_dev *pdev = NULL; - unsigned int pci_ioaddr = 0; - - while ((pdev = pci_find_device(pci_clone_list[i].vendor, pci_clone_list[i].dev_id, pdev))) { - if (pci_enable_device(pdev)) - continue; - pci_ioaddr = pci_resource_start (pdev, 0); - /* Avoid already found cards from previous calls */ - if (check_region(pci_ioaddr, NE_IO_EXTENT)) - continue; - pci_irq_line = pdev->irq; - if (pci_irq_line) break; /* Found it */ - } - if (!pdev) - continue; - printk(KERN_INFO "ne.c: PCI BIOS reports %s at i/o %#x, irq %d.\n", - pci_clone_list[i].name, - pci_ioaddr, pci_irq_line); - printk("*\n* Use of the PCI-NE2000 driver with this card is recommended!\n*\n"); - if (ne_probe1(dev, pci_ioaddr) != 0) { /* Shouldn't happen. */ - printk(KERN_ERR "ne.c: Probe of PCI card at %#x failed.\n", pci_ioaddr); - pci_irq_line = 0; - return -ENXIO; - } - pci_irq_line = 0; - return 0; - } - return -ENODEV; -} -#endif /* CONFIG_PCI */ - static int __init ne_probe_isapnp(struct net_device *dev) { int i; - + for (i = 0; isapnp_clone_list[i].vendor != 0; i++) { struct pci_dev *idev = NULL; @@ -269,14 +197,18 @@ continue; if (idev->activate(idev)) continue; - pci_irq_line = idev->irq_resource[0].start; /* if no irq, search for next */ - if (!pci_irq_line) + if (idev->irq_resource[0].start == 0) continue; /* found it */ - if (ne_probe1(dev, idev->resource[0].start) != 0) { /* Shouldn't happen. */ - printk(KERN_ERR "ne.c: Probe of ISAPnP card at %#lx failed.\n", - idev->resource[0].start); + dev->base_addr = idev->resource[0].start; + dev->irq = idev->irq_resource[0].start; + printk(KERN_INFO "ne.c: ISAPnP reports %s at i/o %#lx, irq %d.\n", + isapnp_clone_list[i].name, + + dev->base_addr, dev->irq); + if (ne_probe1(dev, dev->base_addr) != 0) { /* Shouldn't happen. */ + printk(KERN_ERR "ne.c: Probe of ISAPnP card at %#lx failed.\n", dev->base_addr); return -ENXIO; } ei_status.priv = (unsigned long)idev; @@ -284,9 +216,6 @@ } if (!idev) continue; - printk(KERN_INFO "ne.c: ISAPnP reports %s at i/o %#lx, irq %d.\n", - isapnp_clone_list[i].name, - dev->base_addr, dev->irq); return 0; } @@ -301,11 +230,17 @@ const char *name = NULL; int start_page, stop_page; int neX000, ctron, copam, bad_card; - int reg0 = inb_p(ioaddr); + int reg0, ret; static unsigned version_printed = 0; + + if (!request_region(ioaddr, NE_IO_EXTENT, dev->name)) + return -EBUSY; - if (reg0 == 0xFF) - return -ENODEV; + reg0 = inb_p(ioaddr); + if (reg0 == 0xFF) { + ret = -ENODEV; + goto err_out; + } /* Do a preliminary verification that we have a 8390. */ { @@ -318,12 +253,13 @@ if (inb_p(ioaddr + EN0_COUNTER0) != 0) { outb_p(reg0, ioaddr); outb_p(regd, ioaddr + 0x0d); /* Restore the old values. */ - return -ENODEV; + ret = -ENODEV; + goto err_out; } } if (ei_debug && version_printed++ == 0) - printk(version); + printk(KERN_INFO "%s" KERN_INFO "%s", version1, version2); printk(KERN_INFO "NE*000 ethercard probe at %#3x:", ioaddr); @@ -350,10 +286,11 @@ break; } else { printk(" not found (no reset ack).\n"); - return -ENODEV; + ret = -ENODEV; + goto err_out; } } - + outb_p(0xff, ioaddr + EN0_ISR); /* Ack all intr. */ } @@ -362,7 +299,7 @@ We can't reliably read the SAPROM address without this. (I learned the hard way!). */ { - struct {unsigned char value, offset; } program_seq[] = + struct {unsigned char value, offset; } program_seq[] = { {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/ {0x48, EN0_DCFG}, /* Set byte-wide (0x48) access. */ @@ -390,20 +327,10 @@ wordlength = 1; } - /* At this point, wordlength *only* tells us if the SA_prom is doubled - up or not because some broken PCI cards don't respect the byte-wide - request in program_seq above, and hence don't have doubled up values. - These broken cards would otherwise be detected as an ne1000. */ - if (wordlength == 2) + { for (i = 0; i < 16; i++) SA_prom[i] = SA_prom[i+i]; - - if (pci_irq_line || ioaddr >= 0x400) - wordlength = 2; /* Catch broken PCI cards mentioned above. */ - - if (wordlength == 2) - { /* We must set the 8390 for word mode. */ outb_p(0x49, ioaddr + EN0_DCFG); start_page = NESM_START_PG; @@ -416,13 +343,12 @@ neX000 = (SA_prom[14] == 0x57 && SA_prom[15] == 0x57); ctron = (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d); copam = (SA_prom[14] == 0x49 && SA_prom[15] == 0x00); - /* Set up the rest of the parameters. */ if (neX000 || bad_card || copam) { name = (wordlength == 2) ? "NE2000" : "NE1000"; } - else if (ctron) + else if (ctron) { name = (wordlength == 2) ? "Ctron-8" : "Ctron-16"; start_page = 0x01; @@ -433,13 +359,13 @@ #ifdef SUPPORT_NE_BAD_CLONES /* Ack! Well, there might be a *bad* NE*000 clone there. Check for total bogus addresses. */ - for (i = 0; bad_clone_list[i].name8; i++) + for (i = 0; bad_clone_list[i].name8; i++) { if (SA_prom[0] == bad_clone_list[i].SAprefix[0] && SA_prom[1] == bad_clone_list[i].SAprefix[1] && - SA_prom[2] == bad_clone_list[i].SAprefix[2]) + SA_prom[2] == bad_clone_list[i].SAprefix[2]) { - if (wordlength == 2) + if (wordlength == 2) { name = bad_clone_list[i].name16; } else { @@ -448,31 +374,30 @@ break; } } - if (bad_clone_list[i].name8 == NULL) + if (bad_clone_list[i].name8 == NULL) { printk(" not found (invalid signature %2.2x %2.2x).\n", SA_prom[14], SA_prom[15]); - return -ENXIO; + ret = -ENXIO; + goto err_out; } #else printk(" not found.\n"); - return -ENXIO; + ret = -ENXIO; + goto err_out; #endif } - - if (pci_irq_line) - dev->irq = pci_irq_line; - if (dev->irq < 2) + if (dev->irq < 2) { - autoirq_setup(0); + unsigned long cookie = probe_irq_on(); outb_p(0x50, ioaddr + EN0_IMR); /* Enable one interrupt. */ outb_p(0x00, ioaddr + EN0_RCNTLO); outb_p(0x00, ioaddr + EN0_RCNTHI); outb_p(E8390_RREAD+E8390_START, ioaddr); /* Trigger it... */ mdelay(10); /* wait 10ms for interrupt to propagate */ outb_p(0x00, ioaddr + EN0_IMR); /* Mask it again. */ - dev->irq = autoirq_report(0); + dev->irq = probe_irq_off(cookie); if (ei_debug > 2) printk(" autoirq is %d\n", dev->irq); } else if (dev->irq == 2) @@ -482,31 +407,27 @@ if (! dev->irq) { printk(" failed to detect IRQ line.\n"); - return -EAGAIN; + ret = -EAGAIN; + goto err_out; } /* Allocate dev->priv and fill in 8390 specific dev fields. */ - if (ethdev_init(dev)) + if (ethdev_init(dev)) { printk (" unable to get memory for dev->priv.\n"); - return -ENOMEM; + ret = -ENOMEM; + goto err_out; } - + /* Snarf the interrupt now. There's no point in waiting since we cannot share and the board will usually be enabled. */ - - { - int irqval = request_irq(dev->irq, ei_interrupt, - pci_irq_line ? SA_SHIRQ : 0, name, dev); - if (irqval) { - printk (" unable to get IRQ %d (irqval=%d).\n", dev->irq, irqval); - kfree(dev->priv); - dev->priv = NULL; - return -EAGAIN; - } + ret = request_irq(dev->irq, ei_interrupt, 0, name, dev); + if (ret) { + printk (" unable to get IRQ %d (errno=%d).\n", dev->irq, ret); + goto err_out_kfree; } + dev->base_addr = ioaddr; - request_region(ioaddr, NE_IO_EXTENT, name); for(i = 0; i < ETHER_ADDR_LEN; i++) { printk(" %2.2x", SA_prom[i]); @@ -536,6 +457,13 @@ dev->stop = &ne_close; NS8390_init(dev, 0); return 0; + +err_out_kfree: + kfree(dev->priv); + dev->priv = NULL; +err_out: + release_region(ioaddr, NE_IO_EXTENT); + return ret; } static int ne_open(struct net_device *dev) @@ -589,7 +517,7 @@ /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - if (ei_status.dmaing) + if (ei_status.dmaing) { printk(KERN_EMERG "%s: DMAing conflict in ne_get_8390_hdr " "[DMAstat:%d][irqlock:%d].\n", @@ -628,7 +556,7 @@ char *buf = skb->data; /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - if (ei_status.dmaing) + if (ei_status.dmaing) { printk(KERN_EMERG "%s: DMAing conflict in ne_block_input " "[DMAstat:%d][irqlock:%d].\n", @@ -642,10 +570,10 @@ outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO); outb_p(ring_offset >> 8, nic_base + EN0_RSARHI); outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); - if (ei_status.word16) + if (ei_status.word16) { insw(NE_BASE + NE_DATAPORT,buf,count>>1); - if (count & 0x01) + if (count & 0x01) { buf[count-1] = inb(NE_BASE + NE_DATAPORT); #ifdef NE_SANITY_CHECK @@ -662,7 +590,7 @@ this message you either 1) have a slightly incompatible clone or 2) have noise/speed problems with your bus. */ - if (ei_debug > 1) + if (ei_debug > 1) { /* DMA termination address check... */ int addr, tries = 20; @@ -697,12 +625,12 @@ /* Round the count up for word writes. Do we need to do this? What effect will an odd byte count have on the 8390? I should check someday. */ - + if (ei_status.word16 && (count & 0x01)) count++; /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - if (ei_status.dmaing) + if (ei_status.dmaing) { printk(KERN_EMERG "%s: DMAing conflict in ne_block_output." "[DMAstat:%d][irqlock:%d]\n", @@ -722,7 +650,7 @@ Crynwr packet driver -- the NatSemi method doesn't work. Actually this doesn't always work either, but if you have problems with your NEx000 this is better than nothing! */ - + outb_p(0x42, nic_base + EN0_RCNTLO); outb_p(0x00, nic_base + EN0_RCNTHI); outb_p(0x42, nic_base + EN0_RSARLO); @@ -752,8 +680,8 @@ #ifdef NE_SANITY_CHECK /* This was for the ALPHA version only, but enough people have been encountering problems so it is still here. */ - - if (ei_debug > 1) + + if (ei_debug > 1) { /* DMA termination address check... */ int addr, tries = 20; @@ -765,7 +693,7 @@ break; } while (--tries > 0); - if (tries <= 0) + if (tries <= 0) { printk(KERN_WARNING "%s: Tx packet transfer address mismatch," "%#4.4x (expected) vs. %#4.4x (actual).\n", @@ -801,10 +729,6 @@ MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_NE_CARDS) "i"); MODULE_PARM(bad, "1-" __MODULE_STRING(MAX_NE_CARDS) "i"); -#ifdef CONFIG_PCI -MODULE_PARM(probe_pci, "i"); -#endif - /* This is set up so that no ISA autoprobe takes place. We can't guarantee that the ne2k probe is the last 8390 based probe to take place (as it is at boot) and so the probe will get confused by any other 8390 cards. @@ -833,7 +757,7 @@ if (io[this_dev] != 0) printk(KERN_WARNING "ne.c: No NE*000 card found at i/o = %#x\n", io[this_dev]); else - printk(KERN_NOTICE "ne.c: No PCI cards found. Use \"io=0xNNN\" value(s) for ISA cards.\n"); + printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\" value(s) for ISA cards.\n"); unload_8390_module(); return -ENXIO; } Index: drivers/net/ne2k-pci.c =================================================================== RCS file: /cvsroot/gkernel/linux_2_4/drivers/net/ne2k-pci.c,v retrieving revision 1.1.1.3 diff -u -r1.1.1.3 ne2k-pci.c --- drivers/net/ne2k-pci.c 2000/10/22 21:55:54 1.1.1.3 +++ drivers/net/ne2k-pci.c 2000/11/01 13:24:36 @@ -2,30 +2,49 @@ /* A Linux device driver for PCI NE2000 clones. - Authorship and other copyrights: - 1992-1998 by Donald Becker, NE2000 core and various modifications. + Authors and other copyright holders: + 1992-2000 by Donald Becker, NE2000 core and various modifications. 1995-1998 by Paul Gortmaker, core modifications and PCI support. - Copyright 1993 assigned to the United States Government as represented by the Director, National Security Agency. - - This software may be used and distributed according to the terms - of the GNU Public License, incorporated herein by reference. - The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O - Center of Excellence in Space Data and Information Sciences - Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771 + This software may be used and distributed according to the terms of + the GNU General Public License (GPL), incorporated herein by reference. + Drivers based on or derived from this code fall under the GPL and must + retain the authorship, copyright and license notice. This file is not + a complete program and may only be used when the entire operating + system is licensed under the GPL. + + The author may be reached as becker@scyld.com, or C/O + Scyld Computing Corporation + 410 Severn Ave., Suite 210 + Annapolis MD 21403 - People are making PCI ne2000 clones! Oh the horror, the horror... - Issues remaining: - No full-duplex support. + People are making PCI ne2000 clones! Oh the horror, the horror... + Limited full-duplex support. */ -/* Our copyright info must remain in the binary. */ -static const char *version = -"ne2k-pci.c:vpre-1.00e 5/27/99 D. Becker/P. Gortmaker http://cesdis.gsfc.nasa.gov/linux/drivers/ne2k-pci.html\n"; +/* These identify the driver base version and may not be removed. */ +static const char version1[] = +"ne2k-pci.c:v1.02 10/19/2000 D. Becker/P. Gortmaker\n"; +static const char version2[] = +" http://www.scyld.com/network/ne2k-pci.html\n"; + +/* The user-configurable values. + These may be modified when a driver module is loaded.*/ + +static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */ + +#define MAX_UNITS 8 /* More are supported, limit only on options */ +/* Used to pass the full-duplex flag, etc. */ +static int full_duplex[MAX_UNITS]; +static int options[MAX_UNITS]; +/* Force a non std. amount of memory. Units are 256 byte pages. */ +/* #define PACKETBUF_MEMSIZE 0x40 */ + + #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> @@ -48,8 +67,11 @@ #define outsl outsl_ns #endif -/* Set statically or when loading the driver module. */ -static int debug = 1; +MODULE_AUTHOR("Donald Becker / Paul Gortmaker"); +MODULE_DESCRIPTION("PCI NE2000 clone driver"); +MODULE_PARM(debug, "i"); +MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i"); +MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i"); /* Some defines that people can play with if so inclined. */ @@ -59,19 +81,16 @@ /* Do we implement the read before write bugfix ? */ /* #define NE_RW_BUGFIX */ -/* Do we have a non std. amount of memory? (in units of 256 byte pages) */ -/* #define PACKETBUF_MEMSIZE 0x40 */ - -#define ne2k_flags reg0 /* Rename an existing field to store flags! */ - -/* Only the low 8 bits are usable for non-init-time flags! */ +/* Flags. We rename an existing ei_status field to store flags! */ +/* Thus only the low 8 bits are usable for non-init-time flags. */ +#define ne2k_flags reg0 enum { - HOLTEK_FDX=1, /* Full duplex -> set 0x80 at offset 0x20. */ - ONLY_16BIT_IO=2, ONLY_32BIT_IO=4, /* Chip can do only 16/32-bit xfers. */ + ONLY_16BIT_IO=8, ONLY_32BIT_IO=4, /* Chip can do only 16/32-bit xfers. */ + FORCE_FDX=0x20, /* User override. */ + REALTEK_FDX=0x40, HOLTEK_FDX=0x80, STOP_PG_0x60=0x100, }; - enum ne2k_pci_chipsets { CH_RealTek_RTL_8029 = 0, CH_Winbond_89C940, @@ -90,7 +109,7 @@ char *name; int flags; } pci_clone_list[] __devinitdata = { - {"RealTek RTL-8029", 0}, + {"RealTek RTL-8029", REALTEK_FDX}, {"Winbond 89C940", 0}, {"Compex RL2000", 0}, {"KTI ET32P2", 0}, @@ -145,7 +164,8 @@ \f -/* No room in the standard 8390 structure for extra info we need. */ +/* There is no room in the standard 8390 structure for extra info we need, + so we build a meta/outer-wrapper structure.. */ struct ne2k_pci_card { struct net_device *dev; struct pci_dev *pci_dev; @@ -171,33 +191,35 @@ const struct pci_device_id *ent) { struct net_device *dev; - int i, irq, reg0, start_page, stop_page; + int i; unsigned char SA_prom[32]; - int chip_idx = ent->driver_data; - static unsigned version_printed = 0; + int start_page, stop_page; + int irq, reg0, chip_idx = ent->driver_data; + static unsigned int fnd_cnt; long ioaddr; - - if (version_printed++ == 0) - printk(KERN_INFO "%s", version); + int flags = pci_clone_list[chip_idx].flags; + + if (fnd_cnt++ == 0) + printk(KERN_INFO "%s" KERN_INFO "%s", version1, version2); ioaddr = pci_resource_start (pdev, 0); irq = pdev->irq; - + if (!ioaddr || ((pci_resource_flags (pdev, 0) & IORESOURCE_IO) == 0)) { printk (KERN_ERR "ne2k-pci: no I/O resource at PCI BAR #0\n"); return -ENODEV; } - + i = pci_enable_device (pdev); if (i) return i; - + if (request_region (ioaddr, NE_IO_EXTENT, "ne2k-pci") == NULL) { printk (KERN_ERR "ne2k-pci: I/O resource 0x%x @ 0x%lx busy\n", NE_IO_EXTENT, ioaddr); return -EBUSY; } - + reg0 = inb(ioaddr); if (reg0 == 0xFF) goto err_out_free_res; @@ -222,7 +244,7 @@ printk (KERN_ERR "ne2k-pci: cannot allocate ethernet device\n"); goto err_out_free_res; } - + /* Reset card. Who knows what dain-bramaged state it was left in. */ { unsigned long reset_start_time = jiffies; @@ -238,7 +260,7 @@ printk("ne2k-pci: Card failure (no reset ack).\n"); goto err_out_free_netdev; } - + outb(0xff, ioaddr + EN0_ISR); /* Ack all intr. */ } @@ -269,7 +291,7 @@ /* Note: all PCI cards have at least 16 bit access, so we don't have to check for 8 bit cards. Most cards permit 32 bit access. */ - if (pci_clone_list[chip_idx].flags & ONLY_32BIT_IO) { + if (flags & ONLY_32BIT_IO) { for (i = 0; i < 4 ; i++) ((u32 *)SA_prom)[i] = le32_to_cpu(inl(ioaddr + NE_DATAPORT)); } else @@ -280,8 +302,7 @@ outb(0x49, ioaddr + EN0_DCFG); start_page = NESM_START_PG; - stop_page = - pci_clone_list[chip_idx].flags&STOP_PG_0x60 ? 0x60 : NESM_STOP_PG; + stop_page = flags & STOP_PG_0x60 ? 0x60 : NESM_STOP_PG; /* Set up the rest of the parameters. */ dev->irq = irq; @@ -305,7 +326,11 @@ ei_status.tx_start_page = start_page; ei_status.stop_page = stop_page; ei_status.word16 = 1; - ei_status.ne2k_flags = pci_clone_list[chip_idx].flags; + ei_status.ne2k_flags = flags; + if (fnd_cnt < MAX_UNITS) { + if (full_duplex[fnd_cnt] > 0 || (options[fnd_cnt] & FORCE_FDX)) + ei_status.ne2k_flags |= FORCE_FDX; + } ei_status.rx_start_page = start_page + TX_PAGES; #ifdef PACKETBUF_MEMSIZE @@ -331,20 +356,27 @@ } -static int -ne2k_pci_open(struct net_device *dev) +static int ne2k_pci_open(struct net_device *dev) { MOD_INC_USE_COUNT; if (request_irq(dev->irq, ei_interrupt, SA_SHIRQ, dev->name, dev)) { MOD_DEC_USE_COUNT; return -EAGAIN; } + /* Set full duplex for the chips that we know about. */ + if (ei_status.ne2k_flags & FORCE_FDX) { + long ioaddr = dev->base_addr; + if (ei_status.ne2k_flags & REALTEK_FDX) { + outb(0xC0 + E8390_NODMA, ioaddr + NE_CMD); /* Page 3 */ + outb(inb(ioaddr + 0x20) | 0x80, ioaddr + 0x20); + } else if (ei_status.ne2k_flags & HOLTEK_FDX) + outb(inb(ioaddr + 0x20) | 0x80, ioaddr + 0x20); + } ei_open(dev); return 0; } -static int -ne2k_pci_close(struct net_device *dev) +static int ne2k_pci_close(struct net_device *dev) { ei_close(dev); free_irq(dev->irq, dev); @@ -354,8 +386,7 @@ /* Hard reset the card. This used to pause for the same period that a 8390 reset command required, but that shouldn't be necessary. */ -static void -ne2k_pci_reset_8390(struct net_device *dev) +static void ne2k_pci_reset_8390(struct net_device *dev) { unsigned long reset_start_time = jiffies; @@ -380,8 +411,7 @@ we don't need to be concerned with ring wrap as the header will be at the start of a page, so we optimize accordingly. */ -static void -ne2k_pci_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +static void ne2k_pci_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { long nic_base = dev->base_addr; @@ -418,8 +448,8 @@ The NEx000 doesn't share the on-board packet memory -- you have to put the packet out through the "remote DMA" dataport using outb. */ -static void -ne2k_pci_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) +static void ne2k_pci_block_input(struct net_device *dev, int count, + struct sk_buff *skb, int ring_offset) { long nic_base = dev->base_addr; char *buf = skb->data; @@ -461,9 +491,8 @@ ei_status.dmaing &= ~0x01; } -static void -ne2k_pci_block_output(struct net_device *dev, int count, - const unsigned char *buf, const int start_page) +static void ne2k_pci_block_output(struct net_device *dev, int count, + const unsigned char *buf, const int start_page) { long nic_base = NE_BASE; unsigned long dma_start; @@ -520,8 +549,8 @@ dma_start = jiffies; while ((inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) - if (jiffies - dma_start > 2) { /* Avoid clock roll-over. */ - printk("%s: timeout waiting for Tx RDC.\n", dev->name); + if (jiffies - dma_start > 2) { /* Avoid clock roll-over. */ + printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name); ne2k_pci_reset_8390(dev); NS8390_init(dev,1); break; @@ -536,12 +565,10 @@ static void __devexit ne2k_pci_remove_one (struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); - - if (!dev) { - printk (KERN_ERR "bug! ne2k_pci_remove_one called w/o net_device\n"); - return; - } - + + if (!dev) + BUG(); + unregister_netdev(dev); release_region(dev->base_addr, NE_IO_EXTENT); kfree(dev); @@ -560,18 +587,12 @@ static int __init ne2k_pci_init(void) { int rc; - + if (load_8390_module("ne2k-pci.c")) return -ENOSYS; - - rc = pci_module_init (&ne2k_driver); - - /* XXX should this test CONFIG_HOTPLUG like pci_module_init? */ - /* YYY No. If we're returning non-zero, we're being unloaded - * immediately. dwmw2 - */ - if (rc <= 0) + rc = pci_module_init (&ne2k_driver); + if (rc) unload_8390_module(); return rc; @@ -586,16 +607,3 @@ module_init(ne2k_pci_init); module_exit(ne2k_pci_cleanup); - -\f -/* - * Local variables: - * compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/ -c ne2k-pci.c" - * alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/ -c ne2k-pci.c" - * c-indent-level: 4 - * c-basic-offset: 4 - * tab-width: 4 - * version-control: t - * kept-new-versions: 5 - * End: - */ ^ permalink raw reply [flat|nested] 32+ messages in thread
end of thread, other threads:[~2000-11-10 1:55 UTC | newest] Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- [not found] <Pine.LNX.4.21.0010300344130.6792-100000@web.sajt.cz> 2000-10-29 20:08 ` [patch] NE2000 Jeff Garzik 2000-10-29 20:34 ` Alan Cox 2000-10-30 10:57 ` Jorge Nerin 2000-10-31 13:54 ` changed section attributes Petko Manolov 2000-10-31 14:15 ` Keith Owens 2000-10-31 14:29 ` Petko Manolov 2000-10-31 14:34 ` Keith Owens 2000-10-31 14:41 ` Petko Manolov [not found] ` <39FFE612.2688A5AD@yahoo.com> 2000-11-03 17:45 ` [patch] NE2000 Jorge Nerin 2000-11-04 5:28 ` Andrew Morton 2000-11-06 11:34 ` Jorge Nerin 2000-11-06 18:40 ` kuznet 2000-11-06 18:46 ` kuznet 2000-11-06 22:32 ` Andrew Morton 2000-11-08 16:45 ` kuznet 2000-11-07 2:40 ` Andrew Morton 2000-11-08 20:31 ` kuznet 2000-11-09 1:18 ` David S. Miller 2000-11-09 1:27 ` David S. Miller 2000-11-09 11:20 ` David S. Miller 2000-11-10 1:45 ` Tom Leete 2000-11-09 18:03 ` kuznet 2000-11-09 18:01 ` Steve Whitehouse 2000-11-06 7:06 ` ping -f kills ne2k (was:[patch] NE2000) Paul Gortmaker 2000-11-06 20:08 ` Jorge Nerin 2000-11-09 15:11 ` Jorge Nerin 2000-10-30 9:17 ` [patch] NE2000 Paul Gortmaker 2000-10-30 14:58 ` pavel rabel 2000-10-30 19:29 ` Jeff Garzik 2000-11-01 5:31 ` Paul Gortmaker 2000-11-01 8:23 ` Donald Becker 2000-11-01 13:27 ` Jeff Garzik
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).