diff options
author | Anton Altaparmakov <aia21@hera.kernel.org> | 2005-09-09 08:19:10 -0700 |
---|---|---|
committer | Anton Altaparmakov <aia21@hera.kernel.org> | 2005-09-09 08:19:10 -0700 |
commit | ddcc95963449d028b16d9b9fe50f6e91ce7d9e81 (patch) | |
tree | aaf0392346a18b3e232ddeb5db3c4e917f7ca686 /drivers/pci | |
parent | 223176bc722a7bf519904180e956292ae1d1e819 (diff) | |
parent | 5f5024130287a9467a41b9f94ec170958ae45cbd (diff) |
Merge branch 'master' of /pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/Kconfig | 17 | ||||
-rw-r--r-- | drivers/pci/Makefile | 22 | ||||
-rw-r--r-- | drivers/pci/bus.c | 51 | ||||
-rw-r--r-- | drivers/pci/gen-devlist.c | 132 | ||||
-rw-r--r-- | drivers/pci/hotplug/Makefile | 3 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp.h | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/rpadlpar_core.c | 287 | ||||
-rw-r--r-- | drivers/pci/hotplug/rpaphp.h | 35 | ||||
-rw-r--r-- | drivers/pci/hotplug/rpaphp_core.c | 146 | ||||
-rw-r--r-- | drivers/pci/hotplug/rpaphp_pci.c | 297 | ||||
-rw-r--r-- | drivers/pci/hotplug/rpaphp_slot.c | 66 | ||||
-rw-r--r-- | drivers/pci/hotplug/rpaphp_vio.c | 129 | ||||
-rw-r--r-- | drivers/pci/hotplug/sgi_hotplug.c | 195 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp.h | 2 | ||||
-rw-r--r-- | drivers/pci/msi.c | 10 | ||||
-rw-r--r-- | drivers/pci/names.c | 137 | ||||
-rw-r--r-- | drivers/pci/pci-driver.c | 37 | ||||
-rw-r--r-- | drivers/pci/pci.c | 104 | ||||
-rw-r--r-- | drivers/pci/pci.ids | 10180 | ||||
-rw-r--r-- | drivers/pci/pcie/portdrv_pci.c | 8 | ||||
-rw-r--r-- | drivers/pci/probe.c | 4 | ||||
-rw-r--r-- | drivers/pci/proc.c | 12 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 7 | ||||
-rw-r--r-- | drivers/pci/setup-res.c | 7 |
24 files changed, 596 insertions, 11294 deletions
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 7f31991772e..f187fd8aeed 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -30,23 +30,6 @@ config PCI_LEGACY_PROC When in doubt, say N. -config PCI_NAMES - bool "PCI device name database" - depends on PCI - ---help--- - By default, the kernel contains a database of all known PCI device - names to make the information in /proc/pci, /proc/ioports and - similar files comprehensible to the user. - - This database increases size of the kernel image by about 80KB. This - memory is freed after the system boots up if CONFIG_HOTPLUG is not set. - - Anyway, if you are building an installation floppy or kernel for an - embedded system where kernel image size really matters, you can disable - this feature and you'll get device ID numbers instead of names. - - When in doubt, say Y. - config PCI_DEBUG bool "PCI Debugging" depends on PCI && DEBUG_KERNEL diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 3657f6199c4..716df015f8d 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -3,14 +3,9 @@ # obj-y += access.o bus.o probe.o remove.o pci.o quirks.o \ - names.o pci-driver.o search.o pci-sysfs.o \ - rom.o + pci-driver.o search.o pci-sysfs.o rom.o setup-res.o obj-$(CONFIG_PROC_FS) += proc.o -ifndef CONFIG_SPARC64 -obj-y += setup-res.o -endif - obj-$(CONFIG_HOTPLUG) += hotplug.o # Build the PCI Hotplug drivers if we were asked to @@ -46,21 +41,6 @@ ifeq ($(CONFIG_PCI_DEBUG),y) EXTRA_CFLAGS += -DDEBUG endif -hostprogs-y := gen-devlist - -# Dependencies on generated files need to be listed explicitly -$(obj)/names.o: $(obj)/devlist.h $(obj)/classlist.h -$(obj)/classlist.h: $(obj)/devlist.h - -# And that's how to generate them -quiet_cmd_devlist = DEVLIST $@ - cmd_devlist = ( cd $(obj); ./gen-devlist ) < $< -$(obj)/devlist.h: $(src)/pci.ids $(obj)/gen-devlist - $(call cmd,devlist) - -# Files generated that shall be removed upon make clean -clean-files := devlist.h classlist.h - # Build PCI Express stuff if needed obj-$(CONFIG_PCIEPORTBUS) += pcie/ diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index fb9a11243d2..eed67d9e73b 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -140,16 +140,65 @@ void __devinit pci_bus_add_devices(struct pci_bus *bus) void pci_enable_bridges(struct pci_bus *bus) { struct pci_dev *dev; + int retval; list_for_each_entry(dev, &bus->devices, bus_list) { if (dev->subordinate) { - pci_enable_device(dev); + retval = pci_enable_device(dev); pci_set_master(dev); pci_enable_bridges(dev->subordinate); } } } +/** pci_walk_bus - walk devices on/under bus, calling callback. + * @top bus whose devices should be walked + * @cb callback to be called for each device found + * @userdata arbitrary pointer to be passed to callback. + * + * Walk the given bus, including any bridged devices + * on buses under this bus. Call the provided callback + * on each device found. + */ +void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *), + void *userdata) +{ + struct pci_dev *dev; + struct pci_bus *bus; + struct list_head *next; + + bus = top; + spin_lock(&pci_bus_lock); + next = top->devices.next; + for (;;) { + if (next == &bus->devices) { + /* end of this bus, go up or finish */ + if (bus == top) + break; + next = bus->self->bus_list.next; + bus = bus->self->bus; + continue; + } + dev = list_entry(next, struct pci_dev, bus_list); + pci_dev_get(dev); + if (dev->subordinate) { + /* this is a pci-pci bridge, do its devices next */ + next = dev->subordinate->devices.next; + bus = dev->subordinate; + } else + next = dev->bus_list.next; + spin_unlock(&pci_bus_lock); + + /* Run device routines with the bus unlocked */ + cb(dev, userdata); + + spin_lock(&pci_bus_lock); + pci_dev_put(dev); + } + spin_unlock(&pci_bus_lock); +} +EXPORT_SYMBOL_GPL(pci_walk_bus); + EXPORT_SYMBOL(pci_bus_alloc_resource); EXPORT_SYMBOL_GPL(pci_bus_add_device); EXPORT_SYMBOL(pci_bus_add_devices); diff --git a/drivers/pci/gen-devlist.c b/drivers/pci/gen-devlist.c deleted file mode 100644 index 8abfc499fde..00000000000 --- a/drivers/pci/gen-devlist.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Generate devlist.h and classlist.h from the PCI ID file. - * - * (c) 1999--2002 Martin Mares <mj@ucw.cz> - */ - -#include <stdio.h> -#include <string.h> - -#define MAX_NAME_SIZE 200 - -static void -pq(FILE *f, const char *c, int len) -{ - int i = 1; - while (*c && i != len) { - if (*c == '"') - fprintf(f, "\\\""); - else { - fputc(*c, f); - if (*c == '?' && c[1] == '?') { - /* Avoid trigraphs */ - fprintf(f, "\" \""); - } - } - c++; - i++; - } -} - -int -main(void) -{ - char line[1024], *c, *bra, vend[8]; - int vendors = 0; - int mode = 0; - int lino = 0; - int vendor_len = 0; - FILE *devf, *clsf; - - devf = fopen("devlist.h", "w"); - clsf = fopen("classlist.h", "w"); - if (!devf || !clsf) { - fprintf(stderr, "Cannot create output file!\n"); - return 1; - } - - while (fgets(line, sizeof(line)-1, stdin)) { - lino++; - if ((c = strchr(line, '\n'))) - *c = 0; - if (!line[0] || line[0] == '#') - continue; - if (line[1] == ' ') { - if (line[0] == 'C' && strlen(line) > 4 && line[4] == ' ') { - vend[0] = line[2]; - vend[1] = line[3]; - vend[2] = 0; - mode = 2; - } else goto err; - } - else if (line[0] == '\t') { - if (line[1] == '\t') - continue; - switch (mode) { - case 1: - if (strlen(line) > 5 && line[5] == ' ') { - c = line + 5; - while (*c == ' ') - *c++ = 0; - if (vendor_len + strlen(c) + 1 > MAX_NAME_SIZE) { - /* Too long, try cutting off long description */ - bra = strchr(c, '['); - if (bra && bra > c && bra[-1] == ' ') - bra[-1] = 0; - if (vendor_len + strlen(c) + 1 > MAX_NAME_SIZE) { - fprintf(stderr, "Line %d: Device name too long. Name truncated.\n", lino); - fprintf(stderr, "%s\n", c); - /*return 1;*/ - } - } - fprintf(devf, "\tDEVICE(%s,%s,\"", vend, line+1); - pq(devf, c, MAX_NAME_SIZE - vendor_len - 1); - fputs("\")\n", devf); - } else goto err; - break; - case 2: - if (strlen(line) > 3 && line[3] == ' ') { - c = line + 3; - while (*c == ' ') - *c++ = 0; - fprintf(clsf, "CLASS(%s%s, \"%s\")\n", vend, line+1, c); - } else goto err; - break; - default: - goto err; - } - } else if (strlen(line) > 4 && line[4] == ' ') { - c = line + 4; - while (*c == ' ') - *c++ = 0; - if (vendors) - fputs("ENDVENDOR()\n\n", devf); - vendors++; - strcpy(vend, line); - vendor_len = strlen(c); - if (vendor_len + 24 > MAX_NAME_SIZE) { - fprintf(stderr, "Line %d: Vendor name too long\n", lino); - return 1; - } - fprintf(devf, "VENDOR(%s,\"", vend); - pq(devf, c, 0); - fputs("\")\n", devf); - mode = 1; - } else { - err: - fprintf(stderr, "Line %d: Syntax error in mode %d: %s\n", lino, mode, line); - return 1; - } - } - fputs("ENDVENDOR()\n\ -\n\ -#undef VENDOR\n\ -#undef DEVICE\n\ -#undef ENDVENDOR\n", devf); - fputs("\n#undef CLASS\n", clsf); - - fclose(devf); - fclose(clsf); - - return 0; -} diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile index 246586a3d91..3c71e3077ff 100644 --- a/drivers/pci/hotplug/Makefile +++ b/drivers/pci/hotplug/Makefile @@ -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 diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 2b92b9e8c91..061ead21ef1 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -302,7 +302,7 @@ static inline void return_resource(struct pci_resource **head, struct pci_resour static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot) { - snprintf(buffer, buffer_size, "%d", slot->number); + snprintf(buffer, buffer_size, "%04d_%04d", slot->bus, slot->number); } enum php_ctlr_type { diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index 86b384e4271..4ada15111af 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -19,33 +19,36 @@ #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" 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 -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 */ @@ -67,7 +70,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; @@ -83,7 +86,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; @@ -92,14 +95,14 @@ static struct device_node *find_newly_added_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; } @@ -164,6 +167,20 @@ static int pci_add_secondary_bus(struct device_node *dn, return 0; } +static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent, + struct device_node *dev_dn) +{ + struct pci_dev *tmp = NULL; + struct device_node *child_dn; + + list_for_each_entry(tmp, &parent->devices, bus_list) { + child_dn = pci_device_to_OF_node(tmp); + if (child_dn == dev_dn) + return tmp; + } + return NULL; +} + static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) { struct pci_controller *hose = dn->phb; @@ -179,49 +196,28 @@ static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) pci_bus_add_devices(hose->bus); /* Confirm new bridge dev was created */ - dev = rpaphp_find_pci_dev(dn); - if (!dev) { - printk(KERN_ERR "%s: failed to add pci device\n", __FUNCTION__); - return NULL; - } + dev = dlpar_find_new_dev(hose->bus, dn); + if (dev) { + if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { + printk(KERN_ERR "%s: unexpected header type %d\n", + __FUNCTION__, dev->hdr_type); + return NULL; + } - if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { - printk(KERN_ERR "%s: unexpected header type %d\n", - __FUNCTION__, dev->hdr_type); - return NULL; + if (pci_add_secondary_bus(dn, dev)) + return NULL; } - if (pci_add_secondary_bus(dn, dev)) - return NULL; - return dev; } -static int dlpar_pci_remove_bus(struct pci_dev *bridge_dev) +static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn) { - struct pci_bus *secondary_bus; + struct pci_dev *dev; + int rc; - if (!bridge_dev) { - printk(KERN_ERR "%s: unexpected null device\n", - __FUNCTION__); + if (rpaphp_find_pci_bus(dn)) return -EINVAL; - } - - secondary_bus = bridge_dev->subordinate; - - if (unmap_bus_range(secondary_bus)) { - printk(KERN_ERR "%s: failed to unmap bus range\n", - __FUNCTION__); - return -ERANGE; - } - - pci_remove_bus_device(bridge_dev); - return 0; -} - -static inline int dlpar_add_pci_slot(char *drc_name, struct device_node *dn) -{ - struct pci_dev *dev; /* Add pci bus */ dev = dlpar_pci_add_bus(dn); @@ -231,6 +227,21 @@ static inline int dlpar_add_pci_slot(char *drc_name, struct device_node *dn) return -EIO; } + if (dn->child) { + rc = rpaphp_config_pci_adapter(dev->subordinate); + if (rc < 0) { + printk(KERN_ERR "%s: unable to enable slot %s\n", + __FUNCTION__, drc_name); + 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; } @@ -255,47 +266,67 @@ 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(struct device_node *dn) +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 -EIO; + + if (rpaphp_add_slot(dn)) { + printk(KERN_ERR "%s: unable to add hotplug slot %s\n", + __FUNCTION__, drc_name); + return -EIO; + } + 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; } @@ -316,18 +347,13 @@ int dlpar_add_slot(char *drc_name) { struct device_node *dn = NULL; int node_type; - int rc = 0; + int rc = -EIO; if (down_interruptible(&rpadlpar_sem)) return -ERESTARTSYS; - /* Check for existing hotplug slot */ - if (find_slot(drc_name)) { - rc = -EINVAL; - 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; @@ -335,24 +361,17 @@ int dlpar_add_slot(char *drc_name) switch (node_type) { case NODE_TYPE_VIO: - /* Just add hotplug slot */ + rc = dlpar_add_vio_slot(drc_name, dn); break; case NODE_TYPE_SLOT: rc = dlpar_add_pci_slot(drc_name, dn); break; case NODE_TYPE_PHB: - rc = dlpar_add_phb(dn); + rc = dlpar_add_phb(drc_name, dn); break; - default: - printk("%s: unexpected node type\n", __FUNCTION__); - return -EIO; } - if (!rc && rpaphp_add_slot(dn)) { - printk(KERN_ERR "%s: unable to add hotplug slot %s\n", - __FUNCTION__, drc_name); - rc = -EIO; - } + printk(KERN_INFO "%s: slot %s added\n", DLPAR_MODULE_NAME, drc_name); exit: up(&rpadlpar_sem); return rc; @@ -366,17 +385,17 @@ exit: * of an I/O Slot. * Return Codes: * 0 Success - * -EIO Internal Error + * -EINVAL Vio dev doesn't exist */ -int dlpar_remove_vio_slot(struct slot *slot, char *drc_name) +static int dlpar_remove_vio_slot(char *drc_name, struct device_node *dn) { - /* 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); - return -EIO; - } + vio_dev = vio_find_node(dn); + if (!vio_dev) + return -EINVAL; + + vio_unregister_device(vio_dev); return 0; } @@ -391,31 +410,34 @@ int dlpar_remove_vio_slot(struct slot *slot, 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_dev *bridge_dev; + struct pci_bus *bus; + struct slot *slot; - bridge_dev = slot->bridge; - if (!bridge_dev) { - printk(KERN_ERR "%s: unexpected null bridge device\n", - __FUNCTION__); - return -EIO; - } + bus = rpaphp_find_pci_bus(dn); + if (!bus) + return -EINVAL; - /* Remove hotplug slot */ - if (rpaphp_remove_slot(slot)) { - printk(KERN_ERR "%s: unable to remove hotplug slot %s\n", - __FUNCTION__, drc_name); - 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; + } } - /* Remove pci bus */ - - if (dlpar_pci_remove_bus(bridge_dev)) { - printk(KERN_ERR "%s: unable to remove pci bus %s\n", - __FUNCTION__, drc_name); - return -EIO; + if (unmap_bus_range(bus)) { + printk(KERN_ERR "%s: failed to unmap bus range\n", + __FUNCTION__); + return -ERANGE; } + + BUG_ON(!bus->self); + pci_remove_bus_device(bus->self); return 0; } @@ -434,38 +456,31 @@ int dlpar_remove_pci_slot(struct slot *slot, char *drc_name) */ int dlpar_remove_slot(char *drc_name) { - struct slot *slot; + struct device_node *dn; + 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); - } else { - switch (slot->dev_type) { - case PCI_DEV: - rc = dlpar_remove_pci_slot(slot, drc_name); - break; - - case VIO_DEV: - rc = dlpar_remove_vio_slot(slot, drc_name); - break; - } + 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; diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 81746e6e0e0..61d94d1e29c 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -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 @@ -61,10 +57,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 @@ -72,11 +64,6 @@ extern int debug; #define CONFIGURED 1 #define EMPTY 0 -struct rpaphp_pci_func { - struct pci_dev *pci_dev; - struct list_head sibling; -}; - /* * struct slot - slot information for each *physical* slot */ @@ -88,15 +75,9 @@ struct slot { u32 power_domain; 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 device_node *dn; + struct pci_bus *bus; + struct list_head *pci_devs; struct hotplug_slot *hotplug_slot; }; @@ -107,13 +88,13 @@ extern int num_slots; /* function prototypes */ /* rpaphp_pci.c */ -extern struct pci_dev *rpaphp_find_pci_dev(struct device_node *dn); +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); extern int rpaphp_unconfig_pci_adapter(struct slot *slot); extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); -extern struct hotplug_slot *rpaphp_find_hotplug_slot(struct pci_dev *dev); +extern int rpaphp_config_pci_adapter(struct pci_bus *bus); /* rpaphp_core.c */ extern int rpaphp_add_slot(struct device_node *dn); @@ -121,12 +102,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); diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 29117a3a328..c830ff0acdc 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -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; } @@ -317,34 +307,6 @@ static int is_php_dn(struct device_node *dn, int **indexes, int **names, return 0; } -static int is_dr_dn(struct device_node *dn, int **indexes, int **names, - int **types, int **power_domains, int **my_drc_index) -{ - int rc; - - *my_drc_index = (int *) get_property(dn, "ibm,my-drc-index", NULL); - if(!*my_drc_index) - return (0); - - if (!dn->parent) - return (0); - - rc = get_children_props(dn->parent, indexes, names, types, - power_domains); - return (rc >= 0); -} - -static inline int is_vdevice_root(struct device_node *dn) -{ - return !strcmp(dn->name, "vdevice"); -} - -int is_dlpar_type(const char *type_str) -{ - /* Only register DLPAR-capable nodes of drc-type PHB or SLOT */ - return (!strcmp(type_str, "PHB") || !strcmp(type_str, "SLOT")); -} - /**************************************************************** * rpaphp not only registers PCI hotplug slots(HOTPLUG), * but also logical DR slots(EMBEDDED). @@ -356,54 +318,33 @@ int rpaphp_add_slot(struct device_node *dn) { struct slot *slot; int retval = 0; - int i, *my_drc_index, slot_type; + int i; int *indexes, *names, *types, *power_domains; char *name, *type; 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)) - slot_type = HOTPLUG; - else if (is_dr_dn(dn, &indexes, &names, &types, &power_domains, &my_drc_index)) - slot_type = EMBEDDED; - else goto exit; + if (!is_php_dn(dn, &indexes, &names, &types, &power_domains)) + goto exit; name = (char *) &names[1]; type = (char *) &types[1]; for (i = 0; i < indexes[0]; i++, - name += (strlen(name) + 1), type += (strlen(type) + 1)) { - - if (slot_type == HOTPLUG || - (slot_type == EMBEDDED && - indexes[i + 1] == my_drc_index[0] && - is_dlpar_type(type))) { - if (!(slot = alloc_slot_struct(dn, indexes[i + 1], name, - power_domains[i + 1]))) { - retval = -ENOMEM; - goto exit; - } - if (!strcmp(type, "PHB")) - slot->type = PHB; - else if (slot_type == EMBEDDED) - slot->type = EMBEDDED; - else - slot->type = simple_strtoul(type, NULL, 10); + name += (strlen(name) + 1), type += (strlen(type) + 1)) { + + if (!(slot = alloc_slot_struct(dn, indexes[i + 1], name, + power_domains[i + 1]))) { + retval = -ENOMEM; + goto exit; + } + slot->t |