Skip to content

Commit

Permalink
[PATCH] PCI Hotplug: rpaphp: Move VIO registration
Browse files Browse the repository at this point in the history
Currently, rpaphp registers Virtual I/O slots as hotplug slots.  The
only purpose of this registration is to ensure that the VIO subsystem
is notified of new VIO buses during DLPAR adds.  Similarly, rpaphp
notifies the VIO subsystem when a VIO bus is DLPAR-removed.  The rpaphp
module has special case code to fake results for attributes like power,
adapter status, etc.

The VIO register/unregister functions could just as easily be made from
the DLPAR module.  This patch moves the VIO registration calls to the
DLPAR module, and removes the VIO fluff from rpaphp altogether.

Signed-off-by: John Rose <johnrose@austin.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
John Rose authored and Greg Kroah-Hartman committed Sep 8, 2005
1 parent bde1684 commit 5eeb8c6
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 271 deletions.
3 changes: 1 addition & 2 deletions drivers/pci/hotplug/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ acpiphp-objs := acpiphp_core.o \

rpaphp-objs := rpaphp_core.o \
rpaphp_pci.o \
rpaphp_slot.o \
rpaphp_vio.o
rpaphp_slot.o

rpadlpar_io-objs := rpadlpar_core.o \
rpadlpar_sysfs.o
Expand Down
110 changes: 65 additions & 45 deletions drivers/pci/hotplug/rpadlpar_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <asm/pci-bridge.h>
#include <asm/semaphore.h>
#include <asm/rtas.h>
#include <asm/vio.h>
#include "../pci.h"
#include "rpaphp.h"
#include "rpadlpar.h"
Expand All @@ -29,23 +30,23 @@ static DECLARE_MUTEX(rpadlpar_sem);
#define NODE_TYPE_SLOT 2
#define NODE_TYPE_PHB 3

static struct device_node *find_php_slot_vio_node(char *drc_name)
static struct device_node *find_vio_slot_node(char *drc_name)
{
struct device_node *child;
struct device_node *parent = of_find_node_by_name(NULL, "vdevice");
char *loc_code;
struct device_node *dn = NULL;
char *name;
int rc;

if (!parent)
return NULL;

for (child = of_get_next_child(parent, NULL);
child; child = of_get_next_child(parent, child)) {
loc_code = get_property(child, "ibm,loc-code", NULL);
if (loc_code && !strncmp(loc_code, drc_name, strlen(drc_name)))
return child;
while ((dn = of_get_next_child(parent, dn))) {
rc = rpaphp_get_drc_props(dn, NULL, &name, NULL, NULL);
if ((rc == 0) && (!strcmp(drc_name, name)))
break;
}

return NULL;
return dn;
}

/* Find dlpar-capable pci node that contains the specified name and type */
Expand All @@ -67,7 +68,7 @@ static struct device_node *find_php_slot_pci_node(char *drc_name,
return np;
}

static struct device_node *find_newly_added_node(char *drc_name, int *node_type)
static struct device_node *find_dlpar_node(char *drc_name, int *node_type)
{
struct device_node *dn;

Expand All @@ -83,7 +84,7 @@ static struct device_node *find_newly_added_node(char *drc_name, int *node_type)
return dn;
}

dn = find_php_slot_vio_node(drc_name);
dn = find_vio_slot_node(drc_name);
if (dn) {
*node_type = NODE_TYPE_VIO;
return dn;
Expand Down Expand Up @@ -231,6 +232,12 @@ static inline int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
return -EIO;
}

/* Add hotplug slot */
if (rpaphp_add_slot(dn)) {
printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
__FUNCTION__, drc_name);
return -EIO;
}
return 0;
}

Expand Down Expand Up @@ -288,14 +295,19 @@ static int dlpar_remove_phb(struct slot *slot)
return 0;
}

static int dlpar_add_phb(struct device_node *dn)
static int dlpar_add_phb(char *drc_name, struct device_node *dn)
{
struct pci_controller *phb;

phb = init_phb_dynamic(dn);
if (!phb)
return -EINVAL;

if (rpaphp_add_slot(dn)) {
printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
__FUNCTION__, drc_name);
return -EIO;
}
return 0;
}

