2002-01-17 00:00:44

by Jes Sorensen

[permalink] [raw]
Subject: [patch] VAIO irq assignment fix

Hi

I have gotten a Sony VAIO R505TL laptop which has a Richo RL5C574
Cardbus controller however the broken bios doesn't assign an irq to the
controller even though it is attached.

This patch solves the problem and makes cardbus insert/eject a lot more
stable for me.

Cheers,
Jes
--- ../linux-2.4.18-pre2/arch/i386/kernel/dmi_scan.c Fri Dec 21 12:41:53 2001
+++ arch/i386/kernel/dmi_scan.c Wed Jan 16 18:36:05 2002
@@ -5,6 +5,7 @@
#include <linux/init.h>
#include <linux/apm_bios.h>
#include <linux/slab.h>
+#include <linux/pci.h>
#include <asm/io.h>
#include <linux/pm.h>
#include <asm/keyboard.h>
@@ -416,6 +417,26 @@


/*
+ * Work around broken Sony VAIO Notebooks which do not assign irqs
+ * to their Richo RL5C475 Cardbus controller, IRQ is 9.
+ */
+static __init int fix_broken_sony_bios_irq(struct dmi_blacklist *d)
+{
+ struct pci_dev *pdev = NULL;
+
+ pdev = pci_find_device(PCI_VENDOR_ID_RICOH,
+ PCI_DEVICE_ID_RICOH_RL5C475, pdev);
+ if (pdev) {
+ pdev->irq = 9;
+ pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 9);
+ printk(KERN_INFO "%s detected - fixing missing/"
+ "broken IRQ routing\n", d->ident);
+ }
+ return 0;
+}
+
+
+/*
* Simple "print if true" callback
*/

@@ -614,7 +635,13 @@
NO_MATCH, NO_MATCH
} },

-
+ { fix_broken_sony_bios_irq, "Sony VAIO R505TL Series Laptop", {
+ MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
+ MATCH(DMI_BIOS_VERSION, "R0202U1"),
+ NO_MATCH
+ } },
+
/*
* Generic per vendor APM settings
*/


2002-01-17 14:03:01

by Alan

[permalink] [raw]
Subject: Re: [patch] VAIO irq assignment fix

> I have gotten a Sony VAIO R505TL laptop which has a Richo RL5C574
> Cardbus controller however the broken bios doesn't assign an irq to the
> controller even though it is attached.

Surely pci_enable_device should do that anyway?

2002-01-17 14:05:52

by Jes Sorensen

[permalink] [raw]
Subject: Re: [patch] VAIO irq assignment fix

>>>>> "Alan" == Alan Cox <[email protected]> writes:

>> I have gotten a Sony VAIO R505TL laptop which has a Richo RL5C574
>> Cardbus controller however the broken bios doesn't assign an irq to
>> the controller even though it is attached.

Alan> Surely pci_enable_device should do that anyway?

The problem is that the interrupt is not set in the PIRQ table so if we
don't shoehorn it in, the interrupt source wont be found.

Jes

2002-01-17 14:06:51

by Alan

[permalink] [raw]
Subject: Re: [patch] VAIO irq assignment fix

> Alan> Surely pci_enable_device should do that anyway?
>
> The problem is that the interrupt is not set in the PIRQ table so if we
> don't shoehorn it in, the interrupt source wont be found.

What happens if you use the current ACPI patch btw ?

2002-01-17 14:08:31

by Jes Sorensen

[permalink] [raw]
Subject: Re: [patch] VAIO irq assignment fix

>>>>> "Alan" == Alan Cox <[email protected]> writes:

Alan> Surely pci_enable_device should do that anyway?
>> The problem is that the interrupt is not set in the PIRQ table so if
>> we don't shoehorn it in, the interrupt source wont be found.

Alan> What happens if you use the current ACPI patch btw ?

