I reported twice (Jan 15 the last time) to this list a kernel oops when
reading a CD in a SONY CDU-31A unit with kernels 2.4.18 - 2.4.20 (and
probably all the 2.4 series), which works fine on 2.2.x (and even
1.2.x!!), maybe the maintainer of this part os the code is offline... Are
there any alternatives to fix this problem? Thank you.
Mauricio Martinez wrote:
> I reported twice (Jan 15 the last time) to this list a kernel oops when
> reading a CD in a SONY CDU-31A unit with kernels 2.4.18 - 2.4.20 (and
> probably all the 2.4 series), which works fine on 2.2.x (and even
> 1.2.x!!), maybe the maintainer of this part os the code is offline... Are
> there any alternatives to fix this problem? Thank you.
Drivers for older hardware like this are more than likely unmaintained,
and suffer from bit-rot. I don't have this hardware, but I can offer a
bit of analysis to help you debug this further. From the oops message
in your previous email, it looks like the oops occurred on line 1326 of
cdu31a.c. From the stack dump, I can see that input_data was called
with bytesleft=0x4000. This caused readahead_buffer + bytesleft to go
past the end of the module and oops.
--
Brian Gerst
Hi...
While talking about old (probably unmaintaned) hardware and oops..
Any kernel I've tried oops when I try to use the e2100 driver to get my
Cabletron E2100 isa network-card running.
Btw. I don't expect anyone to care, but I'd be very happy if anyone could
give me any comment/hint... I haven't done much debugging before and I'm
not very familiar with kernel/driver development. (So if anyone wondered
why I'm even looking at this, it's not because I can't live without my
Cabletron. It's more like this might be my chance to get more familiar. ;-])
How to reproduce:
1. load module.
#modprobe e2100
e2100.c: Presently autoprobing (not recommended) for a single card.
e2100.c:v1.01 7/21/94 Donald Becker ([email protected])
00 00 1D 0A 72 AB, IRQ 15, secandary media, memory @ 0xd0000
(I can supply io=0x380 to get rid of the warning message, but there will
be no real difference. I'm not really sure this is the correct value,
but last time I tried this I did look at the jumpers and used the right
value, thats when I noticed the oops. A weird thing btw. It didn't
happen when there also was a ne2000-compatible isa-card used at the same
time, then it just refused to send any traffic.)
2. configure and up the interface, then send traffic using the
interface.
(ping some.remote.ip ... pinging myself works fine, but I guess it's
because the driver isn't involved there)
ksymoops output:
ksymoops 2.4.5 on i586 2.4.20. Options used
-v vmlinux (specified)
-k ksyms (specified)
-l modules (specified)
-o /lib/modules/2.4.20/ (default)
-m System.map (specified)
c38e44e7
*pde = 00000000
Oops: 0000
CPU: 0
EFLAGS: 00010246
eax: 00000030 ebx: 0000002a ecx: 00000000 edx: c38e4a20
esi: c097f6c2 edi: 000d0000 ebp: 00000380 esp: c07d1c7c
ds: 0018 es: 0018 ss: 0018
Process ping (pid: 320, stackpage=c07d10000)
Stack: c10e6a60 00000030 c38e4a20 0000003c c38e12ff c38e4a20 0000002a c097f6c2
00000030 c10e6c60 c38e4a20 c2e20120 c38e4a98 0000002a 00000380 c01d4ce1
c2e20120 c38e4a20 c02ab7c8 c38e4a20 00000000 c01ceac1 c38e4a20 c2e20120
Call Trace: [<c38e4a20>] [<c38e12ff>] [<c38e4a20>] [<c38e4a20>] [<c38e4a98>]
[<c01d4ce1>] [<c38e4a20>] [<c38e4a20>] [<c01ceac1>] [<c38e4a20>] [<c38e4a9e>]
[<c01fa629>] [<c38e4a20>] [<c01fa133>] [<c38e4a20>] [<c38e4a90>] [<c38e4a98>]
[<c01d19fa>] [<c01d20bd>] [<c01e0690>] [<c01e13b2>] [<c01f8217>] [<c01f7eb0>]
[<c010df44>] [<c01c8309>] [<c018e407>] [<c01c9a9c>] [<c0106d34>] [<c0106c23>]
Code: 8a 14 38 25 ff 00 00 00 8d 55 10 8a 04 38 ec b0 05 8d 55 15
Using defaults from ksymoops -t elf32-i386 -a i386
>>edx; c38e4a20 <[e2100]dev_e21+0/570>
>>esi; c097f6c2 <_end+6ae7e6/35fa124>
>>edi; 000d0000 Before first symbol
>>esp; c07d1c7c <_end+500da0/35fa124>
Trace; c38e4a20 <[e2100]dev_e21+0/570>
Trace; c38e12ff <[8390]ei_start_xmit+133/1f8>
Trace; c38e4a20 <[e2100]dev_e21+0/570>
Trace; c38e4a20 <[e2100]dev_e21+0/570>
Trace; c38e4a98 <[e2100]dev_e21+78/570>
Trace; c01d4ce1 <qdisc_restart+51/d8>
Trace; c38e4a20 <[e2100]dev_e21+0/570>
Trace; c38e4a20 <[e2100]dev_e21+0/570>
Trace; c01ceac1 <dev_queue_xmit+101/244>
Trace; c38e4a20 <[e2100]dev_e21+0/570>
Trace; c38e4a9e <[e2100]dev_e21+7e/570>
Trace; c01fa629 <arp_send+1f5/240>
Trace; c38e4a20 <[e2100]dev_e21+0/570>
Trace; c01fa133 <arp_solicit+ab/d4>
Trace; c38e4a20 <[e2100]dev_e21+0/570>
Trace; c38e4a90 <[e2100]dev_e21+70/570>
Trace; c38e4a98 <[e2100]dev_e21+78/570>
Trace; c01d19fa <__neigh_event_send+7e/1b4>
Trace; c01d20bd <neigh_resolve_output+61/19c>
Trace; c01e0690 <ip_output+c4/12c>
Trace; c01e13b2 <ip_build_xmit+2c2/35c>
Trace; c01f8217 <raw_sendmsg+28b/2f4>
Trace; c01f7eb0 <raw_getfrag+0/24>
Trace; c010df44 <do_page_fault+0/486>
Trace; c01c8309 <sockfd_lookup+11/7c>
Trace; c018e407 <tty_ioctl+1b3/39c>
Trace; c01c9a9c <sys_socketcall+1e4/200>
Trace; c0106d34 <error_code+34/40>
Trace; c0106c23 <system_call+33/40>
Code; 00000000 Before first symbol
00000000 <_EIP>:
Code; 00000000 Before first symbol
0: 8a 14 38 mov (%eax,%edi,1),%dl
Code; 00000003 Before first symbol
3: 25 ff 00 00 00 and $0xff,%eax
Code; 00000008 Before first symbol
8: 8d 55 10 lea 0x10(%ebp),%edx
Code; 0000000b Before first symbol
b: 8a 04 38 mov (%eax,%edi,1),%al
Code; 0000000e Before first symbol
e: ec in (%dx),%al
Code; 0000000f Before first symbol
f: b0 05 mov $0x5,%al
Code; 00000011 Before first symbol
11: 8d 55 15 lea 0x15(%ebp),%edx
<0>Kernel panic: Aiee, killing interrupt handler!
Did I forget to append something? (Hope not)
Thanks for all your great work by the way!
Regards,
Andreas Henriksson
--- drivers/net/e2100.c~ 2003-01-28 18:38:21.000000000 +0000
+++ drivers/net/e2100.c 2003-01-28 18:38:21.000000000 +0000
@@ -77,7 +77,7 @@
{
/* This is a little weird: set the shared memory window by doing a
read. The low address bits specify the starting page. */
- readb(mem_base+start_page);
+ isa_readb(mem_base+start_page);
inb(port + E21_MEM_ENABLE);
outb(E21_MEM_ON, port + E21_MEM_ENABLE + E21_MEM_ON);
}
@@ -306,9 +306,9 @@
#ifdef notdef
/* Officially this is what we are doing, but the readl() is faster */
- memcpy_fromio(hdr, shared_mem, sizeof(struct e8390_pkt_hdr));
+ isa_memcpy_fromio(hdr, shared_mem, sizeof(struct e8390_pkt_hdr));
#else
- ((unsigned int*)hdr)[0] = readl(shared_mem);
+ ((unsigned int*)hdr)[0] = isa_readl(shared_mem);
#endif
/* Turn off memory access: we would need to reprogram the window anyway. */
@@ -328,7 +328,7 @@
mem_on(ioaddr, shared_mem, (ring_offset>>8));
/* Packet is always in one chunk -- we can copy + cksum. */
- eth_io_copy_and_sum(skb, dev->mem_start + (ring_offset & 0xff), count, 0);
+ isa_eth_io_copy_and_sum(skb, dev->mem_start + (ring_offset & 0xff), count, 0);
mem_off(ioaddr);
}
@@ -342,10 +342,10 @@
/* Set the shared memory window start by doing a read, with the low address
bits specifying the starting page. */
- readb(shared_mem + start_page);
+ isa_readb(shared_mem + start_page);
mem_on(ioaddr, shared_mem, start_page);
- memcpy_toio(shared_mem, buf, count);
+ isa_memcpy_toio(shared_mem, buf, count);
mem_off(ioaddr);
}
Hi..
It didn't help. :(
Though I had to change it some to get it to compile... hopefully I
didn't screw up. (I did this to avoid "invalid operators to binary +")
#define virt_addr(addr) *(volatile unsigned char *) __io_virt(addr)
and changed the isa_...(foo+bar); to isa_...(virt_addr(foo+bar));
The oops looks about the same.. so I guess the patch didn't do any
difference (even if it might be needed in the long run)...
Any more ideas? ;)
-- Andreas Henriksson
On Tue, Jan 28, 2003 at 06:48:31PM +0000, Alan Cox wrote:
>
> Try this
[patch removed]
(Ignore my last posting, brain obviously stopped working)
It worked (almost)... I had to slap a couple of int-casts on the changes
to get it to compile. No more Oops.
One problem still remains... I still can't send any traffic. :-/
"NETDEV WATCH DOG: eth2: transmit timed out"
Half way there I guess....
Here is a diff with the int-casts. Tested, doesn't oops, but doesn't
make the driver work properly eighter.
Regards,
Andreas Henriksson
--- drivers/net/e2100.c.org Tue Jan 28 22:04:47 2003
+++ drivers/net/e2100.c Wed Jan 29 04:31:26 2003
@@ -77,7 +77,7 @@
{
/* This is a little weird: set the shared memory window by doing a
read. The low address bits specify the starting page. */
- readb(mem_base+start_page);
+ isa_readb((int)(mem_base+start_page));
inb(port + E21_MEM_ENABLE);
outb(E21_MEM_ON, port + E21_MEM_ENABLE + E21_MEM_ON);
}
@@ -306,9 +306,9 @@
#ifdef notdef
/* Officially this is what we are doing, but the readl() is faster */
- memcpy_fromio(hdr, shared_mem, sizeof(struct e8390_pkt_hdr));
+ isa_memcpy_fromio(hdr, (int)shared_mem, sizeof(struct e8390_pkt_hdr));
#else
- ((unsigned int*)hdr)[0] = readl(shared_mem);
+ ((unsigned int*)hdr)[0] = isa_readl((int)shared_mem);
#endif
/* Turn off memory access: we would need to reprogram the window anyway. */
@@ -328,7 +328,7 @@
mem_on(ioaddr, shared_mem, (ring_offset>>8));
/* Packet is always in one chunk -- we can copy + cksum. */
- eth_io_copy_and_sum(skb, dev->mem_start + (ring_offset & 0xff), count, 0);
+ isa_eth_io_copy_and_sum(skb, dev->mem_start + (ring_offset & 0xff), count, 0);
mem_off(ioaddr);
}
@@ -342,10 +342,10 @@
/* Set the shared memory window start by doing a read, with the low address
bits specifying the starting page. */
- readb(shared_mem + start_page);
+ isa_readb((int)(shared_mem + start_page));
mem_on(ioaddr, shared_mem, start_page);
- memcpy_toio(shared_mem, buf, count);
+ isa_memcpy_toio((int)shared_mem, buf, count);
mem_off(ioaddr);
}
> I reported twice (Jan 15 the last time) to this list a kernel oops when
> reading a CD in a SONY CDU-31A unit with kernels 2.4.18 - 2.4.20 (and
> probably all the 2.4 series), which works fine on 2.2.x (and even
> 1.2.x!!), maybe the maintainer of this part os the code is offline... Are
> there any alternatives to fix this problem? Thank you.
There is something wrong here. This should help.
--- linux-2.4.20/drivers/cdrom/cdu31a.c.orig Fri Nov 29 01:53:12 2002
+++ linux-2.4.20/drivers/cdrom/cdu31a.c Wed Jan 29 23:12:39 2003
@@ -1384,9 +1384,9 @@
readahead_buffer + (2048 -
readahead_dataleft),
readahead_dataleft);
- readahead_dataleft = 0;
bytesleft -= readahead_dataleft;
offset += readahead_dataleft;
+ readahead_dataleft = 0;
} else {
/* The readahead will fill the whole buffer, get the data
and return. */