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