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