diff -Nru a/drivers/pci/hotplug/pci_hotplug.h b/drivers/pci/hotplug/pci_hotplug.h --- a/drivers/pci/hotplug/pci_hotplug.h Fri Apr 9 21:22:01 2004 +++ b/drivers/pci/hotplug/pci_hotplug.h Fri Apr 9 21:22:01 2004 @@ -98,6 +98,9 @@ * @get_address: Called to get pci address of a slot. * If this field is NULL, the value passed in the struct hotplug_slot_info * will be used when this value is requested by a user. + * @get_location: Called to get the physical location of a slot. + * If this field is NULL, the value passed in the struct hotplug_slot_info + * will be used when this value is requested by a user. * @get_max_bus_speed: Called to get the max bus speed for a slot. * If this field is NULL, the value passed in the struct hotplug_slot_info * will be used when this value is requested by a user. @@ -121,6 +124,7 @@ int (*get_latch_status) (struct hotplug_slot *slot, u8 *value); int (*get_adapter_status) (struct hotplug_slot *slot, u8 *value); int (*get_address) (struct hotplug_slot *slot, u32 *value); + int (*get_location) (struct hotplug_slot *slot, char *value); int (*get_max_bus_speed) (struct hotplug_slot *slot, enum pci_bus_speed *value); int (*get_cur_bus_speed) (struct hotplug_slot *slot, enum pci_bus_speed *value); }; @@ -141,6 +145,7 @@ u8 latch_status; u8 adapter_status; u32 address; + char *location; enum pci_bus_speed max_bus_speed; enum pci_bus_speed cur_bus_speed; }; diff -Nru a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c --- a/drivers/pci/hotplug/pci_hotplug_core.c Fri Apr 9 21:22:01 2004 +++ b/drivers/pci/hotplug/pci_hotplug_core.c Fri Apr 9 21:22:02 2004 @@ -163,6 +163,16 @@ GET_STATUS(max_bus_speed, enum pci_bus_speed) GET_STATUS(cur_bus_speed, enum pci_bus_speed) +static ssize_t location_read_file (struct hotplug_slot *slot, char *buf) +{ + char *value; + int retval = 0; + + value = slot->info->location; + retval = sprintf (buf, "%s\n", value); + return retval; +} + static ssize_t power_read_file (struct hotplug_slot *slot, char *buf) { int retval; @@ -214,6 +224,11 @@ return count; } +static struct hotplug_slot_attribute hotplug_slot_attr_location = { + .attr = {.name = "phy_location", .mode = S_IFREG | S_IRUGO}, + .show = location_read_file, +}; + static struct hotplug_slot_attribute hotplug_slot_attr_power = { .attr = {.name = "power", .mode = S_IFREG | S_IRUGO | S_IWUSR}, .show = power_read_file, @@ -409,6 +424,15 @@ .store = test_write_file }; +static int has_location_file(struct hotplug_slot *slot) +{ + if ((!slot) || (!slot->ops)) + return -ENODEV; + if(slot->ops->get_location) + return 0; + return -ENOENT; +} + static int has_power_file (struct hotplug_slot *slot) { if ((!slot) || (!slot->ops)) @@ -486,6 +510,9 @@ static int fs_add_slot (struct hotplug_slot *slot) { + if (has_location_file(slot) == 0) + sysfs_create_file(&slot->kobj, &hotplug_slot_attr_location.attr); + if (has_power_file(slot) == 0) sysfs_create_file(&slot->kobj, &hotplug_slot_attr_power.attr); @@ -515,6 +542,9 @@ static void fs_remove_slot (struct hotplug_slot *slot) { + if (has_location_file(slot) == 0) + sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_location.attr); + if (has_power_file(slot) == 0) sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr); @@ -609,9 +639,20 @@ } list_del (&slot->slot_list); fs_remove_slot (slot); dbg ("Removed slot %s from the list\n", slot->name); kobject_unregister(&slot->kobj); return 0; } @@ -634,6 +675,10 @@ * check all fields in the info structure, and update timestamps * for the files referring to the fields that have now changed. */ + if ((has_location_file(slot) == 0) && + (slot->info->location != info->location)) + sysfs_update_file(&slot->kobj, &hotplug_slot_attr_location.attr); + if ((has_power_file(slot) == 0) && (slot->info->power_status != info->power_status)) sysfs_update_file(&slot->kobj, &hotplug_slot_attr_power.attr); diff -Nru a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c --- a/drivers/pci/hotplug/rpadlpar_core.c Fri Apr 9 21:22:01 2004 +++ b/drivers/pci/hotplug/rpadlpar_core.c Fri Apr 9 21:22:01 2004 @@ -79,25 +79,18 @@ return np; } -static inline struct hotplug_slot *find_php_slot(char *drc_name) -{ - struct kobject *k; - - k = kset_find_obj(&pci_hotplug_slots_subsys.kset, drc_name); - if (!k) - return NULL; - - return to_hotplug_slot(k); -} - static struct slot *find_slot(char *drc_name) { - struct hotplug_slot *php_slot = find_php_slot(drc_name); + struct list_head *tmp, *n; + struct slot *slot; - if (!php_slot) - return NULL; + list_for_each_safe(tmp, n, &rpaphp_slot_head) { + slot = list_entry(tmp, struct slot, rpaphp_slot_list); + if (strcmp(slot->location, drc_name) == 0) + return slot; + } - return (struct slot *) php_slot->private; + return NULL; } static void rpadlpar_claim_one_bus(struct pci_bus *b) diff -Nru a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h --- a/drivers/pci/hotplug/rpaphp.h Fri Apr 9 21:22:01 2004 +++ b/drivers/pci/hotplug/rpaphp.h Fri Apr 9 21:22:01 2004 @@ -85,6 +85,7 @@ u32 type; u32 power_domain; char *name; + char *location; struct device_node *dn; /* slot's device_node in OFDT */ /* dn has phb info */ struct pci_dev *bridge; /* slot's pci_dev in pci_devices */ diff -Nru a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c --- a/drivers/pci/hotplug/rpaphp_core.c Fri Apr 9 21:22:02 2004 +++ b/drivers/pci/hotplug/rpaphp_core.c Fri Apr 9 21:22:02 2004 @@ -67,6 +67,7 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value); static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value); static int rpaphp_disable_slot(struct pci_dev *dev); +static int get_location(struct hotplug_slot *hotplug_slot, char *value); struct hotplug_slot_ops rpaphp_hotplug_slot_ops = { .owner = THIS_MODULE, @@ -78,6 +79,7 @@ .get_adapter_status = get_adapter_status, .get_max_bus_speed = get_max_bus_speed, .get_cur_bus_speed = get_cur_bus_speed, + .get_location = get_location, }; static inline struct slot *get_slot (struct hotplug_slot *hotplug_slot, const char *function) @@ -89,6 +91,12 @@ return (struct slot *)hotplug_slot->private; } +/* without this function, PHP core won't create "phy_location" entry */ +static int get_location(struct hotplug_slot *hotplug_slot, char *value) +{ + return 0; +} + static int rpaphp_get_attention_status(struct slot *slot) { return slot->hotplug_slot->info->attention_status; @@ -249,15 +257,7 @@ int rpaphp_remove_slot(struct slot *slot) { int retval = 0; - char *rm_link; - dbg("%s - Entry: slot[%s]\n", __FUNCTION__, slot->name); - if (slot->dev_type == PCI_DEV) - rm_link = pci_name(slot->bridge); - else - rm_link = strstr(slot->dn->full_name, "@"); - - sysfs_remove_link(slot->hotplug_slot->kobj.parent, rm_link); list_del(&slot->rpaphp_slot_list); retval = pci_hp_deregister(slot->hotplug_slot); if (retval) @@ -383,14 +383,7 @@ */ list_for_each_safe(tmp, n, &rpaphp_slot_head) { - char *rm_link; - slot = list_entry(tmp, struct slot, rpaphp_slot_list); - if (slot->dev_type == PCI_DEV) - rm_link = pci_name(slot->bridge); - else - rm_link = strstr(slot->dn->full_name, "@"); - sysfs_remove_link(slot->hotplug_slot->kobj.parent, rm_link); list_del(&slot->rpaphp_slot_list); pci_hp_deregister(slot->hotplug_slot); } @@ -492,3 +485,4 @@ EXPORT_SYMBOL_GPL(rpaphp_add_slot); EXPORT_SYMBOL_GPL(rpaphp_remove_slot); +EXPORT_SYMBOL_GPL(rpaphp_slot_head); diff -Nru a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c --- a/drivers/pci/hotplug/rpaphp_pci.c Fri Apr 9 21:22:01 2004 +++ b/drivers/pci/hotplug/rpaphp_pci.c Fri Apr 9 21:22:01 2004 @@ -318,7 +318,7 @@ dealloc_slot_struct(slot); return 1; } - + strcpy(slot->name, pci_name(slot->bridge)); /* find slot's pci_dev if it's not empty */ if (slot->hotplug_slot->info->adapter_status == EMPTY) { slot->state = EMPTY; /* slot is empty */ diff -Nru a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c --- a/drivers/pci/hotplug/rpaphp_slot.c Fri Apr 9 21:22:01 2004 +++ b/drivers/pci/hotplug/rpaphp_slot.c Fri Apr 9 21:22:01 2004 @@ -43,6 +43,7 @@ void dealloc_slot_struct(struct slot *slot) { + kfree(slot->hotplug_slot->info->location); kfree(slot->hotplug_slot->info); kfree(slot->hotplug_slot->name); kfree(slot->hotplug_slot); @@ -76,17 +77,26 @@ return (NULL); } memset(slot->hotplug_slot->info, 0, sizeof (struct hotplug_slot_info)); - slot->hotplug_slot->name = kmalloc(strlen(drc_name) + 1, GFP_KERNEL); + slot->hotplug_slot->name = kmalloc(BUS_ID_SIZE + 1, GFP_KERNEL); if (!slot->hotplug_slot->name) { kfree(slot->hotplug_slot->info); kfree(slot->hotplug_slot); kfree(slot); return (NULL); } + slot->location = kmalloc(strlen(drc_name) + 1, GFP_KERNEL); + if (!slot->location) { + kfree(slot->hotplug_slot->info); + kfree(slot->hotplug_slot->name); + kfree(slot->hotplug_slot); + kfree(slot); + return (NULL); + } + slot->hotplug_slot->info->location = slot->location; slot->name = slot->hotplug_slot->name; slot->dn = dn; slot->index = drc_index; - strcpy(slot->name, drc_name); + strcpy(slot->location, drc_name); slot->power_domain = power_domain; slot->magic = SLOT_MAGIC; slot->hotplug_slot->private = slot; @@ -109,41 +119,6 @@ err("pci_hp_register failed with error %d\n", retval); rpaphp_release_slot(slot->hotplug_slot); return (retval); - } - switch (slot->dev_type) { - case PCI_DEV: - /* create symlink between slot->name and it's bus_id */ - - dbg("%s: sysfs_create_link: %s --> %s\n", __FUNCTION__, - pci_name(slot->bridge), slot->name); - - retval = sysfs_create_link(slot->hotplug_slot->kobj.parent, - &slot->hotplug_slot->kobj, - pci_name(slot->bridge)); - if (retval) { - err("sysfs_create_link failed with error %d\n", retval); - rpaphp_release_slot(slot->hotplug_slot); - return (retval); - } - break; - case VIO_DEV: - /* create symlink between slot->name and it's uni-address */ - vio_uni_addr = strchr(slot->dn->full_name, '@'); - if (!vio_uni_addr) - return (1); - dbg("%s: sysfs_create_link: %s --> %s\n", __FUNCTION__, - vio_uni_addr, slot->name); - retval = sysfs_create_link(slot->hotplug_slot->kobj.parent, - &slot->hotplug_slot->kobj, - vio_uni_addr); - if (retval) { - err("sysfs_create_link failed with error %d\n", retval); - rpaphp_release_slot(slot->hotplug_slot); - return (retval); - } - break; - default: - return (1); } /* add slot to our internal list */