Nothing ;(

The option that says 'use ACPI for interrupt routing' doesn't do
anything yet.

Jes

2002-01-17 15:00:27

by Kai Germaschewski

[permalink] [raw]
Subject: Re: [patch] VAIO irq assignment fix

On Thu, 17 Jan 2002, Jes Sorensen wrote:

> >> I have gotten a Sony VAIO R505TL laptop which has a Richo RL5C574
> >> Cardbus controller however the broken bios doesn't assign an irq to
> >> the controller even though it is attached.
>
> Alan> Surely pci_enable_device should do that anyway?
>
> The problem is that the interrupt is not set in the PIRQ table so if we
> don't shoehorn it in, the interrupt source wont be found.

Is the interrupt in the ACPI PCI IRQ routing table? Basic support for that
is in the latest ACPI patch, 20011218 (http://www.sf.net/projects/acpi), it'll
print the _PRT entries during boot. However, the info isn't used to
actually setup the routing, so it won't help your problem. I have a patch
which uses the ACPI table for setting up IRQ routing, that should make
sure system work properly.

--Kai

2002-01-17 15:18:49

by Jes Sorensen

[permalink] [raw]
Subject: Re: [patch] VAIO irq assignment fix

>>>>> "Kai" == Kai Germaschewski <[email protected]> writes:

Kai> On Thu, 17 Jan 2002, Jes Sorensen wrote:
>> The problem is that the interrupt is not set in the PIRQ table so if
>> we don't shoehorn it in, the interrupt source wont be found.

Kai> Is the interrupt in the ACPI PCI IRQ routing table? Basic support
Kai> for that is in the latest ACPI patch, 20011218
Kai> (http://www.sf.net/projects/acpi), it'll print the _PRT entries during
Kai> boot. However, the info isn't used to actually setup the routing,
Kai> so it won't help your problem. I have a patch which uses the ACPI
Kai> table for setting up IRQ routing, that should make sure system work
Kai> properly.

I think it's in the ACPI table since a certain M$ OS finds the interrupt
source. As I mentioned to Alan, I tried the latest ACPI patch but as you
say, nothing is done with the information. I haven't tried enabling
ACPI_DEBUG but that sounds to be a next step.

I'd be interested in trying out your patch as well.

Cheers,
Jes

2002-01-17 15:23:39

by Kai Germaschewski

[permalink] [raw]
Subject: Re: [patch] VAIO irq assignment fix

On Thu, 17 Jan 2002, Jes Sorensen wrote:

> I think it's in the ACPI table since a certain M$ OS finds the interrupt
> source. As I mentioned to Alan, I tried the latest ACPI patch but as you
> say, nothing is done with the information. I haven't tried enabling
> ACPI_DEBUG but that sounds to be a next step.

ACPI_DEBUG should print the table at least :)

My patch is appended, it applies on top of 2.4.17+acpi-20011218

--Kai

diff -X excl -urN linux-2.4.17.patches/arch/i386/kernel/pci-i386.h linux-2.4.17.work/arch/i386/kernel/pci-i386.h
--- linux-2.4.17.patches/arch/i386/kernel/pci-i386.h Mon Jan 14 23:55:08 2002
+++ linux-2.4.17.work/arch/i386/kernel/pci-i386.h Fri Dec 28 23:19:14 2001
@@ -21,6 +21,7 @@
#define PCI_ASSIGN_ROMS 0x1000
#define PCI_BIOS_IRQ_SCAN 0x2000
#define PCI_ASSIGN_ALL_BUSSES 0x4000
+#define PCI_ACPI_IRQ 0x8000

extern unsigned int pci_probe;

diff -X excl -urN linux-2.4.17.patches/arch/i386/kernel/pci-irq.c linux-2.4.17.work/arch/i386/kernel/pci-irq.c
--- linux-2.4.17.patches/arch/i386/kernel/pci-irq.c Mon Jan 14 23:55:08 2002
+++ linux-2.4.17.work/arch/i386/kernel/pci-irq.c Tue Jan 8 00:01:32 2002
@@ -512,6 +512,82 @@
pirq_router_dev->slot_name);
}

+static void pcibios_test_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+}
+
+#ifdef CONFIG_ACPI_PCI
+
+extern int acpi_pci_get_current_irq(struct pci_dev *dev, u8 pin, int *irq);
+extern int acpi_pci_set_current_irq(struct pci_dev *dev, u8 pin, int irq);
+extern int acpi_pci_get_possible_irq_mask(struct pci_dev *dev, u8 pin, int *mask);
+
+static int acpi_lookup_irq(struct pci_dev *dev, u8 pin, int assign)
+{
+ int newirq, i, irq, retval;
+ char *msg = NULL;
+ u32 mask;
+
+ DBG("IRQ for %s:%d (%d)", dev->slot_name, pin, dev->irq);
+
+ retval = acpi_pci_get_current_irq(dev, pin, &irq);
+ if (retval < 0) {
+ DBG(" -> failed\n");
+ return 0;
+ }
+ DBG(" -> irq %d", irq);
+
+ retval = acpi_pci_get_possible_irq_mask(dev, pin, &mask);
+ if (retval < 0) {
+ DBG(" -> failed\n");
+ return 0;
+ }
+ DBG(" -> mask %04x", mask);
+ mask &= pcibios_irq_mask;
+
+
+ if (assign) {
+ /* Find the best IRQ to assign */
+ newirq = 0;
+ for (i = 0; i < 16; i++) {
+ if (!(mask & (1 << i)))
+ continue;
+ if (pirq_penalty[i] < pirq_penalty[newirq] &&
+ !request_irq(i, pcibios_test_irq_handler, SA_SHIRQ, "pci-test", dev)) {
+ free_irq(i, dev);
+ newirq = i;
+ }
+ }
+ /* Use the current IRQ if possible */
+ if (irq && ((1 << irq) & mask))
+ newirq = irq;
+
+ DBG(" -> newirq=%d", newirq);
+ if (newirq && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) {
+ DBG(" -> assigning IRQ %d", newirq);
+ if (acpi_pci_set_current_irq(dev, pin, newirq) == 0) {
+ eisa_set_level_irq(newirq);
+ DBG(" ... OK\n");
+ msg = "Assigned";
+ irq = newirq;
+ }
+ }
+ } else {
+ msg = "Found";
+ }
+
+ if (irq) {
+ printk(KERN_INFO "PCI: %s IRQ %d for device %s\n", msg, irq, dev->slot_name);
+
+ dev->irq = irq;
+ pirq_penalty[irq]++;
+ return 1;
+ }
+ return 0;
+}
+
+#endif
+
static struct irq_info *pirq_get_info(struct pci_dev *dev)
{
struct irq_routing_table *rt = pirq_table;
@@ -524,38 +600,25 @@
return NULL;
}

