![Alex Chiang](/assets/img/avatar_default.png)
Currently, /sys/bus/pci/slots/ only exposes hotplug attributes when a hotplug driver is loaded, but PCI slots have attributes such as address, speed, width, etc. that are not related to hotplug at all. Introduce pci_slot as the primary data structure and kobject model. Hotplug attributes described in hotplug_slot become a secondary structure associated with the pci_slot. This patch only creates the infrastructure that allows the separation of PCI slot attributes and hotplug attributes. In this patch, the PCI hotplug core remains the only user of this infrastructure, and thus, /sys/bus/pci/slots/ will still only become populated when a hotplug driver is loaded. A later patch in this series will add a second user of this new infrastructure and demonstrate splitting the task of exposing pci_slot attributes from hotplug_slot attributes. - Make pci_slot the primary sysfs entity. hotplug_slot becomes a subsidiary structure. o pci_create_slot() creates and registers a slot with the PCI core o pci_slot_add_hotplug() gives it hotplug capability - Change the prototype of pci_hp_register() to take the bus and slot number (on parent bus) as parameters. - Remove all the ->get_address methods since this functionality is now handled by pci_slot directly. [achiang@hp.com: rpaphp-correctly-pci_hp_register-for-empty-pci-slots] Tested-by: Badari Pulavarty <pbadari@us.ibm.com> Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> [akpm@linux-foundation.org: build fix] [akpm@linux-foundation.org: make headers_check happy] [akpm@linux-foundation.org: nuther build fix] [akpm@linux-foundation.org: fix typo in #include] Signed-off-by: Alex Chiang <achiang@hp.com> Signed-off-by: Matthew Wilcox <matthew@wil.cx> Cc: Greg KH <greg@kroah.com> Cc: Kristen Carlson Accardi <kristen.c.accardi@intel.com> Cc: Len Brown <lenb@kernel.org> Acked-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
131 lines
2.8 KiB
C
131 lines
2.8 KiB
C
/*
|
|
* Interface for Dynamic Logical Partitioning of I/O Slots on
|
|
* RPA-compliant PPC64 platform.
|
|
*
|
|
* John Rose <johnrose@austin.ibm.com>
|
|
* October 2003
|
|
*
|
|
* Copyright (C) 2003 IBM.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version
|
|
* 2 of the License, or (at your option) any later version.
|
|
*/
|
|
#include <linux/kobject.h>
|
|
#include <linux/string.h>
|
|
#include <linux/pci.h>
|
|
#include <linux/pci_hotplug.h>
|
|
#include "rpadlpar.h"
|
|
#include "../pci.h"
|
|
|
|
#define DLPAR_KOBJ_NAME "control"
|
|
|
|
/* Those two have no quotes because they are passed to __ATTR() which
|
|
* stringifies the argument (yuck !)
|
|
*/
|
|
#define ADD_SLOT_ATTR_NAME add_slot
|
|
#define REMOVE_SLOT_ATTR_NAME remove_slot
|
|
|
|
#define MAX_DRC_NAME_LEN 64
|
|
|
|
static ssize_t add_slot_store(struct kobject *kobj, struct kobj_attribute *attr,
|
|
const char *buf, size_t nbytes)
|
|
{
|
|
char drc_name[MAX_DRC_NAME_LEN];
|
|
char *end;
|
|
int rc;
|
|
|
|
if (nbytes >= MAX_DRC_NAME_LEN)
|
|
return 0;
|
|
|
|
memcpy(drc_name, buf, nbytes);
|
|
|
|
end = strchr(drc_name, '\n');
|
|
if (!end)
|
|
end = &drc_name[nbytes];
|
|
*end = '\0';
|
|
|
|
rc = dlpar_add_slot(drc_name);
|
|
if (rc)
|
|
return rc;
|
|
|
|
return nbytes;
|
|
}
|
|
|
|
static ssize_t add_slot_show(struct kobject *kobj,
|
|
struct kobj_attribute *attr, char *buf)
|
|
{
|
|
return sprintf(buf, "0\n");
|
|
}
|
|
|
|
static ssize_t remove_slot_store(struct kobject *kobj,
|
|
struct kobj_attribute *attr,
|
|
const char *buf, size_t nbytes)
|
|
{
|
|
char drc_name[MAX_DRC_NAME_LEN];
|
|
int rc;
|
|
char *end;
|
|
|
|
if (nbytes >= MAX_DRC_NAME_LEN)
|
|
return 0;
|
|
|
|
memcpy(drc_name, buf, nbytes);
|
|
|
|
end = strchr(drc_name, '\n');
|
|
if (!end)
|
|
end = &drc_name[nbytes];
|
|
*end = '\0';
|
|
|
|
rc = dlpar_remove_slot(drc_name);
|
|
if (rc)
|
|
return rc;
|
|
|
|
return nbytes;
|
|
}
|
|
|
|
static ssize_t remove_slot_show(struct kobject *kobj,
|
|
struct kobj_attribute *attr, char *buf)
|
|
{
|
|
return sprintf(buf, "0\n");
|
|
}
|
|
|
|
static struct kobj_attribute add_slot_attr =
|
|
__ATTR(ADD_SLOT_ATTR_NAME, 0644, add_slot_show, add_slot_store);
|
|
|
|
static struct kobj_attribute remove_slot_attr =
|
|
__ATTR(REMOVE_SLOT_ATTR_NAME, 0644, remove_slot_show, remove_slot_store);
|
|
|
|
static struct attribute *default_attrs[] = {
|
|
&add_slot_attr.attr,
|
|
&remove_slot_attr.attr,
|
|
NULL,
|
|
};
|
|
|
|
static struct attribute_group dlpar_attr_group = {
|
|
.attrs = default_attrs,
|
|
};
|
|
|
|
static struct kobject *dlpar_kobj;
|
|
|
|
int dlpar_sysfs_init(void)
|
|
{
|
|
int error;
|
|
|
|
dlpar_kobj = kobject_create_and_add(DLPAR_KOBJ_NAME,
|
|
&pci_slots_kset->kobj);
|
|
if (!dlpar_kobj)
|
|
return -EINVAL;
|
|
|
|
error = sysfs_create_group(dlpar_kobj, &dlpar_attr_group);
|
|
if (error)
|
|
kobject_put(dlpar_kobj);
|
|
return error;
|
|
}
|
|
|
|
void dlpar_sysfs_exit(void)
|
|
{
|
|
sysfs_remove_group(dlpar_kobj, &dlpar_attr_group);
|
|
kobject_put(dlpar_kobj);
|
|
}
|