Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
8da5f1d4
Commit
8da5f1d4
authored
Apr 15, 2002
by
Patrick Mochel
Committed by
Linus Torvalds
Apr 15, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Further break-up-age
Make ACPI PCI IRQ routing work a bit better...
parent
6af072e1
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
152 additions
and
120 deletions
+152
-120
arch/i386/kernel/pci/Makefile
arch/i386/kernel/pci/Makefile
+9
-2
arch/i386/kernel/pci/acpi.c
arch/i386/kernel/pci/acpi.c
+70
-0
arch/i386/kernel/pci/common.c
arch/i386/kernel/pci/common.c
+0
-44
arch/i386/kernel/pci/irq.c
arch/i386/kernel/pci/irq.c
+13
-69
arch/i386/kernel/pci/legacy.c
arch/i386/kernel/pci/legacy.c
+53
-0
arch/i386/kernel/pci/numa.c
arch/i386/kernel/pci/numa.c
+2
-2
arch/i386/kernel/pci/pci.h
arch/i386/kernel/pci/pci.h
+3
-2
drivers/acpi/acpi_osl.c
drivers/acpi/acpi_osl.c
+2
-1
No files found.
arch/i386/kernel/pci/Makefile
View file @
8da5f1d4
...
...
@@ -2,15 +2,22 @@ O_TARGET := pci.o
obj-y
:=
dma.o i386.o
ifdef
CONFIG_VISWS
ifdef
CONFIG_VISWS
obj-y
+=
visws.o
else
ifdef
CONFIG_MULTIQUAD
ifdef
CONFIG_MULTIQUAD
obj-y
+=
numa.o
else
obj-$(CONFIG_PCI_BIOS)
+=
pcbios.o
obj-$(CONFIG_PCI_DIRECT)
+=
direct.o
obj-y
+=
fixup.o
ifdef
CONFIG_ACPI_PCI
obj-y
+=
acpi.o
else
obj-y
+=
legacy.o
endif
endif
# CONFIG_MULTIQUAD
obj-y
+=
irq.o common.o
endif
# CONFIG_VISWS
...
...
arch/i386/kernel/pci/acpi.c
0 → 100644
View file @
8da5f1d4
#include <linux/pci.h>
#include <linux/acpi.h>
#include "pci.h"
extern
void
eisa_set_level_irq
(
int
irq
);
static
int
acpi_lookup_irq
(
struct
pci_dev
*
dev
,
int
assign
)
{
int
result
=
0
;
int
irq
=
0
;
u8
pin
;
/* TBD: Select IRQ from possible to improve routing performance. */
/* Find IRQ pin */
pci_read_config_byte
(
dev
,
PCI_INTERRUPT_PIN
,
&
pin
);
if
(
!
pin
)
{
DBG
(
" -> no interrupt pin
\n
"
);
return
0
;
}
pin
=
pin
-
1
;
result
=
acpi_prt_get_irq
(
dev
,
pin
,
&
irq
);
if
(
!
irq
)
result
=
-
ENODEV
;
if
(
0
!=
result
)
{
printk
(
KERN_WARNING
"PCI: No IRQ known for interrupt pin %c of device %s
\n
"
,
'A'
+
pin
,
dev
->
slot_name
);
return
result
;
}
/* only check for the IRQ */
if
(
!
assign
)
{
printk
(
KERN_INFO
"PCI: Found IRQ %d for device %s
\n
"
,
irq
,
dev
->
slot_name
);
return
1
;
}
dev
->
irq
=
irq
;
/* also assign an IRQ */
if
(
irq
&&
(
dev
->
class
>>
8
)
!=
PCI_CLASS_DISPLAY_VGA
)
{
result
=
acpi_prt_set_irq
(
dev
,
pin
,
irq
);
if
(
0
!=
result
)
{
printk
(
KERN_WARNING
"PCI: Could not assign IRQ %d to device %s
\n
"
,
irq
,
dev
->
slot_name
);
return
result
;
}
eisa_set_level_irq
(
irq
);
printk
(
KERN_INFO
"PCI: Assigned IRQ %d for device %s
\n
"
,
irq
,
dev
->
slot_name
);
}
return
1
;
}
static
int
__init
pci_acpi_init
(
void
)
{
if
(
!
(
pci_probe
&
PCI_NO_ACPI_ROUTING
))
{
printk
(
KERN_INFO
"PCI: Using ACPI for IRQ routing
\n
"
);
printk
(
KERN_INFO
"PCI: if you experience problems, try using option 'pci=noacpi'
\n
"
);
pci_use_acpi_routing
=
1
;
pci_lookup_irq
=
acpi_lookup_irq
;
}
return
0
;
}
subsys_initcall
(
pci_acpi_init
);
arch/i386/kernel/pci/common.c
View file @
8da5f1d4
...
...
@@ -4,12 +4,8 @@
* (c) 1999--2000 Martin Mares <mj@ucw.cz>
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <asm/segment.h>
...
...
@@ -90,37 +86,6 @@ static void __devinit pcibios_fixup_ghosts(struct pci_bus *b)
}
}
/*
* Discover remaining PCI buses in case there are peer host bridges.
* We use the number of last PCI bus provided by the PCI BIOS.
*/
static
void
__devinit
pcibios_fixup_peer_bridges
(
void
)
{
int
n
;
struct
pci_bus
bus
;
struct
pci_dev
dev
;
u16
l
;
if
(
pcibios_last_bus
<=
0
||
pcibios_last_bus
>=
0xff
)
return
;
DBG
(
"PCI: Peer bridge fixup
\n
"
);
for
(
n
=
0
;
n
<=
pcibios_last_bus
;
n
++
)
{
if
(
pci_bus_exists
(
&
pci_root_buses
,
n
))
continue
;
bus
.
number
=
n
;
bus
.
ops
=
pci_root_ops
;
dev
.
bus
=
&
bus
;
for
(
dev
.
devfn
=
0
;
dev
.
devfn
<
256
;
dev
.
devfn
+=
8
)
if
(
!
pci_read_config_word
(
&
dev
,
PCI_VENDOR_ID
,
&
l
)
&&
l
!=
0x0000
&&
l
!=
0xffff
)
{
DBG
(
"Found device at %02x:%02x [%04x]
\n
"
,
n
,
dev
.
devfn
,
l
);
printk
(
"PCI: Discovered peer bus %02x
\n
"
,
n
);
pci_scan_bus
(
n
,
pci_root_ops
,
NULL
);
break
;
}
}
}
/*
* Called after each bus is probed, but before its children
* are examined.
...
...
@@ -158,15 +123,6 @@ static int __init pcibios_init(void)
return
0
;
}
printk
(
"PCI: Probing PCI hardware
\n
"
);
pci_root_bus
=
pcibios_scan_root
(
0
);
pcibios_irq_init
();
if
(
!
pci_use_acpi_routing
)
pcibios_fixup_peer_bridges
();
pcibios_fixup_irqs
();
pcibios_resource_survey
();
#ifdef CONFIG_PCI_BIOS
...
...
arch/i386/kernel/pci/irq.c
View file @
8da5f1d4
...
...
@@ -46,6 +46,8 @@ struct irq_router {
int
(
*
set
)(
struct
pci_dev
*
router
,
struct
pci_dev
*
dev
,
int
pirq
,
int
new
);
};
int
(
*
pci_lookup_irq
)(
struct
pci_dev
*
dev
,
int
assign
)
=
NULL
;
/*
* Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
*/
...
...
@@ -116,7 +118,7 @@ static void __init pirq_peer_trick(void)
* Code for querying and setting of IRQ routes on various interrupt routers.
*/
static
void
eisa_set_level_irq
(
unsigned
int
irq
)
void
eisa_set_level_irq
(
unsigned
int
irq
)
{
unsigned
char
mask
=
1
<<
(
irq
&
7
);
unsigned
int
port
=
0x4d0
+
(
irq
>>
3
);
...
...
@@ -556,54 +558,6 @@ static void pcibios_test_irq_handler(int irq, void *dev_id, struct pt_regs *regs
{
}
#ifdef CONFIG_ACPI_PCI
static
int
acpi_lookup_irq
(
struct
pci_dev
*
dev
,
u8
pin
,
int
assign
)
{
int
result
=
0
;
int
irq
=
0
;
/* TBD: Select IRQ from possible to improve routing performance. */
result
=
acpi_prt_get_irq
(
dev
,
pin
,
&
irq
);
if
(
!
irq
)
result
=
-
ENODEV
;
if
(
0
!=
result
)
{
printk
(
KERN_WARNING
"PCI: No IRQ known for interrupt pin %c of device %s
\n
"
,
'A'
+
pin
,
dev
->
slot_name
);
return
result
;
}
dev
->
irq
=
irq
;
if
(
!
assign
)
{
/* only check for the IRQ */
printk
(
KERN_INFO
"PCI: Found IRQ %d for device %s
\n
"
,
irq
,
dev
->
slot_name
);
return
1
;
}
/* also assign an IRQ */
if
(
irq
&&
(
dev
->
class
>>
8
)
!=
PCI_CLASS_DISPLAY_VGA
)
{
result
=
acpi_prt_set_irq
(
dev
,
pin
,
irq
);
if
(
0
!=
result
)
{
printk
(
KERN_WARNING
"PCI: Could not assign IRQ %d to device %s
\n
"
,
irq
,
dev
->
slot_name
);
return
result
;
}
eisa_set_level_irq
(
irq
);
printk
(
KERN_INFO
"PCI: Assigned IRQ %d for device %s
\n
"
,
irq
,
dev
->
slot_name
);
}
return
1
;
}
#endif
/* CONFIG_ACPI_PCI */
static
int
pcibios_lookup_irq
(
struct
pci_dev
*
dev
,
int
assign
)
{
u8
pin
;
...
...
@@ -623,12 +577,6 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
}
pin
=
pin
-
1
;
#ifdef CONFIG_ACPI_PCI
/* Use ACPI to lookup IRQ */
if
(
pci_use_acpi_routing
)
return
acpi_lookup_irq
(
dev
,
pin
,
assign
);
#endif
/* Find IRQ routing entry */
if
(
!
pirq_table
)
...
...
@@ -736,21 +684,12 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
return
1
;
}
void
__init
pcibios_irq_init
(
void
)
static
int
__init
pcibios_irq_init
(
void
)
{
DBG
(
"PCI: IRQ init
\n
"
);
#ifdef CONFIG_ACPI_PCI
if
(
!
(
pci_probe
&
PCI_NO_ACPI_ROUTING
))
{
if
(
acpi_prts
.
count
)
{
printk
(
KERN_INFO
"PCI: Using ACPI for IRQ routing
\n
"
);
pci_use_acpi_routing
=
1
;
return
;
}
else
printk
(
KERN_WARNING
"PCI: Invalid ACPI-PCI IRQ routing table
\n
"
);
}
#endif
if
(
pci_lookup_irq
)
return
0
;
pirq_table
=
pirq_find_routing_table
();
...
...
@@ -771,8 +710,13 @@ void __init pcibios_irq_init(void)
if
(
io_apic_assign_pci_irqs
)
pirq_table
=
NULL
;
}
pci_lookup_irq
=
pcibios_lookup_irq
;
pcibios_fixup_irqs
();
return
0
;
}
subsys_initcall
(
pcibios_irq_init
);
void
__init
pcibios_fixup_irqs
(
void
)
{
struct
pci_dev
*
dev
;
...
...
@@ -835,7 +779,7 @@ void __init pcibios_fixup_irqs(void)
* Still no IRQ? Try to lookup one...
*/
if
(
pin
&&
!
dev
->
irq
)
pci
bios
_lookup_irq
(
dev
,
0
);
pci_lookup_irq
(
dev
,
0
);
}
}
...
...
@@ -852,7 +796,7 @@ void pcibios_enable_irq(struct pci_dev *dev)
{
u8
pin
;
pci_read_config_byte
(
dev
,
PCI_INTERRUPT_PIN
,
&
pin
);
if
(
pin
&&
!
pci
bios
_lookup_irq
(
dev
,
1
)
&&
!
dev
->
irq
)
{
if
(
pin
&&
!
pci_lookup_irq
(
dev
,
1
)
&&
!
dev
->
irq
)
{
char
*
msg
;
if
(
io_apic_assign_pci_irqs
)
msg
=
" Probably buggy MP table."
;
...
...
arch/i386/kernel/pci/legacy.c
0 → 100644
View file @
8da5f1d4
/*
* legacy.c - traditional, old school PCI bus probing
*/
#include <linux/pci.h>
#include "pci.h"
/*
* Discover remaining PCI buses in case there are peer host bridges.
* We use the number of last PCI bus provided by the PCI BIOS.
*/
static
void
__devinit
pcibios_fixup_peer_bridges
(
void
)
{
int
n
;
struct
pci_bus
bus
;
struct
pci_dev
dev
;
u16
l
;
if
(
pcibios_last_bus
<=
0
||
pcibios_last_bus
>=
0xff
)
return
;
DBG
(
"PCI: Peer bridge fixup
\n
"
);
for
(
n
=
0
;
n
<=
pcibios_last_bus
;
n
++
)
{
if
(
pci_bus_exists
(
&
pci_root_buses
,
n
))
continue
;
bus
.
number
=
n
;
bus
.
ops
=
pci_root_ops
;
dev
.
bus
=
&
bus
;
for
(
dev
.
devfn
=
0
;
dev
.
devfn
<
256
;
dev
.
devfn
+=
8
)
if
(
!
pci_read_config_word
(
&
dev
,
PCI_VENDOR_ID
,
&
l
)
&&
l
!=
0x0000
&&
l
!=
0xffff
)
{
DBG
(
"Found device at %02x:%02x [%04x]
\n
"
,
n
,
dev
.
devfn
,
l
);
printk
(
"PCI: Discovered peer bus %02x
\n
"
,
n
);
pci_scan_bus
(
n
,
pci_root_ops
,
NULL
);
break
;
}
}
}
static
int
__init
pci_legacy_init
(
void
)
{
if
(
!
pci_root_ops
)
{
printk
(
"PCI: System does not support PCI
\n
"
);
return
0
;
}
printk
(
"PCI: Probing PCI hardware
\n
"
);
pci_root_bus
=
pcibios_scan_root
(
0
);
if
(
!
pci_use_acpi_routing
)
pcibios_fixup_peer_bridges
();
return
0
;
}
subsys_initcall
(
pci_legacy_init
);
arch/i386/kernel/pci/numa.c
View file @
8da5f1d4
...
...
@@ -12,7 +12,7 @@
#define PCI_CONF1_ADDRESS(bus, dev, fn, reg) \
(0x80000000 | (BUS2LOCAL(bus) << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
static
int
pci_conf1_read
(
int
seg
,
int
bus
,
int
dev
,
int
fn
,
int
reg
,
int
len
,
u32
*
value
)
/* CONFIG_MULTIQUAD */
static
int
pci_conf1_read
(
int
seg
,
int
bus
,
int
dev
,
int
fn
,
int
reg
,
int
len
,
u32
*
value
)
{
unsigned
long
flags
;
...
...
@@ -40,7 +40,7 @@ static int pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len,
return
0
;
}
static
int
pci_conf1_write
(
int
seg
,
int
bus
,
int
dev
,
int
fn
,
int
reg
,
int
len
,
u32
value
)
/* CONFIG_MULTIQUAD */
static
int
pci_conf1_write
(
int
seg
,
int
bus
,
int
dev
,
int
fn
,
int
reg
,
int
len
,
u32
value
)
{
unsigned
long
flags
;
...
...
arch/i386/kernel/pci/pci.h
View file @
8da5f1d4
...
...
@@ -4,7 +4,7 @@
* (c) 1999 Martin Mares <mj@ucw.cz>
*/
#
undef
DEBUG
#
define
DEBUG
#ifdef DEBUG
#define DBG(x...) printk(x)
...
...
@@ -69,6 +69,7 @@ extern unsigned int pcibios_irq_mask;
extern
int
pci_use_acpi_routing
;
extern
spinlock_t
pci_config_lock
;
void
pcibios_irq_init
(
void
);
void
pcibios_fixup_irqs
(
void
);
void
pcibios_enable_irq
(
struct
pci_dev
*
dev
);
extern
int
(
*
pci_lookup_irq
)(
struct
pci_dev
*
dev
,
int
assign
);
drivers/acpi/acpi_osl.c
View file @
8da5f1d4
...
...
@@ -77,12 +77,13 @@ acpi_os_initialize(void)
* Initialize PCI configuration space access, as we'll need to access
* it while walking the namespace (bus 0 and root bridges w/ _BBNs).
*/
#if 0
pcibios_config_init();
if (!pci_config_read || !pci_config_write) {
printk(KERN_ERR PREFIX "Access to PCI configuration space unavailable\n");
return AE_NULL_ENTRY;
}
#endif
return
AE_OK
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment