Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
29473ec2
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
29473ec2
编写于
4月 30, 2012
作者:
B
Bjorn Helgaas
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'topic/yinghai-hostbridge-cleanup' into next
上级
977f857c
c57ca65a
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
304 addition
and
267 deletion
+304
-267
arch/x86/pci/acpi.c
arch/x86/pci/acpi.c
+71
-45
arch/x86/pci/amd_bus.c
arch/x86/pci/amd_bus.c
+27
-49
arch/x86/pci/broadcom_bus.c
arch/x86/pci/broadcom_bus.c
+4
-8
arch/x86/pci/bus_numa.c
arch/x86/pci/bus_numa.c
+47
-22
arch/x86/pci/bus_numa.h
arch/x86/pci/bus_numa.h
+10
-8
arch/x86/pci/common.c
arch/x86/pci/common.c
+4
-23
drivers/pci/Makefile
drivers/pci/Makefile
+1
-1
drivers/pci/host-bridge.c
drivers/pci/host-bridge.c
+96
-0
drivers/pci/probe.c
drivers/pci/probe.c
+36
-110
include/linux/pci.h
include/linux/pci.h
+8
-1
未找到文件。
arch/x86/pci/acpi.c
浏览文件 @
29473ec2
...
@@ -9,11 +9,11 @@
...
@@ -9,11 +9,11 @@
struct
pci_root_info
{
struct
pci_root_info
{
struct
acpi_device
*
bridge
;
struct
acpi_device
*
bridge
;
char
*
name
;
char
name
[
16
]
;
unsigned
int
res_num
;
unsigned
int
res_num
;
struct
resource
*
res
;
struct
resource
*
res
;
struct
list_head
*
resources
;
int
busnum
;
int
busnum
;
struct
pci_sysdata
sd
;
};
};
static
bool
pci_use_crs
=
true
;
static
bool
pci_use_crs
=
true
;
...
@@ -287,7 +287,8 @@ static void coalesce_windows(struct pci_root_info *info, unsigned long type)
...
@@ -287,7 +287,8 @@ static void coalesce_windows(struct pci_root_info *info, unsigned long type)
}
}
}
}
static
void
add_resources
(
struct
pci_root_info
*
info
)
static
void
add_resources
(
struct
pci_root_info
*
info
,
struct
list_head
*
resources
)
{
{
int
i
;
int
i
;
struct
resource
*
res
,
*
root
,
*
conflict
;
struct
resource
*
res
,
*
root
,
*
conflict
;
...
@@ -311,53 +312,74 @@ static void add_resources(struct pci_root_info *info)
...
@@ -311,53 +312,74 @@ static void add_resources(struct pci_root_info *info)
"ignoring host bridge window %pR (conflicts with %s %pR)
\n
"
,
"ignoring host bridge window %pR (conflicts with %s %pR)
\n
"
,
res
,
conflict
->
name
,
conflict
);
res
,
conflict
->
name
,
conflict
);
else
else
pci_add_resource
(
info
->
resources
,
res
);
pci_add_resource
(
resources
,
res
);
}
}
}
}
static
void
free_pci_root_info_res
(
struct
pci_root_info
*
info
)
{
kfree
(
info
->
res
);
info
->
res
=
NULL
;
info
->
res_num
=
0
;
}
static
void
__release_pci_root_info
(
struct
pci_root_info
*
info
)
{
int
i
;
struct
resource
*
res
;
for
(
i
=
0
;
i
<
info
->
res_num
;
i
++
)
{
res
=
&
info
->
res
[
i
];
if
(
!
res
->
parent
)
continue
;
if
(
!
(
res
->
flags
&
(
IORESOURCE_MEM
|
IORESOURCE_IO
)))
continue
;
release_resource
(
res
);
}
free_pci_root_info_res
(
info
);
kfree
(
info
);
}
static
void
release_pci_root_info
(
struct
pci_host_bridge
*
bridge
)
{
struct
pci_root_info
*
info
=
bridge
->
release_data
;
__release_pci_root_info
(
info
);
}
static
void
static
void
get_current_resources
(
struct
acpi_device
*
device
,
int
busnum
,
probe_pci_root_info
(
struct
pci_root_info
*
info
,
struct
acpi_device
*
device
,
int
domain
,
struct
list_head
*
resources
)
int
busnum
,
int
domain
)
{
{
struct
pci_root_info
info
;
size_t
size
;
size_t
size
;
info
.
bridge
=
device
;
info
->
bridge
=
device
;
info
.
res_num
=
0
;
info
->
res_num
=
0
;
info
.
resources
=
resources
;
acpi_walk_resources
(
device
->
handle
,
METHOD_NAME__CRS
,
count_resource
,
acpi_walk_resources
(
device
->
handle
,
METHOD_NAME__CRS
,
count_resource
,
&
info
);
info
);
if
(
!
info
.
res_num
)
if
(
!
info
->
res_num
)
return
;
return
;
size
=
sizeof
(
*
info
.
res
)
*
info
.
res_num
;
size
=
sizeof
(
*
info
->
res
)
*
info
->
res_num
;
info
.
res
=
kmalloc
(
size
,
GFP_KERNEL
);
info
->
res_num
=
0
;
if
(
!
info
.
res
)
info
->
res
=
kmalloc
(
size
,
GFP_KERNEL
);
if
(
!
info
->
res
)
return
;
return
;
info
.
name
=
kasprintf
(
GFP_KERNEL
,
"PCI Bus %04x:%02x"
,
domain
,
busnum
);
sprintf
(
info
->
name
,
"PCI Bus %04x:%02x"
,
domain
,
busnum
);
if
(
!
info
.
name
)
goto
name_alloc_fail
;
info
.
res_num
=
0
;
acpi_walk_resources
(
device
->
handle
,
METHOD_NAME__CRS
,
setup_resource
,
acpi_walk_resources
(
device
->
handle
,
METHOD_NAME__CRS
,
setup_resource
,
&
info
);
info
);
if
(
pci_use_crs
)
{
add_resources
(
&
info
);
return
;
}
kfree
(
info
.
name
);
name_alloc_fail:
kfree
(
info
.
res
);
}
}
struct
pci_bus
*
__devinit
pci_acpi_scan_root
(
struct
acpi_pci_root
*
root
)
struct
pci_bus
*
__devinit
pci_acpi_scan_root
(
struct
acpi_pci_root
*
root
)
{
{
struct
acpi_device
*
device
=
root
->
device
;
struct
acpi_device
*
device
=
root
->
device
;
struct
pci_root_info
*
info
=
NULL
;
int
domain
=
root
->
segment
;
int
domain
=
root
->
segment
;
int
busnum
=
root
->
secondary
.
start
;
int
busnum
=
root
->
secondary
.
start
;
LIST_HEAD
(
resources
);
LIST_HEAD
(
resources
);
...
@@ -389,17 +411,14 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
...
@@ -389,17 +411,14 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
if
(
node
!=
-
1
&&
!
node_online
(
node
))
if
(
node
!=
-
1
&&
!
node_online
(
node
))
node
=
-
1
;
node
=
-
1
;
/* Allocate per-root-bus (not per bus) arch-specific data.
info
=
kzalloc
(
sizeof
(
*
info
),
GFP_KERNEL
);
* TODO: leak; this memory is never freed.
if
(
!
info
)
{
* It's arguable whether it's worth the trouble to care.
*/
sd
=
kzalloc
(
sizeof
(
*
sd
),
GFP_KERNEL
);
if
(
!
sd
)
{
printk
(
KERN_WARNING
"pci_bus %04x:%02x: "
printk
(
KERN_WARNING
"pci_bus %04x:%02x: "
"ignored (out of memory)
\n
"
,
domain
,
busnum
);
"ignored (out of memory)
\n
"
,
domain
,
busnum
);
return
NULL
;
return
NULL
;
}
}
sd
=
&
info
->
sd
;
sd
->
domain
=
domain
;
sd
->
domain
=
domain
;
sd
->
node
=
node
;
sd
->
node
=
node
;
/*
/*
...
@@ -413,22 +432,32 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
...
@@ -413,22 +432,32 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
* be replaced by sd.
* be replaced by sd.
*/
*/
memcpy
(
bus
->
sysdata
,
sd
,
sizeof
(
*
sd
));
memcpy
(
bus
->
sysdata
,
sd
,
sizeof
(
*
sd
));
kfree
(
sd
);
kfree
(
info
);
}
else
{
}
else
{
get_current_resources
(
device
,
busnum
,
domain
,
&
resources
);
probe_pci_root_info
(
info
,
device
,
busnum
,
domain
);
/*
/*
* _CRS with no apertures is normal, so only fall back to
* _CRS with no apertures is normal, so only fall back to
* defaults or native bridge info if we're ignoring _CRS.
* defaults or native bridge info if we're ignoring _CRS.
*/
*/
if
(
!
pci_use_crs
)
if
(
pci_use_crs
)
add_resources
(
info
,
&
resources
);
else
{
free_pci_root_info_res
(
info
);
x86_pci_root_bus_resources
(
busnum
,
&
resources
);
x86_pci_root_bus_resources
(
busnum
,
&
resources
);
}
bus
=
pci_create_root_bus
(
NULL
,
busnum
,
&
pci_root_ops
,
sd
,
bus
=
pci_create_root_bus
(
NULL
,
busnum
,
&
pci_root_ops
,
sd
,
&
resources
);
&
resources
);
if
(
bus
)
if
(
bus
)
{
bus
->
subordinate
=
pci_scan_child_bus
(
bus
);
bus
->
subordinate
=
pci_scan_child_bus
(
bus
);
else
pci_set_host_bridge_release
(
to_pci_host_bridge
(
bus
->
bridge
),
release_pci_root_info
,
info
);
}
else
{
pci_free_resource_list
(
&
resources
);
pci_free_resource_list
(
&
resources
);
__release_pci_root_info
(
info
);
}
}
}
/* After the PCI-E bus has been walked and all devices discovered,
/* After the PCI-E bus has been walked and all devices discovered,
...
@@ -445,9 +474,6 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
...
@@ -445,9 +474,6 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
}
}
}
}
if
(
!
bus
)
kfree
(
sd
);
if
(
bus
&&
node
!=
-
1
)
{
if
(
bus
&&
node
!=
-
1
)
{
#ifdef CONFIG_ACPI_NUMA
#ifdef CONFIG_ACPI_NUMA
if
(
pxm
>=
0
)
if
(
pxm
>=
0
)
...
...
arch/x86/pci/amd_bus.c
浏览文件 @
29473ec2
...
@@ -32,6 +32,18 @@ static struct pci_hostbridge_probe pci_probes[] __initdata = {
...
@@ -32,6 +32,18 @@ static struct pci_hostbridge_probe pci_probes[] __initdata = {
#define RANGE_NUM 16
#define RANGE_NUM 16
static
struct
pci_root_info
__init
*
find_pci_root_info
(
int
node
,
int
link
)
{
struct
pci_root_info
*
info
;
/* find the position */
list_for_each_entry
(
info
,
&
pci_root_infos
,
list
)
if
(
info
->
node
==
node
&&
info
->
link
==
link
)
return
info
;
return
NULL
;
}
/**
/**
* early_fill_mp_bus_to_node()
* early_fill_mp_bus_to_node()
* called before pcibios_scan_root and pci_scan_bus
* called before pcibios_scan_root and pci_scan_bus
...
@@ -50,7 +62,6 @@ static int __init early_fill_mp_bus_info(void)
...
@@ -50,7 +62,6 @@ static int __init early_fill_mp_bus_info(void)
int
def_link
;
int
def_link
;
struct
pci_root_info
*
info
;
struct
pci_root_info
*
info
;
u32
reg
;
u32
reg
;
struct
resource
*
res
;
u64
start
;
u64
start
;
u64
end
;
u64
end
;
struct
range
range
[
RANGE_NUM
];
struct
range
range
[
RANGE_NUM
];
...
@@ -86,7 +97,6 @@ static int __init early_fill_mp_bus_info(void)
...
@@ -86,7 +97,6 @@ static int __init early_fill_mp_bus_info(void)
if
(
!
found
)
if
(
!
found
)
return
0
;
return
0
;
pci_root_num
=
0
;
for
(
i
=
0
;
i
<
4
;
i
++
)
{
for
(
i
=
0
;
i
<
4
;
i
++
)
{
int
min_bus
;
int
min_bus
;
int
max_bus
;
int
max_bus
;
...
@@ -105,13 +115,8 @@ static int __init early_fill_mp_bus_info(void)
...
@@ -105,13 +115,8 @@ static int __init early_fill_mp_bus_info(void)
#endif
#endif
link
=
(
reg
>>
8
)
&
0x03
;
link
=
(
reg
>>
8
)
&
0x03
;
info
=
&
pci_root_info
[
pci_root_num
];
info
=
alloc_pci_root_info
(
min_bus
,
max_bus
,
node
,
link
);
info
->
bus_min
=
min_bus
;
info
->
bus_max
=
max_bus
;
info
->
node
=
node
;
info
->
link
=
link
;
sprintf
(
info
->
name
,
"PCI Bus #%02x"
,
min_bus
);
sprintf
(
info
->
name
,
"PCI Bus #%02x"
,
min_bus
);
pci_root_num
++
;
}
}
/* get the default node and link for left over res */
/* get the default node and link for left over res */
...
@@ -134,16 +139,10 @@ static int __init early_fill_mp_bus_info(void)
...
@@ -134,16 +139,10 @@ static int __init early_fill_mp_bus_info(void)
link
=
(
reg
>>
4
)
&
0x03
;
link
=
(
reg
>>
4
)
&
0x03
;
end
=
(
reg
&
0xfff000
)
|
0xfff
;
end
=
(
reg
&
0xfff000
)
|
0xfff
;
/* find the position */
info
=
find_pci_root_info
(
node
,
link
);
for
(
j
=
0
;
j
<
pci_root_num
;
j
++
)
{
if
(
!
info
)
info
=
&
pci_root_info
[
j
];
if
(
info
->
node
==
node
&&
info
->
link
==
link
)
break
;
}
if
(
j
==
pci_root_num
)
continue
;
/* not found */
continue
;
/* not found */
info
=
&
pci_root_info
[
j
];
printk
(
KERN_DEBUG
"node %d link %d: io port [%llx, %llx]
\n
"
,
printk
(
KERN_DEBUG
"node %d link %d: io port [%llx, %llx]
\n
"
,
node
,
link
,
start
,
end
);
node
,
link
,
start
,
end
);
...
@@ -155,13 +154,8 @@ static int __init early_fill_mp_bus_info(void)
...
@@ -155,13 +154,8 @@ static int __init early_fill_mp_bus_info(void)
}
}
/* add left over io port range to def node/link, [0, 0xffff] */
/* add left over io port range to def node/link, [0, 0xffff] */
/* find the position */
/* find the position */
for
(
j
=
0
;
j
<
pci_root_num
;
j
++
)
{
info
=
find_pci_root_info
(
def_node
,
def_link
);
info
=
&
pci_root_info
[
j
];
if
(
info
)
{
if
(
info
->
node
==
def_node
&&
info
->
link
==
def_link
)
break
;
}
if
(
j
<
pci_root_num
)
{
info
=
&
pci_root_info
[
j
];
for
(
i
=
0
;
i
<
RANGE_NUM
;
i
++
)
{
for
(
i
=
0
;
i
<
RANGE_NUM
;
i
++
)
{
if
(
!
range
[
i
].
end
)
if
(
!
range
[
i
].
end
)
continue
;
continue
;
...
@@ -214,16 +208,10 @@ static int __init early_fill_mp_bus_info(void)
...
@@ -214,16 +208,10 @@ static int __init early_fill_mp_bus_info(void)
end
<<=
8
;
end
<<=
8
;
end
|=
0xffff
;
end
|=
0xffff
;
/* find the position */
info
=
find_pci_root_info
(
node
,
link
);
for
(
j
=
0
;
j
<
pci_root_num
;
j
++
)
{
info
=
&
pci_root_info
[
j
];
if
(
info
->
node
==
node
&&
info
->
link
==
link
)
break
;
}
if
(
j
==
pci_root_num
)
continue
;
/* not found */
info
=
&
pci_root_info
[
j
];
if
(
!
info
)
continue
;
printk
(
KERN_DEBUG
"node %d link %d: mmio [%llx, %llx]"
,
printk
(
KERN_DEBUG
"node %d link %d: mmio [%llx, %llx]"
,
node
,
link
,
start
,
end
);
node
,
link
,
start
,
end
);
...
@@ -291,14 +279,8 @@ static int __init early_fill_mp_bus_info(void)
...
@@ -291,14 +279,8 @@ static int __init early_fill_mp_bus_info(void)
* add left over mmio range to def node/link ?
* add left over mmio range to def node/link ?
* that is tricky, just record range in from start_min to 4G
* that is tricky, just record range in from start_min to 4G
*/
*/
for
(
j
=
0
;
j
<
pci_root_num
;
j
++
)
{
info
=
find_pci_root_info
(
def_node
,
def_link
);
info
=
&
pci_root_info
[
j
];
if
(
info
)
{
if
(
info
->
node
==
def_node
&&
info
->
link
==
def_link
)
break
;
}
if
(
j
<
pci_root_num
)
{
info
=
&
pci_root_info
[
j
];
for
(
i
=
0
;
i
<
RANGE_NUM
;
i
++
)
{
for
(
i
=
0
;
i
<
RANGE_NUM
;
i
++
)
{
if
(
!
range
[
i
].
end
)
if
(
!
range
[
i
].
end
)
continue
;
continue
;
...
@@ -309,20 +291,16 @@ static int __init early_fill_mp_bus_info(void)
...
@@ -309,20 +291,16 @@ static int __init early_fill_mp_bus_info(void)
}
}
}
}
for
(
i
=
0
;
i
<
pci_root_num
;
i
++
)
{
list_for_each_entry
(
info
,
&
pci_root_infos
,
list
)
{
int
res_num
;
int
busnum
;
int
busnum
;
struct
pci_root_res
*
root_res
;
info
=
&
pci_root_info
[
i
];
res_num
=
info
->
res_num
;
busnum
=
info
->
bus_min
;
busnum
=
info
->
bus_min
;
printk
(
KERN_DEBUG
"bus: [%02x, %02x] on node %x link %x
\n
"
,
printk
(
KERN_DEBUG
"bus: [%02x, %02x] on node %x link %x
\n
"
,
info
->
bus_min
,
info
->
bus_max
,
info
->
node
,
info
->
link
);
info
->
bus_min
,
info
->
bus_max
,
info
->
node
,
info
->
link
);
for
(
j
=
0
;
j
<
res_num
;
j
++
)
{
list_for_each_entry
(
root_res
,
&
info
->
resources
,
list
)
res
=
&
info
->
res
[
j
];
printk
(
KERN_DEBUG
"bus: %02x %pR
\n
"
,
printk
(
KERN_DEBUG
"bus: %02x index %x %pR
\n
"
,
busnum
,
&
root_res
->
res
);
busnum
,
j
,
res
);
}
}
}
return
0
;
return
0
;
...
...
arch/x86/pci/broadcom_bus.c
浏览文件 @
29473ec2
...
@@ -22,19 +22,15 @@
...
@@ -22,19 +22,15 @@
static
void
__init
cnb20le_res
(
u8
bus
,
u8
slot
,
u8
func
)
static
void
__init
cnb20le_res
(
u8
bus
,
u8
slot
,
u8
func
)
{
{
struct
pci_root_info
*
info
;
struct
pci_root_info
*
info
;
struct
pci_root_res
*
root_res
;
struct
resource
res
;
struct
resource
res
;
u16
word1
,
word2
;
u16
word1
,
word2
;
u8
fbus
,
lbus
;
u8
fbus
,
lbus
;
int
i
;
info
=
&
pci_root_info
[
pci_root_num
];
pci_root_num
++
;
/* read the PCI bus numbers */
/* read the PCI bus numbers */
fbus
=
read_pci_config_byte
(
bus
,
slot
,
func
,
0x44
);
fbus
=
read_pci_config_byte
(
bus
,
slot
,
func
,
0x44
);
lbus
=
read_pci_config_byte
(
bus
,
slot
,
func
,
0x45
);
lbus
=
read_pci_config_byte
(
bus
,
slot
,
func
,
0x45
);
info
->
bus_min
=
fbus
;
info
=
alloc_pci_root_info
(
fbus
,
lbus
,
0
,
0
);
info
->
bus_max
=
lbus
;
/*
/*
* Add the legacy IDE ports on bus 0
* Add the legacy IDE ports on bus 0
...
@@ -86,8 +82,8 @@ static void __init cnb20le_res(u8 bus, u8 slot, u8 func)
...
@@ -86,8 +82,8 @@ static void __init cnb20le_res(u8 bus, u8 slot, u8 func)
res
.
flags
=
IORESOURCE_BUS
;
res
.
flags
=
IORESOURCE_BUS
;
printk
(
KERN_INFO
"CNB20LE PCI Host Bridge (domain 0000 %pR)
\n
"
,
&
res
);
printk
(
KERN_INFO
"CNB20LE PCI Host Bridge (domain 0000 %pR)
\n
"
,
&
res
);
for
(
i
=
0
;
i
<
info
->
res_num
;
i
++
)
list_for_each_entry
(
root_res
,
&
info
->
resources
,
list
)
printk
(
KERN_INFO
"host bridge window %pR
\n
"
,
&
info
->
res
[
i
]
);
printk
(
KERN_INFO
"host bridge window %pR
\n
"
,
&
root_res
->
res
);
}
}
static
int
__init
broadcom_postcore_init
(
void
)
static
int
__init
broadcom_postcore_init
(
void
)
...
...
arch/x86/pci/bus_numa.c
浏览文件 @
29473ec2
...
@@ -4,35 +4,38 @@
...
@@ -4,35 +4,38 @@
#include "bus_numa.h"
#include "bus_numa.h"
int
pci_root_num
;
LIST_HEAD
(
pci_root_infos
);
struct
pci_root_info
pci_root_info
[
PCI_ROOT_NR
];
void
x86_pci_root_bus_resources
(
int
bus
,
struct
list_head
*
resource
s
)
static
struct
pci_root_info
*
x86_find_pci_root_info
(
int
bu
s
)
{
{
int
i
;
int
j
;
struct
pci_root_info
*
info
;
struct
pci_root_info
*
info
;
if
(
!
pci_root_num
)
if
(
list_empty
(
&
pci_root_infos
)
)
goto
default_resources
;
return
NULL
;
for
(
i
=
0
;
i
<
pci_root_num
;
i
++
)
{
list_for_each_entry
(
info
,
&
pci_root_infos
,
list
)
if
(
pci_root_info
[
i
].
bus_min
==
bus
)
if
(
info
->
bus_min
==
bus
)
break
;
return
info
;
}
return
NULL
;
}
if
(
i
==
pci_root_num
)
void
x86_pci_root_bus_resources
(
int
bus
,
struct
list_head
*
resources
)
{
struct
pci_root_info
*
info
=
x86_find_pci_root_info
(
bus
);
struct
pci_root_res
*
root_res
;
if
(
!
info
)
goto
default_resources
;
goto
default_resources
;
printk
(
KERN_DEBUG
"PCI: root bus %02x: hardware-probed resources
\n
"
,
printk
(
KERN_DEBUG
"PCI: root bus %02x: hardware-probed resources
\n
"
,
bus
);
bus
);
info
=
&
pci_root_info
[
i
];
list_for_each_entry
(
root_res
,
&
info
->
resources
,
list
)
{
for
(
j
=
0
;
j
<
info
->
res_num
;
j
++
)
{
struct
resource
*
res
;
struct
resource
*
res
;
struct
resource
*
root
;
struct
resource
*
root
;
res
=
&
info
->
res
[
j
]
;
res
=
&
root_res
->
res
;
pci_add_resource
(
resources
,
res
);
pci_add_resource
(
resources
,
res
);
if
(
res
->
flags
&
IORESOURCE_IO
)
if
(
res
->
flags
&
IORESOURCE_IO
)
root
=
&
ioport_resource
;
root
=
&
ioport_resource
;
...
@@ -53,11 +56,32 @@ void x86_pci_root_bus_resources(int bus, struct list_head *resources)
...
@@ -53,11 +56,32 @@ void x86_pci_root_bus_resources(int bus, struct list_head *resources)
pci_add_resource
(
resources
,
&
iomem_resource
);
pci_add_resource
(
resources
,
&
iomem_resource
);
}
}
struct
pci_root_info
__init
*
alloc_pci_root_info
(
int
bus_min
,
int
bus_max
,
int
node
,
int
link
)
{
struct
pci_root_info
*
info
;
info
=
kzalloc
(
sizeof
(
*
info
),
GFP_KERNEL
);
if
(
!
info
)
return
info
;
INIT_LIST_HEAD
(
&
info
->
resources
);
info
->
bus_min
=
bus_min
;
info
->
bus_max
=
bus_max
;
info
->
node
=
node
;
info
->
link
=
link
;
list_add_tail
(
&
info
->
list
,
&
pci_root_infos
);
return
info
;
}
void
__devinit
update_res
(
struct
pci_root_info
*
info
,
resource_size_t
start
,
void
__devinit
update_res
(
struct
pci_root_info
*
info
,
resource_size_t
start
,
resource_size_t
end
,
unsigned
long
flags
,
int
merge
)
resource_size_t
end
,
unsigned
long
flags
,
int
merge
)
{
{
int
i
;
struct
resource
*
res
;
struct
resource
*
res
;
struct
pci_root_res
*
root_res
;
if
(
start
>
end
)
if
(
start
>
end
)
return
;
return
;
...
@@ -69,11 +93,11 @@ void __devinit update_res(struct pci_root_info *info, resource_size_t start,
...
@@ -69,11 +93,11 @@ void __devinit update_res(struct pci_root_info *info, resource_size_t start,
goto
addit
;
goto
addit
;
/* try to merge it with old one */
/* try to merge it with old one */
for
(
i
=
0
;
i
<
info
->
res_num
;
i
++
)
{
list_for_each_entry
(
root_res
,
&
info
->
resources
,
list
)
{
resource_size_t
final_start
,
final_end
;
resource_size_t
final_start
,
final_end
;
resource_size_t
common_start
,
common_end
;
resource_size_t
common_start
,
common_end
;
res
=
&
info
->
res
[
i
]
;
res
=
&
root_res
->
res
;
if
(
res
->
flags
!=
flags
)
if
(
res
->
flags
!=
flags
)
continue
;
continue
;
...
@@ -93,14 +117,15 @@ void __devinit update_res(struct pci_root_info *info, resource_size_t start,
...
@@ -93,14 +117,15 @@ void __devinit update_res(struct pci_root_info *info, resource_size_t start,
addit:
addit:
/* need to add that */
/* need to add that */
if
(
info
->
res_num
>=
RES_NUM
)
root_res
=
kzalloc
(
sizeof
(
*
root_res
),
GFP_KERNEL
);
if
(
!
root_res
)
return
;
return
;
res
=
&
info
->
res
[
info
->
res_num
]
;
res
=
&
root_res
->
res
;
res
->
name
=
info
->
name
;
res
->
name
=
info
->
name
;
res
->
flags
=
flags
;
res
->
flags
=
flags
;
res
->
start
=
start
;
res
->
start
=
start
;
res
->
end
=
end
;
res
->
end
=
end
;
res
->
child
=
NULL
;
info
->
res_num
++
;
list_add_tail
(
&
root_res
->
list
,
&
info
->
resources
)
;
}
}
arch/x86/pci/bus_numa.h
浏览文件 @
29473ec2
...
@@ -4,22 +4,24 @@
...
@@ -4,22 +4,24 @@
* sub bus (transparent) will use entres from 3 to store extra from
* sub bus (transparent) will use entres from 3 to store extra from
* root, so need to make sure we have enough slot there.
* root, so need to make sure we have enough slot there.
*/
*/
#define RES_NUM 16
struct
pci_root_res
{
struct
list_head
list
;
struct
resource
res
;
};
struct
pci_root_info
{
struct
pci_root_info
{
struct
list_head
list
;
char
name
[
12
];
char
name
[
12
];
unsigned
int
res_num
;
struct
list_head
resources
;
struct
resource
res
[
RES_NUM
];
int
bus_min
;
int
bus_min
;
int
bus_max
;
int
bus_max
;
int
node
;
int
node
;
int
link
;
int
link
;
};
};
/* 4 at this time, it may become to 32 */
extern
struct
list_head
pci_root_infos
;
#define PCI_ROOT_NR 4
struct
pci_root_info
*
alloc_pci_root_info
(
int
bus_min
,
int
bus_max
,
extern
int
pci_root_num
;
int
node
,
int
link
);
extern
struct
pci_root_info
pci_root_info
[
PCI_ROOT_NR
];
extern
void
update_res
(
struct
pci_root_info
*
info
,
resource_size_t
start
,
extern
void
update_res
(
struct
pci_root_info
*
info
,
resource_size_t
start
,
resource_size_t
end
,
unsigned
long
flags
,
int
merge
);
resource_size_t
end
,
unsigned
long
flags
,
int
merge
);
#endif
#endif
arch/x86/pci/common.c
浏览文件 @
29473ec2
...
@@ -430,9 +430,7 @@ void __init dmi_check_pciprobe(void)
...
@@ -430,9 +430,7 @@ void __init dmi_check_pciprobe(void)
struct
pci_bus
*
__devinit
pcibios_scan_root
(
int
busnum
)
struct
pci_bus
*
__devinit
pcibios_scan_root
(
int
busnum
)
{
{
LIST_HEAD
(
resources
);
struct
pci_bus
*
bus
=
NULL
;
struct
pci_bus
*
bus
=
NULL
;
struct
pci_sysdata
*
sd
;
while
((
bus
=
pci_find_next_bus
(
bus
))
!=
NULL
)
{
while
((
bus
=
pci_find_next_bus
(
bus
))
!=
NULL
)
{
if
(
bus
->
number
==
busnum
)
{
if
(
bus
->
number
==
busnum
)
{
...
@@ -441,28 +439,10 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum)
...
@@ -441,28 +439,10 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum)
}
}
}
}
/* Allocate per-root-bus (not per bus) arch-specific data.
return
pci_scan_bus_on_node
(
busnum
,
&
pci_root_ops
,
* TODO: leak; this memory is never freed.
get_mp_bus_to_node
(
busnum
));
* It's arguable whether it's worth the trouble to care.
*/
sd
=
kzalloc
(
sizeof
(
*
sd
),
GFP_KERNEL
);
if
(
!
sd
)
{
printk
(
KERN_ERR
"PCI: OOM, not probing PCI bus %02x
\n
"
,
busnum
);
return
NULL
;
}
sd
->
node
=
get_mp_bus_to_node
(
busnum
);
printk
(
KERN_DEBUG
"PCI: Probing PCI hardware (bus %02x)
\n
"
,
busnum
);
x86_pci_root_bus_resources
(
busnum
,
&
resources
);
bus
=
pci_scan_root_bus
(
NULL
,
busnum
,
&
pci_root_ops
,
sd
,
&
resources
);
if
(
!
bus
)
{
pci_free_resource_list
(
&
resources
);
kfree
(
sd
);
}
return
bus
;
}
}
void
__init
pcibios_set_cache_line_size
(
void
)
void
__init
pcibios_set_cache_line_size
(
void
)
{
{
struct
cpuinfo_x86
*
c
=
&
boot_cpu_data
;
struct
cpuinfo_x86
*
c
=
&
boot_cpu_data
;
...
@@ -656,6 +636,7 @@ struct pci_bus * __devinit pci_scan_bus_on_node(int busno, struct pci_ops *ops,
...
@@ -656,6 +636,7 @@ struct pci_bus * __devinit pci_scan_bus_on_node(int busno, struct pci_ops *ops,
}
}
sd
->
node
=
node
;
sd
->
node
=
node
;
x86_pci_root_bus_resources
(
busno
,
&
resources
);
x86_pci_root_bus_resources
(
busno
,
&
resources
);
printk
(
KERN_DEBUG
"PCI: Probing PCI hardware (bus %02x)
\n
"
,
busno
);
bus
=
pci_scan_root_bus
(
NULL
,
busno
,
ops
,
sd
,
&
resources
);
bus
=
pci_scan_root_bus
(
NULL
,
busno
,
ops
,
sd
,
&
resources
);
if
(
!
bus
)
{
if
(
!
bus
)
{
pci_free_resource_list
(
&
resources
);
pci_free_resource_list
(
&
resources
);
...
...
drivers/pci/Makefile
浏览文件 @
29473ec2
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
# Makefile for the PCI bus specific drivers.
# Makefile for the PCI bus specific drivers.
#
#
obj-y
+=
access.o bus.o probe.o remove.o pci.o
\
obj-y
+=
access.o bus.o probe.o
host-bridge.o
remove.o pci.o
\
pci-driver.o search.o pci-sysfs.o rom.o setup-res.o
\
pci-driver.o search.o pci-sysfs.o rom.o setup-res.o
\
irq.o vpd.o
irq.o vpd.o
obj-$(CONFIG_PROC_FS)
+=
proc.o
obj-$(CONFIG_PROC_FS)
+=
proc.o
...
...
drivers/pci/host-bridge.c
0 → 100644
浏览文件 @
29473ec2
/*
* host bridge related code
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/module.h>
#include "pci.h"
static
struct
pci_bus
*
find_pci_root_bus
(
struct
pci_dev
*
dev
)
{
struct
pci_bus
*
bus
;
bus
=
dev
->
bus
;
while
(
bus
->
parent
)
bus
=
bus
->
parent
;
return
bus
;
}
static
struct
pci_host_bridge
*
find_pci_host_bridge
(
struct
pci_dev
*
dev
)
{
struct
pci_bus
*
bus
=
find_pci_root_bus
(
dev
);
return
to_pci_host_bridge
(
bus
->
bridge
);
}
void
pci_set_host_bridge_release
(
struct
pci_host_bridge
*
bridge
,
void
(
*
release_fn
)(
struct
pci_host_bridge
*
),
void
*
release_data
)
{
bridge
->
release_fn
=
release_fn
;
bridge
->
release_data
=
release_data
;
}
static
bool
resource_contains
(
struct
resource
*
res1
,
struct
resource
*
res2
)
{
return
res1
->
start
<=
res2
->
start
&&
res1
->
end
>=
res2
->
end
;
}
void
pcibios_resource_to_bus
(
struct
pci_dev
*
dev
,
struct
pci_bus_region
*
region
,
struct
resource
*
res
)
{
struct
pci_host_bridge
*
bridge
=
find_pci_host_bridge
(
dev
);
struct
pci_host_bridge_window
*
window
;
resource_size_t
offset
=
0
;
list_for_each_entry
(
window
,
&
bridge
->
windows
,
list
)
{
if
(
resource_type
(
res
)
!=
resource_type
(
window
->
res
))
continue
;
if
(
resource_contains
(
window
->
res
,
res
))
{
offset
=
window
->
offset
;
break
;
}
}
region
->
start
=
res
->
start
-
offset
;
region
->
end
=
res
->
end
-
offset
;
}
EXPORT_SYMBOL
(
pcibios_resource_to_bus
);
static
bool
region_contains
(
struct
pci_bus_region
*
region1
,
struct
pci_bus_region
*
region2
)
{
return
region1
->
start
<=
region2
->
start
&&
region1
->
end
>=
region2
->
end
;
}
void
pcibios_bus_to_resource
(
struct
pci_dev
*
dev
,
struct
resource
*
res
,
struct
pci_bus_region
*
region
)
{
struct
pci_host_bridge
*
bridge
=
find_pci_host_bridge
(
dev
);
struct
pci_host_bridge_window
*
window
;
resource_size_t
offset
=
0
;
list_for_each_entry
(
window
,
&
bridge
->
windows
,
list
)
{
struct
pci_bus_region
bus_region
;
if
(
resource_type
(
res
)
!=
resource_type
(
window
->
res
))
continue
;
bus_region
.
start
=
window
->
res
->
start
-
window
->
offset
;
bus_region
.
end
=
window
->
res
->
end
-
window
->
offset
;
if
(
region_contains
(
&
bus_region
,
region
))
{
offset
=
window
->
offset
;
break
;
}
}
res
->
start
=
region
->
start
+
offset
;
res
->
end
=
region
->
end
+
offset
;
}
EXPORT_SYMBOL
(
pcibios_bus_to_resource
);
drivers/pci/probe.c
浏览文件 @
29473ec2
...
@@ -15,13 +15,10 @@
...
@@ -15,13 +15,10 @@
#define CARDBUS_LATENCY_TIMER 176
/* secondary latency timer */
#define CARDBUS_LATENCY_TIMER 176
/* secondary latency timer */
#define CARDBUS_RESERVE_BUSNR 3
#define CARDBUS_RESERVE_BUSNR 3
static
LIST_HEAD
(
pci_host_bridges
);
/* Ugh. Need to stop exporting this to modules. */
/* Ugh. Need to stop exporting this to modules. */
LIST_HEAD
(
pci_root_buses
);
LIST_HEAD
(
pci_root_buses
);
EXPORT_SYMBOL
(
pci_root_buses
);
EXPORT_SYMBOL
(
pci_root_buses
);
static
int
find_anything
(
struct
device
*
dev
,
void
*
data
)
static
int
find_anything
(
struct
device
*
dev
,
void
*
data
)
{
{
return
1
;
return
1
;
...
@@ -44,82 +41,6 @@ int no_pci_devices(void)
...
@@ -44,82 +41,6 @@ int no_pci_devices(void)
}
}
EXPORT_SYMBOL
(
no_pci_devices
);
EXPORT_SYMBOL
(
no_pci_devices
);
static
struct
pci_host_bridge
*
pci_host_bridge
(
struct
pci_dev
*
dev
)
{
struct
pci_bus
*
bus
;
struct
pci_host_bridge
*
bridge
;
bus
=
dev
->
bus
;
while
(
bus
->
parent
)
bus
=
bus
->
parent
;
list_for_each_entry
(
bridge
,
&
pci_host_bridges
,
list
)
{
if
(
bridge
->
bus
==
bus
)
return
bridge
;
}
return
NULL
;
}
static
bool
resource_contains
(
struct
resource
*
res1
,
struct
resource
*
res2
)
{
return
res1
->
start
<=
res2
->
start
&&
res1
->
end
>=
res2
->
end
;
}
void
pcibios_resource_to_bus
(
struct
pci_dev
*
dev
,
struct
pci_bus_region
*
region
,
struct
resource
*
res
)
{
struct
pci_host_bridge
*
bridge
=
pci_host_bridge
(
dev
);
struct
pci_host_bridge_window
*
window
;
resource_size_t
offset
=
0
;
list_for_each_entry
(
window
,
&
bridge
->
windows
,
list
)
{
if
(
resource_type
(
res
)
!=
resource_type
(
window
->
res
))
continue
;
if
(
resource_contains
(
window
->
res
,
res
))
{
offset
=
window
->
offset
;
break
;
}
}
region
->
start
=
res
->
start
-
offset
;
region
->
end
=
res
->
end
-
offset
;
}
EXPORT_SYMBOL
(
pcibios_resource_to_bus
);
static
bool
region_contains
(
struct
pci_bus_region
*
region1
,
struct
pci_bus_region
*
region2
)
{
return
region1
->
start
<=
region2
->
start
&&
region1
->
end
>=
region2
->
end
;
}
void
pcibios_bus_to_resource
(
struct
pci_dev
*
dev
,
struct
resource
*
res
,
struct
pci_bus_region
*
region
)
{
struct
pci_host_bridge
*
bridge
=
pci_host_bridge
(
dev
);
struct
pci_host_bridge_window
*
window
;
struct
pci_bus_region
bus_region
;
resource_size_t
offset
=
0
;
list_for_each_entry
(
window
,
&
bridge
->
windows
,
list
)
{
if
(
resource_type
(
res
)
!=
resource_type
(
window
->
res
))
continue
;
bus_region
.
start
=
window
->
res
->
start
-
window
->
offset
;
bus_region
.
end
=
window
->
res
->
end
-
window
->
offset
;
if
(
region_contains
(
&
bus_region
,
region
))
{
offset
=
window
->
offset
;
break
;
}
}
res
->
start
=
region
->
start
+
offset
;
res
->
end
=
region
->
end
+
offset
;
}
EXPORT_SYMBOL
(
pcibios_bus_to_resource
);
/*
/*
* PCI Bus Class
* PCI Bus Class
*/
*/
...
@@ -501,6 +422,19 @@ static struct pci_bus * pci_alloc_bus(void)
...
@@ -501,6 +422,19 @@ static struct pci_bus * pci_alloc_bus(void)
return
b
;
return
b
;
}
}
static
struct
pci_host_bridge
*
pci_alloc_host_bridge
(
struct
pci_bus
*
b
)
{
struct
pci_host_bridge
*
bridge
;
bridge
=
kzalloc
(
sizeof
(
*
bridge
),
GFP_KERNEL
);
if
(
bridge
)
{
INIT_LIST_HEAD
(
&
bridge
->
windows
);
bridge
->
bus
=
b
;
}
return
bridge
;
}
static
unsigned
char
pcix_bus_speed
[]
=
{
static
unsigned
char
pcix_bus_speed
[]
=
{
PCI_SPEED_UNKNOWN
,
/* 0 */
PCI_SPEED_UNKNOWN
,
/* 0 */
PCI_SPEED_66MHz_PCIX
,
/* 1 */
PCI_SPEED_66MHz_PCIX
,
/* 1 */
...
@@ -1201,7 +1135,14 @@ int pci_cfg_space_size(struct pci_dev *dev)
...
@@ -1201,7 +1135,14 @@ int pci_cfg_space_size(struct pci_dev *dev)
static
void
pci_release_bus_bridge_dev
(
struct
device
*
dev
)
static
void
pci_release_bus_bridge_dev
(
struct
device
*
dev
)
{
{
kfree
(
dev
);
struct
pci_host_bridge
*
bridge
=
to_pci_host_bridge
(
dev
);
if
(
bridge
->
release_fn
)
bridge
->
release_fn
(
bridge
);
pci_free_resource_list
(
&
bridge
->
windows
);
kfree
(
bridge
);
}
}
struct
pci_dev
*
alloc_pci_dev
(
void
)
struct
pci_dev
*
alloc_pci_dev
(
void
)
...
@@ -1650,28 +1591,19 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
...
@@ -1650,28 +1591,19 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
int
error
;
int
error
;
struct
pci_host_bridge
*
bridge
;
struct
pci_host_bridge
*
bridge
;
struct
pci_bus
*
b
,
*
b2
;
struct
pci_bus
*
b
,
*
b2
;
struct
device
*
dev
;
struct
pci_host_bridge_window
*
window
,
*
n
;
struct
pci_host_bridge_window
*
window
,
*
n
;
struct
resource
*
res
;
struct
resource
*
res
;
resource_size_t
offset
;
resource_size_t
offset
;
char
bus_addr
[
64
];
char
bus_addr
[
64
];
char
*
fmt
;
char
*
fmt
;
bridge
=
kzalloc
(
sizeof
(
*
bridge
),
GFP_KERNEL
);
if
(
!
bridge
)
return
NULL
;
b
=
pci_alloc_bus
();
b
=
pci_alloc_bus
();
if
(
!
b
)
if
(
!
b
)
goto
err_bus
;
return
NULL
;
dev
=
kzalloc
(
sizeof
(
*
dev
),
GFP_KERNEL
);
if
(
!
dev
)
goto
err_dev
;
b
->
sysdata
=
sysdata
;
b
->
sysdata
=
sysdata
;
b
->
ops
=
ops
;
b
->
ops
=
ops
;
b2
=
pci_find_bus
(
pci_domain_nr
(
b
),
bus
);
b2
=
pci_find_bus
(
pci_domain_nr
(
b
),
bus
);
if
(
b2
)
{
if
(
b2
)
{
/* If we already got to this bus through a different bridge, ignore it */
/* If we already got to this bus through a different bridge, ignore it */
...
@@ -1679,13 +1611,17 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
...
@@ -1679,13 +1611,17 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
goto
err_out
;
goto
err_out
;
}
}
dev
->
parent
=
parent
;
bridge
=
pci_alloc_host_bridge
(
b
);
dev
->
release
=
pci_release_bus_bridge_dev
;
if
(
!
bridge
)
dev_set_name
(
dev
,
"pci%04x:%02x"
,
pci_domain_nr
(
b
),
bus
);
goto
err_out
;
error
=
device_register
(
dev
);
bridge
->
dev
.
parent
=
parent
;
bridge
->
dev
.
release
=
pci_release_bus_bridge_dev
;
dev_set_name
(
&
bridge
->
dev
,
"pci%04x:%02x"
,
pci_domain_nr
(
b
),
bus
);
error
=
device_register
(
&
bridge
->
dev
);
if
(
error
)
if
(
error
)
goto
dev_reg_err
;
goto
bridge_
dev_reg_err
;
b
->
bridge
=
get_device
(
dev
);
b
->
bridge
=
get_device
(
&
bridge
->
dev
);
device_enable_async_suspend
(
b
->
bridge
);
device_enable_async_suspend
(
b
->
bridge
);
pci_set_bus_of_node
(
b
);
pci_set_bus_of_node
(
b
);
...
@@ -1704,9 +1640,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
...
@@ -1704,9 +1640,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
b
->
number
=
b
->
secondary
=
bus
;
b
->
number
=
b
->
secondary
=
bus
;
bridge
->
bus
=
b
;
INIT_LIST_HEAD
(
&
bridge
->
windows
);
if
(
parent
)
if
(
parent
)
dev_info
(
parent
,
"PCI host bridge to bus %s
\n
"
,
dev_name
(
&
b
->
dev
));
dev_info
(
parent
,
"PCI host bridge to bus %s
\n
"
,
dev_name
(
&
b
->
dev
));
else
else
...
@@ -1732,25 +1665,18 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
...
@@ -1732,25 +1665,18 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
}
}
down_write
(
&
pci_bus_sem
);
down_write
(
&
pci_bus_sem
);
list_add_tail
(
&
bridge
->
list
,
&
pci_host_bridges
);
list_add_tail
(
&
b
->
node
,
&
pci_root_buses
);
list_add_tail
(
&
b
->
node
,
&
pci_root_buses
);
up_write
(
&
pci_bus_sem
);
up_write
(
&
pci_bus_sem
);
return
b
;
return
b
;
class_dev_reg_err:
class_dev_reg_err:
device_unregister
(
dev
);
put_device
(
&
bridge
->
dev
);
dev_reg_err:
device_unregister
(
&
bridge
->
dev
);
down_write
(
&
pci_bus_sem
);
bridge_dev_reg_err:
list_del
(
&
bridge
->
list
);
kfree
(
bridge
);
list_del
(
&
b
->
node
);
up_write
(
&
pci_bus_sem
);
err_out:
err_out:
kfree
(
dev
);
err_dev:
kfree
(
b
);
kfree
(
b
);
err_bus:
kfree
(
bridge
);
return
NULL
;
return
NULL
;
}
}
...
...
include/linux/pci.h
浏览文件 @
29473ec2
...
@@ -375,11 +375,18 @@ struct pci_host_bridge_window {
...
@@ -375,11 +375,18 @@ struct pci_host_bridge_window {
};
};
struct
pci_host_bridge
{
struct
pci_host_bridge
{
struct
list_head
list
;
struct
device
dev
;
struct
pci_bus
*
bus
;
/* root bus */
struct
pci_bus
*
bus
;
/* root bus */
struct
list_head
windows
;
/* pci_host_bridge_windows */
struct
list_head
windows
;
/* pci_host_bridge_windows */
void
(
*
release_fn
)(
struct
pci_host_bridge
*
);
void
*
release_data
;
};
};
#define to_pci_host_bridge(n) container_of(n, struct pci_host_bridge, dev)
void
pci_set_host_bridge_release
(
struct
pci_host_bridge
*
bridge
,
void
(
*
release_fn
)(
struct
pci_host_bridge
*
),
void
*
release_data
);
/*
/*
* The first PCI_BRIDGE_RESOURCE_NUM PCI bus resources (those that correspond
* The first PCI_BRIDGE_RESOURCE_NUM PCI bus resources (those that correspond
* to P2P or CardBus bridge windows) go in a table. Additional ones (for
* to P2P or CardBus bridge windows) go in a table. Additional ones (for
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录