Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 7900
b: refs/heads/master
c: 56d8456
h: refs/heads/master
v: v3
  • Loading branch information
John Rose authored and Greg Kroah-Hartman committed Sep 8, 2005
1 parent 1a390db commit 0219bbf
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 194 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 940903c5a5a906c622a79b3101586deb1a1b3480
refs/heads/master: 56d8456b06ad1316bff3c75caed5e06e786f20d8
154 changes: 78 additions & 76 deletions trunk/drivers/pci/hotplug/rpadlpar_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

static DECLARE_MUTEX(rpadlpar_sem);

#define DLPAR_MODULE_NAME "rpadlpar_io"

#define NODE_TYPE_VIO 1
#define NODE_TYPE_SLOT 2
#define NODE_TYPE_PHB 3
Expand Down Expand Up @@ -93,14 +95,14 @@ static struct device_node *find_dlpar_node(char *drc_name, int *node_type)
return NULL;
}

static struct slot *find_slot(char *drc_name)
static struct slot *find_slot(struct device_node *dn)
{
struct list_head *tmp, *n;
struct slot *slot;

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)
if (slot->dn == dn)
return slot;
}

Expand Down Expand Up @@ -214,6 +216,9 @@ static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
struct pci_dev *dev;
int rc;

if (rpaphp_find_pci_bus(dn))
return -EINVAL;

/* Add pci bus */
dev = dlpar_pci_add_bus(dn);
if (!dev) {
Expand Down Expand Up @@ -261,46 +266,47 @@ static int dlpar_remove_root_bus(struct pci_controller *phb)
return 0;
}

static int dlpar_remove_phb(struct slot *slot)
static int dlpar_remove_phb(char *drc_name, struct device_node *dn)
{
struct pci_controller *phb;
struct device_node *dn;
struct slot *slot;
int rc = 0;

dn = slot->dn;
if (!dn) {
printk(KERN_ERR "%s: unexpected NULL slot device node\n",
__FUNCTION__);
return -EIO;
}

phb = dn->phb;
if (!phb) {
printk(KERN_ERR "%s: unexpected NULL phb pointer\n",
__FUNCTION__);
return -EIO;
}
if (!rpaphp_find_pci_bus(dn))
return -EINVAL;

if (rpaphp_remove_slot(slot)) {
printk(KERN_ERR "%s: unable to remove hotplug slot %s\n",
__FUNCTION__, slot->location);
return -EIO;
slot = find_slot(dn);
if (slot) {
/* Remove hotplug slot */
if (rpaphp_remove_slot(slot)) {
printk(KERN_ERR
"%s: unable to remove hotplug slot %s\n",
__FUNCTION__, drc_name);
return -EIO;
}
}

rc = dlpar_remove_root_bus(phb);
BUG_ON(!dn->phb);
rc = dlpar_remove_root_bus(dn->phb);
if (rc < 0)
return rc;

dn->phb = NULL;

return 0;
}

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

if (dn->phb) {
/* PHB already exists */
return -EINVAL;
}

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

if (rpaphp_add_slot(dn)) {
printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
Expand All @@ -310,6 +316,20 @@ static int dlpar_add_phb(char *drc_name, struct device_node *dn)
return 0;
}

static int dlpar_add_vio_slot(char *drc_name, struct device_node *dn)
{
if (vio_find_node(dn))
return -EINVAL;

if (!vio_register_device_node(dn)) {
printk(KERN_ERR
"%s: failed to register vio node %s\n",
__FUNCTION__, drc_name);
return -EIO;
}
return 0;
}

/**
* dlpar_add_slot - DLPAR add an I/O Slot
* @drc_name: drc-name of newly added slot
Expand All @@ -327,50 +347,31 @@ int dlpar_add_slot(char *drc_name)
{
struct device_node *dn = NULL;
int node_type;
int rc;
int rc = -EIO;

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

/* Check for existing hotplug slot */
if (find_slot(drc_name)) {
rc = -EINVAL;
goto exit;
}

/* 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:
if (!vio_register_device_node(dn)) {
printk(KERN_ERR
"%s: failed to register vio node %s\n",
__FUNCTION__, drc_name);
goto exit;
}
rc = dlpar_add_vio_slot(drc_name, dn);
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(drc_name, dn);
if (rc)
goto exit;
break;
default:
printk("%s: unexpected node type\n", __FUNCTION__);
goto exit;
}

rc = 0;
printk(KERN_INFO "%s: slot %s added\n", DLPAR_MODULE_NAME, drc_name);
exit:
up(&rpadlpar_sem);
return rc;
Expand All @@ -384,18 +385,15 @@ int dlpar_add_slot(char *drc_name)
* of an I/O Slot.
* Return Codes:
* 0 Success
* -EIO Internal Error
* -EINVAL Vio dev doesn't exist
*/
static int dlpar_remove_vio_slot(struct device_node *dn, char *drc_name)
static int dlpar_remove_vio_slot(char *drc_name, struct device_node *dn)
{
struct vio_dev *vio_dev;

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;
}
if (!vio_dev)
return -EINVAL;

vio_unregister_device(vio_dev);
return 0;
Expand All @@ -412,15 +410,24 @@ static int dlpar_remove_vio_slot(struct device_node *dn, char *drc_name)
* -ENODEV Not a valid drc_name
* -EIO Internal PCI Error
*/
int dlpar_remove_pci_slot(struct slot *slot, char *drc_name)
int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn)
{
struct pci_bus *bus = slot->bus;
struct pci_bus *bus;
struct slot *slot;

/* Remove hotplug slot */
if (rpaphp_remove_slot(slot)) {
printk(KERN_ERR "%s: unable to remove hotplug slot %s\n",
__FUNCTION__, drc_name);
return -EIO;
bus = rpaphp_find_pci_bus(dn);
if (!bus)
return -EINVAL;

slot = find_slot(dn);
if (slot) {
/* Remove hotplug slot */
if (rpaphp_remove_slot(slot)) {
printk(KERN_ERR
"%s: unable to remove hotplug slot %s\n",
__FUNCTION__, drc_name);
return -EIO;
}
}

if (unmap_bus_range(bus)) {
Expand Down Expand Up @@ -450,7 +457,6 @@ 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;

Expand All @@ -463,22 +469,18 @@ int dlpar_remove_slot(char *drc_name)
goto exit;
}

if (node_type == NODE_TYPE_VIO) {
rc = dlpar_remove_vio_slot(dn, drc_name);
} else {
slot = find_slot(drc_name);
if (!slot) {
rc = -EINVAL;
goto exit;
}

if (node_type == NODE_TYPE_PHB)
rc = dlpar_remove_phb(slot);
else {
/* NODE_TYPE_SLOT */
rc = dlpar_remove_pci_slot(slot, drc_name);
}
switch (node_type) {
case NODE_TYPE_VIO:
rc = dlpar_remove_vio_slot(drc_name, dn);
break;
case NODE_TYPE_PHB:
rc = dlpar_remove_phb(drc_name, dn);
break;
case NODE_TYPE_SLOT:
rc = dlpar_remove_pci_slot(drc_name, dn);
break;
}
printk(KERN_INFO "%s: slot %s removed\n", DLPAR_MODULE_NAME, drc_name);
exit:
up(&rpadlpar_sem);
return rc;
Expand Down
6 changes: 1 addition & 5 deletions trunk/drivers/pci/hotplug/rpaphp.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@
#include <linux/pci.h>
#include "pci_hotplug.h"

#define PHB 2
#define HOTPLUG 1
#define EMBEDDED 0

#define DR_INDICATOR 9002
#define DR_ENTITY_SENSE 9003

Expand Down Expand Up @@ -79,7 +75,6 @@ struct slot {
u32 power_domain;
char *name;
char *location;
u8 removable;
struct device_node *dn;
struct pci_bus *bus;
struct list_head *pci_devs;
Expand All @@ -93,6 +88,7 @@ extern int num_slots;
/* function prototypes */

/* rpaphp_pci.c */
extern struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn);
extern int rpaphp_claim_resource(struct pci_dev *dev, int resource);
extern int rpaphp_enable_pci_slot(struct slot *slot);
extern int register_pci_slot(struct slot *slot);
Expand Down
Loading

0 comments on commit 0219bbf

Please sign in to comment.