aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r--drivers/pci/hotplug/acpiphp.h5
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c127
-rw-r--r--drivers/pci/hotplug/acpiphp_ibm.c4
-rw-r--r--drivers/pci/hotplug/cpqphp_sysfs.c2
-rw-r--r--drivers/pci/hotplug/fakephp.c18
-rw-r--r--drivers/pci/hotplug/pci_hotplug.h4
-rw-r--r--drivers/pci/hotplug/pci_hotplug_core.c157
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c12
-rw-r--r--drivers/pci/hotplug/pcihp_skeleton.c9
-rw-r--r--drivers/pci/hotplug/shpchp.h2
-rw-r--r--drivers/pci/hotplug/shpchp_core.c6
-rw-r--r--drivers/pci/hotplug/shpchp_sysfs.c4
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
153struct 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
55static LIST_HEAD(bridge_list); 55static LIST_HEAD(bridge_list);
56static LIST_HEAD(ioapic_list);
57static 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
857static acpi_status
858ioapic_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
842static int acpiphp_configure_ioapics(acpi_handle handle) 902static 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
910static 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
849static int power_on_slot(struct acpiphp_slot *slot) 918static 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 */
1000int acpiphp_bus_trim(acpi_handle handle) 1069static 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
1176static 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
495module_init(ibm_acpiphp_init); 493module_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
141static int open(struct inode *inode, struct file *file) 141static 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
173extern int pci_hp_register (struct hotplug_slot *slot); 173extern int pci_hp_register (struct hotplug_slot *slot);
174extern int pci_hp_deregister (struct hotplug_slot *slot); 174extern int pci_hp_deregister (struct hotplug_slot *slot);
175extern int pci_hp_change_slot_info (struct hotplug_slot *slot, 175extern int __must_check pci_hp_change_slot_info (struct hotplug_slot *slot,
176 struct hotplug_slot_info *info); 176 struct hotplug_slot_info *info);
177extern struct subsystem pci_hotplug_slots_subsys; 177extern 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
483static int fs_add_slot (struct hotplug_slot *slot) 483static 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
544exit_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) 548exit_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; 552exit_max_speed:
553 if (has_address_file(slot) == 0)
554 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_address.attr);
555
556exit_address:
557 if (has_adapter_file(slot) == 0)
558 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
559
560exit_adapter:
561 if (has_latch_file(slot) == 0)
562 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
563
564exit_latch:
565 if (has_attention_file(slot) == 0)
566 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
567
568exit_attention:
569 if (has_power_file(slot) == 0)
570 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr);
571exit_power:
572exit:
573 return retval;
510} 574}
511 575
512static void fs_remove_slot (struct hotplug_slot *slot) 576static 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 */
629int pci_hp_change_slot_info (struct hotplug_slot *slot, struct hotplug_slot_info *info) 693int __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 */
64static int debug; 62static int debug;
65static int num_slots; 63static 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
113static int disable_slot(struct hotplug_slot *hotplug_slot) 110static 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 */
176extern void shpchp_create_ctrl_files (struct controller *ctrl); 176extern int __must_check shpchp_create_ctrl_files(struct controller *ctrl);
177 177
178extern int shpchp_sysfs_enable_slot(struct slot *slot); 178extern int shpchp_sysfs_enable_slot(struct slot *slot);
179extern int shpchp_sysfs_disable_slot(struct slot *slot); 179extern 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
458err_cleanup_slots:
459 cleanup_slots(ctrl);
456err_out_release_ctlr: 460err_out_release_ctlr:
457 ctrl->hpc_ops->release_ctlr(ctrl); 461 ctrl->hpc_ops->release_ctlr(ctrl);
458err_out_free_ctrl: 462err_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}
92static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL); 92static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL);
93 93
94void shpchp_create_ctrl_files (struct controller *ctrl) 94int __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
99void shpchp_remove_ctrl_files(struct controller *ctrl) 99void shpchp_remove_ctrl_files(struct controller *ctrl)