* 2.5.20 - Xircom PCI Cardbus doesn't work
@ 2002-06-03 11:07 Alessandro Suardi
2002-06-06 17:08 ` Peter Osterlund
0 siblings, 1 reply; 38+ messages in thread
From: Alessandro Suardi @ 2002-06-03 11:07 UTC (permalink / raw)
To: linux-kernel; +Cc: Peter Osterlund, mochel
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")
^ permalink raw reply [flat|nested] 38+ messages in thread* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-03 11:07 2.5.20 - Xircom PCI Cardbus doesn't work Alessandro Suardi @ 2002-06-06 17:08 ` Peter Osterlund 2002-06-09 9:17 ` Tobias Diedrich 0 siblings, 1 reply; 38+ messages in thread From: Peter Osterlund @ 2002-06-06 17:08 UTC (permalink / raw) To: Alessandro Suardi; +Cc: linux-kernel, Peter Osterlund, mochel Alessandro Suardi <alessandro.suardi@oracle.com> writes: > 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. -- Peter Osterlund - petero2@telia.com http://w1.894.telia.com/~u89404340 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-06 17:08 ` Peter Osterlund @ 2002-06-09 9:17 ` Tobias Diedrich 2002-06-09 10:55 ` Peter Osterlund 0 siblings, 1 reply; 38+ messages in thread From: Tobias Diedrich @ 2002-06-09 9:17 UTC (permalink / raw) To: Peter Osterlund; +Cc: Alessandro Suardi, linux-kernel, mochel Peter Osterlund wrote: > Alessandro Suardi <alessandro.suardi@oracle.com> writes: > > > 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: --- linux-2.5.20/drivers/pcmcia/cardbus.c Sat May 25 03:55:22 2002 +++ linux-2.5.20/drivers/pcmcia/cardbus.c Sun Jun 9 02:27:35 2002 @@ -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? */ -- Tobias PGP: 0x9AC7E0BC ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-09 9:17 ` Tobias Diedrich @ 2002-06-09 10:55 ` Peter Osterlund 2002-06-10 15:44 ` Patrick Mochel 0 siblings, 1 reply; 38+ messages in thread From: Peter Osterlund @ 2002-06-09 10:55 UTC (permalink / raw) To: Tobias Diedrich; +Cc: Alessandro Suardi, linux-kernel, mochel Tobias Diedrich <ranma@gmx.at> writes: > Peter Osterlund wrote: > > Alessandro Suardi <alessandro.suardi@oracle.com> writes: > > > > > 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 >>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 -- Peter Osterlund - petero2@telia.com http://w1.894.telia.com/~u89404340 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-09 10:55 ` Peter Osterlund @ 2002-06-10 15:44 ` Patrick Mochel 2002-06-10 19:28 ` Peter Osterlund ` (2 more replies) 0 siblings, 3 replies; 38+ messages in thread From: Patrick Mochel @ 2002-06-10 15:44 UTC (permalink / raw) To: Peter Osterlund Cc: Tobias Diedrich, Alessandro Suardi, linux-kernel, torvalds On 9 Jun 2002, Peter Osterlund wrote: > Tobias Diedrich <ranma@gmx.at> writes: > > > Peter Osterlund wrote: > > > Alessandro Suardi <alessandro.suardi@oracle.com> writes: > > > > > > > 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: 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 ChangeSet@1.494, 2002-06-10 08:35:32-07:00, mochel@osdl.org 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 diff -Nru a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c --- a/drivers/pci/hotplug.c Mon Jun 10 08:42:14 2002 +++ b/drivers/pci/hotplug.c Mon Jun 10 08:42:14 2002 @@ -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 diff -Nru a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c --- a/drivers/pcmcia/cardbus.c Mon Jun 10 08:42:14 2002 +++ b/drivers/pcmcia/cardbus.c Mon Jun 10 08:42:14 2002 @@ -178,16 +178,21 @@ void read_cb_mem(socket_info_t * s, u_char fn, int space, u_int addr, u_int len, void *ptr) { - struct pci_dev *dev; + struct pci_dev *dev = NULL; struct resource *res; + list_t * node; DEBUG(3, "cs: read_cb_mem(%d, %#x, %u)\n", space, addr, len); - if (!s->cb_config) + list_for_each(node,&s->cap.cb_dev->subordinate->devices) { + dev = list_entry(node,struct pci_dev,bus_list); + if (PCI_FUNC(dev->devfn) == fn) + break; + dev = NULL; + } + if (!dev) goto fail; - dev = &s->cb_config[fn].dev; - /* Config space? */ if (space == 0) { if (addr + len > 0x100) @@ -233,10 +238,10 @@ { struct pci_bus *bus; struct pci_dev tmp; - u_short vend, v, dev; - u_char i, hdr, fn; - cb_config_t *c; + u16 vend, dev; int irq; + list_t * node; + struct pci_dev * pdev; bus = s->cap.cb_dev->subordinate; memset(&tmp, 0, sizeof(tmp)); @@ -249,80 +254,43 @@ printk(KERN_INFO "cs: cb_alloc(bus %d): vendor 0x%04x, " "device 0x%04x\n", bus->number, vend, dev); - pci_readb(&tmp, PCI_HEADER_TYPE, &hdr); - fn = 1; - if (hdr & 0x80) { - do { - tmp.devfn = fn; - if (pci_readw(&tmp, PCI_VENDOR_ID, &v) || !v || v == 0xffff) - break; - fn++; - } while (fn < 8); - } - s->functions = fn; - - c = kmalloc(fn * sizeof(struct cb_config_t), GFP_ATOMIC); - if (!c) - return CS_OUT_OF_RESOURCE; - memset(c, 0, fn * sizeof(struct cb_config_t)); + /* let generic PCI code scan bus */ + pci_do_scan_bus(bus); + /* walk the bus again and set the irq for the devices, + * enable each one, and let userspace know (pci_insert_device) + */ irq = s->cap.pci_irq; - for (i = 0; i < fn; i++) { - struct pci_dev *dev = &c[i].dev; + list_for_each(node,&bus->devices) { u8 irq_pin; - int r; - - dev->bus = bus; - dev->sysdata = bus->sysdata; - dev->devfn = i; - dev->vendor = vend; - pci_readw(dev, PCI_DEVICE_ID, &dev->device); - dev->hdr_type = hdr & 0x7f; - - pci_setup_device(dev); - - dev->dev.parent = bus->dev; - strcpy(dev->dev.name, dev->name); - strcpy(dev->dev.bus_id, dev->slot_name); - device_register(&dev->dev); - - /* 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); - } + pdev = list_entry(node,struct pci_dev, bus_list); /* Does this function have an interrupt at all? */ - pci_readb(dev, PCI_INTERRUPT_PIN, &irq_pin); + pci_readb(pdev, PCI_INTERRUPT_PIN, &irq_pin); if (irq_pin) { - dev->irq = irq; - pci_writeb(dev, PCI_INTERRUPT_LINE, irq); + pdev->irq = irq; + pci_writeb(pdev, PCI_INTERRUPT_LINE, irq); } - - pci_enable_device(dev); /* XXX check return */ - pci_insert_device(dev, bus); + pci_enable_device(pdev); + pci_insert_device(pdev,bus); } - - s->cb_config = c; s->irq.AssignedIRQ = irq; return CS_SUCCESS; } void cb_free(socket_info_t * s) { - cb_config_t *c = s->cb_config; - - if (c) { - int i; + struct pci_bus * bus = s->cap.cb_dev->subordinate; + list_t * node = bus->devices.next; - s->cb_config = NULL; - for (i = 0 ; i < s->functions ; i++) - pci_remove_device(&c[i].dev); - kfree(c); - printk(KERN_INFO "cs: cb_free(bus %d)\n", s->cap.cb_dev->subordinate->number); + while(node != &bus->devices) { + struct pci_dev * pdev = list_entry(node,struct pci_dev,bus_list); + pci_remove_device(pdev); + node = bus->devices.next; } + + printk(KERN_INFO "cs: cb_free(bus %d)\n", bus->number); } /*===================================================================== @@ -374,27 +342,25 @@ void cb_enable(socket_info_t * s) { - struct pci_dev *dev; - u_char i; + list_t * node; + struct pci_bus * bus = s->cap.cb_dev->subordinate; - DEBUG(0, "cs: cb_enable(bus %d)\n", s->cap.cb_dev->subordinate->number); + DEBUG(0, "cs: cb_enable(bus %d)\n", bus->number); /* Configure bridge */ cb_release_cis_mem(s); /* Set up PCI interrupt and command registers */ - for (i = 0; i < s->functions; i++) { - dev = &s->cb_config[i].dev; + list_for_each(node,&bus->devices) { + struct pci_dev * dev = list_entry(node,struct pci_dev,bus_list); pci_writeb(dev, PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY); pci_writeb(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4); - } - if (s->irq.AssignedIRQ) { - for (i = 0; i < s->functions; i++) { - dev = &s->cb_config[i].dev; + if (s->irq.AssignedIRQ) pci_writeb(dev, PCI_INTERRUPT_LINE, s->irq.AssignedIRQ); - } + } + if (s->irq.AssignedIRQ) { s->socket.io_irq = s->irq.AssignedIRQ; s->ss_entry->set_socket(s->sock, &s->socket); } ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-10 15:44 ` Patrick Mochel @ 2002-06-10 19:28 ` Peter Osterlund 2002-06-14 16:33 ` Linus Torvalds 2002-06-10 20:59 ` 2.5.20 - Xircom PCI Cardbus doesn't work Alessandro Suardi 2002-06-16 4:57 ` Linus Torvalds 2 siblings, 1 reply; 38+ messages in thread From: Peter Osterlund @ 2002-06-10 19:28 UTC (permalink / raw) To: Patrick Mochel; +Cc: Tobias Diedrich, Alessandro Suardi, linux-kernel, torvalds Patrick Mochel <mochel@osdl.org> writes: > On 9 Jun 2002, Peter Osterlund wrote: > > > Tobias Diedrich <ranma@gmx.at> writes: > > > > > Peter Osterlund wrote: > > > > Alessandro Suardi <alessandro.suardi@oracle.com> writes: > > > > > > > > > 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: > > > > 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. > 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 usbfs usb.c: registered new driver hub usb-uhci-hcd.c: High bandwidth mode enabled. PCI: Assigned IRQ 10 for device 00:07.2 hcd-pci.c: usb-uhci-hcd @ 00:07.2, Intel Corp. 82371AB PIIX4 USB hcd-pci.c: irq 10, io base 0000f300 hcd.c: new USB bus registered, assigned bus number 1 ... -- Peter Osterlund - petero2@telia.com http://w1.894.telia.com/~u89404340 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-10 19:28 ` Peter Osterlund @ 2002-06-14 16:33 ` Linus Torvalds 2002-06-14 17:20 ` Peter Osterlund 0 siblings, 1 reply; 38+ messages in thread From: Linus Torvalds @ 2002-06-14 16:33 UTC (permalink / raw) To: Peter Osterlund Cc: Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel On 10 Jun 2002, Peter Osterlund wrote: > > 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 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-14 16:33 ` Linus Torvalds @ 2002-06-14 17:20 ` Peter Osterlund 2002-06-14 17:47 ` Linus Torvalds 0 siblings, 1 reply; 38+ messages in thread From: Peter Osterlund @ 2002-06-14 17:20 UTC (permalink / raw) To: Linus Torvalds Cc: Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel Linus Torvalds <torvalds@transmeta.com> writes: > On 10 Jun 2002, Peter Osterlund wrote: > > > > 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 (petero@p4.localdomain) (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 -- Peter Osterlund - petero2@telia.com http://w1.894.telia.com/~u89404340 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-14 17:20 ` Peter Osterlund @ 2002-06-14 17:47 ` Linus Torvalds 2002-06-14 17:53 ` Vojtech Pavlik 2002-06-14 18:30 ` Peter Osterlund 0 siblings, 2 replies; 38+ messages in thread From: Linus Torvalds @ 2002-06-14 17:47 UTC (permalink / raw) To: Peter Osterlund Cc: Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel On 14 Jun 2002, Peter Osterlund wrote: > > cs: cb_alloc(bus 1): vendor 0x13d1, device 0xab02 > Scanning 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. > 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 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 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-14 17:47 ` Linus Torvalds @ 2002-06-14 17:53 ` Vojtech Pavlik 2002-06-14 18:05 ` Linus Torvalds 2002-06-14 18:30 ` Peter Osterlund 1 sibling, 1 reply; 38+ messages in thread From: Vojtech Pavlik @ 2002-06-14 17:53 UTC (permalink / raw) To: Linus Torvalds Cc: Peter Osterlund, Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel On Fri, Jun 14, 2002 at 10:47:20AM -0700, Linus Torvalds wrote: > > > On 14 Jun 2002, Peter Osterlund wrote: > > > > cs: cb_alloc(bus 1): vendor 0x13d1, device 0xab02 > > Scanning 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. > > > 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 > > 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. 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 ... > 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 majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ -- Vojtech Pavlik SuSE Labs ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-14 17:53 ` Vojtech Pavlik @ 2002-06-14 18:05 ` Linus Torvalds 2002-06-14 18:12 ` Kai Germaschewski 2002-06-14 19:34 ` Jeff Garzik 0 siblings, 2 replies; 38+ messages in thread From: Linus Torvalds @ 2002-06-14 18:05 UTC (permalink / raw) To: Vojtech Pavlik Cc: Peter Osterlund, Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel On Fri, 14 Jun 2002, Vojtech Pavlik wrote: > > 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 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-14 18:05 ` Linus Torvalds @ 2002-06-14 18:12 ` Kai Germaschewski 2002-06-14 18:18 ` Linus Torvalds 2002-06-14 19:31 ` Jeff Garzik 2002-06-14 19:34 ` Jeff Garzik 1 sibling, 2 replies; 38+ messages in thread From: Kai Germaschewski @ 2002-06-14 18:12 UTC (permalink / raw) To: Linus Torvalds Cc: Vojtech Pavlik, Peter Osterlund, Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel On Fri, 14 Jun 2002, Linus Torvalds wrote: > 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 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-14 18:12 ` Kai Germaschewski @ 2002-06-14 18:18 ` Linus Torvalds 2002-06-14 19:37 ` Jeff Garzik 2002-06-14 19:31 ` Jeff Garzik 1 sibling, 1 reply; 38+ messages in thread From: Linus Torvalds @ 2002-06-14 18:18 UTC (permalink / raw) To: Kai Germaschewski Cc: Vojtech Pavlik, Peter Osterlund, Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel On Fri, 14 Jun 2002, Kai Germaschewski wrote: > > 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 ;) 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 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-14 18:18 ` Linus Torvalds @ 2002-06-14 19:37 ` Jeff Garzik 2002-06-15 18:48 ` Linus Torvalds 0 siblings, 1 reply; 38+ messages in thread From: Jeff Garzik @ 2002-06-14 19:37 UTC (permalink / raw) To: Linus Torvalds Cc: Kai Germaschewski, Vojtech Pavlik, Peter Osterlund, Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel Linus Torvalds wrote: > > On Fri, 14 Jun 2002, Kai Germaschewski wrote: > >>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 ;) > > > 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). 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 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-14 19:37 ` Jeff Garzik @ 2002-06-15 18:48 ` Linus Torvalds 2002-06-15 19:05 ` Linus Torvalds 2002-06-15 20:07 ` Jeff Garzik 0 siblings, 2 replies; 38+ messages in thread From: Linus Torvalds @ 2002-06-15 18:48 UTC (permalink / raw) To: Jeff Garzik Cc: Kai Germaschewski, Vojtech Pavlik, Peter Osterlund, Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel On Fri, 14 Jun 2002, Jeff Garzik wrote: > > 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 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. > The only thing I've wanted is a cross-platform way to detect if > pdev->irq returned by pci_enable_device is 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 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-15 18:48 ` Linus Torvalds @ 2002-06-15 19:05 ` Linus Torvalds 2002-06-15 19:39 ` Kai Germaschewski 2002-06-15 20:07 ` Jeff Garzik 1 sibling, 1 reply; 38+ messages in thread From: Linus Torvalds @ 2002-06-15 19:05 UTC (permalink / raw) To: Jeff Garzik Cc: Kai Germaschewski, Vojtech Pavlik, Peter Osterlund, Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel On Sat, 15 Jun 2002, Linus Torvalds wrote: > > 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 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-15 19:05 ` Linus Torvalds @ 2002-06-15 19:39 ` Kai Germaschewski 2002-06-15 19:58 ` Jeff Garzik 0 siblings, 1 reply; 38+ messages in thread From: Kai Germaschewski @ 2002-06-15 19:39 UTC (permalink / raw) To: Linus Torvalds Cc: Jeff Garzik, Vojtech Pavlik, Peter Osterlund, Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel On Sat, 15 Jun 2002, Linus Torvalds wrote: > On Sat, 15 Jun 2002, Linus Torvalds wrote: > > > > 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. 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 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-15 19:39 ` Kai Germaschewski @ 2002-06-15 19:58 ` Jeff Garzik 2002-06-15 23:00 ` Kai Germaschewski 0 siblings, 1 reply; 38+ messages in thread From: Jeff Garzik @ 2002-06-15 19:58 UTC (permalink / raw) To: Kai Germaschewski Cc: Linus Torvalds, Vojtech Pavlik, Peter Osterlund, Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel Kai Germaschewski wrote: > 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. > 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 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-15 19:58 ` Jeff Garzik @ 2002-06-15 23:00 ` Kai Germaschewski 0 siblings, 0 replies; 38+ messages in thread From: Kai Germaschewski @ 2002-06-15 23:00 UTC (permalink / raw) To: Jeff Garzik Cc: Linus Torvalds, Vojtech Pavlik, Peter Osterlund, Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel On Sat, 15 Jun 2002, Jeff Garzik wrote: > > 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) 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) ----------------------------------------------------------------------------- ChangeSet@1.491, 2002-06-15 14:04:46-05:00, kai@tp1.ruhr-uni-bochum.de 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(-) ----------------------------------------------------------------------------- ChangeSet@1.492, 2002-06-15 15:19:22-05:00, kai@tp1.ruhr-uni-bochum.de 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(-) ----------------------------------------------------------------------------- ChangeSet@1.493, 2002-06-15 16:35:23-05:00, kai@tp1.ruhr-uni-bochum.de 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(-) ----------------------------------------------------------------------------- ChangeSet@1.494, 2002-06-15 16:38:20-05:00, kai@tp1.ruhr-uni-bochum.de 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(-) ----------------------------------------------------------------------------- ChangeSet@1.495, 2002-06-15 17:23:10-05:00, kai@tp1.ruhr-uni-bochum.de 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(+) ----------------------------------------------------------------------------- ChangeSet@1.496, 2002-06-15 17:31:38-05:00, kai@tp1.ruhr-uni-bochum.de 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 ============================================================================= ----------------------------------------------------------------------------- ChangeSet@1.491, 2002-06-15 14:04:46-05:00, kai@tp1.ruhr-uni-bochum.de 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. --------------------------------------------------------------------------- diff -Nru a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c --- a/drivers/pci/pci-driver.c Sat Jun 15 17:59:18 2002 +++ b/drivers/pci/pci-driver.c Sat Jun 15 17:59:18 2002 @@ -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; } ----------------------------------------------------------------------------- ChangeSet@1.492, 2002-06-15 15:19:22-05:00, kai@tp1.ruhr-uni-bochum.de 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. --------------------------------------------------------------------------- diff -Nru a/arch/i386/pci/acpi.c b/arch/i386/pci/acpi.c --- a/arch/i386/pci/acpi.c Sat Jun 15 17:59:19 2002 +++ b/arch/i386/pci/acpi.c Sat Jun 15 17:59:19 2002 @@ -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"); diff -Nru a/arch/i386/pci/common.c b/arch/i386/pci/common.c --- a/arch/i386/pci/common.c Sat Jun 15 17:59:19 2002 +++ b/arch/i386/pci/common.c Sat Jun 15 17:59:19 2002 @@ -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; } diff -Nru a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c --- a/arch/i386/pci/irq.c Sat Jun 15 17:59:19 2002 +++ b/arch/i386/pci/irq.c Sat Jun 15 17:59:19 2002 @@ -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); diff -Nru a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h --- a/arch/i386/pci/pci.h Sat Jun 15 17:59:19 2002 +++ b/arch/i386/pci/pci.h Sat Jun 15 17:59:19 2002 @@ -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); diff -Nru a/arch/x86_64/pci/acpi.c b/arch/x86_64/pci/acpi.c --- a/arch/x86_64/pci/acpi.c Sat Jun 15 17:59:19 2002 +++ b/arch/x86_64/pci/acpi.c Sat Jun 15 17:59:19 2002 @@ -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"); diff -Nru a/arch/x86_64/pci/common.c b/arch/x86_64/pci/common.c --- a/arch/x86_64/pci/common.c Sat Jun 15 17:59:19 2002 +++ b/arch/x86_64/pci/common.c Sat Jun 15 17:59:19 2002 @@ -194,3 +194,8 @@ return pcibios_enable_irq(dev); } + +int pcibios_enable_irq(struct pci_dev *dev) +{ + return pcibios_enable_irq_func(dev); +} diff -Nru a/arch/x86_64/pci/irq.c b/arch/x86_64/pci/irq.c --- a/arch/x86_64/pci/irq.c Sat Jun 15 17:59:19 2002 +++ b/arch/x86_64/pci/irq.c Sat Jun 15 17:59:19 2002 @@ -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); diff -Nru a/arch/x86_64/pci/pci.h b/arch/x86_64/pci/pci.h --- a/arch/x86_64/pci/pci.h Sat Jun 15 17:59:19 2002 +++ b/arch/x86_64/pci/pci.h Sat Jun 15 17:59:19 2002 @@ -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); diff -Nru a/drivers/pci/pci.c b/drivers/pci/pci.c --- a/drivers/pci/pci.c Sat Jun 15 17:59:19 2002 +++ b/drivers/pci/pci.c Sat Jun 15 17:59:19 2002 @@ -555,6 +555,56 @@ return 0; } +/** + * pci_assign_irq - Assign an IRQ to a PCI device + * @dev: PCI device + * + * Figure out the the routing from the IRQ pin to an actual IRQ + * vector on the processor. + * Make sure the device is in D0 state (woken up). + * Returns an IRQ number (only supposed to be use for printk() or + * similar), or a negative error code. + */ +int +pci_assign_irq(struct pci_dev *dev) +{ + int retval; + + pci_set_power_state(dev, 0); + + retval = pcibios_assign_irq(dev); + if (retval < 0) + return retval; + + return dev->irq; +} + +/** + * pci_enable_irq - Enable an IRQ on a PCI device + * @dev: PCI device + * + * Route an IRQ pin to an actual IRQ vector on the processor. + * Make sure the device is in D0 state (woken up). + * Returns an IRQ number (only supposed to be use for printk() or + * similar), or a negative error code. + */ +int +pci_enable_irq(struct pci_dev *dev) +{ + int retval; + + retval = pci_assign_irq(dev); + if (retval < 0) + return retval; + + retval = pcibios_enable_irq(dev); + if (retval < 0) + return retval; + + return dev->irq; +} + + static int __devinit pci_init(void) { struct pci_dev *dev; diff -Nru a/include/linux/pci.h b/include/linux/pci.h --- a/include/linux/pci.h Sat Jun 15 17:59:19 2002 +++ b/include/linux/pci.h Sat Jun 15 17:59:19 2002 @@ -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 */ ----------------------------------------------------------------------------- ChangeSet@1.493, 2002-06-15 16:35:23-05:00, kai@tp1.ruhr-uni-bochum.de 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. --------------------------------------------------------------------------- diff -Nru a/drivers/pci/pci.c b/drivers/pci/pci.c --- a/drivers/pci/pci.c Sat Jun 15 17:59:20 2002 +++ b/drivers/pci/pci.c Sat Jun 15 17:59:20 2002 @@ -239,6 +239,34 @@ return 0; } +static void +pci_set_command(struct pci_dev *dev, u16 mask) +{ + u16 cmd; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + + if ((cmd | mask) != cmd) { + printk(KERN_DEBUG "PCI: Enabling device %s (%04x -> %04x)\n", + dev->slot_name, cmd, cmd | mask); + pci_write_config_word(dev, PCI_COMMAND, cmd | mask); + } +} + +static void +pci_clear_command(struct pci_dev *dev, u16 mask) +{ + u16 cmd; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + + if ((cmd & ~mask) != cmd) { + printk(KERN_DEBUG "PCI: Disabling device %s (%04x -> %04x)\n", + dev->slot_name, cmd, cmd & ~mask); + pci_write_config_word(dev, PCI_COMMAND, cmd & ~mask); + } +} + /** * pci_enable_device - Initialize device before it's used by a driver. * @dev: PCI device to be initialized @@ -268,13 +296,7 @@ void pci_disable_device(struct pci_dev *dev) { - u16 pci_command; - - pci_read_config_word(dev, PCI_COMMAND, &pci_command); - if (pci_command & PCI_COMMAND_MASTER) { - pci_command &= ~PCI_COMMAND_MASTER; - pci_write_config_word(dev, PCI_COMMAND, pci_command); - } + pci_clear_command(dev, PCI_COMMAND_MASTER); } /** @@ -426,14 +448,7 @@ void pci_set_master(struct pci_dev *dev) { - u16 cmd; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - if (! (cmd & PCI_COMMAND_MASTER)) { - DBG("PCI: Enabling bus mastering for device %s\n", dev->slot_name); - cmd |= PCI_COMMAND_MASTER; - pci_write_config_word(dev, PCI_COMMAND, cmd); - } + pci_set_command(dev, PCI_COMMAND_MASTER); pcibios_set_master(dev); } @@ -494,7 +509,6 @@ pci_set_mwi(struct pci_dev *dev) { int rc; - u16 cmd; #ifdef HAVE_ARCH_PCI_MWI rc = pcibios_prep_mwi(dev); @@ -505,12 +519,7 @@ if (rc) return rc; - pci_read_config_word(dev, PCI_COMMAND, &cmd); - if (! (cmd & PCI_COMMAND_INVALIDATE)) { - DBG("PCI: Enabling Mem-Wr-Inval for device %s\n", dev->slot_name); - cmd |= PCI_COMMAND_INVALIDATE; - pci_write_config_word(dev, PCI_COMMAND, cmd); - } + pci_set_command(dev, PCI_COMMAND_INVALIDATE); return 0; } @@ -524,13 +533,7 @@ void pci_clear_mwi(struct pci_dev *dev) { - u16 cmd; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - if (cmd & PCI_COMMAND_INVALIDATE) { - cmd &= ~PCI_COMMAND_INVALIDATE; - pci_write_config_word(dev, PCI_COMMAND, cmd); - } + pci_clear_command(dev, PCI_COMMAND_INVALIDATE); } int ----------------------------------------------------------------------------- ChangeSet@1.494, 2002-06-15 16:38:20-05:00, kai@tp1.ruhr-uni-bochum.de 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... --------------------------------------------------------------------------- diff -Nru a/drivers/pci/pci.c b/drivers/pci/pci.c --- a/drivers/pci/pci.c Sat Jun 15 17:59:22 2002 +++ b/drivers/pci/pci.c Sat Jun 15 17:59:22 2002 @@ -280,6 +280,13 @@ { int err; + /* FIXME: this should be turned into + * pci_enable_irq(dev); + * pci_enable_mmio(dev); + * pci_enable_io(dev); + * after splitting the per arch pcibios_enable_device() + * into the appropriate parts + */ pci_set_power_state(dev, 0); if ((err = pcibios_enable_device(dev)) < 0) return err; @@ -562,9 +569,9 @@ * pci_assign_irq - Assign an IRQ to a PCI device * @dev: PCI device * + * Make sure the device is in D0 state (woken up). * Figure out the the routing from the IRQ pin to an actual IRQ * vector on the processor. - * Make sure the device is in D0 state (woken up). * Returns an IRQ number (only supposed to be use for printk() or * similar), or a negative error code. */ @@ -586,8 +593,8 @@ * pci_enable_irq - Enable an IRQ on a PCI device * @dev: PCI device * - * Route an IRQ pin to an actual IRQ vector on the processor. * Make sure the device is in D0 state (woken up). + * Route an IRQ pin to an actual IRQ vector on the processor. * Returns an IRQ number (only supposed to be use for printk() or * similar), or a negative error code. */ @@ -607,6 +614,111 @@ return dev->irq; } +static int +pci_assign_resources(struct pci_dev *dev, unsigned long flags) +{ + int nr, retval = 0; + struct resource *r; + + pci_set_power_state(dev, 0); + + for (nr = 0; nr < PCI_ROM_RESOURCE; nr++) { + r = &dev->resource[nr]; + + /* Skip if other type */ + if ((r->flags ^ flags) & (IORESOURCE_IO | IORESOURCE_MEM)) + continue; + + /* If unassigned, try to assign */ + if (!r->start && r->end) { + retval = pci_assign_resource(dev, nr); + if (retval < 0) + break; + } + } + return retval; +} + +/** + * pci_assign_mmio - Assign MMIO resources on a PCI device + * @dev: PCI device + * + * Make sure the device is in D0 state (woken up). + * Assign all as of yet unassigned MMIO resources for + * the PCI device. + * Returns 0 on success, or a negative error code. + */ +int +pci_assign_mmio(struct pci_dev *dev) +{ + return pci_assign_resources(dev, IORESOURCE_MEM); +} + +/** + * pci_assign_io - Assign IO resources on a PCI device + * @dev: PCI device + * + * Make sure the device is in D0 state (woken up). + * Assign all as of yet unassigned IO resources for + * the PCI device. + * Returns 0 on success, or a negative error code. + */ +int +pci_assign_io(struct pci_dev *dev) +{ + return pci_assign_resources(dev, IORESOURCE_IO); +} + +static int +pci_enable_resources(struct pci_dev *dev, unsigned long flags) +{ + int retval; + + retval = pci_assign_resources(dev, flags); + if (retval < 0) + return retval; + + if (flags & IORESOURCE_IO) + pci_set_command(dev, PCI_COMMAND_IO); + if (flags & IORESOURCE_MEM) + pci_set_command(dev, PCI_COMMAND_MEMORY); + + return 0; +} + +/** + * pci_enable_mmio - Enable IO resources on a PCI device + * @dev: PCI device + * + * Make sure the device is in D0 state (woken up). + * Assign all as of yet unassigned IO resources for + * the PCI device. + * Enable MMIO in the PCI COMMAND config word + * Returns 0 on success, or a negative error code. + */ +int +pci_enable_mmio(struct pci_dev *dev) +{ + return pci_enable_resources(dev, IORESOURCE_MEM); +} + +/** + * pci_enable_io - Enable IO resources on a PCI device + * @dev: PCI device + * + * Make sure the device is in D0 state (woken up). + * Assign all as of yet unassigned IO resources for + * the PCI device. + * Enable IO in the PCI COMMAND config word + * Returns 0 on success, or a negative error code. + */ +int +pci_enable_io(struct pci_dev *dev) +{ + return pci_enable_resources(dev, IORESOURCE_IO); +} + + static int __devinit pci_init(void) { @@ -654,6 +766,13 @@ EXPORT_SYMBOL(pci_save_state); EXPORT_SYMBOL(pci_restore_state); EXPORT_SYMBOL(pci_enable_wake); + +EXPORT_SYMBOL(pci_assign_irq); +EXPORT_SYMBOL(pci_assign_mmio); +EXPORT_SYMBOL(pci_assign_io); +EXPORT_SYMBOL(pci_enable_irq); +EXPORT_SYMBOL(pci_enable_mmio); +EXPORT_SYMBOL(pci_enable_io); /* Obsolete functions */ diff -Nru a/include/linux/pci.h b/include/linux/pci.h --- a/include/linux/pci.h Sat Jun 15 17:59:22 2002 +++ b/include/linux/pci.h Sat Jun 15 17:59:22 2002 @@ -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); ----------------------------------------------------------------------------- ChangeSet@1.495, 2002-06-15 17:23:10-05:00, kai@tp1.ruhr-uni-bochum.de 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). --------------------------------------------------------------------------- diff -Nru a/drivers/pci/pci.c b/drivers/pci/pci.c --- a/drivers/pci/pci.c Sat Jun 15 17:59:23 2002 +++ b/drivers/pci/pci.c Sat Jun 15 17:59:23 2002 @@ -614,6 +614,57 @@ return dev->irq; } +/** + * pci_request_irq - Register an interrupt handler for a PCI device + * @dev: PCI device + * @handler: Function to be called when the IRQ occurs + * @irqflags: Interrupt type flags + * @dev_id: A cookie passed back to the handler function + * + * Make sure the device is in D0 state (woken up). + * Route an IRQ pin to an actual IRQ vector on the processor. + * Register a handler for this IRQ vector. + * Returns an IRQ number (only supposed to be use for printk() or + * similar), or a negative error code. + */ +int +pci_request_irq(struct pci_dev *dev, + void (*handler)(int, void *, struct pt_regs *), + unsigned long flags, void *dev_id) +{ + int retval; + + BUG_ON(!(flags & SA_SHIRQ)); + + retval = pcibios_assign_irq(dev); + if (retval < 0) + return retval; + + retval = request_irq(dev->irq, handler, flags, dev->slot_name, dev_id); + if (retval < 0) + return retval; + + retval = pcibios_enable_irq(dev); + if (retval < 0) + free_irq(dev->irq, dev_id); + + return retval; +} + +/** + * pci_release_irq - Unregister an interrupt handler for a PCI device + * @dev: PCI device + * @dev_id: Same cookie you passed when calling pci_request_irq() + * + * Unregister an IRQ handler previously registered with + * pci_request_irq(). + */ +void +pci_release_irq(struct pci_dev *dev, void *dev_id) +{ + free_irq(dev->irq, dev_id); +} + static int pci_assign_resources(struct pci_dev *dev, unsigned long flags) { @@ -718,7 +769,136 @@ return pci_enable_resources(dev, IORESOURCE_IO); } +static unsigned long +pci_request_resources(struct pci_dev *pdev, unsigned int nr, + unsigned long flags, struct resource *root) +{ + struct pci_driver *drv = pci_dev_driver(pdev); + char *drv_name = drv ? drv->name : "unknown"; + struct resource *res; + + BUG_ON(nr >= PCI_ROM_RESOURCE); + + /* Make sure we have the right type (IO/MMIO) */ + if ((pci_resource_flags(pdev, nr) ^ flags) & + (IORESOURCE_IO | IORESOURCE_MEM)) + goto err; + + /* Assign and enable all resources of this type */ + pci_enable_resources(pdev, flags); + + res = __request_region(root, pci_resource_start(pdev, nr), + pci_resource_len(pdev, nr), drv_name); + if (!res) + goto err; + + return res->start; + + err: + /* Print extensive info so that drivers don't have to do it + themselves */ + printk(KERN_INFO + "%s: failed to get %s(%d) for %s, %#lx-%#lx flags %#lx.\n", + pdev->slot_name, (flags == IORESOURCE_IO ? "IO" : "MMIO"), + nr, drv_name, + pci_resource_start(pdev, nr), + pci_resource_flags(pdev, nr), + pci_resource_end(pdev, nr)); + return 0; +} + +/** + * pci_request_mmio - Register a MMIO region on a PCI device + * @dev: PCI device + * @nr: The index of the Base Address Register (BAR) + * + * Make sure the device is in D0 state (woken up). + * Assign all as of yet unassigned MMIO resources for + * the PCI device. + * Enable MMIO in the PCI COMMAND config word + * Register the requested MMIO region with the kernel + * resource management. + * Map the MMIO region. + * Returns a cookie to be used with the MMIO functions + * (readb, writeb, ...), or NULL on error. + * In case of failure it also printk's extensive information + * about what went wrong (so you don't need to do that in your + * driver) + */ +void * +pci_request_mmio(struct pci_dev *pdev, unsigned int nr) +{ + unsigned long base; + void *addr; + + base = pci_request_resources(pdev, nr, IORESOURCE_MEM, &iomem_resource); + if (!base) + return 0; + + addr = ioremap(base, pci_resource_len(pdev, nr)); + if (!addr) + release_region(base, pci_resource_len(pdev, nr)); + + return addr; +} + +/** + * pci_request_io - Register an IO region on a PCI device + * @dev: PCI device + * @nr: The index of the Base Address Register (BAR) + * + * Make sure the device is in D0 state (woken up). + * Assign all as of yet unassigned IO resources for + * the PCI device. + * Enable IO in the PCI COMMAND config word + * Register the requested IO region with the kernel + * resource management. + * Returns an IO port to be used with the IO functions + * (inb, outb, ...), or 0 on error. + * In case of failure it also printk's extensive information + * about what went wrong (so you don't need to do that in your + * driver) + */ +unsigned long +pci_request_io(struct pci_dev *dev, unsigned int nr) +{ + return pci_request_resources(dev, nr, IORESOURCE_IO, &ioport_resource); +} + +/** + * pci_release_mmio - Release an MMIO region on a PCI device + * @dev: PCI device + * @nr: The index of the Base Address Register (BAR) + * @addr: The cookie returned from pci_request_mmio() + * + * Unmaps and unregisters a MMIO region previously + * registered by pci_request_mmio(). + */ +void +pci_release_mmio(struct pci_dev *dev, unsigned int nr, void *addr) +{ + iounmap(addr); + __release_region(&iomem_resource, + pci_resource_start(dev, nr), + pci_resource_len(dev, nr)); +} + +/** + * pci_release_io - Release an IO region on a PCI device + * @dev: PCI device + * @nr: The index of the Base Address Register (BAR) + * + * Unregisters an IO region previously registered by + * pci_request_io(). + */ +void +pci_release_io(struct pci_dev *dev, unsigned int nr) +{ + __release_region(&ioport_resource, + pci_resource_start(dev, nr), + pci_resource_len(dev, nr)); +} static int __devinit pci_init(void) { @@ -766,6 +946,13 @@ EXPORT_SYMBOL(pci_save_state); EXPORT_SYMBOL(pci_restore_state); EXPORT_SYMBOL(pci_enable_wake); + +EXPORT_SYMBOL(pci_request_irq); +EXPORT_SYMBOL(pci_request_mmio); +EXPORT_SYMBOL(pci_request_io); +EXPORT_SYMBOL(pci_release_irq); +EXPORT_SYMBOL(pci_release_mmio); +EXPORT_SYMBOL(pci_release_io); EXPORT_SYMBOL(pci_assign_irq); EXPORT_SYMBOL(pci_assign_mmio); diff -Nru a/include/linux/pci.h b/include/linux/pci.h --- a/include/linux/pci.h Sat Jun 15 17:59:23 2002 +++ b/include/linux/pci.h Sat Jun 15 17:59:23 2002 @@ -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); ----------------------------------------------------------------------------- ChangeSet@1.496, 2002-06-15 17:31:38-05:00, kai@tp1.ruhr-uni-bochum.de 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. --------------------------------------------------------------------------- diff -Nru a/drivers/net/eepro100.c b/drivers/net/eepro100.c --- a/drivers/net/eepro100.c Sat Jun 15 17:59:24 2002 +++ b/drivers/net/eepro100.c Sat Jun 15 17:59:24 2002 @@ -558,6 +558,7 @@ static int __devinit eepro100_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { + u16 cmd; unsigned long ioaddr; int irq; int acpi_idle_state = 0, pm; @@ -567,65 +568,55 @@ if (speedo_debug > 0 && did_version++ == 0) printk(version); - /* save power state before pci_enable_device overwrites it */ + /* save power state before pci_request_* overwrites it */ pm = pci_find_capability(pdev, PCI_CAP_ID_PM); if (pm) { u16 pwr_command; pci_read_config_word(pdev, pm + PCI_PM_CTRL, &pwr_command); acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK; } - - if (pci_enable_device(pdev)) - goto err_out_free_mmio_region; - - pci_set_master(pdev); - - if (!request_region(pci_resource_start(pdev, 1), - pci_resource_len(pdev, 1), "eepro100")) { - printk (KERN_ERR "eepro100: cannot reserve I/O ports\n"); + irq = pci_assign_irq(pdev); + if (irq < 0) goto err_out_none; - } - if (!request_mem_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0), "eepro100")) { - printk (KERN_ERR "eepro100: cannot reserve MMIO region\n"); - goto err_out_free_pio_region; - } - irq = pdev->irq; #ifdef USE_IO - ioaddr = pci_resource_start(pdev, 1); + 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, IRQ %d.\n", + printk("Found Intel i82557 PCI Speedo at I/O %#lx IRQ %d.\n", ioaddr, irq); #else - ioaddr = (unsigned long)ioremap(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - if (!ioaddr) { - printk (KERN_ERR "eepro100: cannot remap MMIO region %lx @ %lx\n", - pci_resource_len(pdev, 0), pci_resource_start(pdev, 0)); - goto err_out_free_mmio_region; - } + /* Even if using MMIO, the hardware won't work + unless IO is enabled, too */ + if (pci_enable_io(pdev) < 0) + goto err_out_none; + + 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, IRQ %d.\n", + printk("Found Intel i82557 PCI Speedo, MMIO at %#lx IRQ %d.\n", pci_resource_start(pdev, 0), irq); #endif - + pci_set_master(pdev); if (speedo_found1(pdev, ioaddr, cards_found, acpi_idle_state) == 0) cards_found++; else - goto err_out_iounmap; + goto err_out_disable; return 0; -err_out_iounmap: ; -#ifndef USE_IO - iounmap ((void *)ioaddr); + err_out_disable: + pci_disable_device(pdev); +#ifdef USE_IO + pci_release_io(pdev, 1); +#else + pci_release_mmio(pdev, 0, (void *)ioaddr); #endif -err_out_free_mmio_region: - release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); -err_out_free_pio_region: - release_region(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1)); err_out_none: return -ENODEV; } @@ -803,7 +794,6 @@ pci_set_drvdata (pdev, dev); dev->base_addr = ioaddr; - dev->irq = pdev->irq; sp = dev->priv; sp->pdev = pdev; @@ -924,7 +914,7 @@ int retval; if (speedo_debug > 1) - printk(KERN_DEBUG "%s: speedo_open() irq %d.\n", dev->name, dev->irq); + printk(KERN_DEBUG "%s: speedo_open()\n", dev->name); MOD_INC_USE_COUNT; @@ -939,11 +929,12 @@ sp->in_interrupt = 0; /* .. we can safely take handler calls during init. */ - retval = request_irq(dev->irq, &speedo_interrupt, SA_SHIRQ, dev->name, dev); - if (retval) { + retval = pci_request_irq(sp->pdev, &speedo_interrupt, SA_SHIRQ, dev); + if (retval < 0) { MOD_DEC_USE_COUNT; return retval; } + dev->irq = retval; dev->if_port = sp->default_port; @@ -1834,7 +1825,7 @@ /* Shutting down the chip nicely fails to disable flow control. So.. */ outl(PortPartialReset, ioaddr + SCBPort); - free_irq(dev->irq, dev); + pci_release_irq(sp->pdev, dev); /* Print a few items for debugging. */ if (speedo_debug > 3) @@ -2253,11 +2244,10 @@ unregister_netdev(dev); - release_region(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1)); - release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); - -#ifndef USE_IO - iounmap((char *)dev->base_addr); +#ifdef USE_IO + pci_release_io(pdev, 1); +#else + pci_release_mmio(pdev, 0, (void *) dev->base_addr); #endif pci_free_consistent(pdev, TX_RING_SIZE * sizeof(struct TxFD) @@ -2348,7 +2338,6 @@ \f /* * Local variables: - * compile-command: "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c eepro100.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`" * c-indent-level: 4 * c-basic-offset: 4 * tab-width: 4 diff -Nru a/sound/oss/ymfpci.c b/sound/oss/ymfpci.c --- a/sound/oss/ymfpci.c Sat Jun 15 17:59:24 2002 +++ b/sound/oss/ymfpci.c Sat Jun 15 17:59:24 2002 @@ -2496,16 +2496,15 @@ static int __devinit ymf_probe_one(struct pci_dev *pcidev, const struct pci_device_id *ent) { u16 ctrl; - unsigned long base; ymfpci_t *codec; + int irq, err; - int err; - +#if 0 if ((err = pci_enable_device(pcidev)) != 0) { printk(KERN_ERR "ymfpci: pci_enable_device failed\n"); return err; } - base = pci_resource_start(pcidev, 0); +#endif if ((codec = kmalloc(sizeof(ymfpci_t), GFP_KERNEL)) == NULL) { printk(KERN_ERR "ymfpci: no core\n"); @@ -2520,25 +2519,16 @@ codec->pci = pcidev; pci_read_config_byte(pcidev, PCI_REVISION_ID, &codec->rev); - - if (request_mem_region(base, 0x8000, "ymfpci") == NULL) { - printk(KERN_ERR "ymfpci: unable to request mem region\n"); + + codec->reg_area_virt = pci_request_mmio(pcidev, 0); + if (!codec->reg_area_virt) goto out_free; - } - - if ((codec->reg_area_virt = ioremap(base, 0x8000)) == NULL) { - printk(KERN_ERR "ymfpci: unable to map registers\n"); - goto out_release_region; - } pci_set_master(pcidev); - printk(KERN_INFO "ymfpci: %s at 0x%lx IRQ %d\n", - (char *)ent->driver_data, base, pcidev->irq); - ymfpci_aclink_reset(pcidev); if (ymfpci_codec_ready(codec, 0, 1) < 0) - goto out_unmap; + goto out_release_mmio; #ifdef CONFIG_SOUND_YMFPCI_LEGACY if (assigned == 0) { @@ -2556,16 +2546,16 @@ goto out_disable_dsp; ymf_memload(codec); - if (request_irq(pcidev->irq, ymf_interrupt, SA_SHIRQ, "ymfpci", codec) != 0) { - printk(KERN_ERR "ymfpci: unable to request IRQ %d\n", - pcidev->irq); + irq = pci_request_irq(pcidev, ymf_interrupt, SA_SHIRQ, codec); + if (irq < 0) { + printk(KERN_ERR "ymfpci: unable to request IRQ %d\n", irq); goto out_memfree; } /* register /dev/dsp */ if ((codec->dev_audio = register_sound_dsp(&ymf_fops, -1)) < 0) { printk(KERN_ERR "ymfpci: unable to register dsp\n"); - goto out_free_irq; + goto out_release_irq; } /* @@ -2591,6 +2581,9 @@ } #endif /* CONFIG_SOUND_YMFPCI_LEGACY */ + printk(KERN_INFO "ymfpci: %s at 0x%lx IRQ %d\n", + (char *)ent->driver_data, pci_resource_start(pcidev, 0), irq); + /* put it into driver list */ list_add_tail(&codec->ymf_devs, &ymf_devs); pci_set_drvdata(pcidev, codec); @@ -2599,8 +2592,8 @@ out_unregister_sound_dsp: unregister_sound_dsp(codec->dev_audio); - out_free_irq: - free_irq(pcidev->irq, codec); + out_release_irq: + pci_release_irq(pcidev, codec); out_memfree: ymfpci_memfree(codec); out_disable_dsp: @@ -2608,10 +2601,8 @@ ctrl = ymfpci_readw(codec, YDSXGR_GLOBALCTRL); ymfpci_writew(codec, YDSXGR_GLOBALCTRL, ctrl & ~0x0007); ymfpci_writel(codec, YDSXGR_STATUS, ~0); - out_unmap: - iounmap(codec->reg_area_virt); - out_release_region: - release_mem_region(pci_resource_start(pcidev, 0), 0x8000); + out_release_mmio: + pci_release_mmio(pcidev, 0, codec->reg_area_virt); out_free: kfree(codec); return -ENODEV; ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-15 18:48 ` Linus Torvalds 2002-06-15 19:05 ` Linus Torvalds @ 2002-06-15 20:07 ` Jeff Garzik 2002-06-15 22:51 ` Kai Germaschewski 1 sibling, 1 reply; 38+ messages in thread From: Jeff Garzik @ 2002-06-15 20:07 UTC (permalink / raw) To: Linus Torvalds Cc: Kai Germaschewski, Vojtech Pavlik, Peter Osterlund, Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel Linus Torvalds wrote: > 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. >>The only thing I've wanted is a cross-platform way to detect if >>pdev->irq returned by pci_enable_device is 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. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-15 20:07 ` Jeff Garzik @ 2002-06-15 22:51 ` Kai Germaschewski 0 siblings, 0 replies; 38+ messages in thread From: Kai Germaschewski @ 2002-06-15 22:51 UTC (permalink / raw) To: Jeff Garzik Cc: Linus Torvalds, Vojtech Pavlik, Peter Osterlund, Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel On Sat, 15 Jun 2002, Jeff Garzik wrote: > 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? > 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. 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 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-14 18:12 ` Kai Germaschewski 2002-06-14 18:18 ` Linus Torvalds @ 2002-06-14 19:31 ` Jeff Garzik 2002-06-14 23:25 ` Kai Germaschewski 1 sibling, 1 reply; 38+ messages in thread From: Jeff Garzik @ 2002-06-14 19:31 UTC (permalink / raw) To: Kai Germaschewski Cc: Linus Torvalds, Vojtech Pavlik, Peter Osterlund, Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel Kai Germaschewski wrote: > On Fri, 14 Jun 2002, Linus Torvalds wrote: > > >>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 ;) 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 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-14 19:31 ` Jeff Garzik @ 2002-06-14 23:25 ` Kai Germaschewski 2002-06-14 23:53 ` Jeff Garzik 2002-06-15 8:25 ` Ingo Oeser 0 siblings, 2 replies; 38+ messages in thread From: Kai Germaschewski @ 2002-06-14 23:25 UTC (permalink / raw) To: Jeff Garzik Cc: Linus Torvalds, Vojtech Pavlik, Peter Osterlund, Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel On Fri, 14 Jun 2002, Jeff Garzik wrote: > 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. > 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 ===== --- 1.10/arch/i386/pci/i386.c Wed May 8 18:10:45 2002 +++ edited/arch/i386/pci/i386.c Fri Jun 14 17:23:28 2002 @@ -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 ===== --- 1.32/drivers/net/eepro100.c Thu May 30 01:18:19 2002 +++ edited/drivers/net/eepro100.c Fri Jun 14 18:05:35 2002 @@ -559,7 +559,6 @@ const struct pci_device_id *ent) { unsigned long ioaddr; - int irq; int acpi_idle_state = 0, pm; static int cards_found /* = 0 */; @@ -575,57 +574,37 @@ acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK; } - if (pci_enable_device(pdev)) - goto err_out_free_mmio_region; - pci_set_master(pdev); - if (!request_region(pci_resource_start(pdev, 1), - pci_resource_len(pdev, 1), "eepro100")) { - printk (KERN_ERR "eepro100: cannot reserve I/O ports\n"); +#ifdef USE_IO + ioaddr = pci_request_io(pdev, 1); + if (!ioaddr) goto err_out_none; - } - if (!request_mem_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0), "eepro100")) { - printk (KERN_ERR "eepro100: cannot reserve MMIO region\n"); - goto err_out_free_pio_region; - } - irq = pdev->irq; -#ifdef USE_IO - ioaddr = pci_resource_start(pdev, 1); if (speedo_debug > 2) - printk("Found Intel i82557 PCI Speedo at I/O %#lx, IRQ %d.\n", - ioaddr, irq); + printk("Found Intel i82557 PCI Speedo at I/O %#lx.\n", ioaddr); #else - ioaddr = (unsigned long)ioremap(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - if (!ioaddr) { - printk (KERN_ERR "eepro100: cannot remap MMIO region %lx @ %lx\n", - pci_resource_len(pdev, 0), pci_resource_start(pdev, 0)); - goto err_out_free_mmio_region; - } + 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, IRQ %d.\n", - pci_resource_start(pdev, 0), irq); + 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_iounmap; + goto err_out_release; return 0; -err_out_iounmap: ; -#ifndef USE_IO - iounmap ((void *)ioaddr); +err_out_release: +#ifdef USE_IO + pci_release_io(pdev, 1); +#else + pci_release_mmio(pdev, 0, (void *)ioaddr); #endif -err_out_free_mmio_region: - release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); -err_out_free_pio_region: - release_region(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1)); err_out_none: return -ENODEV; } @@ -803,7 +782,6 @@ pci_set_drvdata (pdev, dev); dev->base_addr = ioaddr; - dev->irq = pdev->irq; sp = dev->priv; sp->pdev = pdev; @@ -924,7 +902,7 @@ int retval; if (speedo_debug > 1) - printk(KERN_DEBUG "%s: speedo_open() irq %d.\n", dev->name, dev->irq); + printk(KERN_DEBUG "%s: speedo_open()\n", dev->name); MOD_INC_USE_COUNT; @@ -939,11 +917,12 @@ sp->in_interrupt = 0; /* .. we can safely take handler calls during init. */ - retval = request_irq(dev->irq, &speedo_interrupt, SA_SHIRQ, dev->name, dev); + retval = pci_request_irq(sp->pdev, &speedo_interrupt, SA_SHIRQ, dev->name, dev); if (retval) { MOD_DEC_USE_COUNT; return retval; } + dev->irq = retval; dev->if_port = sp->default_port; @@ -1834,7 +1813,7 @@ /* Shutting down the chip nicely fails to disable flow control. So.. */ outl(PortPartialReset, ioaddr + SCBPort); - free_irq(dev->irq, dev); + pci_release_irq(sp->pdev, dev); /* Print a few items for debugging. */ if (speedo_debug > 3) @@ -2253,11 +2232,12 @@ unregister_netdev(dev); - release_region(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1)); release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); -#ifndef USE_IO - iounmap((char *)dev->base_addr); +#ifdef USE_IO + pci_release_io(pdev, 1); +#else + pci_release_mmio(pdev, 0, (void *) dev->base_addr); #endif pci_free_consistent(pdev, TX_RING_SIZE * sizeof(struct TxFD) @@ -2348,7 +2328,6 @@ \f /* * Local variables: - * compile-command: "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c eepro100.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`" * c-indent-level: 4 * c-basic-offset: 4 * tab-width: 4 ===== drivers/pci/pci.c 1.44 vs edited ===== --- 1.44/drivers/pci/pci.c Wed May 8 18:10:45 2002 +++ edited/drivers/pci/pci.c Fri Jun 14 17:54:07 2002 @@ -555,6 +555,112 @@ return 0; } +#define IORESOURCE_IO_MEM (IORESOURCE_IO | IORESOURCE_MEM) + +unsigned long +__pci_request_region(struct pci_dev *pdev, int nr, unsigned long flags, + struct resource *root) +{ + struct pci_driver *drv = pci_dev_driver(pdev); + char *drv_name = drv ? drv->name : "unknown"; + struct resource *res; + + /* Make sure we have the right type (IO/MMIO) */ + if ((pci_resource_flags(pdev, nr) ^ flags) & IORESOURCE_IO_MEM) + goto err; + + /* If no resource has been assigned yet, try to do it now */ + if (!pci_resource_start(pdev, nr) && pci_resource_end(pdev, nr)) + if (pci_assign_resource(pdev, nr) < 0) + goto err; + + /* Enable the resource (unless already done) */ + pcibios_enable_resource(pdev, nr); + + res = __request_region(root, pci_resource_start(pdev, nr), + pci_resource_len(pdev, nr), drv_name); + if (!res) + goto err; + + return res->start; + + err: + printk(KERN_INFO + "%s: failed to get %s(%d) for %s, %#lx-%#lx flags %#lx.\n", + pdev->slot_name, (flags == IORESOURCE_IO ? "IO" : "MMIO"), + nr, drv_name, + pci_resource_start(pdev, nr), + pci_resource_flags(pdev, nr), + pci_resource_end(pdev, nr)); + + return 0; +} + +unsigned long +pci_request_io(struct pci_dev *pdev, int nr) +{ + return __pci_request_region(pdev, nr, IORESOURCE_IO, &ioport_resource); +} + +void * +pci_request_mmio(struct pci_dev *pdev, int nr) +{ + unsigned long base; + void *addr; + + base = __pci_request_region(pdev, nr, IORESOURCE_MEM, &iomem_resource); + if (!base) + return 0; + + addr = ioremap(base, pci_resource_len(pdev, nr)); + if (!addr) + release_region(base, pci_resource_len(pdev, nr)); + + return addr; +} + +void +pci_release_io(struct pci_dev *pdev, int nr) +{ + __release_region(&ioport_resource, + pci_resource_start(pdev, nr), + pci_resource_len(pdev, nr)); +} + +void +pci_release_mmio(struct pci_dev *pdev, int nr, void *addr) +{ + iounmap(addr); + __release_region(&iomem_resource, + pci_resource_start(pdev, nr), + pci_resource_len(pdev, nr)); +} + +int +pci_request_irq(struct pci_dev *pdev, + void (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *name, void *dev) +{ + int irq, retval; + + pcibios_enable_irq(pdev); + irq = pdev->irq; + + retval = request_irq(irq, handler, flags, name, dev); + if (retval < 0) + return retval; + + return irq; +} + +void +pci_release_irq(struct pci_dev *pdev, void *dev) +{ + free_irq(pdev->irq, dev); +} + + + static int __devinit pci_init(void) { struct pci_dev *dev; @@ -601,6 +707,13 @@ EXPORT_SYMBOL(pci_save_state); EXPORT_SYMBOL(pci_restore_state); EXPORT_SYMBOL(pci_enable_wake); + +EXPORT_SYMBOL(pci_request_io); +EXPORT_SYMBOL(pci_request_mmio); +EXPORT_SYMBOL(pci_release_io); +EXPORT_SYMBOL(pci_release_mmio); +EXPORT_SYMBOL(pci_request_irq); +EXPORT_SYMBOL(pci_release_irq); /* Obsolete functions */ ===== include/linux/pci.h 1.32 vs edited ===== --- 1.32/include/linux/pci.h Tue May 28 20:02:33 2002 +++ edited/include/linux/pci.h Fri Jun 14 17:56:28 2002 @@ -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); ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-14 23:25 ` Kai Germaschewski @ 2002-06-14 23:53 ` Jeff Garzik 2002-06-15 8:25 ` Ingo Oeser 1 sibling, 0 replies; 38+ messages in thread From: Jeff Garzik @ 2002-06-14 23:53 UTC (permalink / raw) To: Kai Germaschewski Cc: Linus Torvalds, Vojtech Pavlik, Peter Osterlund, Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel Kai Germaschewski wrote: > On Fri, 14 Jun 2002, Jeff Garzik wrote: > > >>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. > > >>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. 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 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-14 23:25 ` Kai Germaschewski 2002-06-14 23:53 ` Jeff Garzik @ 2002-06-15 8:25 ` Ingo Oeser 1 sibling, 0 replies; 38+ messages in thread From: Ingo Oeser @ 2002-06-15 8:25 UTC (permalink / raw) To: linux-kernel Hi, On Fri, Jun 14, 2002 at 06:25:15PM -0500, Kai Germaschewski wrote: > We only request the regions we're going to use, so the others may even > stay unassigned and disabled. [...] > 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 -- Science is what we can tell a computer. Art is everything else. --- D.E.Knuth ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-14 18:05 ` Linus Torvalds 2002-06-14 18:12 ` Kai Germaschewski @ 2002-06-14 19:34 ` Jeff Garzik 1 sibling, 0 replies; 38+ messages in thread From: Jeff Garzik @ 2002-06-14 19:34 UTC (permalink / raw) To: Linus Torvalds Cc: Vojtech Pavlik, Peter Osterlund, Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel Linus Torvalds wrote: > 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 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-14 17:47 ` Linus Torvalds 2002-06-14 17:53 ` Vojtech Pavlik @ 2002-06-14 18:30 ` Peter Osterlund 2002-06-14 18:51 ` Linus Torvalds 1 sibling, 1 reply; 38+ messages in thread From: Peter Osterlund @ 2002-06-14 18:30 UTC (permalink / raw) To: Linus Torvalds Cc: Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel Linus Torvalds <torvalds@transmeta.com> writes: > 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.. 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. --- linux/drivers/pcmcia/cardbus.c.old Fri Jun 14 20:04:45 2002 +++ linux/drivers/pcmcia/cardbus.c Fri Jun 14 20:06:39 2002 @@ -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 (petero@p4.localdomain) (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 -- Peter Osterlund - petero2@telia.com http://w1.894.telia.com/~u89404340 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-14 18:30 ` Peter Osterlund @ 2002-06-14 18:51 ` Linus Torvalds 2002-06-14 20:07 ` Peter Osterlund 2002-06-15 2:42 ` Paul Mackerras 0 siblings, 2 replies; 38+ messages in thread From: Linus Torvalds @ 2002-06-14 18:51 UTC (permalink / raw) To: Peter Osterlund Cc: Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel On 14 Jun 2002, Peter Osterlund wrote: > > 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). > 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 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 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-14 18:51 ` Linus Torvalds @ 2002-06-14 20:07 ` Peter Osterlund 2002-06-15 2:42 ` Paul Mackerras 1 sibling, 0 replies; 38+ messages in thread From: Peter Osterlund @ 2002-06-14 20:07 UTC (permalink / raw) To: Linus Torvalds Cc: Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel Linus Torvalds <torvalds@transmeta.com> writes: > > 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? 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.0 yenta_allocate_res: nr=0 type=0x1200 yenta_allocate_res: root->name=PCI mem yenta_allocate_res: size=0x400000 min=0x10000000 max=0xffffffff align=0x400000, ret=0 yenta_allocate_res: res=c11e6de4 name=PCI CardBus #01 start=0x10400000 end=0x107fffff flags=0x1200 yenta_allocate_res: parent=c0251e7c sibling=c11e6920 child=00000000 yenta_allocate_res: parent=PCI mem sibling=S3 Inc. ViRGE/MX child= yenta_allocate_res: nr=1 type=0x200 yenta_allocate_res: root->name=PCI mem yenta_allocate_res: size=0x400000 min=0x10000000 max=0xffffffff align=0x400000, ret=0 yenta_allocate_res: res=c11e6e00 name=PCI CardBus #01 start=0x10800000 end=0x10bfffff flags=0x200 yenta_allocate_res: parent=c0251e7c sibling=c11e6920 child=00000000 yenta_allocate_res: parent=PCI mem sibling=S3 Inc. ViRGE/MX child= yenta_allocate_res: nr=2 type=0x100 yenta_allocate_res: root->name=PCI IO yenta_allocate_res: size=0x100 min=0x4000 max=0xffff align=0x400, ret=0 yenta_allocate_res: res=c11e6e1c name=PCI CardBus #01 start=0x4000 end=0x40ff flags=0x100 yenta_allocate_res: parent=c0251e60 sibling=c11e6190 child=00000000 yenta_allocate_res: parent=PCI IO sibling=Intel Corp. 82371AB PIIX4 USB child= yenta_allocate_res: nr=3 type=0x100 yenta_allocate_res: root->name=PCI IO yenta_allocate_res: size=0x100 min=0x4000 max=0xffff align=0x400, ret=0 yenta_allocate_res: res=c11e6e38 name=PCI CardBus #01 start=0x4400 end=0x44ff flags=0x100 yenta_allocate_res: parent=c0251e60 sibling=c11e6190 child=00000000 yenta_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.1 yenta_allocate_res: nr=0 type=0x1200 yenta_allocate_res: root->name=PCI mem yenta_allocate_res: size=0x400000 min=0x10000000 max=0xffffffff align=0x400000, ret=0 yenta_allocate_res: res=c11df1e4 name=PCI CardBus #05 start=0x10c00000 end=0x10ffffff flags=0x1200 yenta_allocate_res: parent=c0251e7c sibling=c11e6920 child=00000000 yenta_allocate_res: parent=PCI mem sibling=S3 Inc. ViRGE/MX child= yenta_allocate_res: nr=1 type=0x200 yenta_allocate_res: root->name=PCI mem yenta_allocate_res: size=0x400000 min=0x10000000 max=0xffffffff align=0x400000, ret=0 yenta_allocate_res: res=c11df200 name=PCI CardBus #05 start=0x11000000 end=0x113fffff flags=0x200 yenta_allocate_res: parent=c0251e7c sibling=c11e6920 child=00000000 yenta_allocate_res: parent=PCI mem sibling=S3 Inc. ViRGE/MX child= yenta_allocate_res: nr=2 type=0x100 yenta_allocate_res: root->name=PCI IO yenta_allocate_res: size=0x100 min=0x4000 max=0xffff align=0x400, ret=0 yenta_allocate_res: res=c11df21c name=PCI CardBus #05 start=0x4800 end=0x48ff flags=0x100 yenta_allocate_res: parent=c0251e60 sibling=c11e6190 child=00000000 yenta_allocate_res: parent=PCI IO sibling=Intel Corp. 82371AB PIIX4 USB child= yenta_allocate_res: nr=3 type=0x100 yenta_allocate_res: root->name=PCI IO yenta_allocate_res: size=0x100 min=0x4000 max=0xffff align=0x400, ret=0 yenta_allocate_res: res=c11df238 name=PCI CardBus #05 start=0x4c00 end=0x4cff flags=0x100 yenta_allocate_res: parent=c0251e60 sibling=c11e6190 child=00000000 yenta_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 1 pci_read_bridge_bases 0: res=c11e6de4 name=PCI CardBus #01 base=0x0 limit=0x0 Unknown bridge resource 0: assuming transparent pci_read_bridge_bases 1: res=c11e6e00 name=PCI CardBus #01 base=0xf0000000 limit=0x10700000 Unknown bridge resource 1: assuming transparent pci_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 --- linux/drivers/pcmcia/yenta.c.old Fri Jun 14 22:02:08 2002 +++ linux/drivers/pcmcia/yenta.c Fri Jun 14 21:39:38 2002 @@ -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); } --- linux/drivers/pci/probe.c.old Fri Jun 14 22:01:21 2002 +++ linux/drivers/pci/probe.c Fri Jun 14 21:33:32 2002 @@ -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; -- Peter Osterlund - petero2@telia.com http://w1.894.telia.com/~u89404340 ^ permalink raw reply [flat|nested] 38+ messages in thread
* (no subject) 2002-06-14 18:51 ` Linus Torvalds 2002-06-14 20:07 ` Peter Osterlund @ 2002-06-15 2:42 ` Paul Mackerras 2002-06-15 21:58 ` Cardbus Linus Torvalds 1 sibling, 1 reply; 38+ messages in thread From: Paul Mackerras @ 2002-06-15 2:42 UTC (permalink / raw) To: Linus Torvalds; +Cc: linux-kernel, Patrick Mochel, Re Linus Torvalds writes: > > Unknown bridge resource 0: assuming transparent > > Unknown bridge resource 1: assuming transparent > > Unknown bridge resource 2: assuming transparent > > This 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. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Cardbus 2002-06-15 2:42 ` Paul Mackerras @ 2002-06-15 21:58 ` Linus Torvalds 2002-06-16 7:01 ` Cardbus Eric W. Biederman 2002-06-16 8:18 ` Cardbus Paul Mackerras 0 siblings, 2 replies; 38+ messages in thread From: Linus Torvalds @ 2002-06-15 21:58 UTC (permalink / raw) To: Paul Mackerras; +Cc: linux-kernel, Patrick Mochel On Sat, 15 Jun 2002, Paul Mackerras wrote: > > 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 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Cardbus 2002-06-15 21:58 ` Cardbus Linus Torvalds @ 2002-06-16 7:01 ` Eric W. Biederman 2002-06-16 8:18 ` Cardbus Paul Mackerras 1 sibling, 0 replies; 38+ messages in thread From: Eric W. Biederman @ 2002-06-16 7:01 UTC (permalink / raw) To: Linus Torvalds; +Cc: Paul Mackerras, linux-kernel, Patrick Mochel Linus Torvalds <torvalds@transmeta.com> writes: > On Sat, 15 Jun 2002, Paul Mackerras wrote: > > > > 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. 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 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Cardbus 2002-06-15 21:58 ` Cardbus Linus Torvalds 2002-06-16 7:01 ` Cardbus Eric W. Biederman @ 2002-06-16 8:18 ` Paul Mackerras 1 sibling, 0 replies; 38+ messages in thread From: Paul Mackerras @ 2002-06-16 8:18 UTC (permalink / raw) To: Linus Torvalds; +Cc: linux-kernel, Patrick Mochel Linus Torvalds writes: > 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. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-10 15:44 ` Patrick Mochel 2002-06-10 19:28 ` Peter Osterlund @ 2002-06-10 20:59 ` Alessandro Suardi 2002-06-16 4:57 ` Linus Torvalds 2 siblings, 0 replies; 38+ messages in thread From: Alessandro Suardi @ 2002-06-10 20:59 UTC (permalink / raw) To: Patrick Mochel; +Cc: Peter Osterlund, Tobias Diedrich, linux-kernel, torvalds [-- Attachment #1: Type: text/plain, Size: 1971 bytes --] Patrick Mochel wrote: > On 9 Jun 2002, Peter Osterlund wrote: > > >>Tobias Diedrich <ranma@gmx.at> writes: >> >> >>>Peter Osterlund wrote: >>> >>>>Alessandro Suardi <alessandro.suardi@oracle.com> writes: >>>> >>>> >>>>>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: > > > 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 > > ChangeSet@1.494, 2002-06-10 08:35:32-07:00, mochel@osdl.org > 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 [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") [-- Attachment #2: bootmsgs.tar.gz --] [-- Type: application/x-gzip, Size: 4723 bytes --] ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-10 15:44 ` Patrick Mochel 2002-06-10 19:28 ` Peter Osterlund 2002-06-10 20:59 ` 2.5.20 - Xircom PCI Cardbus doesn't work Alessandro Suardi @ 2002-06-16 4:57 ` Linus Torvalds 2002-06-16 7:40 ` Peter Osterlund 2 siblings, 1 reply; 38+ messages in thread From: Linus Torvalds @ 2002-06-16 4:57 UTC (permalink / raw) To: Patrick Mochel Cc: Peter Osterlund, Tobias Diedrich, Alessandro Suardi, linux-kernel On Mon, 10 Jun 2002, Patrick Mochel wrote: > > 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 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-16 4:57 ` Linus Torvalds @ 2002-06-16 7:40 ` Peter Osterlund 2002-06-16 18:16 ` Linus Torvalds 0 siblings, 1 reply; 38+ messages in thread From: Peter Osterlund @ 2002-06-16 7:40 UTC (permalink / raw) To: Linus Torvalds Cc: Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel Linus Torvalds <torvalds@transmeta.com> writes: > On Mon, 10 Jun 2002, Patrick Mochel wrote: > > > > 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? 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: --- linux-2.5.20/drivers/pcmcia/cardbus.c Sat May 25 03:55:22 2002 +++ linux-2.5.20/drivers/pcmcia/cardbus.c Sun Jun 9 02:27:35 2002 @@ -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 00000004 c017aed3 *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 >>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 -- Peter Osterlund - petero2@telia.com http://w1.894.telia.com/~u89404340 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-16 7:40 ` Peter Osterlund @ 2002-06-16 18:16 ` Linus Torvalds 2002-06-16 18:42 ` Martin Dalecki 0 siblings, 1 reply; 38+ messages in thread From: Linus Torvalds @ 2002-06-16 18:16 UTC (permalink / raw) To: Peter Osterlund Cc: Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel On 16 Jun 2002, Peter Osterlund wrote: > > 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. > 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 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: 2.5.20 - Xircom PCI Cardbus doesn't work 2002-06-16 18:16 ` Linus Torvalds @ 2002-06-16 18:42 ` Martin Dalecki 0 siblings, 0 replies; 38+ messages in thread From: Martin Dalecki @ 2002-06-16 18:42 UTC (permalink / raw) To: Linus Torvalds Cc: Peter Osterlund, Patrick Mochel, Tobias Diedrich, Alessandro Suardi, linux-kernel Użytkownik Linus Torvalds napisał: > > On 16 Jun 2002, Peter Osterlund wrote: > >>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. > > >>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... > 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. ^ permalink raw reply [flat|nested] 38+ messages in thread
end of thread, other threads:[~2002-06-16 18:43 UTC | newest] Thread overview: 38+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2002-06-03 11:07 2.5.20 - Xircom PCI Cardbus doesn't work Alessandro Suardi 2002-06-06 17:08 ` Peter Osterlund 2002-06-09 9:17 ` Tobias Diedrich 2002-06-09 10:55 ` Peter Osterlund 2002-06-10 15:44 ` Patrick Mochel 2002-06-10 19:28 ` Peter Osterlund 2002-06-14 16:33 ` Linus Torvalds 2002-06-14 17:20 ` Peter Osterlund 2002-06-14 17:47 ` Linus Torvalds 2002-06-14 17:53 ` Vojtech Pavlik 2002-06-14 18:05 ` Linus Torvalds 2002-06-14 18:12 ` Kai Germaschewski 2002-06-14 18:18 ` Linus Torvalds 2002-06-14 19:37 ` Jeff Garzik 2002-06-15 18:48 ` Linus Torvalds 2002-06-15 19:05 ` Linus Torvalds 2002-06-15 19:39 ` Kai Germaschewski 2002-06-15 19:58 ` Jeff Garzik 2002-06-15 23:00 ` Kai Germaschewski 2002-06-15 20:07 ` Jeff Garzik 2002-06-15 22:51 ` Kai Germaschewski 2002-06-14 19:31 ` Jeff Garzik 2002-06-14 23:25 ` Kai Germaschewski 2002-06-14 23:53 ` Jeff Garzik 2002-06-15 8:25 ` Ingo Oeser 2002-06-14 19:34 ` Jeff Garzik 2002-06-14 18:30 ` Peter Osterlund 2002-06-14 18:51 ` Linus Torvalds 2002-06-14 20:07 ` Peter Osterlund 2002-06-15 2:42 ` Paul Mackerras 2002-06-15 21:58 ` Cardbus Linus Torvalds 2002-06-16 7:01 ` Cardbus Eric W. Biederman 2002-06-16 8:18 ` Cardbus Paul Mackerras 2002-06-10 20:59 ` 2.5.20 - Xircom PCI Cardbus doesn't work Alessandro Suardi 2002-06-16 4:57 ` Linus Torvalds 2002-06-16 7:40 ` Peter Osterlund 2002-06-16 18:16 ` Linus Torvalds 2002-06-16 18:42 ` Martin Dalecki
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox