Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
OpenBMC Firmware
talos-obmc-linux
Commits
adb2705a
Commit
adb2705a
authored
19 years ago
by
Linus Torvalds
Browse files
Options
Download
Plain Diff
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6
parents
f340c0d1
8644d2a4
Changes
69
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
544 additions
and
116 deletions
+544
-116
Documentation/kernel-parameters.txt
Documentation/kernel-parameters.txt
+4
-0
arch/i386/kernel/acpi/boot.c
arch/i386/kernel/acpi/boot.c
+49
-8
arch/i386/pci/common.c
arch/i386/pci/common.c
+6
-2
arch/i386/pci/irq.c
arch/i386/pci/irq.c
+37
-14
arch/i386/pci/legacy.c
arch/i386/pci/legacy.c
+2
-0
arch/i386/pci/mmconfig.c
arch/i386/pci/mmconfig.c
+31
-8
arch/i386/pci/numa.c
arch/i386/pci/numa.c
+2
-0
arch/i386/pci/pci.h
arch/i386/pci/pci.h
+1
-0
arch/ia64/kernel/acpi.c
arch/ia64/kernel/acpi.c
+26
-4
arch/ia64/kernel/iosapic.c
arch/ia64/kernel/iosapic.c
+113
-21
arch/ia64/pci/pci.c
arch/ia64/pci/pci.c
+33
-5
arch/ppc/kernel/pci.c
arch/ppc/kernel/pci.c
+19
-2
arch/ppc64/kernel/pci.c
arch/ppc64/kernel/pci.c
+20
-2
arch/x86_64/pci/mmconfig.c
arch/x86_64/pci/mmconfig.c
+54
-14
drivers/acpi/container.c
drivers/acpi/container.c
+1
-1
drivers/acpi/pci_bind.c
drivers/acpi/pci_bind.c
+20
-7
drivers/acpi/pci_root.c
drivers/acpi/pci_root.c
+23
-1
drivers/acpi/processor_core.c
drivers/acpi/processor_core.c
+1
-1
drivers/acpi/scan.c
drivers/acpi/scan.c
+101
-25
drivers/char/moxa.c
drivers/char/moxa.c
+1
-1
No files found.
Documentation/kernel-parameters.txt
View file @
adb2705a
...
...
@@ -1030,6 +1030,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.
...
...
This diff is collapsed.
Click to expand it.
arch/i386/kernel/acpi/boot.c
View file @
adb2705a
...
...
@@ -159,9 +159,15 @@ char *__acpi_map_table(unsigned long phys, unsigned long size)
#endif
#ifdef CONFIG_PCI_MMCONFIG
static
int
__init
acpi_parse_mcfg
(
unsigned
long
phys_addr
,
unsigned
long
size
)
/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */
struct
acpi_table_mcfg_config
*
pci_mmcfg_config
;
int
pci_mmcfg_config_num
;
int
__init
acpi_parse_mcfg
(
unsigned
long
phys_addr
,
unsigned
long
size
)
{
struct
acpi_table_mcfg
*
mcfg
;
unsigned
long
i
;
int
config_size
;
if
(
!
phys_addr
||
!
size
)
return
-
EINVAL
;
...
...
@@ -172,18 +178,38 @@ static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)
return
-
ENODEV
;
}
if
(
mcfg
->
base_reserved
)
{
printk
(
KERN_ERR
PREFIX
"MMCONFIG not in low 4GB of memory
\n
"
);
/* how many config structures do we have */
pci_mmcfg_config_num
=
0
;
i
=
size
-
sizeof
(
struct
acpi_table_mcfg
);
while
(
i
>=
sizeof
(
struct
acpi_table_mcfg_config
))
{
++
pci_mmcfg_config_num
;
i
-=
sizeof
(
struct
acpi_table_mcfg_config
);
};
if
(
pci_mmcfg_config_num
==
0
)
{
printk
(
KERN_ERR
PREFIX
"MMCONFIG has no entries
\n
"
);
return
-
ENODEV
;
}
pci_mmcfg_base_addr
=
mcfg
->
base_address
;
config_size
=
pci_mmcfg_config_num
*
sizeof
(
*
pci_mmcfg_config
);
pci_mmcfg_config
=
kmalloc
(
config_size
,
GFP_KERNEL
);
if
(
!
pci_mmcfg_config
)
{
printk
(
KERN_WARNING
PREFIX
"No memory for MCFG config tables
\n
"
);
return
-
ENOMEM
;
}
memcpy
(
pci_mmcfg_config
,
&
mcfg
->
config
,
config_size
);
for
(
i
=
0
;
i
<
pci_mmcfg_config_num
;
++
i
)
{
if
(
mcfg
->
config
[
i
].
base_reserved
)
{
printk
(
KERN_ERR
PREFIX
"MMCONFIG not in low 4GB of memory
\n
"
);
return
-
ENODEV
;
}
}
return
0
;
}
#else
#define acpi_parse_mcfg NULL
#endif
/* !CONFIG_PCI_MMCONFIG */
#endif
/* CONFIG_PCI_MMCONFIG */
#ifdef CONFIG_X86_LOCAL_APIC
static
int
__init
...
...
@@ -507,6 +533,22 @@ acpi_unmap_lsapic(int cpu)
EXPORT_SYMBOL
(
acpi_unmap_lsapic
);
#endif
/* CONFIG_ACPI_HOTPLUG_CPU */
int
acpi_register_ioapic
(
acpi_handle
handle
,
u64
phys_addr
,
u32
gsi_base
)
{
/* TBD */
return
-
EINVAL
;
}
EXPORT_SYMBOL
(
acpi_register_ioapic
);
int
acpi_unregister_ioapic
(
acpi_handle
handle
,
u32
gsi_base
)
{
/* TBD */
return
-
EINVAL
;
}
EXPORT_SYMBOL
(
acpi_unregister_ioapic
);
static
unsigned
long
__init
acpi_scan_rsdp
(
unsigned
long
start
,
...
...
@@ -1123,7 +1165,6 @@ int __init acpi_boot_init(void)
acpi_process_madt
();
acpi_table_parse
(
ACPI_HPET
,
acpi_parse_hpet
);
acpi_table_parse
(
ACPI_MCFG
,
acpi_parse_mcfg
);
return
0
;
}
...
...
This diff is collapsed.
Click to expand it.
arch/i386/pci/common.c
View file @
adb2705a
...
...
@@ -25,7 +25,8 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
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
)
...
...
@@ -133,7 +134,7 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum)
printk
(
"PCI: Probing PCI hardware (bus %02x)
\n
"
,
busnum
);
return
pci_scan_bus
(
busnum
,
&
pci_root_ops
,
NULL
);
return
pci_scan_bus
_parented
(
NULL
,
busnum
,
&
pci_root_ops
,
NULL
);
}
extern
u8
pci_cache_line_size
;
...
...
@@ -188,6 +189,9 @@ char * __devinit pcibios_setup(char *str)
}
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
...
...
This diff is collapsed.
Click to expand it.
arch/i386/pci/irq.c
View file @
adb2705a
...
...
@@ -57,6 +57,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 pirq_find_routing_table(void)
{
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
;
}
...
...
This diff is collapsed.
Click to expand it.
arch/i386/pci/legacy.c
View file @
adb2705a
...
...
@@ -45,6 +45,8 @@ static int __init pci_legacy_init(void)
printk
(
"PCI: Probing PCI hardware
\n
"
);
pci_root_bus
=
pcibios_scan_root
(
0
);
if
(
pci_root_bus
)
pci_bus_add_devices
(
pci_root_bus
);
pcibios_fixup_peer_bridges
();
...
...
This diff is collapsed.
Click to expand it.
arch/i386/pci/mmconfig.c
View file @
adb2705a
...
...
@@ -11,11 +11,9 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/acpi.h>
#include "pci.h"
/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */
u32
pci_mmcfg_base_addr
;
#define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG))
/* The base address of the last MMCONFIG device accessed */
...
...
@@ -24,10 +22,31 @@ static u32 mmcfg_last_accessed_device;
/*
* Functions for accessing PCI configuration space with MMCONFIG accesses
*/
static
u32
get_base_addr
(
unsigned
int
seg
,
int
bus
)
{
int
cfg_num
=
-
1
;
struct
acpi_table_mcfg_config
*
cfg
;
while
(
1
)
{
++
cfg_num
;
if
(
cfg_num
>=
pci_mmcfg_config_num
)
{
/* something bad is going on, no cfg table is found. */
/* so we fall back to the old way we used to do this */
/* and just rely on the first entry to be correct. */
return
pci_mmcfg_config
[
0
].
base_address
;
}
cfg
=
&
pci_mmcfg_config
[
cfg_num
];
if
(
cfg
->
pci_segment_group_number
!=
seg
)
continue
;
if
((
cfg
->
start_bus_number
<=
bus
)
&&
(
cfg
->
end_bus_number
>=
bus
))
return
cfg
->
base_address
;
}
}
static
inline
void
pci_exp_set_dev_base
(
int
bus
,
int
devfn
)
static
inline
void
pci_exp_set_dev_base
(
unsigned
int
seg
,
int
bus
,
int
devfn
)
{
u32
dev_base
=
pci_mmcfg
_base_addr
|
(
bus
<<
20
)
|
(
devfn
<<
12
);
u32
dev_base
=
get
_base_addr
(
seg
,
bus
)
|
(
bus
<<
20
)
|
(
devfn
<<
12
);
if
(
dev_base
!=
mmcfg_last_accessed_device
)
{
mmcfg_last_accessed_device
=
dev_base
;
set_fixmap_nocache
(
FIX_PCIE_MCFG
,
dev_base
);
...
...
@@ -44,7 +63,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
spin_lock_irqsave
(
&
pci_config_lock
,
flags
);
pci_exp_set_dev_base
(
bus
,
devfn
);
pci_exp_set_dev_base
(
seg
,
bus
,
devfn
);
switch
(
len
)
{
case
1
:
...
...
@@ -73,7 +92,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
spin_lock_irqsave
(
&
pci_config_lock
,
flags
);
pci_exp_set_dev_base
(
bus
,
devfn
);
pci_exp_set_dev_base
(
seg
,
bus
,
devfn
);
switch
(
len
)
{
case
1
:
...
...
@@ -101,7 +120,11 @@ static int __init pci_mmcfg_init(void)
{
if
((
pci_probe
&
PCI_PROBE_MMCONF
)
==
0
)
goto
out
;
if
(
!
pci_mmcfg_base_addr
)
acpi_table_parse
(
ACPI_MCFG
,
acpi_parse_mcfg
);
if
((
pci_mmcfg_config_num
==
0
)
||
(
pci_mmcfg_config
==
NULL
)
||
(
pci_mmcfg_config
[
0
].
base_address
==
0
))
goto
out
;
/* Kludge for now. Don't use mmconfig on AMD systems because
...
...
This diff is collapsed.
Click to expand it.
arch/i386/pci/numa.c
View file @
adb2705a
...
...
@@ -115,6 +115,8 @@ static int __init pci_numa_init(void)
return
0
;
pci_root_bus
=
pcibios_scan_root
(
0
);
if
(
pci_root_bus
)
pci_bus_add_devices
(
pci_root_bus
);
if
(
num_online_nodes
()
>
1
)
for_each_online_node
(
quad
)
{
if
(
quad
==
0
)
...
...
This diff is collapsed.
Click to expand it.
arch/i386/pci/pci.h
View file @
adb2705a
...
...
@@ -27,6 +27,7 @@
#define PCI_ASSIGN_ALL_BUSSES 0x4000
extern
unsigned
int
pci_probe
;
extern
unsigned
long
pirq_table_addr
;
/* pci-i386.c */
...
...
This diff is collapsed.
Click to expand it.
arch/ia64/kernel/acpi.c
View file @
adb2705a
...
...
@@ -236,9 +236,7 @@ acpi_parse_iosapic (acpi_table_entry_header *header, const unsigned long end)
if
(
BAD_MADT_ENTRY
(
iosapic
,
end
))
return
-
EINVAL
;
iosapic_init
(
iosapic
->
address
,
iosapic
->
global_irq_base
);
return
0
;
return
iosapic_init
(
iosapic
->
address
,
iosapic
->
global_irq_base
);
}
...
...
@@ -772,7 +770,7 @@ EXPORT_SYMBOL(acpi_unmap_lsapic);
#ifdef CONFIG_ACPI_NUMA
acpi_status
__init
acpi_status
__
dev
init
acpi_map_iosapic
(
acpi_handle
handle
,
u32
depth
,
void
*
context
,
void
**
ret
)
{
struct
acpi_buffer
buffer
=
{
ACPI_ALLOCATE_BUFFER
,
NULL
};
...
...
@@ -825,4 +823,28 @@ acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret)
return
AE_OK
;
}
#endif
/* CONFIG_NUMA */
int
acpi_register_ioapic
(
acpi_handle
handle
,
u64
phys_addr
,
u32
gsi_base
)
{
int
err
;
if
((
err
=
iosapic_init
(
phys_addr
,
gsi_base
)))
return
err
;
#if CONFIG_ACPI_NUMA
acpi_map_iosapic
(
handle
,
0
,
NULL
,
NULL
);
#endif
/* CONFIG_ACPI_NUMA */
return
0
;
}
EXPORT_SYMBOL
(
acpi_register_ioapic
);
int
acpi_unregister_ioapic
(
acpi_handle
handle
,
u32
gsi_base
)
{
return
iosapic_remove
(
gsi_base
);
}
EXPORT_SYMBOL
(
acpi_unregister_ioapic
);
#endif
/* CONFIG_ACPI_BOOT */
This diff is collapsed.
Click to expand it.
arch/ia64/kernel/iosapic.c
View file @
adb2705a
...
...
@@ -129,14 +129,13 @@ static struct iosapic {
char
__iomem
*
addr
;
/* base address of IOSAPIC */
unsigned
int
gsi_base
;
/* first GSI assigned to this IOSAPIC */
unsigned
short
num_rte
;
/* number of RTE in this IOSAPIC */
int
rtes_inuse
;
/* # of RTEs in use on this IOSAPIC */
#ifdef CONFIG_NUMA
unsigned
short
node
;
/* numa node association via pxm */
#endif
}
iosapic_lists
[
NR_IOSAPICS
];
static
int
num_iosapic
;
static
unsigned
char
pcat_compat
__initdata
;
/* 8259 compatibility flag */
static
unsigned
char
pcat_compat
__devinitdata
;
/* 8259 compatibility flag */
static
int
iosapic_kmalloc_ok
;
static
LIST_HEAD
(
free_rte_list
);
...
...
@@ -149,7 +148,7 @@ find_iosapic (unsigned int gsi)
{
int
i
;
for
(
i
=
0
;
i
<
num_iosapic
;
i
++
)
{
for
(
i
=
0
;
i
<
NR_IOSAPICS
;
i
++
)
{
if
((
unsigned
)
(
gsi
-
iosapic_lists
[
i
].
gsi_base
)
<
iosapic_lists
[
i
].
num_rte
)
return
i
;
}
...
...
@@ -598,6 +597,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
rte
->
refcnt
++
;
list_add_tail
(
&
rte
->
rte_list
,
&
iosapic_intr_info
[
vector
].
rtes
);
iosapic_intr_info
[
vector
].
count
++
;
iosapic_lists
[
index
].
rtes_inuse
++
;
}
else
if
(
vector_is_shared
(
vector
))
{
struct
iosapic_intr_info
*
info
=
&
iosapic_intr_info
[
vector
];
...
...
@@ -778,7 +778,7 @@ void
iosapic_unregister_intr
(
unsigned
int
gsi
)
{
unsigned
long
flags
;
int
irq
,
vector
;
int
irq
,
vector
,
index
;
irq_desc_t
*
idesc
;
u32
low32
;
unsigned
long
trigger
,
polarity
;
...
...
@@ -819,6 +819,9 @@ iosapic_unregister_intr (unsigned int gsi)
list_del
(
&
rte
->
rte_list
);
iosapic_intr_info
[
vector
].
count
--
;
iosapic_free_rte
(
rte
);
index
=
find_iosapic
(
gsi
);
iosapic_lists
[
index
].
rtes_inuse
--
;
WARN_ON
(
iosapic_lists
[
index
].
rtes_inuse
<
0
);
trigger
=
iosapic_intr_info
[
vector
].
trigger
;
polarity
=
iosapic_intr_info
[
vector
].
polarity
;
...
...
@@ -952,30 +955,86 @@ iosapic_system_init (int system_pcat_compat)
}
}
void
__init
static
inline
int
iosapic_alloc
(
void
)
{
int
index
;
for
(
index
=
0
;
index
<
NR_IOSAPICS
;
index
++
)
if
(
!
iosapic_lists
[
index
].
addr
)
return
index
;
printk
(
KERN_WARNING
"%s: failed to allocate iosapic
\n
"
,
__FUNCTION__
);
return
-
1
;
}
static
inline
void
iosapic_free
(
int
index
)
{
memset
(
&
iosapic_lists
[
index
],
0
,
sizeof
(
iosapic_lists
[
0
]));
}
static
inline
int
iosapic_check_gsi_range
(
unsigned
int
gsi_base
,
unsigned
int
ver
)
{
int
index
;
unsigned
int
gsi_end
,
base
,
end
;
/* check gsi range */
gsi_end
=
gsi_base
+
((
ver
>>
16
)
&
0xff
);
for
(
index
=
0
;
index
<
NR_IOSAPICS
;
index
++
)
{
if
(
!
iosapic_lists
[
index
].
addr
)
continue
;
base
=
iosapic_lists
[
index
].
gsi_base
;
end
=
base
+
iosapic_lists
[
index
].
num_rte
-
1
;
if
(
gsi_base
<
base
&&
gsi_end
<
base
)
continue
;
/* OK */
if
(
gsi_base
>
end
&&
gsi_end
>
end
)
continue
;
/* OK */
return
-
EBUSY
;
}
return
0
;
}
int
__devinit
iosapic_init
(
unsigned
long
phys_addr
,
unsigned
int
gsi_base
)
{
int
num_rte
;
int
num_rte
,
err
,
index
;
unsigned
int
isa_irq
,
ver
;
char
__iomem
*
addr
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
iosapic_lock
,
flags
);
{
addr
=
ioremap
(
phys_addr
,
0
);
ver
=
iosapic_version
(
addr
);
addr
=
ioremap
(
phys_addr
,
0
);
ver
=
iosapic_version
(
addr
);
if
((
err
=
iosapic_check_gsi_range
(
gsi_base
,
ver
)))
{
iounmap
(
addr
);
spin_unlock_irqrestore
(
&
iosapic_lock
,
flags
);
return
err
;
}
/*
* The MAX_REDIR register holds the highest input pin
* number (starting from 0).
* We add 1 so that we can use it for number of pins (= RTEs)
*/
num_rte
=
((
ver
>>
16
)
&
0xff
)
+
1
;
/*
* The MAX_REDIR register holds the highest input pin
* number (starting from 0).
* We add 1 so that we can use it for number of pins (= RTEs)
*/
num_rte
=
((
ver
>>
16
)
&
0xff
)
+
1
;
iosapic_lists
[
num_iosapic
].
addr
=
addr
;
iosapic_lists
[
num_iosapic
].
gsi_base
=
gsi_base
;
iosapic_lists
[
num_iosapic
].
num_rte
=
num_rte
;
index
=
iosapic_alloc
();
iosapic_lists
[
index
].
addr
=
addr
;
iosapic_lists
[
index
].
gsi_base
=
gsi_base
;
iosapic_lists
[
index
].
num_rte
=
num_rte
;
#ifdef CONFIG_NUMA
iosapic_lists
[
num_iosapic
].
node
=
MAX_NUMNODES
;
iosapic_lists
[
index
].
node
=
MAX_NUMNODES
;
#endif
num_iosapic
++
;
}
spin_unlock_irqrestore
(
&
iosapic_lock
,
flags
);
if
((
gsi_base
==
0
)
&&
pcat_compat
)
{
/*
...
...
@@ -986,10 +1045,43 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
for
(
isa_irq
=
0
;
isa_irq
<
16
;
++
isa_irq
)
iosapic_override_isa_irq
(
isa_irq
,
isa_irq
,
IOSAPIC_POL_HIGH
,
IOSAPIC_EDGE
);
}
return
0
;
}
#ifdef CONFIG_HOTPLUG
int
iosapic_remove
(
unsigned
int
gsi_base
)
{
int
index
,
err
=
0
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
iosapic_lock
,
flags
);
{
index
=
find_iosapic
(
gsi_base
);
if
(
index
<
0
)
{
printk
(
KERN_WARNING
"%s: No IOSAPIC for GSI base %u
\n
"
,
__FUNCTION__
,
gsi_base
);
goto
out
;
}
if
(
iosapic_lists
[
index
].
rtes_inuse
)
{
err
=
-
EBUSY
;
printk
(
KERN_WARNING
"%s: IOSAPIC for GSI base %u is busy
\n
"
,
__FUNCTION__
,
gsi_base
);
goto
out
;
}
iounmap
(
iosapic_lists
[
index
].
addr
);
iosapic_free
(
index
);
}
out:
spin_unlock_irqrestore
(
&
iosapic_lock
,
flags
);
return
err
;
}
#endif
/* CONFIG_HOTPLUG */
#ifdef CONFIG_NUMA
void
__init
void
__
dev
init
map_iosapic_to_node
(
unsigned
int
gsi_base
,
int
node
)
{
int
index
;
...
...
This diff is collapsed.
Click to expand it.
arch/ia64/pci/pci.c
View file @
adb2705a
...
...
@@ -312,7 +312,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus)
acpi_walk_resources
(
device
->
handle
,
METHOD_NAME__CRS
,
add_window
,
&
info
);
pbus
=
pci_scan_bus
(
bus
,
&
pci_root_ops
,
controller
);
pbus
=
pci_scan_bus
_parented
(
NULL
,
bus
,
&
pci_root_ops
,
controller
);
if
(
pbus
)
pcibios_setup_root_windows
(
pbus
,
controller
);
...
...
@@ -373,6 +373,25 @@ void pcibios_bus_to_resource(struct pci_dev *dev,
res
->
end
=
region
->
end
+
offset
;
}
static
int
__devinit
is_valid_resource
(
struct
pci_dev
*
dev
,
int
idx
)
{
unsigned
int
i
,
type_mask
=
IORESOURCE_IO
|
IORESOURCE_MEM
;
struct
resource
*
devr
=
&
dev
->
resource
[
idx
];
if
(
!
dev
->
bus
)
return
0
;
for
(
i
=
0
;
i
<
PCI_BUS_NUM_RESOURCES
;
i
++
)
{
struct
resource
*
busr
=
dev
->
bus
->
resource
[
i
];
if
(
!
busr
||
((
busr
->
flags
^
devr
->
flags
)
&
type_mask
))
continue
;
if
((
devr
->
start
)
&&
(
devr
->
start
>=
busr
->
start
)
&&
(
devr
->
end
<=
busr
->
end
))
return
1
;
}
return
0
;
}
static
void
__devinit
pcibios_fixup_device_resources
(
struct
pci_dev
*
dev
)
{
struct
pci_bus_region
region
;
...
...
@@ -386,7 +405,8 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
region
.
start
=
dev
->
resource
[
i
].
start
;
region
.
end
=
dev
->
resource
[
i
].
end
;
pcibios_bus_to_resource
(
dev
,
&
dev
->
resource
[
i
],
&
region
);
pci_claim_resource
(
dev
,
i
);
if
((
is_valid_resource
(
dev
,
i
)))
pci_claim_resource
(
dev
,
i
);
}
}
...
...
@@ -398,6 +418,10 @@ pcibios_fixup_bus (struct pci_bus *b)
{
struct
pci_dev
*
dev
;
if
(
b
->
self
)
{
pci_read_bridge_bases
(
b
);
pcibios_fixup_device_resources
(
b
->
self
);
}
list_for_each_entry
(
dev
,
&
b
->
devices
,
bus_list
)
pcibios_fixup_device_resources
(
dev
);
...
...
@@ -418,18 +442,24 @@ pcibios_enable_resources (struct pci_dev *dev, int mask)
u16
cmd
,
old_cmd
;
int
idx
;
struct
resource
*
r
;
unsigned
long
type_mask
=
IORESOURCE_IO
|
IORESOURCE_MEM
;
if
(
!
dev
)
return
-
EINVAL
;
pci_read_config_word
(
dev
,
PCI_COMMAND
,
&
cmd
);
old_cmd
=
cmd
;
for
(
idx
=
0
;
idx
<
6
;
idx
++
)
{
for
(
idx
=
0
;
idx
<
PCI_NUM_RESOURCES
;
idx
++
)
{
/* Only set up the desired resources. */
if
(
!
(
mask
&
(
1
<<
idx
)))
continue
;
r
=
&
dev
->
resource
[
idx
];
if
(
!
(
r
->
flags
&
type_mask
))
continue
;
if
((
idx
==
PCI_ROM_RESOURCE
)
&&
(
!
(
r
->
flags
&
IORESOURCE_ROM_ENABLE
)))
continue
;
if
(
!
r
->
start
&&
r
->
end
)
{
printk
(
KERN_ERR
"PCI: Device %s not available because of resource collisions
\n
"
,
...
...
@@ -441,8 +471,6 @@ pcibios_enable_resources (struct pci_dev *dev, int mask)
if
(
r
->
flags
&
IORESOURCE_MEM
)
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
"
,
pci_name
(
dev
),
old_cmd
,
cmd
);
pci_write_config_word
(
dev
,
PCI_COMMAND
,
cmd
);
...
...
This diff is collapsed.
Click to expand it.
arch/ppc/kernel/pci.c
View file @
adb2705a
...
...
@@ -1495,7 +1495,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
*
offset
+=
hose
->
pci_mem_offset
;
res_bit
=
IORESOURCE_MEM
;
}
else
{
io_offset
=
(
unsigned
long
)
hose
->
io_base_virt
;
io_offset
=
hose
->
io_base_virt
-
___IO_BASE
;
*
offset
+=
io_offset
;
res_bit
=
IORESOURCE_IO
;
}
...
...
@@ -1522,7 +1522,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
/* found it! construct the final physical address */
if
(
mmap_state
==
pci_mmap_io
)
*
offset
+=
hose
->
io_base_phys
-
_IO_BASE
;
*
offset
+=
hose
->
io_base_phys
-
io_offset
;
return
rp
;
}
...
...
@@ -1739,6 +1739,23 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
return
result
;
}
void
pci_resource_to_user
(
const
struct
pci_dev
*
dev
,
int
bar
,
const
struct
resource
*
rsrc
,
u64
*
start
,
u64
*
end
)
{
struct
pci_controller
*
hose
=
pci_bus_to_hose
(
dev
->
bus
->
number
);
unsigned
long
offset
=
0
;
if
(
hose
==
NULL
)
return
;
if
(
rsrc
->
flags
&
IORESOURCE_IO
)
offset
=
___IO_BASE
-
hose
->
io_base_virt
+
hose
->
io_base_phys
;
*
start
=
rsrc
->
start
+
offset
;
*
end
=
rsrc
->
end
+
offset
;
}
void
__init
pci_init_resource
(
struct
resource
*
res
,
unsigned
long
start
,
unsigned
long
end
,
int
flags
,
char
*
name
)
...
...
This diff is collapsed.
Click to expand it.
arch/ppc64/kernel/pci.c
View file @
adb2705a
...
...
@@ -351,7 +351,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
*
offset
+=
hose
->
pci_mem_offset
;
res_bit
=
IORESOURCE_MEM
;
}
else
{
io_offset
=
(
unsigned
long
)
hose
->
io_base_virt
;
io_offset
=
(
unsigned
long
)
hose
->
io_base_virt
-
pci_io_base
;
*
offset
+=
io_offset
;
res_bit
=
IORESOURCE_IO
;
}
...
...
@@ -378,7 +378,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
/* found it! construct the final physical address */
if
(
mmap_state
==
pci_mmap_io
)
*
offset
+=
hose
->
io_base_phys
-
io_offset
;
*
offset
+=
hose
->
io_base_phys
-
io_offset
;
return
rp
;
}
...
...
@@ -944,4 +944,22 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
}
EXPORT_SYMBOL
(
pci_read_irq_line
);
void
pci_resource_to_user
(
const
struct
pci_dev
*
dev
,
int
bar
,
const
struct
resource
*
rsrc
,
u64
*
start
,
u64
*
end
)
{
struct
pci_controller
*
hose
=
pci_bus_to_host
(
dev
->
bus
);
unsigned
long
offset
=
0
;
if
(
hose
==
NULL
)
return
;
if
(
rsrc
->
flags
&
IORESOURCE_IO
)
offset
=
pci_io_base
-
(
unsigned
long
)
hose
->
io_base_virt
+
hose
->
io_base_phys
;
*
start
=
rsrc
->
start
+
offset
;
*
end
=
rsrc
->
end
+
offset
;
}
#endif
/* CONFIG_PPC_MULTIPLATFORM */
This diff is collapsed.
Click to expand it.
arch/x86_64/pci/mmconfig.c
View file @
adb2705a
...
...
@@ -7,25 +7,50 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/acpi.h>
#include "pci.h"
#define MMCONFIG_APER_SIZE (256*1024*1024)
/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */
u32
pci_mmcfg_base_addr
;
/* Static virtual mapping of the MMCONFIG aperture */
char
*
pci_mmcfg_virt
;
struct
mmcfg_virt
{
struct
acpi_table_mcfg_config
*
cfg
;
char
*
virt
;
};
static
struct
mmcfg_virt
*
pci_mmcfg_virt
;
static
inline
char
*
pci_dev_base
(
unsigned
int
bus
,
unsigned
int
devfn
)
static
char
*
get_virt
(
unsigned
int
seg
,
int
bus
)
{
return
pci_mmcfg_virt
+
((
bus
<<
20
)
|
(
devfn
<<
12
));
int
cfg_num
=
-
1
;
struct
acpi_table_mcfg_config
*
cfg
;
while
(
1
)
{
++
cfg_num
;
if
(
cfg_num
>=
pci_mmcfg_config_num
)
{
/* something bad is going on, no cfg table is found. */
/* so we fall back to the old way we used to do this */
/* and just rely on the first entry to be correct. */
return
pci_mmcfg_virt
[
0
].
virt
;
}
cfg
=
pci_mmcfg_virt
[
cfg_num
].
cfg
;
if
(
cfg
->
pci_segment_group_number
!=
seg
)
continue
;
if
((
cfg
->
start_bus_number
<=
bus
)
&&
(
cfg
->
end_bus_number
>=
bus
))
return
pci_mmcfg_virt
[
cfg_num
].
virt
;
}
}
static
inline
char
*
pci_dev_base
(
unsigned
int
seg
,
unsigned
int
bus
,
unsigned
int
devfn
)
{
return
get_virt
(
seg
,
bus
)
+
((
bus
<<
20
)
|
(
devfn
<<
12
));
}
static
int
pci_mmcfg_read
(
unsigned
int
seg
,
unsigned
int
bus
,
unsigned
int
devfn
,
int
reg
,
int
len
,
u32
*
value
)
{
char
*
addr
=
pci_dev_base
(
bus
,
devfn
);
char
*
addr
=
pci_dev_base
(
seg
,
bus
,
devfn
);
if
(
unlikely
(
!
value
||
(
bus
>
255
)
||
(
devfn
>
255
)
||
(
reg
>
4095
)))
return
-
EINVAL
;
...
...
@@ -48,7 +73,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
static
int
pci_mmcfg_write
(
unsigned
int
seg
,
unsigned
int
bus
,
unsigned
int
devfn
,
int
reg
,
int
len
,
u32
value
)
{
char
*
addr
=
pci_dev_base
(
bus
,
devfn
);
char
*
addr
=
pci_dev_base
(
seg
,
bus
,
devfn
);
if
(
unlikely
((
bus
>
255
)
||
(
devfn
>
255
)
||
(
reg
>
4095
)))
return
-
EINVAL
;
...
...
@@ -75,9 +100,15 @@ static struct pci_raw_ops pci_mmcfg = {
static
int
__init
pci_mmcfg_init
(
void
)
{
int
i
;
if
((
pci_probe
&
PCI_PROBE_MMCONF
)
==
0
)
return
0
;
if
(
!
pci_mmcfg_base_addr
)
acpi_table_parse
(
ACPI_MCFG
,
acpi_parse_mcfg
);
if
((
pci_mmcfg_config_num
==
0
)
||
(
pci_mmcfg_config
==
NULL
)
||
(
pci_mmcfg_config
[
0
].
base_address
==
0
))
return
0
;
/* Kludge for now. Don't use mmconfig on AMD systems because
...
...
@@ -88,13 +119,22 @@ static int __init pci_mmcfg_init(void)
return
0
;
/* RED-PEN i386 doesn't do _nocache right now */
pci_mmcfg_virt
=
ioremap_nocache
(
pci_mmcfg_base_addr
,
MMCONFIG_APER_SIZE
);
if
(
!
pci_mmcfg_virt
)
{
printk
(
"PCI: Cannot
map
mmconfig
aper
ture
\n
"
);
pci_mmcfg_virt
=
kmalloc
(
sizeof
(
*
pci_mmcfg_virt
)
*
pci_mmcfg_config_num
,
GFP_KERNEL
);
if
(
pci_mmcfg_virt
==
NULL
)
{
printk
(
"PCI: Can
not
allocate memory for
mmconfig
struc
ture
s
\n
"
);
return
0
;
}
}
for
(
i
=
0
;
i
<
pci_mmcfg_config_num
;
++
i
)
{
pci_mmcfg_virt
[
i
].
cfg
=
&
pci_mmcfg_config
[
i
];
pci_mmcfg_virt
[
i
].
virt
=
ioremap_nocache
(
pci_mmcfg_config
[
i
].
base_address
,
MMCONFIG_APER_SIZE
);
if
(
!
pci_mmcfg_virt
[
i
].
virt
)
{
printk
(
"PCI: Cannot map mmconfig aperture for segment %d
\n
"
,
pci_mmcfg_config
[
i
].
pci_segment_group_number
);
return
0
;
}
printk
(
KERN_INFO
"PCI: Using MMCONFIG at %x
\n
"
,
pci_mmcfg_config
[
i
].
base_address
);
}
printk
(
KERN_INFO
"PCI: Using MMCONFIG at %x
\n
"
,
pci_mmcfg_base_addr
);
raw_pci_ops
=
&
pci_mmcfg
;
pci_probe
=
(
pci_probe
&
~
PCI_PROBE_MASK
)
|
PCI_PROBE_MMCONF
;
...
...
This diff is collapsed.
Click to expand it.
drivers/acpi/container.c
View file @
adb2705a
...
...
@@ -153,7 +153,7 @@ container_device_add(struct acpi_device **device, acpi_handle handle)
return_VALUE
(
-
ENODEV
);
}
result
=
acpi_bus_s
can
(
*
device
);
result
=
acpi_bus_s
tart
(
*
device
);
return_VALUE
(
result
);
}
...
...
This diff is collapsed.
Click to expand it.
drivers/acpi/pci_bind.c
View file @
adb2705a
...
...
@@ -61,15 +61,14 @@ acpi_pci_data_handler (
/**
* acpi_
os_
get_pci_id
* acpi_get_pci_id
* ------------------
* This function is used by the ACPI Interpreter (a.k.a. Core Subsystem)
* to resolve PCI information for ACPI-PCI devices defined in the namespace.
* This typically occurs when resolving PCI operation region information.
*/
#ifdef ACPI_FUTURE_USAGE
acpi_status
acpi_
os_
get_pci_id
(
acpi_get_pci_id
(
acpi_handle
handle
,
struct
acpi_pci_id
*
id
)
{
...
...
@@ -78,7 +77,7 @@ acpi_os_get_pci_id (
struct
acpi_device
*
device
=
NULL
;
struct
acpi_pci_data
*
data
=
NULL
;
ACPI_FUNCTION_TRACE
(
"acpi_
os_
get_pci_id"
);
ACPI_FUNCTION_TRACE
(
"acpi_get_pci_id"
);
if
(
!
id
)
return_ACPI_STATUS
(
AE_BAD_PARAMETER
);
...
...
@@ -92,7 +91,7 @@ acpi_os_get_pci_id (
}
status
=
acpi_get_data
(
handle
,
acpi_pci_data_handler
,
(
void
**
)
&
data
);
if
(
ACPI_FAILURE
(
status
)
||
!
data
||
!
data
->
dev
)
{
if
(
ACPI_FAILURE
(
status
)
||
!
data
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid ACPI-PCI context for device %s
\n
"
,
acpi_device_bid
(
device
)));
...
...
@@ -115,7 +114,7 @@ acpi_os_get_pci_id (
return_ACPI_STATUS
(
AE_OK
);
}
#endif
/* ACPI_FUTURE_USAGE */
EXPORT_SYMBOL
(
acpi_get_pci_id
);
int
...
...
@@ -129,6 +128,8 @@ acpi_pci_bind (
char
*
pathname
=
NULL
;
struct
acpi_buffer
buffer
=
{
0
,
NULL
};
acpi_handle
handle
=
NULL
;
struct
pci_dev
*
dev
;
struct
pci_bus
*
bus
;
ACPI_FUNCTION_TRACE
(
"acpi_pci_bind"
);
...
...
@@ -193,8 +194,20 @@ acpi_pci_bind (
* Locate matching device in PCI namespace. If it doesn't exist
* this typically means that the device isn't currently inserted
* (e.g. docking station, port replicator, etc.).
* We cannot simply search the global pci device list, since
* PCI devices are added to the global pci list when the root
* bridge start ops are run, which may not have happened yet.
*/
data
->
dev
=
pci_find_slot
(
data
->
id
.
bus
,
PCI_DEVFN
(
data
->
id
.
device
,
data
->
id
.
function
));
bus
=
pci_find_bus
(
data
->
id
.
segment
,
data
->
id
.
bus
);
if
(
bus
)
{
list_for_each_entry
(
dev
,
&
bus
->
devices
,
bus_list
)
{
if
(
dev
->
devfn
==
PCI_DEVFN
(
data
->
id
.
device
,
data
->
id
.
function
))
{
data
->
dev
=
dev
;
break
;
}
}
}
if
(
!
data
->
dev
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Device %02x:%02x:%02x.%02x not present in PCI namespace
\n
"
,
...
...
This diff is collapsed.
Click to expand it.
drivers/acpi/pci_root.c
View file @
adb2705a
...
...
@@ -46,6 +46,7 @@ ACPI_MODULE_NAME ("pci_root")
static
int
acpi_pci_root_add
(
struct
acpi_device
*
device
);
static
int
acpi_pci_root_remove
(
struct
acpi_device
*
device
,
int
type
);
static
int
acpi_pci_root_start
(
struct
acpi_device
*
device
);
static
struct
acpi_driver
acpi_pci_root_driver
=
{
.
name
=
ACPI_PCI_ROOT_DRIVER_NAME
,
...
...
@@ -54,6 +55,7 @@ static struct acpi_driver acpi_pci_root_driver = {
.
ops
=
{
.
add
=
acpi_pci_root_add
,
.
remove
=
acpi_pci_root_remove
,
.
start
=
acpi_pci_root_start
,
},
};
...
...
@@ -169,6 +171,7 @@ acpi_pci_root_add (
if
(
!
root
)
return_VALUE
(
-
ENOMEM
);
memset
(
root
,
0
,
sizeof
(
struct
acpi_pci_root
));
INIT_LIST_HEAD
(
&
root
->
node
);
root
->
handle
=
device
->
handle
;
strcpy
(
acpi_device_name
(
device
),
ACPI_PCI_ROOT_DEVICE_NAME
);
...
...
@@ -298,12 +301,31 @@ acpi_pci_root_add (
root
->
id
.
bus
);
end:
if
(
result
)
if
(
result
)
{
if
(
!
list_empty
(
&
root
->
node
))
list_del
(
&
root
->
node
);
kfree
(
root
);
}
return_VALUE
(
result
);
}
static
int
acpi_pci_root_start
(
struct
acpi_device
*
device
)
{
struct
acpi_pci_root
*
root
;
ACPI_FUNCTION_TRACE
(
"acpi_pci_root_start"
);
list_for_each_entry
(
root
,
&
acpi_pci_roots
,
node
)
{
if
(
root
->
handle
==
device
->
handle
)
{
pci_bus_add_devices
(
root
->
bus
);
return_VALUE
(
0
);
}
}
return_VALUE
(
-
ENODEV
);
}
static
int
acpi_pci_root_remove
(
...
...
This diff is collapsed.
Click to expand it.
drivers/acpi/processor_core.c
View file @
adb2705a
...
...
@@ -723,7 +723,7 @@ int acpi_processor_device_add(
return_VALUE
(
-
ENODEV
);
}
acpi_bus_s
can
(
*
device
);
acpi_bus_s
tart
(
*
device
);
pr
=
acpi_driver_data
(
*
device
);
if
(
!
pr
)
...
...
This diff is collapsed.
Click to expand it.
drivers/acpi/scan.c
View file @
adb2705a
...
...
@@ -553,20 +553,29 @@ acpi_bus_driver_init (
* upon possible configuration and currently allocated resources.
*/
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Driver successfully bound to device
\n
"
));
return_VALUE
(
0
);
}
int
acpi_start_single_object
(
struct
acpi_device
*
device
)
{
int
result
=
0
;
struct
acpi_driver
*
driver
;
ACPI_FUNCTION_TRACE
(
"acpi_start_single_object"
);
if
(
!
(
driver
=
device
->
driver
))
return_VALUE
(
0
);
if
(
driver
->
ops
.
start
)
{
result
=
driver
->
ops
.
start
(
device
);
if
(
result
&&
driver
->
ops
.
remove
)
driver
->
ops
.
remove
(
device
,
ACPI_BUS_REMOVAL_NORMAL
);
return_VALUE
(
result
);
}
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Driver successfully bound to device
\n
"
));
if
(
driver
->
ops
.
scan
)
{
driver
->
ops
.
scan
(
device
);
}
return_VALUE
(
0
);
return_VALUE
(
result
);
}
static
int
acpi_driver_attach
(
struct
acpi_driver
*
drv
)
...
...
@@ -586,6 +595,7 @@ static int acpi_driver_attach(struct acpi_driver * drv)
if
(
!
acpi_bus_match
(
dev
,
drv
))
{
if
(
!
acpi_bus_driver_init
(
dev
,
drv
))
{
acpi_start_single_object
(
dev
);
atomic_inc
(
&
drv
->
references
);
count
++
;
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Found driver [%s] for device [%s]
\n
"
,
...
...
@@ -1009,8 +1019,8 @@ acpi_bus_remove (
}
int
acpi_
bus_add
(
static
int
acpi_
add_single_object
(
struct
acpi_device
**
child
,
struct
acpi_device
*
parent
,
acpi_handle
handle
,
...
...
@@ -1019,7 +1029,7 @@ acpi_bus_add (
int
result
=
0
;
struct
acpi_device
*
device
=
NULL
;
ACPI_FUNCTION_TRACE
(
"acpi_
bus_add
"
);
ACPI_FUNCTION_TRACE
(
"acpi_
add_single_object
"
);
if
(
!
child
)
return_VALUE
(
-
EINVAL
);
...
...
@@ -1140,7 +1150,7 @@ acpi_bus_add (
*
* TBD: Assumes LDM provides driver hot-plug capability.
*/
acpi_bus_find_driver
(
device
);
result
=
acpi_bus_find_driver
(
device
);
end:
if
(
!
result
)
...
...
@@ -1153,10 +1163,10 @@ acpi_bus_add (
return_VALUE
(
result
);
}
EXPORT_SYMBOL
(
acpi_bus_add
);
int
acpi_bus_scan
(
struct
acpi_device
*
start
)
static
int
acpi_bus_scan
(
struct
acpi_device
*
start
,
struct
acpi_bus_ops
*
ops
)
{
acpi_status
status
=
AE_OK
;
struct
acpi_device
*
parent
=
NULL
;
...
...
@@ -1229,9 +1239,20 @@ int acpi_bus_scan (struct acpi_device *start)
continue
;
}
status
=
acpi_bus_add
(
&
child
,
parent
,
chandle
,
type
);
if
(
ACPI_FAILURE
(
status
))
continue
;
if
(
ops
->
acpi_op_add
)
status
=
acpi_add_single_object
(
&
child
,
parent
,
chandle
,
type
);
else
status
=
acpi_bus_get_device
(
chandle
,
&
child
);
if
(
ACPI_FAILURE
(
status
))
continue
;
if
(
ops
->
acpi_op_start
)
{
status
=
acpi_start_single_object
(
child
);
if
(
ACPI_FAILURE
(
status
))
continue
;
}
/*
* If the device is present, enabled, and functioning then
...
...
@@ -1257,8 +1278,50 @@ int acpi_bus_scan (struct acpi_device *start)
return_VALUE
(
0
);
}
EXPORT_SYMBOL
(
acpi_bus_scan
);
int
acpi_bus_add
(
struct
acpi_device
**
child
,
struct
acpi_device
*
parent
,
acpi_handle
handle
,
int
type
)
{
int
result
;
struct
acpi_bus_ops
ops
;
ACPI_FUNCTION_TRACE
(
"acpi_bus_add"
);
result
=
acpi_add_single_object
(
child
,
parent
,
handle
,
type
);
if
(
!
result
)
{
memset
(
&
ops
,
0
,
sizeof
(
ops
));
ops
.
acpi_op_add
=
1
;
result
=
acpi_bus_scan
(
*
child
,
&
ops
);
}
return_VALUE
(
result
);
}
EXPORT_SYMBOL
(
acpi_bus_add
);
int
acpi_bus_start
(
struct
acpi_device
*
device
)
{
int
result
;
struct
acpi_bus_ops
ops
;
ACPI_FUNCTION_TRACE
(
"acpi_bus_start"
);
if
(
!
device
)
return_VALUE
(
-
EINVAL
);
result
=
acpi_start_single_object
(
device
);
if
(
!
result
)
{
memset
(
&
ops
,
0
,
sizeof
(
ops
));
ops
.
acpi_op_start
=
1
;
result
=
acpi_bus_scan
(
device
,
&
ops
);
}
return_VALUE
(
result
);
}
EXPORT_SYMBOL
(
acpi_bus_start
);
static
int
acpi_bus_trim
(
struct
acpi_device
*
start
,
...
...
@@ -1331,13 +1394,19 @@ acpi_bus_scan_fixed (
/*
* Enumerate all fixed-feature devices.
*/
if
(
acpi_fadt
.
pwr_button
==
0
)
result
=
acpi_
bus_add
(
&
device
,
acpi_root
,
if
(
acpi_fadt
.
pwr_button
==
0
)
{
result
=
acpi_
add_single_object
(
&
device
,
acpi_root
,
NULL
,
ACPI_BUS_TYPE_POWER_BUTTON
);
if
(
!
result
)
result
=
acpi_start_single_object
(
device
);
}
if
(
acpi_fadt
.
sleep_button
==
0
)
result
=
acpi_
bus_add
(
&
device
,
acpi_root
,
if
(
acpi_fadt
.
sleep_button
==
0
)
{
result
=
acpi_
add_single_object
(
&
device
,
acpi_root
,
NULL
,
ACPI_BUS_TYPE_SLEEP_BUTTON
);
if
(
!
result
)
result
=
acpi_start_single_object
(
device
);
}
return_VALUE
(
result
);
}
...
...
@@ -1346,6 +1415,7 @@ acpi_bus_scan_fixed (
static
int
__init
acpi_scan_init
(
void
)
{
int
result
;
struct
acpi_bus_ops
ops
;
ACPI_FUNCTION_TRACE
(
"acpi_scan_init"
);
...
...
@@ -1357,17 +1427,23 @@ static int __init acpi_scan_init(void)
/*
* Create the root device in the bus's device tree
*/
result
=
acpi_
bus_add
(
&
acpi_root
,
NULL
,
ACPI_ROOT_OBJECT
,
result
=
acpi_
add_single_object
(
&
acpi_root
,
NULL
,
ACPI_ROOT_OBJECT
,
ACPI_BUS_TYPE_SYSTEM
);
if
(
result
)
goto
Done
;
result
=
acpi_start_single_object
(
acpi_root
);
/*
* Enumerate devices in the ACPI namespace.
*/
result
=
acpi_bus_scan_fixed
(
acpi_root
);
if
(
!
result
)
result
=
acpi_bus_scan
(
acpi_root
);
if
(
!
result
)
{
memset
(
&
ops
,
0
,
sizeof
(
ops
));
ops
.
acpi_op_add
=
1
;
ops
.
acpi_op_start
=
1
;
result
=
acpi_bus_scan
(
acpi_root
,
&
ops
);
}
if
(
result
)
acpi_device_unregister
(
acpi_root
,
ACPI_BUS_REMOVAL_NORMAL
);
...
...
This diff is collapsed.
Click to expand it.
drivers/char/moxa.c
View file @
adb2705a
...
...
@@ -451,7 +451,7 @@ static int __init moxa_init(void)
int
n
=
(
sizeof
(
moxa_pcibrds
)
/
sizeof
(
moxa_pcibrds
[
0
]))
-
1
;
i
=
0
;
while
(
i
<
n
)
{
while
((
p
=
pci_
find
_device
(
moxa_pcibrds
[
i
].
vendor
,
moxa_pcibrds
[
i
].
device
,
p
))
!=
NULL
)
while
((
p
=
pci_
get
_device
(
moxa_pcibrds
[
i
].
vendor
,
moxa_pcibrds
[
i
].
device
,
p
))
!=
NULL
)
{
if
(
pci_enable_device
(
p
))
continue
;
...
...
This diff is collapsed.
Click to expand it.
Prev
1
2
3
4
Next
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