Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
adb2705a
K
Kernel
项目概览
openeuler
/
Kernel
接近 2 年 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
adb2705a
编写于
6月 28, 2005
作者:
L
Linus Torvalds
浏览文件
操作
浏览文件
下载
差异文件
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6
上级
f340c0d1
8644d2a4
变更
69
展开全部
隐藏空白更改
内联
并排
Showing
69 changed file
with
1492 addition
and
1833 deletion
+1492
-1833
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
drivers/char/rio/rio_linux.c
drivers/char/rio/rio_linux.c
+2
-2
drivers/message/fusion/mptfc.c
drivers/message/fusion/mptfc.c
+1
-3
drivers/message/fusion/mptscsih.c
drivers/message/fusion/mptscsih.c
+5
-5
drivers/message/fusion/mptscsih.h
drivers/message/fusion/mptscsih.h
+1
-1
drivers/message/fusion/mptspi.c
drivers/message/fusion/mptspi.c
+1
-3
drivers/net/e100.c
drivers/net/e100.c
+2
-7
drivers/net/via-rhine.c
drivers/net/via-rhine.c
+4
-7
drivers/parisc/dino.c
drivers/parisc/dino.c
+1
-0
drivers/parisc/lba_pci.c
drivers/parisc/lba_pci.c
+2
-0
drivers/pci/bus.c
drivers/pci/bus.c
+7
-4
drivers/pci/hotplug/Makefile
drivers/pci/hotplug/Makefile
+1
-3
drivers/pci/hotplug/acpiphp.h
drivers/pci/hotplug/acpiphp.h
+2
-45
drivers/pci/hotplug/acpiphp_core.c
drivers/pci/hotplug/acpiphp_core.c
+5
-4
drivers/pci/hotplug/acpiphp_glue.c
drivers/pci/hotplug/acpiphp_glue.c
+512
-370
drivers/pci/hotplug/acpiphp_pci.c
drivers/pci/hotplug/acpiphp_pci.c
+0
-449
drivers/pci/hotplug/acpiphp_res.c
drivers/pci/hotplug/acpiphp_res.c
+0
-700
drivers/pci/hotplug/cpqphp_core.c
drivers/pci/hotplug/cpqphp_core.c
+3
-2
drivers/pci/msi.c
drivers/pci/msi.c
+33
-55
drivers/pci/msi.h
drivers/pci/msi.h
+4
-5
drivers/pci/pci-sysfs.c
drivers/pci/pci-sysfs.c
+21
-5
drivers/pci/probe.c
drivers/pci/probe.c
+22
-7
drivers/pci/proc.c
drivers/pci/proc.c
+10
-4
drivers/pci/remove.c
drivers/pci/remove.c
+9
-5
drivers/pci/setup-bus.c
drivers/pci/setup-bus.c
+4
-1
drivers/scsi/3w-9xxx.c
drivers/scsi/3w-9xxx.c
+3
-5
drivers/scsi/3w-xxxx.c
drivers/scsi/3w-xxxx.c
+3
-5
drivers/scsi/ipr.c
drivers/scsi/ipr.c
+4
-6
drivers/scsi/megaraid.c
drivers/scsi/megaraid.c
+3
-5
include/acpi/acpi_bus.h
include/acpi/acpi_bus.h
+16
-1
include/acpi/acpi_drivers.h
include/acpi/acpi_drivers.h
+1
-0
include/asm-alpha/pci.h
include/asm-alpha/pci.h
+19
-0
include/asm-arm/pci.h
include/asm-arm/pci.h
+10
-0
include/asm-frv/pci.h
include/asm-frv/pci.h
+10
-0
include/asm-i386/pci.h
include/asm-i386/pci.h
+10
-0
include/asm-ia64/iosapic.h
include/asm-ia64/iosapic.h
+9
-3
include/asm-ia64/pci.h
include/asm-ia64/pci.h
+19
-0
include/asm-mips/pci.h
include/asm-mips/pci.h
+10
-0
include/asm-parisc/pci.h
include/asm-parisc/pci.h
+19
-0
include/asm-ppc/pci.h
include/asm-ppc/pci.h
+16
-0
include/asm-ppc64/pci.h
include/asm-ppc64/pci.h
+26
-0
include/asm-sh/pci.h
include/asm-sh/pci.h
+10
-0
include/asm-sh64/pci.h
include/asm-sh64/pci.h
+10
-0
include/asm-sparc/pci.h
include/asm-sparc/pci.h
+10
-0
include/asm-sparc64/pci.h
include/asm-sparc64/pci.h
+19
-0
include/asm-v850/pci.h
include/asm-v850/pci.h
+10
-0
include/asm-x86_64/pci.h
include/asm-x86_64/pci.h
+10
-0
include/linux/acpi.h
include/linux/acpi.h
+16
-3
include/linux/pci.h
include/linux/pci.h
+31
-2
include/linux/pci_ids.h
include/linux/pci_ids.h
+2
-0
未找到文件。
Documentation/kernel-parameters.txt
浏览文件 @
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.
...
...
arch/i386/kernel/acpi/boot.c
浏览文件 @
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
;
}
...
...
arch/i386/pci/common.c
浏览文件 @
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
...
...
arch/i386/pci/irq.c
浏览文件 @
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
;
}
...
...
arch/i386/pci/legacy.c
浏览文件 @
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
();
...
...
arch/i386/pci/mmconfig.c
浏览文件 @
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
...
...
arch/i386/pci/numa.c
浏览文件 @
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
)
...
...
arch/i386/pci/pci.h
浏览文件 @
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 */
...
...
arch/ia64/kernel/acpi.c
浏览文件 @
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 */
arch/ia64/kernel/iosapic.c
浏览文件 @
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
;
...
...
arch/ia64/pci/pci.c
浏览文件 @
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
);
...
...
arch/ppc/kernel/pci.c
浏览文件 @
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
)
...
...
arch/ppc64/kernel/pci.c
浏览文件 @
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 */
arch/x86_64/pci/mmconfig.c
浏览文件 @
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: Can
not map mmconfig aperture
\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 structures
\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
;
...
...
drivers/acpi/container.c
浏览文件 @
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
);
}
...
...
drivers/acpi/pci_bind.c
浏览文件 @
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
"
,
...
...
drivers/acpi/pci_root.c
浏览文件 @
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
(
...
...
drivers/acpi/processor_core.c
浏览文件 @
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
)
...
...
drivers/acpi/scan.c
浏览文件 @
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
);
...
...
drivers/char/moxa.c
浏览文件 @
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
;
...
...
drivers/char/rio/rio_linux.c
浏览文件 @
adb2705a
...
...
@@ -1095,7 +1095,7 @@ static int __init rio_init(void)
#ifdef CONFIG_PCI
/* First look for the JET devices: */
while
((
pdev
=
pci_
find_device
(
PCI_VENDOR_ID_SPECIALIX
,
while
((
pdev
=
pci_
get_device
(
PCI_VENDOR_ID_SPECIALIX
,
PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8
,
pdev
)))
{
if
(
pci_enable_device
(
pdev
))
continue
;
...
...
@@ -1169,7 +1169,7 @@ static int __init rio_init(void)
*/
/* Then look for the older RIO/PCI devices: */
while
((
pdev
=
pci_
find_device
(
PCI_VENDOR_ID_SPECIALIX
,
while
((
pdev
=
pci_
get_device
(
PCI_VENDOR_ID_SPECIALIX
,
PCI_DEVICE_ID_SPECIALIX_RIO
,
pdev
)))
{
if
(
pci_enable_device
(
pdev
))
continue
;
...
...
drivers/message/fusion/mptfc.c
浏览文件 @
adb2705a
...
...
@@ -364,9 +364,7 @@ static struct pci_driver mptfc_driver = {
.
id_table
=
mptfc_pci_table
,
.
probe
=
mptfc_probe
,
.
remove
=
__devexit_p
(
mptscsih_remove
),
.
driver
=
{
.
shutdown
=
mptscsih_shutdown
,
},
.
shutdown
=
mptscsih_shutdown
,
#ifdef CONFIG_PM
.
suspend
=
mptscsih_suspend
,
.
resume
=
mptscsih_resume
,
...
...
drivers/message/fusion/mptscsih.c
浏览文件 @
adb2705a
...
...
@@ -170,7 +170,7 @@ static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
#endif
void
mptscsih_remove
(
struct
pci_dev
*
);
void
mptscsih_shutdown
(
struct
device
*
);
void
mptscsih_shutdown
(
struct
pci_dev
*
);
#ifdef CONFIG_PM
int
mptscsih_suspend
(
struct
pci_dev
*
pdev
,
pm_message_t
state
);
int
mptscsih_resume
(
struct
pci_dev
*
pdev
);
...
...
@@ -988,7 +988,7 @@ mptscsih_remove(struct pci_dev *pdev)
#endif
#endif
mptscsih_shutdown
(
&
pdev
->
dev
);
mptscsih_shutdown
(
p
dev
);
sz1
=
0
;
...
...
@@ -1026,9 +1026,9 @@ mptscsih_remove(struct pci_dev *pdev)
*
*/
void
mptscsih_shutdown
(
struct
device
*
dev
)
mptscsih_shutdown
(
struct
pci_dev
*
p
dev
)
{
MPT_ADAPTER
*
ioc
=
pci_get_drvdata
(
to_pci_dev
(
dev
)
);
MPT_ADAPTER
*
ioc
=
pci_get_drvdata
(
pdev
);
struct
Scsi_Host
*
host
=
ioc
->
sh
;
MPT_SCSI_HOST
*
hd
;
...
...
@@ -1054,7 +1054,7 @@ mptscsih_shutdown(struct device * dev)
int
mptscsih_suspend
(
struct
pci_dev
*
pdev
,
pm_message_t
state
)
{
mptscsih_shutdown
(
&
pdev
->
dev
);
mptscsih_shutdown
(
p
dev
);
return
mpt_suspend
(
pdev
,
state
);
}
...
...
drivers/message/fusion/mptscsih.h
浏览文件 @
adb2705a
...
...
@@ -82,7 +82,7 @@
#endif
extern
void
mptscsih_remove
(
struct
pci_dev
*
);
extern
void
mptscsih_shutdown
(
struct
device
*
);
extern
void
mptscsih_shutdown
(
struct
pci_dev
*
);
#ifdef CONFIG_PM
extern
int
mptscsih_suspend
(
struct
pci_dev
*
pdev
,
u32
state
);
extern
int
mptscsih_resume
(
struct
pci_dev
*
pdev
);
...
...
drivers/message/fusion/mptspi.c
浏览文件 @
adb2705a
...
...
@@ -419,9 +419,7 @@ static struct pci_driver mptspi_driver = {
.
id_table
=
mptspi_pci_table
,
.
probe
=
mptspi_probe
,
.
remove
=
__devexit_p
(
mptscsih_remove
),
.
driver
=
{
.
shutdown
=
mptscsih_shutdown
,
},
.
shutdown
=
mptscsih_shutdown
,
#ifdef CONFIG_PM
.
suspend
=
mptscsih_suspend
,
.
resume
=
mptscsih_resume
,
...
...
drivers/net/e100.c
浏览文件 @
adb2705a
...
...
@@ -2447,9 +2447,8 @@ static int e100_resume(struct pci_dev *pdev)
#endif
static
void
e100_shutdown
(
struct
device
*
dev
)
static
void
e100_shutdown
(
struct
pci_dev
*
p
dev
)
{
struct
pci_dev
*
pdev
=
container_of
(
dev
,
struct
pci_dev
,
dev
);
struct
net_device
*
netdev
=
pci_get_drvdata
(
pdev
);
struct
nic
*
nic
=
netdev_priv
(
netdev
);
...
...
@@ -2470,11 +2469,7 @@ static struct pci_driver e100_driver = {
.
suspend
=
e100_suspend
,
.
resume
=
e100_resume
,
#endif
.
driver
=
{
.
shutdown
=
e100_shutdown
,
}
.
shutdown
=
e100_shutdown
,
};
static
int
__init
e100_init_module
(
void
)
...
...
drivers/net/via-rhine.c
浏览文件 @
adb2705a
...
...
@@ -507,7 +507,7 @@ static struct net_device_stats *rhine_get_stats(struct net_device *dev);
static
int
netdev_ioctl
(
struct
net_device
*
dev
,
struct
ifreq
*
rq
,
int
cmd
);
static
struct
ethtool_ops
netdev_ethtool_ops
;
static
int
rhine_close
(
struct
net_device
*
dev
);
static
void
rhine_shutdown
(
struct
device
*
g
dev
);
static
void
rhine_shutdown
(
struct
pci_dev
*
p
dev
);
#define RHINE_WAIT_FOR(condition) do { \
int i=1024; \
...
...
@@ -1895,9 +1895,8 @@ static void __devexit rhine_remove_one(struct pci_dev *pdev)
pci_set_drvdata
(
pdev
,
NULL
);
}
static
void
rhine_shutdown
(
struct
device
*
gen
dev
)
static
void
rhine_shutdown
(
struct
pci_dev
*
p
dev
)
{
struct
pci_dev
*
pdev
=
to_pci_dev
(
gendev
);
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
struct
rhine_private
*
rp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
rp
->
base
;
...
...
@@ -1956,7 +1955,7 @@ static int rhine_suspend(struct pci_dev *pdev, pm_message_t state)
pci_save_state
(
pdev
);
spin_lock_irqsave
(
&
rp
->
lock
,
flags
);
rhine_shutdown
(
&
pdev
->
dev
);
rhine_shutdown
(
p
dev
);
spin_unlock_irqrestore
(
&
rp
->
lock
,
flags
);
free_irq
(
dev
->
irq
,
dev
);
...
...
@@ -2010,9 +2009,7 @@ static struct pci_driver rhine_driver = {
.
suspend
=
rhine_suspend
,
.
resume
=
rhine_resume
,
#endif
/* CONFIG_PM */
.
driver
=
{
.
shutdown
=
rhine_shutdown
,
}
.
shutdown
=
rhine_shutdown
,
};
...
...
drivers/parisc/dino.c
浏览文件 @
adb2705a
...
...
@@ -993,6 +993,7 @@ dino_driver_callback(struct parisc_device *dev)
bus
=
pci_scan_bus_parented
(
&
dev
->
dev
,
dino_current_bus
,
&
dino_cfg_ops
,
NULL
);
if
(
bus
)
{
pci_bus_add_devices
(
bus
);
/* This code *depends* on scanning being single threaded
* if it isn't, this global bus number count will fail
*/
...
...
drivers/parisc/lba_pci.c
浏览文件 @
adb2705a
...
...
@@ -1570,6 +1570,8 @@ lba_driver_probe(struct parisc_device *dev)
lba_bus
=
lba_dev
->
hba
.
hba_bus
=
pci_scan_bus_parented
(
&
dev
->
dev
,
lba_dev
->
hba
.
bus_num
.
start
,
cfg_ops
,
NULL
);
if
(
lba_bus
)
pci_bus_add_devices
(
lba_bus
);
/* This is in lieu of calling pci_assign_unassigned_resources() */
if
(
is_pdc_pat
())
{
...
...
drivers/pci/bus.c
浏览文件 @
adb2705a
...
...
@@ -121,10 +121,13 @@ void __devinit pci_bus_add_devices(struct pci_bus *bus)
* If there is an unattached subordinate bus, attach
* it and then scan for unattached PCI devices.
*/
if
(
dev
->
subordinate
&&
list_empty
(
&
dev
->
subordinate
->
node
))
{
spin_lock
(
&
pci_bus_lock
);
list_add_tail
(
&
dev
->
subordinate
->
node
,
&
dev
->
bus
->
children
);
spin_unlock
(
&
pci_bus_lock
);
if
(
dev
->
subordinate
)
{
if
(
list_empty
(
&
dev
->
subordinate
->
node
))
{
spin_lock
(
&
pci_bus_lock
);
list_add_tail
(
&
dev
->
subordinate
->
node
,
&
dev
->
bus
->
children
);
spin_unlock
(
&
pci_bus_lock
);
}
pci_bus_add_devices
(
dev
->
subordinate
);
sysfs_create_link
(
&
dev
->
subordinate
->
class_dev
.
kobj
,
&
dev
->
dev
.
kobj
,
"bridge"
);
...
...
drivers/pci/hotplug/Makefile
浏览文件 @
adb2705a
...
...
@@ -36,9 +36,7 @@ ibmphp-objs := ibmphp_core.o \
ibmphp_hpc.o
acpiphp-objs
:=
acpiphp_core.o
\
acpiphp_glue.o
\
acpiphp_pci.o
\
acpiphp_res.o
acpiphp_glue.o
rpaphp-objs
:=
rpaphp_core.o
\
rpaphp_pci.o
\
...
...
drivers/pci/hotplug/acpiphp.h
浏览文件 @
adb2705a
...
...
@@ -7,6 +7,8 @@
* Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
* Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
* Copyright (C) 2002,2003 NEC Corporation
* Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com)
* Copyright (C) 2003-2005 Hewlett Packard
*
* All rights reserved.
*
...
...
@@ -52,7 +54,6 @@
struct
acpiphp_bridge
;
struct
acpiphp_slot
;
struct
pci_resource
;
/*
* struct slot - slot information for each *physical* slot
...
...
@@ -65,15 +66,6 @@ struct slot {
struct
acpiphp_slot
*
acpi_slot
;
};
/*
* struct pci_resource - describes pci resource (mem, pfmem, io, bus)
*/
struct
pci_resource
{
struct
pci_resource
*
next
;
u64
base
;
u32
length
;
};
/**
* struct hpp_param - ACPI 2.0 _HPP Hot Plug Parameters
* @cache_line_size in DWORD
...
...
@@ -101,10 +93,6 @@ struct acpiphp_bridge {
int
type
;
int
nr_slots
;
u8
seg
;
u8
bus
;
u8
sub
;
u32
flags
;
/* This bus (host bridge) or Secondary bus (PCI-to-PCI bridge) */
...
...
@@ -117,12 +105,6 @@ struct acpiphp_bridge {
struct
hpp_param
hpp
;
spinlock_t
res_lock
;
/* available resources on this bus */
struct
pci_resource
*
mem_head
;
struct
pci_resource
*
p_mem_head
;
struct
pci_resource
*
io_head
;
struct
pci_resource
*
bus_head
;
};
...
...
@@ -163,12 +145,6 @@ struct acpiphp_func {
u8
function
;
/* pci function# */
u32
flags
;
/* see below */
/* resources used for this function */
struct
pci_resource
*
mem_head
;
struct
pci_resource
*
p_mem_head
;
struct
pci_resource
*
io_head
;
struct
pci_resource
*
bus_head
;
};
/**
...
...
@@ -243,25 +219,6 @@ extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot);
extern
u8
acpiphp_get_adapter_status
(
struct
acpiphp_slot
*
slot
);
extern
u32
acpiphp_get_address
(
struct
acpiphp_slot
*
slot
);
/* acpiphp_pci.c */
extern
struct
pci_dev
*
acpiphp_allocate_pcidev
(
struct
pci_bus
*
pbus
,
int
dev
,
int
fn
);
extern
int
acpiphp_configure_slot
(
struct
acpiphp_slot
*
slot
);
extern
int
acpiphp_configure_function
(
struct
acpiphp_func
*
func
);
extern
void
acpiphp_unconfigure_function
(
struct
acpiphp_func
*
func
);
extern
int
acpiphp_detect_pci_resource
(
struct
acpiphp_bridge
*
bridge
);
extern
int
acpiphp_init_func_resource
(
struct
acpiphp_func
*
func
);
/* acpiphp_res.c */
extern
struct
pci_resource
*
acpiphp_get_io_resource
(
struct
pci_resource
**
head
,
u32
size
);
extern
struct
pci_resource
*
acpiphp_get_resource
(
struct
pci_resource
**
head
,
u32
size
);
extern
struct
pci_resource
*
acpiphp_get_resource_with_base
(
struct
pci_resource
**
head
,
u64
base
,
u32
size
);
extern
int
acpiphp_resource_sort_and_combine
(
struct
pci_resource
**
head
);
extern
struct
pci_resource
*
acpiphp_make_resource
(
u64
base
,
u32
length
);
extern
void
acpiphp_move_resource
(
struct
pci_resource
**
from
,
struct
pci_resource
**
to
);
extern
void
acpiphp_free_resource
(
struct
pci_resource
**
res
);
extern
void
acpiphp_dump_resource
(
struct
acpiphp_bridge
*
bridge
);
/* debug */
extern
void
acpiphp_dump_func_resource
(
struct
acpiphp_func
*
func
);
/* debug */
/* variables */
extern
int
acpiphp_debug
;
...
...
drivers/pci/hotplug/acpiphp_core.c
浏览文件 @
adb2705a
...
...
@@ -7,6 +7,8 @@
* Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
* Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
* Copyright (C) 2002,2003 NEC Corporation
* Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com)
* Copyright (C) 2003-2005 Hewlett Packard
*
* All rights reserved.
*
...
...
@@ -53,8 +55,8 @@ int acpiphp_debug;
static
int
num_slots
;
static
struct
acpiphp_attention_info
*
attention_info
;
#define DRIVER_VERSION "0.
4
"
#define DRIVER_AUTHOR "Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-kochi@bq.jp.nec.com>"
#define DRIVER_VERSION "0.
5
"
#define DRIVER_AUTHOR "Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-kochi@bq.jp.nec.com>
, Matthew Wilcox <willy@hp.com>
"
#define DRIVER_DESC "ACPI Hot Plug PCI Controller Driver"
MODULE_AUTHOR
(
DRIVER_AUTHOR
);
...
...
@@ -281,8 +283,7 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
/**
* get_address - get pci address of a slot
* @hotplug_slot: slot to get status
* @busdev: pointer to struct pci_busdev (seg, bus, dev)
*
* @value: pointer to struct pci_busdev (seg, bus, dev)
*/
static
int
get_address
(
struct
hotplug_slot
*
hotplug_slot
,
u32
*
value
)
{
...
...
drivers/pci/hotplug/acpiphp_glue.c
浏览文件 @
adb2705a
此差异已折叠。
点击以展开。
drivers/pci/hotplug/acpiphp_pci.c
已删除
100644 → 0
浏览文件 @
f340c0d1
/*
* ACPI PCI HotPlug PCI configuration space management
*
* Copyright (C) 1995,2001 Compaq Computer Corporation
* Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
* Copyright (C) 2001,2002 IBM Corp.
* Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
* Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
* Copyright (C) 2002 NEC Corporation
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Send feedback to <t-kochi@bq.jp.nec.com>
*
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/acpi.h>
#include "../pci.h"
#include "pci_hotplug.h"
#include "acpiphp.h"
#define MY_NAME "acpiphp_pci"
/* allocate mem/pmem/io resource to a new function */
static
int
init_config_space
(
struct
acpiphp_func
*
func
)
{
u32
bar
,
len
;
u32
address
[]
=
{
PCI_BASE_ADDRESS_0
,
PCI_BASE_ADDRESS_1
,
PCI_BASE_ADDRESS_2
,
PCI_BASE_ADDRESS_3
,
PCI_BASE_ADDRESS_4
,
PCI_BASE_ADDRESS_5
,
0
};
int
count
;
struct
acpiphp_bridge
*
bridge
;
struct
pci_resource
*
res
;
struct
pci_bus
*
pbus
;
int
bus
,
device
,
function
;
unsigned
int
devfn
;
u16
tmp
;
bridge
=
func
->
slot
->
bridge
;
pbus
=
bridge
->
pci_bus
;
bus
=
bridge
->
bus
;
device
=
func
->
slot
->
device
;
function
=
func
->
function
;
devfn
=
PCI_DEVFN
(
device
,
function
);
for
(
count
=
0
;
address
[
count
];
count
++
)
{
/* for 6 BARs */
pci_bus_write_config_dword
(
pbus
,
devfn
,
address
[
count
],
0xFFFFFFFF
);
pci_bus_read_config_dword
(
pbus
,
devfn
,
address
[
count
],
&
bar
);
if
(
!
bar
)
/* This BAR is not implemented */
continue
;
dbg
(
"Device %02x.%02x BAR %d wants %x
\n
"
,
device
,
function
,
count
,
bar
);
if
(
bar
&
PCI_BASE_ADDRESS_SPACE_IO
)
{
/* This is IO */
len
=
bar
&
(
PCI_BASE_ADDRESS_IO_MASK
&
0xFFFF
);
len
=
len
&
~
(
len
-
1
);
dbg
(
"len in IO %x, BAR %d
\n
"
,
len
,
count
);
spin_lock
(
&
bridge
->
res_lock
);
res
=
acpiphp_get_io_resource
(
&
bridge
->
io_head
,
len
);
spin_unlock
(
&
bridge
->
res_lock
);
if
(
!
res
)
{
err
(
"cannot allocate requested io for %02x:%02x.%d len %x
\n
"
,
bus
,
device
,
function
,
len
);
return
-
1
;
}
pci_bus_write_config_dword
(
pbus
,
devfn
,
address
[
count
],
(
u32
)
res
->
base
);
res
->
next
=
func
->
io_head
;
func
->
io_head
=
res
;
}
else
{
/* This is Memory */
if
(
bar
&
PCI_BASE_ADDRESS_MEM_PREFETCH
)
{
/* pfmem */
len
=
bar
&
0xFFFFFFF0
;
len
=
~
len
+
1
;
dbg
(
"len in PFMEM %x, BAR %d
\n
"
,
len
,
count
);
spin_lock
(
&
bridge
->
res_lock
);
res
=
acpiphp_get_resource
(
&
bridge
->
p_mem_head
,
len
);
spin_unlock
(
&
bridge
->
res_lock
);
if
(
!
res
)
{
err
(
"cannot allocate requested pfmem for %02x:%02x.%d len %x
\n
"
,
bus
,
device
,
function
,
len
);
return
-
1
;
}
pci_bus_write_config_dword
(
pbus
,
devfn
,
address
[
count
],
(
u32
)
res
->
base
);
if
(
bar
&
PCI_BASE_ADDRESS_MEM_TYPE_64
)
{
/* takes up another dword */
dbg
(
"inside the pfmem 64 case, count %d
\n
"
,
count
);
count
+=
1
;
pci_bus_write_config_dword
(
pbus
,
devfn
,
address
[
count
],
(
u32
)(
res
->
base
>>
32
));
}
res
->
next
=
func
->
p_mem_head
;
func
->
p_mem_head
=
res
;
}
else
{
/* regular memory */
len
=
bar
&
0xFFFFFFF0
;
len
=
~
len
+
1
;
dbg
(
"len in MEM %x, BAR %d
\n
"
,
len
,
count
);
spin_lock
(
&
bridge
->
res_lock
);
res
=
acpiphp_get_resource
(
&
bridge
->
mem_head
,
len
);
spin_unlock
(
&
bridge
->
res_lock
);
if
(
!
res
)
{
err
(
"cannot allocate requested pfmem for %02x:%02x.%d len %x
\n
"
,
bus
,
device
,
function
,
len
);
return
-
1
;
}
pci_bus_write_config_dword
(
pbus
,
devfn
,
address
[
count
],
(
u32
)
res
->
base
);
if
(
bar
&
PCI_BASE_ADDRESS_MEM_TYPE_64
)
{
/* takes up another dword */
dbg
(
"inside mem 64 case, reg. mem, count %d
\n
"
,
count
);
count
+=
1
;
pci_bus_write_config_dword
(
pbus
,
devfn
,
address
[
count
],
(
u32
)(
res
->
base
>>
32
));
}
res
->
next
=
func
->
mem_head
;
func
->
mem_head
=
res
;
}
}
}
/* disable expansion rom */
pci_bus_write_config_dword
(
pbus
,
devfn
,
PCI_ROM_ADDRESS
,
0x00000000
);
/* set PCI parameters from _HPP */
pci_bus_write_config_byte
(
pbus
,
devfn
,
PCI_CACHE_LINE_SIZE
,
bridge
->
hpp
.
cache_line_size
);
pci_bus_write_config_byte
(
pbus
,
devfn
,
PCI_LATENCY_TIMER
,
bridge
->
hpp
.
latency_timer
);
pci_bus_read_config_word
(
pbus
,
devfn
,
PCI_COMMAND
,
&
tmp
);
if
(
bridge
->
hpp
.
enable_SERR
)
tmp
|=
PCI_COMMAND_SERR
;
if
(
bridge
->
hpp
.
enable_PERR
)
tmp
|=
PCI_COMMAND_PARITY
;
pci_bus_write_config_word
(
pbus
,
devfn
,
PCI_COMMAND
,
tmp
);
return
0
;
}
/* detect_used_resource - subtract resource under dev from bridge */
static
int
detect_used_resource
(
struct
acpiphp_bridge
*
bridge
,
struct
pci_dev
*
dev
)
{
int
count
;
dbg
(
"Device %s
\n
"
,
pci_name
(
dev
));
for
(
count
=
0
;
count
<
DEVICE_COUNT_RESOURCE
;
count
++
)
{
struct
pci_resource
*
res
;
struct
pci_resource
**
head
;
unsigned
long
base
=
dev
->
resource
[
count
].
start
;
unsigned
long
len
=
dev
->
resource
[
count
].
end
-
base
+
1
;
unsigned
long
flags
=
dev
->
resource
[
count
].
flags
;
if
(
!
flags
)
continue
;
dbg
(
"BAR[%d] 0x%lx - 0x%lx (0x%lx)
\n
"
,
count
,
base
,
base
+
len
-
1
,
flags
);
if
(
flags
&
IORESOURCE_IO
)
{
head
=
&
bridge
->
io_head
;
}
else
if
(
flags
&
IORESOURCE_PREFETCH
)
{
head
=
&
bridge
->
p_mem_head
;
}
else
{
head
=
&
bridge
->
mem_head
;
}
spin_lock
(
&
bridge
->
res_lock
);
res
=
acpiphp_get_resource_with_base
(
head
,
base
,
len
);
spin_unlock
(
&
bridge
->
res_lock
);
if
(
res
)
kfree
(
res
);
}
return
0
;
}
/**
* acpiphp_detect_pci_resource - detect resources under bridge
* @bridge: detect all resources already used under this bridge
*
* collect all resources already allocated for all devices under a bridge.
*/
int
acpiphp_detect_pci_resource
(
struct
acpiphp_bridge
*
bridge
)
{
struct
list_head
*
l
;
struct
pci_dev
*
dev
;
list_for_each
(
l
,
&
bridge
->
pci_bus
->
devices
)
{
dev
=
pci_dev_b
(
l
);
detect_used_resource
(
bridge
,
dev
);
}
return
0
;
}
/**
* acpiphp_init_slot_resource - gather resource usage information of a slot
* @slot: ACPI slot object to be checked, should have valid pci_dev member
*
* TBD: PCI-to-PCI bridge case
* use pci_dev->resource[]
*/
int
acpiphp_init_func_resource
(
struct
acpiphp_func
*
func
)
{
u64
base
;
u32
bar
,
len
;
u32
address
[]
=
{
PCI_BASE_ADDRESS_0
,
PCI_BASE_ADDRESS_1
,
PCI_BASE_ADDRESS_2
,
PCI_BASE_ADDRESS_3
,
PCI_BASE_ADDRESS_4
,
PCI_BASE_ADDRESS_5
,
0
};
int
count
;
struct
pci_resource
*
res
;
struct
pci_dev
*
dev
;
dev
=
func
->
pci_dev
;
dbg
(
"Hot-pluggable device %s
\n
"
,
pci_name
(
dev
));
for
(
count
=
0
;
address
[
count
];
count
++
)
{
/* for 6 BARs */
pci_read_config_dword
(
dev
,
address
[
count
],
&
bar
);
if
(
!
bar
)
/* This BAR is not implemented */
continue
;
pci_write_config_dword
(
dev
,
address
[
count
],
0xFFFFFFFF
);
pci_read_config_dword
(
dev
,
address
[
count
],
&
len
);
if
(
len
&
PCI_BASE_ADDRESS_SPACE_IO
)
{
/* This is IO */
base
=
bar
&
0xFFFFFFFC
;
len
=
len
&
(
PCI_BASE_ADDRESS_IO_MASK
&
0xFFFF
);
len
=
len
&
~
(
len
-
1
);
dbg
(
"BAR[%d] %08x - %08x (IO)
\n
"
,
count
,
(
u32
)
base
,
(
u32
)
base
+
len
-
1
);
res
=
acpiphp_make_resource
(
base
,
len
);
if
(
!
res
)
goto
no_memory
;
res
->
next
=
func
->
io_head
;
func
->
io_head
=
res
;
}
else
{
/* This is Memory */
base
=
bar
&
0xFFFFFFF0
;
if
(
len
&
PCI_BASE_ADDRESS_MEM_PREFETCH
)
{
/* pfmem */
len
&=
0xFFFFFFF0
;
len
=
~
len
+
1
;
if
(
len
&
PCI_BASE_ADDRESS_MEM_TYPE_64
)
{
/* takes up another dword */
dbg
(
"prefetch mem 64
\n
"
);
count
+=
1
;
}
dbg
(
"BAR[%d] %08x - %08x (PMEM)
\n
"
,
count
,
(
u32
)
base
,
(
u32
)
base
+
len
-
1
);
res
=
acpiphp_make_resource
(
base
,
len
);
if
(
!
res
)
goto
no_memory
;
res
->
next
=
func
->
p_mem_head
;
func
->
p_mem_head
=
res
;
}
else
{
/* regular memory */
len
&=
0xFFFFFFF0
;
len
=
~
len
+
1
;
if
(
len
&
PCI_BASE_ADDRESS_MEM_TYPE_64
)
{
/* takes up another dword */
dbg
(
"mem 64
\n
"
);
count
+=
1
;
}
dbg
(
"BAR[%d] %08x - %08x (MEM)
\n
"
,
count
,
(
u32
)
base
,
(
u32
)
base
+
len
-
1
);
res
=
acpiphp_make_resource
(
base
,
len
);
if
(
!
res
)
goto
no_memory
;
res
->
next
=
func
->
mem_head
;
func
->
mem_head
=
res
;
}
}
pci_write_config_dword
(
dev
,
address
[
count
],
bar
);
}
#if 1
acpiphp_dump_func_resource
(
func
);
#endif
return
0
;
no_memory:
err
(
"out of memory
\n
"
);
acpiphp_free_resource
(
&
func
->
io_head
);
acpiphp_free_resource
(
&
func
->
mem_head
);
acpiphp_free_resource
(
&
func
->
p_mem_head
);
return
-
1
;
}
/**
* acpiphp_configure_slot - allocate PCI resources
* @slot: slot to be configured
*
* initializes a PCI functions on a device inserted
* into the slot
*
*/
int
acpiphp_configure_slot
(
struct
acpiphp_slot
*
slot
)
{
struct
acpiphp_func
*
func
;
struct
list_head
*
l
;
u8
hdr
;
u32
dvid
;
int
retval
=
0
;
int
is_multi
=
0
;
pci_bus_read_config_byte
(
slot
->
bridge
->
pci_bus
,
PCI_DEVFN
(
slot
->
device
,
0
),
PCI_HEADER_TYPE
,
&
hdr
);
if
(
hdr
&
0x80
)
is_multi
=
1
;
list_for_each
(
l
,
&
slot
->
funcs
)
{
func
=
list_entry
(
l
,
struct
acpiphp_func
,
sibling
);
if
(
is_multi
||
func
->
function
==
0
)
{
pci_bus_read_config_dword
(
slot
->
bridge
->
pci_bus
,
PCI_DEVFN
(
slot
->
device
,
func
->
function
),
PCI_VENDOR_ID
,
&
dvid
);
if
(
dvid
!=
0xffffffff
)
{
retval
=
init_config_space
(
func
);
if
(
retval
)
break
;
}
}
}
return
retval
;
}
/**
* acpiphp_configure_function - configure PCI function
* @func: function to be configured
*
* initializes a PCI functions on a device inserted
* into the slot
*
*/
int
acpiphp_configure_function
(
struct
acpiphp_func
*
func
)
{
/* all handled by the pci core now */
return
0
;
}
/**
* acpiphp_unconfigure_function - unconfigure PCI function
* @func: function to be unconfigured
*
*/
void
acpiphp_unconfigure_function
(
struct
acpiphp_func
*
func
)
{
struct
acpiphp_bridge
*
bridge
;
/* if pci_dev is NULL, ignore it */
if
(
!
func
->
pci_dev
)
return
;
pci_remove_bus_device
(
func
->
pci_dev
);
/* free all resources */
bridge
=
func
->
slot
->
bridge
;
spin_lock
(
&
bridge
->
res_lock
);
acpiphp_move_resource
(
&
func
->
io_head
,
&
bridge
->
io_head
);
acpiphp_move_resource
(
&
func
->
mem_head
,
&
bridge
->
mem_head
);
acpiphp_move_resource
(
&
func
->
p_mem_head
,
&
bridge
->
p_mem_head
);
acpiphp_move_resource
(
&
func
->
bus_head
,
&
bridge
->
bus_head
);
spin_unlock
(
&
bridge
->
res_lock
);
}
drivers/pci/hotplug/acpiphp_res.c
已删除
100644 → 0
浏览文件 @
f340c0d1
/*
* ACPI PCI HotPlug Utility functions
*
* Copyright (C) 1995,2001 Compaq Computer Corporation
* Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
* Copyright (C) 2001 IBM Corp.
* Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
* Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
* Copyright (C) 2002 NEC Corporation
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Send feedback to <gregkh@us.ibm.com>, <t-kochi@bq.jp.nec.com>
*
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/sysctl.h>
#include <linux/pci.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/timer.h>
#include <linux/ioctl.h>
#include <linux/fcntl.h>
#include <linux/list.h>
#include "pci_hotplug.h"
#include "acpiphp.h"
#define MY_NAME "acpiphp_res"
/*
* sort_by_size - sort nodes by their length, smallest first
*/
static
int
sort_by_size
(
struct
pci_resource
**
head
)
{
struct
pci_resource
*
current_res
;
struct
pci_resource
*
next_res
;
int
out_of_order
=
1
;
if
(
!
(
*
head
))
return
1
;
if
(
!
((
*
head
)
->
next
))
return
0
;
while
(
out_of_order
)
{
out_of_order
=
0
;
/* Special case for swapping list head */
if
(((
*
head
)
->
next
)
&&
((
*
head
)
->
length
>
(
*
head
)
->
next
->
length
))
{
out_of_order
++
;
current_res
=
*
head
;
*
head
=
(
*
head
)
->
next
;
current_res
->
next
=
(
*
head
)
->
next
;
(
*
head
)
->
next
=
current_res
;
}
current_res
=
*
head
;
while
(
current_res
->
next
&&
current_res
->
next
->
next
)
{
if
(
current_res
->
next
->
length
>
current_res
->
next
->
next
->
length
)
{
out_of_order
++
;
next_res
=
current_res
->
next
;
current_res
->
next
=
current_res
->
next
->
next
;
current_res
=
current_res
->
next
;
next_res
->
next
=
current_res
->
next
;
current_res
->
next
=
next_res
;
}
else
current_res
=
current_res
->
next
;
}
}
/* End of out_of_order loop */
return
0
;
}
#if 0
/*
* sort_by_max_size - sort nodes by their length, largest first
*/
static int sort_by_max_size(struct pci_resource **head)
{
struct pci_resource *current_res;
struct pci_resource *next_res;
int out_of_order = 1;
if (!(*head))
return 1;
if (!((*head)->next))
return 0;
while (out_of_order) {
out_of_order = 0;
/* Special case for swapping list head */
if (((*head)->next) &&
((*head)->length < (*head)->next->length)) {
out_of_order++;
current_res = *head;
*head = (*head)->next;
current_res->next = (*head)->next;
(*head)->next = current_res;
}
current_res = *head;
while (current_res->next && current_res->next->next) {
if (current_res->next->length < current_res->next->next->length) {
out_of_order++;
next_res = current_res->next;
current_res->next = current_res->next->next;
current_res = current_res->next;
next_res->next = current_res->next;
current_res->next = next_res;
} else
current_res = current_res->next;
}
} /* End of out_of_order loop */
return 0;
}
#endif
/**
* get_io_resource - get resource for I/O ports
*
* this function sorts the resource list by size and then
* returns the first node of "size" length that is not in the
* ISA aliasing window. If it finds a node larger than "size"
* it will split it up.
*
* size must be a power of two.
*
* difference from get_resource is handling of ISA aliasing space.
*
*/
struct
pci_resource
*
acpiphp_get_io_resource
(
struct
pci_resource
**
head
,
u32
size
)
{
struct
pci_resource
*
prevnode
;
struct
pci_resource
*
node
;
struct
pci_resource
*
split_node
;
u64
temp_qword
;
if
(
!
(
*
head
))
return
NULL
;
if
(
acpiphp_resource_sort_and_combine
(
head
))
return
NULL
;
if
(
sort_by_size
(
head
))
return
NULL
;
for
(
node
=
*
head
;
node
;
node
=
node
->
next
)
{
if
(
node
->
length
<
size
)
continue
;
if
(
node
->
base
&
(
size
-
1
))
{
/* this one isn't base aligned properly
so we'll make a new entry and split it up */
temp_qword
=
(
node
->
base
|
(
size
-
1
))
+
1
;
/* Short circuit if adjusted size is too small */
if
((
node
->
length
-
(
temp_qword
-
node
->
base
))
<
size
)
continue
;
split_node
=
acpiphp_make_resource
(
node
->
base
,
temp_qword
-
node
->
base
);
if
(
!
split_node
)
return
NULL
;
node
->
base
=
temp_qword
;
node
->
length
-=
split_node
->
length
;
/* Put it in the list */
split_node
->
next
=
node
->
next
;
node
->
next
=
split_node
;
}
/* End of non-aligned base */
/* Don't need to check if too small since we already did */
if
(
node
->
length
>
size
)
{
/* this one is longer than we need
so we'll make a new entry and split it up */
split_node
=
acpiphp_make_resource
(
node
->
base
+
size
,
node
->
length
-
size
);
if
(
!
split_node
)
return
NULL
;
node
->
length
=
size
;
/* Put it in the list */
split_node
->
next
=
node
->
next
;
node
->
next
=
split_node
;
}
/* End of too big on top end */
/* For IO make sure it's not in the ISA aliasing space */
if
((
node
->
base
&
0x300L
)
&&
!
(
node
->
base
&
0xfffff000
))
continue
;
/* If we got here, then it is the right size
Now take it out of the list */
if
(
*
head
==
node
)
{
*
head
=
node
->
next
;
}
else
{
prevnode
=
*
head
;
while
(
prevnode
->
next
!=
node
)
prevnode
=
prevnode
->
next
;
prevnode
->
next
=
node
->
next
;
}
node
->
next
=
NULL
;
/* Stop looping */
break
;
}
return
node
;
}
#if 0
/**
* get_max_resource - get the largest resource
*
* Gets the largest node that is at least "size" big from the
* list pointed to by head. It aligns the node on top and bottom
* to "size" alignment before returning it.
*/
static struct pci_resource *acpiphp_get_max_resource (struct pci_resource **head, u32 size)
{
struct pci_resource *max;
struct pci_resource *temp;
struct pci_resource *split_node;
u64 temp_qword;
if (!(*head))
return NULL;
if (acpiphp_resource_sort_and_combine(head))
return NULL;
if (sort_by_max_size(head))
return NULL;
for (max = *head;max; max = max->next) {
/* If not big enough we could probably just bail,
instead we'll continue to the next. */
if (max->length < size)
continue;
if (max->base & (size - 1)) {
/* this one isn't base aligned properly
so we'll make a new entry and split it up */
temp_qword = (max->base | (size-1)) + 1;
/* Short circuit if adjusted size is too small */
if ((max->length - (temp_qword - max->base)) < size)
continue;
split_node = acpiphp_make_resource(max->base, temp_qword - max->base);
if (!split_node)
return NULL;
max->base = temp_qword;
max->length -= split_node->length;
/* Put it next in the list */
split_node->next = max->next;
max->next = split_node;
}
if ((max->base + max->length) & (size - 1)) {
/* this one isn't end aligned properly at the top
so we'll make a new entry and split it up */
temp_qword = ((max->base + max->length) & ~(size - 1));
split_node = acpiphp_make_resource(temp_qword,
max->length + max->base - temp_qword);
if (!split_node)
return NULL;
max->length -= split_node->length;
/* Put it in the list */
split_node->next = max->next;
max->next = split_node;
}
/* Make sure it didn't shrink too much when we aligned it */
if (max->length < size)
continue;
/* Now take it out of the list */
temp = (struct pci_resource*) *head;
if (temp == max) {
*head = max->next;
} else {
while (temp && temp->next != max) {
temp = temp->next;
}
temp->next = max->next;
}
max->next = NULL;
return max;
}
/* If we get here, we couldn't find one */
return NULL;
}
#endif
/**
* get_resource - get resource (mem, pfmem)
*
* this function sorts the resource list by size and then
* returns the first node of "size" length. If it finds a node
* larger than "size" it will split it up.
*
* size must be a power of two.
*
*/
struct
pci_resource
*
acpiphp_get_resource
(
struct
pci_resource
**
head
,
u32
size
)
{
struct
pci_resource
*
prevnode
;
struct
pci_resource
*
node
;
struct
pci_resource
*
split_node
;
u64
temp_qword
;
if
(
!
(
*
head
))
return
NULL
;
if
(
acpiphp_resource_sort_and_combine
(
head
))
return
NULL
;
if
(
sort_by_size
(
head
))
return
NULL
;
for
(
node
=
*
head
;
node
;
node
=
node
->
next
)
{
dbg
(
"%s: req_size =%x node=%p, base=%x, length=%x
\n
"
,
__FUNCTION__
,
size
,
node
,
(
u32
)
node
->
base
,
node
->
length
);
if
(
node
->
length
<
size
)
continue
;
if
(
node
->
base
&
(
size
-
1
))
{
dbg
(
"%s: not aligned
\n
"
,
__FUNCTION__
);
/* this one isn't base aligned properly
so we'll make a new entry and split it up */
temp_qword
=
(
node
->
base
|
(
size
-
1
))
+
1
;
/* Short circuit if adjusted size is too small */
if
((
node
->
length
-
(
temp_qword
-
node
->
base
))
<
size
)
continue
;
split_node
=
acpiphp_make_resource
(
node
->
base
,
temp_qword
-
node
->
base
);
if
(
!
split_node
)
return
NULL
;
node
->
base
=
temp_qword
;
node
->
length
-=
split_node
->
length
;
/* Put it in the list */
split_node
->
next
=
node
->
next
;
node
->
next
=
split_node
;
}
/* End of non-aligned base */
/* Don't need to check if too small since we already did */
if
(
node
->
length
>
size
)
{
dbg
(
"%s: too big
\n
"
,
__FUNCTION__
);
/* this one is longer than we need
so we'll make a new entry and split it up */
split_node
=
acpiphp_make_resource
(
node
->
base
+
size
,
node
->
length
-
size
);
if
(
!
split_node
)
return
NULL
;
node
->
length
=
size
;
/* Put it in the list */
split_node
->
next
=
node
->
next
;
node
->
next
=
split_node
;
}
/* End of too big on top end */
dbg
(
"%s: got one!!!
\n
"
,
__FUNCTION__
);
/* If we got here, then it is the right size
Now take it out of the list */
if
(
*
head
==
node
)
{
*
head
=
node
->
next
;
}
else
{
prevnode
=
*
head
;
while
(
prevnode
->
next
!=
node
)
prevnode
=
prevnode
->
next
;
prevnode
->
next
=
node
->
next
;
}
node
->
next
=
NULL
;
/* Stop looping */
break
;
}
return
node
;
}
/**
* get_resource_with_base - get resource with specific base address
*
* this function
* returns the first node of "size" length located at specified base address.
* If it finds a node larger than "size" it will split it up.
*
* size must be a power of two.
*
*/
struct
pci_resource
*
acpiphp_get_resource_with_base
(
struct
pci_resource
**
head
,
u64
base
,
u32
size
)
{
struct
pci_resource
*
prevnode
;
struct
pci_resource
*
node
;
struct
pci_resource
*
split_node
;
u64
temp_qword
;
if
(
!
(
*
head
))
return
NULL
;
if
(
acpiphp_resource_sort_and_combine
(
head
))
return
NULL
;
for
(
node
=
*
head
;
node
;
node
=
node
->
next
)
{
dbg
(
": 1st req_base=%x req_size =%x node=%p, base=%x, length=%x
\n
"
,
(
u32
)
base
,
size
,
node
,
(
u32
)
node
->
base
,
node
->
length
);
if
(
node
->
base
>
base
)
continue
;
if
((
node
->
base
+
node
->
length
)
<
(
base
+
size
))
continue
;
if
(
node
->
base
<
base
)
{
dbg
(
": split 1
\n
"
);
/* this one isn't base aligned properly
so we'll make a new entry and split it up */
temp_qword
=
base
;
/* Short circuit if adjusted size is too small */
if
((
node
->
length
-
(
temp_qword
-
node
->
base
))
<
size
)
continue
;
split_node
=
acpiphp_make_resource
(
node
->
base
,
temp_qword
-
node
->
base
);
if
(
!
split_node
)
return
NULL
;
node
->
base
=
temp_qword
;
node
->
length
-=
split_node
->
length
;
/* Put it in the list */
split_node
->
next
=
node
->
next
;
node
->
next
=
split_node
;
}
dbg
(
": 2nd req_base=%x req_size =%x node=%p, base=%x, length=%x
\n
"
,
(
u32
)
base
,
size
,
node
,
(
u32
)
node
->
base
,
node
->
length
);
/* Don't need to check if too small since we already did */
if
(
node
->
length
>
size
)
{
dbg
(
": split 2
\n
"
);
/* this one is longer than we need
so we'll make a new entry and split it up */
split_node
=
acpiphp_make_resource
(
node
->
base
+
size
,
node
->
length
-
size
);
if
(
!
split_node
)
return
NULL
;
node
->
length
=
size
;
/* Put it in the list */
split_node
->
next
=
node
->
next
;
node
->
next
=
split_node
;
}
/* End of too big on top end */
dbg
(
": got one!!!
\n
"
);
/* If we got here, then it is the right size
Now take it out of the list */
if
(
*
head
==
node
)
{
*
head
=
node
->
next
;
}
else
{
prevnode
=
*
head
;
while
(
prevnode
->
next
!=
node
)
prevnode
=
prevnode
->
next
;
prevnode
->
next
=
node
->
next
;
}
node
->
next
=
NULL
;
/* Stop looping */
break
;
}
return
node
;
}
/**
* acpiphp_resource_sort_and_combine
*
* Sorts all of the nodes in the list in ascending order by
* their base addresses. Also does garbage collection by
* combining adjacent nodes.
*
* returns 0 if success
*/
int
acpiphp_resource_sort_and_combine
(
struct
pci_resource
**
head
)
{
struct
pci_resource
*
node1
;
struct
pci_resource
*
node2
;
int
out_of_order
=
1
;
if
(
!
(
*
head
))
return
1
;
dbg
(
"*head->next = %p
\n
"
,(
*
head
)
->
next
);
if
(
!
(
*
head
)
->
next
)
return
0
;
/* only one item on the list, already sorted! */
dbg
(
"*head->base = 0x%x
\n
"
,(
u32
)(
*
head
)
->
base
);
dbg
(
"*head->next->base = 0x%x
\n
"
,
(
u32
)(
*
head
)
->
next
->
base
);
while
(
out_of_order
)
{
out_of_order
=
0
;
/* Special case for swapping list head */
if
(((
*
head
)
->
next
)
&&
((
*
head
)
->
base
>
(
*
head
)
->
next
->
base
))
{
node1
=
*
head
;
(
*
head
)
=
(
*
head
)
->
next
;
node1
->
next
=
(
*
head
)
->
next
;
(
*
head
)
->
next
=
node1
;
out_of_order
++
;
}
node1
=
(
*
head
);
while
(
node1
->
next
&&
node1
->
next
->
next
)
{
if
(
node1
->
next
->
base
>
node1
->
next
->
next
->
base
)
{
out_of_order
++
;
node2
=
node1
->
next
;
node1
->
next
=
node1
->
next
->
next
;
node1
=
node1
->
next
;
node2
->
next
=
node1
->
next
;
node1
->
next
=
node2
;
}
else
node1
=
node1
->
next
;
}
}
/* End of out_of_order loop */
node1
=
*
head
;
while
(
node1
&&
node1
->
next
)
{
if
((
node1
->
base
+
node1
->
length
)
==
node1
->
next
->
base
)
{
/* Combine */
dbg
(
"8..
\n
"
);
node1
->
length
+=
node1
->
next
->
length
;
node2
=
node1
->
next
;
node1
->
next
=
node1
->
next
->
next
;
kfree
(
node2
);
}
else
node1
=
node1
->
next
;
}
return
0
;
}
/**
* acpiphp_make_resource - make resource structure
* @base: base address of a resource
* @length: length of a resource
*/
struct
pci_resource
*
acpiphp_make_resource
(
u64
base
,
u32
length
)
{
struct
pci_resource
*
res
;
res
=
kmalloc
(
sizeof
(
struct
pci_resource
),
GFP_KERNEL
);
if
(
res
)
{
memset
(
res
,
0
,
sizeof
(
struct
pci_resource
));
res
->
base
=
base
;
res
->
length
=
length
;
}
return
res
;
}
/**
* acpiphp_move_resource - move linked resources from one to another
* @from: head of linked resource list
* @to: head of linked resource list
*/
void
acpiphp_move_resource
(
struct
pci_resource
**
from
,
struct
pci_resource
**
to
)
{
struct
pci_resource
*
tmp
;
while
(
*
from
)
{
tmp
=
(
*
from
)
->
next
;
(
*
from
)
->
next
=
*
to
;
*
to
=
*
from
;
*
from
=
tmp
;
}
/* *from = NULL is guaranteed */
}
/**
* acpiphp_free_resource - free all linked resources
* @res: head of linked resource list
*/
void
acpiphp_free_resource
(
struct
pci_resource
**
res
)
{
struct
pci_resource
*
tmp
;
while
(
*
res
)
{
tmp
=
(
*
res
)
->
next
;
kfree
(
*
res
);
*
res
=
tmp
;
}
/* *res = NULL is guaranteed */
}
/* debug support functions; will go away sometime :) */
static
void
dump_resource
(
struct
pci_resource
*
head
)
{
struct
pci_resource
*
p
;
int
cnt
;
p
=
head
;
cnt
=
0
;
while
(
p
)
{
dbg
(
"[%02d] %08x - %08x
\n
"
,
cnt
++
,
(
u32
)
p
->
base
,
(
u32
)
p
->
base
+
p
->
length
-
1
);
p
=
p
->
next
;
}
}
void
acpiphp_dump_resource
(
struct
acpiphp_bridge
*
bridge
)
{
dbg
(
"I/O resource:
\n
"
);
dump_resource
(
bridge
->
io_head
);
dbg
(
"MEM resource:
\n
"
);
dump_resource
(
bridge
->
mem_head
);
dbg
(
"PMEM resource:
\n
"
);
dump_resource
(
bridge
->
p_mem_head
);
dbg
(
"BUS resource:
\n
"
);
dump_resource
(
bridge
->
bus_head
);
}
void
acpiphp_dump_func_resource
(
struct
acpiphp_func
*
func
)
{
dbg
(
"I/O resource:
\n
"
);
dump_resource
(
func
->
io_head
);
dbg
(
"MEM resource:
\n
"
);
dump_resource
(
func
->
mem_head
);
dbg
(
"PMEM resource:
\n
"
);
dump_resource
(
func
->
p_mem_head
);
dbg
(
"BUS resource:
\n
"
);
dump_resource
(
func
->
bus_head
);
}
drivers/pci/hotplug/cpqphp_core.c
浏览文件 @
adb2705a
...
...
@@ -60,6 +60,7 @@ static void __iomem *smbios_start;
static
void
__iomem
*
cpqhp_rom_start
;
static
int
power_mode
;
static
int
debug
;
static
int
initialized
;
#define DRIVER_VERSION "0.9.8"
#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>"
...
...
@@ -1271,7 +1272,6 @@ static int one_time_init(void)
{
int
loop
;
int
retval
=
0
;
static
int
initialized
=
0
;
if
(
initialized
)
return
0
;
...
...
@@ -1441,7 +1441,8 @@ static void __exit unload_cpqphpd(void)
}
// Stop the notification mechanism
cpqhp_event_stop_thread
();
if
(
initialized
)
cpqhp_event_stop_thread
();
//unmap the rom address
if
(
cpqhp_rom_start
)
...
...
drivers/pci/msi.c
浏览文件 @
adb2705a
...
...
@@ -28,10 +28,10 @@ static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
static
kmem_cache_t
*
msi_cachep
;
static
int
pci_msi_enable
=
1
;
static
int
last_alloc_vector
=
0
;
static
int
nr_released_vectors
=
0
;
static
int
last_alloc_vector
;
static
int
nr_released_vectors
;
static
int
nr_reserved_vectors
=
NR_HP_RESERVED_VECTORS
;
static
int
nr_msix_devices
=
0
;
static
int
nr_msix_devices
;
#ifndef CONFIG_X86_IO_APIC
int
vector_irq
[
NR_VECTORS
]
=
{
[
0
...
NR_VECTORS
-
1
]
=
-
1
};
...
...
@@ -170,44 +170,30 @@ static unsigned int startup_msi_irq_wo_maskbit(unsigned int vector)
return
0
;
/* never anything pending */
}
static
void
release_msi
(
unsigned
int
vector
);
static
void
shutdown_msi_irq
(
unsigned
int
vector
)
{
release_msi
(
vector
);
}
#define shutdown_msi_irq_wo_maskbit shutdown_msi_irq
static
void
enable_msi_irq_wo_maskbit
(
unsigned
int
vector
)
{}
static
void
disable_msi_irq_wo_maskbit
(
unsigned
int
vector
)
{}
static
void
ack_msi_irq_wo_maskbit
(
unsigned
int
vector
)
{}
static
void
end_msi_irq_wo_maskbit
(
unsigned
int
vector
)
static
unsigned
int
startup_msi_irq_w_maskbit
(
unsigned
int
vector
)
{
move_msi
(
vector
);
ack_APIC_irq
();
startup_msi_irq_wo_maskbit
(
vector
);
unmask_MSI_irq
(
vector
);
return
0
;
/* never anything pending */
}
static
unsigned
int
startup_msi_irq_w_maskbit
(
unsigned
int
vector
)
static
void
shutdown_msi_irq
(
unsigned
int
vector
)
{
struct
msi_desc
*
entry
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
msi_lock
,
flags
);
entry
=
msi_desc
[
vector
];
if
(
!
entry
||
!
entry
->
dev
)
{
spin_unlock_irqrestore
(
&
msi_lock
,
flags
);
return
0
;
}
entry
->
msi_attrib
.
state
=
1
;
/* Mark it active */
if
(
entry
&&
entry
->
dev
)
entry
->
msi_attrib
.
state
=
0
;
/* Mark it not active */
spin_unlock_irqrestore
(
&
msi_lock
,
flags
);
unmask_MSI_irq
(
vector
);
return
0
;
/* never anything pending */
}
#define shutdown_msi_irq_w_maskbit shutdown_msi_irq
#define enable_msi_irq_w_maskbit unmask_MSI_irq
#define disable_msi_irq_w_maskbit mask_MSI_irq
#define ack_msi_irq_w_maskbit mask_MSI_irq
static
void
end_msi_irq_wo_maskbit
(
unsigned
int
vector
)
{
move_msi
(
vector
);
ack_APIC_irq
();
}
static
void
end_msi_irq_w_maskbit
(
unsigned
int
vector
)
{
...
...
@@ -216,6 +202,10 @@ static void end_msi_irq_w_maskbit(unsigned int vector)
ack_APIC_irq
();
}
static
void
do_nothing
(
unsigned
int
vector
)
{
}
/*
* Interrupt Type for MSI-X PCI/PCI-X/PCI-Express Devices,
* which implement the MSI-X Capability Structure.
...
...
@@ -223,10 +213,10 @@ static void end_msi_irq_w_maskbit(unsigned int vector)
static
struct
hw_interrupt_type
msix_irq_type
=
{
.
typename
=
"PCI-MSI-X"
,
.
startup
=
startup_msi_irq_w_maskbit
,
.
shutdown
=
shutdown_msi_irq
_w_maskbit
,
.
enable
=
enable_msi_irq_w_maskbit
,
.
disable
=
disable_msi_irq_w_maskbit
,
.
ack
=
ack_msi_irq_w_maskbit
,
.
shutdown
=
shutdown_msi_irq
,
.
enable
=
unmask_MSI_irq
,
.
disable
=
mask_MSI_irq
,
.
ack
=
mask_MSI_irq
,
.
end
=
end_msi_irq_w_maskbit
,
.
set_affinity
=
set_msi_irq_affinity
};
...
...
@@ -239,10 +229,10 @@ static struct hw_interrupt_type msix_irq_type = {
static
struct
hw_interrupt_type
msi_irq_w_maskbit_type
=
{
.
typename
=
"PCI-MSI"
,
.
startup
=
startup_msi_irq_w_maskbit
,
.
shutdown
=
shutdown_msi_irq
_w_maskbit
,
.
enable
=
enable_msi_irq_w_maskbit
,
.
disable
=
disable_msi_irq_w_maskbit
,
.
ack
=
ack_msi_irq_w_maskbit
,
.
shutdown
=
shutdown_msi_irq
,
.
enable
=
unmask_MSI_irq
,
.
disable
=
mask_MSI_irq
,
.
ack
=
mask_MSI_irq
,
.
end
=
end_msi_irq_w_maskbit
,
.
set_affinity
=
set_msi_irq_affinity
};
...
...
@@ -255,10 +245,10 @@ static struct hw_interrupt_type msi_irq_w_maskbit_type = {
static
struct
hw_interrupt_type
msi_irq_wo_maskbit_type
=
{
.
typename
=
"PCI-MSI"
,
.
startup
=
startup_msi_irq_wo_maskbit
,
.
shutdown
=
shutdown_msi_irq
_wo_maskbit
,
.
enable
=
enable_msi_irq_wo_maskbit
,
.
disable
=
d
isable_msi_irq_wo_maskbit
,
.
ack
=
ack_msi_irq_wo_maskbit
,
.
shutdown
=
shutdown_msi_irq
,
.
enable
=
do_nothing
,
.
disable
=
d
o_nothing
,
.
ack
=
do_nothing
,
.
end
=
end_msi_irq_wo_maskbit
,
.
set_affinity
=
set_msi_irq_affinity
};
...
...
@@ -407,7 +397,7 @@ static struct msi_desc* alloc_msi_entry(void)
{
struct
msi_desc
*
entry
;
entry
=
(
struct
msi_desc
*
)
kmem_cache_alloc
(
msi_cachep
,
SLAB_KERNEL
);
entry
=
kmem_cache_alloc
(
msi_cachep
,
SLAB_KERNEL
);
if
(
!
entry
)
return
NULL
;
...
...
@@ -796,18 +786,6 @@ void pci_disable_msi(struct pci_dev* dev)
}
}
static
void
release_msi
(
unsigned
int
vector
)
{
struct
msi_desc
*
entry
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
msi_lock
,
flags
);
entry
=
msi_desc
[
vector
];
if
(
entry
&&
entry
->
dev
)
entry
->
msi_attrib
.
state
=
0
;
/* Mark it not active */
spin_unlock_irqrestore
(
&
msi_lock
,
flags
);
}
static
int
msi_free_vector
(
struct
pci_dev
*
dev
,
int
vector
,
int
reassign
)
{
struct
msi_desc
*
entry
;
...
...
@@ -924,7 +902,7 @@ static int reroute_msix_table(int head, struct msix_entry *entries, int *nvec)
/**
* pci_enable_msix - configure device's MSI-X capability structure
* @dev: pointer to the pci_dev data structure of MSI-X device function
* @
data
: pointer to an array of MSI-X entries
* @
entries
: pointer to an array of MSI-X entries
* @nvec: number of MSI-X vectors requested for allocation by device driver
*
* Setup the MSI-X capability structure of device function with the number
...
...
drivers/pci/msi.h
浏览文件 @
adb2705a
...
...
@@ -41,11 +41,11 @@ static inline void move_msi(int vector) {}
#define PCI_MSIX_FLAGS_BIRMASK (7 << 0)
#define PCI_MSIX_FLAGS_BITMASK (1 << 0)
#define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET 0
#define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET 4
#define PCI_MSIX_ENTRY_DATA_OFFSET 8
#define PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET 12
#define PCI_MSIX_ENTRY_SIZE 16
#define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET 0
#define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET 4
#define PCI_MSIX_ENTRY_DATA_OFFSET 8
#define PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET 12
#define msi_control_reg(base) (base + PCI_MSI_FLAGS)
#define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO)
...
...
@@ -64,7 +64,6 @@ static inline void move_msi(int vector) {}
#define msi_enable(control, num) multi_msi_enable(control, num); \
control |= PCI_MSI_FLAGS_ENABLE
#define msix_control_reg msi_control_reg
#define msix_table_offset_reg(base) (base + 0x04)
#define msix_pba_offset_reg(base) (base + 0x08)
#define msix_enable(control) control |= PCI_MSIX_FLAGS_ENABLE
...
...
drivers/pci/pci-sysfs.c
浏览文件 @
adb2705a
...
...
@@ -60,15 +60,18 @@ resource_show(struct device * dev, struct device_attribute *attr, char * buf)
char
*
str
=
buf
;
int
i
;
int
max
=
7
;
u64
start
,
end
;
if
(
pci_dev
->
subordinate
)
max
=
DEVICE_COUNT_RESOURCE
;
for
(
i
=
0
;
i
<
max
;
i
++
)
{
str
+=
sprintf
(
str
,
"0x%016lx 0x%016lx 0x%016lx
\n
"
,
pci_resource_start
(
pci_dev
,
i
),
pci_resource_end
(
pci_dev
,
i
),
pci_resource_flags
(
pci_dev
,
i
));
struct
resource
*
res
=
&
pci_dev
->
resource
[
i
];
pci_resource_to_user
(
pci_dev
,
i
,
res
,
&
start
,
&
end
);
str
+=
sprintf
(
str
,
"0x%016llx 0x%016llx 0x%016llx
\n
"
,
(
unsigned
long
long
)
start
,
(
unsigned
long
long
)
end
,
(
unsigned
long
long
)
res
->
flags
);
}
return
(
str
-
buf
);
}
...
...
@@ -313,8 +316,21 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
struct
device
,
kobj
));
struct
resource
*
res
=
(
struct
resource
*
)
attr
->
private
;
enum
pci_mmap_state
mmap_type
;
u64
start
,
end
;
int
i
;
vma
->
vm_pgoff
+=
res
->
start
>>
PAGE_SHIFT
;
for
(
i
=
0
;
i
<
PCI_ROM_RESOURCE
;
i
++
)
if
(
res
==
&
pdev
->
resource
[
i
])
break
;
if
(
i
>=
PCI_ROM_RESOURCE
)
return
-
ENODEV
;
/* pci_mmap_page_range() expects the same kind of entry as coming
* from /proc/bus/pci/ which is a "user visible" value. If this is
* different from the resource itself, arch will do necessary fixup.
*/
pci_resource_to_user
(
pdev
,
i
,
res
,
&
start
,
&
end
);
vma
->
vm_pgoff
+=
start
>>
PAGE_SHIFT
;
mmap_type
=
res
->
flags
&
IORESOURCE_MEM
?
pci_mmap_mem
:
pci_mmap_io
;
return
pci_mmap_page_range
(
pdev
,
vma
,
mmap_type
,
0
);
...
...
drivers/pci/probe.c
浏览文件 @
adb2705a
...
...
@@ -374,8 +374,11 @@ struct pci_bus * __devinit pci_add_new_bus(struct pci_bus *parent, struct pci_de
struct
pci_bus
*
child
;
child
=
pci_alloc_child_bus
(
parent
,
dev
,
busnr
);
if
(
child
)
if
(
child
)
{
spin_lock
(
&
pci_bus_lock
);
list_add_tail
(
&
child
->
node
,
&
parent
->
children
);
spin_unlock
(
&
pci_bus_lock
);
}
return
child
;
}
...
...
@@ -411,7 +414,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
{
struct
pci_bus
*
child
;
int
is_cardbus
=
(
dev
->
hdr_type
==
PCI_HEADER_TYPE_CARDBUS
);
u32
buses
;
u32
buses
,
i
;
u16
bctl
;
pci_read_config_dword
(
dev
,
PCI_PRIMARY_BUS
,
&
buses
);
...
...
@@ -447,7 +450,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
return
max
;
}
child
=
pci_a
lloc_child
_bus
(
bus
,
dev
,
busnr
);
child
=
pci_a
dd_new
_bus
(
bus
,
dev
,
busnr
);
if
(
!
child
)
return
max
;
child
->
primary
=
buses
&
0xFF
;
...
...
@@ -470,7 +473,11 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
/* Clear errors */
pci_write_config_word
(
dev
,
PCI_STATUS
,
0xffff
);
child
=
pci_alloc_child_bus
(
bus
,
dev
,
++
max
);
/* Prevent assigning a bus number that already exists.
* This can happen when a bridge is hot-plugged */
if
(
pci_find_bus
(
pci_domain_nr
(
bus
),
max
+
1
))
return
max
;
child
=
pci_add_new_bus
(
bus
,
dev
,
++
max
);
buses
=
(
buses
&
0xff000000
)
|
((
unsigned
int
)(
child
->
primary
)
<<
0
)
|
((
unsigned
int
)(
child
->
secondary
)
<<
8
)
...
...
@@ -501,7 +508,11 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
* as cards with a PCI-to-PCI bridge can be
* inserted later.
*/
max
+=
CARDBUS_RESERVE_BUSNR
;
for
(
i
=
0
;
i
<
CARDBUS_RESERVE_BUSNR
;
i
++
)
if
(
pci_find_bus
(
pci_domain_nr
(
bus
),
max
+
i
+
1
))
break
;
max
+=
i
;
}
/*
* Set the subordinate bus number to its real value.
...
...
@@ -757,7 +768,9 @@ pci_scan_single_device(struct pci_bus *bus, int devfn)
* and the bus list for fixup functions, etc.
*/
INIT_LIST_HEAD
(
&
dev
->
global_list
);
spin_lock
(
&
pci_bus_lock
);
list_add_tail
(
&
dev
->
bus_list
,
&
bus
->
devices
);
spin_unlock
(
&
pci_bus_lock
);
return
dev
;
}
...
...
@@ -878,7 +891,9 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus,
pr_debug
(
"PCI: Bus %04x:%02x already known
\n
"
,
pci_domain_nr
(
b
),
bus
);
goto
err_out
;
}
spin_lock
(
&
pci_bus_lock
);
list_add_tail
(
&
b
->
node
,
&
pci_root_buses
);
spin_unlock
(
&
pci_bus_lock
);
memset
(
dev
,
0
,
sizeof
(
*
dev
));
dev
->
parent
=
parent
;
...
...
@@ -911,8 +926,6 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus,
b
->
subordinate
=
pci_scan_child_bus
(
b
);
pci_bus_add_devices
(
b
);
return
b
;
sys_create_link_err:
...
...
@@ -922,7 +935,9 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus,
class_dev_reg_err:
device_unregister
(
dev
);
dev_reg_err:
spin_lock
(
&
pci_bus_lock
);
list_del
(
&
b
->
node
);
spin_unlock
(
&
pci_bus_lock
);
err_out:
kfree
(
dev
);
kfree
(
b
);
...
...
drivers/pci/proc.c
浏览文件 @
adb2705a
...
...
@@ -355,14 +355,20 @@ static int show_device(struct seq_file *m, void *v)
dev
->
device
,
dev
->
irq
);
/* Here should be 7 and not PCI_NUM_RESOURCES as we need to preserve compatibility */
for
(
i
=
0
;
i
<
7
;
i
++
)
for
(
i
=
0
;
i
<
7
;
i
++
)
{
u64
start
,
end
;
pci_resource_to_user
(
dev
,
i
,
&
dev
->
resource
[
i
],
&
start
,
&
end
);
seq_printf
(
m
,
LONG_FORMAT
,
dev
->
resource
[
i
].
start
|
((
unsigned
long
)
start
)
|
(
dev
->
resource
[
i
].
flags
&
PCI_REGION_FLAG_MASK
));
for
(
i
=
0
;
i
<
7
;
i
++
)
}
for
(
i
=
0
;
i
<
7
;
i
++
)
{
u64
start
,
end
;
pci_resource_to_user
(
dev
,
i
,
&
dev
->
resource
[
i
],
&
start
,
&
end
);
seq_printf
(
m
,
LONG_FORMAT
,
dev
->
resource
[
i
].
start
<
dev
->
resource
[
i
].
end
?
dev
->
resource
[
i
].
end
-
dev
->
resource
[
i
].
start
+
1
:
0
);
(
unsigned
long
)(
end
-
start
)
+
1
:
0
);
}
seq_putc
(
m
,
'\t'
);
if
(
drv
)
seq_printf
(
m
,
"%s"
,
drv
->
name
);
...
...
drivers/pci/remove.c
浏览文件 @
adb2705a
...
...
@@ -18,17 +18,21 @@ static void pci_free_resources(struct pci_dev *dev)
static
void
pci_destroy_dev
(
struct
pci_dev
*
dev
)
{
pci_proc_detach_device
(
dev
);
pci_remove_sysfs_dev_files
(
dev
);
device_unregister
(
&
dev
->
dev
);
if
(
!
list_empty
(
&
dev
->
global_list
))
{
pci_proc_detach_device
(
dev
);
pci_remove_sysfs_dev_files
(
dev
);
device_unregister
(
&
dev
->
dev
);
spin_lock
(
&
pci_bus_lock
);
list_del
(
&
dev
->
global_list
);
dev
->
global_list
.
next
=
dev
->
global_list
.
prev
=
NULL
;
spin_unlock
(
&
pci_bus_lock
);
}
/* Remove the device from the device lists, and prevent any further
* list accesses from this device */
spin_lock
(
&
pci_bus_lock
);
list_del
(
&
dev
->
bus_list
);
list_del
(
&
dev
->
global_list
);
dev
->
bus_list
.
next
=
dev
->
bus_list
.
prev
=
NULL
;
dev
->
global_list
.
next
=
dev
->
global_list
.
prev
=
NULL
;
spin_unlock
(
&
pci_bus_lock
);
pci_free_resources
(
dev
);
...
...
drivers/pci/setup-bus.c
浏览文件 @
adb2705a
...
...
@@ -72,7 +72,10 @@ pbus_assign_resources_sorted(struct pci_bus *bus)
for
(
list
=
head
.
next
;
list
;)
{
res
=
list
->
res
;
idx
=
res
-
&
list
->
dev
->
resource
[
0
];
pci_assign_resource
(
list
->
dev
,
idx
);
if
(
pci_assign_resource
(
list
->
dev
,
idx
))
{
res
->
start
=
0
;
res
->
flags
=
0
;
}
tmp
=
list
;
list
=
list
->
next
;
kfree
(
tmp
);
...
...
drivers/scsi/3w-9xxx.c
浏览文件 @
adb2705a
...
...
@@ -1916,9 +1916,9 @@ static void __twa_shutdown(TW_Device_Extension *tw_dev)
}
/* End __twa_shutdown() */
/* Wrapper for __twa_shutdown */
static
void
twa_shutdown
(
struct
device
*
dev
)
static
void
twa_shutdown
(
struct
pci_dev
*
p
dev
)
{
struct
Scsi_Host
*
host
=
pci_get_drvdata
(
to_pci_dev
(
dev
)
);
struct
Scsi_Host
*
host
=
pci_get_drvdata
(
pdev
);
TW_Device_Extension
*
tw_dev
=
(
TW_Device_Extension
*
)
host
->
hostdata
;
__twa_shutdown
(
tw_dev
);
...
...
@@ -2140,9 +2140,7 @@ static struct pci_driver twa_driver = {
.
id_table
=
twa_pci_tbl
,
.
probe
=
twa_probe
,
.
remove
=
twa_remove
,
.
driver
=
{
.
shutdown
=
twa_shutdown
}
.
shutdown
=
twa_shutdown
};
/* This function is called on driver initialization */
...
...
drivers/scsi/3w-xxxx.c
浏览文件 @
adb2705a
...
...
@@ -2264,9 +2264,9 @@ static void __tw_shutdown(TW_Device_Extension *tw_dev)
}
/* End __tw_shutdown() */
/* Wrapper for __tw_shutdown */
static
void
tw_shutdown
(
struct
device
*
dev
)
static
void
tw_shutdown
(
struct
pci_dev
*
p
dev
)
{
struct
Scsi_Host
*
host
=
pci_get_drvdata
(
to_pci_dev
(
dev
)
);
struct
Scsi_Host
*
host
=
pci_get_drvdata
(
pdev
);
TW_Device_Extension
*
tw_dev
=
(
TW_Device_Extension
*
)
host
->
hostdata
;
__tw_shutdown
(
tw_dev
);
...
...
@@ -2451,9 +2451,7 @@ static struct pci_driver tw_driver = {
.
id_table
=
tw_pci_tbl
,
.
probe
=
tw_probe
,
.
remove
=
tw_remove
,
.
driver
=
{
.
shutdown
=
tw_shutdown
}
.
shutdown
=
tw_shutdown
,
};
/* This function is called on driver initialization */
...
...
drivers/scsi/ipr.c
浏览文件 @
adb2705a
...
...
@@ -6012,7 +6012,7 @@ static int __devinit ipr_probe(struct pci_dev *pdev,
/**
* ipr_shutdown - Shutdown handler.
* @
dev:
device struct
* @
pdev: pci
device struct
*
* This function is invoked upon system shutdown/reboot. It will issue
* an adapter shutdown to the adapter to flush the write cache.
...
...
@@ -6020,9 +6020,9 @@ static int __devinit ipr_probe(struct pci_dev *pdev,
* Return value:
* none
**/
static
void
ipr_shutdown
(
struct
device
*
dev
)
static
void
ipr_shutdown
(
struct
pci_dev
*
p
dev
)
{
struct
ipr_ioa_cfg
*
ioa_cfg
=
pci_get_drvdata
(
to_pci_dev
(
dev
)
);
struct
ipr_ioa_cfg
*
ioa_cfg
=
pci_get_drvdata
(
pdev
);
unsigned
long
lock_flags
=
0
;
spin_lock_irqsave
(
ioa_cfg
->
host
->
host_lock
,
lock_flags
);
...
...
@@ -6068,9 +6068,7 @@ static struct pci_driver ipr_driver = {
.
id_table
=
ipr_pci_table
,
.
probe
=
ipr_probe
,
.
remove
=
ipr_remove
,
.
driver
=
{
.
shutdown
=
ipr_shutdown
,
},
.
shutdown
=
ipr_shutdown
,
};
/**
...
...
drivers/scsi/megaraid.c
浏览文件 @
adb2705a
...
...
@@ -5036,9 +5036,9 @@ megaraid_remove_one(struct pci_dev *pdev)
}
static
void
megaraid_shutdown
(
struct
device
*
dev
)
megaraid_shutdown
(
struct
pci_dev
*
p
dev
)
{
struct
Scsi_Host
*
host
=
pci_get_drvdata
(
to_pci_dev
(
dev
)
);
struct
Scsi_Host
*
host
=
pci_get_drvdata
(
pdev
);
adapter_t
*
adapter
=
(
adapter_t
*
)
host
->
hostdata
;
__megaraid_shutdown
(
adapter
);
...
...
@@ -5070,9 +5070,7 @@ static struct pci_driver megaraid_pci_driver = {
.
id_table
=
megaraid_pci_tbl
,
.
probe
=
megaraid_probe_one
,
.
remove
=
__devexit_p
(
megaraid_remove_one
),
.
driver
=
{
.
shutdown
=
megaraid_shutdown
,
},
.
shutdown
=
megaraid_shutdown
,
};
static
int
__init
megaraid_init
(
void
)
...
...
include/acpi/acpi_bus.h
浏览文件 @
adb2705a
...
...
@@ -108,6 +108,21 @@ typedef int (*acpi_op_unbind) (struct acpi_device *device);
typedef
int
(
*
acpi_op_match
)
(
struct
acpi_device
*
device
,
struct
acpi_driver
*
driver
);
struct
acpi_bus_ops
{
u32
acpi_op_add
:
1
;
u32
acpi_op_remove
:
1
;
u32
acpi_op_lock
:
1
;
u32
acpi_op_start
:
1
;
u32
acpi_op_stop
:
1
;
u32
acpi_op_suspend
:
1
;
u32
acpi_op_resume
:
1
;
u32
acpi_op_scan
:
1
;
u32
acpi_op_bind
:
1
;
u32
acpi_op_unbind
:
1
;
u32
acpi_op_match
:
1
;
u32
reserved
:
21
;
};
struct
acpi_device_ops
{
acpi_op_add
add
;
acpi_op_remove
remove
;
...
...
@@ -327,9 +342,9 @@ int acpi_bus_generate_event (struct acpi_device *device, u8 type, int data);
int
acpi_bus_receive_event
(
struct
acpi_bus_event
*
event
);
int
acpi_bus_register_driver
(
struct
acpi_driver
*
driver
);
int
acpi_bus_unregister_driver
(
struct
acpi_driver
*
driver
);
int
acpi_bus_scan
(
struct
acpi_device
*
start
);
int
acpi_bus_add
(
struct
acpi_device
**
child
,
struct
acpi_device
*
parent
,
acpi_handle
handle
,
int
type
);
int
acpi_bus_start
(
struct
acpi_device
*
device
);
int
acpi_match_ids
(
struct
acpi_device
*
device
,
char
*
ids
);
...
...
include/acpi/acpi_drivers.h
浏览文件 @
adb2705a
...
...
@@ -68,6 +68,7 @@ void acpi_pci_irq_del_prt (int segment, int bus);
struct
pci_bus
;
acpi_status
acpi_get_pci_id
(
acpi_handle
handle
,
struct
acpi_pci_id
*
id
);
int
acpi_pci_bind
(
struct
acpi_device
*
device
);
int
acpi_pci_unbind
(
struct
acpi_device
*
device
);
int
acpi_pci_bind_root
(
struct
acpi_device
*
device
,
struct
acpi_pci_id
*
id
,
struct
pci_bus
*
bus
);
...
...
include/asm-alpha/pci.h
浏览文件 @
adb2705a
...
...
@@ -223,6 +223,25 @@ pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr,
/* Nothing to do. */
}
#ifdef CONFIG_PCI
static
inline
void
pci_dma_burst_advice
(
struct
pci_dev
*
pdev
,
enum
pci_dma_burst_strategy
*
strat
,
unsigned
long
*
strategy_parameter
)
{
unsigned
long
cacheline_size
;
u8
byte
;
pci_read_config_byte
(
pdev
,
PCI_CACHE_LINE_SIZE
,
&
byte
);
if
(
byte
==
0
)
cacheline_size
=
1024
;
else
cacheline_size
=
(
int
)
byte
*
4
;
*
strat
=
PCI_DMA_BURST_BOUNDARY
;
*
strategy_parameter
=
cacheline_size
;
}
#endif
/* TODO: integrate with include/asm-generic/pci.h ? */
static
inline
int
pci_get_legacy_ide_irq
(
struct
pci_dev
*
dev
,
int
channel
)
{
...
...
include/asm-arm/pci.h
浏览文件 @
adb2705a
...
...
@@ -42,6 +42,16 @@ static inline void pcibios_penalize_isa_irq(int irq)
#define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME)
#define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL))
#ifdef CONFIG_PCI
static
inline
void
pci_dma_burst_advice
(
struct
pci_dev
*
pdev
,
enum
pci_dma_burst_strategy
*
strat
,
unsigned
long
*
strategy_parameter
)
{
*
strat
=
PCI_DMA_BURST_INFINITY
;
*
strategy_parameter
=
~
0UL
;
}
#endif
#define HAVE_PCI_MMAP
extern
int
pci_mmap_page_range
(
struct
pci_dev
*
dev
,
struct
vm_area_struct
*
vma
,
enum
pci_mmap_state
mmap_state
,
int
write_combine
);
...
...
include/asm-frv/pci.h
浏览文件 @
adb2705a
...
...
@@ -57,6 +57,16 @@ extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
*/
#define PCI_DMA_BUS_IS_PHYS (1)
#ifdef CONFIG_PCI
static
inline
void
pci_dma_burst_advice
(
struct
pci_dev
*
pdev
,
enum
pci_dma_burst_strategy
*
strat
,
unsigned
long
*
strategy_parameter
)
{
*
strat
=
PCI_DMA_BURST_INFINITY
;
*
strategy_parameter
=
~
0UL
;
}
#endif
/*
* These are pretty much arbitary with the CoMEM implementation.
* We have the whole address space to ourselves.
...
...
include/asm-i386/pci.h
浏览文件 @
adb2705a
...
...
@@ -99,6 +99,16 @@ static inline void pcibios_add_platform_entries(struct pci_dev *dev)
{
}
#ifdef CONFIG_PCI
static
inline
void
pci_dma_burst_advice
(
struct
pci_dev
*
pdev
,
enum
pci_dma_burst_strategy
*
strat
,
unsigned
long
*
strategy_parameter
)
{
*
strat
=
PCI_DMA_BURST_INFINITY
;
*
strategy_parameter
=
~
0UL
;
}
#endif
#endif
/* __KERNEL__ */
/* implement the pci_ DMA API in terms of the generic device dma_ one */
...
...
include/asm-ia64/iosapic.h
浏览文件 @
adb2705a
...
...
@@ -71,8 +71,11 @@ static inline void iosapic_eoi(char __iomem *iosapic, u32 vector)
}
extern
void
__init
iosapic_system_init
(
int
pcat_compat
);
extern
void
__
init
iosapic_init
(
unsigned
long
address
,
extern
int
__dev
init
iosapic_init
(
unsigned
long
address
,
unsigned
int
gsi_base
);
#ifdef CONFIG_HOTPLUG
extern
int
iosapic_remove
(
unsigned
int
gsi_base
);
#endif
/* CONFIG_HOTPLUG */
extern
int
gsi_to_vector
(
unsigned
int
gsi
);
extern
int
gsi_to_irq
(
unsigned
int
gsi
);
extern
void
iosapic_enable_intr
(
unsigned
int
vector
);
...
...
@@ -94,11 +97,14 @@ extern unsigned int iosapic_version (char __iomem *addr);
extern
void
iosapic_pci_fixup
(
int
);
#ifdef CONFIG_NUMA
extern
void
__init
map_iosapic_to_node
(
unsigned
int
,
int
);
extern
void
__
dev
init
map_iosapic_to_node
(
unsigned
int
,
int
);
#endif
#else
#define iosapic_system_init(pcat_compat) do { } while (0)
#define iosapic_init(address,gsi_base) do { } while (0)
#define iosapic_init(address,gsi_base) (-EINVAL)
#ifdef CONFIG_HOTPLUG
#define iosapic_remove(gsi_base) (-ENODEV)
#endif
/* CONFIG_HOTPLUG */
#define iosapic_register_intr(gsi,polarity,trigger) (gsi)
#define iosapic_unregister_intr(irq) do { } while (0)
#define iosapic_override_isa_irq(isa_irq,gsi,polarity,trigger) do { } while (0)
...
...
include/asm-ia64/pci.h
浏览文件 @
adb2705a
...
...
@@ -82,6 +82,25 @@ extern int pcibios_prep_mwi (struct pci_dev *);
#define sg_dma_len(sg) ((sg)->dma_length)
#define sg_dma_address(sg) ((sg)->dma_address)
#ifdef CONFIG_PCI
static
inline
void
pci_dma_burst_advice
(
struct
pci_dev
*
pdev
,
enum
pci_dma_burst_strategy
*
strat
,
unsigned
long
*
strategy_parameter
)
{
unsigned
long
cacheline_size
;
u8
byte
;
pci_read_config_byte
(
pdev
,
PCI_CACHE_LINE_SIZE
,
&
byte
);
if
(
byte
==
0
)
cacheline_size
=
1024
;
else
cacheline_size
=
(
int
)
byte
*
4
;
*
strat
=
PCI_DMA_BURST_MULTIPLE
;
*
strategy_parameter
=
cacheline_size
;
}
#endif
#define HAVE_PCI_MMAP
extern
int
pci_mmap_page_range
(
struct
pci_dev
*
dev
,
struct
vm_area_struct
*
vma
,
enum
pci_mmap_state
mmap_state
,
int
write_combine
);
...
...
include/asm-mips/pci.h
浏览文件 @
adb2705a
...
...
@@ -130,6 +130,16 @@ extern void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev,
extern
void
pci_dac_dma_sync_single_for_device
(
struct
pci_dev
*
pdev
,
dma64_addr_t
dma_addr
,
size_t
len
,
int
direction
);
#ifdef CONFIG_PCI
static
inline
void
pci_dma_burst_advice
(
struct
pci_dev
*
pdev
,
enum
pci_dma_burst_strategy
*
strat
,
unsigned
long
*
strategy_parameter
)
{
*
strat
=
PCI_DMA_BURST_INFINITY
;
*
strategy_parameter
=
~
0UL
;
}
#endif
extern
void
pcibios_resource_to_bus
(
struct
pci_dev
*
dev
,
struct
pci_bus_region
*
region
,
struct
resource
*
res
);
...
...
include/asm-parisc/pci.h
浏览文件 @
adb2705a
...
...
@@ -230,6 +230,25 @@ extern inline void pcibios_register_hba(struct pci_hba_data *x)
/* export the pci_ DMA API in terms of the dma_ one */
#include <asm-generic/pci-dma-compat.h>
#ifdef CONFIG_PCI
static
inline
void
pci_dma_burst_advice
(
struct
pci_dev
*
pdev
,
enum
pci_dma_burst_strategy
*
strat
,
unsigned
long
*
strategy_parameter
)
{
unsigned
long
cacheline_size
;
u8
byte
;
pci_read_config_byte
(
pdev
,
PCI_CACHE_LINE_SIZE
,
&
byte
);
if
(
byte
==
0
)
cacheline_size
=
1024
;
else
cacheline_size
=
(
int
)
byte
*
4
;
*
strat
=
PCI_DMA_BURST_MULTIPLE
;
*
strategy_parameter
=
cacheline_size
;
}
#endif
extern
void
pcibios_resource_to_bus
(
struct
pci_dev
*
dev
,
struct
pci_bus_region
*
region
,
struct
resource
*
res
);
...
...
include/asm-ppc/pci.h
浏览文件 @
adb2705a
...
...
@@ -69,6 +69,16 @@ extern unsigned long pci_bus_to_phys(unsigned int ba, int busnr);
#define pci_unmap_len(PTR, LEN_NAME) (0)
#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
#ifdef CONFIG_PCI
static
inline
void
pci_dma_burst_advice
(
struct
pci_dev
*
pdev
,
enum
pci_dma_burst_strategy
*
strat
,
unsigned
long
*
strategy_parameter
)
{
*
strat
=
PCI_DMA_BURST_INFINITY
;
*
strategy_parameter
=
~
0UL
;
}
#endif
/*
* At present there are very few 32-bit PPC machines that can have
* memory above the 4GB point, and we don't support that.
...
...
@@ -103,6 +113,12 @@ extern pgprot_t pci_phys_mem_access_prot(struct file *file,
unsigned
long
size
,
pgprot_t
prot
);
#define HAVE_ARCH_PCI_RESOURCE_TO_USER
extern
void
pci_resource_to_user
(
const
struct
pci_dev
*
dev
,
int
bar
,
const
struct
resource
*
rsrc
,
u64
*
start
,
u64
*
end
);
#endif
/* __KERNEL__ */
#endif
/* __PPC_PCI_H */
include/asm-ppc64/pci.h
浏览文件 @
adb2705a
...
...
@@ -78,6 +78,25 @@ static inline int pci_dac_dma_supported(struct pci_dev *hwdev,u64 mask)
return
0
;
}
#ifdef CONFIG_PCI
static
inline
void
pci_dma_burst_advice
(
struct
pci_dev
*
pdev
,
enum
pci_dma_burst_strategy
*
strat
,
unsigned
long
*
strategy_parameter
)
{
unsigned
long
cacheline_size
;
u8
byte
;
pci_read_config_byte
(
pdev
,
PCI_CACHE_LINE_SIZE
,
&
byte
);
if
(
byte
==
0
)
cacheline_size
=
1024
;
else
cacheline_size
=
(
int
)
byte
*
4
;
*
strat
=
PCI_DMA_BURST_MULTIPLE
;
*
strategy_parameter
=
cacheline_size
;
}
#endif
extern
int
pci_domain_nr
(
struct
pci_bus
*
bus
);
/* Decide whether to display the domain number in /proc */
...
...
@@ -136,6 +155,13 @@ extern pgprot_t pci_phys_mem_access_prot(struct file *file,
unsigned
long
size
,
pgprot_t
prot
);
#ifdef CONFIG_PPC_MULTIPLATFORM
#define HAVE_ARCH_PCI_RESOURCE_TO_USER
extern
void
pci_resource_to_user
(
const
struct
pci_dev
*
dev
,
int
bar
,
const
struct
resource
*
rsrc
,
u64
*
start
,
u64
*
end
);
#endif
/* CONFIG_PPC_MULTIPLATFORM */
#endif
/* __KERNEL__ */
...
...
include/asm-sh/pci.h
浏览文件 @
adb2705a
...
...
@@ -96,6 +96,16 @@ static inline void pcibios_penalize_isa_irq(int irq)
#define sg_dma_address(sg) (virt_to_bus((sg)->dma_address))
#define sg_dma_len(sg) ((sg)->length)
#ifdef CONFIG_PCI
static
inline
void
pci_dma_burst_advice
(
struct
pci_dev
*
pdev
,
enum
pci_dma_burst_strategy
*
strat
,
unsigned
long
*
strategy_parameter
)
{
*
strat
=
PCI_DMA_BURST_INFINITY
;
*
strategy_parameter
=
~
0UL
;
}
#endif
/* Board-specific fixup routines. */
extern
void
pcibios_fixup
(
void
);
extern
void
pcibios_fixup_irqs
(
void
);
...
...
include/asm-sh64/pci.h
浏览文件 @
adb2705a
...
...
@@ -86,6 +86,16 @@ static inline void pcibios_penalize_isa_irq(int irq)
#define sg_dma_address(sg) ((sg)->dma_address)
#define sg_dma_len(sg) ((sg)->length)
#ifdef CONFIG_PCI
static
inline
void
pci_dma_burst_advice
(
struct
pci_dev
*
pdev
,
enum
pci_dma_burst_strategy
*
strat
,
unsigned
long
*
strategy_parameter
)
{
*
strat
=
PCI_DMA_BURST_INFINITY
;
*
strategy_parameter
=
~
0UL
;
}
#endif
/* Board-specific fixup routines. */
extern
void
pcibios_fixup
(
void
);
extern
void
pcibios_fixup_irqs
(
void
);
...
...
include/asm-sparc/pci.h
浏览文件 @
adb2705a
...
...
@@ -144,6 +144,16 @@ extern inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
#define pci_dac_dma_supported(dev, mask) (0)
#ifdef CONFIG_PCI
static
inline
void
pci_dma_burst_advice
(
struct
pci_dev
*
pdev
,
enum
pci_dma_burst_strategy
*
strat
,
unsigned
long
*
strategy_parameter
)
{
*
strat
=
PCI_DMA_BURST_INFINITY
;
*
strategy_parameter
=
~
0UL
;
}
#endif
static
inline
void
pcibios_add_platform_entries
(
struct
pci_dev
*
dev
)
{
}
...
...
include/asm-sparc64/pci.h
浏览文件 @
adb2705a
...
...
@@ -220,6 +220,25 @@ static inline int pci_dma_mapping_error(dma_addr_t dma_addr)
return
(
dma_addr
==
PCI_DMA_ERROR_CODE
);
}
#ifdef CONFIG_PCI
static
inline
void
pci_dma_burst_advice
(
struct
pci_dev
*
pdev
,
enum
pci_dma_burst_strategy
*
strat
,
unsigned
long
*
strategy_parameter
)
{
unsigned
long
cacheline_size
;
u8
byte
;
pci_read_config_byte
(
pdev
,
PCI_CACHE_LINE_SIZE
,
&
byte
);
if
(
byte
==
0
)
cacheline_size
=
1024
;
else
cacheline_size
=
(
int
)
byte
*
4
;
*
strat
=
PCI_DMA_BURST_BOUNDARY
;
*
strategy_parameter
=
cacheline_size
;
}
#endif
/* Return the index of the PCI controller for device PDEV. */
extern
int
pci_domain_nr
(
struct
pci_bus
*
bus
);
...
...
include/asm-v850/pci.h
浏览文件 @
adb2705a
...
...
@@ -81,6 +81,16 @@ extern void
pci_free_consistent
(
struct
pci_dev
*
pdev
,
size_t
size
,
void
*
cpu_addr
,
dma_addr_t
dma_addr
);
#ifdef CONFIG_PCI
static
inline
void
pci_dma_burst_advice
(
struct
pci_dev
*
pdev
,
enum
pci_dma_burst_strategy
*
strat
,
unsigned
long
*
strategy_parameter
)
{
*
strat
=
PCI_DMA_BURST_INFINITY
;
*
strategy_parameter
=
~
0UL
;
}
#endif
static
inline
void
pcibios_add_platform_entries
(
struct
pci_dev
*
dev
)
{
}
...
...
include/asm-x86_64/pci.h
浏览文件 @
adb2705a
...
...
@@ -123,6 +123,16 @@ pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr,
flush_write_buffers
();
}
#ifdef CONFIG_PCI
static
inline
void
pci_dma_burst_advice
(
struct
pci_dev
*
pdev
,
enum
pci_dma_burst_strategy
*
strat
,
unsigned
long
*
strategy_parameter
)
{
*
strat
=
PCI_DMA_BURST_INFINITY
;
*
strategy_parameter
=
~
0UL
;
}
#endif
#define HAVE_PCI_MMAP
extern
int
pci_mmap_page_range
(
struct
pci_dev
*
dev
,
struct
vm_area_struct
*
vma
,
enum
pci_mmap_state
mmap_state
,
int
write_combine
);
...
...
include/linux/acpi.h
浏览文件 @
adb2705a
...
...
@@ -342,11 +342,19 @@ struct acpi_table_ecdt {
/* PCI MMCONFIG */
/* Defined in PCI Firmware Specification 3.0 */
struct
acpi_table_mcfg_config
{
u32
base_address
;
u32
base_reserved
;
u16
pci_segment_group_number
;
u8
start_bus_number
;
u8
end_bus_number
;
u8
reserved
[
4
];
}
__attribute__
((
packed
));
struct
acpi_table_mcfg
{
struct
acpi_table_header
header
;
u8
reserved
[
8
];
u32
base_address
;
u32
base_reserved
;
struct
acpi_table_mcfg_config
config
[
0
];
}
__attribute__
((
packed
));
/* Table Handlers */
...
...
@@ -391,6 +399,7 @@ int acpi_table_parse (enum acpi_table_id id, acpi_table_handler handler);
int
acpi_get_table_header_early
(
enum
acpi_table_id
id
,
struct
acpi_table_header
**
header
);
int
acpi_table_parse_madt
(
enum
acpi_madt_entry_id
id
,
acpi_madt_entry_handler
handler
,
unsigned
int
max_entries
);
int
acpi_table_parse_srat
(
enum
acpi_srat_entry_id
id
,
acpi_madt_entry_handler
handler
,
unsigned
int
max_entries
);
int
acpi_parse_mcfg
(
unsigned
long
phys_addr
,
unsigned
long
size
);
void
acpi_table_print
(
struct
acpi_table_header
*
header
,
unsigned
long
phys_addr
);
void
acpi_table_print_madt_entry
(
acpi_table_entry_header
*
madt
);
void
acpi_table_print_srat_entry
(
acpi_table_entry_header
*
srat
);
...
...
@@ -407,9 +416,13 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu);
int
acpi_unmap_lsapic
(
int
cpu
);
#endif
/* CONFIG_ACPI_HOTPLUG_CPU */
int
acpi_register_ioapic
(
acpi_handle
handle
,
u64
phys_addr
,
u32
gsi_base
);
int
acpi_unregister_ioapic
(
acpi_handle
handle
,
u32
gsi_base
);
extern
int
acpi_mp_config
;
extern
u32
pci_mmcfg_base_addr
;
extern
struct
acpi_table_mcfg_config
*
pci_mmcfg_config
;
extern
int
pci_mmcfg_config_num
;
extern
int
sbf_port
;
...
...
include/linux/pci.h
浏览文件 @
adb2705a
...
...
@@ -734,16 +734,20 @@ void pcibios_update_irq(struct pci_dev *, int irq);
/* Generic PCI functions used internally */
extern
struct
pci_bus
*
pci_find_bus
(
int
domain
,
int
busnr
);
void
pci_bus_add_devices
(
struct
pci_bus
*
bus
);
struct
pci_bus
*
pci_scan_bus_parented
(
struct
device
*
parent
,
int
bus
,
struct
pci_ops
*
ops
,
void
*
sysdata
);
static
inline
struct
pci_bus
*
pci_scan_bus
(
int
bus
,
struct
pci_ops
*
ops
,
void
*
sysdata
)
{
return
pci_scan_bus_parented
(
NULL
,
bus
,
ops
,
sysdata
);
struct
pci_bus
*
root_bus
;
root_bus
=
pci_scan_bus_parented
(
NULL
,
bus
,
ops
,
sysdata
);
if
(
root_bus
)
pci_bus_add_devices
(
root_bus
);
return
root_bus
;
}
int
pci_scan_slot
(
struct
pci_bus
*
bus
,
int
devfn
);
struct
pci_dev
*
pci_scan_single_device
(
struct
pci_bus
*
bus
,
int
devfn
);
unsigned
int
pci_scan_child_bus
(
struct
pci_bus
*
bus
);
void
pci_bus_add_device
(
struct
pci_dev
*
dev
);
void
pci_bus_add_devices
(
struct
pci_bus
*
bus
);
void
pci_name_device
(
struct
pci_dev
*
dev
);
char
*
pci_class_name
(
u32
class
);
void
pci_read_bridge_bases
(
struct
pci_bus
*
child
);
...
...
@@ -870,6 +874,15 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass
#define pci_pool_alloc(pool, flags, handle) dma_pool_alloc(pool, flags, handle)
#define pci_pool_free(pool, vaddr, addr) dma_pool_free(pool, vaddr, addr)
enum
pci_dma_burst_strategy
{
PCI_DMA_BURST_INFINITY
,
/* make bursts as large as possible,
strategy_parameter is N/A */
PCI_DMA_BURST_BOUNDARY
,
/* disconnect at every strategy_parameter
byte boundaries */
PCI_DMA_BURST_MULTIPLE
,
/* disconnect at some multiple of
strategy_parameter byte boundaries */
};
#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
extern
struct
pci_dev
*
isa_bridge
;
#endif
...
...
@@ -972,6 +985,8 @@ static inline int pci_proc_domain(struct pci_bus *bus)
}
#endif
#define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0)
#endif
/* !CONFIG_PCI */
/* these helpers provide future and backwards compatibility
...
...
@@ -1016,6 +1031,20 @@ static inline char *pci_name(struct pci_dev *pdev)
#define pci_pretty_name(dev) ""
#endif
/* Some archs don't want to expose struct resource to userland as-is
* in sysfs and /proc
*/
#ifndef HAVE_ARCH_PCI_RESOURCE_TO_USER
static
inline
void
pci_resource_to_user
(
const
struct
pci_dev
*
dev
,
int
bar
,
const
struct
resource
*
rsrc
,
u64
*
start
,
u64
*
end
)
{
*
start
=
rsrc
->
start
;
*
end
=
rsrc
->
end
;
}
#endif
/* HAVE_ARCH_PCI_RESOURCE_TO_USER */
/*
* The world is not perfect and supplies us with broken PCI devices.
* For at least a part of these bugs we need a work-around, so both
...
...
include/linux/pci_ids.h
浏览文件 @
adb2705a
...
...
@@ -62,6 +62,8 @@
#define PCI_BASE_CLASS_SYSTEM 0x08
#define PCI_CLASS_SYSTEM_PIC 0x0800
#define PCI_CLASS_SYSTEM_PIC_IOAPIC 0x080010
#define PCI_CLASS_SYSTEM_PIC_IOXAPIC 0x080020
#define PCI_CLASS_SYSTEM_DMA 0x0801
#define PCI_CLASS_SYSTEM_TIMER 0x0802
#define PCI_CLASS_SYSTEM_RTC 0x0803
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录