aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/pciehprm_acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/hotplug/pciehprm_acpi.c')
-rw-r--r--drivers/pci/hotplug/pciehprm_acpi.c838
1 files changed, 71 insertions, 767 deletions
diff --git a/drivers/pci/hotplug/pciehprm_acpi.c b/drivers/pci/hotplug/pciehprm_acpi.c
index 078550ba2708..c823cfa42eec 100644
--- a/drivers/pci/hotplug/pciehprm_acpi.c
+++ b/drivers/pci/hotplug/pciehprm_acpi.c
@@ -39,70 +39,11 @@
39#include <acpi/acpi_bus.h> 39#include <acpi/acpi_bus.h>
40#include <acpi/actypes.h> 40#include <acpi/actypes.h>
41#include "pciehp.h" 41#include "pciehp.h"
42#include "pciehprm.h"
43
44#define PCI_MAX_BUS 0x100
45#define ACPI_STA_DEVICE_PRESENT 0x01
46 42
47#define METHOD_NAME__SUN "_SUN" 43#define METHOD_NAME__SUN "_SUN"
48#define METHOD_NAME__HPP "_HPP" 44#define METHOD_NAME__HPP "_HPP"
49#define METHOD_NAME_OSHP "OSHP" 45#define METHOD_NAME_OSHP "OSHP"
50 46
51/* Status code for running acpi method to gain native control */
52#define NC_NOT_RUN 0
53#define OSC_NOT_EXIST 1
54#define OSC_RUN_FAILED 2
55#define OSHP_NOT_EXIST 3
56#define OSHP_RUN_FAILED 4
57#define NC_RUN_SUCCESS 5
58
59#define PHP_RES_BUS 0xA0
60#define PHP_RES_IO 0xA1
61#define PHP_RES_MEM 0xA2
62#define PHP_RES_PMEM 0xA3
63
64#define BRIDGE_TYPE_P2P 0x00
65#define BRIDGE_TYPE_HOST 0x01
66
67/* this should go to drivers/acpi/include/ */
68struct acpi__hpp {
69 u8 cache_line_size;
70 u8 latency_timer;
71 u8 enable_serr;
72 u8 enable_perr;
73};
74
75struct acpi_php_slot {
76 struct acpi_php_slot *next;
77 struct acpi_bridge *bridge;
78 acpi_handle handle;
79 int seg;
80 int bus;
81 int dev;
82 int fun;
83 u32 sun;
84 void *slot_ops; /* _STA, _EJx, etc */
85 struct slot *slot;
86}; /* per func */
87
88struct acpi_bridge {
89 struct acpi_bridge *parent;
90 struct acpi_bridge *next;
91 struct acpi_bridge *child;
92 acpi_handle handle;
93 int seg;
94 int pbus; /* pdev->bus->number */
95 int pdevice; /* PCI_SLOT(pdev->devfn) */
96 int pfunction; /* PCI_DEVFN(pdev->devfn) */
97 int bus; /* pdev->subordinate->number */
98 struct acpi__hpp *_hpp;
99 struct acpi_php_slot *slots;
100 int scanned;
101 int type;
102};
103
104static struct acpi_bridge *acpi_bridges_head;
105
106static u8 * acpi_path_name( acpi_handle handle) 47static u8 * acpi_path_name( acpi_handle handle)
107{ 48{
108 acpi_status status; 49 acpi_status status;
@@ -118,85 +59,43 @@ static u8 * acpi_path_name( acpi_handle handle)
118 return path_name; 59 return path_name;
119} 60}
120 61
121static void acpi_get__hpp ( struct acpi_bridge *ab); 62static acpi_status
122static int acpi_run_oshp ( struct acpi_bridge *ab); 63acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
123static int osc_run_status = NC_NOT_RUN;
124static int oshp_run_status = NC_NOT_RUN;
125
126static int acpi_add_slot_to_php_slots(
127 struct acpi_bridge *ab,
128 int bus_num,
129 acpi_handle handle,
130 u32 adr,
131 u32 sun
132 )
133{
134 struct acpi_php_slot *aps;
135 static long samesun = -1;
136
137 aps = (struct acpi_php_slot *) kmalloc (sizeof(struct acpi_php_slot), GFP_KERNEL);
138 if (!aps) {
139 err ("acpi_pciehprm: alloc for aps fail\n");
140 return -1;
141 }
142 memset(aps, 0, sizeof(struct acpi_php_slot));
143
144 aps->handle = handle;
145 aps->bus = bus_num;
146 aps->dev = (adr >> 16) & 0xffff;
147 aps->fun = adr & 0xffff;
148 aps->sun = sun;
149
150 aps->next = ab->slots; /* cling to the bridge */
151 aps->bridge = ab;
152 ab->slots = aps;
153
154 ab->scanned += 1;
155 if (!ab->_hpp)
156 acpi_get__hpp(ab);
157
158 if (osc_run_status == OSC_NOT_EXIST)
159 oshp_run_status = acpi_run_oshp(ab);
160
161 if (sun != samesun) {
162 info("acpi_pciehprm: Slot sun(%x) at s:b:d:f=0x%02x:%02x:%02x:%02x\n",
163 aps->sun, ab->seg, aps->bus, aps->dev, aps->fun);
164 samesun = sun;
165 }
166 return 0;
167}
168
169static void acpi_get__hpp ( struct acpi_bridge *ab)
170{ 64{
171 acpi_status status; 65 acpi_status status;
172 u8 nui[4]; 66 u8 nui[4];
173 struct acpi_buffer ret_buf = { 0, NULL}; 67 struct acpi_buffer ret_buf = { 0, NULL};
174 union acpi_object *ext_obj, *package; 68 union acpi_object *ext_obj, *package;
175 u8 *path_name = acpi_path_name(ab->handle); 69 u8 *path_name = acpi_path_name(handle);
176 int i, len = 0; 70 int i, len = 0;
177 71
178 /* get _hpp */ 72 /* get _hpp */
179 status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf); 73 status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf);
180 switch (status) { 74 switch (status) {
181 case AE_BUFFER_OVERFLOW: 75 case AE_BUFFER_OVERFLOW:
182 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL); 76 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
183 if (!ret_buf.pointer) { 77 if (!ret_buf.pointer) {
184 err ("acpi_pciehprm:%s alloc for _HPP fail\n", path_name); 78 err ("%s:%s alloc for _HPP fail\n", __FUNCTION__,
185 return; 79 path_name);
80 return AE_NO_MEMORY;
186 } 81 }
187 status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf); 82 status = acpi_evaluate_object(handle, METHOD_NAME__HPP,
83 NULL, &ret_buf);
188 if (ACPI_SUCCESS(status)) 84 if (ACPI_SUCCESS(status))
189 break; 85 break;
190 default: 86 default:
191 if (ACPI_FAILURE(status)) { 87 if (ACPI_FAILURE(status)) {
192 err("acpi_pciehprm:%s _HPP fail=0x%x\n", path_name, status); 88 dbg("%s:%s _HPP fail=0x%x\n", __FUNCTION__,
193 return; 89 path_name, status);
90 return status;
194 } 91 }
195 } 92 }
196 93
197 ext_obj = (union acpi_object *) ret_buf.pointer; 94 ext_obj = (union acpi_object *) ret_buf.pointer;
198 if (ext_obj->type != ACPI_TYPE_PACKAGE) { 95 if (ext_obj->type != ACPI_TYPE_PACKAGE) {
199 err ("acpi_pciehprm:%s _HPP obj not a package\n", path_name); 96 err ("%s:%s _HPP obj not a package\n", __FUNCTION__,
97 path_name);
98 status = AE_ERROR;
200 goto free_and_return; 99 goto free_and_return;
201 } 100 }
202 101
@@ -209,689 +108,94 @@ static void acpi_get__hpp ( struct acpi_bridge *ab)
209 nui[i] = (u8)ext_obj->integer.value; 108 nui[i] = (u8)ext_obj->integer.value;
210 break; 109 break;
211 default: 110 default:
212 err ("acpi_pciehprm:%s _HPP obj type incorrect\n", path_name); 111 err ("%s:%s _HPP obj type incorrect\n", __FUNCTION__,
112 path_name);
113 status = AE_ERROR;
213 goto free_and_return; 114 goto free_and_return;
214 } 115 }
215 } 116 }
216 117
217 ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL); 118 hpp->cache_line_size = nui[0];
218 if (!ab->_hpp) { 119 hpp->latency_timer = nui[1];
219 err ("acpi_pciehprm:%s alloc for _HPP failed\n", path_name); 120 hpp->enable_serr = nui[2];
220 goto free_and_return; 121 hpp->enable_perr = nui[3];
221 }
222 memset(ab->_hpp, 0, sizeof(struct acpi__hpp));
223 122
224 ab->_hpp->cache_line_size = nui[0]; 123 dbg(" _HPP: cache_line_size=0x%x\n", hpp->cache_line_size);
225 ab->_hpp->latency_timer = nui[1]; 124 dbg(" _HPP: latency timer =0x%x\n", hpp->latency_timer);
226 ab->_hpp->enable_serr = nui[2]; 125 dbg(" _HPP: enable SERR =0x%x\n", hpp->enable_serr);
227 ab->_hpp->enable_perr = nui[3]; 126 dbg(" _HPP: enable PERR =0x%x\n", hpp->enable_perr);
228
229 dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
230 dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer);
231 dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr);
232 dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr);
233 127
234free_and_return: 128free_and_return:
235 kfree(ret_buf.pointer); 129 kfree(ret_buf.pointer);
130 return status;
236} 131}
237 132
238static int acpi_run_oshp ( struct acpi_bridge *ab) 133static acpi_status acpi_run_oshp(acpi_handle handle)
239{ 134{
240 acpi_status status; 135 acpi_status status;
241 u8 *path_name = acpi_path_name(ab->handle); 136 u8 *path_name = acpi_path_name(handle);
242 137
243 /* run OSHP */ 138 /* run OSHP */
244 status = acpi_evaluate_object(ab->handle, METHOD_NAME_OSHP, NULL, NULL); 139 status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL);
245 if (ACPI_FAILURE(status)) { 140 if (ACPI_FAILURE(status)) {
246 err("acpi_pciehprm:%s OSHP fails=0x%x\n", path_name, status); 141 err("%s:%s OSHP fails=0x%x\n", __FUNCTION__, path_name,
247 oshp_run_status = (status == AE_NOT_FOUND) ? OSHP_NOT_EXIST : OSHP_RUN_FAILED; 142 status);
248 } else { 143 } else {
249 oshp_run_status = NC_RUN_SUCCESS; 144 dbg("%s:%s OSHP passes\n", __FUNCTION__, path_name);
250 dbg("acpi_pciehprm:%s OSHP passes =0x%x\n", path_name, status);
251 dbg("acpi_pciehprm:%s oshp_run_status =0x%x\n", path_name, oshp_run_status);
252 }
253 return oshp_run_status;
254}
255
256/* find acpi_bridge downword from ab. */
257static struct acpi_bridge *
258find_acpi_bridge_by_bus(
259 struct acpi_bridge *ab,
260 int seg,
261 int bus /* pdev->subordinate->number */
262 )
263{
264 struct acpi_bridge *lab = NULL;
265
266 if (!ab)
267 return NULL;
268
269 if ((ab->bus == bus) && (ab->seg == seg))
270 return ab;
271
272 if (ab->child)
273 lab = find_acpi_bridge_by_bus(ab->child, seg, bus);
274
275 if (!lab)
276 if (ab->next)
277 lab = find_acpi_bridge_by_bus(ab->next, seg, bus);
278
279 return lab;
280}
281
282/*
283 * Build a device tree of ACPI PCI Bridges
284 */
285static void pciehprm_acpi_register_a_bridge (
286 struct acpi_bridge **head,
287 struct acpi_bridge *pab, /* parent bridge to which child bridge is added */
288 struct acpi_bridge *cab /* child bridge to add */
289 )
290{
291 struct acpi_bridge *lpab;
292 struct acpi_bridge *lcab;
293
294 lpab = find_acpi_bridge_by_bus(*head, pab->seg, pab->bus);
295 if (!lpab) {
296 if (!(pab->type & BRIDGE_TYPE_HOST))
297 warn("PCI parent bridge s:b(%x:%x) not in list.\n", pab->seg, pab->bus);
298 pab->next = *head;
299 *head = pab;
300 lpab = pab;
301 } 145 }
302 146 return status;
303 if ((cab->type & BRIDGE_TYPE_HOST) && (pab == cab))
304 return;
305
306 lcab = find_acpi_bridge_by_bus(*head, cab->seg, cab->bus);
307 if (lcab) {
308 if ((pab->bus != lcab->parent->bus) || (lcab->bus != cab->bus))
309 err("PCI child bridge s:b(%x:%x) in list with diff parent.\n", cab->seg, cab->bus);
310 return;
311 } else
312 lcab = cab;
313
314 lcab->parent = lpab;
315 lcab->next = lpab->child;
316 lpab->child = lcab;
317} 147}
318 148
319static acpi_status pciehprm_acpi_build_php_slots_callback( 149int get_hp_hw_control_from_firmware(struct pci_dev *dev)
320 acpi_handle handle,
321 u32 Level,
322 void *context,
323 void **retval
324 )
325{ 150{
326 ulong bus_num; 151 acpi_status status;
327 ulong seg_num; 152 /*
328 ulong sun, adr; 153 * Per PCI firmware specification, we should run the ACPI _OSC
329 ulong padr = 0; 154 * method to get control of hotplug hardware before using it
330 acpi_handle phandle = NULL; 155 */
331 struct acpi_bridge *pab = (struct acpi_bridge *)context; 156 /* Fixme: run _OSC for a specific host bridge, not all of them */
332 struct acpi_bridge *lab; 157 status = pci_osc_control_set(OSC_PCI_EXPRESS_NATIVE_HP_CONTROL);
333 acpi_status status; 158
334 u8 *path_name = acpi_path_name(handle); 159 /* Fixme: fail native hotplug if _OSC does not exist for root ports */
335 160 if (status == AE_NOT_FOUND) {
336 /* get _SUN */ 161 /*
337 status = acpi_evaluate_integer(handle, METHOD_NAME__SUN, NULL, &sun); 162 * Some older BIOS's don't support _OSC but support
338 switch(status) { 163 * OSHP to do the same thing
339 case AE_NOT_FOUND: 164 */
340 return AE_OK; 165 acpi_handle handle = DEVICE_ACPI_HANDLE(&(dev->dev));
341 default: 166 if (handle)
342 if (ACPI_FAILURE(status)) { 167 status = acpi_run_oshp(handle);
343 err("acpi_pciehprm:%s _SUN fail=0x%x\n", path_name, status);
344 return status;
345 }
346 }
347
348 /* get _ADR. _ADR must exist if _SUN exists */
349 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
350 if (ACPI_FAILURE(status)) {
351 err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
352 return status;
353 }
354
355 dbg("acpi_pciehprm:%s sun=0x%08x adr=0x%08x\n", path_name, (u32)sun, (u32)adr);
356
357 status = acpi_get_parent(handle, &phandle);
358 if (ACPI_FAILURE(status)) {
359 err("acpi_pciehprm:%s get_parent fail=0x%x\n", path_name, status);
360 return (status);
361 }
362
363 bus_num = pab->bus;
364 seg_num = pab->seg;
365
366 if (pab->bus == bus_num) {
367 lab = pab;
368 } else {
369 dbg("WARN: pab is not parent\n");
370 lab = find_acpi_bridge_by_bus(pab, seg_num, bus_num);
371 if (!lab) {
372 dbg("acpi_pciehprm: alloc new P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
373 lab = (struct acpi_bridge *)kmalloc(sizeof(struct acpi_bridge), GFP_KERNEL);
374 if (!lab) {
375 err("acpi_pciehprm: alloc for ab fail\n");
376 return AE_NO_MEMORY;
377 }
378 memset(lab, 0, sizeof(struct acpi_bridge));
379
380 lab->handle = phandle;
381 lab->pbus = pab->bus;
382 lab->pdevice = (int)(padr >> 16) & 0xffff;
383 lab->pfunction = (int)(padr & 0xffff);
384 lab->bus = (int)bus_num;
385 lab->scanned = 0;
386 lab->type = BRIDGE_TYPE_P2P;
387
388 pciehprm_acpi_register_a_bridge (&acpi_bridges_head, pab, lab);
389 } else
390 dbg("acpi_pciehprm: found P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
391 } 168 }
392
393 acpi_add_slot_to_php_slots(lab, (int)bus_num, handle, (u32)adr, (u32)sun);
394
395 return (status);
396}
397
398static int pciehprm_acpi_build_php_slots(
399 struct acpi_bridge *ab,
400 u32 depth
401 )
402{
403 acpi_status status;
404 u8 *path_name = acpi_path_name(ab->handle);
405
406 /* Walk down this pci bridge to get _SUNs if any behind P2P */
407 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
408 ab->handle,
409 depth,
410 pciehprm_acpi_build_php_slots_callback,
411 ab,
412 NULL );
413 if (ACPI_FAILURE(status)) { 169 if (ACPI_FAILURE(status)) {
414 dbg("acpi_pciehprm:%s walk for _SUN on pci bridge seg:bus(%x:%x) fail=0x%x\n", path_name, ab->seg, ab->bus, status); 170 err("Cannot get control of hotplug hardware\n");
415 return -1; 171 return -1;
416 } 172 }
417 173
174 dbg("Sucess getting control of hotplug hardware\n");
418 return 0; 175 return 0;
419} 176}
420 177
421static void build_a_bridge( 178void get_hp_params_from_firmware(struct pci_dev *dev,
422 struct acpi_bridge *pab, 179 struct hotplug_params *hpp)
423 struct acpi_bridge *ab
424 )
425{
426 u8 *path_name = acpi_path_name(ab->handle);
427
428 pciehprm_acpi_register_a_bridge (&acpi_bridges_head, pab, ab);
429
430 switch (ab->type) {
431 case BRIDGE_TYPE_HOST:
432 dbg("acpi_pciehprm: Registered PCI HOST Bridge(%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
433 ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
434 break;
435 case BRIDGE_TYPE_P2P:
436 dbg("acpi_pciehprm: Registered PCI P2P Bridge(%02x-%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
437 ab->pbus, ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
438 break;
439 };
440
441 /* build any immediate PHP slots under this pci bridge */
442 pciehprm_acpi_build_php_slots(ab, 1);
443}
444
445static struct acpi_bridge * add_p2p_bridge(
446 acpi_handle handle,
447 struct acpi_bridge *pab, /* parent */
448 ulong adr
449 )
450{
451 struct acpi_bridge *ab;
452 struct pci_dev *pdev;
453 ulong devnum, funcnum;
454 u8 *path_name = acpi_path_name(handle);
455
456 ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
457 if (!ab) {
458 err("acpi_pciehprm: alloc for ab fail\n");
459 return NULL;
460 }
461 memset(ab, 0, sizeof(struct acpi_bridge));
462
463 devnum = (adr >> 16) & 0xffff;
464 funcnum = adr & 0xffff;
465
466 pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
467 if (!pdev || !pdev->subordinate) {
468 err("acpi_pciehprm:%s is not a P2P Bridge\n", path_name);
469 kfree(ab);
470 return NULL;
471 }
472
473 ab->handle = handle;
474 ab->seg = pab->seg;
475 ab->pbus = pab->bus; /* or pdev->bus->number */
476 ab->pdevice = devnum; /* or PCI_SLOT(pdev->devfn) */
477 ab->pfunction = funcnum; /* or PCI_FUNC(pdev->devfn) */
478 ab->bus = pdev->subordinate->number;
479 ab->scanned = 0;
480 ab->type = BRIDGE_TYPE_P2P;
481
482 dbg("acpi_pciehprm: P2P(%x-%x) on pci=b:d:f(%x:%x:%x) acpi=b:d:f(%x:%x:%x) [%s]\n",
483 pab->bus, ab->bus, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
484 pab->bus, (u32)devnum, (u32)funcnum, path_name);
485
486 build_a_bridge(pab, ab);
487
488 return ab;
489}
490
491static acpi_status scan_p2p_bridge(
492 acpi_handle handle,
493 u32 Level,
494 void *context,
495 void **retval
496 )
497{
498 struct acpi_bridge *pab = (struct acpi_bridge *)context;
499 struct acpi_bridge *ab;
500 acpi_status status;
501 ulong adr = 0;
502 u8 *path_name = acpi_path_name(handle);
503 ulong devnum, funcnum;
504 struct pci_dev *pdev;
505
506 /* get device, function */
507 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
508 if (ACPI_FAILURE(status)) {
509 if (status != AE_NOT_FOUND)
510 err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
511 return AE_OK;
512 }
513
514 devnum = (adr >> 16) & 0xffff;
515 funcnum = adr & 0xffff;
516
517 pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
518 if (!pdev)
519 return AE_OK;
520 if (!pdev->subordinate)
521 return AE_OK;
522
523 ab = add_p2p_bridge(handle, pab, adr);
524 if (ab) {
525 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
526 handle,
527 (u32)1,
528 scan_p2p_bridge,
529 ab,
530 NULL);
531 if (ACPI_FAILURE(status))
532 dbg("acpi_pciehprm:%s find_p2p fail=0x%x\n", path_name, status);
533 }
534
535 return AE_OK;
536}
537
538static struct acpi_bridge * add_host_bridge(
539 acpi_handle handle,
540 ulong segnum,
541 ulong busnum
542 )
543{
544 ulong adr = 0;
545 acpi_status status;
546 struct acpi_bridge *ab;
547 u8 *path_name = acpi_path_name(handle);
548
549 /* get device, function: host br adr is always 0000 though. */
550 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
551 if (ACPI_FAILURE(status)) {
552 err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
553 return NULL;
554 }
555 dbg("acpi_pciehprm: ROOT PCI seg(0x%x)bus(0x%x)dev(0x%x)func(0x%x) [%s]\n", (u32)segnum,
556 (u32)busnum, (u32)(adr >> 16) & 0xffff, (u32)adr & 0xffff, path_name);
557
558 ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
559 if (!ab) {
560 err("acpi_pciehprm: alloc for ab fail\n");
561 return NULL;
562 }
563 memset(ab, 0, sizeof(struct acpi_bridge));
564
565 ab->handle = handle;
566 ab->seg = (int)segnum;
567 ab->bus = ab->pbus = (int)busnum;
568 ab->pdevice = (int)(adr >> 16) & 0xffff;
569 ab->pfunction = (int)(adr & 0xffff);
570 ab->scanned = 0;
571 ab->type = BRIDGE_TYPE_HOST;
572
573 status = pci_osc_control_set (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL);
574 if (ACPI_FAILURE(status)) {
575 err("%s: status %x\n", __FUNCTION__, status);
576 osc_run_status = (status == AE_NOT_FOUND) ? OSC_NOT_EXIST : OSC_RUN_FAILED;
577 } else {
578 osc_run_status = NC_RUN_SUCCESS;
579 }
580 dbg("%s: osc_run_status %x\n", __FUNCTION__, osc_run_status);
581
582 build_a_bridge(ab, ab);
583
584 return ab;
585}
586
587static acpi_status acpi_scan_from_root_pci_callback (
588 acpi_handle handle,
589 u32 Level,
590 void *context,
591 void **retval
592 )
593{
594 ulong segnum = 0;
595 ulong busnum = 0;
596 acpi_status status;
597 struct acpi_bridge *ab;
598 u8 *path_name = acpi_path_name(handle);
599
600 /* get bus number of this pci root bridge */
601 status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &segnum);
602 if (ACPI_FAILURE(status)) {
603 if (status != AE_NOT_FOUND) {
604 err("acpi_pciehprm:%s evaluate _SEG fail=0x%x\n", path_name, status);
605 return status;
606 }
607 segnum = 0;
608 }
609
610 /* get bus number of this pci root bridge */
611 status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL, &busnum);
612 if (ACPI_FAILURE(status)) {
613 err("acpi_pciehprm:%s evaluate _BBN fail=0x%x\n", path_name, status);
614 return (status);
615 }
616
617 ab = add_host_bridge(handle, segnum, busnum);
618 if (ab) {
619 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
620 handle,
621 1,
622 scan_p2p_bridge,
623 ab,
624 NULL);
625 if (ACPI_FAILURE(status))
626 dbg("acpi_pciehprm:%s find_p2p fail=0x%x\n", path_name, status);
627 }
628
629 return AE_OK;
630}
631
632static int pciehprm_acpi_scan_pci (void)
633{ 180{
634 acpi_status status; 181 acpi_status status = AE_NOT_FOUND;
182 struct pci_dev *pdev = dev;
635 183
636 /* 184 /*
637 * TBD: traverse LDM device tree with the help of 185 * _HPP settings apply to all child buses, until another _HPP is
638 * unified ACPI augmented for php device population. 186 * encountered. If we don't find an _HPP for the input pci dev,
187 * look for it in the parent device scope since that would apply to
188 * this pci dev. If we don't find any _HPP, use hardcoded defaults
639 */ 189 */
640 status = acpi_get_devices ( PCI_ROOT_HID_STRING, 190 while (pdev && (ACPI_FAILURE(status))) {
641 acpi_scan_from_root_pci_callback, 191 acpi_handle handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
642 NULL, 192 if (!handle)
643 NULL ); 193 break;
644 if (ACPI_FAILURE(status)) { 194 status = acpi_run_hpp(handle, hpp);
645 err("acpi_pciehprm:get_device PCI ROOT HID fail=0x%x\n", status); 195 if (!(pdev->bus->parent))
646 return -1; 196 break;
647 } 197 /* Check if a parent object supports _HPP */
648 198 pdev = pdev->bus->parent->self;
649 return 0;
650}
651
652int pciehprm_init(enum php_ctlr_type ctlr_type)
653{
654 int rc;
655
656 if (ctlr_type != PCI)
657 return -ENODEV;
658
659 dbg("pciehprm ACPI init <enter>\n");
660 acpi_bridges_head = NULL;
661
662 /* construct PCI bus:device tree of acpi_handles */
663 rc = pciehprm_acpi_scan_pci();
664 if (rc)
665 return rc;
666
667 if ((oshp_run_status != NC_RUN_SUCCESS) && (osc_run_status != NC_RUN_SUCCESS)) {
668 err("Fails to gain control of native hot-plug\n");
669 rc = -ENODEV;
670 }
671
672 dbg("pciehprm ACPI init %s\n", (rc)?"fail":"success");
673 return rc;
674}
675
676static void free_a_slot(struct acpi_php_slot *aps)
677{
678 dbg(" free a php func of slot(0x%02x) on PCI b:d:f=0x%02x:%02x:%02x\n", aps->sun, aps->bus, aps->dev, aps->fun);
679
680 kfree(aps);
681}
682
683static void free_a_bridge( struct acpi_bridge *ab)
684{
685 struct acpi_php_slot *aps, *next;
686
687 switch (ab->type) {
688 case BRIDGE_TYPE_HOST:
689 dbg("Free ACPI PCI HOST Bridge(%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
690 ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
691 break;
692 case BRIDGE_TYPE_P2P:
693 dbg("Free ACPI PCI P2P Bridge(%x-%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
694 ab->pbus, ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
695 break;
696 };
697
698 /* free slots first */
699 for (aps = ab->slots; aps; aps = next) {
700 next = aps->next;
701 free_a_slot(aps);
702 }
703
704 kfree(ab);
705}
706
707static void pciehprm_free_bridges ( struct acpi_bridge *ab)
708{
709 if (!ab)
710 return;
711
712 if (ab->child)
713 pciehprm_free_bridges (ab->child);
714
715 if (ab->next)
716 pciehprm_free_bridges (ab->next);
717
718 free_a_bridge(ab);
719}
720
721void pciehprm_cleanup(void)
722{
723 pciehprm_free_bridges (acpi_bridges_head);
724}
725
726static int get_number_of_slots (
727 struct acpi_bridge *ab,
728 int selfonly
729 )
730{
731 struct acpi_php_slot *aps;
732 int prev_slot = -1;
733 int slot_num = 0;
734
735 for ( aps = ab->slots; aps; aps = aps->next)
736 if (aps->dev != prev_slot) {
737 prev_slot = aps->dev;
738 slot_num++;
739 }
740
741 if (ab->child)
742 slot_num += get_number_of_slots (ab->child, 0);
743
744 if (selfonly)
745 return slot_num;
746
747 if (ab->next)
748 slot_num += get_number_of_slots (ab->next, 0);
749
750 return slot_num;
751}
752
753static struct acpi_php_slot * get_acpi_slot (
754 struct acpi_bridge *ab,
755 u32 sun
756 )
757{
758 struct acpi_php_slot *aps = NULL;
759
760 for ( aps = ab->slots; aps; aps = aps->next)
761 if (aps->sun == sun)
762 return aps;
763
764 if (!aps && ab->child) {
765 aps = (struct acpi_php_slot *)get_acpi_slot (ab->child, sun);
766 if (aps)
767 return aps;
768 }
769
770 if (!aps && ab->next) {
771 aps = (struct acpi_php_slot *)get_acpi_slot (ab->next, sun);
772 if (aps)
773 return aps;
774 }
775
776 return aps;
777
778}
779
780#if 0
781void * pciehprm_get_slot(struct slot *slot)
782{
783 struct acpi_bridge *ab = acpi_bridges_head;
784 struct acpi_php_slot *aps = get_acpi_slot (ab, slot->number);
785
786 aps->slot = slot;
787
788 dbg("Got acpi slot sun(%x): s:b:d:f(%x:%x:%x:%x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun);
789
790 return (void *)aps;
791}
792#endif
793
794int pciehprm_set_hpp(
795 struct controller *ctrl,
796 struct pci_func *func,
797 u8 card_type
798 )
799{
800 struct acpi_bridge *ab;
801 struct pci_bus lpci_bus, *pci_bus;
802 int rc = 0;
803 unsigned int devfn;
804 u8 cls= 0x08; /* default cache line size */
805 u8 lt = 0x40; /* default latency timer */
806 u8 ep = 0;
807 u8 es = 0;
808
809 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
810 pci_bus = &lpci_bus;
811 pci_bus->number = func->bus;
812 devfn = PCI_DEVFN(func->device, func->function);
813
814 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
815
816 if (ab) {
817 if (ab->_hpp) {
818 lt = (u8)ab->_hpp->latency_timer;
819 cls = (u8)ab->_hpp->cache_line_size;
820 ep = (u8)ab->_hpp->enable_perr;
821 es = (u8)ab->_hpp->enable_serr;
822 } else
823 dbg("_hpp: no _hpp for B/D/F=%#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
824 } else
825 dbg("_hpp: no acpi bridge for B/D/F = %#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
826
827
828 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
829 /* set subordinate Latency Timer */
830 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, lt);
831 } 199 }
832
833 /* set base Latency Timer */
834 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, lt);
835 dbg(" set latency timer =0x%02x: %x\n", lt, rc);
836
837 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, cls);
838 dbg(" set cache_line_size=0x%02x: %x\n", cls, rc);
839
840 return rc;
841} 200}
842 201
843void pciehprm_enable_card(
844 struct controller *ctrl,
845 struct pci_func *func,
846 u8 card_type)
847{
848 u16 command, cmd, bcommand, bcmd;
849 struct pci_bus lpci_bus, *pci_bus;
850 struct acpi_bridge *ab;
851 unsigned int devfn;
852 int rc;
853
854 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
855 pci_bus = &lpci_bus;
856 pci_bus->number = func->bus;
857 devfn = PCI_DEVFN(func->device, func->function);
858
859 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &cmd);
860
861 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
862 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcmd);
863 }
864
865 command = cmd | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
866 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
867 bcommand = bcmd | PCI_BRIDGE_CTL_NO_ISA;
868
869 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
870 if (ab) {
871 if (ab->_hpp) {
872 if (ab->_hpp->enable_perr) {
873 command |= PCI_COMMAND_PARITY;
874 bcommand |= PCI_BRIDGE_CTL_PARITY;
875 } else {
876 command &= ~PCI_COMMAND_PARITY;
877 bcommand &= ~PCI_BRIDGE_CTL_PARITY;
878 }
879 if (ab->_hpp->enable_serr) {
880 command |= PCI_COMMAND_SERR;
881 bcommand |= PCI_BRIDGE_CTL_SERR;
882 } else {
883 command &= ~PCI_COMMAND_SERR;
884 bcommand &= ~PCI_BRIDGE_CTL_SERR;
885 }
886 } else
887 dbg("no _hpp for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
888 } else
889 dbg("no acpi bridge for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
890
891 if (command != cmd) {
892 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
893 }
894 if ((card_type == PCI_HEADER_TYPE_BRIDGE) && (bcommand != bcmd)) {
895 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
896 }
897}