Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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 }
811 
  This page was automatically generated by the LXR engine.