-static void pcibios_test_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
-{
-}
-
-static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
+static int pirq_lookup_irq(struct pci_dev *dev, u8 pin, int assign)
{
- u8 pin;
- struct irq_info *info;
- int i, pirq, newirq;
- int irq = 0;
- u32 mask;
struct irq_router *r = pirq_router;
+ struct irq_info *info;
+ int newirq, pirq, i, irq = 0;
struct pci_dev *dev2;
char *msg = NULL;
+ u32 mask;

if (!pirq_table)
return 0;

- /* Find IRQ routing entry */
- pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
- if (!pin) {
- DBG(" -> no interrupt pin\n");
- return 0;
- }
- pin = pin - 1;
-
DBG("IRQ for %s:%d", dev->slot_name, pin);
info = pirq_get_info(dev);
if (!info) {
DBG(" -> not found in routing table\n");
return 0;
}
+
pirq = info->irq[pin].link;
mask = info->irq[pin].bitmap;
if (!pirq) {
@@ -636,26 +699,47 @@
return 1;
}

+static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
+{
+ u8 pin;
+
+ /* Find IRQ routing entry */
+ pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+ if (!pin) {
+ DBG("PCI: %s: no interrupt pin\n", dev->slot_name);
+ return 0;
+ }
+ pin -= 1;
+
+#ifdef CONFIG_ACPI_PCI
+ if (pci_probe & PCI_ACPI_IRQ)
+ return acpi_lookup_irq(dev, pin, assign);
+#endif
+ return pirq_lookup_irq(dev, pin, assign);
+}
+
void __init pcibios_irq_init(void)
{
DBG("PCI: IRQ init\n");
- pirq_table = pirq_find_routing_table();
+ if (!(pci_probe & PCI_ACPI_IRQ)) {
+ pirq_table = pirq_find_routing_table();
#ifdef CONFIG_PCI_BIOS
- if (!pirq_table && (pci_probe & PCI_BIOS_IRQ_SCAN))
- pirq_table = pcibios_get_irq_routing_table();
+ if (!pirq_table && (pci_probe & PCI_BIOS_IRQ_SCAN))
+ pirq_table = pcibios_get_irq_routing_table();
#endif
- if (pirq_table) {
- pirq_peer_trick();
- pirq_find_router();
- if (pirq_table->exclusive_irqs) {
- int i;
- for (i=0; i<16; i++)
- if (!(pirq_table->exclusive_irqs & (1 << i)))
- pirq_penalty[i] += 100;
- }
- /* If we're using the I/O APIC, avoid using the PCI IRQ routing table */
- if (io_apic_assign_pci_irqs)
- pirq_table = NULL;
+ if (pirq_table) {
+ pirq_peer_trick();
+ pirq_find_router();
+ if (pirq_table->exclusive_irqs) {
+ int i;
+ for (i=0; i<16; i++)
+ if (!(pirq_table->exclusive_irqs & (1 << i)))
+ pirq_penalty[i] += 100;
+ }
+ /* If we're using the I/O APIC, avoid using the PCI IRQ routing table */
+ if (io_apic_assign_pci_irqs)
+ pirq_table = NULL;
+ }
}
}

diff -X excl -urN linux-2.4.17.patches/arch/i386/kernel/pci-pc.c linux-2.4.17.work/arch/i386/kernel/pci-pc.c
--- linux-2.4.17.patches/arch/i386/kernel/pci-pc.c Mon Jan 14 23:55:08 2002
+++ linux-2.4.17.work/arch/i386/kernel/pci-pc.c Fri Dec 28 23:18:54 2001
@@ -1253,6 +1253,12 @@
return NULL;
}
#endif
+#ifdef CONFIG_ACPI_PCI
+ else if (!strcmp(str, "acpiirq")) {
+ pci_probe |= PCI_ACPI_IRQ;
+ return NULL;
+ }
+#endif
#ifdef CONFIG_PCI_DIRECT
else if (!strcmp(str, "conf1")) {
pci_probe = PCI_PROBE_CONF1 | PCI_NO_CHECKS;
diff -X excl -urN linux-2.4.17.patches/drivers/acpi/acpi_pci.c linux-2.4.17.work/drivers/acpi/acpi_pci.c
--- linux-2.4.17.patches/drivers/acpi/acpi_pci.c Mon Jan 14 23:55:08 2002
+++ linux-2.4.17.work/drivers/acpi/acpi_pci.c Mon Jan 7 23:22:46 2002
@@ -119,9 +119,10 @@
if ((0 != acpi_pci_get_status(handle, &sta)) || !(sta & 0x01))
return -ENODEV;

-#ifdef CONFIG_ACPI_DEBUG
- printk(KERN_INFO " link device currently %s\n", (sta & 0x02)?"enabled":"disabled");
-#endif
+ /* If disabled, return */
+
+ if (!(sta & 0x02))
+ return 0;

/* Get the current (default) IRQ assignment */

@@ -146,41 +147,167 @@

while (resource && (bytes_unparsed > 0)) {

- if (index != i++)
- continue;
+ switch (resource->id) {
+ case ACPI_RSTYPE_START_DPF:
+ case ACPI_RSTYPE_END_DPF:
+ break;
+ default:
+ i++;
+ }
+
+ if (i <= index)
+ goto next;

switch (resource->id) {
case ACPI_RSTYPE_IRQ:
- (*irq) = resource->data.irq.interrupts[0];
+ {
+ acpi_resource_irq *p = &resource->data.irq;
+
+ if (p->number_of_interrupts > 0) {
+ (*irq) = p->interrupts[0];
+ }
break;
+ }
case ACPI_RSTYPE_EXT_IRQ:
- (*irq) = resource->data.irq.interrupts[0];
+ {
+ acpi_resource_ext_irq *p = &resource->data.extended_irq;
+ if (p->number_of_interrupts > 0) {
+ (*irq) = p->interrupts[0];
+ }
break;
}
+ }

if (*irq)
break;

+ next:
bytes_unparsed = bytes_unparsed - resource->length;
if (bytes_unparsed > 0)
resource = (acpi_resource*)((u8*)resource + resource->length);
}

- if (!(*irq))
+ return 0;
+}
+
+
+static int
+acpi_pci_get_link_irq_mask (
+ acpi_handle handle,
+ u32 index,
+ u32 *mask)
+{
+ acpi_status status = AE_OK;
+ acpi_buffer buffer = {0, NULL};
+ acpi_resource *resource = NULL;
+ int bytes_unparsed = 0;
+ int i = 0;
+
+ if (!handle || !mask)
+ return -EINVAL;
+
+ status = acpi_get_possible_resources(handle, &buffer);
+ if (status != AE_BUFFER_OVERFLOW)
return -ENODEV;

- /* If disabled, enable by evaluating _SRS using default IRQ */
+ buffer.pointer = kmalloc(buffer.length, GFP_KERNEL);
+ if (!buffer.pointer)
+ return -ENOMEM;
+ memset(buffer.pointer, 0, buffer.length);

- if (!(sta & 0x02)) {
- acpi_buffer buffer = {resource->length, resource};
- printk(KERN_INFO PREFIX "Enabling _PRT entry\n");
- status = acpi_set_current_resources(handle, &buffer);
- if (ACPI_FAILURE(status)) {
- printk(KERN_WARNING PREFIX "Error evaluating _SRS, %s\n",
- acpi_format_exception(status));
- return -ENODEV;
+ status = acpi_get_possible_resources(handle, &buffer);
+ if (ACPI_FAILURE(status)) {
+ kfree(buffer.pointer);
+ return -ENODEV;
+ }
+
+ resource = (acpi_resource *) buffer.pointer;
+
+ bytes_unparsed = buffer.length - 16;
+
+ while (resource && (bytes_unparsed > 0)) {
+
+ switch (resource->id) {
+ case ACPI_RSTYPE_START_DPF:
+ case ACPI_RSTYPE_END_DPF:
+ break;
+ default:
+ i++;
+ }
+
+ if (i <= index)
+ goto next;
+
+ switch (resource->id) {
+ case ACPI_RSTYPE_IRQ:
+ {
+ acpi_resource_irq *p = &resource->data.irq;
+ int j;
+
+ *mask = 0;
+ for (j = 0; j < p->number_of_interrupts; j++) {
+ (*mask) |= (1 << p->interrupts[j]);
+ }
+ return 0;
}
+ case ACPI_RSTYPE_EXT_IRQ:
+ {
+ acpi_resource_ext_irq *p = &resource->data.extended_irq;
+ int j;
+
+ *mask = 0;
+ for (j = 0; j < p->number_of_interrupts; j++) {
+ (*mask) |= (1 << p->interrupts[j]);
+ }
+ return 0;
+ }
+ }
+
+ next:
+ bytes_unparsed = bytes_unparsed - resource->length;
+ if (bytes_unparsed > 0)
+ resource = (acpi_resource *)((u8 *)resource + resource->length);
}
+
+ return -ENODEV;
+}
+
+
+static int
+acpi_pci_set_link_irq (
+ acpi_handle handle,
+ u32 index,
+ u32 irq)
+{
+ acpi_status status = AE_OK;
+ acpi_buffer buffer = {0, NULL};
+ struct {
+ acpi_resource res;
+ acpi_resource end;
+ } resource;
+ int bytes_unparsed = 0;
+ int i = 0;
+
+
+ if (!handle)
+ return -EINVAL;
+
+ memset(&resource, 0, sizeof(resource));
+ resource.res.id = ACPI_RSTYPE_IRQ;
+ resource.res.length = sizeof(acpi_resource);
+ resource.res.data.irq.edge_level = 0; // FIXME?
+ resource.res.data.irq.active_high_low = 0;
+ resource.res.data.irq.shared_exclusive = 1;
+ resource.res.data.irq.number_of_interrupts = 1;
+ resource.res.data.irq.interrupts[0] = irq;
+ resource.end.id = ACPI_RSTYPE_END_TAG;
+
+ buffer.pointer = &resource;
+ buffer.length = resource.res.length + 1;
+ status = acpi_set_current_resources(handle, &buffer);
+
+ if (status != AE_OK)
+ return -ENODEV;

return 0;
}
@@ -243,17 +370,15 @@

/* Type 1 (dynamic)? */
if (prt->source) {
- acpi_handle link_handle = NULL;
- acpi_get_handle(handle, prt->source, &link_handle);
- acpi_pci_get_link_irq(link_handle, prt->source_index,
- &prt->source_index);
- prt->source[0] = 0;
+ prt->link_handle = NULL;
+ acpi_get_handle(handle, prt->source, &prt->link_handle);
+/* prt->source[0] = 0; */
}

#ifdef CONFIG_ACPI_DEBUG
- printk(KERN_INFO " device=%02x pin=%02x irq=%d\n",
+ printk(KERN_INFO " device=%02x pin=%02x source=%s source_index=%d\n",
(u32)(prt->address>>16), (u32)prt->pin,
- (u32)prt->source_index);
+ prt->source, (u32)prt->source_index);
#endif /*CONFIG_ACPI_DEBUG*/

acpi_prt.count++;
@@ -266,6 +391,92 @@
}


+static acpi_pci_routing_table *
+acpi_pci_find_routing_table_entry(struct pci_dev *dev, u8 pin)
+{
+ int busnr = dev->bus->number;
+ acpi_pci_routing_table *prt = NULL;
+
+ if (busnr >= ACPI_PCI_MAX_BUS)
+ return 0;
+
+ prt = (acpi_pci_routing_table *) acpi_prt.entry[busnr];
+ while (prt && prt->length > 0) {
+ if ((prt->address >> 16) == PCI_SLOT(dev->devfn) && prt->pin == pin)
+ return prt;
+ prt = (acpi_pci_routing_table *)
+ ((u8 *) prt + prt->length);
+ }
+ return prt;
+}
+
+
+int
+acpi_pci_get_current_irq(struct pci_dev *dev, u8 pin, int *irq)
+{
+ acpi_pci_routing_table *prt;
+
+ *irq = 0;
+
+ prt = acpi_pci_find_routing_table_entry(dev, pin);
+ if (!prt)
+ return -ENODEV;
+
+ /* Type 1 (dynamic)? */
+ if (prt->source) {
+ return acpi_pci_get_link_irq(prt->link_handle,
+ prt->source_index, irq);
+ } else {
+ *irq = prt->source_index;
+ return 0;
+ }
+}
+
+
+int
+acpi_pci_get_possible_irq_mask(struct pci_dev *dev, u8 pin, int *mask)
+{
+ acpi_pci_routing_table *prt;
+
+ *mask = 0;
+
+ prt = acpi_pci_find_routing_table_entry(dev, pin);
+ if (!prt)
+ return -ENODEV;
+
+ /* Type 1 (dynamic)? */
+ if (prt->source) {
+ return acpi_pci_get_link_irq_mask(prt->link_handle,
+ prt->source_index, mask);
+ } else {
+ *mask = 1 << prt->source_index;
+ return 0;
+ }
+}
+
+
+int
+acpi_pci_set_current_irq(struct pci_dev *dev, u8 pin, int irq)
+{
+ acpi_pci_routing_table *prt;
+
+ prt = acpi_pci_find_routing_table_entry(dev, pin);
+ if (!prt)
+ return -ENODEV;
+
+ /* Type 1 (dynamic)? */
+ if (prt->source) {
+ return acpi_pci_set_link_irq(prt->link_handle,
+ prt->source_index, irq);
+ } else {
+ if (irq != prt->source_index)
+ return -ENODEV;
+
+ return 0;
+ }
+}
+
+
static acpi_status __init
acpi_pci_resolve_bus (
acpi_handle handle,
@@ -432,5 +643,3 @@
return 0;
}

-
-
diff -X excl -urN linux-2.4.17.patches/drivers/acpi/include/actypes.h linux-2.4.17.work/drivers/acpi/include/actypes.h
--- linux-2.4.17.patches/drivers/acpi/include/actypes.h Mon Jan 14 23:55:08 2002
+++ linux-2.4.17.work/drivers/acpi/include/actypes.h Fri Dec 28 23:16:25 2001
@@ -1125,6 +1125,7 @@
u32 pin;
acpi_integer address; /* here for 64-bit alignment */
u32 source_index;
+ void *link_handle;
NATIVE_CHAR source[4]; /* pad to 64 bits so sizeof() works in all cases */

} acpi_pci_routing_table;

2002-01-17 16:39:12

by Jes Sorensen

[permalink] [raw]
Subject: Re: [patch] VAIO irq assignment fix

>>>>> "Kai" == Kai Germaschewski <[email protected]> writes:

Kai> On Thu, 17 Jan 2002, Jes Sorensen wrote:
>> I think it's in the ACPI table since a certain M$ OS finds the
>> interrupt source. As I mentioned to Alan, I tried the latest ACPI
>> patch but as you say, nothing is done with the information. I haven't
>> tried enabling ACPI_DEBUG but that sounds to be a next step.

Kai> ACPI_DEBUG should print the table at least :)

Kai> My patch is appended, it applies on top of 2.4.17+acpi-20011218

Tried it and I can report your patch works as well. I guess I'll need to
modify my patch to not mangle things if your patch is installed, or at
least we should keep my patch in place until the latest ACPI gets
integrated.

Cheers,
Jes

2002-01-17 17:06:14

by Dave Jones

[permalink] [raw]
Subject: Re: [patch] VAIO irq assignment fix

On Thu, 17 Jan 2002, Jes Sorensen wrote:

> Tried it and I can report your patch works as well. I guess I'll need to
> modify my patch to not mangle things if your patch is installed, or at
> least we should keep my patch in place until the latest ACPI gets
> integrated.

Your patch is also useful for the case of CONFIG_ACPI=n
Worth keeping for that alone. I think it needs mangling a little
to look a bit more like the similar HP workaround though,
but thats a minor nit.

--
| Dave Jones. http://www.codemonkey.org.uk
| SuSE Labs

2002-01-17 22:37:44

by Linus Torvalds

[permalink] [raw]
Subject: Re: [patch] VAIO irq assignment fix


On Thu, 17 Jan 2002, Dave Jones wrote:
>
> Your patch is also useful for the case of CONFIG_ACPI=n
> Worth keeping for that alone.

No. Could we please integrate this not with ACPI, but with the much more
limited "arch/i386/kernel/acpitable.c", which does NOT imply full ACPI,
only scanning the tables for information in static format (like the irq
routing stuff).

