* [PATCH 2.6.11.2 1/1] PCI Allow OutOfRange PIRQ table address
@ 2005-03-17 1:24 jayalk
2005-03-17 3:34 ` Randy.Dunlap
0 siblings, 1 reply; 9+ messages in thread
From: jayalk @ 2005-03-17 1:24 UTC (permalink / raw)
To: gregkh; +Cc: linux-kernel, linux-pci
Hi Greg, PCI folk,
I updated this to change pirq_table_addr to a long, and to add a warning
msg if the PIRQ table wasn't found at the specified address, as per thread
with Matthew Wilcox. Let me know if it's okay. Thanks.
In our hardware situation, the BIOS is unable to store or generate it's PIRQ
table in the F0000h-100000h standard range. This patch adds a pci kernel
parameter, pirqaddr to allow the bootloader (or BIOS based loader) to inform
the kernel where the PIRQ table got stored. A beneficial side-effect is that,
if one's BIOS uses a static address each time for it's PIRQ table, then
pirqaddr can be used to avoid the $pirq search through that address block each
time at boot for normal PIRQ BIOSes.
Signed-off-by: Jaya Kumar <jayalk@intworks.biz>
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/pci/common.c linux-2.6.11.2/arch/i386/pci/common.c
--- linux-2.6.11.2-vanilla/arch/i386/pci/common.c 2005-03-10 16:31:25.000000000 +0800
+++ linux-2.6.11.2/arch/i386/pci/common.c 2005-03-11 20:35:41.000000000 +0800
@@ -25,6 +25,7 @@ unsigned int pci_probe = PCI_PROBE_BIOS
int pci_routeirq;
int pcibios_last_bus = -1;
+unsigned long pirq_table_addr = 0;
struct pci_bus *pci_root_bus = NULL;
struct pci_raw_ops *raw_pci_ops;
@@ -188,6 +189,9 @@ char * __devinit pcibios_setup(char *st
} else if (!strcmp(str, "biosirq")) {
pci_probe |= PCI_BIOS_IRQ_SCAN;
return NULL;
+ } else if (!strncmp(str, "pirqaddr=", 9)) {
+ pirq_table_addr = simple_strtol(str+9, NULL, 0);
+ return NULL;
}
#endif
#ifdef CONFIG_PCI_DIRECT
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/pci/irq.c linux-2.6.11.2/arch/i386/pci/irq.c
--- linux-2.6.11.2-vanilla/arch/i386/pci/irq.c 2005-03-10 16:31:25.000000000 +0800
+++ linux-2.6.11.2/arch/i386/pci/irq.c 2005-03-11 20:40:28.000000000 +0800
@@ -58,6 +58,35 @@ struct irq_router_handler {
int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
/*
+ * Check passed address for the PCI IRQ Routing Table signature
+ * and perform checksum verification.
+ */
+
+static inline struct irq_routing_table * __init pirq_check_routing_table(u8 *addr)
+{
+ struct irq_routing_table *rt;
+ int i;
+ u8 sum;
+
+ rt = (struct irq_routing_table *) addr;
+ if (rt->signature != PIRQ_SIGNATURE ||
+ rt->version != PIRQ_VERSION ||
+ rt->size % 16 ||
+ rt->size < sizeof(struct irq_routing_table))
+ return NULL;
+ sum = 0;
+ for(i=0; i<rt->size; i++)
+ sum += addr[i];
+ if (!sum) {
+ DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
+ return rt;
+ }
+ return NULL;
+}
+
+
+
+/*
* Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
*/
@@ -65,21 +94,17 @@ static struct irq_routing_table * __init
{
u8 *addr;
struct irq_routing_table *rt;
- int i;
- u8 sum;
+ if (pirq_table_addr) {
+ rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr));
+ if (rt) {
+ return rt;
+ }
+ printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n");
+ }
for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
- rt = (struct irq_routing_table *) addr;
- if (rt->signature != PIRQ_SIGNATURE ||
- rt->version != PIRQ_VERSION ||
- rt->size % 16 ||
- rt->size < sizeof(struct irq_routing_table))
- continue;
- sum = 0;
- for(i=0; i<rt->size; i++)
- sum += addr[i];
- if (!sum) {
- DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
+ rt = pirq_check_routing_table(addr);
+ if (rt) {
return rt;
}
}
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/pci/pci.h linux-2.6.11.2/arch/i386/pci/pci.h
--- linux-2.6.11.2-vanilla/arch/i386/pci/pci.h 2005-03-10 16:31:25.000000000 +0800
+++ linux-2.6.11.2/arch/i386/pci/pci.h 2005-03-11 20:35:55.000000000 +0800
@@ -27,6 +27,7 @@
#define PCI_ASSIGN_ALL_BUSSES 0x4000
extern unsigned int pci_probe;
+extern unsigned long pirq_table_addr;
/* pci-i386.c */
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/Documentation/kernel-parameters.txt linux-2.6.11.2/Documentation/kernel-parameters.txt
--- linux-2.6.11.2-vanilla/Documentation/kernel-parameters.txt 2005-03-10 16:31:44.000000000 +0800
+++ linux-2.6.11.2/Documentation/kernel-parameters.txt 2005-03-10 16:45:48.000000000 +0800
@@ -967,6 +967,10 @@ running once the system is up.
irqmask=0xMMMM [IA-32] Set a bit mask of IRQs allowed to be assigned
automatically to PCI devices. You can make the kernel
exclude IRQs of your ISA cards this way.
+ pirqaddr=0xAAAAA [IA-32] Specify the physical address
+ of the PIRQ table (normally generated
+ by the BIOS) if it is outside the .
+ F0000h-100000h range.
lastbus=N [IA-32] Scan all buses till bus #N. Can be useful
if the kernel is unable to find your secondary buses
and you want to tell it explicitly which ones they are.
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH 2.6.11.2 1/1] PCI Allow OutOfRange PIRQ table address
2005-03-17 1:24 [PATCH 2.6.11.2 1/1] PCI Allow OutOfRange PIRQ table address jayalk
@ 2005-03-17 3:34 ` Randy.Dunlap
0 siblings, 0 replies; 9+ messages in thread
From: Randy.Dunlap @ 2005-03-17 3:34 UTC (permalink / raw)
To: jayalk; +Cc: gregkh, linux-kernel, linux-pci
jayalk@intworks.biz wrote:
> Hi Greg, PCI folk,
>
> I updated this to change pirq_table_addr to a long, and to add a warning
> msg if the PIRQ table wasn't found at the specified address, as per thread
> with Matthew Wilcox. Let me know if it's okay. Thanks.
>
> In our hardware situation, the BIOS is unable to store or generate it's PIRQ
> table in the F0000h-100000h standard range. This patch adds a pci kernel
> parameter, pirqaddr to allow the bootloader (or BIOS based loader) to inform
> the kernel where the PIRQ table got stored. A beneficial side-effect is that,
> if one's BIOS uses a static address each time for it's PIRQ table, then
> pirqaddr can be used to avoid the $pirq search through that address block each
> time at boot for normal PIRQ BIOSes.
>
> Signed-off-by: Jaya Kumar <jayalk@intworks.biz>
>
> diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/pci/common.c linux-2.6.11.2/arch/i386/pci/common.c
> --- linux-2.6.11.2-vanilla/arch/i386/pci/common.c 2005-03-10 16:31:25.000000000 +0800
> +++ linux-2.6.11.2/arch/i386/pci/common.c 2005-03-11 20:35:41.000000000 +0800
> @@ -25,6 +25,7 @@ unsigned int pci_probe = PCI_PROBE_BIOS
>
> int pci_routeirq;
> int pcibios_last_bus = -1;
> +unsigned long pirq_table_addr = 0;
Don't need to init above (or below) to 0.
> struct pci_bus *pci_root_bus = NULL;
> struct pci_raw_ops *raw_pci_ops;
>
> @@ -188,6 +189,9 @@ char * __devinit pcibios_setup(char *st
> } else if (!strcmp(str, "biosirq")) {
> pci_probe |= PCI_BIOS_IRQ_SCAN;
> return NULL;
> + } else if (!strncmp(str, "pirqaddr=", 9)) {
> + pirq_table_addr = simple_strtol(str+9, NULL, 0);
Use simple_strtoul().
> + return NULL;
> }
> #endif
> #ifdef CONFIG_PCI_DIRECT
> diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/pci/irq.c linux-2.6.11.2/arch/i386/pci/irq.c
> --- linux-2.6.11.2-vanilla/arch/i386/pci/irq.c 2005-03-10 16:31:25.000000000 +0800
> +++ linux-2.6.11.2/arch/i386/pci/irq.c 2005-03-11 20:40:28.000000000 +0800
> @@ -58,6 +58,35 @@ struct irq_router_handler {
> int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
>
> /*
> + * Check passed address for the PCI IRQ Routing Table signature
> + * and perform checksum verification.
> + */
> +
> +static inline struct irq_routing_table * __init pirq_check_routing_table(u8 *addr)
This doesn't need to be both inline and __init.
> +{
> + struct irq_routing_table *rt;
> + int i;
> + u8 sum;
> +
> + rt = (struct irq_routing_table *) addr;
> + if (rt->signature != PIRQ_SIGNATURE ||
> + rt->version != PIRQ_VERSION ||
> + rt->size % 16 ||
> + rt->size < sizeof(struct irq_routing_table))
> + return NULL;
> + sum = 0;
> + for(i=0; i<rt->size; i++)
Space after for: "for ("
Spaces around "<" would be nice for readability.
> + sum += addr[i];
> + if (!sum) {
> + DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
> + return rt;
> + }
> + return NULL;
> +}
> +
> +
> +
> +/*
> * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
> */
>
> @@ -65,21 +94,17 @@ static struct irq_routing_table * __init
> {
> u8 *addr;
> struct irq_routing_table *rt;
> - int i;
> - u8 sum;
>
> + if (pirq_table_addr) {
> + rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr));
> + if (rt) {
> + return rt;
> + }
No braces when not needed for block of statements.
> + printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n");
> + }
> for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
> - rt = (struct irq_routing_table *) addr;
> - if (rt->signature != PIRQ_SIGNATURE ||
> - rt->version != PIRQ_VERSION ||
> - rt->size % 16 ||
> - rt->size < sizeof(struct irq_routing_table))
> - continue;
> - sum = 0;
> - for(i=0; i<rt->size; i++)
> - sum += addr[i];
> - if (!sum) {
> - DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
> + rt = pirq_check_routing_table(addr);
> + if (rt) {
> return rt;
> }
> }
> diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/pci/pci.h linux-2.6.11.2/arch/i386/pci/pci.h
> --- linux-2.6.11.2-vanilla/arch/i386/pci/pci.h 2005-03-10 16:31:25.000000000 +0800
> +++ linux-2.6.11.2/arch/i386/pci/pci.h 2005-03-11 20:35:55.000000000 +0800
> @@ -27,6 +27,7 @@
> #define PCI_ASSIGN_ALL_BUSSES 0x4000
>
> extern unsigned int pci_probe;
> +extern unsigned long pirq_table_addr;
>
> /* pci-i386.c */
>
> diff -uprN -X dontdiff linux-2.6.11.2-vanilla/Documentation/kernel-parameters.txt linux-2.6.11.2/Documentation/kernel-parameters.txt
> --- linux-2.6.11.2-vanilla/Documentation/kernel-parameters.txt 2005-03-10 16:31:44.000000000 +0800
> +++ linux-2.6.11.2/Documentation/kernel-parameters.txt 2005-03-10 16:45:48.000000000 +0800
> @@ -967,6 +967,10 @@ running once the system is up.
> irqmask=0xMMMM [IA-32] Set a bit mask of IRQs allowed to be assigned
> automatically to PCI devices. You can make the kernel
> exclude IRQs of your ISA cards this way.
> + pirqaddr=0xAAAAA [IA-32] Specify the physical address
> + of the PIRQ table (normally generated
> + by the BIOS) if it is outside the .
What is the trailing " . " here? (above)
> + F0000h-100000h range.
> lastbus=N [IA-32] Scan all buses till bus #N. Can be useful
> if the kernel is unable to find your secondary buses
> and you want to tell it explicitly which ones they are.
> -
--
~Randy
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2.6.11.2 1/1] PCI Allow OutOfRange PIRQ table address
@ 2005-03-22 4:20 jayalk
0 siblings, 0 replies; 9+ messages in thread
From: jayalk @ 2005-03-22 4:20 UTC (permalink / raw)
To: gregkh; +Cc: linux-kernel, linux-pci
Hi Greg, PCI folk,
I updated this to remove unnecessary variable initialization, make
check_routing be inline only and not __init, switch to strtoul, and
formatting fixes as per Randy Dunlap's recommendations.
I updated this to change pirq_table_addr to a long, and to add a warning
msg if the PIRQ table wasn't found at the specified address, as per thread
with Matthew Wilcox.
In our hardware situation, the BIOS is unable to store or generate it's PIRQ
table in the F0000h-100000h standard range. This patch adds a pci kernel
parameter, pirqaddr to allow the bootloader (or BIOS based loader) to inform
the kernel where the PIRQ table got stored. A beneficial side-effect is that,
if one's BIOS uses a static address each time for it's PIRQ table, then
pirqaddr can be used to avoid the $pirq search through that address block each
time at boot for normal PIRQ BIOSes.
---
Signed-off-by: Jaya Kumar <jayalk@intworks.biz>
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/pci/common.c linux-2.6.11.2/arch/i386/pci/common.c
--- linux-2.6.11.2-vanilla/arch/i386/pci/common.c 2005-03-10 16:31:25.000000000 +0800
+++ linux-2.6.11.2/arch/i386/pci/common.c 2005-03-17 14:25:54.111123816 +0800
@@ -25,7 +25,8 @@ unsigned int pci_probe = PCI_PROBE_BIOS
int pci_routeirq;
int pcibios_last_bus = -1;
-struct pci_bus *pci_root_bus = NULL;
+unsigned long pirq_table_addr;
+struct pci_bus *pci_root_bus;
struct pci_raw_ops *raw_pci_ops;
static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
@@ -188,6 +189,9 @@ char * __devinit pcibios_setup(char *st
} else if (!strcmp(str, "biosirq")) {
pci_probe |= PCI_BIOS_IRQ_SCAN;
return NULL;
+ } else if (!strncmp(str, "pirqaddr=", 9)) {
+ pirq_table_addr = simple_strtoul(str+9, NULL, 0);
+ return NULL;
}
#endif
#ifdef CONFIG_PCI_DIRECT
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/pci/irq.c linux-2.6.11.2/arch/i386/pci/irq.c
--- linux-2.6.11.2-vanilla/arch/i386/pci/irq.c 2005-03-10 16:31:25.000000000 +0800
+++ linux-2.6.11.2/arch/i386/pci/irq.c 2005-03-17 14:04:22.000000000 +0800
@@ -58,6 +58,35 @@ struct irq_router_handler {
int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
/*
+ * Check passed address for the PCI IRQ Routing Table signature
+ * and perform checksum verification.
+ */
+
+static inline struct irq_routing_table * pirq_check_routing_table(u8 *addr)
+{
+ struct irq_routing_table *rt;
+ int i;
+ u8 sum;
+
+ rt = (struct irq_routing_table *) addr;
+ if (rt->signature != PIRQ_SIGNATURE ||
+ rt->version != PIRQ_VERSION ||
+ rt->size % 16 ||
+ rt->size < sizeof(struct irq_routing_table))
+ return NULL;
+ sum = 0;
+ for (i=0; i < rt->size; i++)
+ sum += addr[i];
+ if (!sum) {
+ DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
+ return rt;
+ }
+ return NULL;
+}
+
+
+
+/*
* Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
*/
@@ -65,23 +94,17 @@ static struct irq_routing_table * __init
{
u8 *addr;
struct irq_routing_table *rt;
- int i;
- u8 sum;
+ if (pirq_table_addr) {
+ rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr));
+ if (rt)
+ return rt;
+ printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n");
+ }
for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
- rt = (struct irq_routing_table *) addr;
- if (rt->signature != PIRQ_SIGNATURE ||
- rt->version != PIRQ_VERSION ||
- rt->size % 16 ||
- rt->size < sizeof(struct irq_routing_table))
- continue;
- sum = 0;
- for(i=0; i<rt->size; i++)
- sum += addr[i];
- if (!sum) {
- DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
+ rt = pirq_check_routing_table(addr);
+ if (rt)
return rt;
- }
}
return NULL;
}
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/pci/pci.h linux-2.6.11.2/arch/i386/pci/pci.h
--- linux-2.6.11.2-vanilla/arch/i386/pci/pci.h 2005-03-10 16:31:25.000000000 +0800
+++ linux-2.6.11.2/arch/i386/pci/pci.h 2005-03-17 08:54:36.000000000 +0800
@@ -27,6 +27,7 @@
#define PCI_ASSIGN_ALL_BUSSES 0x4000
extern unsigned int pci_probe;
+extern unsigned long pirq_table_addr;
/* pci-i386.c */
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/Documentation/kernel-parameters.txt linux-2.6.11.2/Documentation/kernel-parameters.txt
--- linux-2.6.11.2-vanilla/Documentation/kernel-parameters.txt 2005-03-10 16:31:44.000000000 +0800
+++ linux-2.6.11.2/Documentation/kernel-parameters.txt 2005-03-17 13:01:20.000000000 +0800
@@ -967,6 +967,10 @@ running once the system is up.
irqmask=0xMMMM [IA-32] Set a bit mask of IRQs allowed to be assigned
automatically to PCI devices. You can make the kernel
exclude IRQs of your ISA cards this way.
+ pirqaddr=0xAAAAA [IA-32] Specify the physical address
+ of the PIRQ table (normally generated
+ by the BIOS) if it is outside the
+ F0000h-100000h range.
lastbus=N [IA-32] Scan all buses till bus #N. Can be useful
if the kernel is unable to find your secondary buses
and you want to tell it explicitly which ones they are.
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 2.6.11.2 1/1] PCI Allow OutOfRange PIRQ table address
@ 2005-03-17 6:50 jayalk
0 siblings, 0 replies; 9+ messages in thread
From: jayalk @ 2005-03-17 6:50 UTC (permalink / raw)
To: gregkh; +Cc: linux-kernel, linux-pci
Hi Greg, PCI folk,
Sorry, just also did the simple_strtol to strtoul. Let me know if it's okay.
Thanks.
---
I updated this to remove unnecessary variable initialization, make
check_routing be inline only and not __init, and formatting fixes as per
Randy Dunlap's recommendations.
I updated this to change pirq_table_addr to a long, and to add a warning
msg if the PIRQ table wasn't found at the specified address, as per thread
with Matthew Wilcox.
In our hardware situation, the BIOS is unable to store or generate it's PIRQ
table in the F0000h-100000h standard range. This patch adds a pci kernel
parameter, pirqaddr to allow the bootloader (or BIOS based loader) to inform
the kernel where the PIRQ table got stored. A beneficial side-effect is that,
if one's BIOS uses a static address each time for it's PIRQ table, then
pirqaddr can be used to avoid the $pirq search through that address block each
time at boot for normal PIRQ BIOSes.
---
Signed-off-by: Jaya Kumar <jayalk@intworks.biz>
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/pci/common.c linux-2.6.11.2/arch/i386/pci/common.c
--- linux-2.6.11.2-vanilla/arch/i386/pci/common.c 2005-03-10 16:31:25.000000000 +0800
+++ linux-2.6.11.2/arch/i386/pci/common.c 2005-03-17 14:25:54.111123816 +0800
@@ -25,7 +25,8 @@ unsigned int pci_probe = PCI_PROBE_BIOS
int pci_routeirq;
int pcibios_last_bus = -1;
-struct pci_bus *pci_root_bus = NULL;
+unsigned long pirq_table_addr;
+struct pci_bus *pci_root_bus;
struct pci_raw_ops *raw_pci_ops;
static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
@@ -188,6 +189,9 @@ char * __devinit pcibios_setup(char *st
} else if (!strcmp(str, "biosirq")) {
pci_probe |= PCI_BIOS_IRQ_SCAN;
return NULL;
+ } else if (!strncmp(str, "pirqaddr=", 9)) {
+ pirq_table_addr = simple_strtoul(str+9, NULL, 0);
+ return NULL;
}
#endif
#ifdef CONFIG_PCI_DIRECT
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/pci/irq.c linux-2.6.11.2/arch/i386/pci/irq.c
--- linux-2.6.11.2-vanilla/arch/i386/pci/irq.c 2005-03-10 16:31:25.000000000 +0800
+++ linux-2.6.11.2/arch/i386/pci/irq.c 2005-03-17 14:04:22.000000000 +0800
@@ -58,6 +58,35 @@ struct irq_router_handler {
int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
/*
+ * Check passed address for the PCI IRQ Routing Table signature
+ * and perform checksum verification.
+ */
+
+static inline struct irq_routing_table * pirq_check_routing_table(u8 *addr)
+{
+ struct irq_routing_table *rt;
+ int i;
+ u8 sum;
+
+ rt = (struct irq_routing_table *) addr;
+ if (rt->signature != PIRQ_SIGNATURE ||
+ rt->version != PIRQ_VERSION ||
+ rt->size % 16 ||
+ rt->size < sizeof(struct irq_routing_table))
+ return NULL;
+ sum = 0;
+ for (i=0; i < rt->size; i++)
+ sum += addr[i];
+ if (!sum) {
+ DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
+ return rt;
+ }
+ return NULL;
+}
+
+
+
+/*
* Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
*/
@@ -65,23 +94,17 @@ static struct irq_routing_table * __init
{
u8 *addr;
struct irq_routing_table *rt;
- int i;
- u8 sum;
+ if (pirq_table_addr) {
+ rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr));
+ if (rt)
+ return rt;
+ printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n");
+ }
for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
- rt = (struct irq_routing_table *) addr;
- if (rt->signature != PIRQ_SIGNATURE ||
- rt->version != PIRQ_VERSION ||
- rt->size % 16 ||
- rt->size < sizeof(struct irq_routing_table))
- continue;
- sum = 0;
- for(i=0; i<rt->size; i++)
- sum += addr[i];
- if (!sum) {
- DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
+ rt = pirq_check_routing_table(addr);
+ if (rt)
return rt;
- }
}
return NULL;
}
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/pci/pci.h linux-2.6.11.2/arch/i386/pci/pci.h
--- linux-2.6.11.2-vanilla/arch/i386/pci/pci.h 2005-03-10 16:31:25.000000000 +0800
+++ linux-2.6.11.2/arch/i386/pci/pci.h 2005-03-17 08:54:36.000000000 +0800
@@ -27,6 +27,7 @@
#define PCI_ASSIGN_ALL_BUSSES 0x4000
extern unsigned int pci_probe;
+extern unsigned long pirq_table_addr;
/* pci-i386.c */
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/Documentation/kernel-parameters.txt linux-2.6.11.2/Documentation/kernel-parameters.txt
--- linux-2.6.11.2-vanilla/Documentation/kernel-parameters.txt 2005-03-10 16:31:44.000000000 +0800
+++ linux-2.6.11.2/Documentation/kernel-parameters.txt 2005-03-17 13:01:20.000000000 +0800
@@ -967,6 +967,10 @@ running once the system is up.
irqmask=0xMMMM [IA-32] Set a bit mask of IRQs allowed to be assigned
automatically to PCI devices. You can make the kernel
exclude IRQs of your ISA cards this way.
+ pirqaddr=0xAAAAA [IA-32] Specify the physical address
+ of the PIRQ table (normally generated
+ by the BIOS) if it is outside the
+ F0000h-100000h range.
lastbus=N [IA-32] Scan all buses till bus #N. Can be useful
if the kernel is unable to find your secondary buses
and you want to tell it explicitly which ones they are.
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 2.6.11.2 1/1] PCI Allow OutOfRange PIRQ table address
@ 2005-03-17 6:36 jayalk
0 siblings, 0 replies; 9+ messages in thread
From: jayalk @ 2005-03-17 6:36 UTC (permalink / raw)
To: gregkh; +Cc: linux-kernel, linux-pci
Hi Greg, PCI folk,
I updated this to remove unnecessary variable initialization, make
check_routing be inline only and not __init, and formatting fixes as per
Randy Dunlap's recommendations. Let me know if it's okay. Thanks.
---
I updated this to change pirq_table_addr to a long, and to add a warning
msg if the PIRQ table wasn't found at the specified address, as per thread
with Matthew Wilcox.
In our hardware situation, the BIOS is unable to store or generate it's PIRQ
table in the F0000h-100000h standard range. This patch adds a pci kernel
parameter, pirqaddr to allow the bootloader (or BIOS based loader) to inform
the kernel where the PIRQ table got stored. A beneficial side-effect is that,
if one's BIOS uses a static address each time for it's PIRQ table, then
pirqaddr can be used to avoid the $pirq search through that address block each
time at boot for normal PIRQ BIOSes.
---
Signed-off-by: Jaya Kumar <jayalk@intworks.biz>
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/pci/common.c linux-2.6.11.2/arch/i386/pci/common.c
--- linux-2.6.11.2-vanilla/arch/i386/pci/common.c 2005-03-10 16:31:25.000000000 +0800
+++ linux-2.6.11.2/arch/i386/pci/common.c 2005-03-17 12:58:45.246032136 +0800
@@ -25,7 +25,8 @@ unsigned int pci_probe = PCI_PROBE_BIOS
int pci_routeirq;
int pcibios_last_bus = -1;
-struct pci_bus *pci_root_bus = NULL;
+unsigned long pirq_table_addr;
+struct pci_bus *pci_root_bus;
struct pci_raw_ops *raw_pci_ops;
static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
@@ -188,6 +189,9 @@ char * __devinit pcibios_setup(char *st
} else if (!strcmp(str, "biosirq")) {
pci_probe |= PCI_BIOS_IRQ_SCAN;
return NULL;
+ } else if (!strncmp(str, "pirqaddr=", 9)) {
+ pirq_table_addr = simple_strtol(str+9, NULL, 0);
+ return NULL;
}
#endif
#ifdef CONFIG_PCI_DIRECT
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/pci/irq.c linux-2.6.11.2/arch/i386/pci/irq.c
--- linux-2.6.11.2-vanilla/arch/i386/pci/irq.c 2005-03-10 16:31:25.000000000 +0800
+++ linux-2.6.11.2/arch/i386/pci/irq.c 2005-03-17 14:04:22.924414032 +0800
@@ -58,6 +58,35 @@ struct irq_router_handler {
int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
/*
+ * Check passed address for the PCI IRQ Routing Table signature
+ * and perform checksum verification.
+ */
+
+static inline struct irq_routing_table * pirq_check_routing_table(u8 *addr)
+{
+ struct irq_routing_table *rt;
+ int i;
+ u8 sum;
+
+ rt = (struct irq_routing_table *) addr;
+ if (rt->signature != PIRQ_SIGNATURE ||
+ rt->version != PIRQ_VERSION ||
+ rt->size % 16 ||
+ rt->size < sizeof(struct irq_routing_table))
+ return NULL;
+ sum = 0;
+ for (i=0; i < rt->size; i++)
+ sum += addr[i];
+ if (!sum) {
+ DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
+ return rt;
+ }
+ return NULL;
+}
+
+
+
+/*
* Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
*/
@@ -65,23 +94,17 @@ static struct irq_routing_table * __init
{
u8 *addr;
struct irq_routing_table *rt;
- int i;
- u8 sum;
+ if (pirq_table_addr) {
+ rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr));
+ if (rt)
+ return rt;
+ printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n");
+ }
for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
- rt = (struct irq_routing_table *) addr;
- if (rt->signature != PIRQ_SIGNATURE ||
- rt->version != PIRQ_VERSION ||
- rt->size % 16 ||
- rt->size < sizeof(struct irq_routing_table))
- continue;
- sum = 0;
- for(i=0; i<rt->size; i++)
- sum += addr[i];
- if (!sum) {
- DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
+ rt = pirq_check_routing_table(addr);
+ if (rt)
return rt;
- }
}
return NULL;
}
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/pci/pci.h linux-2.6.11.2/arch/i386/pci/pci.h
--- linux-2.6.11.2-vanilla/arch/i386/pci/pci.h 2005-03-10 16:31:25.000000000 +0800
+++ linux-2.6.11.2/arch/i386/pci/pci.h 2005-03-17 08:54:36.000000000 +0800
@@ -27,6 +27,7 @@
#define PCI_ASSIGN_ALL_BUSSES 0x4000
extern unsigned int pci_probe;
+extern unsigned long pirq_table_addr;
/* pci-i386.c */
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/Documentation/kernel-parameters.txt linux-2.6.11.2/Documentation/kernel-parameters.txt
--- linux-2.6.11.2-vanilla/Documentation/kernel-parameters.txt 2005-03-10 16:31:44.000000000 +0800
+++ linux-2.6.11.2/Documentation/kernel-parameters.txt 2005-03-17 13:01:20.000000000 +0800
@@ -967,6 +967,10 @@ running once the system is up.
irqmask=0xMMMM [IA-32] Set a bit mask of IRQs allowed to be assigned
automatically to PCI devices. You can make the kernel
exclude IRQs of your ISA cards this way.
+ pirqaddr=0xAAAAA [IA-32] Specify the physical address
+ of the PIRQ table (normally generated
+ by the BIOS) if it is outside the
+ F0000h-100000h range.
lastbus=N [IA-32] Scan all buses till bus #N. Can be useful
if the kernel is unable to find your secondary buses
and you want to tell it explicitly which ones they are.
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 2.6.11.2 1/1] PCI Allow OutOfRange PIRQ table address
@ 2005-03-17 1:16 jayalk
0 siblings, 0 replies; 9+ messages in thread
From: jayalk @ 2005-03-17 1:16 UTC (permalink / raw)
To: gregkh; +Cc: linux-kernel, linux-pci
Hi Greg, PCI folk,
In our hardware situation, the BIOS is unable to store or generate it's PIRQ
table in the F0000h-100000h standard range. This patch adds a pci kernel
parameter, pirqaddr to allow the bootloader (or BIOS based loader) to inform
the kernel where the PIRQ table got stored. A beneficial side-effect is that,
if one's BIOS uses a static address each time for it's PIRQ table, then
pirqaddr can be used to avoid the $pirq search through that address block each
time at boot for normal PIRQ BIOSes.
Signed-off-by: Jaya Kumar <jayalk@intworks.biz>
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/pci/common.c linux-2.6.11.2/arch/i386/pci/common.c
--- linux-2.6.11.2-vanilla/arch/i386/pci/common.c 2005-03-10 16:31:25.000000000 +0800
+++ linux-2.6.11.2/arch/i386/pci/common.c 2005-03-10 16:56:09.000000000 +0800
@@ -25,6 +25,7 @@ unsigned int pci_probe = PCI_PROBE_BIOS
int pci_routeirq;
int pcibios_last_bus = -1;
+unsigned int pirq_table_addr = 0;
struct pci_bus *pci_root_bus = NULL;
struct pci_raw_ops *raw_pci_ops;
@@ -188,6 +189,9 @@ char * __devinit pcibios_setup(char *st
} else if (!strcmp(str, "biosirq")) {
pci_probe |= PCI_BIOS_IRQ_SCAN;
return NULL;
+ } else if (!strncmp(str, "pirqaddr=", 9)) {
+ pirq_table_addr = simple_strtol(str+9, NULL, 0);
+ return NULL;
}
#endif
#ifdef CONFIG_PCI_DIRECT
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/pci/irq.c linux-2.6.11.2/arch/i386/pci/irq.c
--- linux-2.6.11.2-vanilla/arch/i386/pci/irq.c 2005-03-10 16:31:25.000000000 +0800
+++ linux-2.6.11.2/arch/i386/pci/irq.c 2005-03-10 20:43:02.479487640 +0800
@@ -58,6 +58,35 @@ struct irq_router_handler {
int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
/*
+ * Check passed address for the PCI IRQ Routing Table signature
+ * and perform checksum verification.
+ */
+
+static inline struct irq_routing_table * __init pirq_check_routing_table(u8 *addr)
+{
+ struct irq_routing_table *rt;
+ int i;
+ u8 sum;
+
+ rt = (struct irq_routing_table *) addr;
+ if (rt->signature != PIRQ_SIGNATURE ||
+ rt->version != PIRQ_VERSION ||
+ rt->size % 16 ||
+ rt->size < sizeof(struct irq_routing_table))
+ return NULL;
+ sum = 0;
+ for(i=0; i<rt->size; i++)
+ sum += addr[i];
+ if (!sum) {
+ DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
+ return rt;
+ }
+ return NULL;
+}
+
+
+
+/*
* Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
*/
@@ -65,21 +94,16 @@ static struct irq_routing_table * __init
{
u8 *addr;
struct irq_routing_table *rt;
- int i;
- u8 sum;
+ if (pirq_table_addr) {
+ rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr));
+ if (rt) {
+ return rt;
+ }
+ }
for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
- rt = (struct irq_routing_table *) addr;
- if (rt->signature != PIRQ_SIGNATURE ||
- rt->version != PIRQ_VERSION ||
- rt->size % 16 ||
- rt->size < sizeof(struct irq_routing_table))
- continue;
- sum = 0;
- for(i=0; i<rt->size; i++)
- sum += addr[i];
- if (!sum) {
- DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
+ rt = pirq_check_routing_table(addr);
+ if (rt) {
return rt;
}
}
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/pci/pci.h linux-2.6.11.2/arch/i386/pci/pci.h
--- linux-2.6.11.2-vanilla/arch/i386/pci/pci.h 2005-03-10 16:31:25.000000000 +0800
+++ linux-2.6.11.2/arch/i386/pci/pci.h 2005-03-10 16:52:09.000000000 +0800
@@ -27,6 +27,7 @@
#define PCI_ASSIGN_ALL_BUSSES 0x4000
extern unsigned int pci_probe;
+extern unsigned int pirq_table_addr;
/* pci-i386.c */
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/Documentation/kernel-parameters.txt linux-2.6.11.2/Documentation/kernel-parameters.txt
--- linux-2.6.11.2-vanilla/Documentation/kernel-parameters.txt 2005-03-10 16:31:44.000000000 +0800
+++ linux-2.6.11.2/Documentation/kernel-parameters.txt 2005-03-10 16:45:48.000000000 +0800
@@ -967,6 +967,10 @@ running once the system is up.
irqmask=0xMMMM [IA-32] Set a bit mask of IRQs allowed to be assigned
automatically to PCI devices. You can make the kernel
exclude IRQs of your ISA cards this way.
+ pirqaddr=0xAAAAA [IA-32] Specify the physical address
+ of the PIRQ table (normally generated
+ by the BIOS) if it is outside the .
+ F0000h-100000h range.
lastbus=N [IA-32] Scan all buses till bus #N. Can be useful
if the kernel is unable to find your secondary buses
and you want to tell it explicitly which ones they are.
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 2.6.11.2 1/1] PCI Allow OutOfRange PIRQ table address
@ 2005-03-10 13:29 jayalk
2005-03-10 13:42 ` Matthew Wilcox
0 siblings, 1 reply; 9+ messages in thread
From: jayalk @ 2005-03-10 13:29 UTC (permalink / raw)
To: gregkh; +Cc: linux-kernel, linux-pci
Hi Greg, PCI folk,
In our hardware situation, the BIOS is unable to store or generate it's PIRQ
table in the F0000h-100000h standard range. This patch adds a pci kernel
parameter, pirqaddr to allow the bootloader (or BIOS based loader) to inform
the kernel where the PIRQ table got stored. A beneficial side-effect is that,
if one's BIOS uses a static address each time for it's PIRQ table, then
pirqaddr can be used to avoid the $pirq search through that address block each
time at boot for normal PIRQ BIOSes.
Signed-off-by: Jaya Kumar <jayalk@intworks.biz>
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/pci/common.c linux-2.6.11.2/arch/i386/pci/common.c
--- linux-2.6.11.2-vanilla/arch/i386/pci/common.c 2005-03-10 16:31:25.000000000 +0800
+++ linux-2.6.11.2/arch/i386/pci/common.c 2005-03-10 16:56:09.000000000 +0800
@@ -25,6 +25,7 @@ unsigned int pci_probe = PCI_PROBE_BIOS
int pci_routeirq;
int pcibios_last_bus = -1;
+unsigned int pirq_table_addr = 0;
struct pci_bus *pci_root_bus = NULL;
struct pci_raw_ops *raw_pci_ops;
@@ -188,6 +189,9 @@ char * __devinit pcibios_setup(char *st
} else if (!strcmp(str, "biosirq")) {
pci_probe |= PCI_BIOS_IRQ_SCAN;
return NULL;
+ } else if (!strncmp(str, "pirqaddr=", 9)) {
+ pirq_table_addr = simple_strtol(str+9, NULL, 0);
+ return NULL;
}
#endif
#ifdef CONFIG_PCI_DIRECT
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/pci/irq.c linux-2.6.11.2/arch/i386/pci/irq.c
--- linux-2.6.11.2-vanilla/arch/i386/pci/irq.c 2005-03-10 16:31:25.000000000 +0800
+++ linux-2.6.11.2/arch/i386/pci/irq.c 2005-03-10 20:43:02.479487640 +0800
@@ -58,6 +58,35 @@ struct irq_router_handler {
int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
/*
+ * Check passed address for the PCI IRQ Routing Table signature
+ * and perform checksum verification.
+ */
+
+static inline struct irq_routing_table * __init pirq_check_routing_table(u8 *addr)
+{
+ struct irq_routing_table *rt;
+ int i;
+ u8 sum;
+
+ rt = (struct irq_routing_table *) addr;
+ if (rt->signature != PIRQ_SIGNATURE ||
+ rt->version != PIRQ_VERSION ||
+ rt->size % 16 ||
+ rt->size < sizeof(struct irq_routing_table))
+ return NULL;
+ sum = 0;
+ for(i=0; i<rt->size; i++)
+ sum += addr[i];
+ if (!sum) {
+ DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
+ return rt;
+ }
+ return NULL;
+}
+
+
+
+/*
* Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
*/
@@ -65,21 +94,16 @@ static struct irq_routing_table * __init
{
u8 *addr;
struct irq_routing_table *rt;
- int i;
- u8 sum;
+ if (pirq_table_addr) {
+ rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr));
+ if (rt) {
+ return rt;
+ }
+ }
for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
- rt = (struct irq_routing_table *) addr;
- if (rt->signature != PIRQ_SIGNATURE ||
- rt->version != PIRQ_VERSION ||
- rt->size % 16 ||
- rt->size < sizeof(struct irq_routing_table))
- continue;
- sum = 0;
- for(i=0; i<rt->size; i++)
- sum += addr[i];
- if (!sum) {
- DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
+ rt = pirq_check_routing_table(addr);
+ if (rt) {
return rt;
}
}
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/pci/pci.h linux-2.6.11.2/arch/i386/pci/pci.h
--- linux-2.6.11.2-vanilla/arch/i386/pci/pci.h 2005-03-10 16:31:25.000000000 +0800
+++ linux-2.6.11.2/arch/i386/pci/pci.h 2005-03-10 16:52:09.000000000 +0800
@@ -27,6 +27,7 @@
#define PCI_ASSIGN_ALL_BUSSES 0x4000
extern unsigned int pci_probe;
+extern unsigned int pirq_table_addr;
/* pci-i386.c */
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/Documentation/kernel-parameters.txt linux-2.6.11.2/Documentation/kernel-parameters.txt
--- linux-2.6.11.2-vanilla/Documentation/kernel-parameters.txt 2005-03-10 16:31:44.000000000 +0800
+++ linux-2.6.11.2/Documentation/kernel-parameters.txt 2005-03-10 16:45:48.000000000 +0800
@@ -967,6 +967,10 @@ running once the system is up.
irqmask=0xMMMM [IA-32] Set a bit mask of IRQs allowed to be assigned
automatically to PCI devices. You can make the kernel
exclude IRQs of your ISA cards this way.
+ pirqaddr=0xAAAAA [IA-32] Specify the physical address
+ of the PIRQ table (normally generated
+ by the BIOS) if it is outside the .
+ F0000h-100000h range.
lastbus=N [IA-32] Scan all buses till bus #N. Can be useful
if the kernel is unable to find your secondary buses
and you want to tell it explicitly which ones they are.
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH 2.6.11.2 1/1] PCI Allow OutOfRange PIRQ table address
2005-03-10 13:29 jayalk
@ 2005-03-10 13:42 ` Matthew Wilcox
2005-03-11 12:44 ` jayalk
0 siblings, 1 reply; 9+ messages in thread
From: Matthew Wilcox @ 2005-03-10 13:42 UTC (permalink / raw)
To: jayalk; +Cc: gregkh, linux-kernel, linux-pci
On Thu, Mar 10, 2005 at 05:29:35AM -0800, jayalk@intworks.biz wrote:
Nice work, I like it. You could make it even prettier:
> diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/pci/irq.c linux-2.6.11.2/arch/i386/pci/irq.c
> --- linux-2.6.11.2-vanilla/arch/i386/pci/irq.c 2005-03-10 16:31:25.000000000 +0800
> +++ linux-2.6.11.2/arch/i386/pci/irq.c 2005-03-10 20:43:02.479487640 +0800
> @@ -58,6 +58,35 @@ struct irq_router_handler {
> int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
>
> /*
> + * Check passed address for the PCI IRQ Routing Table signature
> + * and perform checksum verification.
> + */
> +
> +static inline struct irq_routing_table * __init pirq_check_routing_table(u8 *addr)
> +{
> + struct irq_routing_table *rt;
> + int i;
> + u8 sum;
> +
> + rt = (struct irq_routing_table *) addr;
static inline struct irq_routing_table * __init pirq_check_routing_table(unsigned long phys)
{
struct irq_routing_table *rt = __va(phys);
[...]
> @@ -65,21 +94,16 @@ static struct irq_routing_table * __init
> {
> u8 *addr;
unsigned long addr;
> struct irq_routing_table *rt;
> - int i;
> - u8 sum;
>
> + if (pirq_table_addr) {
> + rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr));
> + if (rt) {
> + return rt;
> + }
> + }
if (pirq_table_addr) {
rt = pirq_check_routing_table(pirq_table_addr);
if (rt)
return rt;
}
Should we fall back to searching if someone's specified an address? If not,
it becomes even simpler:
if (pirq_table_addr) {
return pirq_check_routing_table(pirq_table_addr);
}
> for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
This loop would become:
for (addr = 0xf0000; addr < 0x100000; addr += 16) {
> @@ -27,6 +27,7 @@
> #define PCI_ASSIGN_ALL_BUSSES 0x4000
>
> extern unsigned int pci_probe;
> +extern unsigned int pirq_table_addr;
Completely nitpicking, but I think this should be an unsigned long rather
than an int -- physical addresses are normally expressed in terms of
unsigned long.
> + pirqaddr=0xAAAAA [IA-32] Specify the physical address
> + of the PIRQ table (normally generated
> + by the BIOS) if it is outside the .
> + F0000h-100000h range.
And you even bothered to update the documentation! This is definitely
a cut above most of the patches I review ;-)
--
"Next the statesmen will invent cheap lies, putting the blame upon
the nation that is attacked, and every man will be glad of those
conscience-soothing falsities, and will diligently study them, and refuse
to examine any refutations of them; and thus he will by and by convince
himself that the war is just, and will thank God for the better sleep
he enjoys after this process of grotesque self-deception." -- Mark Twain
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH 2.6.11.2 1/1] PCI Allow OutOfRange PIRQ table address
2005-03-10 13:42 ` Matthew Wilcox
@ 2005-03-11 12:44 ` jayalk
0 siblings, 0 replies; 9+ messages in thread
From: jayalk @ 2005-03-11 12:44 UTC (permalink / raw)
To: Matthew Wilcox; +Cc: gregkh, linux-kernel, linux-pci
>On Thu, 10 Mar 2005, Matthew Wilcox wrote:
>> +extern unsigned int pirq_table_addr;
>
> Completely nitpicking, but I think this should be an unsigned long rather
> than an int -- physical addresses are normally expressed in terms of
> unsigned long.
Yup, good point, I'll fix that.
> Should we fall back to searching if someone's specified an address? If not,
> it becomes even simpler:
I think it'd be a failsafe in the case where someone mistakenly copied
an incorrect or mistaken boot loader config. I'll add a warning in that case
so that the user can see that there's been a problem.
>> for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
>
> This loop would become:
>
> for (addr = 0xf0000; addr < 0x100000; addr += 16) {
>
I prefered the former since the __va conversion only gets done for those
initial addresses rather than throughout the loop. I think the
check_routing... should use va addr not phys, for subjective reasons, feels
cleaner, I guess. I'll deferr to whatever the norm is. Let me know.
Thanks for the feedback.
jayakumar
>
>
> On Thu, Mar 10, 2005 at 05:29:35AM -0800, jayalk@intworks.biz wrote:
>
> Nice work, I like it. You could make it even prettier:
>
>> diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/pci/irq.c linux-2.6.11.2/arch/i386/pci/irq.c
>> --- linux-2.6.11.2-vanilla/arch/i386/pci/irq.c 2005-03-10 16:31:25.000000000 +0800
>> +++ linux-2.6.11.2/arch/i386/pci/irq.c 2005-03-10 20:43:02.479487640 +0800
>> @@ -58,6 +58,35 @@ struct irq_router_handler {
>> int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
>>
>> /*
>> + * Check passed address for the PCI IRQ Routing Table signature
>> + * and perform checksum verification.
>> + */
>> +
>> +static inline struct irq_routing_table * __init pirq_check_routing_table(u8 *addr)
>> +{
>> + struct irq_routing_table *rt;
>> + int i;
>> + u8 sum;
>> +
>> + rt = (struct irq_routing_table *) addr;
>
> static inline struct irq_routing_table * __init pirq_check_routing_table(unsigned long phys)
> {
> struct irq_routing_table *rt = __va(phys);
> [...]
>
>> @@ -65,21 +94,16 @@ static struct irq_routing_table * __init
>> {
>> u8 *addr;
>
> unsigned long addr;
>
>> struct irq_routing_table *rt;
>> - int i;
>> - u8 sum;
>>
>> + if (pirq_table_addr) {
>> + rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr));
>> + if (rt) {
>> + return rt;
>> + }
>> + }
>
> if (pirq_table_addr) {
> rt = pirq_check_routing_table(pirq_table_addr);
> if (rt)
> return rt;
> }
>
> Should we fall back to searching if someone's specified an address? If not,
> it becomes even simpler:
>
> if (pirq_table_addr) {
> return pirq_check_routing_table(pirq_table_addr);
> }
>
>> for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
>
> This loop would become:
>
> for (addr = 0xf0000; addr < 0x100000; addr += 16) {
>
>> @@ -27,6 +27,7 @@
>> #define PCI_ASSIGN_ALL_BUSSES 0x4000
>>
>> extern unsigned int pci_probe;
>> +extern unsigned int pirq_table_addr;
>
> Completely nitpicking, but I think this should be an unsigned long rather
> than an int -- physical addresses are normally expressed in terms of
> unsigned long.
>
>> + pirqaddr=0xAAAAA [IA-32] Specify the physical address
>> + of the PIRQ table (normally generated
>> + by the BIOS) if it is outside the .
>> + F0000h-100000h range.
>
> And you even bothered to update the documentation! This is definitely
> a cut above most of the patches I review ;-)
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2005-03-22 4:28 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-17 1:24 [PATCH 2.6.11.2 1/1] PCI Allow OutOfRange PIRQ table address jayalk
2005-03-17 3:34 ` Randy.Dunlap
-- strict thread matches above, loose matches on Subject: below --
2005-03-22 4:20 jayalk
2005-03-17 6:50 jayalk
2005-03-17 6:36 jayalk
2005-03-17 1:16 jayalk
2005-03-10 13:29 jayalk
2005-03-10 13:42 ` Matthew Wilcox
2005-03-11 12:44 ` jayalk
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox