diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2007-05-22 22:47:54 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-02-01 18:04:31 -0500 |
commit | fd7d1ced29e5beb88c9068801da7a362606d8273 (patch) | |
tree | 40bfac045b8f7e6b94da04f76ed402395edc45cf | |
parent | 05cca6e52a5a75ffd491fb50a9f636075b2d77ba (diff) |
PCI: make pci_bus a struct device
This moves the pci_bus class device to be a real struct device and at
the same time, place it in the device tree in the correct location.
Note, the old "bridge" symlink is now gone, but this was a non-standard
link and no userspace program used it. If you need to determine the
device that the bus is on, follow the standard device symlink, or walk
up the device tree.
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/pci/bus.c | 17 | ||||
-rw-r--r-- | drivers/pci/pci-sysfs.c | 6 | ||||
-rw-r--r-- | drivers/pci/pci.h | 2 | ||||
-rw-r--r-- | drivers/pci/probe.c | 64 | ||||
-rw-r--r-- | drivers/pci/remove.c | 6 | ||||
-rw-r--r-- | include/linux/pci.h | 4 |
6 files changed, 46 insertions, 53 deletions
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 863340a7b77f..ef5a6a245f5f 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -108,6 +108,7 @@ int pci_bus_add_device(struct pci_dev *dev) | |||
108 | void pci_bus_add_devices(struct pci_bus *bus) | 108 | void pci_bus_add_devices(struct pci_bus *bus) |
109 | { | 109 | { |
110 | struct pci_dev *dev; | 110 | struct pci_dev *dev; |
111 | struct pci_bus *child_bus; | ||
111 | int retval; | 112 | int retval; |
112 | 113 | ||
113 | list_for_each_entry(dev, &bus->devices, bus_list) { | 114 | list_for_each_entry(dev, &bus->devices, bus_list) { |
@@ -138,11 +139,19 @@ void pci_bus_add_devices(struct pci_bus *bus) | |||
138 | up_write(&pci_bus_sem); | 139 | up_write(&pci_bus_sem); |
139 | } | 140 | } |
140 | pci_bus_add_devices(dev->subordinate); | 141 | pci_bus_add_devices(dev->subordinate); |
141 | retval = sysfs_create_link(&dev->subordinate->class_dev.kobj, | 142 | |
142 | &dev->dev.kobj, "bridge"); | 143 | /* register the bus with sysfs as the parent is now |
144 | * properly registered. */ | ||
145 | child_bus = dev->subordinate; | ||
146 | child_bus->dev.parent = child_bus->bridge; | ||
147 | retval = device_register(&child_bus->dev); | ||
148 | if (!retval) | ||
149 | retval = device_create_file(&child_bus->dev, | ||
150 | &dev_attr_cpuaffinity); | ||
143 | if (retval) | 151 | if (retval) |
144 | dev_err(&dev->dev, "Error creating sysfs " | 152 | dev_err(&dev->dev, "Error registering pci_bus" |
145 | "bridge symlink, continuing...\n"); | 153 | " device bridge symlink," |
154 | " continuing...\n"); | ||
146 | } | 155 | } |
147 | } | 156 | } |
148 | } | 157 | } |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index d05c1b252386..abf4203304e4 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -359,7 +359,7 @@ pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
359 | char *buf, loff_t off, size_t count) | 359 | char *buf, loff_t off, size_t count) |
360 | { | 360 | { |
361 | struct pci_bus *bus = to_pci_bus(container_of(kobj, | 361 | struct pci_bus *bus = to_pci_bus(container_of(kobj, |
362 | struct class_device, | 362 | struct device, |
363 | kobj)); | 363 | kobj)); |
364 | 364 | ||
365 | /* Only support 1, 2 or 4 byte accesses */ | 365 | /* Only support 1, 2 or 4 byte accesses */ |
@@ -384,7 +384,7 @@ pci_write_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
384 | char *buf, loff_t off, size_t count) | 384 | char *buf, loff_t off, size_t count) |
385 | { | 385 | { |
386 | struct pci_bus *bus = to_pci_bus(container_of(kobj, | 386 | struct pci_bus *bus = to_pci_bus(container_of(kobj, |
387 | struct class_device, | 387 | struct device, |
388 | kobj)); | 388 | kobj)); |
389 | /* Only support 1, 2 or 4 byte accesses */ | 389 | /* Only support 1, 2 or 4 byte accesses */ |
390 | if (count != 1 && count != 2 && count != 4) | 390 | if (count != 1 && count != 2 && count != 4) |
@@ -408,7 +408,7 @@ pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr, | |||
408 | struct vm_area_struct *vma) | 408 | struct vm_area_struct *vma) |
409 | { | 409 | { |
410 | struct pci_bus *bus = to_pci_bus(container_of(kobj, | 410 | struct pci_bus *bus = to_pci_bus(container_of(kobj, |
411 | struct class_device, | 411 | struct device, |
412 | kobj)); | 412 | kobj)); |
413 | 413 | ||
414 | return pci_mmap_legacy_page_range(bus, vma); | 414 | return pci_mmap_legacy_page_range(bus, vma); |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 79887efbd986..eabeb1f2ec99 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -64,7 +64,7 @@ static inline int pci_no_d1d2(struct pci_dev *dev) | |||
64 | } | 64 | } |
65 | extern int pcie_mch_quirk; | 65 | extern int pcie_mch_quirk; |
66 | extern struct device_attribute pci_dev_attrs[]; | 66 | extern struct device_attribute pci_dev_attrs[]; |
67 | extern struct class_device_attribute class_device_attr_cpuaffinity; | 67 | extern struct device_attribute dev_attr_cpuaffinity; |
68 | 68 | ||
69 | /** | 69 | /** |
70 | * pci_match_one_device - Tell if a PCI device structure has a matching | 70 | * pci_match_one_device - Tell if a PCI device structure has a matching |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 9b4673df27e7..8b505bd925aa 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -54,7 +54,7 @@ static void pci_create_legacy_files(struct pci_bus *b) | |||
54 | b->legacy_io->attr.mode = S_IRUSR | S_IWUSR; | 54 | b->legacy_io->attr.mode = S_IRUSR | S_IWUSR; |
55 | b->legacy_io->read = pci_read_legacy_io; | 55 | b->legacy_io->read = pci_read_legacy_io; |
56 | b->legacy_io->write = pci_write_legacy_io; | 56 | b->legacy_io->write = pci_write_legacy_io; |
57 | class_device_create_bin_file(&b->class_dev, b->legacy_io); | 57 | device_create_bin_file(&b->dev, b->legacy_io); |
58 | 58 | ||
59 | /* Allocated above after the legacy_io struct */ | 59 | /* Allocated above after the legacy_io struct */ |
60 | b->legacy_mem = b->legacy_io + 1; | 60 | b->legacy_mem = b->legacy_io + 1; |
@@ -62,15 +62,15 @@ static void pci_create_legacy_files(struct pci_bus *b) | |||
62 | b->legacy_mem->size = 1024*1024; | 62 | b->legacy_mem->size = 1024*1024; |
63 | b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR; | 63 | b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR; |
64 | b->legacy_mem->mmap = pci_mmap_legacy_mem; | 64 | b->legacy_mem->mmap = pci_mmap_legacy_mem; |
65 | class_device_create_bin_file(&b->class_dev, b->legacy_mem); | 65 | device_create_bin_file(&b->dev, b->legacy_mem); |
66 | } | 66 | } |
67 | } | 67 | } |
68 | 68 | ||
69 | void pci_remove_legacy_files(struct pci_bus *b) | 69 | void pci_remove_legacy_files(struct pci_bus *b) |
70 | { | 70 | { |
71 | if (b->legacy_io) { | 71 | if (b->legacy_io) { |
72 | class_device_remove_bin_file(&b->class_dev, b->legacy_io); | 72 | device_remove_bin_file(&b->dev, b->legacy_io); |
73 | class_device_remove_bin_file(&b->class_dev, b->legacy_mem); | 73 | device_remove_bin_file(&b->dev, b->legacy_mem); |
74 | kfree(b->legacy_io); /* both are allocated here */ | 74 | kfree(b->legacy_io); /* both are allocated here */ |
75 | } | 75 | } |
76 | } | 76 | } |
@@ -82,26 +82,27 @@ void pci_remove_legacy_files(struct pci_bus *bus) { return; } | |||
82 | /* | 82 | /* |
83 | * PCI Bus Class Devices | 83 | * PCI Bus Class Devices |
84 | */ | 84 | */ |
85 | static ssize_t pci_bus_show_cpuaffinity(struct class_device *class_dev, | 85 | static ssize_t pci_bus_show_cpuaffinity(struct device *dev, |
86 | struct device_attribute *attr, | ||
86 | char *buf) | 87 | char *buf) |
87 | { | 88 | { |
88 | int ret; | 89 | int ret; |
89 | cpumask_t cpumask; | 90 | cpumask_t cpumask; |
90 | 91 | ||
91 | cpumask = pcibus_to_cpumask(to_pci_bus(class_dev)); | 92 | cpumask = pcibus_to_cpumask(to_pci_bus(dev)); |
92 | ret = cpumask_scnprintf(buf, PAGE_SIZE, cpumask); | 93 | ret = cpumask_scnprintf(buf, PAGE_SIZE, cpumask); |
93 | if (ret < PAGE_SIZE) | 94 | if (ret < PAGE_SIZE) |
94 | buf[ret++] = '\n'; | 95 | buf[ret++] = '\n'; |
95 | return ret; | 96 | return ret; |
96 | } | 97 | } |
97 | CLASS_DEVICE_ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpuaffinity, NULL); | 98 | DEVICE_ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpuaffinity, NULL); |
98 | 99 | ||
99 | /* | 100 | /* |
100 | * PCI Bus Class | 101 | * PCI Bus Class |
101 | */ | 102 | */ |
102 | static void release_pcibus_dev(struct class_device *class_dev) | 103 | static void release_pcibus_dev(struct device *dev) |
103 | { | 104 | { |
104 | struct pci_bus *pci_bus = to_pci_bus(class_dev); | 105 | struct pci_bus *pci_bus = to_pci_bus(dev); |
105 | 106 | ||
106 | if (pci_bus->bridge) | 107 | if (pci_bus->bridge) |
107 | put_device(pci_bus->bridge); | 108 | put_device(pci_bus->bridge); |
@@ -110,7 +111,7 @@ static void release_pcibus_dev(struct class_device *class_dev) | |||
110 | 111 | ||
111 | static struct class pcibus_class = { | 112 | static struct class pcibus_class = { |
112 | .name = "pci_bus", | 113 | .name = "pci_bus", |
113 | .release = &release_pcibus_dev, | 114 | .dev_release = &release_pcibus_dev, |
114 | }; | 115 | }; |
115 | 116 | ||
116 | static int __init pcibus_class_init(void) | 117 | static int __init pcibus_class_init(void) |
@@ -393,7 +394,6 @@ pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr) | |||
393 | { | 394 | { |
394 | struct pci_bus *child; | 395 | struct pci_bus *child; |
395 | int i; | 396 | int i; |
396 | int retval; | ||
397 | 397 | ||
398 | /* | 398 | /* |
399 | * Allocate a new bus, and inherit stuff from the parent.. | 399 | * Allocate a new bus, and inherit stuff from the parent.. |
@@ -409,15 +409,12 @@ pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr) | |||
409 | child->bus_flags = parent->bus_flags; | 409 | child->bus_flags = parent->bus_flags; |
410 | child->bridge = get_device(&bridge->dev); | 410 | child->bridge = get_device(&bridge->dev); |
411 | 411 | ||
412 | child->class_dev.class = &pcibus_class; | 412 | /* initialize some portions of the bus device, but don't register it |
413 | sprintf(child->class_dev.class_id, "%04x:%02x", pci_domain_nr(child), busnr); | 413 | * now as the parent is not properly set up yet. This device will get |
414 | retval = class_device_register(&child->class_dev); | 414 | * registered later in pci_bus_add_devices() |
415 | if (retval) | 415 | */ |
416 | goto error_register; | 416 | child->dev.class = &pcibus_class; |
417 | retval = class_device_create_file(&child->class_dev, | 417 | sprintf(child->dev.bus_id, "%04x:%02x", pci_domain_nr(child), busnr); |
418 | &class_device_attr_cpuaffinity); | ||
419 | if (retval) | ||
420 | goto error_file_create; | ||
421 | 418 | ||
422 | /* | 419 | /* |
423 | * Set up the primary, secondary and subordinate | 420 | * Set up the primary, secondary and subordinate |
@@ -435,12 +432,6 @@ pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr) | |||
435 | bridge->subordinate = child; | 432 | bridge->subordinate = child; |
436 | 433 | ||
437 | return child; | 434 | return child; |
438 | |||
439 | error_file_create: | ||
440 | class_device_unregister(&child->class_dev); | ||
441 | error_register: | ||
442 | kfree(child); | ||
443 | return NULL; | ||
444 | } | 435 | } |
445 | 436 | ||
446 | struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr) | 437 | struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr) |
@@ -1107,32 +1098,27 @@ struct pci_bus * pci_create_bus(struct device *parent, | |||
1107 | goto dev_reg_err; | 1098 | goto dev_reg_err; |
1108 | b->bridge = get_device(dev); | 1099 | b->bridge = get_device(dev); |
1109 | 1100 | ||
1110 | b->class_dev.class = &pcibus_class; | 1101 | b->dev.class = &pcibus_class; |
1111 | sprintf(b->class_dev.class_id, "%04x:%02x", pci_domain_nr(b), bus); | 1102 | b->dev.parent = b->bridge; |
1112 | error = class_device_register(&b->class_dev); | 1103 | sprintf(b->dev.bus_id, "%04x:%02x", pci_domain_nr(b), bus); |
1104 | error = device_register(&b->dev); | ||
1113 | if (error) | 1105 | if (error) |
1114 | goto class_dev_reg_err; | 1106 | goto class_dev_reg_err; |
1115 | error = class_device_create_file(&b->class_dev, &class_device_attr_cpuaffinity); | 1107 | error = device_create_file(&b->dev, &dev_attr_cpuaffinity); |
1116 | if (error) | 1108 | if (error) |
1117 | goto class_dev_create_file_err; | 1109 | goto dev_create_file_err; |
1118 | 1110 | ||
1119 | /* Create legacy_io and legacy_mem files for this bus */ | 1111 | /* Create legacy_io and legacy_mem files for this bus */ |
1120 | pci_create_legacy_files(b); | 1112 | pci_create_legacy_files(b); |
1121 | 1113 | ||
1122 | error = sysfs_create_link(&b->class_dev.kobj, &b->bridge->kobj, "bridge"); | ||
1123 | if (error) | ||
1124 | goto sys_create_link_err; | ||
1125 | |||
1126 | b->number = b->secondary = bus; | 1114 | b->number = b->secondary = bus; |
1127 | b->resource[0] = &ioport_resource; | 1115 | b->resource[0] = &ioport_resource; |
1128 | b->resource[1] = &iomem_resource; | 1116 | b->resource[1] = &iomem_resource; |
1129 | 1117 | ||
1130 | return b; | 1118 | return b; |
1131 | 1119 | ||
1132 | sys_create_link_err: | 1120 | dev_create_file_err: |
1133 | class_device_remove_file(&b->class_dev, &class_device_attr_cpuaffinity); | 1121 | device_unregister(&b->dev); |
1134 | class_dev_create_file_err: | ||
1135 | class_device_unregister(&b->class_dev); | ||
1136 | class_dev_reg_err: | 1122 | class_dev_reg_err: |
1137 | device_unregister(dev); | 1123 | device_unregister(dev); |
1138 | dev_reg_err: | 1124 | dev_reg_err: |
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 05c9ad2a7f8b..ec4a82ba29a8 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c | |||
@@ -78,10 +78,8 @@ void pci_remove_bus(struct pci_bus *pci_bus) | |||
78 | list_del(&pci_bus->node); | 78 | list_del(&pci_bus->node); |
79 | up_write(&pci_bus_sem); | 79 | up_write(&pci_bus_sem); |
80 | pci_remove_legacy_files(pci_bus); | 80 | pci_remove_legacy_files(pci_bus); |
81 | class_device_remove_file(&pci_bus->class_dev, | 81 | device_remove_file(&pci_bus->dev, &dev_attr_cpuaffinity); |
82 | &class_device_attr_cpuaffinity); | 82 | device_unregister(&pci_bus->dev); |
83 | sysfs_remove_link(&pci_bus->class_dev.kobj, "bridge"); | ||
84 | class_device_unregister(&pci_bus->class_dev); | ||
85 | } | 83 | } |
86 | EXPORT_SYMBOL(pci_remove_bus); | 84 | EXPORT_SYMBOL(pci_remove_bus); |
87 | 85 | ||
diff --git a/include/linux/pci.h b/include/linux/pci.h index 616f7ee8633f..4f96f1d94ac4 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -278,13 +278,13 @@ struct pci_bus { | |||
278 | unsigned short bridge_ctl; /* manage NO_ISA/FBB/et al behaviors */ | 278 | unsigned short bridge_ctl; /* manage NO_ISA/FBB/et al behaviors */ |
279 | pci_bus_flags_t bus_flags; /* Inherited by child busses */ | 279 | pci_bus_flags_t bus_flags; /* Inherited by child busses */ |
280 | struct device *bridge; | 280 | struct device *bridge; |
281 | struct class_device class_dev; | 281 | struct device dev; |
282 | struct bin_attribute *legacy_io; /* legacy I/O for this bus */ | 282 | struct bin_attribute *legacy_io; /* legacy I/O for this bus */ |
283 | struct bin_attribute *legacy_mem; /* legacy mem */ | 283 | struct bin_attribute *legacy_mem; /* legacy mem */ |
284 | }; | 284 | }; |
285 | 285 | ||
286 | #define pci_bus_b(n) list_entry(n, struct pci_bus, node) | 286 | #define pci_bus_b(n) list_entry(n, struct pci_bus, node) |
287 | #define to_pci_bus(n) container_of(n, struct pci_bus, class_dev) | 287 | #define to_pci_bus(n) container_of(n, struct pci_bus, dev) |
288 | 288 | ||
289 | /* | 289 | /* |
290 | * Error values that may be returned by PCI functions. | 290 | * Error values that may be returned by PCI functions. |