That we can/will/should always enable, and we should NOT EVER encourage
this kind of "per-BIOS" crud. That just becomes a total horror to maintain
in the long run.

Please?

Linus

2002-01-17 23:13:16

by Dave Jones

[permalink] [raw]
Subject: Re: [patch] VAIO irq assignment fix

On Thu, Jan 17, 2002 at 02:35:30PM -0800, Linus Torvalds wrote:
> No. Could we please integrate this not with ACPI, but with the much more
> limited "arch/i386/kernel/acpitable.c", which does NOT imply full ACPI,
> only scanning the tables for information in static format (like the irq
> routing stuff).

I was under the impression that the Intel ACPI folks had things in
mind for acpitable.c along the lines of 'rm', in favour of having
their new interpretor do a "Load, setup, get the hell out" approach
for those that didn't want it staying around.

Either way, I agree improving our ACPI support is a better solution
in the long run.

--
| Dave Jones. http://www.codemonkey.org.uk
| SuSE Labs

2002-01-17 23:14:46

by Kai Germaschewski

[permalink] [raw]
Subject: Re: [patch] VAIO irq assignment fix

On Thu, 17 Jan 2002, Linus Torvalds wrote:

> No. Could we please integrate this not with ACPI, but with the much more
> limited "arch/i386/kernel/acpitable.c", which does NOT imply full ACPI,
> only scanning the tables for information in static format (like the irq
> routing stuff).

