Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/drivers/pci/hotplug/rpadlpar_core.c (Version 2.6.25) and /linux/drivers/pci/hotplug/rpadlpar_core.c (Version 2.6.11.8)


  1 /*                                                  1 /*
  2  * Interface for Dynamic Logical Partitioning       2  * Interface for Dynamic Logical Partitioning of I/O Slots on
  3  * RPA-compliant PPC64 platform.                    3  * RPA-compliant PPC64 platform.
  4  *                                                  4  *
  5  * John Rose <johnrose@austin.ibm.com>              5  * John Rose <johnrose@austin.ibm.com>
  6  * Linda Xie <lxie@us.ibm.com>                      6  * Linda Xie <lxie@us.ibm.com>
  7  *                                                  7  *
  8  * October 2003                                     8  * October 2003
  9  *                                                  9  *
 10  * Copyright (C) 2003 IBM.                         10  * Copyright (C) 2003 IBM.
 11  *                                                 11  *
 12  *      This program is free software; you can     12  *      This program is free software; you can redistribute it and/or
 13  *      modify it under the terms of the GNU G     13  *      modify it under the terms of the GNU General Public License
 14  *      as published by the Free Software Foun     14  *      as published by the Free Software Foundation; either version
 15  *      2 of the License, or (at your option)      15  *      2 of the License, or (at your option) any later version.
 16  */                                                16  */
 17 #include <linux/init.h>                            17 #include <linux/init.h>
 18 #include <linux/pci.h>                             18 #include <linux/pci.h>
 19 #include <linux/string.h>                      << 
 20                                                << 
 21 #include <asm/pci-bridge.h>                        19 #include <asm/pci-bridge.h>
 22 #include <linux/mutex.h>                       !!  20 #include <asm/semaphore.h>
 23 #include <asm/rtas.h>                              21 #include <asm/rtas.h>
 24 #include <asm/vio.h>                           << 
 25                                                << 
 26 #include "../pci.h"                                22 #include "../pci.h"
 27 #include "rpaphp.h"                                23 #include "rpaphp.h"
 28 #include "rpadlpar.h"                              24 #include "rpadlpar.h"
 29                                                    25 
 30 static DEFINE_MUTEX(rpadlpar_mutex);           !!  26 static DECLARE_MUTEX(rpadlpar_sem);
 31                                                << 
 32 #define DLPAR_MODULE_NAME "rpadlpar_io"        << 
 33                                                    27 
 34 #define NODE_TYPE_VIO  1                           28 #define NODE_TYPE_VIO  1
 35 #define NODE_TYPE_SLOT 2                           29 #define NODE_TYPE_SLOT 2
 36 #define NODE_TYPE_PHB  3                           30 #define NODE_TYPE_PHB  3
 37                                                    31 
 38 static struct device_node *find_vio_slot_node( !!  32 static struct device_node *find_php_slot_vio_node(char *drc_name)
 39 {                                                  33 {
                                                   >>  34         struct device_node *child;
 40         struct device_node *parent = of_find_n     35         struct device_node *parent = of_find_node_by_name(NULL, "vdevice");
 41         struct device_node *dn = NULL;         !!  36         char *loc_code;
 42         char *name;                            << 
 43         int rc;                                << 
 44                                                    37 
 45         if (!parent)                               38         if (!parent)
 46                 return NULL;                       39                 return NULL;
 47                                                    40 
 48         while ((dn = of_get_next_child(parent, !!  41         for (child = of_get_next_child(parent, NULL);
 49                 rc = rpaphp_get_drc_props(dn,  !!  42                 child; child = of_get_next_child(parent, child)) {
 50                 if ((rc == 0) && (!strcmp(drc_ !!  43                 loc_code = get_property(child, "ibm,loc-code", NULL);
 51                         break;                 !!  44                 if (loc_code && !strncmp(loc_code, drc_name, strlen(drc_name)))
                                                   >>  45                         return child;
 52         }                                          46         }
 53                                                    47 
 54         return dn;                             !!  48         return NULL;
 55 }                                                  49 }
 56                                                    50 
 57 /* Find dlpar-capable pci node that contains t     51 /* Find dlpar-capable pci node that contains the specified name and type */
 58 static struct device_node *find_php_slot_pci_n     52 static struct device_node *find_php_slot_pci_node(char *drc_name,
 59                                                    53                                                   char *drc_type)
 60 {                                                  54 {
 61         struct device_node *np = NULL;             55         struct device_node *np = NULL;
 62         char *name;                                56         char *name;
 63         char *type;                                57         char *type;
 64         int rc;                                    58         int rc;
 65                                                    59 
 66         while ((np = of_find_node_by_name(np,  !!  60         while ((np = of_find_node_by_type(np, "pci"))) {
 67                 rc = rpaphp_get_drc_props(np,      61                 rc = rpaphp_get_drc_props(np, NULL, &name, &type, NULL);
 68                 if (rc == 0)                       62                 if (rc == 0)
 69                         if (!strcmp(drc_name,      63                         if (!strcmp(drc_name, name) && !strcmp(drc_type, type))
 70                                 break;             64                                 break;
 71         }                                          65         }
 72                                                    66 
 73         return np;                                 67         return np;
 74 }                                                  68 }
 75                                                    69 
 76 static struct device_node *find_dlpar_node(cha !!  70 static struct device_node *find_newly_added_node(char *drc_name, int *node_type)
 77 {                                                  71 {
 78         struct device_node *dn;                    72         struct device_node *dn;
 79                                                    73 
 80         dn = find_php_slot_pci_node(drc_name,      74         dn = find_php_slot_pci_node(drc_name, "SLOT");
 81         if (dn) {                                  75         if (dn) {
 82                 *node_type = NODE_TYPE_SLOT;       76                 *node_type = NODE_TYPE_SLOT;
 83                 return dn;                         77                 return dn;
 84         }                                          78         }
 85                                                    79 
 86         dn = find_php_slot_pci_node(drc_name,      80         dn = find_php_slot_pci_node(drc_name, "PHB");
 87         if (dn) {                                  81         if (dn) {
 88                 *node_type = NODE_TYPE_PHB;        82                 *node_type = NODE_TYPE_PHB;
 89                 return dn;                         83                 return dn;
 90         }                                          84         }
 91                                                    85 
 92         dn = find_vio_slot_node(drc_name);     !!  86         dn = find_php_slot_vio_node(drc_name);
 93         if (dn) {                                  87         if (dn) {
 94                 *node_type = NODE_TYPE_VIO;        88                 *node_type = NODE_TYPE_VIO;
 95                 return dn;                         89                 return dn;
 96         }                                          90         }
 97                                                    91 
 98         return NULL;                               92         return NULL;
 99 }                                                  93 }
100                                                    94 
101 /**                                            !!  95 static struct slot *find_slot(char *drc_name)
102  * find_php_slot - return hotplug slot structu << 
103  * @dn: target &device_node                    << 
104  *                                             << 
105  * This routine will return the hotplug slot s << 
106  * for a given device node. Note that built-in << 
107  * may be dlpar-able, but not hot-pluggable, s << 
108  * will return NULL for built-in PCI slots.    << 
109  */                                            << 
110 static struct slot *find_php_slot(struct devic << 
111 {                                                  96 {
112         struct list_head *tmp, *n;                 97         struct list_head *tmp, *n;
113         struct slot *slot;                         98         struct slot *slot;
114                                                    99 
115         list_for_each_safe(tmp, n, &rpaphp_slo !! 100         list_for_each_safe(tmp, n, &rpaphp_slot_head) {
116                 slot = list_entry(tmp, struct  !! 101                 slot = list_entry(tmp, struct slot, rpaphp_slot_list);
117                 if (slot->dn == dn)            !! 102                 if (strcmp(slot->location, drc_name) == 0)
118                         return slot;           !! 103                         return slot;
119         }                                      !! 104         }
120                                                   105 
121         return NULL;                           !! 106         return NULL;
122 }                                                 107 }
123                                                   108 
124 static struct pci_dev *dlpar_find_new_dev(stru !! 109 static void rpadlpar_claim_one_bus(struct pci_bus *b)
125                                         struct << 
126 {                                                 110 {
127         struct pci_dev *tmp = NULL;            !! 111         struct list_head *ld;
128         struct device_node *child_dn;          !! 112         struct pci_bus *child_bus;
                                                   >> 113 
                                                   >> 114         for (ld = b->devices.next; ld != &b->devices; ld = ld->next) {
                                                   >> 115                 struct pci_dev *dev = pci_dev_b(ld);
                                                   >> 116                 int i;
129                                                   117 
130         list_for_each_entry(tmp, &parent->devi !! 118                 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
131                 child_dn = pci_device_to_OF_no !! 119                         struct resource *r = &dev->resource[i];
132                 if (child_dn == dev_dn)        !! 120 
133                         return tmp;            !! 121                         if (r->parent || !r->start || !r->flags)
                                                   >> 122                                 continue;
                                                   >> 123                         rpaphp_claim_resource(dev, i);
                                                   >> 124                 }
134         }                                         125         }
135         return NULL;                           !! 126 
                                                   >> 127         list_for_each_entry(child_bus, &b->children, node)
                                                   >> 128                 rpadlpar_claim_one_bus(child_bus);
136 }                                                 129 }
137                                                   130 
138 static void dlpar_pci_add_bus(struct device_no !! 131 static int pci_add_secondary_bus(struct device_node *dn,
                                                   >> 132                 struct pci_dev *bridge_dev)
139 {                                                 133 {
140         struct pci_dn *pdn = PCI_DN(dn);       !! 134         struct pci_controller *hose = dn->phb;
141         struct pci_controller *phb = pdn->phb; !! 135         struct pci_bus *child;
142         struct pci_dev *dev = NULL;            !! 136         u8 sec_busno;
143                                                   137 
144         eeh_add_device_tree_early(dn);         !! 138         /* Get busno of downstream bus */
                                                   >> 139         pci_read_config_byte(bridge_dev, PCI_SECONDARY_BUS, &sec_busno);
145                                                   140 
146         /* Add EADS device to PHB bus, adding  !! 141         /* Allocate and add to children of bridge_dev->bus */
147         dev = of_create_pci_dev(dn, phb->bus,  !! 142         child = pci_add_new_bus(bridge_dev->bus, bridge_dev, sec_busno);
148         if (!dev) {                            !! 143         if (!child) {
149                 printk(KERN_ERR "%s: failed to !! 144                 printk(KERN_ERR "%s: could not add secondary bus\n", __FUNCTION__);
150                                 __FUNCTION__,  !! 145                 return 1;
151                 return;                        << 
152         }                                         146         }
153                                                   147 
154         if (dev->hdr_type == PCI_HEADER_TYPE_B !! 148         sprintf(child->name, "PCI Bus #%02x", child->number);
155             dev->hdr_type == PCI_HEADER_TYPE_C << 
156                 of_scan_pci_bridge(dn, dev);   << 
157                                                   149 
158         pcibios_fixup_new_pci_devices(dev->sub !! 150         /* Fixup subordinate bridge bases and resources */
                                                   >> 151         pcibios_fixup_bus(child);
159                                                   152 
160         /* Claim new bus resources */             153         /* Claim new bus resources */
161         pcibios_claim_one_bus(dev->bus);       !! 154         rpadlpar_claim_one_bus(bridge_dev->bus);
162                                                   155 
163         /* Map IO space for child bus, which m !! 156         if (hose->last_busno < child->number)
164         pcibios_map_io_space(dev->subordinate) !! 157                 hose->last_busno = child->number;
165                                                   158 
166         /* Add new devices to global lists.  R !! 159         dn->bussubno = child->number;
167         pci_bus_add_devices(phb->bus);         !! 160 
                                                   >> 161         /* ioremap() for child bus, which may or may not succeed */
                                                   >> 162         remap_bus_range(child);
                                                   >> 163 
                                                   >> 164         return 0;
168 }                                                 165 }
169                                                   166 
170 static int dlpar_add_pci_slot(char *drc_name,  !! 167 static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn)
171 {                                                 168 {
172         struct pci_dev *dev;                   !! 169         struct pci_controller *hose = dn->phb;
173         struct pci_controller *phb;            !! 170         struct pci_dev *dev = NULL;
174                                                   171 
175         if (pcibios_find_pci_bus(dn))          !! 172         /* Scan phb bus for EADS device, adding new one to bus->devices */
176                 return -EINVAL;                !! 173         if (!pci_scan_single_device(hose->bus, dn->devfn)) {
                                                   >> 174                 printk(KERN_ERR "%s: found no device on bus\n", __FUNCTION__);
                                                   >> 175                 return NULL;
                                                   >> 176         }
177                                                   177 
178         /* Add pci bus */                      !! 178         /* Add new devices to global lists.  Register in proc, sysfs. */
179         dlpar_pci_add_bus(dn);                 !! 179         pci_bus_add_devices(hose->bus);
180                                                   180 
181         /* Confirm new bridge dev was created     181         /* Confirm new bridge dev was created */
182         phb = PCI_DN(dn)->phb;                 !! 182         dev = rpaphp_find_pci_dev(dn);
183         dev = dlpar_find_new_dev(phb->bus, dn) << 
184                                                << 
185         if (!dev) {                               183         if (!dev) {
186                 printk(KERN_ERR "%s: unable to !! 184                 printk(KERN_ERR "%s: failed to add pci device\n", __FUNCTION__);
187                         drc_name);             !! 185                 return NULL;
188                 return -EIO;                   << 
189         }                                         186         }
190                                                   187 
191         if (dev->hdr_type != PCI_HEADER_TYPE_B    188         if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
192                 printk(KERN_ERR "%s: unexpecte !! 189                 printk(KERN_ERR "%s: unexpected header type %d\n",
193                         __FUNCTION__, dev->hdr !! 190                         __FUNCTION__, dev->hdr_type);
194                 return -EIO;                   !! 191                 return NULL;
195         }                                         192         }
196                                                   193 
197         /* Add hotplug slot */                 !! 194         if (pci_add_secondary_bus(dn, dev))
198         if (rpaphp_add_slot(dn)) {             !! 195                 return NULL;
199                 printk(KERN_ERR "%s: unable to !! 196 
200                         __FUNCTION__, drc_name !! 197         return dev;
                                                   >> 198 }
                                                   >> 199 
                                                   >> 200 static int dlpar_pci_remove_bus(struct pci_dev *bridge_dev)
                                                   >> 201 {
                                                   >> 202         struct pci_bus *secondary_bus;
                                                   >> 203 
                                                   >> 204         if (!bridge_dev) {
                                                   >> 205                 printk(KERN_ERR "%s: unexpected null device\n",
                                                   >> 206                         __FUNCTION__);
                                                   >> 207                 return 1;
                                                   >> 208         }
                                                   >> 209 
                                                   >> 210         secondary_bus = bridge_dev->subordinate;
                                                   >> 211 
                                                   >> 212         if (unmap_bus_range(secondary_bus)) {
                                                   >> 213                 printk(KERN_ERR "%s: failed to unmap bus range\n",
                                                   >> 214                         __FUNCTION__);
                                                   >> 215                 return 1;
                                                   >> 216         }
                                                   >> 217 
                                                   >> 218         pci_remove_bus_device(bridge_dev);
                                                   >> 219         return 0;
                                                   >> 220 }
                                                   >> 221 
                                                   >> 222 static inline int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
                                                   >> 223 {
                                                   >> 224         struct pci_dev *dev;
                                                   >> 225 
                                                   >> 226         /* Add pci bus */
                                                   >> 227         dev = dlpar_pci_add_bus(dn);
                                                   >> 228         if (!dev) {
                                                   >> 229                 printk(KERN_ERR "%s: unable to add bus %s\n", __FUNCTION__,
                                                   >> 230                         drc_name);
201                 return -EIO;                      231                 return -EIO;
202         }                                         232         }
                                                   >> 233 
203         return 0;                                 234         return 0;
204 }                                                 235 }
205                                                   236 
206 static int dlpar_remove_root_bus(struct pci_co    237 static int dlpar_remove_root_bus(struct pci_controller *phb)
207 {                                                 238 {
208         struct pci_bus *phb_bus;                  239         struct pci_bus *phb_bus;
209         int rc;                                   240         int rc;
210                                                   241 
211         phb_bus = phb->bus;                       242         phb_bus = phb->bus;
212         if (!(list_empty(&phb_bus->children) &    243         if (!(list_empty(&phb_bus->children) &&
213               list_empty(&phb_bus->devices)))     244               list_empty(&phb_bus->devices))) {
214                 return -EBUSY;                    245                 return -EBUSY;
215         }                                         246         }
216                                                   247 
217         rc = pcibios_remove_root_bus(phb);        248         rc = pcibios_remove_root_bus(phb);
218         if (rc)                                   249         if (rc)
219                 return -EIO;                      250                 return -EIO;
220                                                   251 
221         device_unregister(phb_bus->bridge);       252         device_unregister(phb_bus->bridge);
222         pci_remove_bus(phb_bus);                  253         pci_remove_bus(phb_bus);
223                                                   254 
224         return 0;                                 255         return 0;
225 }                                                 256 }
226                                                   257 
227 static int dlpar_remove_phb(char *drc_name, st !! 258 static int dlpar_remove_phb(struct slot *slot)
228 {                                                 259 {
229         struct slot *slot;                     !! 260         struct pci_controller *phb;
230         struct pci_dn *pdn;                    !! 261         struct device_node *dn;
231         int rc = 0;                               262         int rc = 0;
232                                                   263 
233         if (!pcibios_find_pci_bus(dn))         !! 264         dn = slot->dn;
234                 return -EINVAL;                !! 265         if (!dn) {
                                                   >> 266                 printk(KERN_ERR "%s: unexpected NULL slot device node\n",
                                                   >> 267                                 __FUNCTION__);
                                                   >> 268                 return -EIO;
                                                   >> 269         }
                                                   >> 270 
                                                   >> 271         phb = dn->phb;
                                                   >> 272         if (!phb) {
                                                   >> 273                 printk(KERN_ERR "%s: unexpected NULL phb pointer\n",
                                                   >> 274                                 __FUNCTION__);
                                                   >> 275                 return -EIO;
                                                   >> 276         }
235                                                   277 
236         /* If pci slot is hotplugable, use hot !! 278         if (rpaphp_remove_slot(slot)) {
237         slot = find_php_slot(dn);              !! 279                 printk(KERN_ERR "%s: unable to remove hotplug slot %s\n",
238         if (slot) {                            !! 280                         __FUNCTION__, slot->location);
239                 if (rpaphp_deregister_slot(slo !! 281                 return -EIO;
240                         printk(KERN_ERR        << 
241                                 "%s: unable to << 
242                                 __FUNCTION__,  << 
243                         return -EIO;           << 
244                 }                              << 
245         }                                         282         }
246                                                   283 
247         pdn = dn->data;                        !! 284         rc = dlpar_remove_root_bus(phb);
248         BUG_ON(!pdn || !pdn->phb);             !! 285         if (rc)
249         rc = dlpar_remove_root_bus(pdn->phb);  << 
250         if (rc < 0)                            << 
251                 return rc;                        286                 return rc;
252                                                   287 
253         pdn->phb = NULL;                       << 
254                                                << 
255         return 0;                                 288         return 0;
256 }                                                 289 }
257                                                   290 
258 static int dlpar_add_phb(char *drc_name, struc !! 291 static int dlpar_add_phb(struct device_node *dn)
259 {                                                 292 {
260         struct pci_controller *phb;               293         struct pci_controller *phb;
261                                                   294 
262         if (PCI_DN(dn) && PCI_DN(dn)->phb) {   << 
263                 /* PHB already exists */       << 
264                 return -EINVAL;                << 
265         }                                      << 
266                                                << 
267         phb = init_phb_dynamic(dn);               295         phb = init_phb_dynamic(dn);
268         if (!phb)                                 296         if (!phb)
269                 return -EIO;                   !! 297                 return 1;
270                                                   298 
271         if (rpaphp_add_slot(dn)) {             << 
272                 printk(KERN_ERR "%s: unable to << 
273                         __FUNCTION__, drc_name << 
274                 return -EIO;                   << 
275         }                                      << 
276         return 0;                              << 
277 }                                              << 
278                                                << 
279 static int dlpar_add_vio_slot(char *drc_name,  << 
280 {                                              << 
281         if (vio_find_node(dn))                 << 
282                 return -EINVAL;                << 
283                                                << 
284         if (!vio_register_device_node(dn)) {   << 
285                 printk(KERN_ERR                << 
286                         "%s: failed to registe << 
287                         __FUNCTION__, drc_name << 
288                 return -EIO;                   << 
289         }                                      << 
290         return 0;                                 299         return 0;
291 }                                                 300 }
292                                                   301 
293 /**                                               302 /**
294  * dlpar_add_slot - DLPAR add an I/O Slot         303  * dlpar_add_slot - DLPAR add an I/O Slot
295  * @drc_name: drc-name of newly added slot        304  * @drc_name: drc-name of newly added slot
296  *                                                305  *
297  * Make the hotplug module and the kernel awar !! 306  * Make the hotplug module and the kernel aware
298  * Return Codes:                               !! 307  * of a newly added I/O Slot.
                                                   >> 308  * Return Codes -
299  * 0                    Success                   309  * 0                    Success
300  * -ENODEV              Not a valid drc_name      310  * -ENODEV              Not a valid drc_name
301  * -EINVAL              Slot already added        311  * -EINVAL              Slot already added
302  * -ERESTARTSYS         Signalled before obtai    312  * -ERESTARTSYS         Signalled before obtaining lock
303  * -EIO                 Internal PCI Error        313  * -EIO                 Internal PCI Error
304  */                                               314  */
305 int dlpar_add_slot(char *drc_name)                315 int dlpar_add_slot(char *drc_name)
306 {                                                 316 {
307         struct device_node *dn = NULL;            317         struct device_node *dn = NULL;
308         int node_type;                            318         int node_type;
309         int rc = -EIO;                         !! 319         int rc = 0;
310                                                   320 
311         if (mutex_lock_interruptible(&rpadlpar !! 321         if (down_interruptible(&rpadlpar_sem))
312                 return -ERESTARTSYS;              322                 return -ERESTARTSYS;
313                                                   323 
314         /* Find newly added node */            !! 324         /* Check for existing hotplug slot */
315         dn = find_dlpar_node(drc_name, &node_t !! 325         if (find_slot(drc_name)) {
                                                   >> 326                 rc = -EINVAL;
                                                   >> 327                 goto exit;
                                                   >> 328         }
                                                   >> 329 
                                                   >> 330         dn = find_newly_added_node(drc_name, &node_type);
316         if (!dn) {                                331         if (!dn) {
317                 rc = -ENODEV;                     332                 rc = -ENODEV;
318                 goto exit;                        333                 goto exit;
319         }                                         334         }
320                                                   335 
321         switch (node_type) {                      336         switch (node_type) {
322                 case NODE_TYPE_VIO:               337                 case NODE_TYPE_VIO:
323                         rc = dlpar_add_vio_slo !! 338                         /* Just add hotplug slot */
324                         break;                    339                         break;
325                 case NODE_TYPE_SLOT:              340                 case NODE_TYPE_SLOT:
326                         rc = dlpar_add_pci_slo    341                         rc = dlpar_add_pci_slot(drc_name, dn);
327                         break;                    342                         break;
328                 case NODE_TYPE_PHB:               343                 case NODE_TYPE_PHB:
329                         rc = dlpar_add_phb(drc !! 344                         rc = dlpar_add_phb(dn);
330                         break;                    345                         break;
                                                   >> 346                 default:
                                                   >> 347                         printk("%s: unexpected node type\n", __FUNCTION__);
                                                   >> 348                         return -EIO;
331         }                                         349         }
332                                                   350 
333         printk(KERN_INFO "%s: slot %s added\n" !! 351         if (!rc && rpaphp_add_slot(dn)) {
                                                   >> 352                 printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
                                                   >> 353                         __FUNCTION__, drc_name);
                                                   >> 354                 rc = -EIO;
                                                   >> 355         }
334 exit:                                             356 exit:
335         mutex_unlock(&rpadlpar_mutex);         !! 357         up(&rpadlpar_sem);
336         return rc;                                358         return rc;
337 }                                                 359 }
338                                                   360 
339 /**                                               361 /**
340  * dlpar_remove_vio_slot - DLPAR remove a virt    362  * dlpar_remove_vio_slot - DLPAR remove a virtual I/O Slot
341  * @drc_name: drc-name of newly added slot        363  * @drc_name: drc-name of newly added slot
342  * @dn: &device_node                           << 
343  *                                                364  *
344  * Remove the kernel and hotplug representatio !! 365  * Remove the kernel and hotplug representations
                                                   >> 366  * of an I/O Slot.
345  * Return Codes:                                  367  * Return Codes:
346  * 0                    Success                   368  * 0                    Success
347  * -EINVAL              Vio dev doesn't exist  !! 369  * -EIO                 Internal  Error
348  */                                               370  */
349 static int dlpar_remove_vio_slot(char *drc_nam !! 371 int dlpar_remove_vio_slot(struct slot *slot, char *drc_name)
350 {                                                 372 {
351         struct vio_dev *vio_dev;               !! 373         /* Remove hotplug slot */
352                                                << 
353         vio_dev = vio_find_node(dn);           << 
354         if (!vio_dev)                          << 
355                 return -EINVAL;                << 
356                                                   374 
357         vio_unregister_device(vio_dev);        !! 375         if (rpaphp_remove_slot(slot)) {
                                                   >> 376                 printk(KERN_ERR "%s: unable to remove hotplug slot %s\n",
                                                   >> 377                         __FUNCTION__, drc_name);
                                                   >> 378                 return -EIO;
                                                   >> 379         }
358         return 0;                                 380         return 0;
359 }                                                 381 }
360                                                   382 
361 /**                                               383 /**
362  * dlpar_remove_pci_slot - DLPAR remove a PCI  !! 384  * dlpar_remove_slot - DLPAR remove a PCI I/O Slot
363  * @drc_name: drc-name of newly added slot        385  * @drc_name: drc-name of newly added slot
364  * @dn: &device_node                           << 
365  *                                                386  *
366  * Remove the kernel and hotplug representatio !! 387  * Remove the kernel and hotplug representations
                                                   >> 388  * of a PCI I/O Slot.
367  * Return Codes:                                  389  * Return Codes:
368  * 0                    Success                   390  * 0                    Success
369  * -ENODEV              Not a valid drc_name      391  * -ENODEV              Not a valid drc_name
370  * -EIO                 Internal PCI Error        392  * -EIO                 Internal PCI Error
371  */                                               393  */
372 int dlpar_remove_pci_slot(char *drc_name, stru !! 394 int dlpar_remove_pci_slot(struct slot *slot, char *drc_name)
373 {                                                 395 {
374         struct pci_bus *bus;                   !! 396         struct pci_dev *bridge_dev;
375         struct slot *slot;                     << 
376                                                   397 
377         bus = pcibios_find_pci_bus(dn);        !! 398         bridge_dev = slot->bridge;
378         if (!bus)                              !! 399         if (!bridge_dev) {
379                 return -EINVAL;                !! 400                 printk(KERN_ERR "%s: unexpected null bridge device\n",
380                                                << 
381         /* If pci slot is hotplugable, use hot << 
382         slot = find_php_slot(dn);              << 
383         if (slot) {                            << 
384                 if (rpaphp_deregister_slot(slo << 
385                         printk(KERN_ERR        << 
386                                 "%s: unable to << 
387                                 __FUNCTION__,  << 
388                         return -EIO;           << 
389                 }                              << 
390         } else                                 << 
391                 pcibios_remove_pci_devices(bus << 
392                                                << 
393         if (pcibios_unmap_io_space(bus)) {     << 
394                 printk(KERN_ERR "%s: failed to << 
395                         __FUNCTION__);            401                         __FUNCTION__);
396                 return -ERANGE;                !! 402                 return -EIO;
397         }                                         403         }
398                                                   404 
399         BUG_ON(!bus->self);                    !! 405         /* Remove hotplug slot */
400         pci_remove_bus_device(bus->self);      !! 406         if (rpaphp_remove_slot(slot)) {
                                                   >> 407                 printk(KERN_ERR "%s: unable to remove hotplug slot %s\n",
                                                   >> 408                         __FUNCTION__, drc_name);
                                                   >> 409                 return -EIO;
                                                   >> 410         }
                                                   >> 411 
                                                   >> 412         /* Remove pci bus */
                                                   >> 413 
                                                   >> 414         if (dlpar_pci_remove_bus(bridge_dev)) {
                                                   >> 415                 printk(KERN_ERR "%s: unable to remove pci bus %s\n",
                                                   >> 416                         __FUNCTION__, drc_name);
                                                   >> 417                 return -EIO;
                                                   >> 418         }
401         return 0;                                 419         return 0;
402 }                                                 420 }
403                                                   421 
404 /**                                               422 /**
405  * dlpar_remove_slot - DLPAR remove an I/O Slo    423  * dlpar_remove_slot - DLPAR remove an I/O Slot
406  * @drc_name: drc-name of newly added slot        424  * @drc_name: drc-name of newly added slot
407  *                                                425  *
408  * Remove the kernel and hotplug representatio !! 426  * Remove the kernel and hotplug representations
                                                   >> 427  * of an I/O Slot.
409  * Return Codes:                                  428  * Return Codes:
410  * 0                    Success                   429  * 0                    Success
411  * -ENODEV              Not a valid drc_name      430  * -ENODEV              Not a valid drc_name
412  * -EINVAL              Slot already removed      431  * -EINVAL              Slot already removed
413  * -ERESTARTSYS         Signalled before obtai    432  * -ERESTARTSYS         Signalled before obtaining lock
414  * -EIO                 Internal Error            433  * -EIO                 Internal Error
415  */                                               434  */
416 int dlpar_remove_slot(char *drc_name)             435 int dlpar_remove_slot(char *drc_name)
417 {                                                 436 {
418         struct device_node *dn;                !! 437         struct slot *slot;
419         int node_type;                         << 
420         int rc = 0;                               438         int rc = 0;
421                                                   439 
422         if (mutex_lock_interruptible(&rpadlpar !! 440         if (down_interruptible(&rpadlpar_sem))
423                 return -ERESTARTSYS;              441                 return -ERESTARTSYS;
424                                                   442 
425         dn = find_dlpar_node(drc_name, &node_t !! 443         if (!find_php_slot_vio_node(drc_name) &&
426         if (!dn) {                             !! 444             !find_php_slot_pci_node(drc_name, "SLOT") &&
                                                   >> 445             !find_php_slot_pci_node(drc_name, "PHB")) {
427                 rc = -ENODEV;                     446                 rc = -ENODEV;
428                 goto exit;                        447                 goto exit;
429         }                                         448         }
430                                                   449 
431         switch (node_type) {                   !! 450         slot = find_slot(drc_name);
432                 case NODE_TYPE_VIO:            !! 451         if (!slot) {
433                         rc = dlpar_remove_vio_ !! 452                 rc = -EINVAL;
434                         break;                 !! 453                 goto exit;
435                 case NODE_TYPE_PHB:            !! 454         }
436                         rc = dlpar_remove_phb( !! 455         
437                         break;                 !! 456         if (slot->type == PHB) {
438                 case NODE_TYPE_SLOT:           !! 457                 rc = dlpar_remove_phb(slot);
439                         rc = dlpar_remove_pci_ !! 458         } else {
440                         break;                 !! 459                 switch (slot->dev_type) {
                                                   >> 460                         case PCI_DEV:
                                                   >> 461                                 rc = dlpar_remove_pci_slot(slot, drc_name);
                                                   >> 462                                 break;
                                                   >> 463 
                                                   >> 464                         case VIO_DEV:
                                                   >> 465                                 rc = dlpar_remove_vio_slot(slot, drc_name);
                                                   >> 466                                 break;
                                                   >> 467                 }
441         }                                         468         }
442         printk(KERN_INFO "%s: slot %s removed\ << 
443 exit:                                             469 exit:
444         mutex_unlock(&rpadlpar_mutex);         !! 470         up(&rpadlpar_sem);
445         return rc;                                471         return rc;
446 }                                                 472 }
447                                                   473 
448 static inline int is_dlpar_capable(void)          474 static inline int is_dlpar_capable(void)
449 {                                                 475 {
450         int rc = rtas_token("ibm,configure-con    476         int rc = rtas_token("ibm,configure-connector");
451                                                   477 
452         return (int) (rc != RTAS_UNKNOWN_SERVI    478         return (int) (rc != RTAS_UNKNOWN_SERVICE);
453 }                                                 479 }
454                                                   480 
455 int __init rpadlpar_io_init(void)                 481 int __init rpadlpar_io_init(void)
456 {                                                 482 {
457         int rc = 0;                               483         int rc = 0;
458                                                   484 
459         if (!is_dlpar_capable()) {                485         if (!is_dlpar_capable()) {
460                 printk(KERN_WARNING "%s: parti    486                 printk(KERN_WARNING "%s: partition not DLPAR capable\n",
461                         __FUNCTION__);            487                         __FUNCTION__);
462                 return -EPERM;                    488                 return -EPERM;
463         }                                         489         }
464                                                   490 
465         rc = dlpar_sysfs_init();                  491         rc = dlpar_sysfs_init();
466         return rc;                                492         return rc;
467 }                                                 493 }
468                                                   494 
469 void rpadlpar_io_exit(void)                       495 void rpadlpar_io_exit(void)
470 {                                                 496 {
471         dlpar_sysfs_exit();                       497         dlpar_sysfs_exit();
472         return;                                   498         return;
473 }                                                 499 }
474                                                   500 
475 module_init(rpadlpar_io_init);                    501 module_init(rpadlpar_io_init);
476 module_exit(rpadlpar_io_exit);                    502 module_exit(rpadlpar_io_exit);
477 MODULE_LICENSE("GPL");                            503 MODULE_LICENSE("GPL");
478                                                   504 
  This page was automatically generated by the LXR engine.