Expand All @@ -316,7 +328,7 @@ int dlpar_add_slot(char *drc_name)
{
struct device_node *dn = NULL;
int node_type;
int rc = 0;
int rc;

if (down_interruptible(&rpadlpar_sem))
return -ERESTARTSYS;
Expand All @@ -327,32 +339,39 @@ int dlpar_add_slot(char *drc_name)
goto exit;
}

dn = find_newly_added_node(drc_name, &node_type);
/* Find newly added node */
dn = find_dlpar_node(drc_name, &node_type);
if (!dn) {
rc = -ENODEV;
goto exit;
}

rc = -EIO;
switch (node_type) {
case NODE_TYPE_VIO:
/* Just add hotplug slot */
if (!vio_register_device_node(dn)) {
printk(KERN_ERR
"%s: failed to register vio node %s\n",
__FUNCTION__, drc_name);
goto exit;
}
break;
case NODE_TYPE_SLOT:
rc = dlpar_add_pci_slot(drc_name, dn);
if (rc)
goto exit;
break;
case NODE_TYPE_PHB:
rc = dlpar_add_phb(dn);
rc = dlpar_add_phb(drc_name, dn);
if (rc)
goto exit;
break;
default:
printk("%s: unexpected node type\n", __FUNCTION__);
return -EIO;
goto exit;
}