Unfortunately, the PCI interrupt routing stuff in ACPI is not in a static
table, but needs the full-blown AML interpreter. Bad, but we can't do
anything about it.

> That we can/will/should always enable, and we should NOT EVER encourage
> this kind of "per-BIOS" crud. That just becomes a total horror to maintain
> in the long run.

There's one thing which may be worth doing, I think someone else did
suggest this before: Allow for overriding BIOS tables with user provided
correct ones. In this case, Jes could add an entry for the PCMCIA bridge
to the $PIR table and tell the kernel to use this instead of the buggy
BIOS' one.

The question is how to do this cleanly. Of course, it's easy enough to
invent some way to use a corrected table which is linked into vmlinux at
compile time. However, that means that the user has to recompile his
kernel to add the table, which is not an easy option for everyone.

It would be nicer to dynamically add the table, e.g. have the bootloader
load it, kind of like the initrd, but that seems not possible without a
lot of effort. (Or is the initrd protocol flexible enough to allow for
this?)

--Kai

2002-01-18 00:02:29

by Andrew Grover

[permalink] [raw]
Subject: RE: [patch] VAIO irq assignment fix

> From: Dave Jones [mailto:[email protected]]
> I was under the impression that the Intel ACPI folks had things in
> mind for acpitable.c along the lines of 'rm', in favour of having
> their new interpretor do a "Load, setup, get the hell out" approach
> for those that didn't want it staying around.

acpitable.c was written to support machines with a bad MPS table but a valid
$PIR. The 20011218 ACPI patch more closely integrates that code with the
rest, but the ability to get at the MADT (the ACPI MPS replacement table)
and other tables without the interpreter is still supported. The code is
under drivers/acpi, though.

I don't see that option going away any time soon.

