1 /* 2 * PCI Hot Plug Controller Driver for RPA-compliant PPC64 platform. 3 * Copyright (C) 2003 Linda Xie <lxie@us.ibm.com> 4 * 5 * All rights reserved. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or (at 10 * your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 15 * NON INFRINGEMENT. See the GNU General Public License for more 16 * details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 * 22 * Send feedback to <lxie@us.ibm.com> 23 * 24 */ 25 #include <linux/pci.h> 26 #include <asm/pci-bridge.h> 27 #include <asm/rtas.h> 28 #include <asm/machdep.h> 29 #include "../pci.h" /* for pci_add_new_bus */ 30 31 #include "rpaphp.h" 32 33 static struct pci_bus *find_bus_among_children(struct pci_bus *bus, 34 struct device_node *dn) 35 { 36 struct pci_bus *child = NULL; 37 struct list_head *tmp; 38 struct device_node *busdn; 39 40 busdn = pci_bus_to_OF_node(bus); 41 if (busdn == dn) 42 return bus; 43 44 list_for_each(tmp, &bus->children) { 45 child = find_bus_among_children(pci_bus_b(tmp), dn); 46 if (child) 47 break; 48 } 49 return child; 50 } 51 52 struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn) 53 { 54 if (!dn->phb || !dn->phb->bus) 55 return NULL; 56 57 return find_bus_among_children(dn->phb->bus, dn); 58 } 59 EXPORT_SYMBOL_GPL(rpaphp_find_pci_bus); 60 61 int rpaphp_claim_resource(struct pci_dev *dev, int resource) 62 { 63 struct resource *res = &dev->resource[resource]; 64 struct resource *root = pci_find_parent_resource(dev, res); 65 char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge"; 66 int err = -EINVAL; 67 68 if (root != NULL) { 69 err = request_resource(root, res); 70 } 71 72 if (err) { 73 err("PCI: %s region %d of %s %s [%lx:%lx]\n", 74 root ? "Address space collision on" : 75 "No parent found for", 76 resource, dtype, pci_name(dev), res->start, res->end); 77 } 78 return err; 79 } 80 81 EXPORT_SYMBOL_GPL(rpaphp_claim_resource); 82 83 static int rpaphp_get_sensor_state(struct slot *slot, int *state) 84 { 85 int rc; 86 int setlevel; 87 88 rc = rtas_get_sensor(DR_ENTITY_SENSE, slot->index, state); 89 90 if (rc < 0) { 91 if (rc == -EFAULT || rc == -EEXIST) { 92 dbg("%s: slot must be power up to get sensor-state\n", 93 __FUNCTION__); 94 95 /* some slots have to be powered up 96 * before get-sensor will succeed. 97 */ 98 rc = rtas_set_power_level(slot->power_domain, POWER_ON, 99 &setlevel); 100 if (rc < 0) { 101 dbg("%s: power on slot[%s] failed rc=%d.\n", 102 __FUNCTION__, slot->name, rc); 103 } else { 104 rc = rtas_get_sensor(DR_ENTITY_SENSE, 105 slot->index, state); 106 } 107 } else if (rc == -ENODEV) 108 info("%s: slot is unusable\n", __FUNCTION__); 109 else 110 err("%s failed to get sensor state\n", __FUNCTION__); 111 } 112 return rc; 113 } 114 115 /** 116 * get_pci_adapter_status - get the status of a slot 117 * 118 * 0-- slot is empty 119 * 1-- adapter is configured 120 * 2-- adapter is not configured 121 * 3-- not valid 122 */ 123 int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value) 124 { 125 struct pci_bus *bus; 126 int state, rc; 127 128 *value = NOT_VALID; 129 rc = rpaphp_get_sensor_state(slot, &state); 130 if (rc) 131 goto exit; 132 133 if (state == EMPTY) 134 *value = EMPTY; 135 else if (state == PRESENT) { 136 if (!is_init) { 137 /* at run-time slot->state can be changed by */ 138 /* config/unconfig adapter */ 139 *value = slot->state; 140 } else { 141 bus = rpaphp_find_pci_bus(slot->dn); 142 if (bus && !list_empty(&bus->devices)) 143 *value = CONFIGURED; 144 else 145 *value = NOT_CONFIGURED; 146 } 147 } 148 exit: 149 return rc; 150 } 151 152 /* Must be called before pci_bus_add_devices */ 153 static void 154 rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus) 155 { 156 struct pci_dev *dev; 157 158 list_for_each_entry(dev, &bus->devices, bus_list) { 159 /* 160 * Skip already-present devices (which are on the 161 * global device list.) 162 */ 163 if (list_empty(&dev->global_list)) { 164 int i; 165 166 /* Need to setup IOMMU tables */ 167 ppc_md.iommu_dev_setup(dev); 168 169 if(fix_bus) 170 pcibios_fixup_device_resources(dev, bus); 171 pci_read_irq_line(dev); 172 for (i = 0; i < PCI_NUM_RESOURCES; i++) { 173 struct resource *r = &dev->resource[i]; 174 175 if (r->parent || !r->start || !r->flags) 176 continue; 177 rpaphp_claim_resource(dev, i); 178 } 179 } 180 } 181 } 182 183 static int rpaphp_pci_config_bridge(struct pci_dev *dev) 184 { 185 u8 sec_busno; 186 struct pci_bus *child_bus; 187 struct pci_dev *child_dev; 188 189 dbg("Enter %s: BRIDGE dev=%s\n", __FUNCTION__, pci_name(dev)); 190 191 /* get busno of downstream bus */ 192 pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno); 193 194 /* add to children of PCI bridge dev->bus */ 195 child_bus = pci_add_new_bus(dev->bus, dev, sec_busno); 196 if (!child_bus) { 197 err("%s: could not add second bus\n", __FUNCTION__); 198 return -EIO; 199 } 200 sprintf(child_bus->name, "PCI Bus #%02x", child_bus->number); 201 /* do pci_scan_child_bus */ 202 pci_scan_child_bus(child_bus); 203 204 list_for_each_entry(child_dev, &child_bus->devices, bus_list) { 205 eeh_add_device_late(child_dev); 206 } 207 208 /* fixup new pci devices without touching bus struct */ 209 rpaphp_fixup_new_pci_devices(child_bus, 0); 210 211 /* Make the discovered devices available */ 212 pci_bus_add_devices(child_bus); 213 return 0; 214 } 215 216 /***************************************************************************** 217 rpaphp_pci_config_slot() will configure all devices under the 218 given slot->dn and return the the first pci_dev. 219 *****************************************************************************/ 220 static struct pci_dev * 221 rpaphp_pci_config_slot(struct pci_bus *bus) 222 { 223 struct device_node *dn = pci_bus_to_OF_node(bus); 224 struct pci_dev *dev = NULL; 225 int slotno; 226 int num; 227 228 dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name); 229 if (!dn || !dn->child) 230 return NULL; 231 232 slotno = PCI_SLOT(dn->child->devfn); 233 234 /* pci_scan_slot should find all children */ 235 num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); 236 if (num) { 237 rpaphp_fixup_new_pci_devices(bus, 1); 238 pci_bus_add_devices(bus); 239 } 240 if (list_empty(&bus->devices)) { 241 err("%s: No new device found\n", __FUNCTION__); 242 return NULL; 243 } 244 list_for_each_entry(dev, &bus->devices, bus_list) { 245 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) 246 rpaphp_pci_config_bridge(dev); 247 } 248 249 return dev; 250 } 251 252 static void enable_eeh(struct device_node *dn) 253 { 254 struct device_node *sib; 255 256 for (sib = dn->child; sib; sib = sib->sibling) 257 enable_eeh(sib); 258 eeh_add_device_early(dn); 259 return; 260 261 } 262 263 static void print_slot_pci_funcs(struct pci_bus *bus) 264 { 265 struct device_node *dn; 266 struct pci_dev *dev; 267 268 dn = pci_bus_to_OF_node(bus); 269 if (!dn) 270 return; 271 272 dbg("%s: pci_devs of slot[%s]\n", __FUNCTION__, dn->full_name); 273 list_for_each_entry (dev, &bus->devices, bus_list) 274 dbg("\t%s\n", pci_name(dev)); 275 return; 276 } 277 278 int rpaphp_config_pci_adapter(struct pci_bus *bus) 279 { 280 struct device_node *dn = pci_bus_to_OF_node(bus); 281 struct pci_dev *dev; 282 int rc = -ENODEV; 283 284 dbg("Entry %s: slot[%s]\n", __FUNCTION__, dn->full_name); 285 if (!dn) 286 goto exit; 287 288 enable_eeh(dn); 289 dev = rpaphp_pci_config_slot(bus); 290 if (!dev) { 291 err("%s: can't find any devices.\n", __FUNCTION__); 292 goto exit; 293 } 294 print_slot_pci_funcs(bus); 295 rc = 0; 296 exit: 297 dbg("Exit %s: rc=%d\n", __FUNCTION__, rc); 298 return rc; 299 } 300 EXPORT_SYMBOL_GPL(rpaphp_config_pci_adapter); 301 302 static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev) 303 { 304 eeh_remove_device(dev); 305 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { 306 struct pci_bus *bus = dev->subordinate; 307 struct list_head *ln; 308 if (!bus) 309 return; 310 for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { 311 struct pci_dev *pdev = pci_dev_b(ln); 312 if (pdev) 313 rpaphp_eeh_remove_bus_device(pdev); 314 } 315 316 } 317 return; 318 } 319 320 int rpaphp_unconfig_pci_adapter(struct slot *slot) 321 { 322 struct pci_dev *dev, *tmp; 323 int retval = 0; 324 325 list_for_each_entry_safe(dev, tmp, slot->pci_devs, bus_list) { 326 rpaphp_eeh_remove_bus_device(dev); 327 pci_remove_bus_device(dev); 328 } 329 330 slot->state = NOT_CONFIGURED; 331 info("%s: devices in slot[%s] unconfigured.\n", __FUNCTION__, 332 slot->name); 333 return retval; 334 } 335 336 static int setup_pci_hotplug_slot_info(struct slot *slot) 337 { 338 dbg("%s Initilize the PCI slot's hotplug->info structure ...\n", 339 __FUNCTION__); 340 rpaphp_get_power_status(slot, &slot->hotplug_slot->info->power_status); 341 rpaphp_get_pci_adapter_status(slot, 1, 342 &slot->hotplug_slot->info-> 343 adapter_status); 344 if (slot->hotplug_slot->info->adapter_status == NOT_VALID) { 345 err("%s: NOT_VALID: skip dn->full_name=%s\n", 346 __FUNCTION__, slot->dn->full_name); 347 return -EINVAL; 348 } 349 return 0; 350 } 351 352 static void set_slot_name(struct slot *slot) 353 { 354 struct pci_bus *bus = slot->bus; 355 struct pci_dev *bridge; 356 357 bridge = bus->self; 358 if (bridge) 359 strcpy(slot->name, pci_name(bridge)); 360 else 361 sprintf(slot->name, "%04x:%02x:00.0", pci_domain_nr(bus), 362 bus->number); 363 } 364 365 static int setup_pci_slot(struct slot *slot) 366 { 367 struct device_node *dn = slot->dn; 368 struct pci_bus *bus; 369 370 BUG_ON(!dn); 371 bus = rpaphp_find_pci_bus(dn); 372 if (!bus) { 373 err("%s: no pci_bus for dn %s\n", __FUNCTION__, dn->full_name); 374 goto exit_rc; 375 } 376 377 slot->bus = bus; 378 slot->pci_devs = &bus->devices; 379 set_slot_name(slot); 380 381 /* find slot's pci_dev if it's not empty */ 382 if (slot->hotplug_slot->info->adapter_status == EMPTY) { 383 slot->state = EMPTY; /* slot is empty */ 384 } else { 385 /* slot is occupied */ 386 if (!dn->child) { 387 /* non-empty slot has to have child */ 388 err("%s: slot[%s]'s device_node doesn't have child for adapter\n", 389 __FUNCTION__, slot->name); 390 goto exit_rc; 391 } 392 393 if (slot->hotplug_slot->info->adapter_status == NOT_CONFIGURED) { 394 dbg("%s CONFIGURING pci adapter in slot[%s]\n", 395 __FUNCTION__, slot->name); 396 if (rpaphp_config_pci_adapter(slot->bus)) { 397 err("%s: CONFIG pci adapter failed\n", __FUNCTION__); 398 goto exit_rc; 399 } 400 401 } else if (slot->hotplug_slot->info->adapter_status != CONFIGURED) { 402 err("%s: slot[%s]'s adapter_status is NOT_VALID.\n", 403 __FUNCTION__, slot->name); 404 goto exit_rc; 405 } 406 print_slot_pci_funcs(slot->bus); 407 if (!list_empty(slot->pci_devs)) { 408 slot->state = CONFIGURED; 409 } else { 410 /* DLPAR add as opposed to 411 * boot time */ 412 slot->state = NOT_CONFIGURED; 413 } 414 } 415 return 0; 416 exit_rc: 417 dealloc_slot_struct(slot); 418 return -EINVAL; 419 } 420 421 int register_pci_slot(struct slot *slot) 422 { 423 int rc = -EINVAL; 424 425 if (setup_pci_hotplug_slot_info(slot)) 426 goto exit_rc; 427 if (setup_pci_slot(slot)) 428 goto exit_rc; 429 rc = register_slot(slot); 430 exit_rc: 431 return rc; 432 } 433 434 int rpaphp_enable_pci_slot(struct slot *slot) 435 { 436 int retval = 0, state; 437 438 retval = rpaphp_get_sensor_state(slot, &state); 439 if (retval) 440 goto exit; 441 dbg("%s: sensor state[%d]\n", __FUNCTION__, state); 442 /* if slot is not empty, enable the adapter */ 443 if (state == PRESENT) { 444 dbg("%s : slot[%s] is occupied.\n", __FUNCTION__, slot->name); 445 retval = rpaphp_config_pci_adapter(slot->bus); 446 if (!retval) { 447 slot->state = CONFIGURED; 448 dbg("%s: PCI devices in slot[%s] has been configured\n", 449 __FUNCTION__, slot->name); 450 } else { 451 slot->state = NOT_CONFIGURED; 452 dbg("%s: no pci_dev struct for adapter in slot[%s]\n", 453 __FUNCTION__, slot->name); 454 } 455 } else if (state == EMPTY) { 456 dbg("%s : slot[%s] is empty\n", __FUNCTION__, slot->name); 457 slot->state = EMPTY; 458 } else { 459 err("%s: slot[%s] is in invalid state\n", __FUNCTION__, 460 slot->name); 461 slot->state = NOT_VALID; 462 retval = -EINVAL; 463 } 464 exit: 465 dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); 466 return retval; 467 } 468