aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/bus.c11
-rw-r--r--drivers/pci/hotplug/Makefile4
-rw-r--r--drivers/pci/hotplug/acpiphp.h47
-rw-r--r--drivers/pci/hotplug/acpiphp_core.c9
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c882
-rw-r--r--drivers/pci/hotplug/acpiphp_pci.c449
-rw-r--r--drivers/pci/hotplug/acpiphp_res.c700
-rw-r--r--drivers/pci/hotplug/cpqphp_core.c5
-rw-r--r--drivers/pci/msi.c88
-rw-r--r--drivers/pci/msi.h9
-rw-r--r--drivers/pci/pci-sysfs.c26
-rw-r--r--drivers/pci/probe.c29
-rw-r--r--drivers/pci/proc.c14
-rw-r--r--drivers/pci/remove.c14
-rw-r--r--drivers/pci/setup-bus.c5
15 files changed, 633 insertions, 1659 deletions
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index dbd33605cc10..fedae89d8f7d 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -121,10 +121,13 @@ void __devinit pci_bus_add_devices(struct pci_bus *bus)
121 * If there is an unattached subordinate bus, attach 121 * If there is an unattached subordinate bus, attach
122 * it and then scan for unattached PCI devices. 122 * it and then scan for unattached PCI devices.
123 */ 123 */
124 if (dev->subordinate && list_empty(&dev->subordinate->node)) { 124 if (dev->subordinate) {
125 spin_lock(&pci_bus_lock); 125 if (list_empty(&dev->subordinate->node)) {
126 list_add_tail(&dev->subordinate->node, &dev->bus->children); 126 spin_lock(&pci_bus_lock);
127 spin_unlock(&pci_bus_lock); 127 list_add_tail(&dev->subordinate->node,
128 &dev->bus->children);
129 spin_unlock(&pci_bus_lock);
130 }
128 pci_bus_add_devices(dev->subordinate); 131 pci_bus_add_devices(dev->subordinate);
129 132
130 sysfs_create_link(&dev->subordinate->class_dev.kobj, &dev->dev.kobj, "bridge"); 133 sysfs_create_link(&dev->subordinate->class_dev.kobj, &dev->dev.kobj, "bridge");
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile
index 93c120ddbd39..3e632ff8c717 100644
--- a/drivers/pci/hotplug/Makefile
+++ b/drivers/pci/hotplug/Makefile
@@ -36,9 +36,7 @@ ibmphp-objs := ibmphp_core.o \
36 ibmphp_hpc.o 36 ibmphp_hpc.o
37 37
38acpiphp-objs := acpiphp_core.o \ 38acpiphp-objs := acpiphp_core.o \
39 acpiphp_glue.o \ 39 acpiphp_glue.o
40 acpiphp_pci.o \
41 acpiphp_res.o
42 40
43rpaphp-objs := rpaphp_core.o \ 41rpaphp-objs := rpaphp_core.o \
44 rpaphp_pci.o \ 42 rpaphp_pci.o \
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index d9499874c8a9..293603e1b7c3 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -7,6 +7,8 @@
7 * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) 7 * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
8 * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com) 8 * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
9 * Copyright (C) 2002,2003 NEC Corporation 9 * Copyright (C) 2002,2003 NEC Corporation
10 * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com)
11 * Copyright (C) 2003-2005 Hewlett Packard
10 * 12 *
11 * All rights reserved. 13 * All rights reserved.
12 * 14 *
@@ -52,7 +54,6 @@
52 54
53struct acpiphp_bridge; 55struct acpiphp_bridge;
54struct acpiphp_slot; 56struct acpiphp_slot;
55struct pci_resource;
56 57
57/* 58/*
58 * struct slot - slot information for each *physical* slot 59 * struct slot - slot information for each *physical* slot
@@ -65,15 +66,6 @@ struct slot {
65 struct acpiphp_slot *acpi_slot; 66 struct acpiphp_slot *acpi_slot;
66}; 67};
67 68
68/*
69 * struct pci_resource - describes pci resource (mem, pfmem, io, bus)
70 */
71struct pci_resource {
72 struct pci_resource * next;
73 u64 base;
74 u32 length;
75};
76
77/** 69/**
78 * struct hpp_param - ACPI 2.0 _HPP Hot Plug Parameters 70 * struct hpp_param - ACPI 2.0 _HPP Hot Plug Parameters
79 * @cache_line_size in DWORD 71 * @cache_line_size in DWORD
@@ -101,10 +93,6 @@ struct acpiphp_bridge {
101 int type; 93 int type;
102 int nr_slots; 94 int nr_slots;
103 95
104 u8 seg;
105 u8 bus;
106 u8 sub;
107
108 u32 flags; 96 u32 flags;
109 97
110 /* This bus (host bridge) or Secondary bus (PCI-to-PCI bridge) */ 98 /* This bus (host bridge) or Secondary bus (PCI-to-PCI bridge) */
@@ -117,12 +105,6 @@ struct acpiphp_bridge {
117 struct hpp_param hpp; 105 struct hpp_param hpp;
118 106
119 spinlock_t res_lock; 107 spinlock_t res_lock;
120
121 /* available resources on this bus */
122 struct pci_resource *mem_head;
123 struct pci_resource *p_mem_head;
124 struct pci_resource *io_head;
125 struct pci_resource *bus_head;
126}; 108};
127 109
128 110
@@ -163,12 +145,6 @@ struct acpiphp_func {
163 145
164 u8 function; /* pci function# */ 146 u8 function; /* pci function# */
165 u32 flags; /* see below */ 147 u32 flags; /* see below */
166
167 /* resources used for this function */
168 struct pci_resource *mem_head;
169 struct pci_resource *p_mem_head;
170 struct pci_resource *io_head;
171 struct pci_resource *bus_head;
172}; 148};
173 149
174/** 150/**
@@ -243,25 +219,6 @@ extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot);
243extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot); 219extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot);
244extern u32 acpiphp_get_address (struct acpiphp_slot *slot); 220extern u32 acpiphp_get_address (struct acpiphp_slot *slot);
245 221
246/* acpiphp_pci.c */
247extern struct pci_dev *acpiphp_allocate_pcidev (struct pci_bus *pbus, int dev, int fn);
248extern int acpiphp_configure_slot (struct acpiphp_slot *slot);
249extern int acpiphp_configure_function (struct acpiphp_func *func);
250extern void acpiphp_unconfigure_function (struct acpiphp_func *func);
251extern int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge);
252extern int acpiphp_init_func_resource (struct acpiphp_func *func);
253
254/* acpiphp_res.c */
255extern struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size);
256extern struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size);
257extern struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size);
258extern int acpiphp_resource_sort_and_combine (struct pci_resource **head);
259extern struct pci_resource *acpiphp_make_resource (u64 base, u32 length);
260extern void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to);
261extern void acpiphp_free_resource (struct pci_resource **res);
262extern void acpiphp_dump_resource (struct acpiphp_bridge *bridge); /* debug */
263extern void acpiphp_dump_func_resource (struct acpiphp_func *func); /* debug */
264
265/* variables */ 222/* variables */
266extern int acpiphp_debug; 223extern int acpiphp_debug;
267 224
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
index 4539e61a3dc1..60c4c38047a3 100644
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -7,6 +7,8 @@
7 * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) 7 * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
8 * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com) 8 * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
9 * Copyright (C) 2002,2003 NEC Corporation 9 * Copyright (C) 2002,2003 NEC Corporation
10 * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com)
11 * Copyright (C) 2003-2005 Hewlett Packard
10 * 12 *
11 * All rights reserved. 13 * All rights reserved.
12 * 14 *
@@ -53,8 +55,8 @@ int acpiphp_debug;
53static int num_slots; 55static int num_slots;
54static struct acpiphp_attention_info *attention_info; 56static struct acpiphp_attention_info *attention_info;
55 57
56#define DRIVER_VERSION "0.4" 58#define DRIVER_VERSION "0.5"
57#define DRIVER_AUTHOR "Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-kochi@bq.jp.nec.com>" 59#define DRIVER_AUTHOR "Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-kochi@bq.jp.nec.com>, Matthew Wilcox <willy@hp.com>"
58#define DRIVER_DESC "ACPI Hot Plug PCI Controller Driver" 60#define DRIVER_DESC "ACPI Hot Plug PCI Controller Driver"
59 61
60MODULE_AUTHOR(DRIVER_AUTHOR); 62MODULE_AUTHOR(DRIVER_AUTHOR);
@@ -281,8 +283,7 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
281/** 283/**
282 * get_address - get pci address of a slot 284 * get_address - get pci address of a slot
283 * @hotplug_slot: slot to get status 285 * @hotplug_slot: slot to get status
284 * @busdev: pointer to struct pci_busdev (seg, bus, dev) 286 * @value: pointer to struct pci_busdev (seg, bus, dev)
285 *
286 */ 287 */
287static int get_address(struct hotplug_slot *hotplug_slot, u32 *value) 288static int get_address(struct hotplug_slot *hotplug_slot, u32 *value)
288{ 289{
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index e7f41294f811..424e7de181ae 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -4,6 +4,10 @@
4 * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com) 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) 5 * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
6 * Copyright (C) 2002,2003 NEC Corporation 6 * Copyright (C) 2002,2003 NEC Corporation
7 * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com)
8 * Copyright (C) 2003-2005 Hewlett Packard
9 * Copyright (C) 2005 Rajesh Shah (rajesh.shah@intel.com)
10 * Copyright (C) 2005 Intel Corporation
7 * 11 *
8 * All rights reserved. 12 * All rights reserved.
9 * 13 *
@@ -26,6 +30,16 @@
26 * 30 *
27 */ 31 */
28 32
33/*
34 * Lifetime rules for pci_dev:
35 * - The one in acpiphp_func has its refcount elevated by pci_get_slot()
36 * when the driver is loaded or when an insertion event occurs. It loses
37 * a refcount when its ejected or the driver unloads.
38 * - The one in acpiphp_bridge has its refcount elevated by pci_get_slot()
39 * when the bridge is scanned and it loses a refcount when the bridge
40 * is removed.
41 */
42
29#include <linux/init.h> 43#include <linux/init.h>
30#include <linux/module.h> 44#include <linux/module.h>
31 45
@@ -178,21 +192,18 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
178 192
179 bridge->nr_slots++; 193 bridge->nr_slots++;
180 194
181 dbg("found ACPI PCI Hotplug slot at PCI %02x:%02x Slot:%d\n", 195 dbg("found ACPI PCI Hotplug slot %d at PCI %04x:%02x:%02x\n",
182 slot->bridge->bus, slot->device, slot->sun); 196 slot->sun, pci_domain_nr(bridge->pci_bus),
197 bridge->pci_bus->number, slot->device);
183 } 198 }
184 199
185 newfunc->slot = slot; 200 newfunc->slot = slot;
186 list_add_tail(&newfunc->sibling, &slot->funcs); 201 list_add_tail(&newfunc->sibling, &slot->funcs);
187 202
188 /* associate corresponding pci_dev */ 203 /* associate corresponding pci_dev */
189 newfunc->pci_dev = pci_find_slot(bridge->bus, 204 newfunc->pci_dev = pci_get_slot(bridge->pci_bus,
190 PCI_DEVFN(device, function)); 205 PCI_DEVFN(device, function));
191 if (newfunc->pci_dev) { 206 if (newfunc->pci_dev) {
192 if (acpiphp_init_func_resource(newfunc) < 0) {
193 kfree(newfunc);
194 return AE_ERROR;
195 }
196 slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); 207 slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON);
197 } 208 }
198 209
@@ -227,62 +238,6 @@ static int detect_ejectable_slots(acpi_handle *bridge_handle)
227} 238}
228 239
229 240
230/* decode ACPI _CRS data and convert into our internal resource list
231 * TBD: _TRA, etc.
232 */
233static acpi_status
234decode_acpi_resource(struct acpi_resource *resource, void *context)
235{
236 struct acpiphp_bridge *bridge = (struct acpiphp_bridge *) context;
237 struct acpi_resource_address64 address;
238 struct pci_resource *res;
239
240 if (resource->id != ACPI_RSTYPE_ADDRESS16 &&
241 resource->id != ACPI_RSTYPE_ADDRESS32 &&
242 resource->id != ACPI_RSTYPE_ADDRESS64)
243 return AE_OK;
244
245 acpi_resource_to_address64(resource, &address);
246
247 if (address.producer_consumer == ACPI_PRODUCER && address.address_length > 0) {
248 dbg("resource type: %d: 0x%llx - 0x%llx\n", address.resource_type,
249 (unsigned long long)address.min_address_range,
250 (unsigned long long)address.max_address_range);
251 res = acpiphp_make_resource(address.min_address_range,
252 address.address_length);
253 if (!res) {
254 err("out of memory\n");
255 return AE_OK;
256 }
257
258 switch (address.resource_type) {
259 case ACPI_MEMORY_RANGE:
260 if (address.attribute.memory.cache_attribute == ACPI_PREFETCHABLE_MEMORY) {
261 res->next = bridge->p_mem_head;
262 bridge->p_mem_head = res;
263 } else {
264 res->next = bridge->mem_head;
265 bridge->mem_head = res;
266 }
267 break;
268 case ACPI_IO_RANGE:
269 res->next = bridge->io_head;
270 bridge->io_head = res;
271 break;
272 case ACPI_BUS_NUMBER_RANGE:
273 res->next = bridge->bus_head;
274 bridge->bus_head = res;
275 break;
276 default:
277 /* invalid type */
278 kfree(res);
279 break;
280 }
281 }
282
283 return AE_OK;
284}
285
286/* decode ACPI 2.0 _HPP hot plug parameters */ 241/* decode ACPI 2.0 _HPP hot plug parameters */
287static void decode_hpp(struct acpiphp_bridge *bridge) 242static void decode_hpp(struct acpiphp_bridge *bridge)
288{ 243{
@@ -346,34 +301,29 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge)
346 /* decode ACPI 2.0 _HPP (hot plug parameters) */ 301 /* decode ACPI 2.0 _HPP (hot plug parameters) */
347 decode_hpp(bridge); 302 decode_hpp(bridge);
348 303
349 /* subtract all resources already allocated */
350 acpiphp_detect_pci_resource(bridge);
351
352 /* register all slot objects under this bridge */ 304 /* register all slot objects under this bridge */
353 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1, 305 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1,
354 register_slot, bridge, NULL); 306 register_slot, bridge, NULL);
355 307
356 /* install notify handler */ 308 /* install notify handler */
357 status = acpi_install_notify_handler(bridge->handle, 309 if (bridge->type != BRIDGE_TYPE_HOST) {
310 status = acpi_install_notify_handler(bridge->handle,
358 ACPI_SYSTEM_NOTIFY, 311 ACPI_SYSTEM_NOTIFY,
359 handle_hotplug_event_bridge, 312 handle_hotplug_event_bridge,
360 bridge); 313 bridge);
361 314
362 if (ACPI_FAILURE(status)) { 315 if (ACPI_FAILURE(status)) {
363 err("failed to register interrupt notify handler\n"); 316 err("failed to register interrupt notify handler\n");
317 }
364 } 318 }
365 319
366 list_add(&bridge->list, &bridge_list); 320 list_add(&bridge->list, &bridge_list);
367
368 dbg("Bridge resource:\n");
369 acpiphp_dump_resource(bridge);
370} 321}
371 322
372 323
373/* allocate and initialize host bridge data structure */ 324/* allocate and initialize host bridge data structure */
374static void add_host_bridge(acpi_handle *handle, int seg, int bus) 325static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus)
375{ 326{
376 acpi_status status;
377 struct acpiphp_bridge *bridge; 327 struct acpiphp_bridge *bridge;
378 328
379 bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); 329 bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
@@ -384,52 +334,19 @@ static void add_host_bridge(acpi_handle *handle, int seg, int bus)
384 334
385 bridge->type = BRIDGE_TYPE_HOST; 335 bridge->type = BRIDGE_TYPE_HOST;
386 bridge->handle = handle; 336 bridge->handle = handle;
387 bridge->seg = seg;
388 bridge->bus = bus;
389 337
390 bridge->pci_bus = pci_find_bus(seg, bus); 338 bridge->pci_bus = pci_bus;
391 339
392 spin_lock_init(&bridge->res_lock); 340 spin_lock_init(&bridge->res_lock);
393 341
394 /* to be overridden when we decode _CRS */
395 bridge->sub = bridge->bus;
396
397 /* decode resources */
398
399 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
400 decode_acpi_resource, bridge);
401
402 if (ACPI_FAILURE(status)) {
403 err("failed to decode bridge resources\n");
404 kfree(bridge);
405 return;
406 }
407
408 acpiphp_resource_sort_and_combine(&bridge->io_head);
409 acpiphp_resource_sort_and_combine(&bridge->mem_head);
410 acpiphp_resource_sort_and_combine(&bridge->p_mem_head);
411 acpiphp_resource_sort_and_combine(&bridge->bus_head);
412
413 dbg("ACPI _CRS resource:\n");
414 acpiphp_dump_resource(bridge);
415
416 if (bridge->bus_head) {
417 bridge->bus = bridge->bus_head->base;
418 bridge->sub = bridge->bus_head->base + bridge->bus_head->length - 1;
419 }
420
421 init_bridge_misc(bridge); 342 init_bridge_misc(bridge);
422} 343}
423 344
424 345
425/* allocate and initialize PCI-to-PCI bridge data structure */ 346/* allocate and initialize PCI-to-PCI bridge data structure */
426static void add_p2p_bridge(acpi_handle *handle, int seg, int bus, int dev, int fn) 347static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev)
427{ 348{
428 struct acpiphp_bridge *bridge; 349 struct acpiphp_bridge *bridge;
429 u8 tmp8;
430 u16 tmp16;
431 u64 base64, limit64;
432 u32 base, limit, base32u, limit32u;
433 350
434 bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); 351 bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
435 if (bridge == NULL) { 352 if (bridge == NULL) {
@@ -441,133 +358,22 @@ static void add_p2p_bridge(acpi_handle *handle, int seg, int bus, int dev, int f
441 358
442 bridge->type = BRIDGE_TYPE_P2P; 359 bridge->type = BRIDGE_TYPE_P2P;
443 bridge->handle = handle; 360 bridge->handle = handle;
444 bridge->seg = seg;
445
446 bridge->pci_dev = pci_find_slot(bus, PCI_DEVFN(dev, fn));
447 if (!bridge->pci_dev) {
448 err("Can't get pci_dev\n");
449 kfree(bridge);
450 return;
451 }
452 361
453 bridge->pci_bus = bridge->pci_dev->subordinate; 362 bridge->pci_dev = pci_dev_get(pci_dev);
363 bridge->pci_bus = pci_dev->subordinate;
454 if (!bridge->pci_bus) { 364 if (!bridge->pci_bus) {
455 err("This is not a PCI-to-PCI bridge!\n"); 365 err("This is not a PCI-to-PCI bridge!\n");
456 kfree(bridge); 366 goto err;
457 return;
458 } 367 }
459 368
460 spin_lock_init(&bridge->res_lock); 369 spin_lock_init(&bridge->res_lock);
461 370
462 bridge->bus = bridge->pci_bus->number;
463 bridge->sub = bridge->pci_bus->subordinate;
464
465 /*
466 * decode resources under this P2P bridge
467 */
468
469 /* I/O resources */
470 pci_read_config_byte(bridge->pci_dev, PCI_IO_BASE, &tmp8);
471 base = tmp8;
472 pci_read_config_byte(bridge->pci_dev, PCI_IO_LIMIT, &tmp8);
473 limit = tmp8;
474
475 switch (base & PCI_IO_RANGE_TYPE_MASK) {
476 case PCI_IO_RANGE_TYPE_16:
477 base = (base << 8) & 0xf000;
478 limit = ((limit << 8) & 0xf000) + 0xfff;
479 bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);
480 if (!bridge->io_head) {
481 err("out of memory\n");
482 kfree(bridge);
483 return;
484 }
485 dbg("16bit I/O range: %04x-%04x\n",
486 (u32)bridge->io_head->base,
487 (u32)(bridge->io_head->base + bridge->io_head->length - 1));
488 break;
489 case PCI_IO_RANGE_TYPE_32:
490 pci_read_config_word(bridge->pci_dev, PCI_IO_BASE_UPPER16, &tmp16);
491 base = ((u32)tmp16 << 16) | ((base << 8) & 0xf000);
492 pci_read_config_word(bridge->pci_dev, PCI_IO_LIMIT_UPPER16, &tmp16);
493 limit = (((u32)tmp16 << 16) | ((limit << 8) & 0xf000)) + 0xfff;
494 bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);
495 if (!bridge->io_head) {
496 err("out of memory\n");
497 kfree(bridge);
498 return;
499 }
500 dbg("32bit I/O range: %08x-%08x\n",
501 (u32)bridge->io_head->base,
502 (u32)(bridge->io_head->base + bridge->io_head->length - 1));
503 break;
504 case 0x0f:
505 dbg("I/O space unsupported\n");
506 break;
507 default:
508 warn("Unknown I/O range type\n");
509 }
510
511 /* Memory resources (mandatory for P2P bridge) */
512 pci_read_config_word(bridge->pci_dev, PCI_MEMORY_BASE, &tmp16);
513 base = (tmp16 & 0xfff0) << 16;
514 pci_read_config_word(bridge->pci_dev, PCI_MEMORY_LIMIT, &tmp16);
515 limit = ((tmp16 & 0xfff0) << 16) | 0xfffff;
516 bridge->mem_head = acpiphp_make_resource((u64)base, limit - base + 1);
517 if (!bridge->mem_head) {
518 err("out of memory\n");
519 kfree(bridge);
520 return;
521 }
522 dbg("32bit Memory range: %08x-%08x\n",
523 (u32)bridge->mem_head->base,
524 (u32)(bridge->mem_head->base + bridge->mem_head->length-1));
525
526 /* Prefetchable Memory resources (optional) */
527 pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_BASE, &tmp16);
528 base = tmp16;
529 pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_LIMIT, &tmp16);
530 limit = tmp16;
531
532 switch (base & PCI_MEMORY_RANGE_TYPE_MASK) {
533 case PCI_PREF_RANGE_TYPE_32:
534 base = (base & 0xfff0) << 16;
535 limit = ((limit & 0xfff0) << 16) | 0xfffff;
536 bridge->p_mem_head = acpiphp_make_resource((u64)base, limit - base + 1);
537 if (!bridge->p_mem_head) {
538 err("out of memory\n");
539 kfree(bridge);
540 return;
541 }
542 dbg("32bit Prefetchable memory range: %08x-%08x\n",
543 (u32)bridge->p_mem_head->base,
544 (u32)(bridge->p_mem_head->base + bridge->p_mem_head->length - 1));
545 break;
546 case PCI_PREF_RANGE_TYPE_64:
547 pci_read_config_dword(bridge->pci_dev, PCI_PREF_BASE_UPPER32, &base32u);
548 pci_read_config_dword(bridge->pci_dev, PCI_PREF_LIMIT_UPPER32, &limit32u);
549 base64 = ((u64)base32u << 32) | ((base & 0xfff0) << 16);
550 limit64 = (((u64)limit32u << 32) | ((limit & 0xfff0) << 16)) + 0xfffff;
551
552 bridge->p_mem_head = acpiphp_make_resource(base64, limit64 - base64 + 1);
553 if (!bridge->p_mem_head) {
554 err("out of memory\n");
555 kfree(bridge);
556 return;
557 }
558 dbg("64bit Prefetchable memory range: %08x%08x-%08x%08x\n",
559 (u32)(bridge->p_mem_head->base >> 32),
560 (u32)(bridge->p_mem_head->base & 0xffffffff),
561 (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) >> 32),
562 (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) & 0xffffffff));
563 break;
564 case 0x0f:
565 break;
566 default:
567 warn("Unknown prefetchale memory type\n");
568 }
569
570 init_bridge_misc(bridge); 371 init_bridge_misc(bridge);
372 return;
373 err:
374 pci_dev_put(pci_dev);
375 kfree(bridge);
376 return;
571} 377}
572 378
573 379
@@ -577,14 +383,10 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
577{ 383{
578 acpi_status status; 384 acpi_status status;
579 acpi_handle dummy_handle; 385 acpi_handle dummy_handle;
580 unsigned long *segbus = context;
581 unsigned long tmp; 386 unsigned long tmp;
582 int seg, bus, device, function; 387 int device, function;
583 struct pci_dev *dev; 388 struct pci_dev *dev;
584 389 struct pci_bus *pci_bus = context;
585 /* get PCI address */
586 seg = (*segbus >> 8) & 0xff;
587 bus = *segbus & 0xff;
588 390
589 status = acpi_get_handle(handle, "_ADR", &dummy_handle); 391 status = acpi_get_handle(handle, "_ADR", &dummy_handle);
590 if (ACPI_FAILURE(status)) 392 if (ACPI_FAILURE(status))
@@ -599,20 +401,19 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
599 device = (tmp >> 16) & 0xffff; 401 device = (tmp >> 16) & 0xffff;
600 function = tmp & 0xffff; 402 function = tmp & 0xffff;
601 403
602 dev = pci_find_slot(bus, PCI_DEVFN(device, function)); 404 dev = pci_get_slot(pci_bus, PCI_DEVFN(device, function));
603 405
604 if (!dev) 406 if (!dev || !dev->subordinate)
605 return AE_OK; 407 goto out;
606
607 if (!dev->subordinate)
608 return AE_OK;
609 408
610 /* check if this bridge has ejectable slots */ 409 /* check if this bridge has ejectable slots */
611 if (detect_ejectable_slots(handle) > 0) { 410 if (detect_ejectable_slots(handle) > 0) {
612 dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev)); 411 dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev));
613 add_p2p_bridge(handle, seg, bus, device, function); 412 add_p2p_bridge(handle, dev);
614 } 413 }
615 414
415 out:
416 pci_dev_put(dev);
616 return AE_OK; 417 return AE_OK;
617} 418}
618 419
@@ -624,6 +425,7 @@ static int add_bridge(acpi_handle handle)
624 unsigned long tmp; 425 unsigned long tmp;
625 int seg, bus; 426 int seg, bus;
626 acpi_handle dummy_handle; 427 acpi_handle dummy_handle;
428 struct pci_bus *pci_bus;
627 429
628 /* if the bridge doesn't have _STA, we assume it is always there */ 430 /* if the bridge doesn't have _STA, we assume it is always there */
629 status = acpi_get_handle(handle, "_STA", &dummy_handle); 431 status = acpi_get_handle(handle, "_STA", &dummy_handle);
@@ -653,18 +455,22 @@ static int add_bridge(acpi_handle handle)
653 bus = 0; 455 bus = 0;
654 } 456 }
655 457
458 pci_bus = pci_find_bus(seg, bus);
459 if (!pci_bus) {
460 err("Can't find bus %04x:%02x\n", seg, bus);
461 return 0;
462 }
463
656 /* check if this bridge has ejectable slots */ 464 /* check if this bridge has ejectable slots */
657 if (detect_ejectable_slots(handle) > 0) { 465 if (detect_ejectable_slots(handle) > 0) {
658 dbg("found PCI host-bus bridge with hot-pluggable slots\n"); 466 dbg("found PCI host-bus bridge with hot-pluggable slots\n");
659 add_host_bridge(handle, seg, bus); 467 add_host_bridge(handle, pci_bus);
660 return 0; 468 return 0;
661 } 469 }
662 470
663 tmp = seg << 8 | bus;
664
665 /* search P2P bridges under this host bridge */ 471 /* search P2P bridges under this host bridge */
666 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, 472 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
667 find_p2p_bridge, &tmp, NULL); 473 find_p2p_bridge, pci_bus, NULL);
668 474
669 if (ACPI_FAILURE(status)) 475 if (ACPI_FAILURE(status))
670 warn("find_p2p_bridge faied (error code = 0x%x)\n",status); 476 warn("find_p2p_bridge faied (error code = 0x%x)\n",status);
@@ -672,12 +478,205 @@ static int add_bridge(acpi_handle handle)
672 return 0; 478 return 0;
673} 479}
674 480
481static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle)
482{
483 struct list_head *head;
484 list_for_each(head, &bridge_list) {
485 struct acpiphp_bridge *bridge = list_entry(head,
486 struct acpiphp_bridge, list);
487 if (bridge->handle == handle)
488 return bridge;
489 }
490
491 return NULL;
492}
493
494static void cleanup_bridge(struct acpiphp_bridge *bridge)
495{
496 struct list_head *list, *tmp;
497 struct acpiphp_slot *slot;
498 acpi_status status;
499 acpi_handle handle = bridge->handle;
500
501 status = acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
502 handle_hotplug_event_bridge);
503 if (ACPI_FAILURE(status))
504 err("failed to remove notify handler\n");
505
506 slot = bridge->slots;
507 while (slot) {
508 struct acpiphp_slot *next = slot->next;
509 list_for_each_safe (list, tmp, &slot->funcs) {
510 struct acpiphp_func *func;
511 func = list_entry(list, struct acpiphp_func, sibling);
512 status = acpi_remove_notify_handler(func->handle,
513 ACPI_SYSTEM_NOTIFY,
514 handle_hotplug_event_func);
515 if (ACPI_FAILURE(status))
516 err("failed to remove notify handler\n");
517 pci_dev_put(func->pci_dev);
518 list_del(list);
519 kfree(func);
520 }
521 kfree(slot);
522 slot = next;
523 }
524
525 pci_dev_put(bridge->pci_dev);
526 list_del(&bridge->list);
527 kfree(bridge);
528}
529
530static acpi_status
531cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
532{
533 struct acpiphp_bridge *bridge;
534
535 if (!(bridge = acpiphp_handle_to_bridge(handle)))
536 return AE_OK;
537 cleanup_bridge(bridge);
538 return AE_OK;
539}
675 540
676static void remove_bridge(acpi_handle handle) 541static void remove_bridge(acpi_handle handle)
677{ 542{
678 /* No-op for now .. */ 543 struct acpiphp_bridge *bridge;
544
545 bridge = acpiphp_handle_to_bridge(handle);
546 if (bridge) {
547 cleanup_bridge(bridge);
548 } else {
549 /* clean-up p2p bridges under this host bridge */
550 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
551 (u32)1, cleanup_p2p_bridge, NULL, NULL);
552 }
553}
554
555static struct pci_dev * get_apic_pci_info(acpi_handle handle)
556{
557 struct acpi_pci_id id;
558 struct pci_bus *bus;
559 struct pci_dev *dev;
560
561 if (ACPI_FAILURE(acpi_get_pci_id(handle, &id)))
562 return NULL;
563
564 bus = pci_find_bus(id.segment, id.bus);
565 if (!bus)
566 return NULL;
567
568 dev = pci_get_slot(bus, PCI_DEVFN(id.device, id.function));
569 if (!dev)
570 return NULL;
571
572 if ((dev->class != PCI_CLASS_SYSTEM_PIC_IOAPIC) &&
573 (dev->class != PCI_CLASS_SYSTEM_PIC_IOXAPIC))
574 {
575 pci_dev_put(dev);
576 return NULL;
577 }
578
579 return dev;
580}
581
582static int get_gsi_base(acpi_handle handle, u32 *gsi_base)
583{
584 acpi_status status;
585 int result = -1;
586 unsigned long gsb;
587 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
588 union acpi_object *obj;
589 void *table;
590
591 status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb);
592 if (ACPI_SUCCESS(status)) {
593 *gsi_base = (u32)gsb;
594 return 0;
595 }
596
597 status = acpi_evaluate_object(handle, "_MAT", NULL, &buffer);
598 if (ACPI_FAILURE(status) || !buffer.length || !buffer.pointer)
599 return -1;
600
601 obj = buffer.pointer;
602 if (obj->type != ACPI_TYPE_BUFFER)
603 goto out;
604
605 table = obj->buffer.pointer;
606 switch (((acpi_table_entry_header *)table)->type) {
607 case ACPI_MADT_IOSAPIC:
608 *gsi_base = ((struct acpi_table_iosapic *)table)->global_irq_base;
609 result = 0;
610 break;
611 case ACPI_MADT_IOAPIC:
612 *gsi_base = ((struct acpi_table_ioapic *)table)->global_irq_base;
613 result = 0;
614 break;
615 default:
616 break;
617 }
618 out:
619 acpi_os_free(buffer.pointer);
620 return result;
621}
622
623static acpi_status
624ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv)
625{
626 acpi_status status;
627 unsigned long sta;
628 acpi_handle tmp;
629 struct pci_dev *pdev;
630 u32 gsi_base;
631 u64 phys_addr;
632
633 /* Evaluate _STA if present */
634 status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
635 if (ACPI_SUCCESS(status) && sta != ACPI_STA_ALL)
636 return AE_CTRL_DEPTH;
637
638 /* Scan only PCI bus scope */
639 status = acpi_get_handle(handle, "_HID", &tmp);
640 if (ACPI_SUCCESS(status))
641 return AE_CTRL_DEPTH;
642
643 if (get_gsi_base(handle, &gsi_base))
644 return AE_OK;
645
646 pdev = get_apic_pci_info(handle);
647 if (!pdev)
648 return AE_OK;
649
650 if (pci_enable_device(pdev)) {
651 pci_dev_put(pdev);
652 return AE_OK;
653 }
654
655 pci_set_master(pdev);
656
657 if (pci_request_region(pdev, 0, "I/O APIC(acpiphp)")) {
658 pci_disable_device(pdev);
659 pci_dev_put(pdev);
660 return AE_OK;
661 }
662
663 phys_addr = pci_resource_start(pdev, 0);
664 if (acpi_register_ioapic(handle, phys_addr, gsi_base)) {
665 pci_release_region(pdev, 0);
666 pci_disable_device(pdev);
667 pci_dev_put(pdev);
668 return AE_OK;
669 }
670
671 return AE_OK;
679} 672}
680 673
674static int acpiphp_configure_ioapics(acpi_handle handle)
675{
676 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
677 ACPI_UINT32_MAX, ioapic_add, NULL, NULL);
678 return 0;
679}
681 680
682static int power_on_slot(struct acpiphp_slot *slot) 681static int power_on_slot(struct acpiphp_slot *slot)
683{ 682{
@@ -719,8 +718,6 @@ static int power_off_slot(struct acpiphp_slot *slot)
719 acpi_status status; 718 acpi_status status;
720 struct acpiphp_func *func; 719 struct acpiphp_func *func;
721 struct list_head *l; 720 struct list_head *l;
722 struct acpi_object_list arg_list;
723 union acpi_object arg;
724 721
725 int retval = 0; 722 int retval = 0;
726 723
@@ -731,7 +728,7 @@ static int power_off_slot(struct acpiphp_slot *slot)
731 list_for_each (l, &slot->funcs) { 728 list_for_each (l, &slot->funcs) {
732 func = list_entry(l, struct acpiphp_func, sibling); 729 func = list_entry(l, struct acpiphp_func, sibling);
733 730
734 if (func->pci_dev && (func->flags & FUNC_HAS_PS3)) { 731 if (func->flags & FUNC_HAS_PS3) {
735 status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL); 732 status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL);
736 if (ACPI_FAILURE(status)) { 733 if (ACPI_FAILURE(status)) {
737 warn("%s: _PS3 failed\n", __FUNCTION__); 734 warn("%s: _PS3 failed\n", __FUNCTION__);
@@ -742,27 +739,6 @@ static int power_off_slot(struct acpiphp_slot *slot)
742 } 739 }
743 } 740 }
744 741
745 list_for_each (l, &slot->funcs) {
746 func = list_entry(l, struct acpiphp_func, sibling);
747
748 /* We don't want to call _EJ0 on non-existing functions. */
749 if (func->pci_dev && (func->flags & FUNC_HAS_EJ0)) {
750 /* _EJ0 method take one argument */
751 arg_list.count = 1;
752 arg_list.pointer = &arg;
753 arg.type = ACPI_TYPE_INTEGER;
754 arg.integer.value = 1;
755
756 status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL);
757 if (ACPI_FAILURE(status)) {
758 warn("%s: _EJ0 failed\n", __FUNCTION__);
759 retval = -1;
760 goto err_exit;
761 } else
762 break;
763 }
764 }
765
766 /* TBD: evaluate _STA to check if the slot is disabled */ 742 /* TBD: evaluate _STA to check if the slot is disabled */
767 743
768 slot->flags &= (~SLOT_POWEREDON); 744 slot->flags &= (~SLOT_POWEREDON);
@@ -782,70 +758,56 @@ static int power_off_slot(struct acpiphp_slot *slot)
782 */ 758 */
783static int enable_device(struct acpiphp_slot *slot) 759static int enable_device(struct acpiphp_slot *slot)
784{ 760{
785 u8 bus;
786 struct pci_dev *dev; 761 struct pci_dev *dev;
787 struct pci_bus *child; 762 struct pci_bus *bus = slot->bridge->pci_bus;
788 struct list_head *l; 763 struct list_head *l;
789 struct acpiphp_func *func; 764 struct acpiphp_func *func;
790 int retval = 0; 765 int retval = 0;
791 int num; 766 int num, max, pass;
792 767
793 if (slot->flags & SLOT_ENABLED) 768 if (slot->flags & SLOT_ENABLED)
794 goto err_exit; 769 goto err_exit;
795 770
796 /* sanity check: dev should be NULL when hot-plugged in */ 771 /* sanity check: dev should be NULL when hot-plugged in */
797 dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0)); 772 dev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0));
798 if (dev) { 773 if (dev) {
799 /* This case shouldn't happen */ 774 /* This case shouldn't happen */
800 err("pci_dev structure already exists.\n"); 775 err("pci_dev structure already exists.\n");
776 pci_dev_put(dev);
801 retval = -1; 777 retval = -1;
802 goto err_exit; 778 goto err_exit;
803 } 779 }
804 780
805 /* allocate resources to device */ 781 num = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0));
806 retval = acpiphp_configure_slot(slot); 782 if (num == 0) {
807 if (retval)
808 goto err_exit;
809
810 /* returned `dev' is the *first function* only! */
811 num = pci_scan_slot(slot->bridge->pci_bus, PCI_DEVFN(slot->device, 0));
812 if (num)
813 pci_bus_add_devices(slot->bridge->pci_bus);
814 dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0));
815
816 if (!dev) {
817 err("No new device found\n"); 783 err("No new device found\n");
818 retval = -1; 784 retval = -1;
819 goto err_exit; 785 goto err_exit;
820 } 786 }
821 787
822 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { 788 max = bus->secondary;
823 pci_read_config_byte(dev, PCI_SECONDARY_BUS, &bus); 789 for (pass = 0; pass < 2; pass++) {
824 child = (struct pci_bus*) pci_add_new_bus(dev->bus, dev, bus); 790 list_for_each_entry(dev, &bus->devices, bus_list) {
825 pci_do_scan_bus(child); 791 if (PCI_SLOT(dev->devfn) != slot->device)
792 continue;
793 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
794 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
795 max = pci_scan_bridge(bus, dev, max, pass);
796 }
826 } 797 }
827 798
799 pci_bus_assign_resources(bus);
800 pci_bus_add_devices(bus);
801
828 /* associate pci_dev to our representation */ 802 /* associate pci_dev to our representation */
829 list_for_each (l, &slot->funcs) { 803 list_for_each (l, &slot->funcs) {
830 func = list_entry(l, struct acpiphp_func, sibling); 804 func = list_entry(l, struct acpiphp_func, sibling);
831 805 func->pci_dev = pci_get_slot(bus, PCI_DEVFN(slot->device,
832 func->pci_dev = pci_find_slot(slot->bridge->bus,
833 PCI_DEVFN(slot->device,
834 func->function)); 806 func->function));
835 if (!func->pci_dev)
836 continue;
837
838 /* configure device */
839 retval = acpiphp_configure_function(func);
840 if (retval)
841 goto err_exit;
842 } 807 }
843 808
844 slot->flags |= SLOT_ENABLED; 809 slot->flags |= SLOT_ENABLED;
845 810
846 dbg("Available resources:\n");
847 acpiphp_dump_resource(slot->bridge);
848
849 err_exit: 811 err_exit:
850 return retval; 812 return retval;
851} 813}
@@ -866,9 +828,12 @@ static int disable_device(struct acpiphp_slot *slot)
866 828
867 list_for_each (l, &slot->funcs) { 829 list_for_each (l, &slot->funcs) {
868 func = list_entry(l, struct acpiphp_func, sibling); 830 func = list_entry(l, struct acpiphp_func, sibling);
831 if (!func->pci_dev)
832 continue;
869 833
870 if (func->pci_dev) 834 pci_remove_bus_device(func->pci_dev);
871 acpiphp_unconfigure_function(func); 835 pci_dev_put(func->pci_dev);
836 func->pci_dev = NULL;
872 } 837 }
873 838
874 slot->flags &= (~SLOT_ENABLED); 839 slot->flags &= (~SLOT_ENABLED);
@@ -920,6 +885,39 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot)
920} 885}
921 886
922/** 887/**
888 * acpiphp_eject_slot - physically eject the slot
889 */
890static int acpiphp_eject_slot(struct acpiphp_slot *slot)
891{
892 acpi_status status;
893 struct acpiphp_func *func;
894 struct list_head *l;
895 struct acpi_object_list arg_list;
896 union acpi_object arg;
897
898 list_for_each (l, &slot->funcs) {
899 func = list_entry(l, struct acpiphp_func, sibling);
900
901 /* We don't want to call _EJ0 on non-existing functions. */
902 if ((func->flags & FUNC_HAS_EJ0)) {
903 /* _EJ0 method take one argument */
904 arg_list.count = 1;
905 arg_list.pointer = &arg;
906 arg.type = ACPI_TYPE_INTEGER;
907 arg.integer.value = 1;
908
909 status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL);
910 if (ACPI_FAILURE(status)) {
911 warn("%s: _EJ0 failed\n", __FUNCTION__);
912 return -1;
913 } else
914 break;
915 }
916 }
917 return 0;
918}
919
920/**
923 * acpiphp_check_bridge - re-enumerate devices 921 * acpiphp_check_bridge - re-enumerate devices
924 * 922 *
925 * Iterate over all slots under this bridge and make sure that if a 923 * Iterate over all slots under this bridge and make sure that if a
@@ -942,6 +940,8 @@ static int acpiphp_check_bridge(struct acpiphp_bridge *bridge)
942 if (retval) { 940 if (retval) {
943 err("Error occurred in disabling\n"); 941 err("Error occurred in disabling\n");
944 goto err_exit; 942 goto err_exit;
943 } else {
944 acpiphp_eject_slot(slot);
945 } 945 }
946 disabled++; 946 disabled++;
947 } else { 947 } else {
@@ -962,6 +962,144 @@ static int acpiphp_check_bridge(struct acpiphp_bridge *bridge)
962 return retval; 962 return retval;
963} 963}
964 964
965static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge)
966{
967 u16 pci_cmd, pci_bctl;
968 struct pci_dev *cdev;
969
970 /* Program hpp values for this device */
971 if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
972 (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
973 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
974 return;
975 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
976 bridge->hpp.cache_line_size);
977 pci_write_config_byte(dev, PCI_LATENCY_TIMER,
978 bridge->hpp.latency_timer);
979 pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
980 if (bridge->hpp.enable_SERR)
981 pci_cmd |= PCI_COMMAND_SERR;
982 else
983 pci_cmd &= ~PCI_COMMAND_SERR;
984 if (bridge->hpp.enable_PERR)
985 pci_cmd |= PCI_COMMAND_PARITY;
986 else
987 pci_cmd &= ~PCI_COMMAND_PARITY;
988 pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
989
990 /* Program bridge control value and child devices */
991 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
992 pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
993 bridge->hpp.latency_timer);
994 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
995 if (bridge->hpp.enable_SERR)
996 pci_bctl |= PCI_BRIDGE_CTL_SERR;
997 else
998 pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
999 if (bridge->hpp.enable_PERR)
1000 pci_bctl |= PCI_BRIDGE_CTL_PARITY;
1001 else
1002 pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
1003 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
1004 if (dev->subordinate) {
1005 list_for_each_entry(cdev, &dev->subordinate->devices,
1006 bus_list)
1007 program_hpp(cdev, bridge);
1008 }
1009 }
1010}
1011
1012static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus)
1013{
1014 struct acpiphp_bridge bridge;
1015 struct pci_dev *dev;
1016
1017 memset(&bridge, 0, sizeof(bridge));
1018 bridge.handle = handle;
1019 decode_hpp(&bridge);
1020 list_for_each_entry(dev, &bus->devices, bus_list)
1021 program_hpp(dev, &bridge);
1022
1023}
1024
1025/*
1026 * Remove devices for which we could not assign resources, call
1027 * arch specific code to fix-up the bus
1028 */
1029static void acpiphp_sanitize_bus(struct pci_bus *bus)
1030{
1031 struct pci_dev *dev;
1032 int i;
1033 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM;
1034
1035 list_for_each_entry(dev, &bus->devices, bus_list) {
1036 for (i=0; i<PCI_BRIDGE_RESOURCES; i++) {
1037 struct resource *res = &dev->resource[i];
1038 if ((res->flags & type_mask) && !res->start &&
1039 res->end) {
1040 /* Could not assign a required resources
1041 * for this device, remove it */
1042 pci_remove_bus_device(dev);
1043 break;
1044 }
1045 }
1046 }
1047}
1048
1049/* Program resources in newly inserted bridge */
1050static int acpiphp_configure_bridge (acpi_handle handle)
1051{
1052 struct acpi_pci_id pci_id;
1053 struct pci_bus *bus;
1054
1055 if (ACPI_FAILURE(acpi_get_pci_id(handle, &pci_id))) {
1056 err("cannot get PCI domain and bus number for bridge\n");
1057 return -EINVAL;
1058 }
1059 bus = pci_find_bus(pci_id.segment, pci_id.bus);
1060 if (!bus) {
1061 err("cannot find bus %d:%d\n",
1062 pci_id.segment, pci_id.bus);
1063 return -EINVAL;
1064 }
1065
1066 pci_bus_size_bridges(bus);
1067 pci_bus_assign_resources(bus);
1068 acpiphp_sanitize_bus(bus);
1069 acpiphp_set_hpp_values(handle, bus);
1070 pci_enable_bridges(bus);
1071 acpiphp_configure_ioapics(handle);
1072 return 0;
1073}
1074
1075static void handle_bridge_insertion(acpi_handle handle, u32 type)
1076{
1077 struct acpi_device *device, *pdevice;
1078 acpi_handle phandle;
1079
1080 if ((type != ACPI_NOTIFY_BUS_CHECK) &&
1081 (type != ACPI_NOTIFY_DEVICE_CHECK)) {
1082 err("unexpected notification type %d\n", type);
1083 return;
1084 }
1085
1086 acpi_get_parent(handle, &phandle);
1087 if (acpi_bus_get_device(phandle, &pdevice)) {
1088 dbg("no parent device, assuming NULL\n");
1089 pdevice = NULL;
1090 }
1091 if (acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE)) {
1092 err("cannot add bridge to acpi list\n");
1093 return;
1094 }
1095 if (!acpiphp_configure_bridge(handle) &&
1096 !acpi_bus_start(device))
1097 add_bridge(handle);
1098 else
1099 err("cannot configure and start bridge\n");
1100
1101}
1102
965/* 1103/*
966 * ACPI event handlers 1104 * ACPI event handlers
967 */ 1105 */
@@ -982,8 +1120,19 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont
982 char objname[64]; 1120 char objname[64];
983 struct acpi_buffer buffer = { .length = sizeof(objname), 1121 struct acpi_buffer buffer = { .length = sizeof(objname),
984 .pointer = objname }; 1122 .pointer = objname };
1123 struct acpi_device *device;
985 1124
986 bridge = (struct acpiphp_bridge *)context; 1125 if (acpi_bus_get_device(handle, &device)) {
1126 /* This bridge must have just been physically inserted */
1127 handle_bridge_insertion(handle, type);
1128 return;
1129 }
1130
1131 bridge = acpiphp_handle_to_bridge(handle);
1132 if (!bridge) {
1133 err("cannot get bridge info\n");
1134 return;
1135 }
987 1136
988 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); 1137 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
989 1138
@@ -1031,7 +1180,6 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont
1031 } 1180 }
1032} 1181}
1033 1182
1034
1035/** 1183/**
1036 * handle_hotplug_event_func - handle ACPI event on functions (i.e. slots) 1184 * handle_hotplug_event_func - handle ACPI event on functions (i.e. slots)
1037 * 1185 *
@@ -1074,7 +1222,8 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *contex
1074 case ACPI_NOTIFY_EJECT_REQUEST: 1222 case ACPI_NOTIFY_EJECT_REQUEST:
1075 /* request device eject */ 1223 /* request device eject */
1076 dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname); 1224 dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname);
1077 acpiphp_disable_slot(func->slot); 1225 if (!(acpiphp_disable_slot(func->slot)))
1226 acpiphp_eject_slot(func->slot);
1078 break; 1227 break;
1079 1228
1080 default: 1229 default:
@@ -1083,6 +1232,47 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *contex
1083 } 1232 }
1084} 1233}
1085 1234
1235static int is_root_bridge(acpi_handle handle)
1236{
1237 acpi_status status;
1238 struct acpi_device_info *info;
1239 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
1240 int i;
1241
1242 status = acpi_get_object_info(handle, &buffer);
1243 if (ACPI_SUCCESS(status)) {
1244 info = buffer.pointer;
1245 if ((info->valid & ACPI_VALID_HID) &&
1246 !strcmp(PCI_ROOT_HID_STRING,
1247 info->hardware_id.value)) {
1248 acpi_os_free(buffer.pointer);
1249 return 1;
1250 }
1251 if (info->valid & ACPI_VALID_CID) {
1252 for (i=0; i < info->compatibility_id.count; i++) {
1253 if (!strcmp(PCI_ROOT_HID_STRING,
1254 info->compatibility_id.id[i].value)) {
1255 acpi_os_free(buffer.pointer);
1256 return 1;
1257 }
1258 }
1259 }
1260 }
1261 return 0;
1262}
1263
1264static acpi_status
1265find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
1266{
1267 int *count = (int *)context;
1268
1269 if (is_root_bridge(handle)) {
1270 acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
1271 handle_hotplug_event_bridge, NULL);
1272 (*count)++;
1273 }
1274 return AE_OK ;
1275}
1086 1276
1087static struct acpi_pci_driver acpi_pci_hp_driver = { 1277static struct acpi_pci_driver acpi_pci_hp_driver = {
1088 .add = add_bridge, 1278 .add = add_bridge,
@@ -1095,15 +1285,15 @@ static struct acpi_pci_driver acpi_pci_hp_driver = {
1095 */ 1285 */
1096int __init acpiphp_glue_init(void) 1286int __init acpiphp_glue_init(void)
1097{ 1287{
1098 int num; 1288 int num = 0;
1099
1100 if (list_empty(&pci_root_buses))
1101 return -1;
1102 1289
1103 num = acpi_pci_register_driver(&acpi_pci_hp_driver); 1290 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
1291 ACPI_UINT32_MAX, find_root_bridges, &num, NULL);
1104 1292
1105 if (num <= 0) 1293 if (num <= 0)
1106 return -1; 1294 return -1;
1295 else
1296 acpi_pci_register_driver(&acpi_pci_hp_driver);
1107 1297
1108 return 0; 1298 return 0;
1109} 1299}
@@ -1116,46 +1306,6 @@ int __init acpiphp_glue_init(void)
1116 */ 1306 */
1117void __exit acpiphp_glue_exit(void) 1307void __exit acpiphp_glue_exit(void)
1118{ 1308{
1119 struct list_head *l1, *l2, *n1, *n2;
1120 struct acpiphp_bridge *bridge;
1121 struct acpiphp_slot *slot, *next;
1122 struct acpiphp_func *func;
1123 acpi_status status;
1124
1125 list_for_each_safe (l1, n1, &bridge_list) {
1126 bridge = (struct acpiphp_bridge *)l1;
1127 slot = bridge->slots;
1128 while (slot) {
1129 next = slot->next;
1130 list_for_each_safe (l2, n2, &slot->funcs) {
1131 func = list_entry(l2, struct acpiphp_func, sibling);
1132 acpiphp_free_resource(&func->io_head);
1133 acpiphp_free_resource(&func->mem_head);
1134 acpiphp_free_resource(&func->p_mem_head);
1135 acpiphp_free_resource(&func->bus_head);
1136 status = acpi_remove_notify_handler(func->handle,
1137 ACPI_SYSTEM_NOTIFY,
1138 handle_hotplug_event_func);
1139 if (ACPI_FAILURE(status))
1140 err("failed to remove notify handler\n");
1141 kfree(func);
1142 }
1143 kfree(slot);
1144 slot = next;
1145 }
1146 status = acpi_remove_notify_handler(bridge->handle, ACPI_SYSTEM_NOTIFY,
1147 handle_hotplug_event_bridge);
1148 if (ACPI_FAILURE(status))
1149 err("failed to remove notify handler\n");
1150
1151 acpiphp_free_resource(&bridge->io_head);
1152 acpiphp_free_resource(&bridge->mem_head);
1153 acpiphp_free_resource(&bridge->p_mem_head);
1154 acpiphp_free_resource(&bridge->bus_head);
1155
1156 kfree(bridge);
1157 }
1158
1159 acpi_pci_unregister_driver(&acpi_pci_hp_driver); 1309 acpi_pci_unregister_driver(&acpi_pci_hp_driver);
1160} 1310}
1161 1311
@@ -1173,11 +1323,14 @@ int __init acpiphp_get_num_slots(void)
1173 1323
1174 list_for_each (node, &bridge_list) { 1324 list_for_each (node, &bridge_list) {
1175 bridge = (struct acpiphp_bridge *)node; 1325 bridge = (struct acpiphp_bridge *)node;
1176 dbg("Bus%d %dslot(s)\n", bridge->bus, bridge->nr_slots); 1326 dbg("Bus %04x:%02x has %d slot%s\n",
1327 pci_domain_nr(bridge->pci_bus),
1328 bridge->pci_bus->number, bridge->nr_slots,
1329 bridge->nr_slots == 1 ? "" : "s");
1177 num_slots += bridge->nr_slots; 1330 num_slots += bridge->nr_slots;
1178 } 1331 }
1179 1332
1180 dbg("Total %dslots\n", num_slots); 1333 dbg("Total %d slots\n", num_slots);
1181 return num_slots; 1334 return num_slots;
1182} 1335}
1183 1336
@@ -1254,7 +1407,6 @@ int acpiphp_enable_slot(struct acpiphp_slot *slot)
1254 return retval; 1407 return retval;
1255} 1408}
1256 1409
1257
1258/** 1410/**
1259 * acpiphp_disable_slot - power off slot 1411 * acpiphp_disable_slot - power off slot
1260 */ 1412 */
@@ -1274,13 +1426,6 @@ int acpiphp_disable_slot(struct acpiphp_slot *slot)
1274 if (retval) 1426 if (retval)
1275 goto err_exit; 1427 goto err_exit;
1276 1428
1277 acpiphp_resource_sort_and_combine(&slot->bridge->io_head);
1278 acpiphp_resource_sort_and_combine(&slot->bridge->mem_head);
1279 acpiphp_resource_sort_and_combine(&slot->bridge->p_mem_head);
1280 acpiphp_resource_sort_and_combine(&slot->bridge->bus_head);
1281 dbg("Available resources:\n");
1282 acpiphp_dump_resource(slot->bridge);
1283
1284 err_exit: 1429 err_exit:
1285 up(&slot->crit_sect); 1430 up(&slot->crit_sect);
1286 return retval; 1431 return retval;
@@ -1293,11 +1438,7 @@ int acpiphp_disable_slot(struct acpiphp_slot *slot)
1293 */ 1438 */
1294u8 acpiphp_get_power_status(struct acpiphp_slot *slot) 1439u8 acpiphp_get_power_status(struct acpiphp_slot *slot)
1295{ 1440{
1296 unsigned int sta; 1441 return (slot->flags & SLOT_POWEREDON);
1297
1298 sta = get_slot_status(slot);
1299
1300 return (sta & ACPI_STA_ENABLED) ? 1 : 0;
1301} 1442}
1302 1443
1303 1444
@@ -1335,9 +1476,10 @@ u8 acpiphp_get_adapter_status(struct acpiphp_slot *slot)
1335u32 acpiphp_get_address(struct acpiphp_slot *slot) 1476u32 acpiphp_get_address(struct acpiphp_slot *slot)
1336{ 1477{
1337 u32 address; 1478 u32 address;
1479 struct pci_bus *pci_bus = slot->bridge->pci_bus;
1338 1480
1339 address = ((slot->bridge->seg) << 16) | 1481 address = (pci_domain_nr(pci_bus) << 16) |
1340 ((slot->bridge->bus) << 8) | 1482 (pci_bus->number << 8) |
1341 slot->device; 1483 slot->device;
1342 1484
1343 return address; 1485 return address;
diff --git a/drivers/pci/hotplug/acpiphp_pci.c b/drivers/pci/hotplug/acpiphp_pci.c
deleted file mode 100644
index 54d97c9d1dff..000000000000
--- a/drivers/pci/hotplug/acpiphp_pci.c
+++ /dev/null
@@ -1,449 +0,0 @@
1/*
2 * ACPI PCI HotPlug PCI configuration space management
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001,2002 IBM Corp.
7 * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
8 * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
9 * Copyright (C) 2002 NEC Corporation
10 *
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or (at
16 * your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
21 * NON INFRINGEMENT. See the GNU General Public License for more
22 * details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 * Send feedback to <t-kochi@bq.jp.nec.com>
29 *
30 */
31
32#include <linux/init.h>
33#include <linux/module.h>
34
35#include <linux/kernel.h>
36#include <linux/pci.h>
37#include <linux/acpi.h>
38#include "../pci.h"
39#include "pci_hotplug.h"
40#include "acpiphp.h"
41
42#define MY_NAME "acpiphp_pci"
43
44
45/* allocate mem/pmem/io resource to a new function */
46static int init_config_space (struct acpiphp_func *func)
47{
48 u32 bar, len;
49 u32 address[] = {
50 PCI_BASE_ADDRESS_0,
51 PCI_BASE_ADDRESS_1,
52 PCI_BASE_ADDRESS_2,
53 PCI_BASE_ADDRESS_3,
54 PCI_BASE_ADDRESS_4,
55 PCI_BASE_ADDRESS_5,
56 0
57 };
58 int count;
59 struct acpiphp_bridge *bridge;
60 struct pci_resource *res;
61 struct pci_bus *pbus;
62 int bus, device, function;
63 unsigned int devfn;
64 u16 tmp;
65
66 bridge = func->slot->bridge;
67 pbus = bridge->pci_bus;
68 bus = bridge->bus;
69 device = func->slot->device;
70 function = func->function;
71 devfn = PCI_DEVFN(device, function);
72
73 for (count = 0; address[count]; count++) { /* for 6 BARs */
74 pci_bus_write_config_dword(pbus, devfn,
75 address[count], 0xFFFFFFFF);
76 pci_bus_read_config_dword(pbus, devfn, address[count], &bar);
77
78 if (!bar) /* This BAR is not implemented */
79 continue;
80
81 dbg("Device %02x.%02x BAR %d wants %x\n", device, function, count, bar);
82
83 if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
84 /* This is IO */
85
86 len = bar & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
87 len = len & ~(len - 1);
88
89 dbg("len in IO %x, BAR %d\n", len, count);
90
91 spin_lock(&bridge->res_lock);
92 res = acpiphp_get_io_resource(&bridge->io_head, len);
93 spin_unlock(&bridge->res_lock);
94
95 if (!res) {
96 err("cannot allocate requested io for %02x:%02x.%d len %x\n",
97 bus, device, function, len);
98 return -1;
99 }
100 pci_bus_write_config_dword(pbus, devfn,
101 address[count],
102 (u32)res->base);
103 res->next = func->io_head;
104 func->io_head = res;
105
106 } else {
107 /* This is Memory */
108 if (bar & PCI_BASE_ADDRESS_MEM_PREFETCH) {
109 /* pfmem */
110
111 len = bar & 0xFFFFFFF0;
112 len = ~len + 1;
113
114 dbg("len in PFMEM %x, BAR %d\n", len, count);
115
116 spin_lock(&bridge->res_lock);
117 res = acpiphp_get_resource(&bridge->p_mem_head, len);
118 spin_unlock(&bridge->res_lock);
119
120 if (!res) {
121 err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n",
122 bus, device, function, len);
123 return -1;
124 }
125
126 pci_bus_write_config_dword(pbus, devfn,
127 address[count],
128 (u32)res->base);
129
130 if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) { /* takes up another dword */
131 dbg("inside the pfmem 64 case, count %d\n", count);
132 count += 1;
133 pci_bus_write_config_dword(pbus, devfn,
134 address[count],
135 (u32)(res->base >> 32));
136 }
137
138 res->next = func->p_mem_head;
139 func->p_mem_head = res;
140
141 } else {
142 /* regular memory */
143
144 len = bar & 0xFFFFFFF0;
145 len = ~len + 1;
146
147 dbg("len in MEM %x, BAR %d\n", len, count);
148
149 spin_lock(&bridge->res_lock);
150 res = acpiphp_get_resource(&bridge->mem_head, len);
151 spin_unlock(&bridge->res_lock);
152
153 if (!res) {
154 err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n",
155 bus, device, function, len);
156 return -1;
157 }
158
159 pci_bus_write_config_dword(pbus, devfn,
160 address[count],
161 (u32)res->base);
162
163 if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) {
164 /* takes up another dword */
165 dbg("inside mem 64 case, reg. mem, count %d\n", count);
166 count += 1;
167 pci_bus_write_config_dword(pbus, devfn,
168 address[count],
169 (u32)(res->base >> 32));
170 }
171
172 res->next = func->mem_head;
173 func->mem_head = res;
174
175 }
176 }
177 }
178
179 /* disable expansion rom */
180 pci_bus_write_config_dword(pbus, devfn, PCI_ROM_ADDRESS, 0x00000000);
181
182 /* set PCI parameters from _HPP */
183 pci_bus_write_config_byte(pbus, devfn, PCI_CACHE_LINE_SIZE,
184 bridge->hpp.cache_line_size);
185 pci_bus_write_config_byte(pbus, devfn, PCI_LATENCY_TIMER,
186 bridge->hpp.latency_timer);
187
188 pci_bus_read_config_word(pbus, devfn, PCI_COMMAND, &tmp);
189 if (bridge->hpp.enable_SERR)
190 tmp |= PCI_COMMAND_SERR;
191 if (bridge->hpp.enable_PERR)
192 tmp |= PCI_COMMAND_PARITY;
193 pci_bus_write_config_word(pbus, devfn, PCI_COMMAND, tmp);
194
195 return 0;
196}
197
198/* detect_used_resource - subtract resource under dev from bridge */
199static int detect_used_resource (struct acpiphp_bridge *bridge, struct pci_dev *dev)
200{
201 int count;
202
203 dbg("Device %s\n", pci_name(dev));
204
205 for (count = 0; count < DEVICE_COUNT_RESOURCE; count++) {
206 struct pci_resource *res;
207 struct pci_resource **head;
208 unsigned long base = dev->resource[count].start;
209 unsigned long len = dev->resource[count].end - base + 1;
210 unsigned long flags = dev->resource[count].flags;
211
212 if (!flags)
213 continue;
214
215 dbg("BAR[%d] 0x%lx - 0x%lx (0x%lx)\n", count, base,
216 base + len - 1, flags);
217
218 if (flags & IORESOURCE_IO) {
219 head = &bridge->io_head;
220 } else if (flags & IORESOURCE_PREFETCH) {
221 head = &bridge->p_mem_head;
222 } else {
223 head = &bridge->mem_head;
224 }
225
226 spin_lock(&bridge->res_lock);
227 res = acpiphp_get_resource_with_base(head, base, len);
228 spin_unlock(&bridge->res_lock);
229 if (res)
230 kfree(res);
231 }
232
233 return 0;
234}
235
236
237/**
238 * acpiphp_detect_pci_resource - detect resources under bridge
239 * @bridge: detect all resources already used under this bridge
240 *
241 * collect all resources already allocated for all devices under a bridge.
242 */
243int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge)
244{
245 struct list_head *l;
246 struct pci_dev *dev;
247
248 list_for_each (l, &bridge->pci_bus->devices) {
249 dev = pci_dev_b(l);
250 detect_used_resource(bridge, dev);
251 }
252
253 return 0;
254}
255
256
257/**
258 * acpiphp_init_slot_resource - gather resource usage information of a slot
259 * @slot: ACPI slot object to be checked, should have valid pci_dev member
260 *
261 * TBD: PCI-to-PCI bridge case
262 * use pci_dev->resource[]
263 */
264int acpiphp_init_func_resource (struct acpiphp_func *func)
265{
266 u64 base;
267 u32 bar, len;
268 u32 address[] = {
269 PCI_BASE_ADDRESS_0,
270 PCI_BASE_ADDRESS_1,
271 PCI_BASE_ADDRESS_2,
272 PCI_BASE_ADDRESS_3,
273 PCI_BASE_ADDRESS_4,
274 PCI_BASE_ADDRESS_5,
275 0
276 };
277 int count;
278 struct pci_resource *res;
279 struct pci_dev *dev;
280
281 dev = func->pci_dev;
282 dbg("Hot-pluggable device %s\n", pci_name(dev));
283
284 for (count = 0; address[count]; count++) { /* for 6 BARs */
285 pci_read_config_dword(dev, address[count], &bar);
286
287 if (!bar) /* This BAR is not implemented */
288 continue;
289
290 pci_write_config_dword(dev, address[count], 0xFFFFFFFF);
291 pci_read_config_dword(dev, address[count], &len);
292
293 if (len & PCI_BASE_ADDRESS_SPACE_IO) {
294 /* This is IO */
295 base = bar & 0xFFFFFFFC;
296 len = len & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
297 len = len & ~(len - 1);
298
299 dbg("BAR[%d] %08x - %08x (IO)\n", count, (u32)base, (u32)base + len - 1);
300
301 res = acpiphp_make_resource(base, len);
302 if (!res)
303 goto no_memory;
304
305 res->next = func->io_head;
306 func->io_head = res;
307
308 } else {
309 /* This is Memory */
310 base = bar & 0xFFFFFFF0;
311 if (len & PCI_BASE_ADDRESS_MEM_PREFETCH) {
312 /* pfmem */
313
314 len &= 0xFFFFFFF0;
315 len = ~len + 1;
316
317 if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) { /* takes up another dword */
318 dbg("prefetch mem 64\n");
319 count += 1;
320 }
321 dbg("BAR[%d] %08x - %08x (PMEM)\n", count, (u32)base, (u32)base + len - 1);
322 res = acpiphp_make_resource(base, len);
323 if (!res)
324 goto no_memory;
325
326 res->next = func->p_mem_head;
327 func->p_mem_head = res;
328
329 } else {
330 /* regular memory */
331
332 len &= 0xFFFFFFF0;
333 len = ~len + 1;
334
335 if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) {
336 /* takes up another dword */
337 dbg("mem 64\n");
338 count += 1;
339 }
340 dbg("BAR[%d] %08x - %08x (MEM)\n", count, (u32)base, (u32)base + len - 1);
341 res = acpiphp_make_resource(base, len);
342 if (!res)
343 goto no_memory;
344
345 res->next = func->mem_head;
346 func->mem_head = res;
347
348 }
349 }
350
351 pci_write_config_dword(dev, address[count], bar);
352 }
353#if 1
354 acpiphp_dump_func_resource(func);
355#endif
356
357 return 0;
358
359 no_memory:
360 err("out of memory\n");
361 acpiphp_free_resource(&func->io_head);
362 acpiphp_free_resource(&func->mem_head);
363 acpiphp_free_resource(&func->p_mem_head);
364
365 return -1;
366}
367
368
369/**
370 * acpiphp_configure_slot - allocate PCI resources
371 * @slot: slot to be configured
372 *
373 * initializes a PCI functions on a device inserted
374 * into the slot
375 *
376 */
377int acpiphp_configure_slot (struct acpiphp_slot *slot)
378{
379 struct acpiphp_func *func;
380 struct list_head *l;
381 u8 hdr;
382 u32 dvid;
383 int retval = 0;
384 int is_multi = 0;
385
386 pci_bus_read_config_byte(slot->bridge->pci_bus,
387 PCI_DEVFN(slot->device, 0),
388 PCI_HEADER_TYPE, &hdr);
389
390 if (hdr & 0x80)
391 is_multi = 1;
392
393 list_for_each (l, &slot->funcs) {
394 func = list_entry(l, struct acpiphp_func, sibling);
395 if (is_multi || func->function == 0) {
396 pci_bus_read_config_dword(slot->bridge->pci_bus,
397 PCI_DEVFN(slot->device,
398 func->function),
399 PCI_VENDOR_ID, &dvid);
400 if (dvid != 0xffffffff) {
401 retval = init_config_space(func);
402 if (retval)
403 break;
404 }
405 }
406 }
407
408 return retval;
409}
410
411/**
412 * acpiphp_configure_function - configure PCI function
413 * @func: function to be configured
414 *
415 * initializes a PCI functions on a device inserted
416 * into the slot
417 *
418 */
419int acpiphp_configure_function (struct acpiphp_func *func)
420{
421 /* all handled by the pci core now */
422 return 0;
423}
424
425/**
426 * acpiphp_unconfigure_function - unconfigure PCI function
427 * @func: function to be unconfigured
428 *
429 */
430void acpiphp_unconfigure_function (struct acpiphp_func *func)
431{
432 struct acpiphp_bridge *bridge;
433
434 /* if pci_dev is NULL, ignore it */
435 if (!func->pci_dev)
436 return;
437
438 pci_remove_bus_device(func->pci_dev);
439
440 /* free all resources */
441 bridge = func->slot->bridge;
442
443 spin_lock(&bridge->res_lock);
444 acpiphp_move_resource(&func->io_head, &bridge->io_head);
445 acpiphp_move_resource(&func->mem_head, &bridge->mem_head);
446 acpiphp_move_resource(&func->p_mem_head, &bridge->p_mem_head);
447 acpiphp_move_resource(&func->bus_head, &bridge->bus_head);
448 spin_unlock(&bridge->res_lock);
449}
diff --git a/drivers/pci/hotplug/acpiphp_res.c b/drivers/pci/hotplug/acpiphp_res.c
deleted file mode 100644
index f54b1fa7b75a..000000000000
--- a/drivers/pci/hotplug/acpiphp_res.c
+++ /dev/null
@@ -1,700 +0,0 @@
1/*
2 * ACPI PCI HotPlug Utility functions
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
8 * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
9 * Copyright (C) 2002 NEC Corporation
10 *
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or (at
16 * your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
21 * NON INFRINGEMENT. See the GNU General Public License for more
22 * details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 * Send feedback to <gregkh@us.ibm.com>, <t-kochi@bq.jp.nec.com>
29 *
30 */
31
32#include <linux/init.h>
33#include <linux/module.h>
34
35#include <linux/kernel.h>
36#include <linux/types.h>
37#include <linux/proc_fs.h>
38#include <linux/sysctl.h>
39#include <linux/pci.h>
40#include <linux/smp.h>
41#include <linux/smp_lock.h>
42
43#include <linux/string.h>
44#include <linux/mm.h>
45#include <linux/errno.h>
46#include <linux/ioport.h>
47#include <linux/slab.h>
48#include <linux/interrupt.h>
49#include <linux/timer.h>
50
51#include <linux/ioctl.h>
52#include <linux/fcntl.h>
53
54#include <linux/list.h>
55
56#include "pci_hotplug.h"
57#include "acpiphp.h"
58
59#define MY_NAME "acpiphp_res"
60
61
62/*
63 * sort_by_size - sort nodes by their length, smallest first
64 */
65static int sort_by_size(struct pci_resource **head)
66{
67 struct pci_resource *current_res;
68 struct pci_resource *next_res;
69 int out_of_order = 1;
70
71 if (!(*head))
72 return 1;
73
74 if (!((*head)->next))
75 return 0;
76
77 while (out_of_order) {
78 out_of_order = 0;
79
80 /* Special case for swapping list head */
81 if (((*head)->next) &&
82 ((*head)->length > (*head)->next->length)) {
83 out_of_order++;
84 current_res = *head;
85 *head = (*head)->next;
86 current_res->next = (*head)->next;
87 (*head)->next = current_res;
88 }
89
90 current_res = *head;
91
92 while (current_res->next && current_res->next->next) {
93 if (current_res->next->length > current_res->next->next->length) {
94 out_of_order++;
95 next_res = current_res->next;
96 current_res->next = current_res->next->next;
97 current_res = current_res->next;
98 next_res->next = current_res->next;
99 current_res->next = next_res;
100 } else
101 current_res = current_res->next;
102 }
103 } /* End of out_of_order loop */
104
105 return 0;
106}
107
108#if 0
109/*
110 * sort_by_max_size - sort nodes by their length, largest first
111 */
112static int sort_by_max_size(struct pci_resource **head)
113{
114 struct pci_resource *current_res;
115 struct pci_resource *next_res;
116 int out_of_order = 1;
117
118 if (!(*head))
119 return 1;
120
121 if (!((*head)->next))
122 return 0;
123
124 while (out_of_order) {
125 out_of_order = 0;
126
127 /* Special case for swapping list head */
128 if (((*head)->next) &&
129 ((*head)->length < (*head)->next->length)) {
130 out_of_order++;
131 current_res = *head;
132 *head = (*head)->next;
133 current_res->next = (*head)->next;
134 (*head)->next = current_res;
135 }
136
137 current_res = *head;
138
139 while (current_res->next && current_res->next->next) {
140 if (current_res->next->length < current_res->next->next->length) {
141 out_of_order++;
142 next_res = current_res->next;
143 current_res->next = current_res->next->next;
144 current_res = current_res->next;
145 next_res->next = current_res->next;
146 current_res->next = next_res;
147 } else
148 current_res = current_res->next;
149 }
150 } /* End of out_of_order loop */
151
152 return 0;
153}
154#endif
155
156/**
157 * get_io_resource - get resource for I/O ports
158 *
159 * this function sorts the resource list by size and then
160 * returns the first node of "size" length that is not in the
161 * ISA aliasing window. If it finds a node larger than "size"
162 * it will split it up.
163 *
164 * size must be a power of two.
165 *
166 * difference from get_resource is handling of ISA aliasing space.
167 *
168 */
169struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size)
170{
171 struct pci_resource *prevnode;
172 struct pci_resource *node;
173 struct pci_resource *split_node;
174 u64 temp_qword;
175
176 if (!(*head))
177 return NULL;
178
179 if (acpiphp_resource_sort_and_combine(head))
180 return NULL;
181
182 if (sort_by_size(head))
183 return NULL;
184
185 for (node = *head; node; node = node->next) {
186 if (node->length < size)
187 continue;
188
189 if (node->base & (size - 1)) {
190 /* this one isn't base aligned properly
191 so we'll make a new entry and split it up */
192 temp_qword = (node->base | (size-1)) + 1;
193
194 /* Short circuit if adjusted size is too small */
195 if ((node->length - (temp_qword - node->base)) < size)
196 continue;
197
198 split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
199
200 if (!split_node)
201 return NULL;
202
203 node->base = temp_qword;
204 node->length -= split_node->length;
205
206 /* Put it in the list */
207 split_node->next = node->next;
208 node->next = split_node;
209 } /* End of non-aligned base */
210
211 /* Don't need to check if too small since we already did */
212 if (node->length > size) {
213 /* this one is longer than we need
214 so we'll make a new entry and split it up */
215 split_node = acpiphp_make_resource(node->base + size, node->length - size);
216
217 if (!split_node)
218 return NULL;
219
220 node->length = size;
221
222 /* Put it in the list */
223 split_node->next = node->next;
224 node->next = split_node;
225 } /* End of too big on top end */
226
227 /* For IO make sure it's not in the ISA aliasing space */
228 if ((node->base & 0x300L) && !(node->base & 0xfffff000))
229 continue;
230
231 /* If we got here, then it is the right size
232 Now take it out of the list */
233 if (*head == node) {
234 *head = node->next;
235 } else {
236 prevnode = *head;
237 while (prevnode->next != node)
238 prevnode = prevnode->next;
239
240 prevnode->next = node->next;
241 }
242 node->next = NULL;
243 /* Stop looping */
244 break;
245 }
246
247 return node;
248}
249
250
251#if 0
252/**
253 * get_max_resource - get the largest resource
254 *
255 * Gets the largest node that is at least "size" big from the
256 * list pointed to by head. It aligns the node on top and bottom
257 * to "size" alignment before returning it.
258 */
259static struct pci_resource *acpiphp_get_max_resource (struct pci_resource **head, u32 size)
260{
261 struct pci_resource *max;
262 struct pci_resource *temp;
263 struct pci_resource *split_node;
264 u64 temp_qword;
265
266 if (!(*head))
267 return NULL;
268
269 if (acpiphp_resource_sort_and_combine(head))
270 return NULL;
271
272 if (sort_by_max_size(head))
273 return NULL;
274
275 for (max = *head;max; max = max->next) {
276
277 /* If not big enough we could probably just bail,
278 instead we'll continue to the next. */
279 if (max->length < size)
280 continue;
281
282 if (max->base & (size - 1)) {
283 /* this one isn't base aligned properly
284 so we'll make a new entry and split it up */
285 temp_qword = (max->base | (size-1)) + 1;
286
287 /* Short circuit if adjusted size is too small */
288 if ((max->length - (temp_qword - max->base)) < size)
289 continue;
290
291 split_node = acpiphp_make_resource(max->base, temp_qword - max->base);
292
293 if (!split_node)
294 return NULL;
295
296 max->base = temp_qword;
297 max->length -= split_node->length;
298
299 /* Put it next in the list */
300 split_node->next = max->next;
301 max->next = split_node;
302 }
303
304 if ((max->base + max->length) & (size - 1)) {
305 /* this one isn't end aligned properly at the top
306 so we'll make a new entry and split it up */
307 temp_qword = ((max->base + max->length) & ~(size - 1));
308
309 split_node = acpiphp_make_resource(temp_qword,
310 max->length + max->base - temp_qword);
311
312 if (!split_node)
313 return NULL;
314
315 max->length -= split_node->length;
316
317 /* Put it in the list */
318 split_node->next = max->next;
319 max->next = split_node;
320 }
321
322 /* Make sure it didn't shrink too much when we aligned it */
323 if (max->length < size)
324 continue;
325
326 /* Now take it out of the list */
327 temp = (struct pci_resource*) *head;
328 if (temp == max) {
329 *head = max->next;
330 } else {
331 while (temp && temp->next != max) {
332 temp = temp->next;
333 }
334
335 temp->next = max->next;
336 }
337
338 max->next = NULL;
339 return max;
340 }
341
342 /* If we get here, we couldn't find one */
343 return NULL;
344}
345#endif
346
347/**
348 * get_resource - get resource (mem, pfmem)
349 *
350 * this function sorts the resource list by size and then
351 * returns the first node of "size" length. If it finds a node
352 * larger than "size" it will split it up.
353 *
354 * size must be a power of two.
355 *
356 */
357struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size)
358{
359 struct pci_resource *prevnode;
360 struct pci_resource *node;
361 struct pci_resource *split_node;
362 u64 temp_qword;
363
364 if (!(*head))
365 return NULL;
366
367 if (acpiphp_resource_sort_and_combine(head))
368 return NULL;
369
370 if (sort_by_size(head))
371 return NULL;
372
373 for (node = *head; node; node = node->next) {
374 dbg("%s: req_size =%x node=%p, base=%x, length=%x\n",
375 __FUNCTION__, size, node, (u32)node->base, node->length);
376 if (node->length < size)
377 continue;
378
379 if (node->base & (size - 1)) {
380 dbg("%s: not aligned\n", __FUNCTION__);
381 /* this one isn't base aligned properly
382 so we'll make a new entry and split it up */
383 temp_qword = (node->base | (size-1)) + 1;
384
385 /* Short circuit if adjusted size is too small */
386 if ((node->length - (temp_qword - node->base)) < size)
387 continue;
388
389 split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
390
391 if (!split_node)
392 return NULL;
393
394 node->base = temp_qword;
395 node->length -= split_node->length;
396
397 /* Put it in the list */
398 split_node->next = node->next;
399 node->next = split_node;
400 } /* End of non-aligned base */
401
402 /* Don't need to check if too small since we already did */
403 if (node->length > size) {
404 dbg("%s: too big\n", __FUNCTION__);
405 /* this one is longer than we need
406 so we'll make a new entry and split it up */
407 split_node = acpiphp_make_resource(node->base + size, node->length - size);
408
409 if (!split_node)
410 return NULL;
411
412 node->length = size;
413
414 /* Put it in the list */
415 split_node->next = node->next;
416 node->next = split_node;
417 } /* End of too big on top end */
418
419 dbg("%s: got one!!!\n", __FUNCTION__);
420 /* If we got here, then it is the right size
421 Now take it out of the list */
422 if (*head == node) {
423 *head = node->next;
424 } else {
425 prevnode = *head;
426 while (prevnode->next != node)
427 prevnode = prevnode->next;
428
429 prevnode->next = node->next;
430 }
431 node->next = NULL;
432 /* Stop looping */
433 break;
434 }
435 return node;
436}
437
438/**
439 * get_resource_with_base - get resource with specific base address
440 *
441 * this function
442 * returns the first node of "size" length located at specified base address.
443 * If it finds a node larger than "size" it will split it up.
444 *
445 * size must be a power of two.
446 *
447 */
448struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size)
449{
450 struct pci_resource *prevnode;
451 struct pci_resource *node;
452 struct pci_resource *split_node;
453 u64 temp_qword;
454
455 if (!(*head))
456 return NULL;
457
458 if (acpiphp_resource_sort_and_combine(head))
459 return NULL;
460
461 for (node = *head; node; node = node->next) {
462 dbg(": 1st req_base=%x req_size =%x node=%p, base=%x, length=%x\n",
463 (u32)base, size, node, (u32)node->base, node->length);
464 if (node->base > base)
465 continue;
466
467 if ((node->base + node->length) < (base + size))
468 continue;
469
470 if (node->base < base) {
471 dbg(": split 1\n");
472 /* this one isn't base aligned properly
473 so we'll make a new entry and split it up */
474 temp_qword = base;
475
476 /* Short circuit if adjusted size is too small */
477 if ((node->length - (temp_qword - node->base)) < size)
478 continue;
479
480 split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
481
482 if (!split_node)
483 return NULL;
484
485 node->base = temp_qword;
486 node->length -= split_node->length;
487
488 /* Put it in the list */
489 split_node->next = node->next;
490 node->next = split_node;
491 }
492
493 dbg(": 2nd req_base=%x req_size =%x node=%p, base=%x, length=%x\n",
494 (u32)base, size, node, (u32)node->base, node->length);
495
496 /* Don't need to check if too small since we already did */
497 if (node->length > size) {
498 dbg(": split 2\n");
499 /* this one is longer than we need
500 so we'll make a new entry and split it up */
501 split_node = acpiphp_make_resource(node->base + size, node->length - size);
502
503 if (!split_node)
504 return NULL;
505
506 node->length = size;
507
508 /* Put it in the list */
509 split_node->next = node->next;
510 node->next = split_node;
511 } /* End of too big on top end */
512
513 dbg(": got one!!!\n");
514 /* If we got here, then it is the right size
515 Now take it out of the list */
516 if (*head == node) {
517 *head = node->next;
518 } else {
519 prevnode = *head;
520 while (prevnode->next != node)
521 prevnode = prevnode->next;
522
523 prevnode->next = node->next;
524 }
525 node->next = NULL;
526 /* Stop looping */
527 break;
528 }
529 return node;
530}
531
532
533/**
534 * acpiphp_resource_sort_and_combine
535 *
536 * Sorts all of the nodes in the list in ascending order by
537 * their base addresses. Also does garbage collection by
538 * combining adjacent nodes.
539 *
540 * returns 0 if success
541 */
542int acpiphp_resource_sort_and_combine (struct pci_resource **head)
543{
544 struct pci_resource *node1;
545 struct pci_resource *node2;
546 int out_of_order = 1;
547
548 if (!(*head))
549 return 1;
550
551 dbg("*head->next = %p\n",(*head)->next);
552
553 if (!(*head)->next)
554 return 0; /* only one item on the list, already sorted! */
555
556 dbg("*head->base = 0x%x\n",(u32)(*head)->base);
557 dbg("*head->next->base = 0x%x\n", (u32)(*head)->next->base);
558 while (out_of_order) {
559 out_of_order = 0;
560
561 /* Special case for swapping list head */
562 if (((*head)->next) &&
563 ((*head)->base > (*head)->next->base)) {
564 node1 = *head;
565 (*head) = (*head)->next;
566 node1->next = (*head)->next;
567 (*head)->next = node1;
568 out_of_order++;
569 }
570
571 node1 = (*head);
572
573 while (node1->next && node1->next->next) {
574 if (node1->next->base > node1->next->next->base) {
575 out_of_order++;
576 node2 = node1->next;
577 node1->next = node1->next->next;
578 node1 = node1->next;
579 node2->next = node1->next;
580 node1->next = node2;
581 } else
582 node1 = node1->next;
583 }
584 } /* End of out_of_order loop */
585
586 node1 = *head;
587
588 while (node1 && node1->next) {
589 if ((node1->base + node1->length) == node1->next->base) {
590 /* Combine */
591 dbg("8..\n");
592 node1->length += node1->next->length;
593 node2 = node1->next;
594 node1->next = node1->next->next;
595 kfree(node2);
596 } else
597 node1 = node1->next;
598 }
599
600 return 0;
601}
602
603
604/**
605 * acpiphp_make_resource - make resource structure
606 * @base: base address of a resource
607 * @length: length of a resource
608 */
609struct pci_resource *acpiphp_make_resource (u64 base, u32 length)
610{
611 struct pci_resource *res;
612
613 res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
614 if (res) {
615 memset(res, 0, sizeof(struct pci_resource));
616 res->base = base;
617 res->length = length;
618 }
619
620 return res;
621}
622
623
624/**
625 * acpiphp_move_resource - move linked resources from one to another
626 * @from: head of linked resource list
627 * @to: head of linked resource list
628 */
629void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to)
630{
631 struct pci_resource *tmp;
632
633 while (*from) {
634 tmp = (*from)->next;
635 (*from)->next = *to;
636 *to = *from;
637 *from = tmp;
638 }
639
640 /* *from = NULL is guaranteed */
641}
642
643
644/**
645 * acpiphp_free_resource - free all linked resources
646 * @res: head of linked resource list
647 */
648void acpiphp_free_resource (struct pci_resource **res)
649{
650 struct pci_resource *tmp;
651
652 while (*res) {
653 tmp = (*res)->next;
654 kfree(*res);
655 *res = tmp;
656 }
657
658 /* *res = NULL is guaranteed */
659}
660
661
662/* debug support functions; will go away sometime :) */
663static void dump_resource(struct pci_resource *head)
664{
665 struct pci_resource *p;
666 int cnt;
667
668 p = head;
669 cnt = 0;
670
671 while (p) {
672 dbg("[%02d] %08x - %08x\n",
673 cnt++, (u32)p->base, (u32)p->base + p->length - 1);
674 p = p->next;
675 }
676}
677
678void acpiphp_dump_resource(struct acpiphp_bridge *bridge)
679{
680 dbg("I/O resource:\n");
681 dump_resource(bridge->io_head);
682 dbg("MEM resource:\n");
683 dump_resource(bridge->mem_head);
684 dbg("PMEM resource:\n");
685 dump_resource(bridge->p_mem_head);
686 dbg("BUS resource:\n");
687 dump_resource(bridge->bus_head);
688}
689
690void acpiphp_dump_func_resource(struct acpiphp_func *func)
691{
692 dbg("I/O resource:\n");
693 dump_resource(func->io_head);
694 dbg("MEM resource:\n");
695 dump_resource(func->mem_head);
696 dbg("PMEM resource:\n");
697 dump_resource(func->p_mem_head);
698 dbg("BUS resource:\n");
699 dump_resource(func->bus_head);
700}
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
index afbccfa5217d..8c6d3987d461 100644
--- a/drivers/pci/hotplug/cpqphp_core.c
+++ b/drivers/pci/hotplug/cpqphp_core.c
@@ -60,6 +60,7 @@ static void __iomem *smbios_start;
60static void __iomem *cpqhp_rom_start; 60static void __iomem *cpqhp_rom_start;
61static int power_mode; 61static int power_mode;
62static int debug; 62static int debug;
63static int initialized;
63 64
64#define DRIVER_VERSION "0.9.8" 65#define DRIVER_VERSION "0.9.8"
65#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>" 66#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>"
@@ -1271,7 +1272,6 @@ static int one_time_init(void)
1271{ 1272{
1272 int loop; 1273 int loop;
1273 int retval = 0; 1274 int retval = 0;
1274 static int initialized = 0;
1275 1275
1276 if (initialized) 1276 if (initialized)
1277 return 0; 1277 return 0;
@@ -1441,7 +1441,8 @@ static void __exit unload_cpqphpd(void)
1441 } 1441 }
1442 1442
1443 // Stop the notification mechanism 1443 // Stop the notification mechanism
1444 cpqhp_event_stop_thread(); 1444 if (initialized)
1445 cpqhp_event_stop_thread();
1445 1446
1446 //unmap the rom address 1447 //unmap the rom address
1447 if (cpqhp_rom_start) 1448 if (cpqhp_rom_start)
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 30206ac43c44..b5ab9aa6ff7c 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -28,10 +28,10 @@ static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
28static kmem_cache_t* msi_cachep; 28static kmem_cache_t* msi_cachep;
29 29
30static int pci_msi_enable = 1; 30static int pci_msi_enable = 1;
31static int last_alloc_vector = 0; 31static int last_alloc_vector;
32static int nr_released_vectors = 0; 32static int nr_released_vectors;
33static int nr_reserved_vectors = NR_HP_RESERVED_VECTORS; 33static int nr_reserved_vectors = NR_HP_RESERVED_VECTORS;
34static int nr_msix_devices = 0; 34static int nr_msix_devices;
35 35
36#ifndef CONFIG_X86_IO_APIC 36#ifndef CONFIG_X86_IO_APIC
37int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1}; 37int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1};
@@ -170,44 +170,30 @@ static unsigned int startup_msi_irq_wo_maskbit(unsigned int vector)
170 return 0; /* never anything pending */ 170 return 0; /* never anything pending */
171} 171}
172 172
173static void release_msi(unsigned int vector); 173static unsigned int startup_msi_irq_w_maskbit(unsigned int vector)
174static void shutdown_msi_irq(unsigned int vector)
175{
176 release_msi(vector);
177}
178
179#define shutdown_msi_irq_wo_maskbit shutdown_msi_irq
180static void enable_msi_irq_wo_maskbit(unsigned int vector) {}
181static void disable_msi_irq_wo_maskbit(unsigned int vector) {}
182static void ack_msi_irq_wo_maskbit(unsigned int vector) {}
183static void end_msi_irq_wo_maskbit(unsigned int vector)
184{ 174{
185 move_msi(vector); 175 startup_msi_irq_wo_maskbit(vector);
186 ack_APIC_irq(); 176 unmask_MSI_irq(vector);
177 return 0; /* never anything pending */
187} 178}
188 179
189static unsigned int startup_msi_irq_w_maskbit(unsigned int vector) 180static void shutdown_msi_irq(unsigned int vector)
190{ 181{
191 struct msi_desc *entry; 182 struct msi_desc *entry;
192 unsigned long flags; 183 unsigned long flags;
193 184
194 spin_lock_irqsave(&msi_lock, flags); 185 spin_lock_irqsave(&msi_lock, flags);
195 entry = msi_desc[vector]; 186 entry = msi_desc[vector];
196 if (!entry || !entry->dev) { 187 if (entry && entry->dev)
197 spin_unlock_irqrestore(&msi_lock, flags); 188 entry->msi_attrib.state = 0; /* Mark it not active */
198 return 0;
199 }
200 entry->msi_attrib.state = 1; /* Mark it active */
201 spin_unlock_irqrestore(&msi_lock, flags); 189 spin_unlock_irqrestore(&msi_lock, flags);
202
203 unmask_MSI_irq(vector);
204 return 0; /* never anything pending */
205} 190}
206 191
207#define shutdown_msi_irq_w_maskbit shutdown_msi_irq 192static void end_msi_irq_wo_maskbit(unsigned int vector)
208#define enable_msi_irq_w_maskbit unmask_MSI_irq 193{
209#define disable_msi_irq_w_maskbit mask_MSI_irq 194 move_msi(vector);
210#define ack_msi_irq_w_maskbit mask_MSI_irq 195 ack_APIC_irq();
196}
211 197
212static void end_msi_irq_w_maskbit(unsigned int vector) 198static void end_msi_irq_w_maskbit(unsigned int vector)
213{ 199{
@@ -216,6 +202,10 @@ static void end_msi_irq_w_maskbit(unsigned int vector)
216 ack_APIC_irq(); 202 ack_APIC_irq();
217} 203}
218 204
205static void do_nothing(unsigned int vector)
206{
207}
208
219/* 209/*
220 * Interrupt Type for MSI-X PCI/PCI-X/PCI-Express Devices, 210 * Interrupt Type for MSI-X PCI/PCI-X/PCI-Express Devices,
221 * which implement the MSI-X Capability Structure. 211 * which implement the MSI-X Capability Structure.
@@ -223,10 +213,10 @@ static void end_msi_irq_w_maskbit(unsigned int vector)
223static struct hw_interrupt_type msix_irq_type = { 213static struct hw_interrupt_type msix_irq_type = {
224 .typename = "PCI-MSI-X", 214 .typename = "PCI-MSI-X",
225 .startup = startup_msi_irq_w_maskbit, 215 .startup = startup_msi_irq_w_maskbit,
226 .shutdown = shutdown_msi_irq_w_maskbit, 216 .shutdown = shutdown_msi_irq,
227 .enable = enable_msi_irq_w_maskbit, 217 .enable = unmask_MSI_irq,
228 .disable = disable_msi_irq_w_maskbit, 218 .disable = mask_MSI_irq,
229 .ack = ack_msi_irq_w_maskbit, 219 .ack = mask_MSI_irq,
230 .end = end_msi_irq_w_maskbit, 220 .end = end_msi_irq_w_maskbit,
231 .set_affinity = set_msi_irq_affinity 221 .set_affinity = set_msi_irq_affinity
232}; 222};
@@ -239,10 +229,10 @@ static struct hw_interrupt_type msix_irq_type = {
239static struct hw_interrupt_type msi_irq_w_maskbit_type = { 229static struct hw_interrupt_type msi_irq_w_maskbit_type = {
240 .typename = "PCI-MSI", 230 .typename = "PCI-MSI",
241 .startup = startup_msi_irq_w_maskbit, 231 .startup = startup_msi_irq_w_maskbit,
242 .shutdown = shutdown_msi_irq_w_maskbit, 232 .shutdown = shutdown_msi_irq,
243 .enable = enable_msi_irq_w_maskbit, 233 .enable = unmask_MSI_irq,
244 .disable = disable_msi_irq_w_maskbit, 234 .disable = mask_MSI_irq,
245 .ack = ack_msi_irq_w_maskbit, 235 .ack = mask_MSI_irq,
246 .end = end_msi_irq_w_maskbit, 236 .end = end_msi_irq_w_maskbit,
247 .set_affinity = set_msi_irq_affinity 237 .set_affinity = set_msi_irq_affinity
248}; 238};
@@ -255,10 +245,10 @@ static struct hw_interrupt_type msi_irq_w_maskbit_type = {
255static struct hw_interrupt_type msi_irq_wo_maskbit_type = { 245static struct hw_interrupt_type msi_irq_wo_maskbit_type = {
256 .typename = "PCI-MSI", 246 .typename = "PCI-MSI",
257 .startup = startup_msi_irq_wo_maskbit, 247 .startup = startup_msi_irq_wo_maskbit,
258 .shutdown = shutdown_msi_irq_wo_maskbit, 248 .shutdown = shutdown_msi_irq,
259 .enable = enable_msi_irq_wo_maskbit, 249 .enable = do_nothing,
260 .disable = disable_msi_irq_wo_maskbit, 250 .disable = do_nothing,
261 .ack = ack_msi_irq_wo_maskbit, 251 .ack = do_nothing,
262 .end = end_msi_irq_wo_maskbit, 252 .end = end_msi_irq_wo_maskbit,
263 .set_affinity = set_msi_irq_affinity 253 .set_affinity = set_msi_irq_affinity
264}; 254};
@@ -407,7 +397,7 @@ static struct msi_desc* alloc_msi_entry(void)
407{ 397{
408 struct msi_desc *entry; 398 struct msi_desc *entry;
409 399
410 entry = (struct msi_desc*) kmem_cache_alloc(msi_cachep, SLAB_KERNEL); 400 entry = kmem_cache_alloc(msi_cachep, SLAB_KERNEL);
411 if (!entry) 401 if (!entry)
412 return NULL; 402 return NULL;
413 403
@@ -796,18 +786,6 @@ void pci_disable_msi(struct pci_dev* dev)
796 } 786 }
797} 787}
798 788
799static void release_msi(unsigned int vector)
800{
801 struct msi_desc *entry;
802 unsigned long flags;
803
804 spin_lock_irqsave(&msi_lock, flags);
805 entry = msi_desc[vector];
806 if (entry && entry->dev)
807 entry->msi_attrib.state = 0; /* Mark it not active */
808 spin_unlock_irqrestore(&msi_lock, flags);
809}
810
811static int msi_free_vector(struct pci_dev* dev, int vector, int reassign) 789static int msi_free_vector(struct pci_dev* dev, int vector, int reassign)
812{ 790{
813 struct msi_desc *entry; 791 struct msi_desc *entry;
@@ -924,7 +902,7 @@ static int reroute_msix_table(int head, struct msix_entry *entries, int *nvec)
924/** 902/**
925 * pci_enable_msix - configure device's MSI-X capability structure 903 * pci_enable_msix - configure device's MSI-X capability structure
926 * @dev: pointer to the pci_dev data structure of MSI-X device function 904 * @dev: pointer to the pci_dev data structure of MSI-X device function
927 * @data: pointer to an array of MSI-X entries 905 * @entries: pointer to an array of MSI-X entries
928 * @nvec: number of MSI-X vectors requested for allocation by device driver 906 * @nvec: number of MSI-X vectors requested for allocation by device driver
929 * 907 *
930 * Setup the MSI-X capability structure of device function with the number 908 * Setup the MSI-X capability structure of device function with the number
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h
index bef21ae3cbd0..390f1851c0f1 100644
--- a/drivers/pci/msi.h
+++ b/drivers/pci/msi.h
@@ -41,11 +41,11 @@ static inline void move_msi(int vector) {}
41#define PCI_MSIX_FLAGS_BIRMASK (7 << 0) 41#define PCI_MSIX_FLAGS_BIRMASK (7 << 0)
42#define PCI_MSIX_FLAGS_BITMASK (1 << 0) 42#define PCI_MSIX_FLAGS_BITMASK (1 << 0)
43 43
44#define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET 0
45#define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET 4
46#define PCI_MSIX_ENTRY_DATA_OFFSET 8
47#define PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET 12
48#define PCI_MSIX_ENTRY_SIZE 16 44#define PCI_MSIX_ENTRY_SIZE 16
45#define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET 0
46#define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET 4
47#define PCI_MSIX_ENTRY_DATA_OFFSET 8
48#define PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET 12
49 49
50#define msi_control_reg(base) (base + PCI_MSI_FLAGS) 50#define msi_control_reg(base) (base + PCI_MSI_FLAGS)
51#define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO) 51#define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO)
@@ -64,7 +64,6 @@ static inline void move_msi(int vector) {}
64#define msi_enable(control, num) multi_msi_enable(control, num); \ 64#define msi_enable(control, num) multi_msi_enable(control, num); \
65 control |= PCI_MSI_FLAGS_ENABLE 65 control |= PCI_MSI_FLAGS_ENABLE
66 66
67#define msix_control_reg msi_control_reg
68#define msix_table_offset_reg(base) (base + 0x04) 67#define msix_table_offset_reg(base) (base + 0x04)
69#define msix_pba_offset_reg(base) (base + 0x08) 68#define msix_pba_offset_reg(base) (base + 0x08)
70#define msix_enable(control) control |= PCI_MSIX_FLAGS_ENABLE 69#define msix_enable(control) control |= PCI_MSIX_FLAGS_ENABLE
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index a15f94072a6f..cc9d65388e62 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -60,15 +60,18 @@ resource_show(struct device * dev, struct device_attribute *attr, char * buf)
60 char * str = buf; 60 char * str = buf;
61 int i; 61 int i;
62 int max = 7; 62 int max = 7;
63 u64 start, end;
63 64
64 if (pci_dev->subordinate) 65 if (pci_dev->subordinate)
65 max = DEVICE_COUNT_RESOURCE; 66 max = DEVICE_COUNT_RESOURCE;
66 67
67 for (i = 0; i < max; i++) { 68 for (i = 0; i < max; i++) {
68 str += sprintf(str,"0x%016lx 0x%016lx 0x%016lx\n", 69 struct resource *res = &pci_dev->resource[i];
69 pci_resource_start(pci_dev,i), 70 pci_resource_to_user(pci_dev, i, res, &start, &end);
70 pci_resource_end(pci_dev,i), 71 str += sprintf(str,"0x%016llx 0x%016llx 0x%016llx\n",
71 pci_resource_flags(pci_dev,i)); 72 (unsigned long long)start,
73 (unsigned long long)end,
74 (unsigned long long)res->flags);
72 } 75 }
73 return (str - buf); 76 return (str - buf);
74} 77}
@@ -313,8 +316,21 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
313 struct device, kobj)); 316 struct device, kobj));
314 struct resource *res = (struct resource *)attr->private; 317 struct resource *res = (struct resource *)attr->private;
315 enum pci_mmap_state mmap_type; 318 enum pci_mmap_state mmap_type;
319 u64 start, end;
320 int i;
316 321
317 vma->vm_pgoff += res->start >> PAGE_SHIFT; 322 for (i = 0; i < PCI_ROM_RESOURCE; i++)
323 if (res == &pdev->resource[i])
324 break;
325 if (i >= PCI_ROM_RESOURCE)
326 return -ENODEV;
327
328 /* pci_mmap_page_range() expects the same kind of entry as coming
329 * from /proc/bus/pci/ which is a "user visible" value. If this is
330 * different from the resource itself, arch will do necessary fixup.
331 */
332 pci_resource_to_user(pdev, i, res, &start, &end);
333 vma->vm_pgoff += start >> PAGE_SHIFT;
318 mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io; 334 mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;
319 335
320 return pci_mmap_page_range(pdev, vma, mmap_type, 0); 336 return pci_mmap_page_range(pdev, vma, mmap_type, 0);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index fd48b201eb53..6a0a82f0508b 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -374,8 +374,11 @@ struct pci_bus * __devinit pci_add_new_bus(struct pci_bus *parent, struct pci_de
374 struct pci_bus *child; 374 struct pci_bus *child;
375 375
376 child = pci_alloc_child_bus(parent, dev, busnr); 376 child = pci_alloc_child_bus(parent, dev, busnr);
377 if (child) 377 if (child) {
378 spin_lock(&pci_bus_lock);
378 list_add_tail(&child->node, &parent->children); 379 list_add_tail(&child->node, &parent->children);
380 spin_unlock(&pci_bus_lock);
381 }
379 return child; 382 return child;
380} 383}
381 384
@@ -411,7 +414,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
411{ 414{
412 struct pci_bus *child; 415 struct pci_bus *child;
413 int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); 416 int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS);
414 u32 buses; 417 u32 buses, i;
415 u16 bctl; 418 u16 bctl;
416 419
417 pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); 420 pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses);
@@ -447,7 +450,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
447 return max; 450 return max;
448 } 451 }
449 452
450 child = pci_alloc_child_bus(bus, dev, busnr); 453 child = pci_add_new_bus(bus, dev, busnr);
451 if (!child) 454 if (!child)
452 return max; 455 return max;
453 child->primary = buses & 0xFF; 456 child->primary = buses & 0xFF;
@@ -470,7 +473,11 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
470 /* Clear errors */ 473 /* Clear errors */
471 pci_write_config_word(dev, PCI_STATUS, 0xffff); 474 pci_write_config_word(dev, PCI_STATUS, 0xffff);
472 475
473 child = pci_alloc_child_bus(bus, dev, ++max); 476 /* Prevent assigning a bus number that already exists.
477 * This can happen when a bridge is hot-plugged */
478 if (pci_find_bus(pci_domain_nr(bus), max+1))
479 return max;
480 child = pci_add_new_bus(bus, dev, ++max);
474 buses = (buses & 0xff000000) 481 buses = (buses & 0xff000000)
475 | ((unsigned int)(child->primary) << 0) 482 | ((unsigned int)(child->primary) << 0)
476 | ((unsigned int)(child->secondary) << 8) 483 | ((unsigned int)(child->secondary) << 8)
@@ -501,7 +508,11 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
501 * as cards with a PCI-to-PCI bridge can be 508 * as cards with a PCI-to-PCI bridge can be
502 * inserted later. 509 * inserted later.
503 */ 510 */
504 max += CARDBUS_RESERVE_BUSNR; 511 for (i=0; i<CARDBUS_RESERVE_BUSNR; i++)
512 if (pci_find_bus(pci_domain_nr(bus),
513 max+i+1))
514 break;
515 max += i;
505 } 516 }
506 /* 517 /*
507 * Set the subordinate bus number to its real value. 518 * Set the subordinate bus number to its real value.
@@ -757,7 +768,9 @@ pci_scan_single_device(struct pci_bus *bus, int devfn)
757 * and the bus list for fixup functions, etc. 768 * and the bus list for fixup functions, etc.
758 */ 769 */
759 INIT_LIST_HEAD(&dev->global_list); 770 INIT_LIST_HEAD(&dev->global_list);
771 spin_lock(&pci_bus_lock);
760 list_add_tail(&dev->bus_list, &bus->devices); 772 list_add_tail(&dev->bus_list, &bus->devices);
773 spin_unlock(&pci_bus_lock);
761 774
762 return dev; 775 return dev;
763} 776}
@@ -878,7 +891,9 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus,
878 pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus); 891 pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus);
879 goto err_out; 892 goto err_out;
880 } 893 }
894 spin_lock(&pci_bus_lock);
881 list_add_tail(&b->node, &pci_root_buses); 895 list_add_tail(&b->node, &pci_root_buses);
896 spin_unlock(&pci_bus_lock);
882 897
883 memset(dev, 0, sizeof(*dev)); 898 memset(dev, 0, sizeof(*dev));
884 dev->parent = parent; 899 dev->parent = parent;
@@ -911,8 +926,6 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus,
911 926
912 b->subordinate = pci_scan_child_bus(b); 927 b->subordinate = pci_scan_child_bus(b);
913 928
914 pci_bus_add_devices(b);
915
916 return b; 929 return b;
917 930
918sys_create_link_err: 931sys_create_link_err:
@@ -922,7 +935,9 @@ class_dev_create_file_err:
922class_dev_reg_err: 935class_dev_reg_err:
923 device_unregister(dev); 936 device_unregister(dev);
924dev_reg_err: 937dev_reg_err:
938 spin_lock(&pci_bus_lock);
925 list_del(&b->node); 939 list_del(&b->node);
940 spin_unlock(&pci_bus_lock);
926err_out: 941err_out:
927 kfree(dev); 942 kfree(dev);
928 kfree(b); 943 kfree(b);
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index e68bbfb1e7c3..7988fc8df3fd 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -355,14 +355,20 @@ static int show_device(struct seq_file *m, void *v)
355 dev->device, 355 dev->device,
356 dev->irq); 356 dev->irq);
357 /* Here should be 7 and not PCI_NUM_RESOURCES as we need to preserve compatibility */ 357 /* Here should be 7 and not PCI_NUM_RESOURCES as we need to preserve compatibility */
358 for(i=0; i<7; i++) 358 for (i=0; i<7; i++) {
359 u64 start, end;
360 pci_resource_to_user(dev, i, &dev->resource[i], &start, &end);
359 seq_printf(m, LONG_FORMAT, 361 seq_printf(m, LONG_FORMAT,
360 dev->resource[i].start | 362 ((unsigned long)start) |
361 (dev->resource[i].flags & PCI_REGION_FLAG_MASK)); 363 (dev->resource[i].flags & PCI_REGION_FLAG_MASK));
362 for(i=0; i<7; i++) 364 }
365 for (i=0; i<7; i++) {
366 u64 start, end;
367 pci_resource_to_user(dev, i, &dev->resource[i], &start, &end);
363 seq_printf(m, LONG_FORMAT, 368 seq_printf(m, LONG_FORMAT,
364 dev->resource[i].start < dev->resource[i].end ? 369 dev->resource[i].start < dev->resource[i].end ?
365 dev->resource[i].end - dev->resource[i].start + 1 : 0); 370 (unsigned long)(end - start) + 1 : 0);
371 }
366 seq_putc(m, '\t'); 372 seq_putc(m, '\t');
367 if (drv) 373 if (drv)
368 seq_printf(m, "%s", drv->name); 374 seq_printf(m, "%s", drv->name);
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 96f077f9a659..27a294b6965d 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -18,17 +18,21 @@ static void pci_free_resources(struct pci_dev *dev)
18 18
19static void pci_destroy_dev(struct pci_dev *dev) 19static void pci_destroy_dev(struct pci_dev *dev)
20{ 20{
21 pci_proc_detach_device(dev); 21 if (!list_empty(&dev->global_list)) {
22 pci_remove_sysfs_dev_files(dev); 22 pci_proc_detach_device(dev);
23 device_unregister(&dev->dev); 23 pci_remove_sysfs_dev_files(dev);
24 device_unregister(&dev->dev);
25 spin_lock(&pci_bus_lock);
26 list_del(&dev->global_list);
27 dev->global_list.next = dev->global_list.prev = NULL;
28 spin_unlock(&pci_bus_lock);
29 }
24 30
25 /* Remove the device from the device lists, and prevent any further 31 /* Remove the device from the device lists, and prevent any further
26 * list accesses from this device */ 32 * list accesses from this device */
27 spin_lock(&pci_bus_lock); 33 spin_lock(&pci_bus_lock);
28 list_del(&dev->bus_list); 34 list_del(&dev->bus_list);
29 list_del(&dev->global_list);
30 dev->bus_list.next = dev->bus_list.prev = NULL; 35 dev->bus_list.next = dev->bus_list.prev = NULL;
31 dev->global_list.next = dev->global_list.prev = NULL;
32 spin_unlock(&pci_bus_lock); 36 spin_unlock(&pci_bus_lock);
33 37
34 pci_free_resources(dev); 38 pci_free_resources(dev);
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 1ba84be0b4c0..6b628de948af 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -72,7 +72,10 @@ pbus_assign_resources_sorted(struct pci_bus *bus)
72 for (list = head.next; list;) { 72 for (list = head.next; list;) {
73 res = list->res; 73 res = list->res;
74 idx = res - &list->dev->resource[0]; 74 idx = res - &list->dev->resource[0];
75 pci_assign_resource(list->dev, idx); 75 if (pci_assign_resource(list->dev, idx)) {
76 res->start = 0;
77 res->flags = 0;
78 }
76 tmp = list; 79 tmp = list;
77 list = list->next; 80 list = list->next;
78 kfree(tmp); 81 kfree(tmp);