ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / pci / hotplug / pciehp_pci.c
1 /*
2  * PCI Express Hot Plug Controller Driver
3  *
4  * Copyright (C) 1995,2001 Compaq Computer Corporation
5  * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6  * Copyright (C) 2001 IBM Corp.
7  * Copyright (C) 2003-2004 Intel Corporation
8  *
9  * All rights reserved.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or (at
14  * your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful, but
17  * WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19  * NON INFRINGEMENT.  See the GNU General Public License for more
20  * details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25  *
26  * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
27  *
28  */
29
30 #include <linux/config.h>
31 #include <linux/module.h>
32 #include <linux/kernel.h>
33 #include <linux/types.h>
34 #include <linux/slab.h>
35 #include <linux/workqueue.h>
36 #include <linux/proc_fs.h>
37 #include <linux/pci.h>
38 #include "../pci.h"
39 #include "pciehp.h"
40 #ifndef CONFIG_IA64
41 #include "../../../arch/i386/pci/pci.h"    /* horrible hack showing how processor dependant we are... */
42 #endif
43
44
45 int pciehp_configure_device (struct controller* ctrl, struct pci_func* func)  
46 {
47         unsigned char bus;
48         struct pci_bus *child;
49         int num;
50
51         if (func->pci_dev == NULL)
52                 func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
53
54         /* Still NULL ? Well then scan for it ! */
55         if (func->pci_dev == NULL) {
56                 dbg("%s: pci_dev still null. do pci_scan_slot\n", __FUNCTION__);
57
58                 num = pci_scan_slot(ctrl->pci_dev->subordinate, PCI_DEVFN(func->device, func->function));
59
60                 if (num)
61                         pci_bus_add_devices(ctrl->pci_dev->subordinate);
62                 
63                 func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
64                 if (func->pci_dev == NULL) {
65                         dbg("ERROR: pci_dev still null\n");
66                         return 0;
67                 }
68         }
69
70         if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
71                 pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus);
72                 child = (struct pci_bus*) pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus);
73                 pci_do_scan_bus(child);
74
75         }
76
77         return 0;
78 }
79
80
81 int pciehp_unconfigure_device(struct pci_func* func) 
82 {
83         int rc = 0;
84         int j;
85
86         dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus, func->device, func->function);
87
88         for (j=0; j<8 ; j++) {
89                 struct pci_dev* temp = pci_find_slot(func->bus, (func->device << 3) | j);
90                 if (temp) {
91                         pci_remove_bus_device(temp);
92                 }
93         }
94         return rc;
95 }
96
97 /*
98  * pciehp_set_irq
99  *
100  * @bus_num: bus number of PCI device
101  * @dev_num: device number of PCI device
102  * @slot: pointer to u8 where slot number will be returned
103  */
104 int pciehp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
105 {
106 #if defined(CONFIG_X86) && !defined(CONFIG_X86_IO_APIC) && !defined(CONFIG_X86_64)
107         int rc;
108         u16 temp_word;
109         struct pci_dev fakedev;
110         struct pci_bus fakebus;
111
112         fakedev.devfn = dev_num << 3;
113         fakedev.bus = &fakebus;
114         fakebus.number = bus_num;
115         dbg("%s: dev %d, bus %d, pin %d, num %d\n",
116             __FUNCTION__, dev_num, bus_num, int_pin, irq_num);
117         rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num);
118         dbg("%s: rc %d\n", __FUNCTION__, rc);
119         if (!rc)
120                 return !rc;
121
122         /* set the Edge Level Control Register (ELCR) */
123         temp_word = inb(0x4d0);
124         temp_word |= inb(0x4d1) << 8;
125
126         temp_word |= 0x01 << irq_num;
127
128         /* This should only be for x86 as it sets the Edge Level Control Register */
129         outb((u8) (temp_word & 0xFF), 0x4d0);
130         outb((u8) ((temp_word & 0xFF00) >> 8), 0x4d1);
131 #endif
132         return 0;
133 }
134
135 /* More PCI configuration routines; this time centered around hotplug controller */
136
137
138 /*
139  * pciehp_save_config
140  *
141  * Reads configuration for all slots in a PCI bus and saves info.
142  *
143  * Note:  For non-hot plug busses, the slot # saved is the device #
144  *
145  * returns 0 if success
146  */
147 int pciehp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num)
148 {
149         int rc;
150         u8 class_code;
151         u8 header_type;
152         u32 ID;
153         u8 secondary_bus;
154         struct pci_func *new_slot;
155         int sub_bus;
156         int max_functions;
157         int function;
158         u8 DevError;
159         int device = 0;
160         int cloop = 0;
161         int stop_it;
162         int index;
163         int is_hot_plug = num_ctlr_slots || first_device_num;
164         struct pci_bus lpci_bus, *pci_bus;
165         int FirstSupported, LastSupported;
166
167         dbg("%s: Enter\n", __FUNCTION__);
168
169         memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
170         pci_bus = &lpci_bus;
171
172         dbg("%s: num_ctlr_slots = %d, first_device_num = %d\n", __FUNCTION__, num_ctlr_slots, first_device_num);
173
174         /*   Decide which slots are supported */
175         if (is_hot_plug) {
176                 /*********************************
177                  *  is_hot_plug is the slot mask
178                  *********************************/
179                 FirstSupported = first_device_num;
180                 LastSupported = FirstSupported + num_ctlr_slots - 1;
181         } else {
182                 FirstSupported = 0;
183                 LastSupported = 0x1F;
184         }
185
186         dbg("FirstSupported = %d, LastSupported = %d\n", FirstSupported, LastSupported);
187
188         /*   Save PCI configuration space for all devices in supported slots */
189         dbg("%s: pci_bus->number = %x\n", __FUNCTION__, pci_bus->number);
190         pci_bus->number = busnumber;
191         dbg("%s: bus = %x, dev = %x\n", __FUNCTION__, busnumber, device);
192         for (device = FirstSupported; device <= LastSupported; device++) {
193                 ID = 0xFFFFFFFF;
194                 rc = pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);
195
196                 if (ID != 0xFFFFFFFF) {   /*  device in slot */
197                         dbg("%s: ID = %x\n", __FUNCTION__, ID);
198                         rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0), 0x0B, &class_code);
199                         if (rc)
200                                 return rc;
201
202                         rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0), PCI_HEADER_TYPE, &header_type);
203                         if (rc)
204                                 return rc;
205
206                         dbg("class_code = %x, header_type = %x\n", class_code, header_type);
207
208                         /* If multi-function device, set max_functions to 8 */
209                         if (header_type & 0x80)
210                                 max_functions = 8;
211                         else
212                                 max_functions = 1;
213
214                         function = 0;
215
216                         do {
217                                 DevError = 0;
218                                 dbg("%s: In do loop\n", __FUNCTION__);
219
220                                 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {   /* P-P Bridge */
221                                         /* Recurse the subordinate bus
222                                          * get the subordinate bus number
223                                          */
224                                         rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, function), 
225                                                 PCI_SECONDARY_BUS, &secondary_bus);
226                                         if (rc) {
227                                                 return rc;
228                                         } else {
229                                                 sub_bus = (int) secondary_bus;
230
231                                                 /* Save secondary bus cfg spc with this recursive call. */
232                                                 rc = pciehp_save_config(ctrl, sub_bus, 0, 0);
233                                                 if (rc)
234                                                         return rc;
235                                         }
236                                 }
237
238                                 index = 0;
239                                 new_slot = pciehp_slot_find(busnumber, device, index++);
240
241                                 dbg("%s: new_slot = %p bus %x dev %x fun %x\n",
242                                 __FUNCTION__, new_slot, busnumber, device, index-1);
243
244                                 while (new_slot && (new_slot->function != (u8) function)) {
245                                         new_slot = pciehp_slot_find(busnumber, device, index++);
246                                         dbg("%s: while loop, new_slot = %p bus %x dev %x fun %x\n",
247                                         __FUNCTION__, new_slot, busnumber, device, index-1);
248                                 }
249                                 if (!new_slot) {
250                                         /* Setup slot structure. */
251                                         new_slot = pciehp_slot_create(busnumber);
252                                         dbg("%s: if, new_slot = %p bus %x dev %x fun %x\n",
253                                         __FUNCTION__, new_slot, busnumber, device, function);
254
255                                         if (new_slot == NULL)
256                                                 return(1);
257                                 }
258
259                                 new_slot->bus = (u8) busnumber;
260                                 new_slot->device = (u8) device;
261                                 new_slot->function = (u8) function;
262                                 new_slot->is_a_board = 1;
263                                 new_slot->switch_save = 0x10;
264                                 /* In case of unsupported board */
265                                 new_slot->status = DevError;
266                                 new_slot->pci_dev = pci_find_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function);
267                                 dbg("new_slot->pci_dev = %p\n", new_slot->pci_dev);
268
269                                 for (cloop = 0; cloop < 0x20; cloop++) {
270                                         rc = pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, function), cloop << 2, 
271                                                 (u32 *) & (new_slot->config_space [cloop]));
272                                         /* dbg("new_slot->config_space[%x] = %x\n", cloop, new_slot->config_space[cloop]); */
273                                         if (rc)
274                                                 return rc;
275                                 }
276
277                                 function++;
278
279                                 stop_it = 0;
280
281                                 /*  this loop skips to the next present function
282                                  *  reading in Class Code and Header type.
283                                  */
284
285                                 while ((function < max_functions)&&(!stop_it)) {
286                                         dbg("%s: In while loop \n", __FUNCTION__);
287                                         rc = pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, function), PCI_VENDOR_ID, &ID);
288
289                                         if (ID == 0xFFFFFFFF) {  /* nothing there. */
290                                                 function++;
291                                                 dbg("Nothing there\n");
292                                         } else {  /* Something there */
293                                                 rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, function), 0x0B, 
294                                                         &class_code);
295                                                 if (rc)
296                                                         return rc;
297
298                                                 rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, function), PCI_HEADER_TYPE, 
299                                                         &header_type);
300                                                 if (rc)
301                                                         return rc;
302
303                                                 dbg("class_code = %x, header_type = %x\n", class_code, header_type);
304                                                 stop_it++;
305                                         }
306                                 }
307
308                         } while (function < max_functions);
309                 }               /* End of IF (device in slot?) */
310                 else if (is_hot_plug) {
311                         /* Setup slot structure with entry for empty slot */
312                         new_slot = pciehp_slot_create(busnumber);
313
314                         if (new_slot == NULL) {
315                                 return(1);
316                         }
317                         dbg("new_slot = %p, bus = %x, dev = %x, fun = %x\n", new_slot,
318                                 new_slot->bus, new_slot->device, new_slot->function);
319
320                         new_slot->bus = (u8) busnumber;
321                         new_slot->device = (u8) device;
322                         new_slot->function = 0;
323                         new_slot->is_a_board = 0;
324                         new_slot->presence_save = 0;
325                         new_slot->switch_save = 0;
326                 }
327         }                       /* End of FOR loop */
328
329         dbg("%s: Exit\n", __FUNCTION__);
330         return(0);
331 }
332
333
334 /*
335  * pciehp_save_slot_config
336  *
337  * Saves configuration info for all PCI devices in a given slot
338  * including subordinate busses.
339  *
340  * returns 0 if success
341  */
342 int pciehp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot)
343 {
344         int rc;
345         u8 class_code;
346         u8 header_type;
347         u32 ID;
348         u8 secondary_bus;
349         int sub_bus;
350         int max_functions;
351         int function;
352         int cloop = 0;
353         int stop_it;
354         struct pci_bus lpci_bus, *pci_bus;
355         memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
356         pci_bus = &lpci_bus;
357         pci_bus->number = new_slot->bus;
358
359         ID = 0xFFFFFFFF;
360
361         pci_bus_read_config_dword(pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_VENDOR_ID, &ID);
362
363         if (ID != 0xFFFFFFFF) {   /*  device in slot */
364                 pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0), 0x0B, &class_code);
365
366                 pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_HEADER_TYPE, &header_type);
367
368                 if (header_type & 0x80) /* Multi-function device */
369                         max_functions = 8;
370                 else
371                         max_functions = 1;
372
373                 function = 0;
374
375                 do {
376                         if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {     /* PCI-PCI Bridge */
377                                 /*  Recurse the subordinate bus */
378                                 pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, function), 
379                                         PCI_SECONDARY_BUS, &secondary_bus);
380
381                                 sub_bus = (int) secondary_bus;
382
383                                 /* Save the config headers for the secondary bus. */
384                                 rc = pciehp_save_config(ctrl, sub_bus, 0, 0);
385
386                                 if (rc)
387                                         return(rc);
388
389                         }       /* End of IF */
390
391                         new_slot->status = 0;
392
393                         for (cloop = 0; cloop < 0x20; cloop++) {
394                                 pci_bus_read_config_dword(pci_bus, PCI_DEVFN(new_slot->device, function), 
395                                         cloop << 2, (u32 *) & (new_slot->config_space [cloop]));
396                         }
397
398                         function++;
399
400                         stop_it = 0;
401
402                         /*  this loop skips to the next present function
403                          *  reading in the Class Code and the Header type.
404                          */
405
406                         while ((function < max_functions) && (!stop_it)) {
407                                 pci_bus_read_config_dword(pci_bus, PCI_DEVFN(new_slot->device, function), PCI_VENDOR_ID, &ID);
408
409                                 if (ID == 0xFFFFFFFF) {  /* nothing there. */
410                                         function++;
411                                 } else {  /* Something there */
412                                         pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, function), 0x0B, &class_code);
413
414                                         pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, function), PCI_HEADER_TYPE, 
415                                                 &header_type);
416
417                                         stop_it++;
418                                 }
419                         }
420
421                 } while (function < max_functions);
422         }                       /* End of IF (device in slot?) */
423         else {
424                 return(2);
425         }
426
427         return(0);
428 }
429
430
431 /*
432  * pciehp_save_used_resources
433  *
434  * Stores used resource information for existing boards.  this is
435  * for boards that were in the system when this driver was loaded.
436  * this function is for hot plug ADD
437  *
438  * returns 0 if success
439  * if disable  == 1(DISABLE_CARD),
440  *  it loops for all functions of the slot and disables them.
441  * else, it just get resources of the function and return.
442  */
443 int pciehp_save_used_resources (struct controller *ctrl, struct pci_func *func, int disable)
444 {
445         u8 cloop;
446         u8 header_type;
447         u8 secondary_bus;
448         u8 temp_byte;
449         u16 command;
450         u16 save_command;
451         u16 w_base, w_length;
452         u32 temp_register;
453         u32 save_base;
454         u32 base, length;
455         u64 base64 = 0;
456         int index = 0;
457         unsigned int devfn;
458         struct pci_resource *mem_node = NULL;
459         struct pci_resource *p_mem_node = NULL;
460         struct pci_resource *t_mem_node;
461         struct pci_resource *io_node;
462         struct pci_resource *bus_node;
463         struct pci_bus lpci_bus, *pci_bus;
464         memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
465         pci_bus = &lpci_bus;
466
467         if (disable)
468                 func = pciehp_slot_find(func->bus, func->device, index++);
469
470         while ((func != NULL) && func->is_a_board) {
471                 pci_bus->number = func->bus;
472                 devfn = PCI_DEVFN(func->device, func->function);
473
474                 /* Save the command register */
475                 pci_bus_read_config_word (pci_bus, devfn, PCI_COMMAND, &save_command);
476
477                 if (disable) {
478                         /* disable card */
479                         command = 0x00;
480                         pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
481                 }
482
483                 /* Check for Bridge */
484                 pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
485
486                 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {     /* PCI-PCI Bridge */
487                         dbg("Save_used_res of PCI bridge b:d=0x%x:%x, sc=0x%x\n", func->bus, func->device, save_command);
488                         if (disable) {
489                                 /* Clear Bridge Control Register */
490                                 command = 0x00;
491                                 pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
492                         }
493
494                         pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
495                         pci_bus_read_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, &temp_byte);
496
497                         bus_node =(struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
498                         if (!bus_node)
499                                 return -ENOMEM;
500
501                         bus_node->base = (ulong)secondary_bus;
502                         bus_node->length = (ulong)(temp_byte - secondary_bus + 1);
503
504                         bus_node->next = func->bus_head;
505                         func->bus_head = bus_node;
506
507                         /* Save IO base and Limit registers */
508                         pci_bus_read_config_byte (pci_bus, devfn, PCI_IO_BASE, &temp_byte);
509                         base = temp_byte;
510                         pci_bus_read_config_byte (pci_bus, devfn, PCI_IO_LIMIT, &temp_byte);
511                         length = temp_byte;
512
513                         if ((base <= length) && (!disable || (save_command & PCI_COMMAND_IO))) {
514                                 io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
515                                 if (!io_node)
516                                         return -ENOMEM;
517
518                                 io_node->base = (ulong)(base & PCI_IO_RANGE_MASK) << 8;
519                                 io_node->length = (ulong)(length - base + 0x10) << 8;
520
521                                 io_node->next = func->io_head;
522                                 func->io_head = io_node;
523                         }
524
525                         /* Save memory base and Limit registers */
526                         pci_bus_read_config_word (pci_bus, devfn, PCI_MEMORY_BASE, &w_base);
527                         pci_bus_read_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length);
528
529                         if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
530                                 mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
531                                 if (!mem_node)
532                                         return -ENOMEM;
533
534                                 mem_node->base = (ulong)w_base << 16;
535                                 mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
536
537                                 mem_node->next = func->mem_head;
538                                 func->mem_head = mem_node;
539                         }
540                         /* Save prefetchable memory base and Limit registers */
541                         pci_bus_read_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base);
542                         pci_bus_read_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length);
543
544                         if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
545                                 p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
546                                 if (!p_mem_node)
547                                         return -ENOMEM;
548
549                                 p_mem_node->base = (ulong)w_base << 16;
550                                 p_mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
551
552                                 p_mem_node->next = func->p_mem_head;
553                                 func->p_mem_head = p_mem_node;
554                         }
555                 } else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
556                         dbg("Save_used_res of PCI adapter b:d=0x%x:%x, sc=0x%x\n", func->bus, func->device, save_command);
557
558                         /* Figure out IO and memory base lengths */
559                         for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) {
560                                 pci_bus_read_config_dword (pci_bus, devfn, cloop, &save_base);
561
562                                 temp_register = 0xFFFFFFFF;
563                                 pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
564                                 pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp_register);
565
566                                 if (!disable) {
567                                         pci_bus_write_config_dword (pci_bus, devfn, cloop, save_base);
568                                 }
569
570                                 if (!temp_register)
571                                         continue;
572
573                                 base = temp_register;
574
575                                 if ((base & PCI_BASE_ADDRESS_SPACE_IO) && (!disable || (save_command & PCI_COMMAND_IO))) {
576                                         /* IO base */
577                                         /* set temp_register = amount of IO space requested */
578                                         base = base & 0xFFFFFFFCL;
579                                         base = (~base) + 1;
580
581                                         io_node = (struct pci_resource *) kmalloc(sizeof (struct pci_resource), GFP_KERNEL);
582                                         if (!io_node)
583                                                 return -ENOMEM;
584
585                                         io_node->base = (ulong)save_base & PCI_BASE_ADDRESS_IO_MASK;
586                                         io_node->length = (ulong)base;
587                                         dbg("sur adapter: IO bar=0x%x(length=0x%x)\n", io_node->base, io_node->length);
588
589                                         io_node->next = func->io_head;
590                                         func->io_head = io_node;
591                                 } else {  /* map Memory */
592                                         int prefetchable = 1;
593                                         /* struct pci_resources **res_node; */
594                                         char *res_type_str = "PMEM";
595                                         u32 temp_register2;
596
597                                         t_mem_node = (struct pci_resource *) kmalloc(sizeof (struct pci_resource), GFP_KERNEL);
598                                         if (!t_mem_node)
599                                                 return -ENOMEM;
600
601                                         if (!(base & PCI_BASE_ADDRESS_MEM_PREFETCH) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
602                                                 prefetchable = 0;
603                                                 mem_node = t_mem_node;
604                                                 res_type_str++;
605                                         } else
606                                                 p_mem_node = t_mem_node;
607
608                                         base = base & 0xFFFFFFF0L;
609                                         base = (~base) + 1;
610
611                                         switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
612                                         case PCI_BASE_ADDRESS_MEM_TYPE_32:
613                                                 if (prefetchable) {
614                                                         p_mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
615                                                         p_mem_node->length = (ulong)base;
616                                                         dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n", res_type_str, 
617                                                                 p_mem_node->base, p_mem_node->length);
618
619                                                         p_mem_node->next = func->p_mem_head;
620                                                         func->p_mem_head = p_mem_node;
621                                                 } else {
622                                                         mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
623                                                         mem_node->length = (ulong)base;
624                                                         dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n", res_type_str, 
625                                                                 mem_node->base, mem_node->length);
626
627                                                         mem_node->next = func->mem_head;
628                                                         func->mem_head = mem_node;
629                                                 }
630                                                 break;
631                                         case PCI_BASE_ADDRESS_MEM_TYPE_64:
632                                                 pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2);
633                                                 base64 = temp_register2;
634                                                 base64 = (base64 << 32) | save_base;
635
636                                                 if (temp_register2) {
637                                                         dbg("sur adapter: 64 %s high dword of base64(0x%x:%x) masked to 0\n", 
638                                                                 res_type_str, temp_register2, (u32)base64);
639                                                         base64 &= 0x00000000FFFFFFFFL;
640                                                 }
641
642                                                 if (prefetchable) {
643                                                         p_mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
644                                                         p_mem_node->length = base;
645                                                         dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n", res_type_str, 
646                                                                 p_mem_node->base, p_mem_node->length);
647
648                                                         p_mem_node->next = func->p_mem_head;
649                                                         func->p_mem_head = p_mem_node;
650                                                 } else {
651                                                         mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
652                                                         mem_node->length = base;
653                                                         dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n", res_type_str, 
654                                                                 mem_node->base, mem_node->length);
655
656                                                         mem_node->next = func->mem_head;
657                                                         func->mem_head = mem_node;
658                                                 }
659                                                 cloop += 4;
660                                                 break;
661                                         default:
662                                                 dbg("asur: reserved BAR type=0x%x\n", temp_register);
663                                                 break;
664                                         }
665                                 } 
666                         }       /* End of base register loop */
667                 } else {        /* Some other unknown header type */
668                         dbg("Save_used_res of PCI unknown type b:d=0x%x:%x. skip.\n", func->bus, func->device);
669                 }
670
671                 /* find the next device in this slot */
672                 if (!disable)
673                         break;
674                 func = pciehp_slot_find(func->bus, func->device, index++);
675         }
676
677         return(0);
678 }
679
680
681 /*
682  * pciehp_return_board_resources
683  *
684  * this routine returns all resources allocated to a board to
685  * the available pool.
686  *
687  * returns 0 if success
688  */
689 int pciehp_return_board_resources(struct pci_func * func, struct resource_lists * resources)
690 {
691         int rc = 0;
692         struct pci_resource *node;
693         struct pci_resource *t_node;
694         dbg("%s\n", __FUNCTION__);
695
696         if (!func)
697                 return(1);
698
699         node = func->io_head;
700         func->io_head = NULL;
701         while (node) {
702                 t_node = node->next;
703                 return_resource(&(resources->io_head), node);
704                 node = t_node;
705         }
706
707         node = func->mem_head;
708         func->mem_head = NULL;
709         while (node) {
710                 t_node = node->next;
711                 return_resource(&(resources->mem_head), node);
712                 node = t_node;
713         }
714
715         node = func->p_mem_head;
716         func->p_mem_head = NULL;
717         while (node) {
718                 t_node = node->next;
719                 return_resource(&(resources->p_mem_head), node);
720                 node = t_node;
721         }
722
723         node = func->bus_head;
724         func->bus_head = NULL;
725         while (node) {
726                 t_node = node->next;
727                 return_resource(&(resources->bus_head), node);
728                 node = t_node;
729         }
730
731         rc |= pciehp_resource_sort_and_combine(&(resources->mem_head));
732         rc |= pciehp_resource_sort_and_combine(&(resources->p_mem_head));
733         rc |= pciehp_resource_sort_and_combine(&(resources->io_head));
734         rc |= pciehp_resource_sort_and_combine(&(resources->bus_head));
735
736         return(rc);
737 }
738
739
740 /*
741  * pciehp_destroy_resource_list
742  *
743  * Puts node back in the resource list pointed to by head
744  */
745 void pciehp_destroy_resource_list (struct resource_lists * resources)
746 {
747         struct pci_resource *res, *tres;
748
749         res = resources->io_head;
750         resources->io_head = NULL;
751
752         while (res) {
753                 tres = res;
754                 res = res->next;
755                 kfree(tres);
756         }
757
758         res = resources->mem_head;
759         resources->mem_head = NULL;
760
761         while (res) {
762                 tres = res;
763                 res = res->next;
764                 kfree(tres);
765         }
766
767         res = resources->p_mem_head;
768         resources->p_mem_head = NULL;
769
770         while (res) {
771                 tres = res;
772                 res = res->next;
773                 kfree(tres);
774         }
775
776         res = resources->bus_head;
777         resources->bus_head = NULL;
778
779         while (res) {
780                 tres = res;
781                 res = res->next;
782                 kfree(tres);
783         }
784 }
785
786
787 /*
788  * pciehp_destroy_board_resources
789  *
790  * Puts node back in the resource list pointed to by head
791  */
792 void pciehp_destroy_board_resources (struct pci_func * func)
793 {
794         struct pci_resource *res, *tres;
795
796         res = func->io_head;
797         func->io_head = NULL;
798
799         while (res) {
800                 tres = res;
801                 res = res->next;
802                 kfree(tres);
803         }
804
805         res = func->mem_head;
806         func->mem_head = NULL;
807
808         while (res) {
809                 tres = res;
810                 res = res->next;
811                 kfree(tres);
812         }
813
814         res = func->p_mem_head;
815         func->p_mem_head = NULL;
816
817         while (res) {
818                 tres = res;
819                 res = res->next;
820                 kfree(tres);
821         }
822
823         res = func->bus_head;
824         func->bus_head = NULL;
825
826         while (res) {
827                 tres = res;
828                 res = res->next;
829                 kfree(tres);
830         }
831 }
832