if (!rc && rpaphp_add_slot(dn)) {
printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
__FUNCTION__, drc_name);
rc = -EIO;
}
rc = 0;
exit:
up(&rpadlpar_sem);
return rc;
Expand All @@ -368,15 +387,18 @@ int dlpar_add_slot(char *drc_name)
* 0 Success
* -EIO Internal Error
*/
int dlpar_remove_vio_slot(struct slot *slot, char *drc_name)
static int dlpar_remove_vio_slot(struct device_node *dn, char *drc_name)
{
/* Remove hotplug slot */
struct vio_dev *vio_dev;

if (rpaphp_remove_slot(slot)) {
printk(KERN_ERR "%s: unable to remove hotplug slot %s\n",
__FUNCTION__, drc_name);
vio_dev = vio_find_node(dn);
if (!vio_dev) {
printk(KERN_ERR "%s: %s does not correspond to a vio dev\n",
__FUNCTION__, drc_name);
return -EIO;
}

vio_unregister_device(vio_dev);
return 0;
}

Expand Down Expand Up @@ -434,36 +456,34 @@ int dlpar_remove_pci_slot(struct slot *slot, char *drc_name)
*/
int dlpar_remove_slot(char *drc_name)
{
struct device_node *dn;
struct slot *slot;
int node_type;
int rc = 0;

if (down_interruptible(&rpadlpar_sem))
return -ERESTARTSYS;

if (!find_php_slot_vio_node(drc_name) &&
!find_php_slot_pci_node(drc_name, "SLOT") &&
!find_php_slot_pci_node(drc_name, "PHB")) {
dn = find_dlpar_node(drc_name, &node_type);
if (!dn) {
rc = -ENODEV;
goto exit;
}

slot = find_slot(drc_name);
if (!slot) {
rc = -EINVAL;
goto exit;
}

if (slot->type == PHB) {
rc = dlpar_remove_phb(slot);
if (node_type == NODE_TYPE_VIO) {
rc = dlpar_remove_vio_slot(dn, drc_name);
} else {
switch (slot->dev_type) {
case PCI_DEV:
rc = dlpar_remove_pci_slot(slot, drc_name);
break;
slot = find_slot(drc_name);
if (!slot) {
rc = -EINVAL;
goto exit;
}

case VIO_DEV:
rc = dlpar_remove_vio_slot(slot, drc_name);
break;
if (node_type == NODE_TYPE_PHB)
rc = dlpar_remove_phb(slot);
else {
/* NODE_TYPE_SLOT */
rc = dlpar_remove_pci_slot(slot, drc_name);
}
}
exit:
Expand Down
16 changes: 1 addition & 15 deletions drivers/pci/hotplug/rpaphp.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,6 @@ extern int debug;
#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)

/* slot types */
#define VIO_DEV 1
#define PCI_DEV 2

/* slot states */

#define NOT_VALID 3
Expand All @@ -84,14 +80,10 @@ struct slot {
char *name;
char *location;
u8 removable;
u8 dev_type; /* VIO or PCI */
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 */
union {
struct list_head *pci_devs; /* pci_devs in PCI slot */
struct vio_dev *vio_dev; /* vio_dev in VIO slot */
} dev;
struct list_head *pci_devs; /* pci_devs in PCI slot */
struct hotplug_slot *hotplug_slot;
};

Expand All @@ -115,12 +107,6 @@ extern int rpaphp_remove_slot(struct slot *slot);
extern int rpaphp_get_drc_props(struct device_node *dn, int *drc_index,
char **drc_name, char **drc_type, int *drc_power_domain);

/* rpaphp_vio.c */
extern int rpaphp_get_vio_adapter_status(struct slot *slot, int is_init, u8 * value);
extern int rpaphp_unconfig_vio_adapter(struct slot *slot);
extern int register_vio_slot(struct device_node *dn);
extern int rpaphp_enable_vio_slot(struct slot *slot);

/* rpaphp_slot.c */
extern void dealloc_slot_struct(struct slot *slot);
extern struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain);
Expand Down
77 changes: 13 additions & 64 deletions drivers/pci/hotplug/rpaphp_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,17 +152,7 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value)
int retval = 0;

down(&rpaphp_sem);
/* have to go through this */
switch (slot->dev_type) {
case PCI_DEV:
retval = rpaphp_get_pci_adapter_status(slot, 0, value);
break;
case VIO_DEV:
retval = rpaphp_get_vio_adapter_status(slot, 0, value);
break;
default:
retval = -EINVAL;
}
retval = rpaphp_get_pci_adapter_status(slot, 0, value);
up(&rpaphp_sem);
return retval;
}
Expand Down Expand Up @@ -362,12 +352,6 @@ int rpaphp_add_slot(struct device_node *dn)

dbg("Entry %s: dn->full_name=%s\n", __FUNCTION__, dn->full_name);

if (dn->parent && is_vdevice_root(dn->parent)) {
/* register a VIO device */
retval = register_vio_slot(dn);
goto exit;
}

/* register PCI devices */
if (dn->name != 0 && strcmp(dn->name, "pci") == 0) {
if (is_php_dn(dn, &indexes, &names, &types, &power_domains))
Expand Down Expand Up @@ -412,31 +396,6 @@ int rpaphp_add_slot(struct device_node *dn)
return retval;
}

/*
* init_slots - initialize 'struct slot' structures for each slot
*
*/
static void init_slots(void)
{
struct device_node *dn;

for (dn = find_all_nodes(); dn; dn = dn->next)
rpaphp_add_slot(dn);
}

static int __init init_rpa(void)
{

init_MUTEX(&rpaphp_sem);

/* initialize internal data structure etc. */
init_slots();
if (!num_slots)
return -ENODEV;

return 0;
}

static void __exit cleanup_slots(void)
{
struct list_head *tmp, *n;
Expand All @@ -458,10 +417,18 @@ static void __exit cleanup_slots(void)

static int __init rpaphp_init(void)
{
struct device_node *dn = NULL;

info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
init_MUTEX(&rpaphp_sem);

while ((dn = of_find_node_by_type(dn, "pci")))
rpaphp_add_slot(dn);

if (!num_slots)
return -ENODEV;

/* read all the PRA info from the system */
return init_rpa();
return 0;
}

static void __exit rpaphp_exit(void)
Expand All @@ -481,16 +448,7 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)

dbg("ENABLING SLOT %s\n", slot->name);
down(&rpaphp_sem);
switch (slot->dev_type) {
case PCI_DEV:
retval = rpaphp_enable_pci_slot(slot);
break;
case VIO_DEV:
retval = rpaphp_enable_vio_slot(slot);
break;
default:
retval = -EINVAL;
}
retval = rpaphp_enable_pci_slot(slot);
up(&rpaphp_sem);
exit:
dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
Expand All @@ -511,16 +469,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)

dbg("DISABLING SLOT %s\n", slot->name);
down(&rpaphp_sem);
switch (slot->dev_type) {
case PCI_DEV:
retval = rpaphp_unconfig_pci_adapter(slot);
break;
case VIO_DEV:
retval = rpaphp_unconfig_vio_adapter(slot);
break;
default:
retval = -ENODEV;
}
retval = rpaphp_unconfig_pci_adapter(slot);
up(&rpaphp_sem);
exit:
dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
Expand Down
Loading

0 comments on commit 5eeb8c6

Please sign in to comment.