However, without a valid $PIR (which is what is becoming more common and is
the Sony's problem) you need the interpreter, like Kai mentioned. We are
working to incorporate Kai's code into the next acpi patch, which will
evaluate and use _PRT properly. In fact, that's just what I was working on
this afternoon, so Real Soon Now. ;-)

Regards -- Andy

2002-01-18 00:21:52

by Alan

[permalink] [raw]
Subject: Re: [patch] VAIO irq assignment fix

> Unfortunately, the PCI interrupt routing stuff in ACPI is not in a static
> table, but needs the full-blown AML interpreter. Bad, but we can't do
> anything about it.

Is that true of the MPS table as well ? Can you deduce one from the other
even if you dont have a usable APIC ?

> It would be nicer to dynamically add the table, e.g. have the bootloader
> load it, kind of like the initrd, but that seems not possible without a
> lot of effort. (Or is the initrd protocol flexible enough to allow for
> this?)

It may not be enough. The AML can be doing register setup and configuration.

2002-01-18 00:30:02

by Ben Greear

[permalink] [raw]
Subject: Re: [patch] VAIO irq assignment fix



Dave Jones wrote:

> On Thu, Jan 17, 2002 at 02:35:30PM -0800, Linus Torvalds wrote:
> > No. Could we please integrate this not with ACPI, but with the much more
> > limited "arch/i386/kernel/acpitable.c", which does NOT imply full ACPI,
> > only scanning the tables for information in static format (like the irq
> > routing stuff).
>
> I was under the impression that the Intel ACPI folks had things in
> mind for acpitable.c along the lines of 'rm', in favour of having
> their new interpretor do a "Load, setup, get the hell out" approach
> for those that didn't want it staying around.
>
> Either way, I agree improving our ACPI support is a better solution
> in the long run.


No argument here, but I'd love to use my cardbus NICs in my VAIO
one way or another in the next stable kernel!


>
>


--
Ben Greear <[email protected]> <Ben_Greear AT excite.com>
President of Candela Technologies Inc http://www.candelatech.com
ScryMUD: http://scry.wanfear.com http://scry.wanfear.com/~greear


2002-01-21 19:01:02

by Lee Packham

[permalink] [raw]
Subject: RE: [patch] VAIO irq assignment fix

Now... I have a Sony Vaio FX-103 with the RICOH RL5C476 not the 75. The
laptop has 192 MB of RAM (not the standard 64) and a 10gb harddisk.
Mandrake 8.1 with a 2.4.16 kernel with a USB PCI IRQ Routing patch to
make USB work (yes I am waiting heavily for the ACPI stuff!).

Anyhow, no matter what I do (including your patch modified to work on
the different controller) I cannot get two cards to work inside this
laptop.

One is a wireless card, one is a compact flash converter thing (for the
camera).

Both cards work individually. The laptop locks up if I insert both
cards. There is no OOPS or anything... It just locks up. Removing the
cards does not spring it back to life.

It is probably down to the fact that the Vaio laptops assign everything
IRQ9. Please find attached my /proc/interrupts and lspci -vvv.

Any ideas?

Thanks

Lee P.



-----Original Message-----
From: [email protected]
[mailto:[email protected]] On Behalf Of Alan Cox
Sent: 18 January 2002 00:33
To: Kai Germaschewski
Cc: Linus Torvalds; Dave Jones; Jes Sorensen; Alan Cox;
[email protected]; Marcelo Tosatti
Subject: Re: [patch] VAIO irq assignment fix

> Unfortunately, the PCI interrupt routing stuff in ACPI is not in a
static
> table, but needs the full-blown AML interpreter. Bad, but we can't do
> anything about it.

Is that true of the MPS table as well ? Can you deduce one from the
other
even if you dont have a usable APIC ?

> It would be nicer to dynamically add the table, e.g. have the
bootloader
> load it, kind of like the initrd, but that seems not possible without
a
> lot of effort. (Or is the initrd protocol flexible enough to allow for

> this?)

It may not be enough. The AML can be doing register setup and
configuration.


Attachments:
lspci (7.28 kB)
interrupts.txt (503.00 B)
Download all attachments

2002-01-21 20:06:58

by Manfred Spraul

[permalink] [raw]
Subject: Re: [patch] VAIO irq assignment fix

Lee Packham wrote:
>
> Now... I have a Sony Vaio FX-103 with the RICOH RL5C476 not the 75. The
> laptop has 192 MB of RAM (not the standard 64) and a 10gb harddisk.
> Mandrake 8.1 with a 2.4.16 kernel with a USB PCI IRQ Routing patch to
> make USB work (yes I am waiting heavily for the ACPI stuff!).
>
> Anyhow, no matter what I do (including your patch modified to work on
> the different controller) I cannot get two cards to work inside this
> laptop.
>
Have you tried Ingo's IRQ rate limiter? Perhaps someone forgets to send
an EOI to the hardware, and then everything locks up due to a level
triggered interrupt that remains active forever.

http://groups.google.com/groups?hl=en&selm=fa.o69hfov.tl2696%40ifi.uio.no&rnum=5

--
Manfre

2002-01-22 18:04:21

by Gunther Mayer

