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