Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rpaphp_pci.c
Go to the documentation of this file.
1 /*
2  * PCI Hot Plug Controller Driver for RPA-compliant PPC64 platform.
3  * Copyright (C) 2003 Linda Xie <[email protected]>
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 <[email protected]>
23  *
24  */
25 #include <linux/pci.h>
26 #include <linux/string.h>
27 
28 #include <asm/pci-bridge.h>
29 #include <asm/rtas.h>
30 #include <asm/machdep.h>
31 
32 #include "../pci.h" /* for pci_add_new_bus */
33 #include "rpaphp.h"
34 
36 {
37  int rc;
38  int setlevel;
39 
40  rc = rtas_get_sensor(DR_ENTITY_SENSE, slot->index, state);
41 
42  if (rc < 0) {
43  if (rc == -EFAULT || rc == -EEXIST) {
44  dbg("%s: slot must be power up to get sensor-state\n",
45  __func__);
46 
47  /* some slots have to be powered up
48  * before get-sensor will succeed.
49  */
51  &setlevel);
52  if (rc < 0) {
53  dbg("%s: power on slot[%s] failed rc=%d.\n",
54  __func__, slot->name, rc);
55  } else {
57  slot->index, state);
58  }
59  } else if (rc == -ENODEV)
60  info("%s: slot is unusable\n", __func__);
61  else
62  err("%s failed to get sensor state\n", __func__);
63  }
64  return rc;
65 }
66 
77 {
78  int rc, level, state;
79  struct pci_bus *bus;
80  struct hotplug_slot_info *info = slot->hotplug_slot->info;
81 
82  info->adapter_status = NOT_VALID;
83  slot->state = EMPTY;
84 
85  /* Find out if the power is turned on for the slot */
86  rc = rtas_get_power_level(slot->power_domain, &level);
87  if (rc)
88  return rc;
89  info->power_status = level;
90 
91  /* Figure out if there is an adapter in the slot */
92  rc = rpaphp_get_sensor_state(slot, &state);
93  if (rc)
94  return rc;
95 
96  bus = pcibios_find_pci_bus(slot->dn);
97  if (!bus) {
98  err("%s: no pci_bus for dn %s\n", __func__, slot->dn->full_name);
99  return -EINVAL;
100  }
101 
102  info->adapter_status = EMPTY;
103  slot->bus = bus;
104  slot->pci_devs = &bus->devices;
105 
106  /* if there's an adapter in the slot, go add the pci devices */
107  if (state == PRESENT) {
109  slot->state = NOT_CONFIGURED;
110 
111  /* non-empty slot has to have child */
112  if (!slot->dn->child) {
113  err("%s: slot[%s]'s device_node doesn't have child for adapter\n",
114  __func__, slot->name);
115  return -EINVAL;
116  }
117 
118  if (list_empty(&bus->devices))
120 
121  if (!list_empty(&bus->devices)) {
122  info->adapter_status = CONFIGURED;
123  slot->state = CONFIGURED;
124  }
125 
126  if (rpaphp_debug) {
127  struct pci_dev *dev;
128  dbg("%s: pci_devs of slot[%s]\n", __func__, slot->dn->full_name);
129  list_for_each_entry (dev, &bus->devices, bus_list)
130  dbg("\t%s\n", pci_name(dev));
131  }
132  }
133 
134  return 0;
135 }
136