[permalink] [raw]
Subject: Re: [patch] VAIO irq assignment fix ->CompactFlash-pcmcia freeze

diff -ur linux-2.4.15.orig/drivers/ide/ide-cs.c linux/drivers/ide/ide-cs.c
--- linux-2.4.15.orig/drivers/ide/ide-cs.c Sun Sep 30 21:26:05 2001
+++ linux/drivers/ide/ide-cs.c Sun Nov 25 13:11:36 2001
@@ -42,6 +42,7 @@
#include <linux/ioport.h>
#include <linux/hdreg.h>
#include <linux/major.h>
+#include <linux/ide.h>

#include <asm/io.h>
#include <asm/system.h>
@@ -226,6 +227,16 @@
#define CFG_CHECK(fn, args...) \
if (CardServices(fn, args) != 0) goto next_entry

+int idecs_register (int io_base, int ctl_base, int irq)
+{
+ hw_regs_t hw;
+ ide_init_hwif_ports(&hw, (ide_ioreg_t) io_base, (ide_ioreg_t) ctl_base, NULL);
+ hw.irq = irq;
+ hw.chipset = ide_pci; // this enables IRQ sharing w/ PCI irqs
+ return ide_register_hw(&hw, NULL);
+}
+
+
void ide_config(dev_link_t *link)
{
client_handle_t handle = link->handle;
@@ -327,12 +338,16 @@
if (link->io.NumPorts2)
release_region(link->io.BasePort2, link->io.NumPorts2);

+ /* disable drive interrupts during IDE probe */
+ if(ctl_base)
+ outb(0x02, ctl_base);
+
/* retry registration in case device is still spinning up */
for (i = 0; i < 10; i++) {
- hd = ide_register(io_base, ctl_base, link->irq.AssignedIRQ);
+ hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ);
if (hd >= 0) break;
if (link->io.NumPorts1 == 0x20) {
- hd = ide_register(io_base+0x10, ctl_base+0x10,
+ hd = idecs_register(io_base+0x10, ctl_base+0x10,
link->irq.AssignedIRQ);
if (hd >= 0) {
io_base += 0x10; ctl_base += 0x10;
Only in linux/drivers/ide: ide-cs.c-2415
diff -ur linux-2.4.15.orig/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.4.15.orig/drivers/ide/ide.c Thu Oct 25 22:58:35 2001
+++ linux/drivers/ide/ide.c Sun Nov 25 13:02:34 2001
@@ -2293,6 +2293,7 @@
memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));
hwif->irq = hw->irq;
hwif->noprobe = 0;
+ hwif->chipset = hw->chipset;

if (!initializing) {
ide_probe_module();
diff -ur linux-2.4.15.orig/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.4.15.orig/include/linux/ide.h Thu Nov 22 20:48:07 2001
+++ linux/include/linux/ide.h Sun Nov 25 13:05:57 2001
@@ -223,6 +223,23 @@
#endif

/*
+ * hwif_chipset_t is used to keep track of the specific hardware
+ * chipset used by each IDE interface, if known.
+ */
+typedef enum { ide_unknown, ide_generic, ide_pci,
+ ide_cmd640, ide_dtc2278, ide_ali14xx,
+ ide_qd65xx, ide_umc8672, ide_ht6560b,
+ ide_pdc4030, ide_rz1000, ide_trm290,
+ ide_cmd646, ide_cy82c693, ide_4drives,
+ ide_pmac, ide_etrax100
+} hwif_chipset_t;
+
+#define IDE_CHIPSET_PCI_MASK \
+ ((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx))
+#define IDE_CHIPSET_IS_PCI(c) ((IDE_CHIPSET_PCI_MASK >> (c)) & 1)
+
+
+/*
* Structure to hold all information about the location of this port
*/
typedef struct hw_regs_s {
@@ -231,6 +248,7 @@
int dma; /* our dma entry */
ide_ack_intr_t *ack_intr; /* acknowledge interrupt */
void *priv; /* interface specific data */
+ hwif_chipset_t chipset;
} hw_regs_t;

/*
@@ -439,22 +457,6 @@
* ide soft-power support
*/
typedef int (ide_busproc_t) (struct hwif_s *, int);
-
-/*
- * hwif_chipset_t is used to keep track of the specific hardware
- * chipset used by each IDE interface, if known.
- */
-typedef enum { ide_unknown, ide_generic, ide_pci,
- ide_cmd640, ide_dtc2278, ide_ali14xx,
- ide_qd65xx, ide_umc8672, ide_ht6560b,
- ide_pdc4030, ide_rz1000, ide_trm290,
- ide_cmd646, ide_cy82c693, ide_4drives,
- ide_pmac, ide_etrax100
-} hwif_chipset_t;
-
-#define IDE_CHIPSET_PCI_MASK \
- ((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx))
-#define IDE_CHIPSET_IS_PCI(c) ((IDE_CHIPSET_PCI_MASK >> (c)) & 1)

#ifdef CONFIG_BLK_DEV_IDEPCI
typedef struct ide_pci_devid_s {


Attachments:
gmdiff-lx2415-compactflash+pcmcia+PCI (3.84 kB)