diff options
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r-- | drivers/pci/hotplug/acpiphp.h | 5 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 127 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_ibm.c | 4 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpqphp_sysfs.c | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/fakephp.c | 18 | ||||
-rw-r--r-- | drivers/pci/hotplug/pci_hotplug.h | 4 | ||||
-rw-r--r-- | drivers/pci/hotplug/pci_hotplug_core.c | 157 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_ctrl.c | 12 | ||||
-rw-r--r-- | drivers/pci/hotplug/pcihp_skeleton.c | 9 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp.h | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_core.c | 6 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_sysfs.c | 4 |
12 files changed, 276 insertions, 74 deletions
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index be104eced34c..7fff07e877c7 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h | |||
@@ -150,6 +150,11 @@ struct acpiphp_attention_info | |||
150 | struct module *owner; | 150 | struct module *owner; |
151 | }; | 151 | }; |
152 | 152 | ||
153 | struct acpiphp_ioapic { | ||
154 | struct pci_dev *dev; | ||
155 | u32 gsi_base; | ||
156 | struct list_head list; | ||
157 | }; | ||
153 | 158 | ||
154 | /* PCI bus bridge HID */ | 159 | /* PCI bus bridge HID */ |
155 | #define ACPI_PCI_HOST_HID "PNP0A03" | 160 | #define ACPI_PCI_HOST_HID "PNP0A03" |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index ae67a8f55ba1..83e8e4412de5 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -53,6 +53,8 @@ | |||
53 | #include "acpiphp.h" | 53 | #include "acpiphp.h" |
54 | 54 | ||
55 | static LIST_HEAD(bridge_list); | 55 | static LIST_HEAD(bridge_list); |
56 | static LIST_HEAD(ioapic_list); | ||
57 | static DEFINE_SPINLOCK(ioapic_list_lock); | ||
56 | 58 | ||
57 | #define MY_NAME "acpiphp_glue" | 59 | #define MY_NAME "acpiphp_glue" |
58 | 60 | ||
@@ -797,6 +799,7 @@ ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
797 | struct pci_dev *pdev; | 799 | struct pci_dev *pdev; |
798 | u32 gsi_base; | 800 | u32 gsi_base; |
799 | u64 phys_addr; | 801 | u64 phys_addr; |
802 | struct acpiphp_ioapic *ioapic; | ||
800 | 803 | ||
801 | /* Evaluate _STA if present */ | 804 | /* Evaluate _STA if present */ |
802 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); | 805 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); |
@@ -811,41 +814,107 @@ ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
811 | if (get_gsi_base(handle, &gsi_base)) | 814 | if (get_gsi_base(handle, &gsi_base)) |
812 | return AE_OK; | 815 | return AE_OK; |
813 | 816 | ||
817 | ioapic = kmalloc(sizeof(*ioapic), GFP_KERNEL); | ||
818 | if (!ioapic) | ||
819 | return AE_NO_MEMORY; | ||
820 | |||
814 | pdev = get_apic_pci_info(handle); | 821 | pdev = get_apic_pci_info(handle); |
815 | if (!pdev) | 822 | if (!pdev) |
816 | return AE_OK; | 823 | goto exit_kfree; |
817 | 824 | ||
818 | if (pci_enable_device(pdev)) { | 825 | if (pci_enable_device(pdev)) |
819 | pci_dev_put(pdev); | 826 | goto exit_pci_dev_put; |
820 | return AE_OK; | ||
821 | } | ||
822 | 827 | ||
823 | pci_set_master(pdev); | 828 | pci_set_master(pdev); |
824 | 829 | ||
825 | if (pci_request_region(pdev, 0, "I/O APIC(acpiphp)")) { | 830 | if (pci_request_region(pdev, 0, "I/O APIC(acpiphp)")) |
826 | pci_disable_device(pdev); | 831 | goto exit_pci_disable_device; |
827 | pci_dev_put(pdev); | ||
828 | return AE_OK; | ||
829 | } | ||
830 | 832 | ||
831 | phys_addr = pci_resource_start(pdev, 0); | 833 | phys_addr = pci_resource_start(pdev, 0); |
832 | if (acpi_register_ioapic(handle, phys_addr, gsi_base)) { | 834 | if (acpi_register_ioapic(handle, phys_addr, gsi_base)) |
833 | pci_release_region(pdev, 0); | 835 | goto exit_pci_release_region; |
834 | pci_disable_device(pdev); | 836 | |
835 | pci_dev_put(pdev); | 837 | ioapic->gsi_base = gsi_base; |
838 | ioapic->dev = pdev; | ||
839 | spin_lock(&ioapic_list_lock); | ||
840 | list_add_tail(&ioapic->list, &ioapic_list); | ||
841 | spin_unlock(&ioapic_list_lock); | ||
842 | |||
843 | return AE_OK; | ||
844 | |||
845 | exit_pci_release_region: | ||
846 | pci_release_region(pdev, 0); | ||
847 | exit_pci_disable_device: | ||
848 | pci_disable_device(pdev); | ||
849 | exit_pci_dev_put: | ||
850 | pci_dev_put(pdev); | ||
851 | exit_kfree: | ||
852 | kfree(ioapic); | ||
853 | |||
854 | return AE_OK; | ||
855 | } | ||
856 | |||
857 | static acpi_status | ||
858 | ioapic_remove(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
859 | { | ||
860 | acpi_status status; | ||
861 | unsigned long sta; | ||
862 | acpi_handle tmp; | ||
863 | u32 gsi_base; | ||
864 | struct acpiphp_ioapic *pos, *n, *ioapic = NULL; | ||
865 | |||
866 | /* Evaluate _STA if present */ | ||
867 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); | ||
868 | if (ACPI_SUCCESS(status) && sta != ACPI_STA_ALL) | ||
869 | return AE_CTRL_DEPTH; | ||
870 | |||
871 | /* Scan only PCI bus scope */ | ||
872 | status = acpi_get_handle(handle, "_HID", &tmp); | ||
873 | if (ACPI_SUCCESS(status)) | ||
874 | return AE_CTRL_DEPTH; | ||
875 | |||
876 | if (get_gsi_base(handle, &gsi_base)) | ||
836 | return AE_OK; | 877 | return AE_OK; |
878 | |||
879 | acpi_unregister_ioapic(handle, gsi_base); | ||
880 | |||
881 | spin_lock(&ioapic_list_lock); | ||
882 | list_for_each_entry_safe(pos, n, &ioapic_list, list) { | ||
883 | if (pos->gsi_base != gsi_base) | ||
884 | continue; | ||
885 | ioapic = pos; | ||
886 | list_del(&ioapic->list); | ||
887 | break; | ||
837 | } | 888 | } |
889 | spin_unlock(&ioapic_list_lock); | ||
890 | |||
891 | if (!ioapic) | ||
892 | return AE_OK; | ||
893 | |||
894 | pci_release_region(ioapic->dev, 0); | ||
895 | pci_disable_device(ioapic->dev); | ||
896 | pci_dev_put(ioapic->dev); | ||
897 | kfree(ioapic); | ||
838 | 898 | ||
839 | return AE_OK; | 899 | return AE_OK; |
840 | } | 900 | } |
841 | 901 | ||
842 | static int acpiphp_configure_ioapics(acpi_handle handle) | 902 | static int acpiphp_configure_ioapics(acpi_handle handle) |
843 | { | 903 | { |
904 | ioapic_add(handle, 0, NULL, NULL); | ||
844 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, | 905 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, |
845 | ACPI_UINT32_MAX, ioapic_add, NULL, NULL); | 906 | ACPI_UINT32_MAX, ioapic_add, NULL, NULL); |
846 | return 0; | 907 | return 0; |
847 | } | 908 | } |
848 | 909 | ||
910 | static int acpiphp_unconfigure_ioapics(acpi_handle handle) | ||
911 | { | ||
912 | ioapic_remove(handle, 0, NULL, NULL); | ||
913 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, | ||
914 | ACPI_UINT32_MAX, ioapic_remove, NULL, NULL); | ||
915 | return 0; | ||
916 | } | ||
917 | |||
849 | static int power_on_slot(struct acpiphp_slot *slot) | 918 | static int power_on_slot(struct acpiphp_slot *slot) |
850 | { | 919 | { |
851 | acpi_status status; | 920 | acpi_status status; |
@@ -997,7 +1066,7 @@ acpiphp_bus_add_out: | |||
997 | * @handle: handle to acpi namespace | 1066 | * @handle: handle to acpi namespace |
998 | * | 1067 | * |
999 | */ | 1068 | */ |
1000 | int acpiphp_bus_trim(acpi_handle handle) | 1069 | static int acpiphp_bus_trim(acpi_handle handle) |
1001 | { | 1070 | { |
1002 | struct acpi_device *device; | 1071 | struct acpi_device *device; |
1003 | int retval; | 1072 | int retval; |
@@ -1074,10 +1143,11 @@ static int enable_device(struct acpiphp_slot *slot) | |||
1074 | 1143 | ||
1075 | pci_bus_assign_resources(bus); | 1144 | pci_bus_assign_resources(bus); |
1076 | acpiphp_sanitize_bus(bus); | 1145 | acpiphp_sanitize_bus(bus); |
1146 | acpiphp_set_hpp_values(slot->bridge->handle, bus); | ||
1147 | list_for_each_entry(func, &slot->funcs, sibling) | ||
1148 | acpiphp_configure_ioapics(func->handle); | ||
1077 | pci_enable_bridges(bus); | 1149 | pci_enable_bridges(bus); |
1078 | pci_bus_add_devices(bus); | 1150 | pci_bus_add_devices(bus); |
1079 | acpiphp_set_hpp_values(slot->bridge->handle, bus); | ||
1080 | acpiphp_configure_ioapics(slot->bridge->handle); | ||
1081 | 1151 | ||
1082 | /* associate pci_dev to our representation */ | 1152 | /* associate pci_dev to our representation */ |
1083 | list_for_each (l, &slot->funcs) { | 1153 | list_for_each (l, &slot->funcs) { |
@@ -1103,6 +1173,16 @@ static int enable_device(struct acpiphp_slot *slot) | |||
1103 | return retval; | 1173 | return retval; |
1104 | } | 1174 | } |
1105 | 1175 | ||
1176 | static void disable_bridges(struct pci_bus *bus) | ||
1177 | { | ||
1178 | struct pci_dev *dev; | ||
1179 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
1180 | if (dev->subordinate) { | ||
1181 | disable_bridges(dev->subordinate); | ||
1182 | pci_disable_device(dev); | ||
1183 | } | ||
1184 | } | ||
1185 | } | ||
1106 | 1186 | ||
1107 | /** | 1187 | /** |
1108 | * disable_device - disable a slot | 1188 | * disable_device - disable a slot |
@@ -1127,6 +1207,19 @@ static int disable_device(struct acpiphp_slot *slot) | |||
1127 | func->bridge = NULL; | 1207 | func->bridge = NULL; |
1128 | } | 1208 | } |
1129 | 1209 | ||
1210 | if (func->pci_dev) { | ||
1211 | pci_stop_bus_device(func->pci_dev); | ||
1212 | if (func->pci_dev->subordinate) { | ||
1213 | disable_bridges(func->pci_dev->subordinate); | ||
1214 | pci_disable_device(func->pci_dev); | ||
1215 | } | ||
1216 | } | ||
1217 | } | ||
1218 | |||
1219 | list_for_each (l, &slot->funcs) { | ||
1220 | func = list_entry(l, struct acpiphp_func, sibling); | ||
1221 | |||
1222 | acpiphp_unconfigure_ioapics(func->handle); | ||
1130 | acpiphp_bus_trim(func->handle); | 1223 | acpiphp_bus_trim(func->handle); |
1131 | /* try to remove anyway. | 1224 | /* try to remove anyway. |
1132 | * acpiphp_bus_add might have been failed */ | 1225 | * acpiphp_bus_add might have been failed */ |
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index 317457dd4014..d0a07d9ab30c 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c | |||
@@ -487,9 +487,7 @@ static void __exit ibm_acpiphp_exit(void) | |||
487 | if (ACPI_FAILURE(status)) | 487 | if (ACPI_FAILURE(status)) |
488 | err("%s: Notification handler removal failed\n", __FUNCTION__); | 488 | err("%s: Notification handler removal failed\n", __FUNCTION__); |
489 | /* remove the /sys entries */ | 489 | /* remove the /sys entries */ |
490 | if (sysfs_remove_bin_file(sysdir, &ibm_apci_table_attr)) | 490 | sysfs_remove_bin_file(sysdir, &ibm_apci_table_attr); |
491 | err("%s: removal of sysfs file apci_table failed\n", | ||
492 | __FUNCTION__); | ||
493 | } | 491 | } |
494 | 492 | ||
495 | module_init(ibm_acpiphp_init); | 493 | module_init(ibm_acpiphp_init); |
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c index 8b3da007e859..5bab666cd67e 100644 --- a/drivers/pci/hotplug/cpqphp_sysfs.c +++ b/drivers/pci/hotplug/cpqphp_sysfs.c | |||
@@ -140,7 +140,7 @@ struct ctrl_dbg { | |||
140 | 140 | ||
141 | static int open(struct inode *inode, struct file *file) | 141 | static int open(struct inode *inode, struct file *file) |
142 | { | 142 | { |
143 | struct controller *ctrl = inode->u.generic_ip; | 143 | struct controller *ctrl = inode->i_private; |
144 | struct ctrl_dbg *dbg; | 144 | struct ctrl_dbg *dbg; |
145 | int retval = -ENOMEM; | 145 | int retval = -ENOMEM; |
146 | 146 | ||
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c index dd2b762777c4..05a4f0f90186 100644 --- a/drivers/pci/hotplug/fakephp.c +++ b/drivers/pci/hotplug/fakephp.c | |||
@@ -176,7 +176,9 @@ static void pci_rescan_slot(struct pci_dev *temp) | |||
176 | struct pci_bus *bus = temp->bus; | 176 | struct pci_bus *bus = temp->bus; |
177 | struct pci_dev *dev; | 177 | struct pci_dev *dev; |
178 | int func; | 178 | int func; |
179 | int retval; | ||
179 | u8 hdr_type; | 180 | u8 hdr_type; |
181 | |||
180 | if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) { | 182 | if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) { |
181 | temp->hdr_type = hdr_type & 0x7f; | 183 | temp->hdr_type = hdr_type & 0x7f; |
182 | if (!pci_find_slot(bus->number, temp->devfn)) { | 184 | if (!pci_find_slot(bus->number, temp->devfn)) { |
@@ -185,8 +187,12 @@ static void pci_rescan_slot(struct pci_dev *temp) | |||
185 | dbg("New device on %s function %x:%x\n", | 187 | dbg("New device on %s function %x:%x\n", |
186 | bus->name, temp->devfn >> 3, | 188 | bus->name, temp->devfn >> 3, |
187 | temp->devfn & 7); | 189 | temp->devfn & 7); |
188 | pci_bus_add_device(dev); | 190 | retval = pci_bus_add_device(dev); |
189 | add_slot(dev); | 191 | if (retval) |
192 | dev_err(&dev->dev, "error adding " | ||
193 | "device, continuing.\n"); | ||
194 | else | ||
195 | add_slot(dev); | ||
190 | } | 196 | } |
191 | } | 197 | } |
192 | /* multifunction device? */ | 198 | /* multifunction device? */ |
@@ -205,8 +211,12 @@ static void pci_rescan_slot(struct pci_dev *temp) | |||
205 | dbg("New device on %s function %x:%x\n", | 211 | dbg("New device on %s function %x:%x\n", |
206 | bus->name, temp->devfn >> 3, | 212 | bus->name, temp->devfn >> 3, |
207 | temp->devfn & 7); | 213 | temp->devfn & 7); |
208 | pci_bus_add_device(dev); | 214 | retval = pci_bus_add_device(dev); |
209 | add_slot(dev); | 215 | if (retval) |
216 | dev_err(&dev->dev, "error adding " | ||
217 | "device, continuing.\n"); | ||
218 | else | ||
219 | add_slot(dev); | ||
210 | } | 220 | } |
211 | } | 221 | } |
212 | } | 222 | } |
diff --git a/drivers/pci/hotplug/pci_hotplug.h b/drivers/pci/hotplug/pci_hotplug.h index e929b7c11429..772523dc3860 100644 --- a/drivers/pci/hotplug/pci_hotplug.h +++ b/drivers/pci/hotplug/pci_hotplug.h | |||
@@ -172,8 +172,8 @@ struct hotplug_slot { | |||
172 | 172 | ||
173 | extern int pci_hp_register (struct hotplug_slot *slot); | 173 | extern int pci_hp_register (struct hotplug_slot *slot); |
174 | extern int pci_hp_deregister (struct hotplug_slot *slot); | 174 | extern int pci_hp_deregister (struct hotplug_slot *slot); |
175 | extern int pci_hp_change_slot_info (struct hotplug_slot *slot, | 175 | extern int __must_check pci_hp_change_slot_info (struct hotplug_slot *slot, |
176 | struct hotplug_slot_info *info); | 176 | struct hotplug_slot_info *info); |
177 | extern struct subsystem pci_hotplug_slots_subsys; | 177 | extern struct subsystem pci_hotplug_slots_subsys; |
178 | 178 | ||
179 | /* PCI Setting Record (Type 0) */ | 179 | /* PCI Setting Record (Type 0) */ |
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index b7b378df89e3..e2823ea9c4ed 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c | |||
@@ -482,31 +482,95 @@ static int has_test_file (struct hotplug_slot *slot) | |||
482 | 482 | ||
483 | static int fs_add_slot (struct hotplug_slot *slot) | 483 | static int fs_add_slot (struct hotplug_slot *slot) |
484 | { | 484 | { |
485 | if (has_power_file(slot) == 0) | 485 | int retval = 0; |
486 | sysfs_create_file(&slot->kobj, &hotplug_slot_attr_power.attr); | ||
487 | 486 | ||
488 | if (has_attention_file(slot) == 0) | 487 | if (has_power_file(slot) == 0) { |
489 | sysfs_create_file(&slot->kobj, &hotplug_slot_attr_attention.attr); | 488 | retval = sysfs_create_file(&slot->kobj, &hotplug_slot_attr_power.attr); |
489 | if (retval) | ||
490 | goto exit_power; | ||
491 | } | ||
490 | 492 | ||
491 | if (has_latch_file(slot) == 0) | 493 | if (has_attention_file(slot) == 0) { |
492 | sysfs_create_file(&slot->kobj, &hotplug_slot_attr_latch.attr); | 494 | retval = sysfs_create_file(&slot->kobj, |
495 | &hotplug_slot_attr_attention.attr); | ||
496 | if (retval) | ||
497 | goto exit_attention; | ||
498 | } | ||
493 | 499 | ||
494 | if (has_adapter_file(slot) == 0) | 500 | if (has_latch_file(slot) == 0) { |
495 | sysfs_create_file(&slot->kobj, &hotplug_slot_attr_presence.attr); | 501 | retval = sysfs_create_file(&slot->kobj, |
502 | &hotplug_slot_attr_latch.attr); | ||
503 | if (retval) | ||
504 | goto exit_latch; | ||
505 | } | ||
496 | 506 | ||
497 | if (has_address_file(slot) == 0) | 507 | if (has_adapter_file(slot) == 0) { |
498 | sysfs_create_file(&slot->kobj, &hotplug_slot_attr_address.attr); | 508 | retval = sysfs_create_file(&slot->kobj, |
509 | &hotplug_slot_attr_presence.attr); | ||
510 | if (retval) | ||
511 | goto exit_adapter; | ||
512 | } | ||
499 | 513 | ||
500 | if (has_max_bus_speed_file(slot) == 0) | 514 | if (has_address_file(slot) == 0) { |
501 | sysfs_create_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr); | 515 | retval = sysfs_create_file(&slot->kobj, |
516 | &hotplug_slot_attr_address.attr); | ||
517 | if (retval) | ||
518 | goto exit_address; | ||
519 | } | ||
502 | 520 | ||
521 | if (has_max_bus_speed_file(slot) == 0) { | ||
522 | retval = sysfs_create_file(&slot->kobj, | ||
523 | &hotplug_slot_attr_max_bus_speed.attr); | ||
524 | if (retval) | ||
525 | goto exit_max_speed; | ||
526 | } | ||
527 | |||
528 | if (has_cur_bus_speed_file(slot) == 0) { | ||
529 | retval = sysfs_create_file(&slot->kobj, | ||
530 | &hotplug_slot_attr_cur_bus_speed.attr); | ||
531 | if (retval) | ||
532 | goto exit_cur_speed; | ||
533 | } | ||
534 | |||
535 | if (has_test_file(slot) == 0) { | ||
536 | retval = sysfs_create_file(&slot->kobj, | ||
537 | &hotplug_slot_attr_test.attr); | ||
538 | if (retval) | ||
539 | goto exit_test; | ||
540 | } | ||
541 | |||
542 | goto exit; | ||
543 | |||
544 | exit_test: | ||
503 | if (has_cur_bus_speed_file(slot) == 0) | 545 | if (has_cur_bus_speed_file(slot) == 0) |
504 | sysfs_create_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr); | 546 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr); |
505 | 547 | ||
506 | if (has_test_file(slot) == 0) | 548 | exit_cur_speed: |
507 | sysfs_create_file(&slot->kobj, &hotplug_slot_attr_test.attr); | 549 | if (has_max_bus_speed_file(slot) == 0) |
550 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr); | ||
508 | 551 | ||
509 | return 0; | 552 | exit_max_speed: |
553 | if (has_address_file(slot) == 0) | ||
554 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_address.attr); | ||
555 | |||
556 | exit_address: | ||
557 | if (has_adapter_file(slot) == 0) | ||
558 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_presence.attr); | ||
559 | |||
560 | exit_adapter: | ||
561 | if (has_latch_file(slot) == 0) | ||
562 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr); | ||
563 | |||
564 | exit_latch: | ||
565 | if (has_attention_file(slot) == 0) | ||
566 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_attention.attr); | ||
567 | |||
568 | exit_attention: | ||
569 | if (has_power_file(slot) == 0) | ||
570 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr); | ||
571 | exit_power: | ||
572 | exit: | ||
573 | return retval; | ||
510 | } | 574 | } |
511 | 575 | ||
512 | static void fs_remove_slot (struct hotplug_slot *slot) | 576 | static void fs_remove_slot (struct hotplug_slot *slot) |
@@ -626,8 +690,11 @@ int pci_hp_deregister (struct hotplug_slot *slot) | |||
626 | * | 690 | * |
627 | * Returns 0 if successful, anything else for an error. | 691 | * Returns 0 if successful, anything else for an error. |
628 | */ | 692 | */ |
629 | int pci_hp_change_slot_info (struct hotplug_slot *slot, struct hotplug_slot_info *info) | 693 | int __must_check pci_hp_change_slot_info(struct hotplug_slot *slot, |
694 | struct hotplug_slot_info *info) | ||
630 | { | 695 | { |
696 | int retval; | ||
697 | |||
631 | if ((slot == NULL) || (info == NULL)) | 698 | if ((slot == NULL) || (info == NULL)) |
632 | return -ENODEV; | 699 | return -ENODEV; |
633 | 700 | ||
@@ -636,32 +703,60 @@ int pci_hp_change_slot_info (struct hotplug_slot *slot, struct hotplug_slot_info | |||
636 | * for the files referring to the fields that have now changed. | 703 | * for the files referring to the fields that have now changed. |
637 | */ | 704 | */ |
638 | if ((has_power_file(slot) == 0) && | 705 | if ((has_power_file(slot) == 0) && |
639 | (slot->info->power_status != info->power_status)) | 706 | (slot->info->power_status != info->power_status)) { |
640 | sysfs_update_file(&slot->kobj, &hotplug_slot_attr_power.attr); | 707 | retval = sysfs_update_file(&slot->kobj, |
708 | &hotplug_slot_attr_power.attr); | ||
709 | if (retval) | ||
710 | return retval; | ||
711 | } | ||
641 | 712 | ||
642 | if ((has_attention_file(slot) == 0) && | 713 | if ((has_attention_file(slot) == 0) && |
643 | (slot->info->attention_status != info->attention_status)) | 714 | (slot->info->attention_status != info->attention_status)) { |
644 | sysfs_update_file(&slot->kobj, &hotplug_slot_attr_attention.attr); | 715 | retval = sysfs_update_file(&slot->kobj, |
716 | &hotplug_slot_attr_attention.attr); | ||
717 | if (retval) | ||
718 | return retval; | ||
719 | } | ||
645 | 720 | ||
646 | if ((has_latch_file(slot) == 0) && | 721 | if ((has_latch_file(slot) == 0) && |
647 | (slot->info->latch_status != info->latch_status)) | 722 | (slot->info->latch_status != info->latch_status)) { |
648 | sysfs_update_file(&slot->kobj, &hotplug_slot_attr_latch.attr); | 723 | retval = sysfs_update_file(&slot->kobj, |
724 | &hotplug_slot_attr_latch.attr); | ||
725 | if (retval) | ||
726 | return retval; | ||
727 | } | ||
649 | 728 | ||
650 | if ((has_adapter_file(slot) == 0) && | 729 | if ((has_adapter_file(slot) == 0) && |
651 | (slot->info->adapter_status != info->adapter_status)) | 730 | (slot->info->adapter_status != info->adapter_status)) { |
652 | sysfs_update_file(&slot->kobj, &hotplug_slot_attr_presence.attr); | 731 | retval = sysfs_update_file(&slot->kobj, |
732 | &hotplug_slot_attr_presence.attr); | ||
733 | if (retval) | ||
734 | return retval; | ||
735 | } | ||
653 | 736 | ||
654 | if ((has_address_file(slot) == 0) && | 737 | if ((has_address_file(slot) == 0) && |
655 | (slot->info->address != info->address)) | 738 | (slot->info->address != info->address)) { |
656 | sysfs_update_file(&slot->kobj, &hotplug_slot_attr_address.attr); | 739 | retval = sysfs_update_file(&slot->kobj, |
740 | &hotplug_slot_attr_address.attr); | ||
741 | if (retval) | ||
742 | return retval; | ||
743 | } | ||
657 | 744 | ||
658 | if ((has_max_bus_speed_file(slot) == 0) && | 745 | if ((has_max_bus_speed_file(slot) == 0) && |
659 | (slot->info->max_bus_speed != info->max_bus_speed)) | 746 | (slot->info->max_bus_speed != info->max_bus_speed)) { |
660 | sysfs_update_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr); | 747 | retval = sysfs_update_file(&slot->kobj, |
748 | &hotplug_slot_attr_max_bus_speed.attr); | ||
749 | if (retval) | ||
750 | return retval; | ||
751 | } | ||
661 | 752 | ||
662 | if ((has_cur_bus_speed_file(slot) == 0) && | 753 | if ((has_cur_bus_speed_file(slot) == 0) && |
663 | (slot->info->cur_bus_speed != info->cur_bus_speed)) | 754 | (slot->info->cur_bus_speed != info->cur_bus_speed)) { |
664 | sysfs_update_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr); | 755 | retval = sysfs_update_file(&slot->kobj, |
756 | &hotplug_slot_attr_cur_bus_speed.attr); | ||
757 | if (retval) | ||
758 | return retval; | ||
759 | } | ||
665 | 760 | ||
666 | memcpy (slot->info, info, sizeof (struct hotplug_slot_info)); | 761 | memcpy (slot->info, info, sizeof (struct hotplug_slot_info)); |
667 | 762 | ||
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 33d198768356..41290a106bd8 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
@@ -762,14 +762,14 @@ int pciehp_enable_slot(struct slot *p_slot) | |||
762 | if (rc || !getstatus) { | 762 | if (rc || !getstatus) { |
763 | info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); | 763 | info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); |
764 | mutex_unlock(&p_slot->ctrl->crit_sect); | 764 | mutex_unlock(&p_slot->ctrl->crit_sect); |
765 | return 1; | 765 | return -ENODEV; |
766 | } | 766 | } |
767 | if (MRL_SENS(p_slot->ctrl->ctrlcap)) { | 767 | if (MRL_SENS(p_slot->ctrl->ctrlcap)) { |
768 | rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); | 768 | rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); |
769 | if (rc || getstatus) { | 769 | if (rc || getstatus) { |
770 | info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); | 770 | info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); |
771 | mutex_unlock(&p_slot->ctrl->crit_sect); | 771 | mutex_unlock(&p_slot->ctrl->crit_sect); |
772 | return 1; | 772 | return -ENODEV; |
773 | } | 773 | } |
774 | } | 774 | } |
775 | 775 | ||
@@ -778,7 +778,7 @@ int pciehp_enable_slot(struct slot *p_slot) | |||
778 | if (rc || getstatus) { | 778 | if (rc || getstatus) { |
779 | info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); | 779 | info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); |
780 | mutex_unlock(&p_slot->ctrl->crit_sect); | 780 | mutex_unlock(&p_slot->ctrl->crit_sect); |
781 | return 1; | 781 | return -EINVAL; |
782 | } | 782 | } |
783 | } | 783 | } |
784 | mutex_unlock(&p_slot->ctrl->crit_sect); | 784 | mutex_unlock(&p_slot->ctrl->crit_sect); |
@@ -813,7 +813,7 @@ int pciehp_disable_slot(struct slot *p_slot) | |||
813 | if (ret || !getstatus) { | 813 | if (ret || !getstatus) { |
814 | info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); | 814 | info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); |
815 | mutex_unlock(&p_slot->ctrl->crit_sect); | 815 | mutex_unlock(&p_slot->ctrl->crit_sect); |
816 | return 1; | 816 | return -ENODEV; |
817 | } | 817 | } |
818 | } | 818 | } |
819 | 819 | ||
@@ -822,7 +822,7 @@ int pciehp_disable_slot(struct slot *p_slot) | |||
822 | if (ret || getstatus) { | 822 | if (ret || getstatus) { |
823 | info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); | 823 | info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); |
824 | mutex_unlock(&p_slot->ctrl->crit_sect); | 824 | mutex_unlock(&p_slot->ctrl->crit_sect); |
825 | return 1; | 825 | return -ENODEV; |
826 | } | 826 | } |
827 | } | 827 | } |
828 | 828 | ||
@@ -831,7 +831,7 @@ int pciehp_disable_slot(struct slot *p_slot) | |||
831 | if (ret || !getstatus) { | 831 | if (ret || !getstatus) { |
832 | info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); | 832 | info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); |
833 | mutex_unlock(&p_slot->ctrl->crit_sect); | 833 | mutex_unlock(&p_slot->ctrl->crit_sect); |
834 | return 1; | 834 | return -EINVAL; |
835 | } | 835 | } |
836 | } | 836 | } |
837 | 837 | ||
diff --git a/drivers/pci/hotplug/pcihp_skeleton.c b/drivers/pci/hotplug/pcihp_skeleton.c index 8ad446605f75..2b9e10e38613 100644 --- a/drivers/pci/hotplug/pcihp_skeleton.c +++ b/drivers/pci/hotplug/pcihp_skeleton.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * PCI Hot Plug Controller Skeleton Driver - 0.2 | 2 | * PCI Hot Plug Controller Skeleton Driver - 0.3 |
3 | * | 3 | * |
4 | * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com) | 4 | * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com) |
5 | * Copyright (C) 2001,2003 IBM Corp. | 5 | * Copyright (C) 2001,2003 IBM Corp. |
@@ -21,7 +21,7 @@ | |||
21 | * along with this program; if not, write to the Free Software | 21 | * along with this program; if not, write to the Free Software |
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
23 | * | 23 | * |
24 | * This driver is to be used as a skeleton driver to be show how to interface | 24 | * This driver is to be used as a skeleton driver to show how to interface |
25 | * with the pci hotplug core easily. | 25 | * with the pci hotplug core easily. |
26 | * | 26 | * |
27 | * Send feedback to <greg@kroah.com> | 27 | * Send feedback to <greg@kroah.com> |
@@ -58,8 +58,6 @@ static LIST_HEAD(slot_list); | |||
58 | #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) | 58 | #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) |
59 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) | 59 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) |
60 | 60 | ||
61 | |||
62 | |||
63 | /* local variables */ | 61 | /* local variables */ |
64 | static int debug; | 62 | static int debug; |
65 | static int num_slots; | 63 | static int num_slots; |
@@ -109,7 +107,6 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) | |||
109 | return retval; | 107 | return retval; |
110 | } | 108 | } |
111 | 109 | ||
112 | |||
113 | static int disable_slot(struct hotplug_slot *hotplug_slot) | 110 | static int disable_slot(struct hotplug_slot *hotplug_slot) |
114 | { | 111 | { |
115 | struct slot *slot = hotplug_slot->private; | 112 | struct slot *slot = hotplug_slot->private; |
@@ -342,7 +339,7 @@ static int __init pcihp_skel_init(void) | |||
342 | info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); | 339 | info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); |
343 | /* | 340 | /* |
344 | * Do specific initialization stuff for your driver here | 341 | * Do specific initialization stuff for your driver here |
345 | * Like initializing your controller hardware (if any) and | 342 | * like initializing your controller hardware (if any) and |
346 | * determining the number of slots you have in the system | 343 | * determining the number of slots you have in the system |
347 | * right now. | 344 | * right now. |
348 | */ | 345 | */ |
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index 7208b95c6ee7..c7103ac5cd06 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h | |||
@@ -173,7 +173,7 @@ struct controller { | |||
173 | #define msg_button_cancel "PCI slot #%s - action canceled due to button press.\n" | 173 | #define msg_button_cancel "PCI slot #%s - action canceled due to button press.\n" |
174 | 174 | ||
175 | /* sysfs functions for the hotplug controller info */ | 175 | /* sysfs functions for the hotplug controller info */ |
176 | extern void shpchp_create_ctrl_files (struct controller *ctrl); | 176 | extern int __must_check shpchp_create_ctrl_files(struct controller *ctrl); |
177 | 177 | ||
178 | extern int shpchp_sysfs_enable_slot(struct slot *slot); | 178 | extern int shpchp_sysfs_enable_slot(struct slot *slot); |
179 | extern int shpchp_sysfs_disable_slot(struct slot *slot); | 179 | extern int shpchp_sysfs_disable_slot(struct slot *slot); |
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index a14e7de19846..235c18a22393 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c | |||
@@ -449,10 +449,14 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
449 | ctrl->speed = PCI_SPEED_33MHz; | 449 | ctrl->speed = PCI_SPEED_33MHz; |
450 | } | 450 | } |
451 | 451 | ||
452 | shpchp_create_ctrl_files(ctrl); | 452 | rc = shpchp_create_ctrl_files(ctrl); |
453 | if (rc) | ||
454 | goto err_cleanup_slots; | ||
453 | 455 | ||
454 | return 0; | 456 | return 0; |
455 | 457 | ||
458 | err_cleanup_slots: | ||
459 | cleanup_slots(ctrl); | ||
456 | err_out_release_ctlr: | 460 | err_out_release_ctlr: |
457 | ctrl->hpc_ops->release_ctlr(ctrl); | 461 | ctrl->hpc_ops->release_ctlr(ctrl); |
458 | err_out_free_ctrl: | 462 | err_out_free_ctrl: |
diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c index 620e1139e607..29fa9d26adae 100644 --- a/drivers/pci/hotplug/shpchp_sysfs.c +++ b/drivers/pci/hotplug/shpchp_sysfs.c | |||
@@ -91,9 +91,9 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha | |||
91 | } | 91 | } |
92 | static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL); | 92 | static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL); |
93 | 93 | ||
94 | void shpchp_create_ctrl_files (struct controller *ctrl) | 94 | int __must_check shpchp_create_ctrl_files (struct controller *ctrl) |
95 | { | 95 | { |
96 | device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl); | 96 | return device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl); |
97 | } | 97 | } |
98 | 98 | ||
99 | void shpchp_remove_ctrl_files(struct controller *ctrl) | 99 | void shpchp_remove_ctrl_files(struct controller *ctrl) |