Merge git://git.skbuff.net/gitroot/yoshfuji/linux-2.6-git-rfc3542
[pandora-kernel.git] / drivers / pci / hotplug / pciehprm_acpi.c
1 /*
2  * PCIEHPRM ACPI: PHP Resource Manager for ACPI platform
3  *
4  * Copyright (C) 2003-2004 Intel Corporation
5  *
6  * All rights reserved.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or (at
11  * your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
16  * NON INFRINGEMENT.  See the GNU General Public License for more
17  * details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  *
23  * Send feedback to <kristen.c.accardi@intel.com>
24  *
25  */
26
27 #include <linux/config.h>
28 #include <linux/module.h>
29 #include <linux/kernel.h>
30 #include <linux/types.h>
31 #include <linux/pci.h>
32 #include <linux/init.h>
33 #include <linux/acpi.h>
34 #include <linux/efi.h>
35 #include <linux/pci-acpi.h>
36 #include <asm/uaccess.h>
37 #include <asm/system.h>
38 #ifdef  CONFIG_IA64
39 #include <asm/iosapic.h>
40 #endif
41 #include <acpi/acpi.h>
42 #include <acpi/acpi_bus.h>
43 #include <acpi/actypes.h>
44 #include "pciehp.h"
45 #include "pciehprm.h"
46
47 #define PCI_MAX_BUS             0x100
48 #define ACPI_STA_DEVICE_PRESENT 0x01
49
50 #define METHOD_NAME__SUN        "_SUN"
51 #define METHOD_NAME__HPP        "_HPP"
52 #define METHOD_NAME_OSHP        "OSHP"
53
54 /* Status code for running acpi method to gain native control */
55 #define NC_NOT_RUN      0
56 #define OSC_NOT_EXIST   1
57 #define OSC_RUN_FAILED  2
58 #define OSHP_NOT_EXIST  3
59 #define OSHP_RUN_FAILED 4
60 #define NC_RUN_SUCCESS  5
61
62 #define PHP_RES_BUS             0xA0
63 #define PHP_RES_IO              0xA1
64 #define PHP_RES_MEM             0xA2
65 #define PHP_RES_PMEM            0xA3
66
67 #define BRIDGE_TYPE_P2P         0x00
68 #define BRIDGE_TYPE_HOST        0x01
69
70 /* this should go to drivers/acpi/include/ */
71 struct acpi__hpp {
72         u8      cache_line_size;
73         u8      latency_timer;
74         u8      enable_serr;
75         u8      enable_perr;
76 };
77
78 struct acpi_php_slot {
79         struct acpi_php_slot    *next;
80         struct acpi_bridge      *bridge;
81         acpi_handle     handle;
82         int     seg;
83         int     bus;
84         int     dev;
85         int     fun;
86         u32     sun;
87         struct pci_resource *mem_head;
88         struct pci_resource *p_mem_head;
89         struct pci_resource *io_head;
90         struct pci_resource *bus_head;
91         void    *slot_ops;      /* _STA, _EJx, etc */
92         struct slot *slot;
93 };              /* per func */
94
95 struct acpi_bridge {
96         struct acpi_bridge      *parent;
97         struct acpi_bridge      *next;
98         struct acpi_bridge      *child;
99         acpi_handle     handle;
100         int seg;
101         int pbus;                       /* pdev->bus->number            */
102         int pdevice;                    /* PCI_SLOT(pdev->devfn)        */
103         int pfunction;                  /* PCI_DEVFN(pdev->devfn)       */
104         int bus;                        /* pdev->subordinate->number    */
105         struct acpi__hpp                *_hpp;
106         struct acpi_php_slot    *slots;
107         struct pci_resource     *tmem_head;     /* total from crs       */
108         struct pci_resource     *tp_mem_head;   /* total from crs       */
109         struct pci_resource     *tio_head;      /* total from crs       */
110         struct pci_resource     *tbus_head;     /* total from crs       */
111         struct pci_resource     *mem_head;      /* available    */
112         struct pci_resource     *p_mem_head;    /* available    */
113         struct pci_resource     *io_head;       /* available    */
114         struct pci_resource     *bus_head;      /* available    */
115         int scanned;
116         int type;
117 };
118
119 static struct acpi_bridge *acpi_bridges_head;
120
121 static u8 * acpi_path_name( acpi_handle handle)
122 {
123         acpi_status             status;
124         static u8               path_name[ACPI_PATHNAME_MAX];
125         struct acpi_buffer      ret_buf = { ACPI_PATHNAME_MAX, path_name };
126
127         memset(path_name, 0, sizeof (path_name));
128         status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &ret_buf);
129
130         if (ACPI_FAILURE(status))
131                 return NULL;
132         else
133                 return path_name;       
134 }
135
136 static void acpi_get__hpp ( struct acpi_bridge  *ab);
137 static int acpi_run_oshp ( struct acpi_bridge   *ab);
138 static int osc_run_status = NC_NOT_RUN;
139 static int oshp_run_status = NC_NOT_RUN;
140
141 static int acpi_add_slot_to_php_slots(
142         struct acpi_bridge      *ab,
143         int                     bus_num,
144         acpi_handle             handle,
145         u32                     adr,
146         u32                     sun
147         )
148 {
149         struct acpi_php_slot    *aps;
150         static long     samesun = -1;
151
152         aps = (struct acpi_php_slot *) kmalloc (sizeof(struct acpi_php_slot), GFP_KERNEL);
153         if (!aps) {
154                 err ("acpi_pciehprm: alloc for aps fail\n");
155                 return -1;
156         }
157         memset(aps, 0, sizeof(struct acpi_php_slot));
158
159         aps->handle = handle;
160         aps->bus = bus_num;
161         aps->dev = (adr >> 16) & 0xffff;
162         aps->fun = adr & 0xffff;
163         aps->sun = sun;
164
165         aps->next = ab->slots;  /* cling to the bridge */
166         aps->bridge = ab;
167         ab->slots = aps;
168
169         ab->scanned += 1;
170         if (!ab->_hpp)
171                 acpi_get__hpp(ab);
172         
173         if (osc_run_status == OSC_NOT_EXIST)
174                 oshp_run_status = acpi_run_oshp(ab);
175
176         if (sun != samesun) {
177                 info("acpi_pciehprm:   Slot sun(%x) at s:b:d:f=0x%02x:%02x:%02x:%02x\n", 
178                         aps->sun, ab->seg, aps->bus, aps->dev, aps->fun);
179                 samesun = sun;
180         }
181         return 0;
182 }
183
184 static void acpi_get__hpp ( struct acpi_bridge  *ab)
185 {
186         acpi_status             status;
187         u8                      nui[4];
188         struct acpi_buffer      ret_buf = { 0, NULL};
189         union acpi_object       *ext_obj, *package;
190         u8                      *path_name = acpi_path_name(ab->handle);
191         int                     i, len = 0;
192
193         /* get _hpp */
194         status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf);
195         switch (status) {
196         case AE_BUFFER_OVERFLOW:
197                 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
198                 if (!ret_buf.pointer) {
199                         err ("acpi_pciehprm:%s alloc for _HPP fail\n", path_name);
200                         return;
201                 }
202                 status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf);
203                 if (ACPI_SUCCESS(status))
204                         break;
205         default:
206                 if (ACPI_FAILURE(status)) {
207                         err("acpi_pciehprm:%s _HPP fail=0x%x\n", path_name, status);
208                         return;
209                 }
210         }
211
212         ext_obj = (union acpi_object *) ret_buf.pointer;
213         if (ext_obj->type != ACPI_TYPE_PACKAGE) {
214                 err ("acpi_pciehprm:%s _HPP obj not a package\n", path_name);
215                 goto free_and_return;
216         }
217
218         len = ext_obj->package.count;
219         package = (union acpi_object *) ret_buf.pointer;
220         for ( i = 0; (i < len) || (i < 4); i++) {
221                 ext_obj = (union acpi_object *) &package->package.elements[i];
222                 switch (ext_obj->type) {
223                 case ACPI_TYPE_INTEGER:
224                         nui[i] = (u8)ext_obj->integer.value;
225                         break;
226                 default:
227                         err ("acpi_pciehprm:%s _HPP obj type incorrect\n", path_name);
228                         goto free_and_return;
229                 }
230         }
231
232         ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL);
233         if (!ab->_hpp) {
234                 err ("acpi_pciehprm:%s alloc for _HPP failed\n", path_name);
235                 goto free_and_return;
236         }
237         memset(ab->_hpp, 0, sizeof(struct acpi__hpp));
238
239         ab->_hpp->cache_line_size       = nui[0];
240         ab->_hpp->latency_timer         = nui[1];
241         ab->_hpp->enable_serr           = nui[2];
242         ab->_hpp->enable_perr           = nui[3];
243
244         dbg("  _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
245         dbg("  _HPP: latency timer  =0x%x\n", ab->_hpp->latency_timer);
246         dbg("  _HPP: enable SERR    =0x%x\n", ab->_hpp->enable_serr);
247         dbg("  _HPP: enable PERR    =0x%x\n", ab->_hpp->enable_perr);
248
249 free_and_return:
250         kfree(ret_buf.pointer);
251 }
252
253 static int acpi_run_oshp ( struct acpi_bridge   *ab)
254 {
255         acpi_status             status;
256         u8                      *path_name = acpi_path_name(ab->handle);
257
258         /* run OSHP */
259         status = acpi_evaluate_object(ab->handle, METHOD_NAME_OSHP, NULL, NULL);
260         if (ACPI_FAILURE(status)) {
261                 err("acpi_pciehprm:%s OSHP fails=0x%x\n", path_name, status);
262                 oshp_run_status = (status == AE_NOT_FOUND) ? OSHP_NOT_EXIST : OSHP_RUN_FAILED;
263         } else {
264                 oshp_run_status = NC_RUN_SUCCESS;
265                 dbg("acpi_pciehprm:%s OSHP passes =0x%x\n", path_name, status);
266                 dbg("acpi_pciehprm:%s oshp_run_status =0x%x\n", path_name, oshp_run_status);
267         }
268         return oshp_run_status;
269 }
270
271 static acpi_status acpi_evaluate_crs(
272         acpi_handle             handle,
273         struct acpi_resource    **retbuf
274         )
275 {
276         acpi_status             status;
277         struct acpi_buffer      crsbuf;
278         u8                      *path_name = acpi_path_name(handle);
279
280         crsbuf.length  = 0;
281         crsbuf.pointer = NULL;
282
283         status = acpi_get_current_resources (handle, &crsbuf);
284
285         switch (status) {
286         case AE_BUFFER_OVERFLOW:
287                 break;          /* found */
288         case AE_NOT_FOUND:
289                 dbg("acpi_pciehprm:%s _CRS not found\n", path_name);
290                 return status;
291         default:
292                 err ("acpi_pciehprm:%s _CRS fail=0x%x\n", path_name, status);
293                 return status;
294         }
295
296         crsbuf.pointer = kmalloc (crsbuf.length, GFP_KERNEL);
297         if (!crsbuf.pointer) {
298                 err ("acpi_pciehprm: alloc %ld bytes for %s _CRS fail\n", (ulong)crsbuf.length, path_name);
299                 return AE_NO_MEMORY;
300         }
301
302         status = acpi_get_current_resources (handle, &crsbuf);
303         if (ACPI_FAILURE(status)) {
304                 err("acpi_pciehprm: %s _CRS fail=0x%x.\n", path_name, status);
305                 kfree(crsbuf.pointer);
306                 return status;
307         }
308
309         *retbuf = crsbuf.pointer;
310
311         return status;
312 }
313
314 static void free_pci_resource ( struct pci_resource     *aprh)
315 {
316         struct pci_resource     *res, *next;
317
318         for (res = aprh; res; res = next) {
319                 next = res->next;
320                 kfree(res);
321         }
322 }
323
324 static void print_pci_resource ( struct pci_resource    *aprh)
325 {
326         struct pci_resource     *res;
327
328         for (res = aprh; res; res = res->next)
329                 dbg("        base= 0x%x length= 0x%x\n", res->base, res->length);
330 }
331
332 static void print_slot_resources( struct acpi_php_slot  *aps)
333 {
334         if (aps->bus_head) {
335                 dbg("    BUS Resources:\n");
336                 print_pci_resource (aps->bus_head);
337         }
338
339         if (aps->io_head) {
340                 dbg("    IO Resources:\n");
341                 print_pci_resource (aps->io_head);
342         }
343
344         if (aps->mem_head) {
345                 dbg("    MEM Resources:\n");
346                 print_pci_resource (aps->mem_head);
347         }
348
349         if (aps->p_mem_head) {
350                 dbg("    PMEM Resources:\n");
351                 print_pci_resource (aps->p_mem_head);
352         }
353 }
354
355 static void print_pci_resources( struct acpi_bridge     *ab)
356 {
357         if (ab->tbus_head) {
358                 dbg("    Total BUS Resources:\n");
359                 print_pci_resource (ab->tbus_head);
360         }
361         if (ab->bus_head) {
362                 dbg("    BUS Resources:\n");
363                 print_pci_resource (ab->bus_head);
364         }
365
366         if (ab->tio_head) {
367                 dbg("    Total IO Resources:\n");
368                 print_pci_resource (ab->tio_head);
369         }
370         if (ab->io_head) {
371                 dbg("    IO Resources:\n");
372                 print_pci_resource (ab->io_head);
373         }
374
375         if (ab->tmem_head) {
376                 dbg("    Total MEM Resources:\n");
377                 print_pci_resource (ab->tmem_head);
378         }
379         if (ab->mem_head) {
380                 dbg("    MEM Resources:\n");
381                 print_pci_resource (ab->mem_head);
382         }
383
384         if (ab->tp_mem_head) {
385                 dbg("    Total PMEM Resources:\n");
386                 print_pci_resource (ab->tp_mem_head);
387         }
388         if (ab->p_mem_head) {
389                 dbg("    PMEM Resources:\n");
390                 print_pci_resource (ab->p_mem_head);
391         }
392         if (ab->_hpp) {
393                 dbg("    _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
394                 dbg("    _HPP: latency timer  =0x%x\n", ab->_hpp->latency_timer);
395                 dbg("    _HPP: enable SERR    =0x%x\n", ab->_hpp->enable_serr);
396                 dbg("    _HPP: enable PERR    =0x%x\n", ab->_hpp->enable_perr);
397         }
398 }
399
400 static int pciehprm_delete_resource(
401         struct pci_resource **aprh,
402         ulong base,
403         ulong size)
404 {
405         struct pci_resource *res;
406         struct pci_resource *prevnode;
407         struct pci_resource *split_node;
408         ulong tbase;
409
410         pciehp_resource_sort_and_combine(aprh);
411
412         for (res = *aprh; res; res = res->next) {
413                 if (res->base > base)
414                         continue;
415
416                 if ((res->base + res->length) < (base + size))
417                         continue;
418
419                 if (res->base < base) {
420                         tbase = base;
421
422                         if ((res->length - (tbase - res->base)) < size)
423                                 continue;
424
425                         split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
426                         if (!split_node)
427                                 return -ENOMEM;
428
429                         split_node->base = res->base;
430                         split_node->length = tbase - res->base;
431                         res->base = tbase;
432                         res->length -= split_node->length;
433
434                         split_node->next = res->next;
435                         res->next = split_node;
436                 }
437
438                 if (res->length >= size) {
439                         split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
440                         if (!split_node)
441                                 return -ENOMEM;
442
443                         split_node->base = res->base + size;
444                         split_node->length = res->length - size;
445                         res->length = size;
446
447                         split_node->next = res->next;
448                         res->next = split_node;
449                 }
450
451                 if (*aprh == res) {
452                         *aprh = res->next;
453                 } else {
454                         prevnode = *aprh;
455                         while (prevnode->next != res)
456                                 prevnode = prevnode->next;
457
458                         prevnode->next = res->next;
459                 }
460                 res->next = NULL;
461                 kfree(res);
462                 break;
463         }
464
465         return 0;
466 }
467
468 static int pciehprm_delete_resources(
469         struct pci_resource **aprh,
470         struct pci_resource *this
471         )
472 {
473         struct pci_resource *res;
474
475         for (res = this; res; res = res->next)
476                 pciehprm_delete_resource(aprh, res->base, res->length);
477
478         return 0;
479 }
480
481 static int pciehprm_add_resource(
482         struct pci_resource **aprh,
483         ulong base,
484         ulong size)
485 {
486         struct pci_resource *res;
487
488         for (res = *aprh; res; res = res->next) {
489                 if ((res->base + res->length) == base) {
490                         res->length += size;
491                         size = 0L;
492                         break;
493                 }
494                 if (res->next == *aprh)
495                         break;
496         }
497
498         if (size) {
499                 res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
500                 if (!res) {
501                         err ("acpi_pciehprm: alloc for res fail\n");
502                         return -ENOMEM;
503                 }
504                 memset(res, 0, sizeof (struct pci_resource));
505
506                 res->base = base;
507                 res->length = size;
508                 res->next = *aprh;
509                 *aprh = res;
510         }
511
512         return 0;
513 }
514
515 static int pciehprm_add_resources(
516         struct pci_resource **aprh,
517         struct pci_resource *this
518         )
519 {
520         struct pci_resource *res;
521         int     rc = 0;
522
523         for (res = this; res && !rc; res = res->next)
524                 rc = pciehprm_add_resource(aprh, res->base, res->length);
525
526         return rc;
527 }
528
529 static void acpi_parse_io (
530         struct acpi_bridge              *ab,
531         union acpi_resource_data        *data
532         )
533 {
534         struct acpi_resource_io *dataio;
535         dataio = (struct acpi_resource_io *) data;
536
537         dbg("Io Resource\n");
538         dbg("  %d bit decode\n", ACPI_DECODE_16 == dataio->io_decode ? 16:10);
539         dbg("  Range minimum base: %08X\n", dataio->min_base_address);
540         dbg("  Range maximum base: %08X\n", dataio->max_base_address);
541         dbg("  Alignment: %08X\n", dataio->alignment);
542         dbg("  Range Length: %08X\n", dataio->range_length);
543 }
544
545 static void acpi_parse_fixed_io (
546         struct acpi_bridge      *ab,
547         union acpi_resource_data        *data
548         )
549 {
550         struct acpi_resource_fixed_io  *datafio;
551         datafio = (struct acpi_resource_fixed_io *) data;
552
553         dbg("Fixed Io Resource\n");
554         dbg("  Range base address: %08X", datafio->base_address);
555         dbg("  Range length: %08X", datafio->range_length);
556 }
557
558 static void acpi_parse_address16_32 (
559         struct acpi_bridge      *ab,
560         union acpi_resource_data        *data,
561         acpi_resource_type      id
562         )
563 {
564         /* 
565          * acpi_resource_address16 == acpi_resource_address32
566          * acpi_resource_address16 *data16 = (acpi_resource_address16 *) data;
567          */
568         struct acpi_resource_address32 *data32 = (struct acpi_resource_address32 *) data;
569         struct pci_resource **aprh, **tprh;
570
571         if (id == ACPI_RSTYPE_ADDRESS16)
572                 dbg("acpi_pciehprm:16-Bit Address Space Resource\n");
573         else
574                 dbg("acpi_pciehprm:32-Bit Address Space Resource\n");
575
576         switch (data32->resource_type) {
577         case ACPI_MEMORY_RANGE: 
578                 dbg("  Resource Type: Memory Range\n");
579                 aprh = &ab->mem_head;
580                 tprh = &ab->tmem_head;
581
582                 switch (data32->attribute.memory.cache_attribute) {
583                 case ACPI_NON_CACHEABLE_MEMORY:
584                         dbg("  Type Specific: Noncacheable memory\n");
585                         break; 
586                 case ACPI_CACHABLE_MEMORY:
587                         dbg("  Type Specific: Cacheable memory\n");
588                         break; 
589                 case ACPI_WRITE_COMBINING_MEMORY:
590                         dbg("  Type Specific: Write-combining memory\n");
591                         break; 
592                 case ACPI_PREFETCHABLE_MEMORY:
593                         aprh = &ab->p_mem_head;
594                         dbg("  Type Specific: Prefetchable memory\n");
595                         break; 
596                 default:
597                         dbg("  Type Specific: Invalid cache attribute\n");
598                         break;
599                 }
600
601                 dbg("  Type Specific: Read%s\n", ACPI_READ_WRITE_MEMORY == data32->attribute.memory.read_write_attribute ? "/Write":" Only");
602                 break;
603
604         case ACPI_IO_RANGE: 
605                 dbg("  Resource Type: I/O Range\n");
606                 aprh = &ab->io_head;
607                 tprh = &ab->tio_head;
608
609                 switch (data32->attribute.io.range_attribute) {
610                 case ACPI_NON_ISA_ONLY_RANGES:
611                         dbg("  Type Specific: Non-ISA Io Addresses\n");
612                         break; 
613                 case ACPI_ISA_ONLY_RANGES:
614                         dbg("  Type Specific: ISA Io Addresses\n");
615                         break; 
616                 case ACPI_ENTIRE_RANGE:
617                         dbg("  Type Specific: ISA and non-ISA Io Addresses\n");
618                         break; 
619                 default:
620                         dbg("  Type Specific: Invalid range attribute\n");
621                         break;
622                 }
623                 break;
624
625         case ACPI_BUS_NUMBER_RANGE: 
626                 dbg("  Resource Type: Bus Number Range(fixed)\n");
627                 /* fixup to be compatible with the rest of php driver */
628                 data32->min_address_range++;
629                 data32->address_length--;
630                 aprh = &ab->bus_head;
631                 tprh = &ab->tbus_head;
632                 break; 
633         default: 
634                 dbg("  Resource Type: Invalid resource type. Exiting.\n");
635                 return;
636         }
637
638         dbg("  Resource %s\n", ACPI_CONSUMER == data32->producer_consumer ? "Consumer":"Producer");
639         dbg("  %s decode\n", ACPI_SUB_DECODE == data32->decode ? "Subtractive":"Positive");
640         dbg("  Min address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->min_address_fixed ? "":"not");
641         dbg("  Max address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->max_address_fixed ? "":"not");
642         dbg("  Granularity: %08X\n", data32->granularity);
643         dbg("  Address range min: %08X\n", data32->min_address_range);
644         dbg("  Address range max: %08X\n", data32->max_address_range);
645         dbg("  Address translation offset: %08X\n", data32->address_translation_offset);
646         dbg("  Address Length: %08X\n", data32->address_length);
647
648         if (0xFF != data32->resource_source.index) {
649                 dbg("  Resource Source Index: %X\n", data32->resource_source.index);
650                 /* dbg("  Resource Source: %s\n", data32->resource_source.string_ptr); */
651         }
652
653         pciehprm_add_resource(aprh, data32->min_address_range, data32->address_length);
654 }
655
656 static acpi_status acpi_parse_crs(
657         struct acpi_bridge      *ab,
658         struct acpi_resource    *crsbuf
659         )
660 {
661         acpi_status             status = AE_OK;
662         struct acpi_resource    *resource = crsbuf;
663         u8                              count = 0;
664         u8                              done = 0;
665
666         while (!done) {
667                 dbg("acpi_pciehprm: PCI bus 0x%x Resource structure %x.\n", ab->bus, count++);
668                 switch (resource->id) {
669                 case ACPI_RSTYPE_IRQ:
670                         dbg("Irq -------- Resource\n");
671                         break; 
672                 case ACPI_RSTYPE_DMA:
673                         dbg("DMA -------- Resource\n");
674                         break; 
675                 case ACPI_RSTYPE_START_DPF:
676                         dbg("Start DPF -------- Resource\n");
677                         break; 
678                 case ACPI_RSTYPE_END_DPF:
679                         dbg("End DPF -------- Resource\n");
680                         break; 
681                 case ACPI_RSTYPE_IO:
682                         acpi_parse_io (ab, &resource->data);
683                         break; 
684                 case ACPI_RSTYPE_FIXED_IO:
685                         acpi_parse_fixed_io (ab, &resource->data);
686                         break; 
687                 case ACPI_RSTYPE_VENDOR:
688                         dbg("Vendor -------- Resource\n");
689                         break; 
690                 case ACPI_RSTYPE_END_TAG:
691                         dbg("End_tag -------- Resource\n");
692                         done = 1;
693                         break; 
694                 case ACPI_RSTYPE_MEM24:
695                         dbg("Mem24 -------- Resource\n");
696                         break; 
697                 case ACPI_RSTYPE_MEM32:
698                         dbg("Mem32 -------- Resource\n");
699                         break; 
700                 case ACPI_RSTYPE_FIXED_MEM32:
701                         dbg("Fixed Mem32 -------- Resource\n");
702                         break; 
703                 case ACPI_RSTYPE_ADDRESS16:
704                         acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS16);
705                         break; 
706                 case ACPI_RSTYPE_ADDRESS32:
707                         acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS32);
708                         break; 
709                 case ACPI_RSTYPE_ADDRESS64:
710                         info("Address64 -------- Resource unparsed\n");
711                         break; 
712                 case ACPI_RSTYPE_EXT_IRQ:
713                         dbg("Ext Irq -------- Resource\n");
714                         break; 
715                 default:
716                         dbg("Invalid -------- resource type 0x%x\n", resource->id);
717                         break;
718                 }
719
720                 resource = (struct acpi_resource *) ((char *)resource + resource->length);
721         }
722
723         return status;
724 }
725
726 static acpi_status acpi_get_crs( struct acpi_bridge     *ab)
727 {
728         acpi_status             status;
729         struct acpi_resource    *crsbuf;
730
731         status = acpi_evaluate_crs(ab->handle, &crsbuf);
732         if (ACPI_SUCCESS(status)) {
733                 status = acpi_parse_crs(ab, crsbuf);
734                 kfree(crsbuf);
735
736                 pciehp_resource_sort_and_combine(&ab->bus_head);
737                 pciehp_resource_sort_and_combine(&ab->io_head);
738                 pciehp_resource_sort_and_combine(&ab->mem_head);
739                 pciehp_resource_sort_and_combine(&ab->p_mem_head);
740
741                 pciehprm_add_resources (&ab->tbus_head, ab->bus_head);
742                 pciehprm_add_resources (&ab->tio_head, ab->io_head);
743                 pciehprm_add_resources (&ab->tmem_head, ab->mem_head);
744                 pciehprm_add_resources (&ab->tp_mem_head, ab->p_mem_head);
745         }
746
747         return status;
748 }
749
750 /* find acpi_bridge downword from ab.  */
751 static struct acpi_bridge *
752 find_acpi_bridge_by_bus(
753         struct acpi_bridge *ab,
754         int seg,
755         int bus         /* pdev->subordinate->number */
756         )
757 {
758         struct acpi_bridge      *lab = NULL;
759
760         if (!ab)
761                 return NULL;
762
763         if ((ab->bus == bus) && (ab->seg == seg))
764                 return ab;
765
766         if (ab->child)
767                 lab = find_acpi_bridge_by_bus(ab->child, seg, bus);
768
769         if (!lab)
770         if (ab->next)
771                 lab = find_acpi_bridge_by_bus(ab->next, seg, bus);
772
773         return lab;
774 }
775
776 /*
777  * Build a device tree of ACPI PCI Bridges
778  */
779 static void pciehprm_acpi_register_a_bridge (
780         struct acpi_bridge      **head,
781         struct acpi_bridge      *pab,   /* parent bridge to which child bridge is added */
782         struct acpi_bridge      *cab    /* child bridge to add */
783         )
784 {
785         struct acpi_bridge      *lpab;
786         struct acpi_bridge      *lcab;
787
788         lpab = find_acpi_bridge_by_bus(*head, pab->seg, pab->bus);
789         if (!lpab) {
790                 if (!(pab->type & BRIDGE_TYPE_HOST))
791                         warn("PCI parent bridge s:b(%x:%x) not in list.\n", pab->seg, pab->bus);
792                 pab->next = *head;
793                 *head = pab;
794                 lpab = pab;
795         }
796
797         if ((cab->type & BRIDGE_TYPE_HOST) && (pab == cab))
798                 return;
799
800         lcab = find_acpi_bridge_by_bus(*head, cab->seg, cab->bus);
801         if (lcab) {
802                 if ((pab->bus != lcab->parent->bus) || (lcab->bus != cab->bus))
803                         err("PCI child bridge s:b(%x:%x) in list with diff parent.\n", cab->seg, cab->bus);
804                 return;
805         } else
806                 lcab = cab;
807
808         lcab->parent = lpab;
809         lcab->next = lpab->child;
810         lpab->child = lcab;
811 }
812
813 static acpi_status pciehprm_acpi_build_php_slots_callback(
814         acpi_handle             handle,
815         u32                     Level,
816         void                    *context,
817         void                    **retval
818         )
819 {
820         ulong           bus_num;
821         ulong           seg_num;
822         ulong           sun, adr;
823         ulong           padr = 0;
824         acpi_handle             phandle = NULL;
825         struct acpi_bridge      *pab = (struct acpi_bridge *)context;
826         struct acpi_bridge      *lab;
827         acpi_status             status;
828         u8                      *path_name = acpi_path_name(handle);
829
830         /* get _SUN */
831         status = acpi_evaluate_integer(handle, METHOD_NAME__SUN, NULL, &sun);
832         switch(status) {
833         case AE_NOT_FOUND:
834                 return AE_OK;
835         default:
836                 if (ACPI_FAILURE(status)) {
837                         err("acpi_pciehprm:%s _SUN fail=0x%x\n", path_name, status);
838                         return status;
839                 }
840         }
841
842         /* get _ADR. _ADR must exist if _SUN exists */
843         status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
844         if (ACPI_FAILURE(status)) {
845                 err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
846                 return status;
847         }
848
849         dbg("acpi_pciehprm:%s sun=0x%08x adr=0x%08x\n", path_name, (u32)sun, (u32)adr);
850
851         status = acpi_get_parent(handle, &phandle);
852         if (ACPI_FAILURE(status)) {
853                 err("acpi_pciehprm:%s get_parent fail=0x%x\n", path_name, status);
854                 return (status);
855         }
856
857         bus_num = pab->bus;
858         seg_num = pab->seg;
859
860         if (pab->bus == bus_num) {
861                 lab = pab;
862         } else {
863                 dbg("WARN: pab is not parent\n");
864                 lab = find_acpi_bridge_by_bus(pab, seg_num, bus_num);
865                 if (!lab) {
866                         dbg("acpi_pciehprm: alloc new P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
867                         lab = (struct acpi_bridge *)kmalloc(sizeof(struct acpi_bridge), GFP_KERNEL);
868                         if (!lab) {
869                                 err("acpi_pciehprm: alloc for ab fail\n");
870                                 return AE_NO_MEMORY;
871                         }
872                         memset(lab, 0, sizeof(struct acpi_bridge));
873
874                         lab->handle = phandle;
875                         lab->pbus = pab->bus;
876                         lab->pdevice = (int)(padr >> 16) & 0xffff;
877                         lab->pfunction = (int)(padr & 0xffff);
878                         lab->bus = (int)bus_num;
879                         lab->scanned = 0;
880                         lab->type = BRIDGE_TYPE_P2P;
881
882                         pciehprm_acpi_register_a_bridge (&acpi_bridges_head, pab, lab);
883                 } else
884                         dbg("acpi_pciehprm: found P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
885         }
886
887         acpi_add_slot_to_php_slots(lab, (int)bus_num, handle, (u32)adr, (u32)sun);
888
889         return (status);
890 }
891
892 static int pciehprm_acpi_build_php_slots(
893         struct acpi_bridge      *ab,
894         u32                     depth
895         )
896 {
897         acpi_status     status;
898         u8              *path_name = acpi_path_name(ab->handle);
899
900         /* Walk down this pci bridge to get _SUNs if any behind P2P */
901         status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
902                                 ab->handle,
903                                 depth,
904                                 pciehprm_acpi_build_php_slots_callback,
905                                 ab,
906                                 NULL );
907         if (ACPI_FAILURE(status)) {
908                 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);
909                 return -1;
910         }
911
912         return 0;
913 }
914
915 static void build_a_bridge(
916         struct acpi_bridge      *pab,
917         struct acpi_bridge      *ab
918         )
919 {
920         u8              *path_name = acpi_path_name(ab->handle);
921
922         pciehprm_acpi_register_a_bridge (&acpi_bridges_head, pab, ab);
923
924         switch (ab->type) {
925         case BRIDGE_TYPE_HOST:
926                 dbg("acpi_pciehprm: Registered PCI HOST Bridge(%02x)    on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
927                         ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
928                 break;
929         case BRIDGE_TYPE_P2P:
930                 dbg("acpi_pciehprm: Registered PCI  P2P Bridge(%02x-%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
931                         ab->pbus, ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
932                 break;
933         };
934
935         /* build any immediate PHP slots under this pci bridge */
936         pciehprm_acpi_build_php_slots(ab, 1);
937 }
938
939 static struct acpi_bridge * add_p2p_bridge(
940         acpi_handle handle,
941         struct acpi_bridge      *pab,   /* parent */
942         ulong   adr
943         )
944 {
945         struct acpi_bridge      *ab;
946         struct pci_dev  *pdev;
947         ulong           devnum, funcnum;
948         u8                      *path_name = acpi_path_name(handle);
949
950         ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
951         if (!ab) {
952                 err("acpi_pciehprm: alloc for ab fail\n");
953                 return NULL;
954         }
955         memset(ab, 0, sizeof(struct acpi_bridge));
956
957         devnum = (adr >> 16) & 0xffff;
958         funcnum = adr & 0xffff;
959
960         pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
961         if (!pdev || !pdev->subordinate) {
962                 err("acpi_pciehprm:%s is not a P2P Bridge\n", path_name);
963                 kfree(ab);
964                 return NULL;
965         }
966
967         ab->handle = handle;
968         ab->seg = pab->seg;
969         ab->pbus = pab->bus;            /* or pdev->bus->number */
970         ab->pdevice = devnum;           /* or PCI_SLOT(pdev->devfn) */
971         ab->pfunction = funcnum;        /* or PCI_FUNC(pdev->devfn) */
972         ab->bus = pdev->subordinate->number;
973         ab->scanned = 0;
974         ab->type = BRIDGE_TYPE_P2P;
975
976         dbg("acpi_pciehprm: P2P(%x-%x) on pci=b:d:f(%x:%x:%x) acpi=b:d:f(%x:%x:%x) [%s]\n",
977                 pab->bus, ab->bus, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
978                 pab->bus, (u32)devnum, (u32)funcnum, path_name);
979
980         build_a_bridge(pab, ab);
981
982         return ab;
983 }
984
985 static acpi_status scan_p2p_bridge(
986         acpi_handle             handle,
987         u32                     Level,
988         void                    *context,
989         void                    **retval
990         )
991 {
992         struct acpi_bridge      *pab = (struct acpi_bridge *)context;
993         struct acpi_bridge      *ab;
994         acpi_status             status;
995         ulong                   adr = 0;
996         u8                      *path_name = acpi_path_name(handle);
997         ulong                   devnum, funcnum;
998         struct pci_dev          *pdev;
999
1000         /* get device, function */
1001         status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
1002         if (ACPI_FAILURE(status)) {
1003                 if (status != AE_NOT_FOUND)
1004                         err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
1005                 return AE_OK;
1006         }
1007
1008         devnum = (adr >> 16) & 0xffff;
1009         funcnum = adr & 0xffff;
1010
1011         pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
1012         if (!pdev)
1013                 return AE_OK;
1014         if (!pdev->subordinate)
1015                 return AE_OK;
1016
1017         ab = add_p2p_bridge(handle, pab, adr);
1018         if (ab) {
1019                 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
1020                                         handle,
1021                                         (u32)1,
1022                                         scan_p2p_bridge,
1023                                         ab,
1024                                         NULL);
1025                 if (ACPI_FAILURE(status))
1026                         dbg("acpi_pciehprm:%s find_p2p fail=0x%x\n", path_name, status);
1027         }
1028
1029         return AE_OK;
1030 }
1031
1032 static struct acpi_bridge * add_host_bridge(
1033         acpi_handle handle,
1034         ulong   segnum,
1035         ulong   busnum
1036         )
1037 {
1038         ulong                   adr = 0;
1039         acpi_status             status;
1040         struct acpi_bridge      *ab;
1041         u8                      *path_name = acpi_path_name(handle);
1042
1043         /* get device, function: host br adr is always 0000 though.  */
1044         status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
1045         if (ACPI_FAILURE(status)) {
1046                 err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
1047                 return NULL;
1048         }
1049         dbg("acpi_pciehprm: ROOT PCI seg(0x%x)bus(0x%x)dev(0x%x)func(0x%x) [%s]\n", (u32)segnum, 
1050                 (u32)busnum, (u32)(adr >> 16) & 0xffff, (u32)adr & 0xffff, path_name);
1051
1052         ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
1053         if (!ab) {
1054                 err("acpi_pciehprm: alloc for ab fail\n");
1055                 return NULL;
1056         }
1057         memset(ab, 0, sizeof(struct acpi_bridge));
1058
1059         ab->handle = handle;
1060         ab->seg = (int)segnum;
1061         ab->bus = ab->pbus = (int)busnum;
1062         ab->pdevice = (int)(adr >> 16) & 0xffff;
1063         ab->pfunction = (int)(adr & 0xffff);
1064         ab->scanned = 0;
1065         ab->type = BRIDGE_TYPE_HOST;
1066
1067         /* get root pci bridge's current resources */
1068         status = acpi_get_crs(ab);
1069         if (ACPI_FAILURE(status)) {
1070                 err("acpi_pciehprm:%s evaluate _CRS fail=0x%x\n", path_name, status);
1071                 kfree(ab);
1072                 return NULL;
1073         }
1074
1075         status = pci_osc_control_set (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL); 
1076         if (ACPI_FAILURE(status)) {
1077                 err("%s: status %x\n", __FUNCTION__, status);
1078                 osc_run_status = (status == AE_NOT_FOUND) ? OSC_NOT_EXIST : OSC_RUN_FAILED;
1079         } else {
1080                 osc_run_status = NC_RUN_SUCCESS;
1081         }       
1082         dbg("%s: osc_run_status %x\n", __FUNCTION__, osc_run_status);
1083         
1084         build_a_bridge(ab, ab);
1085
1086         return ab;
1087 }
1088
1089 static acpi_status acpi_scan_from_root_pci_callback (
1090         acpi_handle     handle,
1091         u32                     Level,
1092         void            *context,
1093         void            **retval
1094         )
1095 {
1096         ulong           segnum = 0;
1097         ulong           busnum = 0;
1098         acpi_status             status;
1099         struct acpi_bridge      *ab;
1100         u8                      *path_name = acpi_path_name(handle);
1101
1102         /* get bus number of this pci root bridge */
1103         status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &segnum);
1104         if (ACPI_FAILURE(status)) {
1105                 if (status != AE_NOT_FOUND) {
1106                         err("acpi_pciehprm:%s evaluate _SEG fail=0x%x\n", path_name, status);
1107                         return status;
1108                 }
1109                 segnum = 0;
1110         }
1111
1112         /* get bus number of this pci root bridge */
1113         status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL, &busnum);
1114         if (ACPI_FAILURE(status)) {
1115                 err("acpi_pciehprm:%s evaluate _BBN fail=0x%x\n", path_name, status);
1116                 return (status);
1117         }
1118
1119         ab = add_host_bridge(handle, segnum, busnum);
1120         if (ab) {
1121                 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
1122                                         handle,
1123                                         1,
1124                                         scan_p2p_bridge,
1125                                         ab,
1126                                         NULL);
1127                 if (ACPI_FAILURE(status))
1128                         dbg("acpi_pciehprm:%s find_p2p fail=0x%x\n", path_name, status);
1129         }
1130
1131         return AE_OK;
1132 }
1133
1134 static int pciehprm_acpi_scan_pci (void)
1135 {
1136         acpi_status     status;
1137
1138         /*
1139          * TBD: traverse LDM device tree with the help of
1140          *  unified ACPI augmented for php device population.
1141          */
1142         status = acpi_get_devices ( PCI_ROOT_HID_STRING,
1143                                 acpi_scan_from_root_pci_callback,
1144                                 NULL,
1145                                 NULL );
1146         if (ACPI_FAILURE(status)) {
1147                 err("acpi_pciehprm:get_device PCI ROOT HID fail=0x%x\n", status);
1148                 return -1;
1149         }
1150
1151         return 0;
1152 }
1153
1154 int pciehprm_init(enum php_ctlr_type ctlr_type)
1155 {
1156         int     rc;
1157
1158         if (ctlr_type != PCI)
1159                 return -ENODEV;
1160
1161         dbg("pciehprm ACPI init <enter>\n");
1162         acpi_bridges_head = NULL;
1163
1164         /* construct PCI bus:device tree of acpi_handles */
1165         rc = pciehprm_acpi_scan_pci();
1166         if (rc)
1167                 return rc;
1168
1169         if ((oshp_run_status != NC_RUN_SUCCESS) && (osc_run_status != NC_RUN_SUCCESS)) {
1170                 err("Fails to gain control of native hot-plug\n");
1171                 rc = -ENODEV;
1172         }
1173
1174         dbg("pciehprm ACPI init %s\n", (rc)?"fail":"success");
1175         return rc;
1176 }
1177
1178 static void free_a_slot(struct acpi_php_slot *aps)
1179 {
1180         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);
1181
1182         free_pci_resource (aps->io_head);
1183         free_pci_resource (aps->bus_head);
1184         free_pci_resource (aps->mem_head);
1185         free_pci_resource (aps->p_mem_head);
1186
1187         kfree(aps);
1188 }
1189
1190 static void free_a_bridge( struct acpi_bridge   *ab)
1191 {
1192         struct acpi_php_slot    *aps, *next;
1193
1194         switch (ab->type) {
1195         case BRIDGE_TYPE_HOST:
1196                 dbg("Free ACPI PCI HOST Bridge(%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
1197                         ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
1198                 break;
1199         case BRIDGE_TYPE_P2P:
1200                 dbg("Free ACPI PCI P2P Bridge(%x-%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
1201                         ab->pbus, ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
1202                 break;
1203         };
1204
1205         /* free slots first */
1206         for (aps = ab->slots; aps; aps = next) {
1207                 next = aps->next;
1208                 free_a_slot(aps);
1209         }
1210
1211         free_pci_resource (ab->io_head);
1212         free_pci_resource (ab->tio_head);
1213         free_pci_resource (ab->bus_head);
1214         free_pci_resource (ab->tbus_head);
1215         free_pci_resource (ab->mem_head);
1216         free_pci_resource (ab->tmem_head);
1217         free_pci_resource (ab->p_mem_head);
1218         free_pci_resource (ab->tp_mem_head);
1219
1220         kfree(ab);
1221 }
1222
1223 static void pciehprm_free_bridges ( struct acpi_bridge  *ab)
1224 {
1225         if (!ab)
1226                 return;
1227
1228         if (ab->child)
1229                 pciehprm_free_bridges (ab->child);
1230
1231         if (ab->next)
1232                 pciehprm_free_bridges (ab->next);
1233
1234         free_a_bridge(ab);
1235 }
1236
1237 void pciehprm_cleanup(void)
1238 {
1239         pciehprm_free_bridges (acpi_bridges_head);
1240 }
1241
1242 static int get_number_of_slots (
1243         struct acpi_bridge      *ab,
1244         int                             selfonly
1245         )
1246 {
1247         struct acpi_php_slot    *aps;
1248         int     prev_slot = -1;
1249         int     slot_num = 0;
1250
1251         for ( aps = ab->slots; aps; aps = aps->next)
1252                 if (aps->dev != prev_slot) {
1253                         prev_slot = aps->dev;
1254                         slot_num++;
1255                 }
1256
1257         if (ab->child)
1258                 slot_num += get_number_of_slots (ab->child, 0);
1259
1260         if (selfonly)
1261                 return slot_num;
1262
1263         if (ab->next)
1264                 slot_num += get_number_of_slots (ab->next, 0);
1265
1266         return slot_num;
1267 }
1268
1269 static int print_acpi_resources (struct acpi_bridge     *ab)
1270 {
1271         struct acpi_php_slot            *aps;
1272         int     i;
1273
1274         switch (ab->type) {
1275         case BRIDGE_TYPE_HOST:
1276                 dbg("PCI HOST Bridge (%x) [%s]\n", ab->bus, acpi_path_name(ab->handle));
1277                 break;
1278         case BRIDGE_TYPE_P2P:
1279                 dbg("PCI P2P Bridge (%x-%x) [%s]\n", ab->pbus, ab->bus, acpi_path_name(ab->handle));
1280                 break;
1281         };
1282
1283         print_pci_resources (ab);
1284
1285         for ( i = -1, aps = ab->slots; aps; aps = aps->next) {
1286                 if (aps->dev == i)
1287                         continue;
1288                 dbg("  Slot sun(%x) s:b:d:f(%02x:%02x:%02x:%02x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun);
1289                 print_slot_resources(aps);
1290                 i = aps->dev;
1291         }
1292
1293         if (ab->child)
1294                 print_acpi_resources (ab->child);
1295
1296         if (ab->next)
1297                 print_acpi_resources (ab->next);
1298
1299         return 0;
1300 }
1301
1302 int pciehprm_print_pirt(void)
1303 {
1304         dbg("PCIEHPRM ACPI Slots\n");
1305         if (acpi_bridges_head)
1306                 print_acpi_resources (acpi_bridges_head);
1307
1308         return 0;
1309 }
1310
1311 static struct acpi_php_slot * get_acpi_slot (
1312         struct acpi_bridge *ab,
1313         u32 sun
1314         )
1315 {
1316         struct acpi_php_slot    *aps = NULL;
1317
1318         for ( aps = ab->slots; aps; aps = aps->next)
1319                 if (aps->sun == sun)
1320                         return aps;
1321
1322         if (!aps && ab->child) {
1323                 aps = (struct acpi_php_slot *)get_acpi_slot (ab->child, sun);
1324                 if (aps)
1325                         return aps;
1326         }
1327
1328         if (!aps && ab->next) {
1329                 aps = (struct acpi_php_slot *)get_acpi_slot (ab->next, sun);
1330                 if (aps)
1331                         return aps;
1332         }
1333
1334         return aps;
1335
1336 }
1337
1338 #if 0
1339 void * pciehprm_get_slot(struct slot *slot)
1340 {
1341         struct acpi_bridge      *ab = acpi_bridges_head;
1342         struct acpi_php_slot    *aps = get_acpi_slot (ab, slot->number);
1343
1344         aps->slot = slot;
1345
1346         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);
1347
1348         return (void *)aps;
1349 }
1350 #endif
1351
1352 static void pciehprm_dump_func_res( struct pci_func *fun)
1353 {
1354         struct pci_func *func = fun;
1355
1356         if (func->bus_head) {
1357                 dbg(":    BUS Resources:\n");
1358                 print_pci_resource (func->bus_head);
1359         }
1360         if (func->io_head) {
1361                 dbg(":    IO Resources:\n");
1362                 print_pci_resource (func->io_head);
1363         }
1364         if (func->mem_head) {
1365                 dbg(":    MEM Resources:\n");
1366                 print_pci_resource (func->mem_head);
1367         }
1368         if (func->p_mem_head) {
1369                 dbg(":    PMEM Resources:\n");
1370                 print_pci_resource (func->p_mem_head);
1371         }
1372 }
1373
1374 static void pciehprm_dump_ctrl_res( struct controller *ctlr)
1375 {
1376         struct controller *ctrl = ctlr;
1377
1378         if (ctrl->bus_head) {
1379                 dbg(":    BUS Resources:\n");
1380                 print_pci_resource (ctrl->bus_head);
1381         }
1382         if (ctrl->io_head) {
1383                 dbg(":    IO Resources:\n");
1384                 print_pci_resource (ctrl->io_head);
1385         }
1386         if (ctrl->mem_head) {
1387                 dbg(":    MEM Resources:\n");
1388                 print_pci_resource (ctrl->mem_head);
1389         }
1390         if (ctrl->p_mem_head) {
1391                 dbg(":    PMEM Resources:\n");
1392                 print_pci_resource (ctrl->p_mem_head);
1393         }
1394 }
1395
1396 static int pciehprm_get_used_resources (
1397         struct controller *ctrl,
1398         struct pci_func *func
1399         )
1400 {
1401         return pciehp_save_used_resources (ctrl, func, !DISABLE_CARD);
1402 }
1403
1404 static int configure_existing_function(
1405         struct controller *ctrl,
1406         struct pci_func *func
1407         )
1408 {
1409         int rc;
1410
1411         /* see how much resources the func has used. */
1412         rc = pciehprm_get_used_resources (ctrl, func);
1413
1414         if (!rc) {
1415                 /* subtract the resources used by the func from ctrl resources */
1416                 rc  = pciehprm_delete_resources (&ctrl->bus_head, func->bus_head);
1417                 rc |= pciehprm_delete_resources (&ctrl->io_head, func->io_head);
1418                 rc |= pciehprm_delete_resources (&ctrl->mem_head, func->mem_head);
1419                 rc |= pciehprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head);
1420                 if (rc)
1421                         warn("aCEF: cannot del used resources\n");
1422         } else
1423                 err("aCEF: cannot get used resources\n");
1424
1425         return rc;
1426 }
1427
1428 static int bind_pci_resources_to_slots ( struct controller *ctrl)
1429 {
1430         struct pci_func *func, new_func;
1431         int busn = ctrl->slot_bus;
1432         int devn, funn;
1433         u32     vid;
1434
1435         for (devn = 0; devn < 32; devn++) {
1436                 for (funn = 0; funn < 8; funn++) {
1437                         /*
1438                         if (devn == ctrl->device && funn == ctrl->function)
1439                                 continue;
1440                         */
1441                         /* find out if this entry is for an occupied slot */
1442                         vid = 0xFFFFFFFF;
1443                         pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
1444
1445                         if (vid != 0xFFFFFFFF) {
1446                                 dbg("%s: vid = %x\n", __FUNCTION__, vid);
1447                                 func = pciehp_slot_find(busn, devn, funn);
1448                                 if (!func) {
1449                                         memset(&new_func, 0, sizeof(struct pci_func));
1450                                         new_func.bus = busn;
1451                                         new_func.device = devn;
1452                                         new_func.function = funn;
1453                                         new_func.is_a_board = 1;
1454                                         configure_existing_function(ctrl, &new_func);
1455                                         pciehprm_dump_func_res(&new_func);
1456                                 } else {
1457                                         configure_existing_function(ctrl, func);
1458                                         pciehprm_dump_func_res(func);
1459                                 }
1460                                 dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
1461                         }
1462                 }
1463         }
1464
1465         return 0;
1466 }
1467
1468 static int bind_pci_resources(
1469         struct controller       *ctrl,
1470         struct acpi_bridge      *ab
1471         )
1472 {
1473         int             status = 0;
1474
1475         if (ab->bus_head) {
1476                 dbg("bapr:  BUS Resources add on PCI 0x%x\n", ab->bus);
1477                 status = pciehprm_add_resources (&ctrl->bus_head, ab->bus_head);
1478                 if (pciehprm_delete_resources (&ab->bus_head, ctrl->bus_head))
1479                         warn("bapr:  cannot sub BUS Resource on PCI 0x%x\n", ab->bus);
1480                 if (status) {
1481                         err("bapr:  BUS Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1482                         return status;
1483                 }
1484         } else
1485                 info("bapr:  No BUS Resource on PCI 0x%x.\n", ab->bus);
1486
1487         if (ab->io_head) {
1488                 dbg("bapr:  IO Resources add on PCI 0x%x\n", ab->bus);
1489                 status = pciehprm_add_resources (&ctrl->io_head, ab->io_head);
1490                 if (pciehprm_delete_resources (&ab->io_head, ctrl->io_head))
1491                         warn("bapr:  cannot sub IO Resource on PCI 0x%x\n", ab->bus);
1492                 if (status) {
1493                         err("bapr:  IO Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1494                         return status;
1495                 }
1496         } else
1497                 info("bapr:  No  IO Resource on PCI 0x%x.\n", ab->bus);
1498
1499         if (ab->mem_head) {
1500                 dbg("bapr:  MEM Resources add on PCI 0x%x\n", ab->bus);
1501                 status = pciehprm_add_resources (&ctrl->mem_head, ab->mem_head);
1502                 if (pciehprm_delete_resources (&ab->mem_head, ctrl->mem_head))
1503                         warn("bapr:  cannot sub MEM Resource on PCI 0x%x\n", ab->bus);
1504                 if (status) {
1505                         err("bapr:  MEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1506                         return status;
1507                 }
1508         } else
1509                 info("bapr:  No MEM Resource on PCI 0x%x.\n", ab->bus);
1510
1511         if (ab->p_mem_head) {
1512                 dbg("bapr:  PMEM Resources add on PCI 0x%x\n", ab->bus);
1513                 status = pciehprm_add_resources (&ctrl->p_mem_head, ab->p_mem_head);
1514                 if (pciehprm_delete_resources (&ab->p_mem_head, ctrl->p_mem_head))
1515                         warn("bapr:  cannot sub PMEM Resource on PCI 0x%x\n", ab->bus);
1516                 if (status) {
1517                         err("bapr:  PMEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1518                         return status;
1519                 }
1520         } else
1521                 info("bapr:  No PMEM Resource on PCI 0x%x.\n", ab->bus);
1522
1523         return status;
1524 }
1525
1526 static int no_pci_resources( struct acpi_bridge *ab)
1527 {
1528         return !(ab->p_mem_head || ab->mem_head || ab->io_head || ab->bus_head);
1529 }
1530
1531 static int find_pci_bridge_resources (
1532         struct controller *ctrl,
1533         struct acpi_bridge *ab
1534         )
1535 {
1536         int     rc = 0;
1537         struct pci_func func;
1538
1539         memset(&func, 0, sizeof(struct pci_func));
1540
1541         func.bus = ab->pbus;
1542         func.device = ab->pdevice;
1543         func.function = ab->pfunction;
1544         func.is_a_board = 1;
1545
1546         /* Get used resources for this PCI bridge */
1547         rc = pciehp_save_used_resources (ctrl, &func, !DISABLE_CARD);
1548
1549         ab->io_head = func.io_head;
1550         ab->mem_head = func.mem_head;
1551         ab->p_mem_head = func.p_mem_head;
1552         ab->bus_head = func.bus_head;
1553         if (ab->bus_head)
1554                 pciehprm_delete_resource(&ab->bus_head, ctrl->pci_dev->subordinate->number, 1);
1555
1556         return rc;
1557 }
1558
1559 static int get_pci_resources_from_bridge(
1560         struct controller *ctrl,
1561         struct acpi_bridge *ab
1562         )
1563 {
1564         int     rc = 0;
1565
1566         dbg("grfb:  Get Resources for PCI 0x%x from actual PCI bridge 0x%x.\n", ctrl->bus, ab->bus);
1567
1568         rc = find_pci_bridge_resources (ctrl, ab);
1569
1570         pciehp_resource_sort_and_combine(&ab->bus_head);
1571         pciehp_resource_sort_and_combine(&ab->io_head);
1572         pciehp_resource_sort_and_combine(&ab->mem_head);
1573         pciehp_resource_sort_and_combine(&ab->p_mem_head);
1574
1575         pciehprm_add_resources (&ab->tbus_head, ab->bus_head);
1576         pciehprm_add_resources (&ab->tio_head, ab->io_head);
1577         pciehprm_add_resources (&ab->tmem_head, ab->mem_head);
1578         pciehprm_add_resources (&ab->tp_mem_head, ab->p_mem_head);
1579
1580         return rc;
1581 }
1582
1583 static int get_pci_resources(
1584         struct controller       *ctrl,
1585         struct acpi_bridge      *ab
1586         )
1587 {
1588         int     rc = 0;
1589
1590         if (no_pci_resources(ab)) {
1591                 dbg("spbr:PCI 0x%x has no resources. Get parent resources.\n", ab->bus);
1592                 rc = get_pci_resources_from_bridge(ctrl, ab);
1593         }
1594
1595         return rc;
1596 }
1597
1598 /*
1599  * Get resources for this ctrl.
1600  *  1. get total resources from ACPI _CRS or bridge (this ctrl)
1601  *  2. find used resources of existing adapters
1602  *      3. subtract used resources from total resources
1603  */
1604 int pciehprm_find_available_resources( struct controller *ctrl)
1605 {
1606         int rc = 0;
1607         struct acpi_bridge      *ab;
1608
1609         ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->pci_dev->subordinate->number);
1610         if (!ab) {
1611                 err("pfar:cannot locate acpi bridge of PCI 0x%x.\n", ctrl->pci_dev->subordinate->number);
1612                 return -1;
1613         }
1614         if (no_pci_resources(ab)) {
1615                 rc = get_pci_resources(ctrl, ab);
1616                 if (rc) {
1617                         err("pfar:cannot get pci resources of PCI 0x%x.\n", ctrl->pci_dev->subordinate->number);
1618                         return -1;
1619                 }
1620         }
1621
1622         rc = bind_pci_resources(ctrl, ab);
1623         dbg("pfar:pre-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number);
1624         pciehprm_dump_ctrl_res(ctrl);
1625
1626         bind_pci_resources_to_slots (ctrl);
1627
1628         dbg("pfar:post-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number);
1629         pciehprm_dump_ctrl_res(ctrl);
1630
1631         return rc;
1632 }
1633
1634 int pciehprm_set_hpp(
1635         struct controller *ctrl,
1636         struct pci_func *func,
1637         u8      card_type
1638         )
1639 {
1640         struct acpi_bridge      *ab;
1641         struct pci_bus lpci_bus, *pci_bus;
1642         int                             rc = 0;
1643         unsigned int    devfn;
1644         u8                              cls= 0x08;      /* default cache line size      */
1645         u8                              lt = 0x40;      /* default latency timer        */
1646         u8                              ep = 0;
1647         u8                              es = 0;
1648
1649         memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
1650         pci_bus = &lpci_bus;
1651         pci_bus->number = func->bus;
1652         devfn = PCI_DEVFN(func->device, func->function);
1653
1654         ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
1655
1656         if (ab) {
1657                 if (ab->_hpp) {
1658                         lt  = (u8)ab->_hpp->latency_timer;
1659                         cls = (u8)ab->_hpp->cache_line_size;
1660                         ep  = (u8)ab->_hpp->enable_perr;
1661                         es  = (u8)ab->_hpp->enable_serr;
1662                 } else
1663                         dbg("_hpp: no _hpp for B/D/F=%#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
1664         } else
1665                 dbg("_hpp: no acpi bridge for B/D/F = %#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
1666
1667
1668         if (card_type == PCI_HEADER_TYPE_BRIDGE) {
1669                 /* set subordinate Latency Timer */
1670                 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, lt);
1671         }
1672
1673         /* set base Latency Timer */
1674         rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, lt);
1675         dbg("  set latency timer  =0x%02x: %x\n", lt, rc);
1676
1677         rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, cls);
1678         dbg("  set cache_line_size=0x%02x: %x\n", cls, rc);
1679
1680         return rc;
1681 }
1682
1683 void pciehprm_enable_card(
1684         struct controller *ctrl,
1685         struct pci_func *func,
1686         u8 card_type)
1687 {
1688         u16 command, cmd, bcommand, bcmd;
1689         struct pci_bus lpci_bus, *pci_bus;
1690         struct acpi_bridge      *ab;
1691         unsigned int devfn;
1692         int rc;
1693
1694         memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
1695         pci_bus = &lpci_bus;
1696         pci_bus->number = func->bus;
1697         devfn = PCI_DEVFN(func->device, func->function);
1698
1699         rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &cmd);
1700
1701         if (card_type == PCI_HEADER_TYPE_BRIDGE) {
1702                 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcmd);
1703         }
1704
1705         command  = cmd | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
1706                 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
1707         bcommand  = bcmd | PCI_BRIDGE_CTL_NO_ISA;
1708
1709         ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
1710         if (ab) {
1711                 if (ab->_hpp) {
1712                         if (ab->_hpp->enable_perr) {
1713                                 command |= PCI_COMMAND_PARITY;
1714                                 bcommand |= PCI_BRIDGE_CTL_PARITY;
1715                         } else {
1716                                 command &= ~PCI_COMMAND_PARITY;
1717                                 bcommand &= ~PCI_BRIDGE_CTL_PARITY;
1718                         }
1719                         if (ab->_hpp->enable_serr) {
1720                                 command |= PCI_COMMAND_SERR;
1721                                 bcommand |= PCI_BRIDGE_CTL_SERR;
1722                         } else {
1723                                 command &= ~PCI_COMMAND_SERR;
1724                                 bcommand &= ~PCI_BRIDGE_CTL_SERR;
1725                         }
1726                 } else
1727                         dbg("no _hpp for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
1728         } else
1729                 dbg("no acpi bridge for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
1730
1731         if (command != cmd) {
1732                 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
1733         }
1734         if ((card_type == PCI_HEADER_TYPE_BRIDGE) && (bcommand != bcmd)) {
1735                 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
1736         }
1737 }