rpaphp_pci.c revision 01657868be1c21b2b8b0e683ea24bdcc2331d522
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PCI Hot Plug Controller Driver for RPA-compliant PPC64 platform. 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2003 Linda Xie <lxie@us.ibm.com> 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * All rights reserved. 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or modify 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it under the terms of the GNU General Public License as published by 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the Free Software Foundation; either version 2 of the License, or (at 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * your option) any later version. 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is distributed in the hope that it will be useful, but 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * WITHOUT ANY WARRANTY; without even the implied warranty of 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NON INFRINGEMENT. See the GNU General Public License for more 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * details. 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * You should have received a copy of the GNU General Public License 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * along with this program; if not, write to the Free Software 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Send feedback to <lxie@us.ibm.com> 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pci.h> 264e57b6817880946a3a78d5d8cad1ace363f7e449Tim Schmielau#include <linux/string.h> 274e57b6817880946a3a78d5d8cad1ace363f7e449Tim Schmielau 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/pci-bridge.h> 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/rtas.h> 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/machdep.h> 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 324e57b6817880946a3a78d5d8cad1ace363f7e449Tim Schmielau#include "../pci.h" /* for pci_add_new_bus */ 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "rpaphp.h" 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int rpaphp_get_sensor_state(struct slot *slot, int *state) 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rc; 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int setlevel; 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc = rtas_get_sensor(DR_ENTITY_SENSE, slot->index, state); 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rc < 0) { 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rc == -EFAULT || rc == -EEXIST) { 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dbg("%s: slot must be power up to get sensor-state\n", 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __FUNCTION__); 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* some slots have to be powered up 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * before get-sensor will succeed. 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc = rtas_set_power_level(slot->power_domain, POWER_ON, 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &setlevel); 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rc < 0) { 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dbg("%s: power on slot[%s] failed rc=%d.\n", 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __FUNCTION__, slot->name, rc); 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc = rtas_get_sensor(DR_ENTITY_SENSE, 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds slot->index, state); 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (rc == -ENODEV) 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds info("%s: slot is unusable\n", __FUNCTION__); 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err("%s failed to get sensor state\n", __FUNCTION__); 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return rc; 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * get_pci_adapter_status - get the status of a slot 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0-- slot is empty 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1-- adapter is configured 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2-- adapter is not configured 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3-- not valid 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value) 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 770945cd5f908a09ad99bf42d7ded16f26f24f317dJohn Rose struct pci_bus *bus; 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int state, rc; 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *value = NOT_VALID; 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc = rpaphp_get_sensor_state(slot, &state); 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rc) 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto exit; 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8556d8456b06ad1316bff3c75caed5e06e786f20d8John Rose if (state == EMPTY) 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *value = EMPTY; 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (state == PRESENT) { 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!is_init) { 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* at run-time slot->state can be changed by */ 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* config/unconfig adapter */ 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *value = slot->state; 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 9301657868be1c21b2b8b0e683ea24bdcc2331d522Linas Vepstas bus = pcibios_find_pci_bus(slot->dn); 940945cd5f908a09ad99bf42d7ded16f26f24f317dJohn Rose if (bus && !list_empty(&bus->devices)) 950945cd5f908a09ad99bf42d7ded16f26f24f317dJohn Rose *value = CONFIGURED; 960945cd5f908a09ad99bf42d7ded16f26f24f317dJohn Rose else 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *value = NOT_CONFIGURED; 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsexit: 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return rc; 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Must be called before pci_bus_add_devices */ 1055fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rosevoid rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus) 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_dev *dev; 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds list_for_each_entry(dev, &bus->devices, bus_list) { 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Skip already-present devices (which are on the 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * global device list.) 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (list_empty(&dev->global_list)) { 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Need to setup IOMMU tables */ 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ppc_md.iommu_dev_setup(dev); 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(fix_bus) 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pcibios_fixup_device_resources(dev, bus); 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_irq_line(dev); 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < PCI_NUM_RESOURCES; i++) { 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct resource *r = &dev->resource[i]; 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (r->parent || !r->start || !r->flags) 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 128cd5b50be8d8e8e6170da3a261fc625fd603f9dc4Linas Vepstas pci_claim_resource(dev, i); 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1345fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rosestatic void rpaphp_eeh_add_bus_device(struct pci_bus *bus) 1355fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose{ 1365fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose struct pci_dev *dev; 1375fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose 1385fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose list_for_each_entry(dev, &bus->devices, bus_list) { 1395fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose eeh_add_device_late(dev); 1405fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { 1415fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose struct pci_bus *subbus = dev->subordinate; 1425fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose if (subbus) 1435fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose rpaphp_eeh_add_bus_device (subbus); 1445fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose } 1455fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose } 1465fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose} 1475fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int rpaphp_pci_config_bridge(struct pci_dev *dev) 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 sec_busno; 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_bus *child_bus; 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_dev *child_dev; 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dbg("Enter %s: BRIDGE dev=%s\n", __FUNCTION__, pci_name(dev)); 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* get busno of downstream bus */ 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno); 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* add to children of PCI bridge dev->bus */ 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds child_bus = pci_add_new_bus(dev->bus, dev, sec_busno); 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!child_bus) { 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err("%s: could not add second bus\n", __FUNCTION__); 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EIO; 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sprintf(child_bus->name, "PCI Bus #%02x", child_bus->number); 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* do pci_scan_child_bus */ 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_scan_child_bus(child_bus); 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds list_for_each_entry(child_dev, &child_bus->devices, bus_list) { 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds eeh_add_device_late(child_dev); 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* fixup new pci devices without touching bus struct */ 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rpaphp_fixup_new_pci_devices(child_bus, 0); 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Make the discovered devices available */ 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_bus_add_devices(child_bus); 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1815fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rosevoid rpaphp_init_new_devs(struct pci_bus *bus) 1825fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose{ 1835fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose rpaphp_fixup_new_pci_devices(bus, 0); 1845fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose rpaphp_eeh_add_bus_device(bus); 1855fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose} 1865fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John RoseEXPORT_SYMBOL_GPL(rpaphp_init_new_devs); 1875fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose 188bde168412440084e649e7e04938bd1ab6e7bf978John Rose/***************************************************************************** 189bde168412440084e649e7e04938bd1ab6e7bf978John Rose rpaphp_pci_config_slot() will configure all devices under the 190bde168412440084e649e7e04938bd1ab6e7bf978John Rose given slot->dn and return the the first pci_dev. 191bde168412440084e649e7e04938bd1ab6e7bf978John Rose *****************************************************************************/ 192bde168412440084e649e7e04938bd1ab6e7bf978John Rosestatic struct pci_dev * 193940903c5a5a906c622a79b3101586deb1a1b3480John Roserpaphp_pci_config_slot(struct pci_bus *bus) 194bde168412440084e649e7e04938bd1ab6e7bf978John Rose{ 195940903c5a5a906c622a79b3101586deb1a1b3480John Rose struct device_node *dn = pci_bus_to_OF_node(bus); 196bde168412440084e649e7e04938bd1ab6e7bf978John Rose struct pci_dev *dev = NULL; 1979c209c919df95f83aa042b3352c43841ad15a02bJohn Rose int slotno; 198bde168412440084e649e7e04938bd1ab6e7bf978John Rose int num; 199bde168412440084e649e7e04938bd1ab6e7bf978John Rose 200bde168412440084e649e7e04938bd1ab6e7bf978John Rose dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name); 201940903c5a5a906c622a79b3101586deb1a1b3480John Rose if (!dn || !dn->child) 2020945cd5f908a09ad99bf42d7ded16f26f24f317dJohn Rose return NULL; 203bde168412440084e649e7e04938bd1ab6e7bf978John Rose 20489a071b80767c3a7ed56e13ae5e810f751b19eebAndrew Morton if (_machine == PLATFORM_PSERIES_LPAR) { 2055fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose of_scan_bus(dn, bus); 2065fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose if (list_empty(&bus->devices)) { 2075fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose err("%s: No new device found\n", __FUNCTION__); 2085fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose return NULL; 2095fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose } 2109c209c919df95f83aa042b3352c43841ad15a02bJohn Rose 2115fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose rpaphp_init_new_devs(bus); 2120945cd5f908a09ad99bf42d7ded16f26f24f317dJohn Rose pci_bus_add_devices(bus); 2135fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose dev = list_entry(&bus->devices, struct pci_dev, bus_list); 2145fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose } else { 2155fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); 2165fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose 2175fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose /* pci_scan_slot should find all children */ 2185fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); 2195fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose if (num) { 2205fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose rpaphp_fixup_new_pci_devices(bus, 1); 2215fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose pci_bus_add_devices(bus); 2225fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose } 2235fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose if (list_empty(&bus->devices)) { 2245fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose err("%s: No new device found\n", __FUNCTION__); 2255fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose return NULL; 2265fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose } 2275fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose list_for_each_entry(dev, &bus->devices, bus_list) { 2285fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) 2295fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose rpaphp_pci_config_bridge(dev); 2305fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose 2315fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose rpaphp_eeh_add_bus_device(bus); 2325fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose } 233bde168412440084e649e7e04938bd1ab6e7bf978John Rose } 2340945cd5f908a09ad99bf42d7ded16f26f24f317dJohn Rose 235bde168412440084e649e7e04938bd1ab6e7bf978John Rose return dev; 236bde168412440084e649e7e04938bd1ab6e7bf978John Rose} 237bde168412440084e649e7e04938bd1ab6e7bf978John Rose 238940903c5a5a906c622a79b3101586deb1a1b3480John Rosestatic void print_slot_pci_funcs(struct pci_bus *bus) 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 240940903c5a5a906c622a79b3101586deb1a1b3480John Rose struct device_node *dn; 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_dev *dev; 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 243940903c5a5a906c622a79b3101586deb1a1b3480John Rose dn = pci_bus_to_OF_node(bus); 244940903c5a5a906c622a79b3101586deb1a1b3480John Rose if (!dn) 245940903c5a5a906c622a79b3101586deb1a1b3480John Rose return; 246940903c5a5a906c622a79b3101586deb1a1b3480John Rose 247940903c5a5a906c622a79b3101586deb1a1b3480John Rose dbg("%s: pci_devs of slot[%s]\n", __FUNCTION__, dn->full_name); 248940903c5a5a906c622a79b3101586deb1a1b3480John Rose list_for_each_entry (dev, &bus->devices, bus_list) 2495eeb8c63a38ff20285f3bbe7bcfe5e7c33c8ba14John Rose dbg("\t%s\n", pci_name(dev)); 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 253940903c5a5a906c622a79b3101586deb1a1b3480John Roseint rpaphp_config_pci_adapter(struct pci_bus *bus) 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 255940903c5a5a906c622a79b3101586deb1a1b3480John Rose struct device_node *dn = pci_bus_to_OF_node(bus); 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_dev *dev; 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rc = -ENODEV; 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 259940903c5a5a906c622a79b3101586deb1a1b3480John Rose dbg("Entry %s: slot[%s]\n", __FUNCTION__, dn->full_name); 260940903c5a5a906c622a79b3101586deb1a1b3480John Rose if (!dn) 261940903c5a5a906c622a79b3101586deb1a1b3480John Rose goto exit; 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 263d681db4aed4453c7d34adfbb64956271186514e9Linas Vepstas eeh_add_device_tree_early(dn); 264940903c5a5a906c622a79b3101586deb1a1b3480John Rose dev = rpaphp_pci_config_slot(bus); 2659c209c919df95f83aa042b3352c43841ad15a02bJohn Rose if (!dev) { 2669c209c919df95f83aa042b3352c43841ad15a02bJohn Rose err("%s: can't find any devices.\n", __FUNCTION__); 2679c209c919df95f83aa042b3352c43841ad15a02bJohn Rose goto exit; 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 269940903c5a5a906c622a79b3101586deb1a1b3480John Rose print_slot_pci_funcs(bus); 2709c209c919df95f83aa042b3352c43841ad15a02bJohn Rose rc = 0; 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsexit: 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dbg("Exit %s: rc=%d\n", __FUNCTION__, rc); 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return rc; 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 275940903c5a5a906c622a79b3101586deb1a1b3480John RoseEXPORT_SYMBOL_GPL(rpaphp_config_pci_adapter); 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void rpaphp_eeh_remove_bus_device(struct pci_dev *dev) 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds eeh_remove_device(dev); 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_bus *bus = dev->subordinate; 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct list_head *ln; 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!bus) 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_dev *pdev = pci_dev_b(ln); 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pdev) 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rpaphp_eeh_remove_bus_device(pdev); 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 295934199e95d6ac28f42686fe3009877eff33e06c3Linas Vepstasint rpaphp_unconfig_pci_adapter(struct pci_bus *bus) 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2979c209c919df95f83aa042b3352c43841ad15a02bJohn Rose struct pci_dev *dev, *tmp; 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 299934199e95d6ac28f42686fe3009877eff33e06c3Linas Vepstas list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rpaphp_eeh_remove_bus_device(dev); 3019c209c919df95f83aa042b3352c43841ad15a02bJohn Rose pci_remove_bus_device(dev); 3029c209c919df95f83aa042b3352c43841ad15a02bJohn Rose } 303934199e95d6ac28f42686fe3009877eff33e06c3Linas Vepstas return 0; 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3055fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John RoseEXPORT_SYMBOL_GPL(rpaphp_unconfig_pci_adapter); 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int setup_pci_hotplug_slot_info(struct slot *slot) 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 309f5c99dfc11dce8f26c1ceedb6595fa0eac335ea3Jesper Juhl struct hotplug_slot_info *hotplug_slot_info = slot->hotplug_slot->info; 310f5c99dfc11dce8f26c1ceedb6595fa0eac335ea3Jesper Juhl 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dbg("%s Initilize the PCI slot's hotplug->info structure ...\n", 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __FUNCTION__); 313f5c99dfc11dce8f26c1ceedb6595fa0eac335ea3Jesper Juhl rpaphp_get_power_status(slot, &hotplug_slot_info->power_status); 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rpaphp_get_pci_adapter_status(slot, 1, 315f5c99dfc11dce8f26c1ceedb6595fa0eac335ea3Jesper Juhl &hotplug_slot_info->adapter_status); 316f5c99dfc11dce8f26c1ceedb6595fa0eac335ea3Jesper Juhl if (hotplug_slot_info->adapter_status == NOT_VALID) { 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err("%s: NOT_VALID: skip dn->full_name=%s\n", 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __FUNCTION__, slot->dn->full_name); 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3249c209c919df95f83aa042b3352c43841ad15a02bJohn Rosestatic void set_slot_name(struct slot *slot) 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3269c209c919df95f83aa042b3352c43841ad15a02bJohn Rose struct pci_bus *bus = slot->bus; 3279c209c919df95f83aa042b3352c43841ad15a02bJohn Rose struct pci_dev *bridge; 3289c209c919df95f83aa042b3352c43841ad15a02bJohn Rose 3299c209c919df95f83aa042b3352c43841ad15a02bJohn Rose bridge = bus->self; 3309c209c919df95f83aa042b3352c43841ad15a02bJohn Rose if (bridge) 3319c209c919df95f83aa042b3352c43841ad15a02bJohn Rose strcpy(slot->name, pci_name(bridge)); 3329c209c919df95f83aa042b3352c43841ad15a02bJohn Rose else 3339c209c919df95f83aa042b3352c43841ad15a02bJohn Rose sprintf(slot->name, "%04x:%02x:00.0", pci_domain_nr(bus), 3349c209c919df95f83aa042b3352c43841ad15a02bJohn Rose bus->number); 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int setup_pci_slot(struct slot *slot) 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3399c209c919df95f83aa042b3352c43841ad15a02bJohn Rose struct device_node *dn = slot->dn; 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_bus *bus; 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3429c209c919df95f83aa042b3352c43841ad15a02bJohn Rose BUG_ON(!dn); 34301657868be1c21b2b8b0e683ea24bdcc2331d522Linas Vepstas bus = pcibios_find_pci_bus(dn); 3449c209c919df95f83aa042b3352c43841ad15a02bJohn Rose if (!bus) { 3459c209c919df95f83aa042b3352c43841ad15a02bJohn Rose err("%s: no pci_bus for dn %s\n", __FUNCTION__, dn->full_name); 3469c209c919df95f83aa042b3352c43841ad15a02bJohn Rose goto exit_rc; 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3499c209c919df95f83aa042b3352c43841ad15a02bJohn Rose slot->bus = bus; 3509c209c919df95f83aa042b3352c43841ad15a02bJohn Rose slot->pci_devs = &bus->devices; 3519c209c919df95f83aa042b3352c43841ad15a02bJohn Rose set_slot_name(slot); 3529c209c919df95f83aa042b3352c43841ad15a02bJohn Rose 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* find slot's pci_dev if it's not empty */ 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (slot->hotplug_slot->info->adapter_status == EMPTY) { 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds slot->state = EMPTY; /* slot is empty */ 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* slot is occupied */ 3589c209c919df95f83aa042b3352c43841ad15a02bJohn Rose if (!dn->child) { 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* non-empty slot has to have child */ 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err("%s: slot[%s]'s device_node doesn't have child for adapter\n", 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __FUNCTION__, slot->name); 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto exit_rc; 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (slot->hotplug_slot->info->adapter_status == NOT_CONFIGURED) { 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dbg("%s CONFIGURING pci adapter in slot[%s]\n", 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __FUNCTION__, slot->name); 368940903c5a5a906c622a79b3101586deb1a1b3480John Rose if (rpaphp_config_pci_adapter(slot->bus)) { 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err("%s: CONFIG pci adapter failed\n", __FUNCTION__); 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto exit_rc; 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (slot->hotplug_slot->info->adapter_status != CONFIGURED) { 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err("%s: slot[%s]'s adapter_status is NOT_VALID.\n", 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __FUNCTION__, slot->name); 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto exit_rc; 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 378940903c5a5a906c622a79b3101586deb1a1b3480John Rose print_slot_pci_funcs(slot->bus); 3795eeb8c63a38ff20285f3bbe7bcfe5e7c33c8ba14John Rose if (!list_empty(slot->pci_devs)) { 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds slot->state = CONFIGURED; 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* DLPAR add as opposed to 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * boot time */ 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds slot->state = NOT_CONFIGURED; 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsexit_rc: 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dealloc_slot_struct(slot); 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint register_pci_slot(struct slot *slot) 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rc = -EINVAL; 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (setup_pci_hotplug_slot_info(slot)) 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto exit_rc; 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (setup_pci_slot(slot)) 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto exit_rc; 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc = register_slot(slot); 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsexit_rc: 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return rc; 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint rpaphp_enable_pci_slot(struct slot *slot) 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int retval = 0, state; 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = rpaphp_get_sensor_state(slot, &state); 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (retval) 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto exit; 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dbg("%s: sensor state[%d]\n", __FUNCTION__, state); 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* if slot is not empty, enable the adapter */ 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (state == PRESENT) { 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dbg("%s : slot[%s] is occupied.\n", __FUNCTION__, slot->name); 417940903c5a5a906c622a79b3101586deb1a1b3480John Rose retval = rpaphp_config_pci_adapter(slot->bus); 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!retval) { 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds slot->state = CONFIGURED; 4205fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose info("%s: devices in slot[%s] configured\n", 4215fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6John Rose __FUNCTION__, slot->name); 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds slot->state = NOT_CONFIGURED; 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dbg("%s: no pci_dev struct for adapter in slot[%s]\n", 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __FUNCTION__, slot->name); 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (state == EMPTY) { 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dbg("%s : slot[%s] is empty\n", __FUNCTION__, slot->name); 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds slot->state = EMPTY; 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err("%s: slot[%s] is in invalid state\n", __FUNCTION__, 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds slot->name); 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds slot->state = NOT_VALID; 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = -EINVAL; 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsexit: 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return retval; 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 440