Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
68b308e8
Commit
68b308e8
authored
Jan 28, 2004
by
Matthew Dobson
Committed by
Linus Torvalds
Jan 28, 2004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] PCI: add pci_bus sysfs class
This is needed to show pci bus topology to userspace properly.
parent
78d65a24
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
85 additions
and
37 deletions
+85
-37
drivers/pci/bus.c
drivers/pci/bus.c
+2
-0
drivers/pci/probe.c
drivers/pci/probe.c
+79
-35
include/linux/pci.h
include/linux/pci.h
+4
-2
No files found.
drivers/pci/bus.c
View file @
68b308e8
...
...
@@ -116,6 +116,8 @@ void __devinit pci_bus_add_devices(struct pci_bus *bus)
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/probe.c
View file @
68b308e8
...
...
@@ -6,6 +6,7 @@
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/cpumask.h>
#undef DEBUG
...
...
@@ -24,6 +25,39 @@ EXPORT_SYMBOL(pci_root_buses);
LIST_HEAD
(
pci_devices
);
/*
* PCI Bus Class
*/
static
void
release_pcibus_dev
(
struct
class_device
*
class_dev
)
{
struct
pci_bus
*
pci_bus
=
to_pci_bus
(
class_dev
);
if
(
pci_bus
->
bridge
)
put_device
(
pci_bus
->
bridge
);
kfree
(
pci_bus
);
}
static
struct
class
pcibus_class
=
{
.
name
=
"pci_bus"
,
.
release
=
&
release_pcibus_dev
,
};
static
int
__init
pcibus_class_init
(
void
)
{
return
class_register
(
&
pcibus_class
);
}
postcore_initcall
(
pcibus_class_init
);
/*
* PCI Bus Class Devices
*/
static
ssize_t
pci_bus_show_cpuaffinity
(
struct
class_device
*
class_dev
,
char
*
buf
)
{
cpumask_t
cpumask
=
pcibus_to_cpumask
((
to_pci_bus
(
class_dev
))
->
number
);
return
sprintf
(
buf
,
"%lx
\n
"
,
(
unsigned
long
)
cpumask
);
}
static
CLASS_DEVICE_ATTR
(
cpuaffinity
,
S_IRUGO
,
pci_bus_show_cpuaffinity
,
NULL
);
/*
* Translate the low bits of the PCI base
* to the resource type
...
...
@@ -238,37 +272,40 @@ static struct pci_bus * __devinit
pci_alloc_child_bus
(
struct
pci_bus
*
parent
,
struct
pci_dev
*
bridge
,
int
busnr
)
{
struct
pci_bus
*
child
;
int
i
;
/*
* Allocate a new bus, and inherit stuff from the parent..
*/
child
=
pci_alloc_bus
();
if
(
!
child
)
return
NULL
;
if
(
child
)
{
int
i
;
child
->
self
=
bridge
;
child
->
parent
=
parent
;
child
->
ops
=
parent
->
ops
;
child
->
sysdata
=
parent
->
sysdata
;
child
->
dev
=
&
bridge
->
dev
;
child
->
self
=
bridge
;
child
->
parent
=
parent
;
child
->
ops
=
parent
->
ops
;
child
->
sysdata
=
parent
->
sysdata
;
child
->
bridge
=
get_device
(
&
bridge
->
dev
);
/*
* Set up the primary, secondary and subordinate
* bus numbers.
*/
child
->
number
=
child
->
secondary
=
busnr
;
child
->
primary
=
parent
->
secondary
;
child
->
subordinate
=
0xff
;
/* Set up default resource pointers and names.. */
for
(
i
=
0
;
i
<
4
;
i
++
)
{
child
->
resource
[
i
]
=
&
bridge
->
resource
[
PCI_BRIDGE_RESOURCES
+
i
];
child
->
resource
[
i
]
->
name
=
child
->
name
;
}
child
->
class_dev
.
class
=
&
pcibus_class
;
sprintf
(
child
->
class_dev
.
class_id
,
"%04x:%02x"
,
pci_domain_nr
(
child
),
busnr
);
class_device_register
(
&
child
->
class_dev
);
class_device_create_file
(
&
child
->
class_dev
,
&
class_device_attr_cpuaffinity
);
bridge
->
subordinate
=
child
;
/*
* Set up the primary, secondary and subordinate
* bus numbers.
*/
child
->
number
=
child
->
secondary
=
busnr
;
child
->
primary
=
parent
->
secondary
;
child
->
subordinate
=
0xff
;
/* Set up default resource pointers and names.. */
for
(
i
=
0
;
i
<
4
;
i
++
)
{
child
->
resource
[
i
]
=
&
bridge
->
resource
[
PCI_BRIDGE_RESOURCES
+
i
];
child
->
resource
[
i
]
->
name
=
child
->
name
;
}
bridge
->
subordinate
=
child
;
return
child
;
}
...
...
@@ -307,18 +344,17 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
pci_name
(
dev
),
buses
&
0xffffff
,
pass
);
if
((
buses
&
0xffff00
)
&&
!
pcibios_assign_all_busses
()
&&
!
is_cardbus
)
{
unsigned
int
cmax
;
unsigned
int
cmax
,
busnr
;
/*
* Bus already configured by firmware, process it in the first
* pass and just note the configuration.
*/
if
(
pass
)
return
max
;
child
=
pci_alloc_child_bus
(
bus
,
dev
,
0
);
busnr
=
(
buses
>>
8
)
&
0xFF
;
child
=
pci_alloc_child_bus
(
bus
,
dev
,
busnr
);
child
->
primary
=
buses
&
0xFF
;
child
->
secondary
=
(
buses
>>
8
)
&
0xFF
;
child
->
subordinate
=
(
buses
>>
16
)
&
0xFF
;
child
->
number
=
child
->
secondary
;
cmax
=
pci_scan_child_bus
(
child
);
if
(
cmax
>
max
)
max
=
cmax
;
}
else
{
...
...
@@ -508,7 +544,7 @@ pci_scan_device(struct pci_bus *bus, int devfn)
memset
(
dev
,
0
,
sizeof
(
struct
pci_dev
));
dev
->
bus
=
bus
;
dev
->
sysdata
=
bus
->
sysdata
;
dev
->
dev
.
parent
=
bus
->
dev
;
dev
->
dev
.
parent
=
bus
->
bridge
;
dev
->
dev
.
bus
=
&
pci_bus_type
;
dev
->
devfn
=
devfn
;
dev
->
hdr_type
=
hdr_type
&
0x7f
;
...
...
@@ -635,13 +671,14 @@ unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus)
struct
pci_bus
*
__devinit
pci_scan_bus_parented
(
struct
device
*
parent
,
int
bus
,
struct
pci_ops
*
ops
,
void
*
sysdata
)
{
struct
pci_bus
*
b
;
struct
device
*
dev
;
b
=
pci_alloc_bus
();
if
(
!
b
)
return
NULL
;
b
->
dev
=
kmalloc
(
sizeof
(
*
(
b
->
dev
)),
GFP_KERNEL
);
if
(
!
b
->
dev
){
dev
=
kmalloc
(
sizeof
(
*
dev
),
GFP_KERNEL
);
if
(
!
dev
){
kfree
(
b
);
return
NULL
;
}
...
...
@@ -652,17 +689,24 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus,
if
(
pci_find_bus
(
pci_domain_nr
(
b
),
bus
))
{
/* If we already got to this bus through a different bridge, ignore it */
DBG
(
"PCI: Bus %02x already known
\n
"
,
bus
);
kfree
(
b
->
dev
);
kfree
(
dev
);
kfree
(
b
);
return
NULL
;
}
list_add_tail
(
&
b
->
node
,
&
pci_root_buses
);
memset
(
b
->
dev
,
0
,
sizeof
(
*
(
b
->
dev
)));
b
->
dev
->
parent
=
parent
;
sprintf
(
b
->
dev
->
bus_id
,
"pci%04x:%02x"
,
pci_domain_nr
(
b
),
bus
);
device_register
(
b
->
dev
);
memset
(
dev
,
0
,
sizeof
(
*
dev
));
dev
->
parent
=
parent
;
sprintf
(
dev
->
bus_id
,
"pci%04x:%02x"
,
pci_domain_nr
(
b
),
bus
);
device_register
(
dev
);
b
->
bridge
=
get_device
(
dev
);
b
->
class_dev
.
class
=
&
pcibus_class
;
sprintf
(
b
->
class_dev
.
class_id
,
"%04x:%02x"
,
pci_domain_nr
(
b
),
bus
);
class_device_register
(
&
b
->
class_dev
);
class_device_create_file
(
&
b
->
class_dev
,
&
class_device_attr_cpuaffinity
);
sysfs_create_link
(
&
b
->
class_dev
.
kobj
,
&
b
->
bridge
->
kobj
,
"bridge"
);
b
->
number
=
b
->
secondary
=
bus
;
b
->
resource
[
0
]
=
&
ioport_resource
;
...
...
include/linux/pci.h
View file @
68b308e8
...
...
@@ -473,10 +473,12 @@ struct pci_bus {
char
name
[
48
];
struct
device
*
dev
;
struct
device
*
bridge
;
struct
class_device
class_dev
;
};
#define pci_bus_b(n) list_entry(n, struct pci_bus, node)
#define pci_bus_b(n) list_entry(n, struct pci_bus, node)
#define to_pci_bus(n) container_of(n, struct pci_bus, class_dev)
/*
* Error values that may be returned by PCI functions.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment