2.5.20 - Xircom PCI Cardbus doesn't work
Subsystems (4)
In 2.5.19 I got an oops on boot (kindly fixed by Peter's patch),
in 2.5.20 no oopsen but eth0 isn't seen anymore by the kernel:
[...]
Jun 3 12:50:38 dolphin kernel: PCI: Probing PCI hardware Jun 3 12:50:38 dolphin kernel: PCI: Probing PCI hardware (bus 00) Jun 3 12:50:38 dolphin kernel: PCI: Address space collision on region 7 of device Intel Corp. 82371AB PIIX4 ACPI [800:83f] Jun 3 12:50:38 dolphin kernel: PCI: Address space collision on region 8 of device Intel Corp. 82371AB PIIX4 ACPI [840:85f] Jun 3 12:50:38 dolphin kernel: Unknown bridge resource 2: assuming transparent Jun 3 12:50:38 dolphin kernel: PCI: Using IRQ router PIIX [8086/7110] at 00:07.0 [...] Jun 3 12:50:39 dolphin kernel: Linux Kernel Card Services 3.1.22 Jun 3 12:50:39 dolphin kernel: options: [pci] [cardbus] [pm] Jun 3 12:50:39 dolphin kernel: PCI: Found IRQ 11 for device 00:03.0 Jun 3 12:50:39 dolphin kernel: PCI: Sharing IRQ 11 with 00:03.1 Jun 3 12:50:39 dolphin kernel: PCI: Sharing IRQ 11 with 00:07.2 Jun 3 12:50:39 dolphin keytable: Loading keymap: succeeded Jun 3 12:50:39 dolphin kernel: PCI: Found IRQ 11 for device 00:03.1 Jun 3 12:50:39 dolphin kernel: PCI: Sharing IRQ 11 with 00:03.0 Jun 3 12:50:39 dolphin kernel: PCI: Sharing IRQ 11 with 00:07.2 Jun 3 12:50:39 dolphin kernel: Yenta IRQ list 06d8, PCI irq11 Jun 3 12:50:39 dolphin kernel: Socket status: 30000020 Jun 3 12:50:39 dolphin kernel: Yenta IRQ list 06d8, PCI irq11 Jun 3 12:50:39 dolphin kernel: Socket status: 30000006 [...] Jun 3 12:50:39 dolphin kernel: cs: cb_alloc(bus 2): vendor 0x115d, device 0x0003 Jun 3 12:50:39 dolphin kernel: PCI: Enabling device 02:00.0 (0000 -> 0003) Jun 3 12:50:39 dolphin kernel: PCI: Enabling device 02:00.1 (0000 -> 0003) [...] Jun 3 12:50:40 dolphin kernel: cs: IO port probe 0x0100-0x04ff: excluding 0x290-0x297 0x378-0x37f 0x4d0-0x4d7 Jun 3 12:50:40 dolphin cardmgr[597]: socket 0: Xircom CBEM56G-100 CardBus 10/100 Ethernet + 56K Modem Jun 3 12:50:40 dolphin sshd: Starting sshd: Jun 3 12:50:37 dolphin network: Bringing up interface eth0: succeeded Jun 3 12:50:40 dolphin kernel: cs: IO port probe 0x0a00-0x0aff: clean. Jun 3 12:50:41 dolphin cardmgr[597]: executing: 'modprobe cb_enabler' Jun 3 12:50:41 dolphin apmd[572]: Battery: * * * (100% 4:15) Jun 3 12:50:41 dolphin cardmgr[597]: executing: 'modprobe xircom_cb' Jun 3 12:50:41 dolphin sshd: succeeded Jun 3 12:50:41 dolphin sshd: Jun 3 12:50:42 dolphin rc: Starting sshd: succeeded Jun 3 12:50:42 dolphin cardmgr[597]: get dev info on socket 0 failed: Resource temporarily unavailable
Note that cb_enabler and xircom_cb are aliased to 'off' in
/etc/modules.conf since both are actually built in-kernel.
...back to 2.5.18 for the moment.
Thanks & ciao,
--alessandro
"the hands that build / can also pull down
even the hands of love"
(U2, "Exit")
Quoted 2 lines · Alessandro Suardi
In 2.5.19 I got an oops on boot (kindly fixed by Peter's patch),
in 2.5.20 no oopsen but eth0 isn't seen anymore by the kernel:
Same problem here. My network card isn't seen either by the kernel in 2.5.20. If it's still broken in 2.5.21, maybe I'll try to fix it.
Signature · 2 lines
Peter Osterlund - [email protected] http://w1.894.telia.com/~u89404340
Quoted 7 lines · Peter Osterlund
Quoted 2 lines · Alessandro Suardi
In 2.5.19 I got an oops on boot (kindly fixed by Peter's patch),
in 2.5.20 no oopsen but eth0 isn't seen anymore by the kernel:Same problem here. My network card isn't seen either by the kernel in 2.5.20. If it's still broken in 2.5.21, maybe I'll try to fix it.
This oneliner fixes it for me, but I don't know if that's the right fix:
drivers/pcmcia/cardbus.c +1 -0
@@ -284,6 +284,7 @@ dev->dev.parent = bus->dev;strcpy (dev->dev.name, dev->name);strcpy (dev->dev.bus_id, dev->slot_name); + dev->dev.bus = &pci_bus_type;device_register (&dev->dev);/* FIXME: Do we need to enable the expansion ROM? */
Signature · 1 line
Tobias PGP: 0x9AC7E0BC
Quoted 10 lines · Tobias Diedrich
Quoted 7 lines · Peter Osterlund
Quoted 2 lines · Alessandro Suardi
In 2.5.19 I got an oops on boot (kindly fixed by Peter's patch),
in 2.5.20 no oopsen but eth0 isn't seen anymore by the kernel:Same problem here. My network card isn't seen either by the kernel in 2.5.20. If it's still broken in 2.5.21, maybe I'll try to fix it.
This oneliner fixes it for me, but I don't know if that's the right fix:
Thanks, it fixes my problem too. (This patch is still needed in 2.5.21.) However, in 2.5.21 I get an oops at shutdown in device_detach. This happens both with and without your patch:
flushing ide devices: hda <1>Unable to handle kernel NULL pointer dereference a4 c017ae03
*pde = 00000000
Oops: 0002 CPU: 0 EIP: 0010:[<c017ae03>] Not tainted
Using defaults from ksymoops -t elf32-i386 -a i386
EFLAGS: 00010202
eax: c02f6d24 ebx: c3784000 ecx: 00000000 edx: 00000000
esi: c02f6d0c edi: c0290180 ebp: 00000000 esp: c3785e50
ds: 0018 es: 0018 ss: 0018
Stack: c02f6d0c c02f6bb4 00000001 c017b17d c02f6d0c c02f6bb0 c01b030c c02f6d0c
c02f6bb0 c01a9a26 c02f6bb0 c028fcbc 00000000 00000001 bffffcc8 c011e27c
c028fcbc 00000001 00000000 00000001 c3784000 fee1dead c011e64e c02d8b88
Call Trace: [<c017b17d>] [<c01b030c>] [<c01a9a26>] [<c011e27c>] [<c011e64e>]
[<c01241ec>] [<c020e776>] [<c0208f57>] [<c0138f7b>] [<c014ac2e>] [<c02067a4>
[<c01490ec>] [<c01380ea>] [<c0136bc0>] [<c0136c31>] [<c0106ee7>]
Code: 89 4a 04 89 11 89 46 18 89 40 04 8b 43 10 48 89 43 10 8b 43 Quoted 1 line
Quoted 1 line
EIP;
c017ae03<device_detach+53/a0> <=====
Trace; c017b17d <put_device+6d/a0>
Trace; c01b030c <idedisk_cleanup+1c/60>
Trace; c01a9a26 <ata_sys_notify+a6/e0>
Trace; c011e27c <notifier_call_chain+1c/40>
Trace; c011e64e <sys_reboot+fe/2a0>
Trace; c01241ec <handle_mm_fault+6c/120>
Trace; c020e776 <dev_change_flags+106/110>
Trace; c0208f57 <sk_free+37/40>
Trace; c0138f7b <invalidate_inode_buffers+b/70>
Trace; c014ac2e <clear_inode+e/b0>
Trace; c02067a4 <sock_destroy_inode+14/20>
Trace; c01490ec <dput+1c/1a0>
Trace; c01380ea <fput+ea/110>
Trace; c0136bc0 <filp_close+a0/b0>
Trace; c0136c31 <sys_close+61/90>
Trace; c0106ee7 <syscall_call+7/b>
Code; c017ae03 <device_detach+53/a0>
00000000 <_EIP>:
Code; c017ae03 <device_detach+53/a0> <=====
0: 89 4a 04 mov %ecx,0x4(%edx) <=====
Code; c017ae06 <device_detach+56/a0>
3: 89 11 mov %edx,(%ecx)
Code; c017ae08 <device_detach+58/a0>
5: 89 46 18 mov %eax,0x18(%esi)
Code; c017ae0b <device_detach+5b/a0>
8: 89 40 04 mov %eax,0x4(%eax)
Code; c017ae0e <device_detach+5e/a0>
b: 8b 43 10 mov 0x10(%ebx),%eax
Code; c017ae11 <device_detach+61/a0>
e: 48 dec %eax
Code; c017ae12 <device_detach+62/a0>
f: 89 43 10 mov %eax,0x10(%ebx)
Code; c017ae15 <device_detach+65/a0>
12: 8b 43 00 mov 0x0(%ebx),%eax
Signature · 2 lines
Peter Osterlund - [email protected] http://w1.894.telia.com/~u89404340
Quoted 8 lines · Peter Osterlund
Quoted 6 lines · Tobias Diedrich
Quoted 5 lines · Peter Osterlund
Quoted 2 lines · Alessandro Suardi
In 2.5.19 I got an oops on boot (kindly fixed by Peter's patch),
in 2.5.20 no oopsen but eth0 isn't seen anymore by the kernel:
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
Same problem here. My network card isn't seen either by the kernel in 2.5.20. If it's still broken in 2.5.21, maybe I'll try to fix it.
This oneliner fixes it for me, but I don't know if that's the right fix:
Thanks, it fixes my problem too. (This patch is still needed in 2.5.21.) However, in 2.5.21 I get an oops at shutdown in
device_detach. This happens both with and without your patch:
Sorry about the delay. Could you please try this patch and let me know if it helps? It attempts to treat cardbus more like PCI, and let the PCI helpers do the probing.
Note that it's based on the assumption that there is a cardbus bridge for each cardbus slot. This appears to be true on all systems I've seen, but it may not hold for all systems. If other people are feeling adventurous, please give this a try and let me know if it works.
You can pull from bk://ldm.bkbits.net/linux-2.5-cardbus
Thanks,
-pat
[email protected], 2002-06-10 08:35:32-07:00, [email protected]
Treat cardbus more like PCI: let the PCI helpers do more WRT probing
drivers/pci/hotplug.c | 2 drivers/pcmcia/cardbus.c | 114 ++++++++++++++++------------------------------- 2 files changed, 40 insertions, 76 deletions
drivers/pci/hotplug.c +0 -2
@@ -56,8 +56,6 @@void pci_insert_device (struct pci_dev *dev,struct pci_bus *bus) { -list_add_tail (&dev->bus_list, &bus->devices); -list_add_tail (&dev->global_list, &pci_devices);#ifdef CONFIG_PROC_FS pci_proc_attach_device (dev);#endif
drivers/pcmcia/cardbus.c +40 -74
173 lines not on this page · raw message
Quoted 14 lines · Patrick Mochel
Quoted 12 lines · Peter Osterlund
Quoted 9 lines · Tobias Diedrich
Quoted 6 lines · Peter Osterlund
Quoted 1 line · Alessandro Suardi
in 2.5.20 no oopsen but eth0 isn't seen anymore by the kernel:
Same problem here. My network card isn't seen either by the kernel in 2.5.20.
This oneliner fixes it for me, but I don't know if that's the right fix:
Quoted 7 lines
Quoted 3 lines
Thanks, it fixes my problem too. (This patch is still needed in 2.5.21.) However, in 2.5.21 I get an oops at shutdown in
device_detach. This happens both with and without your patch:Sorry about the delay. Could you please try this patch and let me know if it helps? It attempts to treat cardbus more like PCI, and let the PCI helpers do the probing.
It doesn't help unfortunately. The network card is not detected at boot and I get the same oops at shutdown as with a vanilla 2.5.21 kernel.
Quoted 3 lines
Note that it's based on the assumption that there is a cardbus bridge for each cardbus slot. This appears to be true on all systems I've seen, but it may not hold for all systems.
This is true on my system as well.
Here is the output from dmesg after booting (drivers/pci/probe.c compiled with debugging turned on):
...
Initializing RT netlink socket
PCI: PCI BIOS revision 2.10 entry at 0xeafd0, last bus=2
PCI: Using configuration type 1
PCI: Probing PCI hardware
PCI: Probing PCI hardware (bus 00)
Scanning bus 00
Found 00:00 [8086/7100] 000600 00
Found 00:38 [8086/7110] 000680 00
Found 00:39 [8086/7111] 000101 00
Found 00:3a [8086/7112] 000c03 00
Found 00:3b [8086/7113] 000680 00
Found 00:40 [5333/8c01] 000300 00
Found 00:50 [104c/ac17] 000607 02
Found 00:51 [104c/ac17] 000607 02
Fixups for bus 00
Scanning behind PCI bridge 00:0a.0, config 000000, pass 0
Scanning behind PCI bridge 00:0a.1, config 000000, pass 0
Scanning behind PCI bridge 00:0a.0, config 000000, pass 1
Scanning behind PCI bridge 00:0a.1, config 000000, pass 1
Bus scan for 00 returning with max=08
PCI: Using IRQ router PIIX [8086/7110] at 00:07.0
PCI: IRQ 0 for device 00:0a.0 doesn't match PIRQ mask - try pci=usepirqmask
PCI: IRQ 0 for device 00:0a.1 doesn't match PIRQ mask - try pci=usepirqmask
apm: BIOS version 1.2 Flags 0x03 (Driver version 1.16)
Starting kswapd
BIO: pool of 256 setup, 14Kb (56 bytes/bio)
biovec: init pool 0, 1 entries, 12 bytes
biovec: init pool 1, 4 entries, 48 bytes
biovec: init pool 2, 16 entries, 192 bytes
biovec: init pool 3, 64 entries, 768 bytes
biovec: init pool 4, 128 entries, 1536 bytes
biovec: init pool 5, 256 entries, 3072 bytes
Limiting direct PCI/PCI transfers.
pty: 256 Unix98 ptys configured
Serial driver version 5.05c (2001-07-08) with MANY_PORTS SHARE_IRQ SERIAL_PCI en abled
ttyS00 at 0x03f8 (irq = 4) is a 16550A
ttyS01 at 0x02f8 (irq = 3) is a 16550A
block: 224 slots per queue, batch=32
Floppy drive(s): fd0 is 1.44M
FDC 0 is a post-1991 82077
PPP generic driver version 2.4.2
ATA/ATAPI device driver v7.0.0
ATA: PCI bus speed 33.3MHz
ATA: unknown interface: Intel Corp. 82371AB PIIX4 IDE, PCI slot 00:07.1
hda: TOSHIBA MK4006MAV, DISK drive
hdc: CD-224E, ATAPI CD/DVD-ROM drive
ide0 at 0x1f0-0x1f7,0x3f6 on irq 14
ide1 at 0x170-0x177,0x376 on irq 15
hda: 8007552 sectors, CHS=7944/16/63
hda: [PTBL] [993/128/63] hda1 hda2 hda3 hda4
SCSI subsystem driver Revision: 1.00
scsi0 : SCSI host adapter emulation for ATAPI devices
scsi: device set offline - command error recover failed: host 0 channel 0 id 0 l un 0
Linux Kernel Card Services 3.1.22
options: [pci] [cardbus] [pm]
PCI: IRQ 0 for device 00:0a.0 doesn't match PIRQ mask - try pci=usepirqmask
PCI: Assigned IRQ 10 for device 00:0a.0
PCI: IRQ 0 for device 00:0a.1 doesn't match PIRQ mask - try pci=usepirqmask
PCI: Assigned IRQ 10 for device 00:0a.1
Intel PCIC probe: not found.
NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: ICMP, UDP, TCP
IP: routing cache hash table of 512 buckets, 4Kbytes
TCP: Hash tables configured (established 4096 bind 4096) ip_conntrack version 2.0 (512 buckets, 4096 max) - 292 bytes per conntrack
NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
Yenta IRQ list 0a98, PCI irq10
Socket status: 30000068
Yenta IRQ list 0a98, PCI irq10
Socket status: 30000006
cs: cb_alloc(bus 1): vendor 0x13d1, device 0xab02
Scanning bus 01
Found 01:00 [13d1/ab02] 000200 00
Fixups for bus 01
Unknown bridge resource 0: assuming transparent
Unknown bridge resource 1: assuming transparent
Unknown bridge resource 2: assuming transparent
Bus scan for 01 returning with max=01
PCI: Device 01:00.0 not available because of resource collisions
VFS: Mounted root (ext2 filesystem) readonly.
Freeing unused kernel memory: 196k freed
Adding Swap: 104828k swap-space (priority -1)usb.c: registered new driver usbfsusb.c: registered new driver hubusb-uhci-hcd.c: High bandwidth mode enabled.
PCI: Assigned IRQ 10 for device 00:07.2hcd-pci.c: usb-uhci-hcd @ 00:07.2, Intel Corp. 82371AB PIIX4 USB hcd-pci.c: irq 10, io base 0000f300hcd.c: new USB bus registered, assigned bus number 1
...
Signature · 2 lines
Peter Osterlund - [email protected] http://w1.894.telia.com/~u89404340
Quoted 32 lines · Patrick Mochel
Quoted 11 lines · Peter Osterlund
Quoted 8 lines · Tobias Diedrich
Quoted 6 lines · Peter Osterlund
Quoted 2 lines · Alessandro Suardi
In 2.5.19 I got an oops on boot (kindly fixed by Peter's patch),
in 2.5.20 no oopsen but eth0 isn't seen anymore by the kernel:Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
Same problem here. My network card isn't seen either by the kernel in 2.5.20. If it's still broken in 2.5.21, maybe I'll try to fix it.
This oneliner fixes it for me, but I don't know if that's the right fix:
Thanks, it fixes my problem too. (This patch is still needed in 2.5.21.) However, in 2.5.21 I get an oops at shutdown in
device_detach. This happens both with and without your patch:Sorry about the delay. Could you please try this patch and let me know if it helps? It attempts to treat cardbus more like PCI, and let the PCI helpers do the probing.
Note that it's based on the assumption that there is a cardbus bridge for each cardbus slot. This appears to be true on all systems I've seen, but it may not hold for all systems. If other people are feeling adventurous, please give this a try and let me know if it works.
You can pull from bk://ldm.bkbits.net/linux-2.5-cardbus
Thanks,
Quoted 8 lines
-pat
[email protected], 2002-06-10 08:35:32-07:00, [email protected]
Treat cardbus more like PCI: let the PCI helpers do more WRT probingdrivers/pci/hotplug.c | 2 drivers/pcmcia/cardbus.c | 114 ++++++++++++++++------------------------------- 2 files changed, 40 insertions, 76 deletions
[snipped patch]
Still no go, and the card functions are misdetected - cardmgr
attempts to load memory_cs. Full dmesg and /var/log/messages for this boot in the attached .tar.gz file.
Thanks,
--alessandro
"the hands that build / can also pull down
even the hands of love"
(U2, "Exit")
Quoted 4 lines · Peter Osterlund
It doesn't help unfortunately. The network card is not detected at boot and I get the same oops at shutdown as with a vanilla 2.5.21 kernel.
Actually, the card seems to be detected, but:
PCI: Device 01:00.0 not available because of resource collisions
Can you enable PCI debugging and send a full log of that? The DEBUG stuff is sadly a manual diff and a recompile: please manually enable DEBUG in arch/i386/pci/pci.h and in drivers/pci/*.c (yes, there's not even one global place, you have to do it individually for each *.c file, ugh).
Linus
Quoted 11 lines · Linus Torvalds
Quoted 4 lines · Peter Osterlund
It doesn't help unfortunately. The network card is not detected at boot and I get the same oops at shutdown as with a vanilla 2.5.21 kernel.
Actually, the card seems to be detected, but:
PCI: Device 01:00.0 not available because of resource collisions
Can you enable PCI debugging and send a full log of that?
OK, the log is below.
I wonder if this has anything to do with my problem:
PCI: IRQ 0 for device 00:0a.1 doesn't match PIRQ mask - try pci=usepirqmask
I've been seeing this for a long time in 2.5, but never bothered to investigate because before 2.5.21 it didn't seem to cause any harm. Passing pci=usepirqmask as boot argument to the kernel doesn't make any difference.
Linux version 2.5.21-packet ([email protected]) (gcc version 2.96 20000731 (Red Hat Linux 7.3 2.96-110)) #17 Fri Jun 14 18:50:59 CEST 2002 Video mode to be used for restore is ffff
BIOS-provided physical RAM map:
BIOS-e801: 0000000000000000 - 000000000009f000 (usable)
BIOS-e801: 0000000000100000 - 0000000004000000 (usable)
64MB LOWMEM available.
On node 0 totalpages: 16384
zone(0): 4096 pages.
zone(1): 12288 pages.
zone(2): 0 pages.
Kernel command line: auto BOOT_IMAGE=test ro root=304 BOOT_FILE=/vmlinuz console=ttyS0,115200n8
Initializing CPU#0
Detected 233.866 MHz processor.
Console: colour VGA+ 80x25
Calibrating delay loop... 466.94 BogoMIPS
Memory: 62696k/65536k available (1152k kernel code, 2452k reserved, 287k data, 200k init, 0k highmem)
Dentry-cache hash table entries: 8192 (order: 4, 65536 bytes)
Inode-cache hash table entries: 4096 (order: 3, 32768 bytes)
Mount-cache hash table entries: 512 (order: 0, 4096 bytes)
Intel Pentium with F0 0F bug - workaround enabled.
CPU: Intel Pentium MMX stepping 03
Checking 'hlt' instruction... OK.
POSIX conformance testing by UNIFIX
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
Initializing RT netlink socket
PCI: BIOS32 Service Directory structure at 0xc00e8050
PCI: BIOS32 Service Directory entry at 0xeaf90
PCI: BIOS probe returned s=00 hw=01 ver=02.10 l=02
PCI: PCI BIOS revision 2.10 entry at 0xeafd0, last bus=2
PCI: Using configuration type 1
PCI: Probing PCI hardware
PCI: Probing PCI hardware (bus 00)
Scanning bus 00
Found 00:00 [8086/7100] 000600 00
PCI: Calling quirk c01d5650 for 00:00.0
Found 00:38 [8086/7110] 000680 00
PCI: Calling quirk c01d5650 for 00:07.0
Found 00:39 [8086/7111] 000101 00
PCI: Calling quirk c01d5650 for 00:07.1
PCI: IDE base address fixup for 00:07.1
Found 00:3a [8086/7112] 000c03 00
PCI: Calling quirk c01d5650 for 00:07.2
PCI: Calling quirk c0273da0 for 00:07.2
Found 00:3b [8086/7113] 000680 00
PCI: Calling quirk c01d5650 for 00:07.3
PCI: Calling quirk c01d5720 for 00:07.3
PCI: Calling quirk c0273be0 for 00:07.3
Found 00:40 [5333/8c01] 000300 00
PCI: Calling quirk c01d5650 for 00:08.0
Found 00:50 [104c/ac17] 000607 02
PCI: Calling quirk c01d5650 for 00:0a.0
Found 00:51 [104c/ac17] 000607 02
PCI: Calling quirk c01d5650 for 00:0a.1
Fixups for bus 00
PCI: Scanning for ghost devices on bus 0
Scanning behind PCI bridge 00:0a.0, config 000000, pass 0
Scanning behind PCI bridge 00:0a.1, config 000000, pass 0
Scanning behind PCI bridge 00:0a.0, config 000000, pass 1
Scanning behind PCI bridge 00:0a.1, config 000000, pass 1
Bus scan for 00 returning with max=08
PCI: Peer bridge fixup
PCI: IRQ init
PCI: Interrupt Routing Table found at 0xc00fe840
00:07 slot=00 0:00/1eb8 1:00/1eb8 2:00/1eb8 3:63/0400
00:0a slot=00 0:60/0400 1:61/0400 2:00/0400 3:00/0400
00:0c slot=00 0:60/1eb8 1:00/1eb8 2:00/1eb8 3:00/1eb8
PCI: Attempting to find IRQ router for 8086:122e
PCI: Using IRQ router PIIX [8086/7110] at 00:07.0
PCI: IRQ fixup
00:0a.0: ignoring bogus IRQ 255
00:0a.1: ignoring bogus IRQ 255
IRQ for 00:0a.0:0 -> PIRQ 60, mask 0400, excl 0000<4>PCI: IRQ 0 for device 00:0a.0 doesn't match PIRQ mask - try pci=usepirqmask
-> newirq=0 ... failed
IRQ for 00:0a.1:1 -> PIRQ 61, mask 0400, excl 0000<4>PCI: IRQ 0 for device 00:0a.1 doesn't match PIRQ mask - try pci=usepirqmask
-> newirq=0 ... failed
PCI: Allocating resources
PCI: Resource 00001100-0000110f (f=101, d=0, p=0)
PCI: Resource 0000f300-0000f31f (f=101, d=0, p=0)
PCI: Resource c0000000-c3ffffff (f=200, d=0, p=0)
got res[10000000:10000fff] for resource 0 of Texas Instruments PCI1220
got res[10001000:10001fff] for resource 0 of Texas Instruments PCI1220 (#2)
PCI: Sorting device list...
apm: BIOS version 1.2 Flags 0x03 (Driver version 1.16)
Starting kswapd
BIO: pool of 256 setup, 14Kb (56 bytes/bio)
biovec: init pool 0, 1 entries, 12 bytes
biovec: init pool 1, 4 entries, 48 bytes
biovec: init pool 2, 16 entries, 192 bytes
biovec: init pool 3, 64 entries, 768 bytes
biovec: init pool 4, 128 entries, 1536 bytes
biovec: init pool 5, 256 entries, 3072 bytes
PCI: Calling quirk c0273950 for 00:00.0
Limiting direct PCI/PCI transfers.
PCI: Calling quirk c0273e10 for 00:00.0
PCI: Calling quirk c0273e10 for 00:07.0
PCI: Calling quirk c0273e10 for 00:07.1
PCI: Calling quirk c0273e10 for 00:07.2
PCI: Calling quirk c0273e10 for 00:07.3
PCI: Calling quirk c0273e10 for 00:08.0
PCI: Calling quirk c0273e10 for 00:0a.0
PCI: Calling quirk c0273e10 for 00:0a.1
pty: 256 Unix98 ptys configured
Serial driver version 5.05c (2001-07-08) with MANY_PORTS SHARE_IRQ SERIAL_PCI enabled
ttyS00 at 0x03f8 (irq = 4) is a 16550A
ttyS01 at 0x02f8 (irq = 3) is a 16550A
block: 224 slots per queue, batch=32
Floppy drive(s): fd0 is 1.44M
FDC 0 is a post-1991 82077
PPP generic driver version 2.4.2
ATA/ATAPI device driver v7.0.0
ATA: PCI bus speed 33.3MHz
ATA: unknown interface: Intel Corp. 82371AB PIIX4 IDE, PCI slot 00:07.1
hda: TOSHIBA MK4006MAV, DISK drive
hdc: CD-224E, ATAPI CD/DVD-ROM drive
ide0 at 0x1f0-0x1f7,0x3f6 on irq 14
ide1 at 0x170-0x177,0x376 on irq 15
hda: 8007552 sectors, CHS=7944/16/63
hda: [PTBL] [993/128/63] hda1 hda2 hda3 hda4
SCSI subsystem driver Revision: 1.00
scsi0 : SCSI host adapter emulation for ATAPI devices
scsi: device set offline - command error recover failed: host 0 channel 0 id 0 lun 0
Linux Kernel Card Services 3.1.22
options: [pci] [cardbus] [pm]
IRQ for 00:0a.0:0 -> PIRQ 60, mask 0400, excl 0000<4>PCI: IRQ 0 for device 00:0a.0 doesn't match PIRQ mask - try pci=usepirqmask
-> newirq=10 -> assigning IRQ 10 -> edge ... OK
PCI: Assigned IRQ 10 for device 00:0a.0
IRQ for 00:0a.1:1 -> PIRQ 61, mask 0400, excl 0000<4>PCI: IRQ 0 for device 00:0a.1 doesn't match PIRQ mask - try pci=usepirqmask
-> newirq=10 -> assigning IRQ 10 ... OK
PCI: Assigned IRQ 10 for device 00:0a.1
Intel PCIC probe: not found.
NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: ICMP, UDP, TCP
IP: routing cache hash table of 512 buckets, 4Kbytes
TCP: Hash tables configured (established 4096 bind 4096)ip_conntrack version 2.0 (512 buckets, 4096 max) - 292 bytes per conntrack
NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
Yenta IRQ list 0a98, PCI irq10
Socket status: 30000068
Yenta IRQ list 0a98, PCI irq10
Socket status: 30000006
cs: cb_alloc(bus 1): vendor 0x13d1, device 0xab02
Scanning bus 01
Found 01:00 [13d1/ab02] 000200 00
PCI: Calling quirk c01d5650 for 01:00.0
Fixups for bus 01
PCI: Scanning for ghost devices on bus 1
Unknown bridge resource 0: assuming transparent
Unknown bridge resource 1: assuming transparent
Unknown bridge resource 2: assuming transparent
Bus scan for 01 returning with max=01
PCI: Device 01:00.0 not available because of resource collisions
VFS: Mounted root (ext2 filesystem) readonly.
Freeing unused kernel memory: 200k freed
INIT: version 2.78 booting
Welcome to Red Hat Linux
Signature · 2 lines
Peter Osterlund - [email protected] http://w1.894.telia.com/~u89404340
Quoted 4 lines · Peter Osterlund
cs:
cb_alloc(bus 1): vendor0x13d1, device0xab02Scanning bus 01
Found 01:00 [13d1/ab02] 000200 00
Ok, it found a regular PCI network card (000200) with a regular header (00), and it will have read all the resources but not _allocated_ them yet.
Quoted 8 lines
PCI: Calling quirk
c01d5650for 01:00.0
Fixups for bus 01
PCI: Scanning for ghost devices on bus 1
Unknown bridge resource 0: assuming transparent Unknown bridge resource 1: assuming transparent Unknown bridge resource 2: assuming transparent
Bus scan for 01 returning with max=01
PCI: Device 01:00.0 not available because of resource collisions
And here it calls it unavailable, because it notices that the device has resources, but they haven't been allocated, so it assumes that lack of allocation is due to some resource conflict.
However, it _looks_ like the lack of resource allocation is simply because we never bothered to even try to allocate them.
Pat, your change to use "pci_do_scan_bus()" seems to have dropped the:
/* FIXME: Do we need to enable the expansion ROM? */
for (r = 0; r < 7; r++) {
struct resource *res = dev->resource + r;
if (res->flags)
pci_assign_resource(dev, r);
}thing completely, which is the thing that actually _allocates_ and assigns the resources.
Peter, mind adding that resource allocation loop to the "cb_alloc()" function, inside the "list_for_each(node,&bus->devices) {" loop? Just before the "Does this function have an interrupt at all?" line..
Alternatively, maybe that resource allocation might just be done in "pci_enable_device()". It does kind of make sense at that point, instead of just giving up due to unallocated resources..
Linus
Quoted 37 lines · Linus Torvalds
Quoted 4 lines · Peter Osterlund
cs:
cb_alloc(bus 1): vendor0x13d1, device0xab02Scanning bus 01
Found 01:00 [13d1/ab02] 000200 00Ok, it found a regular PCI network card (000200) with a regular header (00), and it will have read all the resources but not _allocated_ them yet.
Quoted 8 lines
PCI: Calling quirk
c01d5650for 01:00.0
Fixups for bus 01
PCI: Scanning for ghost devices on bus 1
Unknown bridge resource 0: assuming transparent Unknown bridge resource 1: assuming transparent Unknown bridge resource 2: assuming transparent
Bus scan for 01 returning with max=01
PCI: Device 01:00.0 not available because of resource collisionsAnd here it calls it unavailable, because it notices that the device has resources, but they haven't been allocated, so it assumes that lack of allocation is due to some resource conflict.
However, it _looks_ like the lack of resource allocation is simply because we never bothered to even try to allocate them.
Pat, your change to use "
pci_do_scan_bus()" seems to have dropped the:/* FIXME: Do we need to enable the expansion ROM? */ for (r = 0; r < 7; r++) { struct resource *res = dev->resource + r; if (res->flags) pci_assign_resource(dev, r); }
Quoted 2 lines
thing completely, which is the thing that actually _allocates_ and assigns the resources.
Could this be what has bitten us with new Intel IDE controllers on latest 2.5? They also were disabled due to 'resource collisions', and had some i/o not allocated at all - just size was nonzero. It was fixed in the quirks code by clearing the size fields, because the i/o space isn't needed ...
Quoted 15 lines
Peter, mind adding that resource allocation loop to the "
cb_alloc()" function, inside the "list_for_each(node,&bus->devices){" loop? Just before the "Does this function have an interrupt at all?" line..Alternatively, maybe that resource allocation might just be done in "
pci_enable_device()". It does kind of make sense at that point, instead of just giving up due to unallocated resources..Linus
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Signature · 2 lines
Vojtech Pavlik SuSE Labs
Quoted 6 lines · Vojtech Pavlik
Could this be what has bitten us with new Intel IDE controllers on latest 2.5? They also were disabled due to 'resource collisions', and had some i/o not allocated at all - just size was nonzero. It was fixed in the quirks code by clearing the size fields, because the i/o space isn't needed ...
That's not this particular code - this code only handles PCMCIA.
But yes, it's the same issue: a resource that wasn't allocated by the BIOS, and that the Linux boot sequence didn't bother to allocate either. The PCI sequence _should_ allocate resources for non-PCMCIA devices in pcibios_resource_survey(), where it does
pcibios_assign_resources();
but the fact is, that that code is explicitly disabled for IDE controllers. See pcibios_assign_resources() in arch/i386/pci/i386.c.
I suspect that forcing resource assignment into "pci_enable_device()" should fix that too.
Although there should probably be some way for the driver to tell which resources it cares about (some drivers care about the PCI ROM's, for example, others don't. Some drivers don't care about the IO region, and others don't care about the MEM region). So the _right_ answer might be to pass in a bitmap to "pci_enable_device()", which tells the enable code which parts the driver really cares about..
Linus
Quoted 9 lines · Linus Torvalds
I suspect that forcing resource assignment into "
pci_enable_device()" should fix that too.Although there should probably be some way for the driver to tell which resources it cares about (some drivers care about the PCI ROM's, for example, others don't. Some drivers don't care about the IO region, and others don't care about the MEM region). So the _right_ answer might be to pass in a bitmap to "
pci_enable_device()", which tells the enable code which parts the driver really cares about..
That reminds me of some idea I had been thinking about for some time:
What about adding some pci_request_irq() and pci_request_{,mem_}_region, which would allow for some cleanup of ever-recurring code sequences in drivers, and which at the same time would allow for the above? pci_request_mem_region() might even include the ioremap() as well ;)
And yeah, eventually, that might be better done at 'struct device' level, but that doesn't make a difference to the conceptual idea.
--Kai
Quoted 5 lines · Kai Germaschewski
What about adding some
pci_request_irq()and pci_request_{,mem_}_region, which would allow for some cleanup of ever-recurring code sequences in drivers, and which at the same time would allow for the above?pci_request_mem_region()might even include theioremap()as well ;)
That might be the right solution - leave "pci_enable_dev()" as-is, and just consider that the legacy way of "enable stuff that got allocated automatically".
And make new drivers start using "pci_request_irq()" and friends.
(The current "pci_enable_dev()" is broken in many respects: sometimes you do NOT want to enable the IRQ until you have set up the device, but in order to set up the device you may need to know _which_ irq it will have, and you need to enable access to memory and IO regions and map the device).
Linus
Quoted 12 lines · Linus Torvalds
However, it _looks_ like the lack of resource allocation is simply because we never bothered to even try to allocate them.
Pat, your change to use "
pci_do_scan_bus()" seems to have dropped the:/* FIXME: Do we need to enable the expansion ROM? */ for (r = 0; r < 7; r++) { struct resource *res = dev->resource + r; if (res->flags) pci_assign_resource(dev, r); }
Quoted 6 lines
thing completely, which is the thing that actually _allocates_ and assigns the resources.
Peter, mind adding that resource allocation loop to the "
cb_alloc()" function, inside the "list_for_each(node,&bus->devices){" loop? Just before the "Does this function have an interrupt at all?" line..
OK, with the patch below I get a little further. The kernel no longer complains about resource collisions, bringing up eth0 works, but the network card is still not usable:
eth0: Transmit timed out, status ffffffff, CSR12 ffffffff, resetting...
eth0: Out-of-sync dirty pointer, 0 vs. 17.
drivers/pcmcia/cardbus.c renamed from drivers/pcmcia/cardbus.c.old +8 -0
@@ -262,9 +262,17 @@*/ irq = s->cap.pci_irq;list_for_each (node,&bus->devices) { +int r;u8 irq_pin; pdev = list_entry(node,struct pci_dev, bus_list); +/* FIXME: Do we need to enable the expansion ROM? */ +for (r =0 ; r <7 ; r++) { +struct resource *res = pdev->resource + r; +if (res->flags) +pci_assign_resource (pdev, r); + } +/* Does this function have an interrupt at all? */ pci_readb (pdev,PCI_INTERRUPT_PIN , &irq_pin);if (irq_pin) {
Linux version 2.5.21-packet ([email protected]) (gcc version 2.96 20000731 (Red Hat Linux 7.3 2.96-110)) #18 Fri Jun 14 20:06:47 CEST 2002 Video mode to be used for restore is ffff
BIOS-provided physical RAM map:
BIOS-e801: 0000000000000000 - 000000000009f000 (usable)
BIOS-e801: 0000000000100000 - 0000000004000000 (usable)
64MB LOWMEM available.
On node 0 totalpages: 16384
zone(0): 4096 pages.
zone(1): 12288 pages.
zone(2): 0 pages.
Kernel command line: auto BOOT_IMAGE=test ro root=304 BOOT_FILE=/vmlinuz console=ttyS0,115200n8
Initializing CPU#0
Detected 233.868 MHz processor.
Console: colour VGA+ 80x25
Calibrating delay loop... 466.94 BogoMIPS
Memory: 62696k/65536k available (1152k kernel code, 2452k reserved, 287k data, 200k init, 0k highmem)
Dentry-cache hash table entries: 8192 (order: 4, 65536 bytes)
Inode-cache hash table entries: 4096 (order: 3, 32768 bytes)
Mount-cache hash table entries: 512 (order: 0, 4096 bytes)
Intel Pentium with F0 0F bug - workaround enabled.
CPU: Intel Pentium MMX stepping 03
Checking 'hlt' instruction... OK.
POSIX conformance testing by UNIFIX
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
Initializing RT netlink socket
PCI: BIOS32 Service Directory structure at 0xc00e8050
PCI: BIOS32 Service Directory entry at 0xeaf90
PCI: BIOS probe returned s=00 hw=01 ver=02.10 l=02
PCI: PCI BIOS revision 2.10 entry at 0xeafd0, last bus=2
PCI: Using configuration type 1
PCI: Probing PCI hardware
PCI: Probing PCI hardware (bus 00)
Scanning bus 00
Found 00:00 [8086/7100] 000600 00
PCI: Calling quirk c01d56a0 for 00:00.0
Found 00:38 [8086/7110] 000680 00
PCI: Calling quirk c01d56a0 for 00:07.0
Found 00:39 [8086/7111] 000101 00
PCI: Calling quirk c01d56a0 for 00:07.1
PCI: IDE base address fixup for 00:07.1
Found 00:3a [8086/7112] 000c03 00
PCI: Calling quirk c01d56a0 for 00:07.2
PCI: Calling quirk c0273da0 for 00:07.2
Found 00:3b [8086/7113] 000680 00
PCI: Calling quirk c01d56a0 for 00:07.3
PCI: Calling quirk c01d5770 for 00:07.3
PCI: Calling quirk c0273be0 for 00:07.3
Found 00:40 [5333/8c01] 000300 00
PCI: Calling quirk c01d56a0 for 00:08.0
Found 00:50 [104c/ac17] 000607 02
PCI: Calling quirk c01d56a0 for 00:0a.0
Found 00:51 [104c/ac17] 000607 02
PCI: Calling quirk c01d56a0 for 00:0a.1
Fixups for bus 00
PCI: Scanning for ghost devices on bus 0
Scanning behind PCI bridge 00:0a.0, config 000000, pass 0
Scanning behind PCI bridge 00:0a.1, config 000000, pass 0
Scanning behind PCI bridge 00:0a.0, config 000000, pass 1
Scanning behind PCI bridge 00:0a.1, config 000000, pass 1
Bus scan for 00 returning with max=08
PCI: Peer bridge fixup
PCI: IRQ init
PCI: Interrupt Routing Table found at 0xc00fe840
00:07 slot=00 0:00/1eb8 1:00/1eb8 2:00/1eb8 3:63/0400
00:0a slot=00 0:60/0400 1:61/0400 2:00/0400 3:00/0400
00:0c slot=00 0:60/1eb8 1:00/1eb8 2:00/1eb8 3:00/1eb8
PCI: Attempting to find IRQ router for 8086:122e
PCI: Using IRQ router PIIX [8086/7110] at 00:07.0
PCI: IRQ fixup
00:0a.0: ignoring bogus IRQ 255
00:0a.1: ignoring bogus IRQ 255
IRQ for 00:0a.0:0 -> PIRQ 60, mask 0400, excl 0000<4>PCI: IRQ 0 for device 00:0a.0 doesn't match PIRQ mask - try pci=usepirqmask
-> newirq=0 ... failed
IRQ for 00:0a.1:1 -> PIRQ 61, mask 0400, excl 0000<4>PCI: IRQ 0 for device 00:0a.1 doesn't match PIRQ mask - try pci=usepirqmask
-> newirq=0 ... failed
PCI: Allocating resources
PCI: Resource 00001100-0000110f (f=101, d=0, p=0)
PCI: Resource 0000f300-0000f31f (f=101, d=0, p=0)
PCI: Resource c0000000-c3ffffff (f=200, d=0, p=0)
got res[10000000:10000fff] for resource 0 of Texas Instruments PCI1220
got res[10001000:10001fff] for resource 0 of Texas Instruments PCI1220 (#2)
PCI: Sorting device list...
apm: BIOS version 1.2 Flags 0x03 (Driver version 1.16)
Starting kswapd
BIO: pool of 256 setup, 14Kb (56 bytes/bio)
biovec: init pool 0, 1 entries, 12 bytes
biovec: init pool 1, 4 entries, 48 bytes
biovec: init pool 2, 16 entries, 192 bytes
biovec: init pool 3, 64 entries, 768 bytes
biovec: init pool 4, 128 entries, 1536 bytes
biovec: init pool 5, 256 entries, 3072 bytes
PCI: Calling quirk c0273950 for 00:00.0
Limiting direct PCI/PCI transfers.
PCI: Calling quirk c0273e10 for 00:00.0
PCI: Calling quirk c0273e10 for 00:07.0
PCI: Calling quirk c0273e10 for 00:07.1
PCI: Calling quirk c0273e10 for 00:07.2
PCI: Calling quirk c0273e10 for 00:07.3
PCI: Calling quirk c0273e10 for 00:08.0
PCI: Calling quirk c0273e10 for 00:0a.0
PCI: Calling quirk c0273e10 for 00:0a.1
pty: 256 Unix98 ptys configured
Serial driver version 5.05c (2001-07-08) with MANY_PORTS SHARE_IRQ SERIAL_PCI enabled
ttyS00 at 0x03f8 (irq = 4) is a 16550A
ttyS01 at 0x02f8 (irq = 3) is a 16550A
block: 224 slots per queue, batch=32
Floppy drive(s): fd0 is 1.44M
FDC 0 is a post-1991 82077
PPP generic driver version 2.4.2
ATA/ATAPI device driver v7.0.0
ATA: PCI bus speed 33.3MHz
ATA: unknown interface: Intel Corp. 82371AB PIIX4 IDE, PCI slot 00:07.1
hda: TOSHIBA MK4006MAV, DISK drive
hdc: CD-224E, ATAPI CD/DVD-ROM drive
ide0 at 0x1f0-0x1f7,0x3f6 on irq 14
ide1 at 0x170-0x177,0x376 on irq 15
hda: 8007552 sectors, CHS=7944/16/63
hda: [PTBL] [993/128/63] hda1 hda2 hda3 hda4
SCSI subsystem driver Revision: 1.00
scsi0 : SCSI host adapter emulation for ATAPI devices
scsi: device set offline - command error recover failed: host 0 channel 0 id 0 lun 0
Linux Kernel Card Services 3.1.22
options: [pci] [cardbus] [pm]
IRQ for 00:0a.0:0 -> PIRQ 60, mask 0400, excl 0000<4>PCI: IRQ 0 for device 00:0a.0 doesn't match PIRQ mask - try pci=usepirqmask
-> newirq=10 -> assigning IRQ 10 -> edge ... OK
PCI: Assigned IRQ 10 for device 00:0a.0
IRQ for 00:0a.1:1 -> PIRQ 61, mask 0400, excl 0000<4>PCI: IRQ 0 for device 00:0a.1 doesn't match PIRQ mask - try pci=usepirqmask
-> newirq=10 -> assigning IRQ 10 ... OK
PCI: Assigned IRQ 10 for device 00:0a.1
Intel PCIC probe: not found.
NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: ICMP, UDP, TCP
IP: routing cache hash table of 512 buckets, 4Kbytes
TCP: Hash tables configured (established 4096 bind 4096)ip_conntrack version 2.0 (512 buckets, 4096 max) - 292 bytes per conntrack
NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
Yenta IRQ list 0a98, PCI irq10
Socket status: 30000068
Yenta IRQ list 0a98, PCI irq10
Socket status: 30000006
cs: cb_alloc(bus 1): vendor 0x13d1, device 0xab02
Scanning bus 01
Found 01:00 [13d1/ab02] 000200 00
PCI: Calling quirk c01d56a0 for 01:00.0
Fixups for bus 01
PCI: Scanning for ghost devices on bus 1
Unknown bridge resource 0: assuming transparent
Unknown bridge resource 1: assuming transparent
Unknown bridge resource 2: assuming transparent
Bus scan for 01 returning with max=01
got res[1800:18ff] for resource 0 of PCI device 13d1:ab02 (Abocom Systems Inc)
got res[10002000:100023ff] for resource 1 of PCI device 13d1:ab02 (Abocom Systems Inc)
got res[10020000:1003ffff] for resource 6 of PCI device 13d1:ab02 (Abocom Systems Inc)
PCI: Enabling device 01:00.0 (0000 -> 0003)
IRQ for 01:00.0:0 -> not found in routing table
VFS: Mounted root (ext2 filesystem) readonly.
Freeing unused kernel memory: 200k freed
INIT: version 2.78 booting
Welcome to Red Hat Linux
Press 'I' to enter interactive startup.
Mounting proc filesystem: [ OK ] Configuring kernel parameters: [ OK ] modprobe: modprobe: cannot create /var/log/ksymoops/20020614.log Read-only file system modprobe: modprobe: cannot create /var/log/ksymoops/20020614.log Read-only file system Setting clock (utc): Fri Jun 14 20:09:35 CEST 2002 [ OK ] Activating swap partitions: [ OK ]
Setting hostname pengo.localdomain: [ OK ]
modprobe: cannot create /var/log/ksymoops/20020614.log Read-only file system /lib/modules/2.5.21-packet/kernel/drivers/usb/core/usbcore.o: cannot create /var/log/ksymoops/20020614200935.ksyms Read-only file system /lib/modules/2.5.21-packet/kernel/drivers/usb/core/usbcore.o: cannot create /var/log/ksymoops/20020614.log Read-only file system Mounting USB filesystem: [ OK ]
Initializing USB controller (usb-uhci-hcd): [ OK ]
Checking root filesystem/dev/hda4: clean, 133078/759808 files, 2827438/3032064 blocks
[/sbin/fsck.ext2 -- /] fsck.ext2 -a /dev/hda4
[ OK ]
Remounting root filesystem in read-write mode: [ OK ]
Finding module dependencies: [ OK ]
Checking filesystems
Checking all file systems.
[ OK ]
Mounting local filesystems: [ OK ]
Turning on user and group quotas for local filesystems: [ OK ]
Enabling swap space: [ OK ]
INIT: Entering runlevel: 3
Entering non-interactive startup
Starting up APM daemon: [ OK ]
apmd[198]: Charge: * * * (-1% unknown)
Setting network parameters: [ OK ] Bringing up interface lo: [ OK ] Bringing up interface eth0: [ OK ] Starting system logger: [ OK ] Starting kernel logger: [ OK ] Starting portmapper: [ OK ]
Starting NFS file locking services:
Starting NFS statd: [ OK ]
Starting automount:[ OK ]
Initializing random number generator: [ OK ]
Mounting other filesystems: [ OK ] Starting identd: [ OK ] Starting atd: [ OK ] Starting pcmcia: [ OK ] Starting xinetd: [ OK ] Starting named: [ OK ] Starting lpd: [ OK ] Starting NFS services: eth0: Transmit timed out, status ffffffff, CSR12 ffffffff, resetting... eth0: Transmit timed out, status ffffffff, CSR12 ffffffff, resetting... eth0: Out-of-sync dirty pointer, 0 vs. 17. eth0: Transmit timed out, status ffffffff, CSR12 ffffffff, resetting...
[ OK ]
Starting NFS quotas: [ OK ]
Starting NFS mountd: eth0: Transmit timed out, status ffffffff, CSR12 ffffffff, resetting...
eth0: Out-of-sync dirty pointer, 16 vs. 33.
INIT: Switching to runlevel: 6
INIT: Sending processes the TERM signal
Stopping named: [ OK ]
Stopping xinetd: [ OK ]
Stopping atd: [ OK ]
Stopping lpd: [ OK ]
Stopping identd: [ OK ]
Shutting down NFS file locking services:
Shutting down NFS statd: [ OK ]
Saving random seed: [ OK ]
Stopping automount:[ OK ]
Stopping portmapper: [ OK ] Shutting down kernel logger: [ OK ] Shutting down system logger: [ OK ] Shutting down interface eth0: [ OK ] Shutting down APM daemon: [ OK ] Starting killall: [ OK ]
Sending all processes the TERM signal...
Sending all processes the KILL signal...
Syncing hardware clock to system time
Turning off swap:
Turning off quotas:
Unmounting file systems:
Unmounting proc file system:
Please stand by while rebooting the system...
flushing ide devices: hda <1>Unable to handle kernel NULL pointer dereference at virtual address 00000004
printing eip:c017aea3
*pde = 00000000
Oops: 0002
CPU: 0
EIP: 0010:[<c017aea3>] Not tainted
EFLAGS: 00010202
eax: c02c6d24 ebx: c37bc000 ecx: 00000000 edx: 00000000
esi: c02c6d0c edi: c02622a0 ebp: 00000000 esp: c37bde50
ds: 0018 es: 0018 ss: 0018
Process reboot (pid: 924, threadinfo=c37bc000 task=c11d3760)
Stack: c02c6d0c c02c6bb4 00000001 c017b21d c02c6d0c c02c6bb0 c01b03ac c02c6d0c
c02c6bb0 c01a9ac6 c02c6bb0 c0261ddc 00000000 00000001 bffffcc8 c011e27c
c0261ddc 00000001 00000000 00000001 c37bc000 fee1dead c011e64e c02a8b88
Call Trace: [<c017b21d>] [<c01b03ac>] [<c01a9ac6>] [<c011e27c>] [<c011e64e>]
[<c01241ec>] [<c01de9a6>] [<c01d9187>] [<c0138f7b>] [<c014ac2e>] [<c01d69d4>]
[<c01490ec>] [<c01380ea>] [<c0136bc0>] [<c0136c31>] [<c0106ee7>]
Code: 89 4a 04 89 11 89 46 18 89 40 04 8b 43 10 48 89 43 10 8b 43
<6>note: reboot[924] exited with preempt_count 2/etc/rc6.d/S01reboot: line 1: 924 Segmentation fault reboot -i -d -p
INIT: no more processes left in this runlevel
Signature · 2 lines
Peter Osterlund - [email protected] http://w1.894.telia.com/~u89404340
Quoted 7 lines · Peter Osterlund
OK, with the patch below I get a little further. The kernel no longer complains about resource collisions, bringing up eth0 works, but the network card is still not usable:
eth0: Transmit timed out, status ffffffff, CSR12 ffffffff, resetting...
eth0: Out-of-sync dirty pointer, 0 vs. 17.
Some part of your resource isn't mapped through the cardbus bridge. Either because the bridge resources themselves were wrong, or because we didn't enable the resouce after we allocated it (the latter is unlikely, as any "pci_enable_dev()" will do that part).
Quoted 5 lines
Yenta IRQ list 0a98, PCI irq10
Socket status: 30000068
Yenta IRQ list 0a98, PCI irq10
Socket status: 30000006
cs:cb_alloc(bus 1): vendor0x13d1, device0xab02
Quoted 8 lines
Scanning bus 01
Found 01:00 [13d1/ab02] 000200 00
PCI: Calling quirkc01d56a0for 01:00.0
Fixups for bus 01
PCI: Scanning for ghost devices on bus 1
Unknown bridge resource 0: assuming transparent
Unknown bridge resource 1: assuming transparent
Unknown bridge resource 2: assuming transparent
This is the problem.
The PCI code thinks that the parent of the network device doesn't have resources allocated, so it will allocate the resources from the parent of the parent.
Which is wrong, since it means that it will try to allocate the PCI resources from outside the window that the cardbus controller is exporting. Resulting in the fffff stuff.
HOWEVER, I don't see why that happens. yenta_allocate_resources() should have made absolutely certain that we have all the necessary bridge resources clearly allocated. Can you add debug code to the end of "yenta_allocate_res()" that prints out the resource that got allocated?
Pat?
Linus
Quoted 14 lines · Kai Germaschewski
Quoted 9 lines · Linus Torvalds
I suspect that forcing resource assignment into "
pci_enable_device()" should fix that too.Although there should probably be some way for the driver to tell which resources it cares about (some drivers care about the PCI ROM's, for example, others don't. Some drivers don't care about the IO region, and others don't care about the MEM region). So the _right_ answer might be to pass in a bitmap to "
pci_enable_device()", which tells the enable code which parts the driver really cares about..
Quoted 6 lines
That reminds me of some idea I had been thinking about for some time:
What about adding some
pci_request_irq()and pci_request_{,mem_}_region, which would allow for some cleanup of ever-recurring code sequences in drivers, and which at the same time would allow for the above?pci_request_mem_region()might even include theioremap()as well ;)
We already have pci_request_regions() and currently PCI drivers should use that.
Auto-ioremap would be bad, though... you would wind up wasting address space for any case where MMIO areas are not 100% utilized (like network cards that require use of PIO due to hardware bugs, but still export an MMIO region for their NIC registers)
Jeff
Quoted 6 lines · Linus Torvalds
Although there should probably be some way for the driver to tell which resources it cares about (some drivers care about the PCI ROM's, for example, others don't. Some drivers don't care about the IO region, and others don't care about the MEM region). So the _right_ answer might be to pass in a bitmap to "
pci_enable_device()", which tells the enable code which parts the driver really cares about..
Such a mask has been desired before :)
That would indeed be nice. Still want to keep busmaster enabling separate, though...
Jeff
Quoted 13 lines · Linus Torvalds
Quoted 4 lines · Kai Germaschewski
What about adding some
pci_request_irq()and pci_request_{,mem_}_region, which would allow for some cleanup of ever-recurring code sequences in drivers, and which at the same time would allow for the above?pci_request_mem_region()might even include theioremap()as well ;)That might be the right solution - leave "
pci_enable_dev()" as-is, and just consider that the legacy way of "enable stuff that got allocated automatically".
Quoted 7 lines
And make new drivers start using "
pci_request_irq()" and friends.(The current "
pci_enable_dev()" is broken in many respects: sometimes you do NOT want to enable the IRQ until you have set up the device, but in order to set up the device you may need to know _which_ irq it will have, and you need to enable access to memory and IO regions and map the device).
Can someone clarify for me the need of pci_request_irq??
pci_enable_device() assigns the IRQ in routing, but it is not enabled until you call request_irq. I don't see any simplification that can be done in the PCI API.
The only thing I've wanted is a cross-platform way to detect if pdev->irq returned by pci_enable_device is valid.
Jeff
Quoted 11 lines · Linus Torvalds
Quoted 4 lines
PCI: Scanning for ghost devices on bus 1 Unknown bridge resource 0: assuming transparent Unknown bridge resource 1: assuming transparent Unknown bridge resource 2: assuming transparent
This is the problem.
The PCI code thinks that the parent of the network device doesn't have resources allocated, so it will allocate the resources from the parent of the parent.
Quoted 8 lines
Which is wrong, since it means that it will try to allocate the PCI resources from outside the window that the cardbus controller is exporting. Resulting in the fffff stuff.
HOWEVER, I don't see why that happens.
yenta_allocate_resources()should have made absolutely certain that we have all the necessary bridge resources clearly allocated. Can you add debug code to the end of "yenta_allocate_res()" that prints out the resource that got allocated?
I added a bunch of printk statements, see patch at the end for details. Here is the output:
Linux Kernel Card Services 3.1.22
options: [pci] [cardbus] [pm]
IRQ for 00:0a.0:0 -> PIRQ 60, mask 0400, excl 0000<4>PCI: IRQ 0 for device 00:0a.0 doesn't match PIRQ mask - try pci=usepirqmask
-> newirq=10 -> assigning IRQ 10 -> edge ... OK
PCI: Assigned IRQ 10 for device 00:0a.0yenta_allocate_res: nr=0 type=0x1200yenta_allocate_res: root->name=PCI memyenta_allocate_res: size=0x400000 min=0x10000000 max=0xffffffff align=0x400000, ret=0yenta_allocate_res: res=c11e6de4 name=PCI CardBus #01 start=0x10400000 end=0x107fffff flags=0x1200yenta_allocate_res: parent=c0251e7c sibling=c11e6920 child=00000000yenta_allocate_res: parent=PCI mem sibling=S3 Inc. ViRGE/MX child=yenta_allocate_res: nr=1 type=0x200yenta_allocate_res: root->name=PCI memyenta_allocate_res: size=0x400000 min=0x10000000 max=0xffffffff align=0x400000, ret=0yenta_allocate_res: res=c11e6e00 name=PCI CardBus #01 start=0x10800000 end=0x10bfffff flags=0x200yenta_allocate_res: parent=c0251e7c sibling=c11e6920 child=00000000yenta_allocate_res: parent=PCI mem sibling=S3 Inc. ViRGE/MX child=yenta_allocate_res: nr=2 type=0x100yenta_allocate_res: root->name=PCI IOyenta_allocate_res: size=0x100 min=0x4000 max=0xffff align=0x400, ret=0yenta_allocate_res: res=c11e6e1c name=PCI CardBus #01 start=0x4000 end=0x40ff flags=0x100yenta_allocate_res: parent=c0251e60 sibling=c11e6190 child=00000000yenta_allocate_res: parent=PCI IO sibling=Intel Corp. 82371AB PIIX4 USB child=yenta_allocate_res: nr=3 type=0x100yenta_allocate_res: root->name=PCI IOyenta_allocate_res: size=0x100 min=0x4000 max=0xffff align=0x400, ret=0yenta_allocate_res: res=c11e6e38 name=PCI CardBus #01 start=0x4400 end=0x44ff flags=0x100yenta_allocate_res: parent=c0251e60 sibling=c11e6190 child=00000000yenta_allocate_res: parent=PCI IO sibling=Intel Corp. 82371AB PIIX4 USB child=
IRQ for 00:0a.1:1 -> PIRQ 61, mask 0400, excl 0000<4>PCI: IRQ 0 for device 00:0a.1 doesn't match PIRQ mask - try pci=usepirqmask
-> newirq=10 -> assigning IRQ 10 ... OK
PCI: Assigned IRQ 10 for device 00:0a.1yenta_allocate_res: nr=0 type=0x1200yenta_allocate_res: root->name=PCI memyenta_allocate_res: size=0x400000 min=0x10000000 max=0xffffffff align=0x400000, ret=0yenta_allocate_res: res=c11df1e4 name=PCI CardBus #05 start=0x10c00000 end=0x10ffffff flags=0x1200yenta_allocate_res: parent=c0251e7c sibling=c11e6920 child=00000000yenta_allocate_res: parent=PCI mem sibling=S3 Inc. ViRGE/MX child=yenta_allocate_res: nr=1 type=0x200yenta_allocate_res: root->name=PCI memyenta_allocate_res: size=0x400000 min=0x10000000 max=0xffffffff align=0x400000, ret=0yenta_allocate_res: res=c11df200 name=PCI CardBus #05 start=0x11000000 end=0x113fffff flags=0x200yenta_allocate_res: parent=c0251e7c sibling=c11e6920 child=00000000yenta_allocate_res: parent=PCI mem sibling=S3 Inc. ViRGE/MX child=yenta_allocate_res: nr=2 type=0x100yenta_allocate_res: root->name=PCI IOyenta_allocate_res: size=0x100 min=0x4000 max=0xffff align=0x400, ret=0yenta_allocate_res: res=c11df21c name=PCI CardBus #05 start=0x4800 end=0x48ff flags=0x100yenta_allocate_res: parent=c0251e60 sibling=c11e6190 child=00000000yenta_allocate_res: parent=PCI IO sibling=Intel Corp. 82371AB PIIX4 USB child=yenta_allocate_res: nr=3 type=0x100yenta_allocate_res: root->name=PCI IOyenta_allocate_res: size=0x100 min=0x4000 max=0xffff align=0x400, ret=0yenta_allocate_res: res=c11df238 name=PCI CardBus #05 start=0x4c00 end=0x4cff flags=0x100yenta_allocate_res: parent=c0251e60 sibling=c11e6190 child=00000000yenta_allocate_res: parent=PCI IO sibling=Intel Corp. 82371AB PIIX4 USB child=
Intel PCIC probe: not found.
NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: ICMP, UDP, TCP
IP: routing cache hash table of 512 buckets, 4Kbytes
TCP: Hash tables configured (established 4096 bind 4096)ip_conntrack version 2.0 (512 buckets, 4096 max) - 292 bytes per conntrack
NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
Yenta IRQ list 0a98, PCI irq10
Socket status: 30000068
Yenta IRQ list 0a98, PCI irq10
Socket status: 30000006
cs: cb_alloc(bus 1): vendor 0x13d1, device 0xab02
Scanning bus 01
Found 01:00 [13d1/ab02] 000200 00
PCI: Calling quirk c01d57b0 for 01:00.0
Fixups for bus 01
PCI: Scanning for ghost devices on bus 1pci_read_bridge_bases 0: res=c11e6de4 name=PCI CardBus #01 base=0x0 limit=0x0
Unknown bridge resource 0: assuming transparentpci_read_bridge_bases 1: res=c11e6e00 name=PCI CardBus #01 base=0xf0000000 limit=0x10700000
Unknown bridge resource 1: assuming transparentpci_read_bridge_bases 2: res=c11e6e1c name=PCI CardBus #01 base=0x0 limit=0x10800000
Unknown bridge resource 2: assuming transparent
Bus scan for 01 returning with max=01
got res[1800:18ff] for resource 0 of PCI device 13d1:ab02 (Abocom Systems Inc)
got res[10002000:100023ff] for resource 1 of PCI device 13d1:ab02 (Abocom Systems Inc)
got res[10020000:1003ffff] for resource 6 of PCI device 13d1:ab02 (Abocom Systems Inc)
PCI: Enabling device 01:00.0 (0000 -> 0003)
IRQ for 01:00.0:0 -> not found in routing table
VFS: Mounted root (ext2 filesystem) readonly.
Freeing unused kernel memory: 200k freed
INIT: version 2.78 booting
drivers/pcmcia/yenta.c renamed from drivers/pcmcia/yenta.c.old +18 -1
@@ -709,6 +709,9 @@u32 align, size, min, max;unsigned offset;unsigned mask; +int ret; + +printk ("yenta_allocate_res: nr=%d type=0x%x\n" , nr, type);/* The granularity of the memory limit is 4kB, on IO it's 4 bytes */ mask = ~0xfff ;
@@ -727,6 +730,8 @@if (!root)return ; +printk ("yenta_allocate_res: root->name=%s\n" , root->name); + start =config_readl (socket, offset) & mask; end =config_readl (socket, offset+4 ) | ~mask;if (start && end > start) {
@@ -745,9 +750,21 @@ max =0xffff ; } -if (allocate_resource (root, res, size, min, max, align,NULL ,NULL ) <0 ) + ret =allocate_resource (root, res, size, min, max, align,NULL ,NULL ); +printk ("yenta_allocate_res: size=0x%x min=0x%x max=0x%x align=0x%x, ret=%d\n" , + size, min, max, align, ret); +if (ret <0 )return ; +printk ("yenta_allocate_res: res=%p name=%s start=0x%lx end=0x%lx flags=0x%lx\n" , + res, res->name, res->start, res->end, res->flags); +printk ("yenta_allocate_res: parent=%p sibling=%p child=%p\n" , + res->parent, res->sibling, res->child); +printk ("yenta_allocate_res: parent=%s sibling=%s child=%s\n" , + res->parent ? res->parent->name :"" , + res->sibling ? res->sibling->name :"" , + res->child ? res->child->name :"" ); +config_writel (socket, offset, res->start);config_writel (socket, offset+4 , res->end); }
drivers/pci/probe.c renamed from drivers/pci/probe.c.old +7 -1
@@ -7,7 +7,7 @@#include <linux/slab.h> #include <linux/module.h> -#undef DEBUG +#define DEBUG #ifdef DEBUG #define DBG(x...) printk(x)
@@ -145,6 +145,8 @@ limit |= (io_limit_hi <<16 ); } +printk ("pci_read_bridge_bases 0: res=%p name=%s base=0x%lx limit=0x%lx\n" , + res, res ? res->name :"" , base, limit);if (base && base <= limit) { res->flags = (io_base_lo &PCI_IO_RANGE_TYPE_MASK ) |IORESOURCE_IO ; res->start = base;
@@ -163,6 +165,8 @@pci_read_config_word (dev,PCI_MEMORY_LIMIT , &mem_limit_lo); base = (mem_base_lo &PCI_MEMORY_RANGE_MASK ) <<16 ; limit = (mem_limit_lo &PCI_MEMORY_RANGE_MASK ) <<16 ; +printk ("pci_read_bridge_bases 1: res=%p name=%s base=0x%lx limit=0x%lx\n" , + res, res ? res->name :"" , base, limit);if (base && base <= limit) { res->flags = (mem_base_lo &PCI_MEMORY_RANGE_TYPE_MASK ) |IORESOURCE_MEM ; res->start = base;
@@ -193,6 +197,8 @@ }#endif } +printk ("pci_read_bridge_bases 2: res=%p name=%s base=0x%lx limit=0x%lx\n" , + res, res ? res->name :"" , base, limit);if (base && base <= limit) { res->flags = (mem_base_lo &PCI_MEMORY_RANGE_TYPE_MASK ) |IORESOURCE_MEM |IORESOURCE_PREFETCH ; res->start = base;
Signature · 2 lines
Peter Osterlund - [email protected] http://w1.894.telia.com/~u89404340
Quoted 2 lines · Jeff Garzik
We already have
pci_request_regions()and currently PCI drivers should use that.
I have to admit I wasn't aware of that. It doesn't really help with the problem which started this thread, though.
Quoted 4 lines
Auto-ioremap would be bad, though... you would wind up wasting address space for any case where MMIO areas are not 100% utilized (like network cards that require use of PIO due to hardware bugs, but still export an MMIO region for their NIC registers)
auto-ioremap would be bad for pci_request_regions(), which just blindly allocates all regions. Let's show an example of what I was thinking about, though.
This is eepro100.c::eepro100_init_one() after the conversion
- IMO it looks a lot simpler than the old code.
--------------------------------------------------------------
#ifdef USE_IO
ioaddr = pci_request_io(pdev, 1);
if (!ioaddr)
goto err_out_none;
if (speedo_debug > 2)
printk("Found Intel i82557 PCI Speedo at I/O %#lx.\n", ioaddr);
#else
ioaddr = (unsigned long) pci_request_mmio(pdev, 0);
if (!ioaddr)
goto err_out_none;
if (speedo_debug > 2)
printk("Found Intel i82557 PCI Speedo, MMIO at %#lx.\n",
pci_resource_start(pdev, 0));
#endif
if (speedo_found1(pdev, ioaddr, cards_found, acpi_idle_state) == 0)
cards_found++;
else
goto err_out_release;
return 0;err_out_release:
#ifdef USE_IO pci_release_io(pdev, 1); #else pci_release_mmio(pdev, 0, (void *)ioaddr); #endif err_out_none: return -ENODEV;
--------------------------------------------------------------
We only request the regions we're going to use, so the others may even stay unassigned and disabled.
So my idea looks something like this:
unsigned long pci_request_io(struct pci_dev *pdev, int nr); void * pci_request_mmio(struct pci_dev *pdev, int nr); void pci_release_io(struct pci_dev *pdev, int nr); void pci_release_mmio(struct pci_dev *pdev, int nr, void *addr); int pci_request_irq(struct pci_dev *pdev, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *name, void *dev); void pci_release_irq(struct pci_dev *pdev, void *dev);
These functions return directly what we need: an address for in/out[bwl], a cookie for read/write[bwl] - well, and the irq which however is only for informational purposes.
It probably makes sense to split the pci_request_irq() into pci_assign_irq() and pci_request_irq(), since we want to delay the pci_request_irq() until we really need it.
The advantages are:
o saves the ioremap etc.
o tells the PCI layer explicitly which resources we use, so it doesn't have to take the all or nothing pci_enable_device()/ pci_request_resources() approach
o adds appropriate printk(KERN_INFO) when request_region etc fails, saving thousands of places where we need do the printk() by hand, and fixing the other thousands of places where we don't printk() so the user has no idea why the driver wouldn't load.
I deliberately deviated a bit from the normal syntax
(region -> io, mem_region -> mmio, free_irq -> release_irq), for one reason since I find it more logical this way, but also because the API is somewhat different, so it shouldn't just appear to be the same - the difference being e.g. that the old API needed the explicit pci_enable_device(), whereas that should not be used in the new one.
A very early patch is appended, totally untested, though - I chose eepro100 since I have that in my laptop, but I don't have my laptop here.
Some parts of the implementation are not as clean as they could be since I didn't want to muck with the internals of the PCI layer too much - some cleanup there wouldn't hurt, though.
--Kai
===== arch/i386/pci/i386.c 1.10 vs edited =====
arch/i386/pci/i386.c +14 -7
@@ -243,16 +243,15 @@pcibios_assign_resources (); } -int pcibios_enable_resources (struct pci_dev *dev) +int pcibios_enable_resource (struct pci_dev *dev,int nr) { +struct resource *r = &dev->resource (nr);u16 cmd, old_cmd; -int idx; -struct resource *r;pci_read_config_word (dev,PCI_COMMAND , &cmd); old_cmd = cmd; -for (idx=0 ; idx<6 ; idx++) { - r = &dev->resource[idx]; + +if (nr !=PCI_ROM_RESOURCE ) {if (!r->start && r->end) {printk (KERN_ERR "PCI: Device %s not available because of resource collisions\n" , dev->slot_name);return -EINVAL ;
@@ -261,13 +260,21 @@ cmd |=PCI_COMMAND_IO ;if (r->flags &IORESOURCE_MEM ) cmd |=PCI_COMMAND_MEMORY ; + }else { +if (r->start) + cmd |=PCI_COMMAND_MEMORY ; } -if (dev->resource[PCI_ROM_RESOURCE ].start) - cmd |=PCI_COMMAND_MEMORY ;if (cmd != old_cmd) {printk ("PCI: Enabling device %s (%04x -> %04x)\n" , dev->slot_name, old_cmd, cmd);pci_write_config_word (dev,PCI_COMMAND , cmd); } +} + +int pcibios_enable_resources (struct pci_dev *dev) +{ +for (idx =0 ; idx <=PCI_ROM_RESOURCE ; idx++) +pcibios_enable_resource (dev, idx); +return 0 ; }
===== drivers/net/eepro100.c 1.32 vs edited =====
drivers/net/eepro100.c +24 -45
138 lines not on this page · raw message
===== drivers/pci/pci.c 1.44 vs edited =====
drivers/pci/pci.c +113 -0
125 lines not on this page · raw message
===== include/linux/pci.h 1.32 vs edited =====
include/linux/pci.h +10 -0
@@ -580,6 +580,16 @@int pci_set_power_state (struct pci_dev *dev,int state);int pci_enable_wake (struct pci_dev *dev,u32 state,int enable); +/* New resource management */ +unsigned long pci_request_io (struct pci_dev *pdev,int nr); +void *pci_request_mmio (struct pci_dev *pdev,int nr); +void pci_release_io (struct pci_dev *pdev,int nr); +void pci_release_mmio (struct pci_dev *pdev,int nr,void *addr); +int pci_request_irq (struct pci_dev *pdev, +void (*handler)(int ,void *,struct pt_regs *), +unsigned long flags,const char *name,void *dev); +void pci_release_irq (struct pci_dev *pdev,void *dev); +/* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */ int pci_claim_resource (struct pci_dev *,int );
Quoted 81 lines · Kai Germaschewski
Quoted 1 line · Jeff Garzik
We already have
pci_request_regions()and currently PCI drivers should use that.I have to admit I wasn't aware of that. It doesn't really help with the problem which started this thread, though.
Quoted 1 line
Auto-ioremap would be bad, though... you would wind up wasting address space for any case where MMIO areas are not 100% utilized (like network cards that require use of PIO due to hardware bugs, but still export an MMIO region for their NIC registers)
auto-ioremap would be bad for
pci_request_regions(), which just blindly allocates all regions. Let's show an example of what I was thinking about, though.This is
eepro100.c::eepro100_init_one()after the conversion
- IMO it looks a lot simpler than the old code.--------------------------------------------------------------
#ifdef USE_IO ioaddr = pci_request_io(pdev, 1); if (!ioaddr) goto err_out_none; if (speedo_debug > 2) printk("Found Intel i82557 PCI Speedo at I/O %#lx.\n", ioaddr); #else ioaddr = (unsigned long) pci_request_mmio(pdev, 0); if (!ioaddr) goto err_out_none; if (speedo_debug > 2) printk("Found Intel i82557 PCI Speedo, MMIO at %#lx.\n", pci_resource_start(pdev, 0)); #endif if (speedo_found1(pdev, ioaddr, cards_found, acpi_idle_state) == 0) cards_found++; else goto err_out_release; return 0;
err_out_release:#ifdef USE_IO pci_release_io(pdev, 1); #else pci_release_mmio(pdev, 0, (void *)ioaddr); #endif err_out_none: return -ENODEV;--------------------------------------------------------------
We only request the regions we're going to use, so the others may even stay unassigned and disabled.
So my idea looks something like this:
unsigned long pci_request_io(struct pci_dev *pdev, int nr); void * pci_request_mmio(struct pci_dev *pdev, int nr); void pci_release_io(struct pci_dev *pdev, int nr); void pci_release_mmio(struct pci_dev *pdev, int nr, void *addr); int pci_request_irq(struct pci_dev *pdev, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *name, void *dev); void pci_release_irq(struct pci_dev *pdev, void *dev);These functions return directly what we need: an address for in/out[bwl], a cookie for read/write[bwl] - well, and the irq which however is only for informational purposes.
It probably makes sense to split the
pci_request_irq()intopci_assign_irq()andpci_request_irq(), since we want to delay thepci_request_irq()until we really need it.
Quoted 9 lines
The advantages are:
o saves the ioremap etc.
o tells the PCI layer explicitly which resources we use, so it doesn't have to take the all or nothing pci_enable_device()/pci_request_resources()approach
o adds appropriateprintk(KERN_INFO)whenrequest_regionetc fails, saving thousands of places where we need do theprintk()by hand, and fixing the other thousands of places where we don'tprintk()so the user has no idea why the driver wouldn't load.
Thanks for the patch, I can see where you're headed more clearly.
Comments:
* You absolutely need a separate _assign_irq(). request_irq() and free_irq() are used today as the points which enable and disable an irq for a device.
* You want to keep pci_enable_device(), such that, in driver code it does not need to be moved. This is an important hook for hotplug PCI and cardbus and such things, which need a point where they may enable the device as a whole. One important function pci_enable_device() does now, for example, is bring the PCI device to D0 full-power-on state.
* Remember that you must handle two cases here: 1) BIOS-pre-assigned region values, and 2) on-the-fly assigned values. Drivers needs to work transparently such that, on a desktop PCI system, pci_request_regions() is _really_ all the reservation they need. And the same driver, using the same code, should handle cardbus and other systems that are having resources assigned to them dynamically. I don't really care that much how's it's implemented behind-the-scenes, as long as the end-result driver code handles both these cases without a forest of "if's" and "ifdef's"
Jeff
Quoted 5 lines · Linus Torvalds
Quoted 3 lines
Unknown bridge resource 0: assuming transparent
Unknown bridge resource 1: assuming transparent
Unknown bridge resource 2: assuming transparentThis is the problem.
BTW, this "assuming transparent" bit continually causes us problems on RS/6000 machines that have a PCI-PCI bus. If none of the cards behind the bridge have any I/O resources, the firmware will set up the bridge with the I/O window closed, by setting the base register to one more than the limit register, which is correct according to the Intel document describing PCI-PCI bridges.
Then the bridge probing code comes along and says "assuming transparent", which is wrong. The aperture is closed and the bridge should have no I/O space resource.
I would really like the relevant code in pci_read_bridge_bases to look like this:
if ((base || limit) && base <= limit) {
res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
res->start = base;
res->end = limit + 0xfff;
res->name = child->name;
} else if (base == limit + 0x1000) {
/* Firmware/BIOS has deactivated this window */
res->start = res->end = 0;
res->flags = 0;
printk(KERN_ERR "Bridge %s resource %d was deactivated by"
" firmware\n", dev->slot_name, 0);
} else {
/*
* Ugh. We don't know enough about this bridge. Just assume
* that it's entirely transparent.
*/
printk(KERN_ERR "Unknown bridge resource %d: assuming transparent\n", 0);
child->resource[0] = child->parent->resource[0];
}The (base || limit) part instead of just testing base is needed because we sometimes get PCI-PCI bridges that are legitimately set up with the bridge having an aperture starting at I/O address 0.
IIRC someone told me that we had to do the "assuming transparent" bit because of buggy PCI-PCI bridges used on some PCs. Can anyone enlighten me on the details of that?
Paul.
Hi,
Quoted 2 lines · Kai Germaschewski
We only request the regions we're going to use, so the others may even stay unassigned and disabled.
[...]
Quoted 3 lines
These functions return directly what we need: an address for in/out[bwl], a cookie for read/write[bwl] - well, and the irq which however is only for informational purposes.
I like it!
This also allows us to remove the anal checking & cleanup duplicated in each and every driver to be removed.
So your solution will save lots of code at least in all PCI-only drivers.
I even wrote my own routine that does exactly that, to save the code.
Some people can not use pci_enable_resources(), because sometimes one of the resources is a PCI-Interface chip, that has a different driver, which enabled one resource already itself.
So splitting this out alone is already a win.
Regards
Ingo Oeser
Signature · 1 line
Science is what we can tell a computer. Art is everything else. --- D.E.Knuth
Quoted 6 lines · Jeff Garzik
Can someone clarify for me the need of
pci_request_irq??
pci_enable_device()assigns the IRQ in routing, but it is not enabled until you callrequest_irq. I don't see any simplification that can be done in the PCI API.
The irq _is_ enabled ona hardware level.
Which can be a total disaster if there are shared PCI irq's, and the interrupt is "screaming" (ie an active level-sensitive thing).
We've had this on cardbus, for example, where we need to do an "pci_emable_device()" in order to get access to the PCI IO mappings, which are needed to shut the device up.
Right now the solution to a screaming device can be something as nasty as
cli(); pci_enable_device(); disable_irq(dev->irq); sti(); /* IRQ handling needs this ioremapped */ membase = ioremap(dev->resource[]); request_irq(dev->irq); /* Now we can enable the irq, because we have a valid handler */ enable_irq(dev->irq);
which is horribly stupid. We really want to do
pci_enable_mem(dev); membase = ioremap(dev->resource[]); pci_request_irq(dev, irq_handler);
where "pci_request_irq()" enables the interrupt and adds an interrupt handler atomically.
Quoted 2 lines
The only thing I've wanted is a cross-platform way to detect if
pdev->irqreturned bypci_enable_deviceis valid.
It's required to be valid, because if it isn't, then the platform is broken. There are no cross-platform issues: complain to the platform vendor and/or the linux code for that architecture.
Linus
Quoted 14 lines · Linus Torvalds
Right now the solution to a screaming device can be something as nasty as
cli(); pci_enable_device(); disable_irq(dev->irq); sti(); /* IRQ handling needs this ioremapped */ membase = ioremap(dev->resource[]); request_irq(dev->irq); /* Now we can enable the irq, because we have a valid handler */ enable_irq(dev->irq);
Side note: the other approach to screaming devices is to pray that they don't happen.
Which is actually the approach Linux takes, and which tends to work reasonably well. All PCI devices reset without pending interrupts, and probably windows doesn't react well to the bios doing something stupid.
But it's actually happened for pcmcia depending on init order (and right now linux pcmcia is just fairly careful about the ordering).
Linus
Quoted 13 lines · Linus Torvalds
Quoted 12 lines · Linus Torvalds
Right now the solution to a screaming device can be something as nasty as
cli(); pci_enable_device(); disable_irq(dev->irq); sti(); /* IRQ handling needs this ioremapped */ membase = ioremap(dev->resource[]); request_irq(dev->irq);
Quoted 5 lines
Quoted 2 lines
/* Now we can enable the irq, because we have a valid handler */ enable_irq(dev->irq);Side note: the other approach to screaming devices is to pray that they don't happen.
I think there are situations where we don't have a choice but praying anyway. Since there's no PCI_COMMAND_IRQ, the only way to suppress IRQs AFAICS is to not route them (well, or ignore them, which is what we do if there's no handler installed), but that's just not possible when the IRQ line is shared with some other active device.
I still think it's probably a good idea to replace pci_enable_device() by a more fine-grained API, which allows a driver author to specify which exact resources he needs.
In the normal case, a driver would only use a subset of the following three functions as needed:
int pci_request_irq(pci_dev, handler, ...); unsigned long pci_request_io(pci_dev, nr); unsigned long pci_request_mmio(pci_dev, nr);
(plus appropriate s/request/release/ of course)
Internally, they'd do the right thing, i.e. assign and enable resources as needed.
At least for the _irq case an associated
int pci_assign_irq(pci_dev);
is useful, since some drivers (e.g. net, serial) only request their irq when the device is opened (which make sense for performance reasons with shared irqs), but it'd still be nice to fail the ::probe() when no IRQ can be assigned.
So a complete API would be
pci_request_{irq,io,mmio}
pci_release_{irq,io,mmio}
pci_enable_{irq,io,mmio}
pci_assign_{irq,io,mmio}but normally a driver would just use pci_request/release_*() + maybe pci_assign_irq(), which will take care of the appropriate assign/enable internally.
--Kai
Quoted 2 lines · Kai Germaschewski
I still think it's probably a good idea to replace
pci_enable_device()
by a more fine-grained API, which allows a driver author to specify which exact resources he needs.
To repeat, pci_enable_device is not _just_ resource assignment.
It also provides:
1) power state management (wakes up the device)
2) an entry point which guarantees the bus layer that the driver is not interested in the hardware at all before that point. Or IOW, pci_enable_device is a bus layer hook for whatever "device wakeup/appearing" needs that bus has. Sure, we are talking about moving some of that functionality to other functions (pci_request_<foo>), but that doesn't mean we should ditch the hook altogether.
Remember, we have a matching pair here: pci_enable_device, pci_disable_device. Update the code that goes on between those two calls, sure. But leave the calls there.
Quoted 10 lines
So a complete API would be
pci_request_{irq,io,mmio} pci_release_{irq,io,mmio} pci_enable_{irq,io,mmio} pci_assign_{irq,io,mmio}but normally a driver would just use pci_request/release_*() + maybe
pci_assign_irq(), which will take care of the appropriate assign/enable internally.
That seems like a decent enough API, pending a bit of driver conversion to see how well it works out in practice. So I'm ok with it (with the pci_enable_device proviso, above)
Jeff
Quoted 9 lines · Linus Torvalds
which is horribly stupid. We really want to do
pci_enable_mem(dev); membase = ioremap(dev->resource[]); pci_request_irq(dev, irq_handler);where "
pci_request_irq()" enables the interrupt and adds an interrupt handler atomically.
That seems ok to me. Note that we still want pci_{enable,disable}_device to exist (as mentioned in the mail to Kai)... I'm fine with moving a lot of pci_enable_device's duties to pci_{assign,request,release}_{irq,io,mem} as long as we don't kill it completely.
Quoted 7 lines
Quoted 2 lines
The only thing I've wanted is a cross-platform way to detect if
pdev->irqreturned bypci_enable_deviceis valid.It's required to be valid, because if it isn't, then the platform is broken. There are no cross-platform issues: complain to the platform vendor and/or the linux code for that architecture.
Well, then I should either complain to myself, or to you ;-) Part of this comes back to PCI irq routing. The actual situation encountered is,
When ia32 PCI irq routing messes up, or some other random reason why an irq is not available for a PCI device, pdev->irq==0. So I test for that in my code. Then DaveM bitches at me for my test (pdev->irq < 2) not being cross-platform.
My suggested solution, if you like Kai's proposal, is to have pci_assign_irq() or pci_request_irq() return an error if PCI IRQ routing fails.
Jeff
P.S. Random tangent: the PCI layer could do a lot better job at spreading devices across the available IRQs. I've seen devices clustered on a single interrupt by the Linux PCI code, where their pci irq routing masks indicating other, not-assigned-at-all irqs were available.
Re: Cardbus
In reply to Paul MackerrasQuoted 4 lines · Paul Mackerras
IIRC someone told me that we had to do the "assuming transparent" bit because of buggy PCI-PCI bridges used on some PCs. Can anyone enlighten me on the details of that?
It has nothing to do with "buggy" PCI-PCI bridges, and everything to do with the fact that a lot of bridges seem to extend on the official PCI bridge interface in various ways. In particular, it seems to be fairly common to have the _real_ bridging information in the chip-specific range (PCI config area 0x40+) instead of in the official "2 mem resources, 2 IO resources" place.
I think even some bog-standard Intel PCI bridge did exactly this. But all my pdf files are at work right now.
Linus
Quoted 5 lines · Jeff Garzik
That seems ok to me. Note that we still want pci_{enable,disable}_device to exist (as mentioned in the mail to Kai)... I'm fine with moving a lot of pci_enable_device's duties to pci_{assign,request,release}_{irq,io,mem} as long as we don't kill it completely.
I'm aware that something like pci_enable_device() still is necessary, but I moved this part of the functionality into pci_request_*.
pci_enable_device() does the equivalent of
{ pci_assign_irq(); pci_assign_mmio(); pci_assign_io() } where these again internally do pci_set_power_state() (and could extended to do whatever else necessary).
The main reason against pci_enable_device() is that it makes a smooth transition impossible - We cannot change pci_enable_device()'s behavior in a way that relies on all drivers using pci_request_*() already. And introducing a new function under a new name seems pointless when it can be hidden inside the new API as well.
What's not so nice is that it destroys the symmetry between pci_enable_device() and pci_disable_device().
But I think I have an idea for that one as well: This new API will be used in conjunction with the new-style pci_register_driver() etc interface, where the PCI layer knows when we call ::probe() and ::remove(). So it'd be actually even nicer to do the pci_set_power_state() etc before ::probe() is called, and pci_disable_device after::remove() has finished (and on ::probe() error path)
How does that sound?
Quoted 8 lines
When ia32 PCI irq routing messes up, or some other random reason why an irq is not available for a PCI device, pdev->irq==0. So I test for that in my code. Then DaveM bitches at me for my test (
pdev->irq< 2) not being cross-platform.My suggested solution, if you like Kai's proposal, is to have
pci_assign_irq()orpci_request_irq()return an error if PCI IRQ routing fails.
Yes, makes sense. Actually currently pci_enable_device() should return an error when the IRQ routing fails - it does so when using ACPI routing, but not when doing PIRQ routing, so I think that's a bug to be fixed in arch/i386/pci/irq.c.
I decided to return an int from pci_*_irq, where < 0 means error. The number returned otherwise shell only be used for printk("IRQ %d", ret), anyway - pci_dev->irq stays opaque to the driver.
Proposed patch to follow in a minute.
--Kai
Quoted 7 lines · Jeff Garzik
Quoted 7 lines
So a complete API would be
pci_request_{irq,io,mmio} pci_release_{irq,io,mmio} pci_enable_{irq,io,mmio} pci_assign_{irq,io,mmio}
Quoted 8 lines
Quoted 3 lines
but normally a driver would just use pci_request/release_*() + maybe
pci_assign_irq(), which will take care of the appropriate assign/enable internally.That seems like a decent enough API, pending a bit of driver conversion to see how well it works out in practice. So I'm ok with it (with the
pci_enable_deviceproviso, above)
Okay, so here's a patch which actually compiles and works here.
TODO:
o move the pci_set_power_state() before calling pci_driver::probe() add pci_disable_device() after pci_driver::remove()
o fix other archs.
Currently, each arch has a
pcibios_enable_device()
function, which now needs to be split into
pcibios_assign_irq()
pcibios_enable_irq()
IO/MMIO is all taken care of by the generic code currently. (Possibly we need to add callbacks into arch-specific code there)
Apart from breaking each arch but i386/x86_64, the patch is ready, at least from my point of view ;)
--Kai
Pull from http://linux-isdn.bkbits.net/linux-2.5.pci
(Merging changesets omitted for clarity)
-----------------------------------------------------------------------------
[email protected], 2002-06-15 14:04:46-05:00, [email protected]
PCI: Set pci_dev->driver before calling ::probe()
That's just preparation so that we can use pci_dev->driver inside the probe() routine, e.g. for driver->name.
----------------------------------------------------------------------------
pci-driver.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-)
-----------------------------------------------------------------------------
[email protected], 2002-06-15 15:19:22-05:00, [email protected]
PCI: Introduce pci_assign_irq() and pci_enable_irq()
The functions assign and route an IRQ on a PCI device, a bit inline docu is available in drivers/pci/pci.c
Internally they call back into the arch specific pcibios_assign/enable_irq(), which means everything but i386/x86_64 gets broken by this change (should be easy to fix, though).
Rename the function pointer pcibios_enable_irq to pcibios_enable_irq_func to not clash with these functions.
----------------------------------------------------------------------------
arch/i386/pci/acpi.c | 2 - arch/i386/pci/common.c | 18 +++++++++++++++- arch/i386/pci/irq.c | 10 +++++---- arch/i386/pci/pci.h | 3 -- arch/x86_64/pci/acpi.c | 2 - arch/x86_64/pci/common.c | 5 ++++ arch/x86_64/pci/irq.c | 10 +++++---- arch/x86_64/pci/pci.h | 3 -- drivers/pci/pci.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/pci.h | 2 + 10 files changed, 90 insertions(+), 15 deletions(-)
-----------------------------------------------------------------------------
[email protected], 2002-06-15 16:35:23-05:00, [email protected]
PCI: Introduce wrapper to set/clear PCI command bits
It'd be worth it even if we wouldn't make yet more use of it in the next patch.
----------------------------------------------------------------------------
pci.c | 61 ++++++++++++++++++++++++++++++++----------------------------- 1 files changed, 32 insertions(+), 29 deletions(-)
-----------------------------------------------------------------------------
[email protected], 2002-06-15 16:38:20-05:00, [email protected]
PCI: Introduce pci_assign/enable_io/mmio functions
The main use of those will be internal to pci_request/release_io/mmio. However, we export them, since there'll always be hardware which needs special hacks...
----------------------------------------------------------------------------
drivers/pci/pci.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++- include/linux/pci.h | 7 ++ 2 files changed, 128 insertions(+), 2 deletions(-)
-----------------------------------------------------------------------------
[email protected], 2002-06-15 17:23:10-05:00, [email protected]
PCI: Add pci_request_* and pci_release_* API
Docu is available inline. When switching a driver to this API, calling pci_enable_device() is not necessary anymore, the needed resources will be activated at pci_request_* time.
In particular, that means if your driver only uses MMIO, IO resources on your card won't be assigned and enabled (it's possible that the BIOS did that, though).
----------------------------------------------------------------------------
drivers/pci/pci.c | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/pci.h | 9 ++ 2 files changed, 196 insertions(+)
-----------------------------------------------------------------------------
[email protected], 2002-06-15 17:31:38-05:00, [email protected]
PCI: Convert two sample drivers to new interface
eepro100 and ymfpci still work fine on my laptop after the change, even when zeroing out their BARs during boot.
----------------------------------------------------------------------------
drivers/net/eepro100.c | 83 +++++++++++++++++++++---------------------------- sound/oss/ymfpci.c | 45 ++++++++++---------------- 2 files changed, 54 insertions(+), 74 deletions(-)
=============================================================================
unified diffs follow for reference
=============================================================================
-----------------------------------------------------------------------------
[email protected], 2002-06-15 14:04:46-05:00, [email protected]
PCI: Set pci_dev->driver before calling ::probe()
That's just preparation so that we can use pci_dev->driver inside the probe() routine, e.g. for driver->name.
---------------------------------------------------------------------------
drivers/pci/pci-driver.c +6 -4
@@ -48,12 +48,14 @@const struct pci_device_id *id; id =pci_match_device (drv->id_table, pci_dev); -if (id) - error = drv->probe (pci_dev, id); -if (error >=0 ) { +if (id) { pci_dev->driver = drv; - error =0 ; + error = drv->probe (pci_dev, id); } +if (error <0 ) + pci_dev->driver =NULL ; +else + error =0 ; }return error; }
-----------------------------------------------------------------------------
[email protected], 2002-06-15 15:19:22-05:00, [email protected]
PCI: Introduce pci_assign_irq() and pci_enable_irq()
The functions assign and route an IRQ on a PCI device, a bit inline docu is available in drivers/pci/pci.c
Internally they call back into the arch specific pcibios_assign/enable_irq(), which means everything but i386/x86_64 gets broken by this change (should be easy to fix, though).
Rename the function pointer pcibios_enable_irq to pcibios_enable_irq_func to not clash with these functions.
---------------------------------------------------------------------------
arch/i386/pci/acpi.c +1 -1
@@ -13,7 +13,7 @@printk (KERN_INFO "PCI: Using ACPI for IRQ routing\n" );printk (KERN_INFO "PCI: if you experience problems, try using option 'pci=noacpi'\n" ); pcibios_scanned++; - pcibios_enable_irq = acpi_pci_irq_enable; + pcibios_enable_irq_func = acpi_pci_irq_enable; }else printk (KERN_WARNING "PCI: Invalid ACPI-PCI IRQ routing table\n" );
arch/i386/pci/common.c +17 -1
@@ -209,5 +209,21 @@if ((err =pcibios_enable_resources (dev)) <0 )return err; -return pcibios_enable_irq (dev); +return pcibios_enable_irq_func (dev); +} + +int pcibios_assign_irq (struct pci_dev *dev) +{ +return pcibios_enable_irq_func (dev); +} + +/* +* We've done all the work in pcibios_assign_irq already. +* We may want to change this later to activate the actual routing at this +* point, though. +* It's only ever called after a successful pcibios_assign_irq() +*/ +int pcibios_enable_irq (struct pci_dev *dev) +{ +return 0 ; }
arch/i386/pci/irq.c +6 -4
@@ -44,7 +44,7 @@int (*set)(struct pci_dev *router,struct pci_dev *dev,int pirq,int new); }; -int (*pcibios_enable_irq)(struct pci_dev *dev) =NULL ; +int (*pcibios_enable_irq_func)(struct pci_dev *dev);/* * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
@@ -684,11 +684,13 @@return 1 ; } +static int pirq_enable_irq (struct pci_dev *dev); +static int __init pcibios_irq_init (void ) {DBG ("PCI: IRQ init\n" ); -if (pcibios_enable_irq) +if (pcibios_enable_irq_func)return 0 ; pirq_table =pirq_find_routing_table ();
@@ -711,7 +713,7 @@ pirq_table =NULL ; } - pcibios_enable_irq = pirq_enable_irq; + pcibios_enable_irq_func = pirq_enable_irq;pcibios_fixup_irqs ();return 0 ;
@@ -794,7 +796,7 @@ pirq_penalty[irq] +=100 ; } -int pirq_enable_irq (struct pci_dev *dev) +static int pirq_enable_irq (struct pci_dev *dev) {u8 pin;pci_read_config_byte (dev,PCI_INTERRUPT_PIN , &pin);
arch/i386/pci/pci.h +1 -2
@@ -70,6 +70,5 @@extern spinlock_t pci_config_lock;void pcibios_fixup_irqs (void ); -int pirq_enable_irq (struct pci_dev *dev); -extern int (*pcibios_enable_irq)(struct pci_dev *dev); +extern int (*pcibios_enable_irq_func)(struct pci_dev *dev);
arch/x86_64/pci/acpi.c +1 -1
@@ -13,7 +13,7 @@printk (KERN_INFO "PCI: Using ACPI for IRQ routing\n" );printk (KERN_INFO "PCI: if you experience problems, try using option 'pci=noacpi'\n" ); pcibios_scanned++; - pcibios_enable_irq = acpi_pci_irq_enable; + pcibios_enable_irq_func = acpi_pci_irq_enable; }else printk (KERN_WARNING "PCI: Invalid ACPI-PCI IRQ routing table\n" );
arch/x86_64/pci/common.c +5 -0
@@ -194,3 +194,8 @@return pcibios_enable_irq (dev); } + +int pcibios_enable_irq (struct pci_dev *dev) +{ +return pcibios_enable_irq_func (dev); +}
arch/x86_64/pci/irq.c +6 -4
@@ -44,7 +44,7 @@int (*set)(struct pci_dev *router,struct pci_dev *dev,int pirq,int new); }; -int (*pcibios_enable_irq)(struct pci_dev *dev) =NULL ; +int (*pcibios_enable_irq_func)(struct pci_dev *dev);/* * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
@@ -528,11 +528,13 @@return 1 ; } +static int pirq_enable_irq (struct pci_dev *dev); +static int __init pcibios_irq_init (void ) {DBG ("PCI: IRQ init\n" ); -if (pcibios_enable_irq) +if (pcibios_enable_irq_func)return 0 ; pirq_table =pirq_find_routing_table ();
@@ -551,7 +553,7 @@ pirq_table =NULL ; } - pcibios_enable_irq = pirq_enable_irq; + pcibios_enable_irq_func = pirq_enable_irq;pcibios_fixup_irqs ();return 0 ;
@@ -634,7 +636,7 @@ pirq_penalty[irq] +=100 ; } -int pirq_enable_irq (struct pci_dev *dev) +static int pirq_enable_irq (struct pci_dev *dev) {u8 pin;pci_read_config_byte (dev,PCI_INTERRUPT_PIN , &pin);
arch/x86_64/pci/pci.h +1 -2
@@ -68,6 +68,5 @@extern spinlock_t pci_config_lock;void pcibios_fixup_irqs (void ); -int pirq_enable_irq (struct pci_dev *dev); -extern int (*pcibios_enable_irq)(struct pci_dev *dev); +extern int (*pcibios_enable_irq_func)(struct pci_dev *dev);
drivers/pci/pci.c +50 -0
56 lines not on this page · raw message
include/linux/pci.h +2 -0
@@ -500,6 +500,8 @@void pcibios_fixup_bus (struct pci_bus *);int pcibios_enable_device (struct pci_dev *); +int pcibios_assign_irq (struct pci_dev *dev); +int pcibios_enable_irq (struct pci_dev *dev);char *pcibios_setup (char *str);/* Used only when drivers/pci/setup.c is used */
-----------------------------------------------------------------------------
[email protected], 2002-06-15 16:35:23-05:00, [email protected]
PCI: Introduce wrapper to set/clear PCI command bits
It'd be worth it even if we wouldn't make yet more use of it in the next patch.
---------------------------------------------------------------------------
drivers/pci/pci.c +32 -29
97 lines not on this page · raw message
-----------------------------------------------------------------------------
[email protected], 2002-06-15 16:38:20-05:00, [email protected]
PCI: Introduce pci_assign/enable_io/mmio functions
The main use of those will be internal to pci_request/release_io/mmio. However, we export them, since there'll always be hardware which needs special hacks...
---------------------------------------------------------------------------
drivers/pci/pci.c +121 -2
156 lines not on this page · raw message
include/linux/pci.h +7 -0
@@ -576,6 +576,13 @@int pci_dac_set_dma_mask (struct pci_dev *dev,u64 mask);int pci_assign_resource (struct pci_dev *dev,int i); +int pci_assign_irq (struct pci_dev *dev); +int pci_enable_irq (struct pci_dev *dev); +int pci_assign_mmio (struct pci_dev *dev); +int pci_assign_io (struct pci_dev *dev); +int pci_enable_mmio (struct pci_dev *dev); +int pci_enable_io (struct pci_dev *dev); +/* Power management related routines */ int pci_save_state (struct pci_dev *dev,u32 *buffer);int pci_restore_state (struct pci_dev *dev,u32 *buffer);
-----------------------------------------------------------------------------
[email protected], 2002-06-15 17:23:10-05:00, [email protected]
PCI: Add pci_request_* and pci_release_* API
Docu is available inline. When switching a driver to this API, calling pci_enable_device() is not necessary anymore, the needed resources will be activated at pci_request_* time.
In particular, that means if your driver only uses MMIO, IO resources on your card won't be assigned and enabled (it's possible that the BIOS did that, though).
---------------------------------------------------------------------------
drivers/pci/pci.c +187 -0
206 lines not on this page · raw message
include/linux/pci.h +9 -0
@@ -576,6 +576,15 @@int pci_dac_set_dma_mask (struct pci_dev *dev,u64 mask);int pci_assign_resource (struct pci_dev *dev,int i); +int pci_request_irq (struct pci_dev *dev, +void (*handler)(int ,void *,struct pt_regs *), +unsigned long flags,void *dev_id); +void *pci_request_mmio (struct pci_dev *pdev,unsigned int nr); +unsigned long pci_request_io (struct pci_dev *dev,unsigned int nr); +void pci_release_irq (struct pci_dev *dev,void *dev_id); +void pci_release_mmio (struct pci_dev *dev,unsigned int nr,void *addr); +void pci_release_io (struct pci_dev *dev,unsigned int nr); +int pci_assign_irq (struct pci_dev *dev);int pci_enable_irq (struct pci_dev *dev);int pci_assign_mmio (struct pci_dev *dev);
-----------------------------------------------------------------------------
[email protected], 2002-06-15 17:31:38-05:00, [email protected]
PCI: Convert two sample drivers to new interface
eepro100 and ymfpci still work fine on my laptop after the change, even when zeroing out their BARs during boot.
---------------------------------------------------------------------------
drivers/net/eepro100.c +36 -47
157 lines not on this page · raw message
sound/oss/ymfpci.c +18 -27
99 lines not on this page · raw message
Quoted 4 lines · Patrick Mochel
Sorry about the delay. Could you please try this patch and let me know if it helps? It attempts to treat cardbus more like PCI, and let the PCI helpers do the probing.
Peter, can you just remove this patch from your kernel, I don't know how to fix it. It does something bad to all the resource allocations. The child resources don't find the parent any more, and you can see the result in /proc/iomem and /proc/ioport clearly. The cardbus devices are not seen as "children" of the cardbus controller any more from a resource standpoint.
So can you go back to the setup before applying this patch, and do a debugging run of that version instead?
Linus
Re: Cardbus
In reply to Linus TorvaldsQuoted 6 lines · Linus Torvalds
Quoted 4 lines · Paul Mackerras
IIRC someone told me that we had to do the "assuming transparent" bit because of buggy PCI-PCI bridges used on some PCs. Can anyone enlighten me on the details of that?
Quoted 6 lines
It has nothing to do with "buggy" PCI-PCI bridges, and everything to do with the fact that a lot of bridges seem to extend on the official PCI bridge interface in various ways. In particular, it seems to be fairly common to have the _real_ bridging information in the chip-specific range (PCI config area 0x40+) instead of in the official "2 mem resources, 2 IO resources" place.
As additional detail this works for the bridge manufactures because they can get the BIOS to do the hard work, and the os doesn't have to touch it. For any component that isn't designed to be part of a plug-in card, there isn't a compelling reason for the vendors to follow a standard interface for configuring it. Only the use case must follow a standard interface.
Eric
Quoted 13 lines · Linus Torvalds
Quoted 4 lines · Patrick Mochel
Sorry about the delay. Could you please try this patch and let me know if it helps? It attempts to treat cardbus more like PCI, and let the PCI helpers do the probing.
Peter, can you just remove this patch from your kernel, I don't know how to fix it. It does something bad to all the resource allocations. The child resources don't find the parent any more, and you can see the result in
/proc/iomemand/proc/ioportclearly. The cardbus devices are not seen as "children" of the cardbus controller any more from a resource standpoint.
Quoted 2 lines
So can you go back to the setup before applying this patch, and do a debugging run of that version instead?
Sure, with an unpatched 2.5.21 kernel, bringing up eth0 fails during boot. Tobias Diedrich posted a one-line patch that fixes this problem for me:
drivers/pcmcia/cardbus.c +1 -0
@@ -284,6 +284,7 @@ dev->dev.parent = bus->dev;strcpy (dev->dev.name, dev->name);strcpy (dev->dev.bus_id, dev->slot_name); + dev->dev.bus = &pci_bus_type;device_register (&dev->dev);/* FIXME: Do we need to enable the expansion ROM? */
But he said he didn't know if it was the right fix, and noone has commented on that yet.
All tests I have done so far with 2.5.21 based kernels produce an oops at shutdown, which makes the machine hang instead of rebooting or powering off. I'm not sure if it's related to cardbus devices though. It could also be caused by the broken cdrom drive in that machine.
Turning off swap:
Turning off quotas:
Unmounting file systems:
Unmounting proc file system:
Halting system...
flushing ide devices: hda <1>Unable to handle kernel NULL pointer dereference at
virtual address 00000004c017aed3
*pde = 00000000
Oops: 0002 CPU: 0 EIP: 0010:[<c017aed3>] Not tainted
Using defaults from ksymoops -t elf32-i386 -a i386
EFLAGS: 00010202
eax: c02c6d24 ebx: c3ad2000 ecx: 00000000 edx: 00000000
esi: c02c6d0c edi: c0262460 ebp: 00000000 esp: c3ad3e50
ds: 0018 es: 0018 ss: 0018
Stack: c02c6d0c c02c6bb4 00000001 c017b24d c02c6d0c c02c6bb0 c01b03dc c02c6d0c
c02c6bb0 c01a9af6 c02c6bb0 c0261f9c 00000000 00000003 bffffcc8 c011e27c
c0261f9c 00000003 00000000 00000001 c3ad2000 fee1dead c011e6ce c02a8b88
Call Trace: [<c017b24d>] [<c01b03dc>] [<c01a9af6>] [<c011e27c>] [<c011e6ce>]
[<c010fde9>] [<c011c810>] [<c011c8a7>] [<c011cc45>] [<c011d81d>] [<c01380ea>]
[<c0136bc0>] [<c0136c31>] [<c0106ee7>]
Code: 89 4a 04 89 11 89 46 18 89 40 04 8b 43 10 48 89 43 10 8b 43 Quoted 1 line
Quoted 1 line
EIP;
c017aed3<do_driver_detach+23/70> <=====
Trace; c017b24d <device_read_power+d/40>
Trace; c01b03dc <idedisk_ioctl+8c/300>
Trace; c01a9af6 <drive_is_flashcard+96/a0>
Trace; c011e27c <notifier_call_chain+1c/40>
Trace; c011e6ce <sys_reboot+17e/2a0>
Trace; c010fde9 <wake_up_process+9/10>
Trace; c011c810 <deliver_signal+50/60>
Trace; c011c8a7 <send_sig_info+87/b0>
Trace; c011cc45 <kill_something_info+165/190>
Trace; c011d81d <sys_kill+4d/60>
Trace; c01380ea <fput+ea/110>
Trace; c0136bc0 <filp_close+a0/b0>
Trace; c0136c31 <sys_close+61/90>
Trace; c0106ee7 <syscall_call+7/b>
Code; c017aed3 <do_driver_detach+23/70>
00000000 <_EIP>:
Code; c017aed3 <do_driver_detach+23/70> <=====
0: 89 4a 04 mov %ecx,0x4(%edx) <=====
Code; c017aed6 <do_driver_detach+26/70>
3: 89 11 mov %edx,(%ecx)
Code; c017aed8 <do_driver_detach+28/70>
5: 89 46 18 mov %eax,0x18(%esi)
Code; c017aedb <do_driver_detach+2b/70>
8: 89 40 04 mov %eax,0x4(%eax)
Code; c017aede <do_driver_detach+2e/70>
b: 8b 43 10 mov 0x10(%ebx),%eax
Code; c017aee1 <do_driver_detach+31/70>
e: 48 dec %eax
Code; c017aee2 <do_driver_detach+32/70>
f: 89 43 10 mov %eax,0x10(%ebx)
Code; c017aee5 <do_driver_detach+35/70>
12: 8b 43 00 mov 0x0(%ebx),%eax
Signature · 2 lines
Peter Osterlund - [email protected] http://w1.894.telia.com/~u89404340
Re: Cardbus
In reply to Linus TorvaldsQuoted 6 lines · Linus Torvalds
It has nothing to do with "buggy" PCI-PCI bridges, and everything to do with the fact that a lot of bridges seem to extend on the official PCI bridge interface in various ways. In particular, it seems to be fairly common to have the _real_ bridging information in the chip-specific range (PCI config area 0x40+) instead of in the official "2 mem resources, 2 IO resources" place.
OK, that makes sense. (The "buggy" wasn't intended as any kind of put-down, it was just what I had been told.)
What ends up in the official places? Zeroes, maybe?
Can we discriminate between these bridges, and bridges which use the official places but where the firmware has closed an aperture? I really would like the code not to assume the bridge is transparent in the latter case.
Paul.
Quoted 4 lines · Peter Osterlund
Sure, with an unpatched 2.5.21 kernel, bringing up eth0 fails during boot. Tobias Diedrich posted a one-line patch that fixes this problem for me:
Ok, that looks correct to me. Good.
Quoted 3 lines
All tests I have done so far with 2.5.21 based kernels produce an oops at shutdown, which makes the machine hang instead of rebooting or powering off.
This is an IDE one - the IDE driver puts a device that it never got.
I'll do a 2.5.22 (with Tobias' fix too).
Linus
Quoted 11 lines · Użytkownik Linus Torvalds
Quoted 3 lines · Peter Osterlund
Sure, with an unpatched 2.5.21 kernel, bringing up eth0 fails during boot. Tobias Diedrich posted a one-line patch that fixes this problem for me:
Ok, that looks correct to me. Good.
Quoted 6 lines
Quoted 3 lines
All tests I have done so far with 2.5.21 based kernels produce an oops at shutdown, which makes the machine hang instead of rebooting or powering off.
This is an IDE one - the IDE driver puts a device that it never got.
Adam J. Richter provided me already to "ture" sollution, which is moving the management of devices entierly away out from IDE code to the generic part. However I...
Quoted 1 line
I'll do a 2.5.22 (with Tobias' fix too).
... would be glad to release them based on 2.5.22, since this would avoid some work synchronization problems.