xref: /linux/drivers/pci/hotplug/shpchp_pci.c (revision 16dab54b8cbac39bd3f639db5d7d0fd8300a6cb0)
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>, <kristen.c.accardi@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 }
811