1 /*
2  * ACPI PCI HotPlug glue functions to ACPI CA subsystem
3  *
4  * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
5  * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
6  * Copyright (C) 2002,2003 NEC Corporation
7  *
8  * All rights reserved.
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or (at
13  * your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18  * NON INFRINGEMENT.  See the GNU General Public License for more
19  * details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  *
25  * Send feedback to <t-kochi@bq.jp.nec.com>
26  *
27  */
28 
29 #include <linux/init.h>
30 #include <linux/module.h>
31 
32 #include <linux/kernel.h>
33 #include <linux/pci.h>
34 #include <linux/smp_lock.h>
35 #include <asm/semaphore.h>
36 
37 #include "pci_hotplug.h"
38 #include "acpiphp.h"
39 
40 static LIST_HEAD(bridge_list);
41 
42 #define MY_NAME "acpiphp_glue"
43 
44 static void handle_hotplug_event_bridge (acpi_handle, u32, void *);
45 static void handle_hotplug_event_func (acpi_handle, u32, void *);
46 
47 /*
48  * initialization & terminatation routines
49  */
50 
51 /**
52  * is_ejectable - determine if a slot is ejectable
53  * @handle: handle to acpi namespace
54  *
55  * Ejectable slot should satisfy at least these conditions:
56  *
57  *  1. has _ADR method
58  *  2. has _EJ0 method
59  *
60  * optionally
61  *
62  *  1. has _STA method
63  *  2. has _PS0 method
64  *  3. has _PS3 method
65  *  4. ..
66  *
67  */
is_ejectable(acpi_handle handle)68 static int is_ejectable (acpi_handle handle)
69 {
70 	acpi_status status;
71 	acpi_handle tmp;
72 
73 	status = acpi_get_handle(handle, "_ADR", &tmp);
74 	if (ACPI_FAILURE(status)) {
75 		return 0;
76 	}
77 
78 	status = acpi_get_handle(handle, "_EJ0", &tmp);
79 	if (ACPI_FAILURE(status)) {
80 		return 0;
81 	}
82 
83 	return 1;
84 }
85 
86 
87 /* callback routine to check the existence of ejectable slots */
88 static acpi_status
is_ejectable_slot(acpi_handle handle,u32 lvl,void * context,void ** rv)89 is_ejectable_slot (acpi_handle handle, u32 lvl,	void *context, void **rv)
90 {
91 	int *count = (int *)context;
92 
93 	if (is_ejectable(handle)) {
94 		(*count)++;
95 		/* only one ejectable slot is enough */
96 		return AE_CTRL_TERMINATE;
97 	} else {
98 		return AE_OK;
99 	}
100 }
101 
102 
103 /* callback routine to register each ACPI PCI slot object */
104 static acpi_status
register_slot(acpi_handle handle,u32 lvl,void * context,void ** rv)105 register_slot (acpi_handle handle, u32 lvl, void *context, void **rv)
106 {
107 	struct acpiphp_bridge *bridge = (struct acpiphp_bridge *)context;
108 	struct acpiphp_slot *slot;
109 	struct acpiphp_func *newfunc;
110 	acpi_handle tmp;
111 	acpi_status status = AE_OK;
112 	unsigned long adr, sun;
113 	int device, function;
114 	static int num_slots = 0;	/* XXX if we support I/O node hotplug... */
115 
116 	status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
117 
118 	if (ACPI_FAILURE(status))
119 		return AE_OK;
120 
121 	status = acpi_get_handle(handle, "_EJ0", &tmp);
122 
123 	if (ACPI_FAILURE(status))
124 		return AE_OK;
125 
126 	device = (adr >> 16) & 0xffff;
127 	function = adr & 0xffff;
128 
129 	newfunc = kmalloc(sizeof(struct acpiphp_func), GFP_KERNEL);
130 	if (!newfunc)
131 		return AE_NO_MEMORY;
132 	memset(newfunc, 0, sizeof(struct acpiphp_func));
133 
134 	INIT_LIST_HEAD(&newfunc->sibling);
135 	newfunc->handle = handle;
136 	newfunc->function = function;
137 	newfunc->flags = FUNC_HAS_EJ0;
138 
139 	if (ACPI_SUCCESS(acpi_get_handle(handle, "_STA", &tmp)))
140 		newfunc->flags |= FUNC_HAS_STA;
141 
142 	if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS0", &tmp)))
143 		newfunc->flags |= FUNC_HAS_PS0;
144 
145 	if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", &tmp)))
146 		newfunc->flags |= FUNC_HAS_PS3;
147 
148 	status = acpi_evaluate_integer(handle, "_SUN", NULL, &sun);
149 	if (ACPI_FAILURE(status))
150 		sun = -1;
151 
152 	/* search for objects that share the same slot */
153 	for (slot = bridge->slots; slot; slot = slot->next)
154 		if (slot->device == device) {
155 			if (slot->sun != sun)
156 				warn("sibling found, but _SUN doesn't match!\n");
157 			break;
158 		}
159 
160 	if (!slot) {
161 		slot = kmalloc(sizeof(struct acpiphp_slot), GFP_KERNEL);
162 		if (!slot) {
163 			kfree(newfunc);
164 			return AE_NO_MEMORY;
165 		}
166 
167 		memset(slot, 0, sizeof(struct acpiphp_slot));
168 		slot->bridge = bridge;
169 		slot->id = num_slots++;
170 		slot->device = device;
171 		slot->sun = sun;
172 		INIT_LIST_HEAD(&slot->funcs);
173 		init_MUTEX(&slot->crit_sect);
174 
175 		slot->next = bridge->slots;
176 		bridge->slots = slot;
177 
178 		bridge->nr_slots++;
179 
180 		dbg("found ACPI PCI Hotplug slot at PCI %02x:%02x Slot:%d\n",
181 		    slot->bridge->bus, slot->device, slot->sun);
182 	}
183 
184 	newfunc->slot = slot;
185 	list_add_tail(&newfunc->sibling, &slot->funcs);
186 
187 	/* associate corresponding pci_dev */
188 	newfunc->pci_dev = pci_find_slot(bridge->bus,
189 					 PCI_DEVFN(device, function));
190 	if (newfunc->pci_dev) {
191 		if (acpiphp_init_func_resource(newfunc) < 0) {
192 			kfree(newfunc);
193 			return AE_ERROR;
194 		}
195 		slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON);
196 	}
197 
198 	/* install notify handler */
199 	status = acpi_install_notify_handler(handle,
200 					     ACPI_SYSTEM_NOTIFY,
201 					     handle_hotplug_event_func,
202 					     newfunc);
203 
204 	if (ACPI_FAILURE(status)) {
205 		err("failed to register interrupt notify handler\n");
206 		return status;
207 	}
208 
209 	return AE_OK;
210 }
211 
212 
213 /* see if it's worth looking at this bridge */
detect_ejectable_slots(acpi_handle * bridge_handle)214 static int detect_ejectable_slots (acpi_handle *bridge_handle)
215 {
216 	acpi_status status;
217 	int count;
218 
219 	count = 0;
220 
221 	/* only check slots defined directly below bridge object */
222 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle, (u32)1,
223 				     is_ejectable_slot, (void *)&count, NULL);
224 
225 	return count;
226 }
227 
228 
229 /* decode ACPI _CRS data and convert into our internal resource list
230  * TBD: _TRA, etc.
231  */
232 static void
decode_acpi_resource(struct acpi_resource * resource,struct acpiphp_bridge * bridge)233 decode_acpi_resource (struct acpi_resource *resource, struct acpiphp_bridge *bridge)
234 {
235 	struct acpi_resource_address16 *address16_data;
236 	struct acpi_resource_address32 *address32_data;
237 	struct acpi_resource_address64 *address64_data;
238 	struct pci_resource *res;
239 
240 	u32 resource_type, producer_consumer, address_length;
241 	u64 min_address_range, max_address_range;
242 	u16 cache_attribute = 0;
243 
244 	int done = 0, found;
245 
246 	/* shut up gcc */
247 	resource_type = producer_consumer = address_length = 0;
248 	min_address_range = max_address_range = 0;
249 
250 	while (!done) {
251 		found = 0;
252 
253 		switch (resource->id) {
254 		case ACPI_RSTYPE_ADDRESS16:
255 			address16_data = (struct acpi_resource_address16 *)&resource->data;
256 			resource_type = address16_data->resource_type;
257 			producer_consumer = address16_data->producer_consumer;
258 			min_address_range = address16_data->min_address_range;
259 			max_address_range = address16_data->max_address_range;
260 			address_length = address16_data->address_length;
261 			if (resource_type == ACPI_MEMORY_RANGE)
262 				cache_attribute = address16_data->attribute.memory.cache_attribute;
263 			found = 1;
264 			break;
265 
266 		case ACPI_RSTYPE_ADDRESS32:
267 			address32_data = (struct acpi_resource_address32 *)&resource->data;
268 			resource_type = address32_data->resource_type;
269 			producer_consumer = address32_data->producer_consumer;
270 			min_address_range = address32_data->min_address_range;
271 			max_address_range = address32_data->max_address_range;
272 			address_length = address32_data->address_length;
273 			if (resource_type == ACPI_MEMORY_RANGE)
274 				cache_attribute = address32_data->attribute.memory.cache_attribute;
275 			found = 1;
276 			break;
277 
278 		case ACPI_RSTYPE_ADDRESS64:
279 			address64_data = (struct acpi_resource_address64 *)&resource->data;
280 			resource_type = address64_data->resource_type;
281 			producer_consumer = address64_data->producer_consumer;
282 			min_address_range = address64_data->min_address_range;
283 			max_address_range = address64_data->max_address_range;
284 			address_length = address64_data->address_length;
285 			if (resource_type == ACPI_MEMORY_RANGE)
286 				cache_attribute = address64_data->attribute.memory.cache_attribute;
287 			found = 1;
288 			break;
289 
290 		case ACPI_RSTYPE_END_TAG:
291 			done = 1;
292 			break;
293 
294 		default:
295 			/* ignore */
296 			break;
297 		}
298 
299 		resource = (struct acpi_resource *)((char*)resource + resource->length);
300 
301 		if (found && producer_consumer == ACPI_PRODUCER && address_length > 0) {
302 			switch (resource_type) {
303 			case ACPI_MEMORY_RANGE:
304 				if (cache_attribute == ACPI_PREFETCHABLE_MEMORY) {
305 					dbg("resource type: prefetchable memory 0x%x - 0x%x\n", (u32)min_address_range, (u32)max_address_range);
306 					res = acpiphp_make_resource(min_address_range,
307 							    address_length);
308 					if (!res) {
309 						err("out of memory\n");
310 						return;
311 					}
312 					res->next = bridge->p_mem_head;
313 					bridge->p_mem_head = res;
314 				} else {
315 					dbg("resource type: memory 0x%x - 0x%x\n", (u32)min_address_range, (u32)max_address_range);
316 					res = acpiphp_make_resource(min_address_range,
317 							    address_length);
318 					if (!res) {
319 						err("out of memory\n");
320 						return;
321 					}
322 					res->next = bridge->mem_head;
323 					bridge->mem_head = res;
324 				}
325 				break;
326 			case ACPI_IO_RANGE:
327 				dbg("resource type: io 0x%x - 0x%x\n", (u32)min_address_range, (u32)max_address_range);
328 				res = acpiphp_make_resource(min_address_range,
329 						    address_length);
330 				if (!res) {
331 					err("out of memory\n");
332 					return;
333 				}
334 				res->next = bridge->io_head;
335 				bridge->io_head = res;
336 				break;
337 			case ACPI_BUS_NUMBER_RANGE:
338 				dbg("resource type: bus number %d - %d\n", (u32)min_address_range, (u32)max_address_range);
339 				res = acpiphp_make_resource(min_address_range,
340 						    address_length);
341 				if (!res) {
342 					err("out of memory\n");
343 					return;
344 				}
345 				res->next = bridge->bus_head;
346 				bridge->bus_head = res;
347 				break;
348 			default:
349 				/* invalid type */
350 				break;
351 			}
352 		}
353 	}
354 
355 	acpiphp_resource_sort_and_combine(&bridge->io_head);
356 	acpiphp_resource_sort_and_combine(&bridge->mem_head);
357 	acpiphp_resource_sort_and_combine(&bridge->p_mem_head);
358 	acpiphp_resource_sort_and_combine(&bridge->bus_head);
359 
360 	dbg("ACPI _CRS resource:\n");
361 	acpiphp_dump_resource(bridge);
362 }
363 
364 
365 /* find pci_bus structure associated to specific bus number */
find_pci_bus(const struct list_head * list,int bus)366 static struct pci_bus *find_pci_bus(const struct list_head *list, int bus)
367 {
368 	const struct list_head *l;
369 
370 	list_for_each (l, list) {
371 		struct pci_bus *b = pci_bus_b(l);
372 		if (b->number == bus)
373 			return b;
374 
375 		if (!list_empty(&b->children)) {
376 			/* XXX recursive call */
377 			b = find_pci_bus(&b->children, bus);
378 
379 			if (b)
380 				return b;
381 		}
382 	}
383 
384 	return NULL;
385 }
386 
387 
388 /* decode ACPI 2.0 _HPP hot plug parameters */
decode_hpp(struct acpiphp_bridge * bridge)389 static void decode_hpp(struct acpiphp_bridge *bridge)
390 {
391 	acpi_status status;
392 	struct acpi_buffer buffer = { .length = ACPI_ALLOCATE_BUFFER,
393 				      .pointer = NULL};
394 	union acpi_object *package;
395 	int i;
396 
397 	/* default numbers */
398 	bridge->hpp.cache_line_size = 0x10;
399 	bridge->hpp.latency_timer = 0x40;
400 	bridge->hpp.enable_SERR = 0;
401 	bridge->hpp.enable_PERR = 0;
402 
403 	status = acpi_evaluate_object(bridge->handle, "_HPP", NULL, &buffer);
404 
405 	if (ACPI_FAILURE(status)) {
406 		dbg("_HPP evaluation failed\n");
407 		return;
408 	}
409 
410 	package = (union acpi_object *) buffer.pointer;
411 
412 	if (!package || package->type != ACPI_TYPE_PACKAGE ||
413 	    package->package.count != 4 || !package->package.elements) {
414 		err("invalid _HPP object; ignoring\n");
415 		goto err_exit;
416 	}
417 
418 	for (i = 0; i < 4; i++) {
419 		if (package->package.elements[i].type != ACPI_TYPE_INTEGER) {
420 			err("invalid _HPP parameter type; ignoring\n");
421 			goto err_exit;
422 		}
423 	}
424 
425 	bridge->hpp.cache_line_size = package->package.elements[0].integer.value;
426 	bridge->hpp.latency_timer = package->package.elements[1].integer.value;
427 	bridge->hpp.enable_SERR = package->package.elements[2].integer.value;
428 	bridge->hpp.enable_PERR = package->package.elements[3].integer.value;
429 
430 	dbg("_HPP parameter = (%02x, %02x, %02x, %02x)\n",
431 	    bridge->hpp.cache_line_size,
432 	    bridge->hpp.latency_timer,
433 	    bridge->hpp.enable_SERR,
434 	    bridge->hpp.enable_PERR);
435 
436 	bridge->flags |= BRIDGE_HAS_HPP;
437 
438  err_exit:
439 	kfree(buffer.pointer);
440 }
441 
442 
443 /* initialize miscellaneous stuff for both root and PCI-to-PCI bridge */
init_bridge_misc(struct acpiphp_bridge * bridge)444 static void init_bridge_misc (struct acpiphp_bridge *bridge)
445 {
446 	acpi_status status;
447 
448 	/* decode ACPI 2.0 _HPP (hot plug parameters) */
449 	decode_hpp(bridge);
450 
451 	/* subtract all resources already allocated */
452 	acpiphp_detect_pci_resource(bridge);
453 
454 	/* register all slot objects under this bridge */
455 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1,
456 				     register_slot, bridge, NULL);
457 
458 	/* install notify handler */
459 	status = acpi_install_notify_handler(bridge->handle,
460 					     ACPI_SYSTEM_NOTIFY,
461 					     handle_hotplug_event_bridge,
462 					     bridge);
463 
464 	if (ACPI_FAILURE(status)) {
465 		err("failed to register interrupt notify handler\n");
466 	}
467 
468 	list_add(&bridge->list, &bridge_list);
469 
470 	dbg("Bridge resource:\n");
471 	acpiphp_dump_resource(bridge);
472 }
473 
474 
475 /* allocate and initialize host bridge data structure */
add_host_bridge(acpi_handle * handle,int seg,int bus)476 static void add_host_bridge (acpi_handle *handle, int seg, int bus)
477 {
478 	acpi_status status;
479 	struct acpi_buffer buffer = { .length = ACPI_ALLOCATE_BUFFER,
480 				      .pointer = NULL};
481 	struct acpiphp_bridge *bridge;
482 
483 	bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
484 	if (bridge == NULL)
485 		return;
486 
487 	memset(bridge, 0, sizeof(struct acpiphp_bridge));
488 
489 	bridge->type = BRIDGE_TYPE_HOST;
490 	bridge->handle = handle;
491 	bridge->seg = seg;
492 	bridge->bus = bus;
493 
494 	bridge->pci_bus = find_pci_bus(&pci_root_buses, bus);
495 
496 	bridge->res_lock = SPIN_LOCK_UNLOCKED;
497 
498 	/* to be overridden when we decode _CRS	*/
499 	bridge->sub = bridge->bus;
500 
501 	/* decode resources */
502 
503 	status = acpi_get_current_resources(handle, &buffer);
504 
505 	if (ACPI_FAILURE(status)) {
506 		err("failed to decode bridge resources\n");
507 		kfree(bridge);
508 		return;
509 	}
510 
511 	decode_acpi_resource(buffer.pointer, bridge);
512 	kfree(buffer.pointer);
513 
514 	if (bridge->bus_head) {
515 		bridge->bus = bridge->bus_head->base;
516 		bridge->sub = bridge->bus_head->base + bridge->bus_head->length - 1;
517 	}
518 
519 	init_bridge_misc(bridge);
520 }
521 
522 
523 /* allocate and initialize PCI-to-PCI bridge data structure */
add_p2p_bridge(acpi_handle * handle,int seg,int bus,int dev,int fn)524 static void add_p2p_bridge (acpi_handle *handle, int seg, int bus, int dev, int fn)
525 {
526 	struct acpiphp_bridge *bridge;
527 	u8 tmp8;
528 	u16 tmp16;
529 	u64 base64, limit64;
530 	u32 base, limit, base32u, limit32u;
531 
532 	bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
533 	if (bridge == NULL) {
534 		err("out of memory\n");
535 		return;
536 	}
537 
538 	memset(bridge, 0, sizeof(struct acpiphp_bridge));
539 
540 	bridge->type = BRIDGE_TYPE_P2P;
541 	bridge->handle = handle;
542 	bridge->seg = seg;
543 
544 	bridge->pci_dev = pci_find_slot(bus, PCI_DEVFN(dev, fn));
545 	if (!bridge->pci_dev) {
546 		err("Can't get pci_dev\n");
547 		kfree(bridge);
548 		return;
549 	}
550 
551 	bridge->pci_bus = bridge->pci_dev->subordinate;
552 	if (!bridge->pci_bus) {
553 		err("This is not a PCI-to-PCI bridge!\n");
554 		kfree(bridge);
555 		return;
556 	}
557 
558 	bridge->res_lock = SPIN_LOCK_UNLOCKED;
559 
560 	bridge->bus = bridge->pci_bus->number;
561 	bridge->sub = bridge->pci_bus->subordinate;
562 
563 	/*
564 	 * decode resources under this P2P bridge
565 	 */
566 
567 	/* I/O resources */
568 	pci_read_config_byte(bridge->pci_dev, PCI_IO_BASE, &tmp8);
569 	base = tmp8;
570 	pci_read_config_byte(bridge->pci_dev, PCI_IO_LIMIT, &tmp8);
571 	limit = tmp8;
572 
573 	switch (base & PCI_IO_RANGE_TYPE_MASK) {
574 	case PCI_IO_RANGE_TYPE_16:
575 		base = (base << 8) & 0xf000;
576 		limit = ((limit << 8) & 0xf000) + 0xfff;
577 		bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);
578 		if (!bridge->io_head) {
579 			err("out of memory\n");
580 			kfree(bridge);
581 			return;
582 		}
583 		dbg("16bit I/O range: %04x-%04x\n",
584 		    (u32)bridge->io_head->base,
585 		    (u32)(bridge->io_head->base + bridge->io_head->length - 1));
586 		break;
587 	case PCI_IO_RANGE_TYPE_32:
588 		pci_read_config_word(bridge->pci_dev, PCI_IO_BASE_UPPER16, &tmp16);
589 		base = ((u32)tmp16 << 16) | ((base << 8) & 0xf000);
590 		pci_read_config_word(bridge->pci_dev, PCI_IO_LIMIT_UPPER16, &tmp16);
591 		limit = (((u32)tmp16 << 16) | ((limit << 8) & 0xf000)) + 0xfff;
592 		bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);
593 		if (!bridge->io_head) {
594 			err("out of memory\n");
595 			kfree(bridge);
596 			return;
597 		}
598 		dbg("32bit I/O range: %08x-%08x\n",
599 		    (u32)bridge->io_head->base,
600 		    (u32)(bridge->io_head->base + bridge->io_head->length - 1));
601 		break;
602 	case 0x0f:
603 		dbg("I/O space unsupported\n");
604 		break;
605 	default:
606 		warn("Unknown I/O range type\n");
607 	}
608 
609 	/* Memory resources (mandatory for P2P bridge) */
610 	pci_read_config_word(bridge->pci_dev, PCI_MEMORY_BASE, &tmp16);
611 	base = (tmp16 & 0xfff0) << 16;
612 	pci_read_config_word(bridge->pci_dev, PCI_MEMORY_LIMIT, &tmp16);
613 	limit = ((tmp16 & 0xfff0) << 16) | 0xfffff;
614 	bridge->mem_head = acpiphp_make_resource((u64)base, limit - base + 1);
615 	if (!bridge->mem_head) {
616 		err("out of memory\n");
617 		kfree(bridge);
618 		return;
619 	}
620 	dbg("32bit Memory range: %08x-%08x\n",
621 	    (u32)bridge->mem_head->base,
622 	    (u32)(bridge->mem_head->base + bridge->mem_head->length-1));
623 
624 	/* Prefetchable Memory resources (optional) */
625 	pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_BASE, &tmp16);
626 	base = tmp16;
627 	pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_LIMIT, &tmp16);
628 	limit = tmp16;
629 
630 	switch (base & PCI_MEMORY_RANGE_TYPE_MASK) {
631 	case PCI_PREF_RANGE_TYPE_32:
632 		base = (base & 0xfff0) << 16;
633 		limit = ((limit & 0xfff0) << 16) | 0xfffff;
634 		bridge->p_mem_head = acpiphp_make_resource((u64)base, limit - base + 1);
635 		if (!bridge->p_mem_head) {
636 			err("out of memory\n");
637 			kfree(bridge);
638 			return;
639 		}
640 		dbg("32bit Prefetchable memory range: %08x-%08x\n",
641 		    (u32)bridge->p_mem_head->base,
642 		    (u32)(bridge->p_mem_head->base + bridge->p_mem_head->length - 1));
643 		break;
644 	case PCI_PREF_RANGE_TYPE_64:
645 		pci_read_config_dword(bridge->pci_dev, PCI_PREF_BASE_UPPER32, &base32u);
646 		pci_read_config_dword(bridge->pci_dev, PCI_PREF_LIMIT_UPPER32, &limit32u);
647 		base64 = ((u64)base32u << 32) | ((base & 0xfff0) << 16);
648 		limit64 = (((u64)limit32u << 32) | ((limit & 0xfff0) << 16)) + 0xfffff;
649 
650 		bridge->p_mem_head = acpiphp_make_resource(base64, limit64 - base64 + 1);
651 		if (!bridge->p_mem_head) {
652 			err("out of memory\n");
653 			kfree(bridge);
654 			return;
655 		}
656 		dbg("64bit Prefetchable memory range: %08x%08x-%08x%08x\n",
657 		    (u32)(bridge->p_mem_head->base >> 32),
658 		    (u32)(bridge->p_mem_head->base & 0xffffffff),
659 		    (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) >> 32),
660 		    (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) & 0xffffffff));
661 		break;
662 	case 0x0f:
663 		break;
664 	default:
665 		warn("Unknown prefetchale memory type\n");
666 	}
667 
668 	init_bridge_misc(bridge);
669 }
670 
671 
672 /* callback routine to find P2P bridges */
673 static acpi_status
find_p2p_bridge(acpi_handle handle,u32 lvl,void * context,void ** rv)674 find_p2p_bridge (acpi_handle handle, u32 lvl, void *context, void **rv)
675 {
676 	acpi_status status;
677 	acpi_handle dummy_handle;
678 	unsigned long *segbus = context;
679 	unsigned long tmp;
680 	int seg, bus, device, function;
681 	struct pci_dev *dev;
682 
683 	/* get PCI address */
684 	seg = (*segbus >> 8) & 0xff;
685 	bus = *segbus & 0xff;
686 
687 	status = acpi_get_handle(handle, "_ADR", &dummy_handle);
688 	if (ACPI_FAILURE(status))
689 		return AE_OK;		/* continue */
690 
691 	status = acpi_evaluate_integer(handle, "_ADR", NULL, &tmp);
692 	if (ACPI_FAILURE(status)) {
693 		dbg("%s: _ADR evaluation failure\n", __FUNCTION__);
694 		return AE_OK;
695 	}
696 
697 	device = (tmp >> 16) & 0xffff;
698 	function = tmp & 0xffff;
699 
700 	dev = pci_find_slot(bus, PCI_DEVFN(device, function));
701 
702 	if (!dev)
703 		return AE_OK;
704 
705 	if (!dev->subordinate)
706 		return AE_OK;
707 
708 	/* check if this bridge has ejectable slots */
709 	if (detect_ejectable_slots(handle) > 0) {
710 		dbg("found PCI-to-PCI bridge at PCI %s\n", dev->slot_name);
711 		add_p2p_bridge(handle, seg, bus, device, function);
712 	}
713 
714 	return AE_OK;
715 }
716 
717 
718 /* find hot-pluggable slots, and then find P2P bridge */
add_bridge(acpi_handle handle)719 static int add_bridge (acpi_handle handle)
720 {
721 	acpi_status status;
722 	unsigned long tmp;
723 	int seg, bus;
724 	acpi_handle dummy_handle;
725 
726 	/* if the bridge doesn't have _STA, we assume it is always there */
727 	status = acpi_get_handle(handle, "_STA", &dummy_handle);
728 	if (ACPI_SUCCESS(status)) {
729 		status = acpi_evaluate_integer(handle, "_STA", NULL, &tmp);
730 		if (ACPI_FAILURE(status)) {
731 			dbg("%s: _STA evaluation failure\n", __FUNCTION__);
732 			return 0;
733 		}
734 		if ((tmp & ACPI_STA_FUNCTIONING) == 0)
735 			/* don't register this object */
736 			return 0;
737 	}
738 
739 	/* get PCI segment number */
740 	status = acpi_evaluate_integer(handle, "_SEG", NULL, &tmp);
741 
742 	seg = ACPI_SUCCESS(status) ? tmp : 0;
743 
744 	/* get PCI bus number */
745 	status = acpi_evaluate_integer(handle, "_BBN", NULL, &tmp);
746 
747 	if (ACPI_SUCCESS(status)) {
748 		bus = tmp;
749 	} else {
750 		warn("can't get bus number, assuming 0\n");
751 		bus = 0;
752 	}
753 
754 	/* check if this bridge has ejectable slots */
755 	if (detect_ejectable_slots(handle) > 0) {
756 		dbg("found PCI host-bus bridge with hot-pluggable slots\n");
757 		add_host_bridge(handle, seg, bus);
758 		return 0;
759 	}
760 
761 	tmp = seg << 8 | bus;
762 
763 	/* search P2P bridges under this host bridge */
764 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
765 				     find_p2p_bridge, &tmp, NULL);
766 
767 	if (ACPI_FAILURE(status))
768 		warn("find_p2p_bridge faied (error code = 0x%x)\n",status);
769 
770 	return 0;
771 }
772 
773 
remove_bridge(acpi_handle handle)774 static void remove_bridge (acpi_handle handle)
775 {
776 	/* No-op for now .. */
777 }
778 
power_on_slot(struct acpiphp_slot * slot)779 static int power_on_slot (struct acpiphp_slot *slot)
780 {
781 	acpi_status status;
782 	struct acpiphp_func *func;
783 	struct list_head *l;
784 	int retval = 0;
785 
786 	/* if already enabled, just skip */
787 	if (slot->flags & SLOT_POWEREDON)
788 		goto err_exit;
789 
790 	list_for_each (l, &slot->funcs) {
791 		func = list_entry(l, struct acpiphp_func, sibling);
792 
793 		if (func->flags & FUNC_HAS_PS0) {
794 			dbg("%s: executing _PS0\n", __FUNCTION__);
795 			status = acpi_evaluate_object(func->handle, "_PS0", NULL, NULL);
796 			if (ACPI_FAILURE(status)) {
797 				warn("%s: _PS0 failed\n", __FUNCTION__);
798 				retval = -1;
799 				goto err_exit;
800 			} else
801 				break;
802 		}
803 	}
804 
805 	/* TBD: evaluate _STA to check if the slot is enabled */
806 
807 	slot->flags |= SLOT_POWEREDON;
808 
809  err_exit:
810 	return retval;
811 }
812 
813 
power_off_slot(struct acpiphp_slot * slot)814 static int power_off_slot (struct acpiphp_slot *slot)
815 {
816 	acpi_status status;
817 	struct acpiphp_func *func;
818 	struct list_head *l;
819 	struct acpi_object_list arg_list;
820 	union acpi_object arg;
821 
822 	int retval = 0;
823 
824 	/* if already disabled, just skip */
825 	if ((slot->flags & SLOT_POWEREDON) == 0)
826 		goto err_exit;
827 
828 	list_for_each (l, &slot->funcs) {
829 		func = list_entry(l, struct acpiphp_func, sibling);
830 
831 		if (func->pci_dev && (func->flags & FUNC_HAS_PS3)) {
832 			status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL);
833 			if (ACPI_FAILURE(status)) {
834 				warn("%s: _PS3 failed\n", __FUNCTION__);
835 				retval = -1;
836 				goto err_exit;
837 			} else
838 				break;
839 		}
840 	}
841 
842 	list_for_each (l, &slot->funcs) {
843 		func = list_entry(l, struct acpiphp_func, sibling);
844 
845 		/* We don't want to call _EJ0 on non-existing functions. */
846 		if (func->pci_dev && (func->flags & FUNC_HAS_EJ0)) {
847 			/* _EJ0 method take one argument */
848 			arg_list.count = 1;
849 			arg_list.pointer = &arg;
850 			arg.type = ACPI_TYPE_INTEGER;
851 			arg.integer.value = 1;
852 			status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL);
853 			if (ACPI_FAILURE(status)) {
854 				warn("%s: _EJ0 failed\n", __FUNCTION__);
855 				retval = -1;
856 				goto err_exit;
857 			} else
858 				break;
859 		}
860 	}
861 
862 	/* TBD: evaluate _STA to check if the slot is disabled */
863 
864 	slot->flags &= (~SLOT_POWEREDON);
865 
866  err_exit:
867 	return retval;
868 }
869 
870 
871 /**
872  * enable_device - enable, configure a slot
873  * @slot: slot to be enabled
874  *
875  * This function should be called per *physical slot*,
876  * not per each slot object in ACPI namespace.
877  *
878  */
enable_device(struct acpiphp_slot * slot)879 static int enable_device (struct acpiphp_slot *slot)
880 {
881 	u8 bus;
882 	struct pci_dev dev0, *dev;
883 	struct pci_bus *child;
884 	struct list_head *l;
885 	struct acpiphp_func *func;
886 	int retval = 0;
887 
888 	if (slot->flags & SLOT_ENABLED)
889 		goto err_exit;
890 
891 	/* sanity check: dev should be NULL when hot-plugged in */
892 	dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0));
893 	if (dev) {
894 		/* This case shouldn't happen */
895 		err("pci_dev structure already exists.\n");
896 		retval = -1;
897 		goto err_exit;
898 	}
899 
900 	/* allocate resources to device */
901 	retval = acpiphp_configure_slot(slot);
902 	if (retval)
903 		goto err_exit;
904 
905 	memset(&dev0, 0, sizeof (struct pci_dev));
906 
907 	dev0.bus = slot->bridge->pci_bus;
908 	dev0.devfn = PCI_DEVFN(slot->device, 0);
909 	dev0.sysdata = dev0.bus->sysdata;
910 
911 	/* returned `dev' is the *first function* only! */
912 	dev = pci_scan_slot (&dev0);
913 
914 	if (!dev) {
915 		err("No new device found\n");
916 		retval = -1;
917 		goto err_exit;
918 	}
919 
920 	if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
921 		pci_read_config_byte(dev, PCI_SECONDARY_BUS, &bus);
922 		child = (struct pci_bus*) pci_add_new_bus(dev->bus, dev, bus);
923 		pci_do_scan_bus(child);
924 	}
925 
926 	/* associate pci_dev to our representation */
927 	list_for_each (l, &slot->funcs) {
928 		func = list_entry(l, struct acpiphp_func, sibling);
929 
930 		func->pci_dev = pci_find_slot(slot->bridge->bus,
931 					      PCI_DEVFN(slot->device,
932 							func->function));
933 		if (!func->pci_dev)
934 			continue;
935 
936 		/* configure device */
937 		retval = acpiphp_configure_function(func);
938 		if (retval)
939 			goto err_exit;
940 	}
941 
942 	slot->flags |= SLOT_ENABLED;
943 
944 	dbg("Available resources:\n");
945 	acpiphp_dump_resource(slot->bridge);
946 
947  err_exit:
948 	return retval;
949 }
950 
951 
952 /**
953  * disable_device - disable a slot
954  */
disable_device(struct acpiphp_slot * slot)955 static int disable_device (struct acpiphp_slot *slot)
956 {
957 	int retval = 0;
958 	struct acpiphp_func *func;
959 	struct list_head *l;
960 
961 	/* is this slot already disabled? */
962 	if (!(slot->flags & SLOT_ENABLED))
963 		goto err_exit;
964 
965 	list_for_each (l, &slot->funcs) {
966 		func = list_entry(l, struct acpiphp_func, sibling);
967 
968 		if (func->pci_dev)
969 			if (acpiphp_unconfigure_function(func)) {
970 				err("failed to unconfigure device\n");
971 				retval = -1;
972 				goto err_exit;
973 			}
974 	}
975 
976 	slot->flags &= (~SLOT_ENABLED);
977 
978  err_exit:
979 	return retval;
980 }
981 
982 
983 /**
984  * get_slot_status - get ACPI slot status
985  *
986  * if a slot has _STA for each function and if any one of them
987  * returned non-zero status, return it
988  *
989  * if a slot doesn't have _STA and if any one of its functions'
990  * configuration space is configured, return 0x0f as a _STA
991  *
992  * otherwise return 0
993  */
get_slot_status(struct acpiphp_slot * slot)994 static unsigned int get_slot_status (struct acpiphp_slot *slot)
995 {
996 	acpi_status status;
997 	unsigned long sta = 0;
998 	u32 dvid;
999 	struct list_head *l;
1000 	struct acpiphp_func *func;
1001 
1002 	list_for_each (l, &slot->funcs) {
1003 		func = list_entry(l, struct acpiphp_func, sibling);
1004 
1005 		if (func->flags & FUNC_HAS_STA) {
1006 			status = acpi_evaluate_integer(func->handle, "_STA", NULL, &sta);
1007 			if (ACPI_SUCCESS(status) && sta)
1008 				break;
1009 		} else {
1010 			pci_bus_read_config_dword(slot->bridge->pci_bus,
1011 					PCI_DEVFN(slot->device, func->function),
1012 					PCI_VENDOR_ID, &dvid);
1013 			if (dvid != 0xffffffff) {
1014 				sta = ACPI_STA_ALL;
1015 				break;
1016 			}
1017 		}
1018 	}
1019 
1020 	return (unsigned int)sta;
1021 }
1022 
1023 
1024 /*
1025  * ACPI event handlers
1026  */
1027 
1028 /**
1029  * handle_hotplug_event_bridge - handle ACPI event on bridges
1030  *
1031  * @handle: Notify()'ed acpi_handle
1032  * @type: Notify code
1033  * @context: pointer to acpiphp_bridge structure
1034  *
1035  * handles ACPI event notification on {host,p2p} bridges
1036  *
1037  */
handle_hotplug_event_bridge(acpi_handle handle,u32 type,void * context)1038 static void handle_hotplug_event_bridge (acpi_handle handle, u32 type, void *context)
1039 {
1040 	struct acpiphp_bridge *bridge;
1041 	char objname[64];
1042 	struct acpi_buffer buffer = { .length = sizeof(objname),
1043 				      .pointer = objname };
1044 
1045 	bridge = (struct acpiphp_bridge *)context;
1046 
1047 	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
1048 
1049 	switch (type) {
1050 	case ACPI_NOTIFY_BUS_CHECK:
1051 		/* bus re-enumerate */
1052 		dbg("%s: Bus check notify on %s\n", __FUNCTION__, objname);
1053 		acpiphp_check_bridge(bridge);
1054 		break;
1055 
1056 	case ACPI_NOTIFY_DEVICE_CHECK:
1057 		/* device check */
1058 		dbg("%s: Device check notify on %s\n", __FUNCTION__, objname);
1059 		acpiphp_check_bridge(bridge);
1060 		break;
1061 
1062 	case ACPI_NOTIFY_DEVICE_WAKE:
1063 		/* wake event */
1064 		dbg("%s: Device wake notify on %s\n", __FUNCTION__, objname);
1065 		break;
1066 
1067 	case ACPI_NOTIFY_EJECT_REQUEST:
1068 		/* request device eject */
1069 		dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname);
1070 		break;
1071 
1072 	default:
1073 		warn("notify_handler: unknown event type 0x%x for %s\n", type, objname);
1074 		break;
1075 	}
1076 }
1077 
1078 
1079 /**
1080  * handle_hotplug_event_func - handle ACPI event on functions (i.e. slots)
1081  *
1082  * @handle: Notify()'ed acpi_handle
1083  * @type: Notify code
1084  * @context: pointer to acpiphp_func structure
1085  *
1086  * handles ACPI event notification on slots
1087  *
1088  */
handle_hotplug_event_func(acpi_handle handle,u32 type,void * context)1089 static void handle_hotplug_event_func (acpi_handle handle, u32 type, void *context)
1090 {
1091 	struct acpiphp_func *func;
1092 	char objname[64];
1093 	struct acpi_buffer buffer = { .length = sizeof(objname),
1094 				      .pointer = objname };
1095 
1096 	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
1097 
1098 	func = (struct acpiphp_func *)context;
1099 
1100 	switch (type) {
1101 	case ACPI_NOTIFY_BUS_CHECK:
1102 		/* bus re-enumerate */
1103 		dbg("%s: Bus check notify on %s\n", __FUNCTION__, objname);
1104 		acpiphp_enable_slot(func->slot);
1105 		break;
1106 
1107 	case ACPI_NOTIFY_DEVICE_CHECK:
1108 		/* device check : re-enumerate from parent bus */
1109 		dbg("%s: Device check notify on %s\n", __FUNCTION__, objname);
1110 		acpiphp_check_bridge(func->slot->bridge);
1111 		break;
1112 
1113 	case ACPI_NOTIFY_DEVICE_WAKE:
1114 		/* wake event */
1115 		dbg("%s: Device wake notify on %s\n", __FUNCTION__, objname);
1116 		break;
1117 
1118 	case ACPI_NOTIFY_EJECT_REQUEST:
1119 		/* request device eject */
1120 		dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname);
1121 		acpiphp_disable_slot(func->slot);
1122 		break;
1123 
1124 	default:
1125 		warn("notify_handler: unknown event type 0x%x for %s\n", type, objname);
1126 		break;
1127 	}
1128 }
1129 
1130 
1131 static struct acpi_pci_driver acpi_pci_hp_driver = {
1132 	.add =		add_bridge,
1133 	.remove =	remove_bridge,
1134 };
1135 
1136 /**
1137  * acpiphp_glue_init - initializes all PCI hotplug - ACPI glue data structures
1138  *
1139  */
acpiphp_glue_init(void)1140 int acpiphp_glue_init (void)
1141 {
1142 	int num;
1143 
1144 	if (list_empty(&pci_root_buses))
1145 		return -1;
1146 
1147 	num = acpi_pci_register_driver(&acpi_pci_hp_driver);
1148 
1149 	if (num <= 0)
1150 		return -1;
1151 
1152 	return 0;
1153 }
1154 
1155 
1156 /**
1157  * acpiphp_glue_exit - terminates all PCI hotplug - ACPI glue data structures
1158  *
1159  * This function frees all data allocated in acpiphp_glue_init()
1160  */
acpiphp_glue_exit(void)1161 void acpiphp_glue_exit (void)
1162 {
1163 	struct list_head *l1, *l2, *n1, *n2;
1164 	struct acpiphp_bridge *bridge;
1165 	struct acpiphp_slot *slot, *next;
1166 	struct acpiphp_func *func;
1167 	acpi_status status;
1168 
1169 	list_for_each_safe (l1, n1, &bridge_list) {
1170 		bridge = (struct acpiphp_bridge *)l1;
1171 		slot = bridge->slots;
1172 		while (slot) {
1173 			next = slot->next;
1174 			list_for_each_safe (l2, n2, &slot->funcs) {
1175 				func = list_entry(l2, struct acpiphp_func, sibling);
1176 				acpiphp_free_resource(&func->io_head);
1177 				acpiphp_free_resource(&func->mem_head);
1178 				acpiphp_free_resource(&func->p_mem_head);
1179 				acpiphp_free_resource(&func->bus_head);
1180 				status = acpi_remove_notify_handler(func->handle,
1181 								    ACPI_SYSTEM_NOTIFY,
1182 								    handle_hotplug_event_func);
1183 				if (ACPI_FAILURE(status))
1184 					err("failed to remove notify handler\n");
1185 				kfree(func);
1186 			}
1187 			kfree(slot);
1188 			slot = next;
1189 		}
1190 		status = acpi_remove_notify_handler(bridge->handle, ACPI_SYSTEM_NOTIFY,
1191 						    handle_hotplug_event_bridge);
1192 		if (ACPI_FAILURE(status))
1193 			err("failed to remove notify handler\n");
1194 
1195 		acpiphp_free_resource(&bridge->io_head);
1196 		acpiphp_free_resource(&bridge->mem_head);
1197 		acpiphp_free_resource(&bridge->p_mem_head);
1198 		acpiphp_free_resource(&bridge->bus_head);
1199 
1200 		kfree(bridge);
1201 	}
1202 }
1203 
1204 
1205 /**
1206  * acpiphp_get_num_slots - count number of slots in a system
1207  */
acpiphp_get_num_slots(void)1208 int acpiphp_get_num_slots (void)
1209 {
1210 	struct list_head *node;
1211 	struct acpiphp_bridge *bridge;
1212 	int num_slots;
1213 
1214 	num_slots = 0;
1215 
1216 	list_for_each (node, &bridge_list) {
1217 		bridge = (struct acpiphp_bridge *)node;
1218 		dbg("Bus%d %dslot(s)\n", bridge->bus, bridge->nr_slots);
1219 		num_slots += bridge->nr_slots;
1220 	}
1221 
1222 	dbg("Total %dslots\n", num_slots);
1223 	return num_slots;
1224 }
1225 
1226 
1227 /**
1228  * acpiphp_for_each_slot - call function for each slot
1229  * @fn: callback function
1230  * @data: context to be passed to callback function
1231  *
1232  */
acpiphp_for_each_slot(acpiphp_callback fn,void * data)1233 int acpiphp_for_each_slot(acpiphp_callback fn, void *data)
1234 {
1235 	struct list_head *node;
1236 	struct acpiphp_bridge *bridge;
1237 	struct acpiphp_slot *slot;
1238 	int retval = 0;
1239 
1240 	list_for_each (node, &bridge_list) {
1241 		bridge = (struct acpiphp_bridge *)node;
1242 		for (slot = bridge->slots; slot; slot = slot->next) {
1243 			retval = fn(slot, data);
1244 			if (!retval)
1245 				goto err_exit;
1246 		}
1247 	}
1248 
1249  err_exit:
1250 	return retval;
1251 }
1252 
1253 
1254 /* search matching slot from id  */
get_slot_from_id(int id)1255 struct acpiphp_slot *get_slot_from_id (int id)
1256 {
1257 	struct list_head *node;
1258 	struct acpiphp_bridge *bridge;
1259 	struct acpiphp_slot *slot;
1260 
1261 	list_for_each (node, &bridge_list) {
1262 		bridge = (struct acpiphp_bridge *)node;
1263 		for (slot = bridge->slots; slot; slot = slot->next)
1264 			if (slot->id == id)
1265 				return slot;
1266 	}
1267 
1268 	/* should never happen! */
1269 	err("%s: no object for id %d\n",__FUNCTION__, id);
1270 	return 0;
1271 }
1272 
1273 
1274 /**
1275  * acpiphp_enable_slot - power on slot
1276  */
acpiphp_enable_slot(struct acpiphp_slot * slot)1277 int acpiphp_enable_slot (struct acpiphp_slot *slot)
1278 {
1279 	int retval;
1280 
1281 	down(&slot->crit_sect);
1282 
1283 	/* wake up all functions */
1284 	retval = power_on_slot(slot);
1285 	if (retval)
1286 		goto err_exit;
1287 
1288 	if (get_slot_status(slot) == ACPI_STA_ALL)
1289 		/* configure all functions */
1290 		retval = enable_device(slot);
1291 
1292  err_exit:
1293 	up(&slot->crit_sect);
1294 	return retval;
1295 }
1296 
1297 
1298 /**
1299  * acpiphp_disable_slot - power off slot
1300  */
acpiphp_disable_slot(struct acpiphp_slot * slot)1301 int acpiphp_disable_slot (struct acpiphp_slot *slot)
1302 {
1303 	int retval = 0;
1304 
1305 	down(&slot->crit_sect);
1306 
1307 	/* unconfigure all functions */
1308 	retval = disable_device(slot);
1309 	if (retval)
1310 		goto err_exit;
1311 
1312 	/* power off all functions */
1313 	retval = power_off_slot(slot);
1314 	if (retval)
1315 		goto err_exit;
1316 
1317 	acpiphp_resource_sort_and_combine(&slot->bridge->io_head);
1318 	acpiphp_resource_sort_and_combine(&slot->bridge->mem_head);
1319 	acpiphp_resource_sort_and_combine(&slot->bridge->p_mem_head);
1320 	acpiphp_resource_sort_and_combine(&slot->bridge->bus_head);
1321 	dbg("Available resources:\n");
1322 	acpiphp_dump_resource(slot->bridge);
1323 
1324  err_exit:
1325 	up(&slot->crit_sect);
1326 	return retval;
1327 }
1328 
1329 
1330 /**
1331  * acpiphp_check_bridge - re-enumerate devices
1332  */
acpiphp_check_bridge(struct acpiphp_bridge * bridge)1333 int acpiphp_check_bridge (struct acpiphp_bridge *bridge)
1334 {
1335 	struct acpiphp_slot *slot;
1336 	unsigned int sta;
1337 	int retval = 0;
1338 	int enabled, disabled;
1339 
1340 	enabled = disabled = 0;
1341 
1342 	for (slot = bridge->slots; slot; slot = slot->next) {
1343 		sta = get_slot_status(slot);
1344 		if (slot->flags & SLOT_ENABLED) {
1345 			/* if enabled but not present, disable */
1346 			if (sta != ACPI_STA_ALL) {
1347 				retval = acpiphp_disable_slot(slot);
1348 				if (retval) {
1349 					err("Error occurred in enabling\n");
1350 					up(&slot->crit_sect);
1351 					goto err_exit;
1352 				}
1353 				disabled++;
1354 			}
1355 		} else {
1356 			/* if disabled but present, enable */
1357 			if (sta == ACPI_STA_ALL) {
1358 				retval = acpiphp_enable_slot(slot);
1359 				if (retval) {
1360 					err("Error occurred in enabling\n");
1361 					up(&slot->crit_sect);
1362 					goto err_exit;
1363 				}
1364 				enabled++;
1365 			}
1366 		}
1367 	}
1368 
1369 	dbg("%s: %d enabled, %d disabled\n", __FUNCTION__, enabled, disabled);
1370 
1371  err_exit:
1372 	return retval;
1373 }
1374 
1375 
1376 /*
1377  * slot enabled:  1
1378  * slot disabled: 0
1379  */
acpiphp_get_power_status(struct acpiphp_slot * slot)1380 u8 acpiphp_get_power_status (struct acpiphp_slot *slot)
1381 {
1382 	unsigned int sta;
1383 
1384 	sta = get_slot_status(slot);
1385 
1386 	return (sta & ACPI_STA_ENABLED) ? 1 : 0;
1387 }
1388 
1389 
1390 /*
1391  * attention LED ON: 1
1392  *		OFF: 0
1393  *
1394  * TBD
1395  * no direct attention led status information via ACPI
1396  *
1397  */
acpiphp_get_attention_status(struct acpiphp_slot * slot)1398 u8 acpiphp_get_attention_status (struct acpiphp_slot *slot)
1399 {
1400 	return 0;
1401 }
1402 
1403 
1404 /*
1405  * latch closed:  1
1406  * latch   open:  0
1407  */
acpiphp_get_latch_status(struct acpiphp_slot * slot)1408 u8 acpiphp_get_latch_status (struct acpiphp_slot *slot)
1409 {
1410 	unsigned int sta;
1411 
1412 	sta = get_slot_status(slot);
1413 
1414 	return (sta & ACPI_STA_SHOW_IN_UI) ? 1 : 0;
1415 }
1416 
1417 
1418 /*
1419  * adapter presence : 1
1420  *          absence : 0
1421  */
acpiphp_get_adapter_status(struct acpiphp_slot * slot)1422 u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot)
1423 {
1424 	unsigned int sta;
1425 
1426 	sta = get_slot_status(slot);
1427 
1428 	return (sta == 0) ? 0 : 1;
1429 }
1430 
1431 
1432 /*
1433  * pci address (seg/bus/dev)
1434  */
acpiphp_get_address(struct acpiphp_slot * slot)1435 u32 acpiphp_get_address (struct acpiphp_slot *slot)
1436 {
1437 	u32 address;
1438 
1439 	address = ((slot->bridge->seg) << 16) |
1440 		  ((slot->bridge->bus) << 8) |
1441 		  slot->device;
1442 
1443 	return address;
1444 }
1445