X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fpci%2Fhotplug%2Facpiphp_core.c;h=60c4c38047a3a63f4b308d269ddbb520c171a9e2;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=4f1b0da8e47e7bad04fa7877441244df6929004b;hpb=f7ed79d23a47594e7834d66a8f14449796d4f3e6;p=linux-2.6.git diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index 4f1b0da8e..60c4c3804 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c @@ -44,6 +44,8 @@ #include "pci_hotplug.h" #include "acpiphp.h" +static LIST_HEAD(slot_list); + #define MY_NAME "acpiphp" static int debug; @@ -339,53 +341,62 @@ static void release_slot(struct hotplug_slot *hotplug_slot) kfree(slot); } -/* callback routine to initialize 'struct slot' for each slot */ -int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot) +/** + * init_slots - initialize 'struct slot' structures for each slot + * + */ +static int __init init_slots(void) { struct slot *slot; - struct hotplug_slot *hotplug_slot; - struct hotplug_slot_info *hotplug_slot_info; int retval = -ENOMEM; - - slot = kzalloc(sizeof(*slot), GFP_KERNEL); - if (!slot) - goto error; - - slot->hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL); - if (!slot->hotplug_slot) - goto error_slot; - - slot->hotplug_slot->info = kzalloc(sizeof(*hotplug_slot_info), - GFP_KERNEL); - if (!slot->hotplug_slot->info) - goto error_hpslot; - - slot->hotplug_slot->name = kzalloc(SLOT_NAME_SIZE, GFP_KERNEL); - if (!slot->hotplug_slot->name) - goto error_info; - - slot->hotplug_slot->private = slot; - slot->hotplug_slot->release = &release_slot; - slot->hotplug_slot->ops = &acpi_hotplug_slot_ops; - - slot->acpi_slot = acpiphp_slot; - slot->hotplug_slot->info->power_status = acpiphp_get_power_status(slot->acpi_slot); - slot->hotplug_slot->info->attention_status = 0; - slot->hotplug_slot->info->latch_status = acpiphp_get_latch_status(slot->acpi_slot); - slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot); - slot->hotplug_slot->info->max_bus_speed = PCI_SPEED_UNKNOWN; - slot->hotplug_slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN; - - acpiphp_slot->slot = slot; - make_slot_name(slot); - - retval = pci_hp_register(slot->hotplug_slot); - if (retval) { - err("pci_hp_register failed with error %d\n", retval); - goto error_name; - } - - info("Slot [%s] registered\n", slot->hotplug_slot->name); + int i; + + for (i = 0; i < num_slots; ++i) { + slot = kmalloc(sizeof(struct slot), GFP_KERNEL); + if (!slot) + goto error; + memset(slot, 0, sizeof(struct slot)); + + slot->hotplug_slot = kmalloc(sizeof(struct hotplug_slot), GFP_KERNEL); + if (!slot->hotplug_slot) + goto error_slot; + memset(slot->hotplug_slot, 0, sizeof(struct hotplug_slot)); + + slot->hotplug_slot->info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL); + if (!slot->hotplug_slot->info) + goto error_hpslot; + memset(slot->hotplug_slot->info, 0, sizeof(struct hotplug_slot_info)); + + slot->hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL); + if (!slot->hotplug_slot->name) + goto error_info; + + slot->number = i; + + slot->hotplug_slot->private = slot; + slot->hotplug_slot->release = &release_slot; + slot->hotplug_slot->ops = &acpi_hotplug_slot_ops; + + slot->acpi_slot = get_slot_from_id(i); + slot->hotplug_slot->info->power_status = acpiphp_get_power_status(slot->acpi_slot); + slot->hotplug_slot->info->attention_status = 0; + slot->hotplug_slot->info->latch_status = acpiphp_get_latch_status(slot->acpi_slot); + slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot); + slot->hotplug_slot->info->max_bus_speed = PCI_SPEED_UNKNOWN; + slot->hotplug_slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN; + + make_slot_name(slot); + + retval = pci_hp_register(slot->hotplug_slot); + if (retval) { + err("pci_hp_register failed with error %d\n", retval); + goto error_name; + } + + /* add slot to our internal list */ + list_add(&slot->slot_list, &slot_list); + info("Slot [%s] registered\n", slot->hotplug_slot->name); + } return 0; error_name: @@ -401,51 +412,42 @@ error: } -void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *acpiphp_slot) +static void __exit cleanup_slots (void) { - struct slot *slot = acpiphp_slot->slot; - int retval = 0; - - info ("Slot [%s] unregistered\n", slot->hotplug_slot->name); + struct list_head *tmp, *n; + struct slot *slot; - retval = pci_hp_deregister(slot->hotplug_slot); - if (retval) - err("pci_hp_deregister failed with error %d\n", retval); + list_for_each_safe (tmp, n, &slot_list) { + /* memory will be freed in release_slot callback */ + slot = list_entry(tmp, struct slot, slot_list); + list_del(&slot->slot_list); + pci_hp_deregister(slot->hotplug_slot); + } } static int __init acpiphp_init(void) { int retval; - int docking_station; info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); acpiphp_debug = debug; - docking_station = find_dock_station(); - /* read all the ACPI info from the system */ retval = init_acpi(); - - /* if we have found a docking station, we should - * go ahead and load even if init_acpi has found - * no slots. This handles the case when the _DCK - * method not defined under the actual dock bridge - */ - if (docking_station) - return 0; - else + if (retval) return retval; + + return init_slots(); } static void __exit acpiphp_exit(void) { + cleanup_slots(); /* deallocate internal data structures etc. */ acpiphp_glue_exit(); - - remove_dock_station(); } module_init(acpiphp_init);