root/arch/i386/kernel/bios32.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bios32_service
  2. pcibios_init
  3. pcibios_present
  4. pcibios_find_class
  5. pcibios_find_device
  6. pcibios_read_config_byte
  7. pcibios_read_config_word
  8. pcibios_read_config_dword
  9. pcibios_write_config_byte
  10. pcibios_write_config_word
  11. pcibios_write_config_dword
  12. NCR53c810_test
  13. pcibios_strerror
  14. multi_function
  15. interrupt_decode
  16. bist_probe
  17. revision_decode
  18. class_decode
  19. device_decode
  20. vendor_decode
  21. probe_devices
  22. probe_pci
  23. add_pci_resource
  24. get_pci_list
  25. bios32_init

   1 /*
   2  * bios32.c - BIOS32, PCI BIOS functions.
   3  *
   4  * Sponsored by
   5  *      iX Multiuser Multitasking Magazine
   6  *      Hannover, Germany
   7  *      hm@ix.de
   8  *
   9  * Copyright 1993, 1994 Drew Eckhardt
  10  *      Visionary Computing
  11  *      (Unix and Linux consulting and custom programming)
  12  *      Drew@Colorado.EDU
  13  *      +1 (303) 786-7975
  14  *
  15  * Pciprobe added by Frederic Potter 1994
  16  *      Potter@Cao-Vlsi.Ibp.FR
  17  *
  18  *
  19  * For more information, please consult
  20  *
  21  * PCI BIOS Specification Revision
  22  * PCI Local Bus Specification
  23  * PCI System Design Guide
  24  *
  25  * PCI Special Interest Group
  26  * M/S HF3-15A
  27  * 5200 N.E. Elam Young Parkway
  28  * Hillsboro, Oregon 97124-6497
  29  * +1 (503) 696-2000
  30  * +1 (800) 433-5177
  31  *
  32  * Manuals are $25 each or $50 for all three, plus $7 shipping
  33  * within the United States, $35 abroad.
  34  *
  35  *
  36  * CHANGELOG :
  37  * Jun 17, 1994 : Modified to accommodate the broken pre-PCI BIOS SPECIFICATION
  38  *      Revision 2.0 present on <thys@dennis.ee.up.ac.za>'s ASUS mainboard.
  39  *
  40  * Jan 10, 1995 : Modified to store the information about configured pci
  41  *      devices into a list, which can be accessed via /proc/pci by
  42  *      Curtis Varner, cvarner@cs.ucr.edu
  43  */
  44 
  45 #include <linux/config.h>
  46 #include <linux/types.h>
  47 #include <linux/kernel.h>
  48 #include <linux/bios32.h>
  49 #include <linux/pci.h>
  50 
  51 #include <asm/segment.h>
  52 
  53 #define PCIBIOS_PCI_FUNCTION_ID         0xb1XX
  54 #define PCIBIOS_PCI_BIOS_PRESENT        0xb101
  55 #define PCIBIOS_FIND_PCI_DEVICE         0xb102
  56 #define PCIBIOS_FIND_PCI_CLASS_CODE     0xb103
  57 #define PCIBIOS_GENERATE_SPECIAL_CYCLE  0xb106
  58 #define PCIBIOS_READ_CONFIG_BYTE        0xb108
  59 #define PCIBIOS_READ_CONFIG_WORD        0xb109
  60 #define PCIBIOS_READ_CONFIG_DWORD       0xb10a
  61 #define PCIBIOS_WRITE_CONFIG_BYTE       0xb10b
  62 #define PCIBIOS_WRITE_CONFIG_WORD       0xb10c
  63 #define PCIBIOS_WRITE_CONFIG_DWORD      0xb10d
  64 
  65 #ifdef CONFIG_PCI
  66 extern void add_pci_resource(unsigned char, unsigned char);
  67 #endif
  68 
  69 /* BIOS32 signature: "_32_" */
  70 #define BIOS32_SIGNATURE        (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24))
  71 
  72 /* PCI signature: "PCI " */
  73 #define PCI_SIGNATURE           (('P' << 0) + ('C' << 8) + ('I' << 16) + (' ' << 24))
  74 
  75 /* PCI service signature: "$PCI" */
  76 #define PCI_SERVICE             (('$' << 0) + ('P' << 8) + ('C' << 16) + ('I' << 24))
  77 
  78 /*
  79  * This is the standard structure used to identify the entry point
  80  * to the BIOS32 Service Directory, as documented in
  81  *      Standard BIOS 32-bit Service Directory Proposal
  82  *      Revision 0.4 May 24, 1993
  83  *      Phoenix Technologies Ltd.
  84  *      Norwood, MA
  85  * and the PCI BIOS specification.
  86  */
  87 
  88 #ifdef CONFIG_PCI
  89 typedef struct pci_resource_t
  90 {
  91    unsigned char bus;
  92    unsigned char dev_fn;
  93    struct pci_resource_t *next;
  94 } pci_resource_t;
  95 #endif
  96 
  97 union bios32 {
  98         struct {
  99                 unsigned long signature;        /* _32_ */
 100                 unsigned long entry;            /* 32 bit physical address */
 101                 unsigned char revision;         /* Revision level, 0 */
 102                 unsigned char length;           /* Length in paragraphs should be 01 */
 103                 unsigned char checksum;         /* All bytes must add up to zero */
 104                 unsigned char reserved[5];      /* Must be zero */
 105         } fields;
 106         char chars[16];
 107 };
 108 
 109 /*
 110  * Physical address of the service directory.  I don't know if we're
 111  * allowed to have more than one of these or not, so just in case
 112  * we'll make bios32_init() take a memory start parameter and store
 113  * the array there.
 114  */
 115 
 116 static unsigned long bios32_entry = 0;
 117 static struct {
 118         unsigned long address;
 119         unsigned short segment;
 120 } bios32_indirect = { 0, KERNEL_CS };
 121 
 122 #ifdef CONFIG_PCI
 123 /*
 124  * Returns the entry point for the given service, NULL on error
 125  */
 126 
 127 #define PCI_LIST_SIZE 32
 128 
 129 static pci_resource_t pci_list = { 0, 0, NULL };
 130 static int pci_index = 0;
 131 static pci_resource_t pci_table[PCI_LIST_SIZE];
 132 
 133 static unsigned long bios32_service(unsigned long service)
     /* [previous][next][first][last][top][bottom][index][help] */
 134 {
 135         unsigned char return_code;      /* %al */
 136         unsigned long address;          /* %ebx */
 137         unsigned long length;           /* %ecx */
 138         unsigned long entry;            /* %edx */
 139 
 140         __asm__("lcall (%%edi)"
 141                 : "=a" (return_code),
 142                   "=b" (address),
 143                   "=c" (length),
 144                   "=d" (entry)
 145                 : "0" (service),
 146                   "1" (0),
 147                   "D" (&bios32_indirect));
 148 
 149         switch (return_code) {
 150                 case 0:
 151                         return address + entry;
 152                 case 0x80:      /* Not present */
 153                         printk("bios32_service(%ld) : not present\n", service);
 154                         return 0;
 155                 default: /* Shouldn't happen */
 156                         printk("bios32_service(%ld) : returned 0x%x, mail drew@colorado.edu\n",
 157                                 service, return_code);
 158                         return 0;
 159         }
 160 }
 161 
 162 static long pcibios_entry = 0;
 163 static struct {
 164         unsigned long address;
 165         unsigned short segment;
 166 } pci_indirect = { 0, KERNEL_CS };
 167 
 168 void NCR53c810_test(void);
 169 
 170 static unsigned long pcibios_init(unsigned long memory_start, unsigned long memory_end)
     /* [previous][next][first][last][top][bottom][index][help] */
 171 {
 172         unsigned long signature;
 173         unsigned char present_status;
 174         unsigned char major_revision;
 175         unsigned char minor_revision;
 176         int pack;
 177 
 178         if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
 179                 pci_indirect.address = pcibios_entry;
 180 
 181                 __asm__("lcall (%%edi)\n\t"
 182                         "jc 1f\n\t"
 183                         "xor %%ah, %%ah\n"
 184                         "1:\tshl $8, %%eax\n\t"
 185                         "movw %%bx, %%ax"
 186                         : "=d" (signature),
 187                           "=a" (pack)
 188                         : "1" (PCIBIOS_PCI_BIOS_PRESENT),
 189                           "D" (&pci_indirect)
 190                         : "bx", "cx");
 191 
 192                 present_status = (pack >> 16) & 0xff;
 193                 major_revision = (pack >> 8) & 0xff;
 194                 minor_revision = pack & 0xff;
 195                 if (present_status || (signature != PCI_SIGNATURE)) {
 196                         printk ("pcibios_init : %s : BIOS32 Service Directory says PCI BIOS is present,\n"
 197                                 "       but PCI_BIOS_PRESENT subfunction fails with present status of 0x%x\n"
 198                                 "       and signature of 0x%08lx (%c%c%c%c).  mail drew@Colorado.EDU\n",
 199                                 (signature == PCI_SIGNATURE) ?  "WARNING" : "ERROR",
 200                                 present_status, signature,
 201                                 (char) (signature >>  0), (char) (signature >>  8),
 202                                 (char) (signature >> 16), (char) (signature >> 24));
 203 
 204                         if (signature != PCI_SIGNATURE)
 205                                 pcibios_entry = 0;
 206                 }
 207                 if (pcibios_entry) {
 208                         printk ("pcibios_init : PCI BIOS revision %x.%02x entry at 0x%lx\n",
 209                                 major_revision, minor_revision, pcibios_entry);
 210                 }
 211         }
 212 
 213 #if 0
 214         NCR53c810_test();
 215 #endif
 216         return memory_start;
 217 }
 218 
 219 int pcibios_present(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 220 {
 221         return pcibios_entry ? 1 : 0;
 222 }
 223 
 224 int pcibios_find_class (unsigned long class_code, unsigned short index,
     /* [previous][next][first][last][top][bottom][index][help] */
 225         unsigned char *bus, unsigned char *device_fn)
 226 {
 227         unsigned long bx;
 228         unsigned long ret;
 229 
 230         __asm__ ("lcall (%%edi)\n\t"
 231                 "jc 1f\n\t"
 232                 "xor %%ah, %%ah\n"
 233                 "1:"
 234                 : "=b" (bx),
 235                   "=a" (ret)
 236                 : "1" (PCIBIOS_FIND_PCI_CLASS_CODE),
 237                   "c" (class_code),
 238                   "S" ((int) index),
 239                   "D" (&pci_indirect));
 240         *bus = (bx >> 8) & 0xff;
 241         *device_fn = bx & 0xff;
 242         return (int) (ret & 0xff00) >> 8;
 243 }
 244 
 245 
 246 int pcibios_find_device (unsigned short vendor, unsigned short device_id,
     /* [previous][next][first][last][top][bottom][index][help] */
 247         unsigned short index, unsigned char *bus, unsigned char *device_fn)
 248 {
 249         unsigned short bx;
 250         unsigned short ret;
 251 
 252         __asm__("lcall (%%edi)\n\t"
 253                 "jc 1f\n\t"
 254                 "xor %%ah, %%ah\n"
 255                 "1:"
 256                 : "=b" (bx),
 257                   "=a" (ret)
 258                 : "1" (PCIBIOS_FIND_PCI_DEVICE),
 259                   "c" (device_id),
 260                   "d" (vendor),
 261                   "S" ((int) index),
 262                   "D" (&pci_indirect));
 263         *bus = (bx >> 8) & 0xff;
 264         *device_fn = bx & 0xff;
 265         return (int) (ret & 0xff00) >> 8;
 266 }
 267 
 268 int pcibios_read_config_byte(unsigned char bus,
     /* [previous][next][first][last][top][bottom][index][help] */
 269         unsigned char device_fn, unsigned char where, unsigned char *value)
 270 {
 271         unsigned long ret;
 272         unsigned long bx = (bus << 8) | device_fn;
 273 
 274         __asm__("lcall (%%esi)\n\t"
 275                 "jc 1f\n\t"
 276                 "xor %%ah, %%ah\n"
 277                 "1:"
 278                 : "=c" (*value),
 279                   "=a" (ret)
 280                 : "1" (PCIBIOS_READ_CONFIG_BYTE),
 281                   "b" (bx),
 282                   "D" ((long) where),
 283                   "S" (&pci_indirect));
 284         return (int) (ret & 0xff00) >> 8;
 285 }
 286 
 287 int pcibios_read_config_word (unsigned char bus,
     /* [previous][next][first][last][top][bottom][index][help] */
 288         unsigned char device_fn, unsigned char where, unsigned short *value)
 289 {
 290         unsigned long ret;
 291         unsigned long bx = (bus << 8) | device_fn;
 292 
 293         __asm__("lcall (%%esi)\n\t"
 294                 "jc 1f\n\t"
 295                 "xor %%ah, %%ah\n"
 296                 "1:"
 297                 : "=c" (*value),
 298                   "=a" (ret)
 299                 : "1" (PCIBIOS_READ_CONFIG_WORD),
 300                   "b" (bx),
 301                   "D" ((long) where),
 302                   "S" (&pci_indirect));
 303         return (int) (ret & 0xff00) >> 8;
 304 }
 305 
 306 int pcibios_read_config_dword (unsigned char bus,
     /* [previous][next][first][last][top][bottom][index][help] */
 307         unsigned char device_fn, unsigned char where, unsigned long *value)
 308 {
 309         unsigned long ret;
 310         unsigned long bx = (bus << 8) | device_fn;
 311 
 312         __asm__("lcall (%%esi)\n\t"
 313                 "jc 1f\n\t"
 314                 "xor %%ah, %%ah\n"
 315                 "1:"
 316                 : "=c" (*value),
 317                   "=a" (ret)
 318                 : "1" (PCIBIOS_READ_CONFIG_DWORD),
 319                   "b" (bx),
 320                   "D" ((long) where),
 321                   "S" (&pci_indirect));
 322         return (int) (ret & 0xff00) >> 8;
 323 }
 324 
 325 int pcibios_write_config_byte (unsigned char bus,
     /* [previous][next][first][last][top][bottom][index][help] */
 326         unsigned char device_fn, unsigned char where, unsigned char value)
 327 {
 328         unsigned long ret;
 329         unsigned long bx = (bus << 8) | device_fn;
 330 
 331         __asm__("lcall (%%esi)\n\t"
 332                 "jc 1f\n\t"
 333                 "xor %%ah, %%ah\n"
 334                 "1:"
 335                 : "=a" (ret)
 336                 : "0" (PCIBIOS_WRITE_CONFIG_BYTE),
 337                   "c" (value),
 338                   "b" (bx),
 339                   "D" ((long) where),
 340                   "S" (&pci_indirect));
 341         return (int) (ret & 0xff00) >> 8;
 342 }
 343 
 344 int pcibios_write_config_word (unsigned char bus,
     /* [previous][next][first][last][top][bottom][index][help] */
 345         unsigned char device_fn, unsigned char where, unsigned short value)
 346 {
 347         unsigned long ret;
 348         unsigned long bx = (bus << 8) | device_fn;
 349 
 350         __asm__("lcall (%%esi)\n\t"
 351                 "jc 1f\n\t"
 352                 "xor %%ah, %%ah\n"
 353                 "1:"
 354                 : "=a" (ret)
 355                 : "0" (PCIBIOS_WRITE_CONFIG_WORD),
 356                   "c" (value),
 357                   "b" (bx),
 358                   "D" ((long) where),
 359                   "S" (&pci_indirect));
 360         return (int) (ret & 0xff00) >> 8;
 361 }
 362 
 363 int pcibios_write_config_dword (unsigned char bus,
     /* [previous][next][first][last][top][bottom][index][help] */
 364         unsigned char device_fn, unsigned char where, unsigned long value)
 365 {
 366         unsigned long ret;
 367         unsigned long bx = (bus << 8) | device_fn;
 368 
 369         __asm__("lcall (%%esi)\n\t"
 370                 "jc 1f\n\t"
 371                 "xor %%ah, %%ah\n"
 372                 "1:"
 373                 : "=a" (ret)
 374                 : "0" (PCIBIOS_WRITE_CONFIG_DWORD),
 375                   "c" (value),
 376                   "b" (bx),
 377                   "D" ((long) where),
 378                   "S" (&pci_indirect));
 379         return (int) (ret & 0xff00) >> 8;
 380 }
 381 
 382 void NCR53c810_test(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 383 {
 384         unsigned char bus, device_fn;
 385         unsigned short index;
 386         int ret;
 387         unsigned char row, col;
 388         unsigned long val;
 389 
 390         for (index = 0; index < 4; ++index) {
 391                 ret = pcibios_find_device (
 392                         (unsigned short) PCI_VENDOR_ID_NCR,
 393                         (unsigned short) PCI_DEVICE_ID_NCR_53C810,
 394                         index, &bus, &device_fn);
 395                 if (ret)
 396                         break;
 397                 printk ("ncr53c810 : at PCI bus %d, device %d, function %d.",
 398                         bus, ((device_fn & 0xf8) >> 3), (device_fn & 7));
 399                 for (row = 0; row < 0x3c; row += 0x10) {
 400                         printk ("\n     reg 0x%02x      ", row);
 401                         for (col = 0; col < 0x10; col += 4) {
 402                         if (!(ret = pcibios_read_config_dword (bus, device_fn, row+col, &val)))
 403                                 printk ("0x%08lx          ", val);
 404                         else
 405                                 printk ("error 0x%02x ", ret);
 406                         }
 407                 }
 408                 printk ("\n");
 409         }
 410 }
 411 
 412 char *pcibios_strerror (int error)
     /* [previous][next][first][last][top][bottom][index][help] */
 413 {
 414         static char buf[80];
 415 
 416         switch (error) {
 417                 case PCIBIOS_SUCCESSFUL:
 418                         return "SUCCESSFUL";
 419 
 420                 case PCIBIOS_FUNC_NOT_SUPPORTED:
 421                         return "FUNC_NOT_SUPPORTED";
 422 
 423                 case PCIBIOS_BAD_VENDOR_ID:
 424                         return "SUCCESSFUL";
 425 
 426                 case PCIBIOS_DEVICE_NOT_FOUND:
 427                         return "DEVICE_NOT_FOUND";
 428 
 429                 case PCIBIOS_BAD_REGISTER_NUMBER:
 430                         return "BAD_REGISTER_NUMBER";
 431 
 432                 default:
 433                         sprintf (buf, "UNKNOWN RETURN 0x%x", error);
 434                         return buf;
 435         }
 436 }
 437 
 438 
 439 /* Recognize multi-function device */
 440 
 441 int multi_function(unsigned char bus,unsigned char dev_fn)
     /* [previous][next][first][last][top][bottom][index][help] */
 442 {
 443         unsigned char header;
 444                 pcibios_read_config_byte(
 445                         bus, dev_fn, (unsigned char) PCI_HEADER_TYPE, &header);
 446                 return (header&7==7);
 447 }
 448 
 449 /* Returns Interrupt register */
 450 
 451 int interrupt_decode(unsigned char bus,unsigned char dev_fn)
     /* [previous][next][first][last][top][bottom][index][help] */
 452 {
 453         unsigned char interrupt;
 454                 pcibios_read_config_byte(
 455                         bus, dev_fn, (unsigned char) PCI_INTERRUPT_LINE, &interrupt);
 456                 if (interrupt>16) return 0;
 457                 return interrupt;
 458 }
 459 
 460 /* probe for being bist capable */
 461 
 462 int bist_probe(unsigned char bus,unsigned char dev_fn)
     /* [previous][next][first][last][top][bottom][index][help] */
 463 {
 464         unsigned char           bist;
 465                 pcibios_read_config_byte(
 466                         bus, dev_fn, (unsigned char) PCI_BIST, &bist);
 467                 return (bist & PCI_BIST_CAPABLE !=0);
 468 }
 469 
 470 
 471 /* Get the chip revision */
 472 
 473 int revision_decode(unsigned char bus,unsigned char dev_fn)
     /* [previous][next][first][last][top][bottom][index][help] */
 474 {
 475         unsigned char           revision;
 476                 pcibios_read_config_byte(
 477                         bus, dev_fn, (unsigned char) PCI_CLASS_REVISION, &revision);
 478                 return (int) revision;
 479 }
 480 
 481 
 482 
 483 /* Gives the Class code using the 16 higher bits */
 484 /* of the PCI_CLASS_REVISION configuration register */
 485 
 486 int class_decode(unsigned char bus,unsigned char dev_fn)
     /* [previous][next][first][last][top][bottom][index][help] */
 487 {
 488         struct pci_class_type   pci_class[PCI_CLASS_NUM+1] = PCI_CLASS_TYPE;
 489         int                     i;
 490         unsigned long           class;
 491                 pcibios_read_config_dword(
 492                         bus, dev_fn, (unsigned char) PCI_CLASS_REVISION, &class);
 493                 class=class >> 16;
 494                 for (i=0;i<PCI_CLASS_NUM;i++)
 495                         if (class==pci_class[i].class_id) break;
 496                 return i;
 497 }
 498 
 499 
 500 int device_decode(unsigned char bus,unsigned char dev_fn,unsigned short vendor)
     /* [previous][next][first][last][top][bottom][index][help] */
 501 {
 502         struct pci_device_type  pci_device[PCI_DEVICE_NUM+1] = PCI_DEVICE_TYPE;
 503         int                     i;
 504         unsigned short          device;
 505 
 506         pcibios_read_config_word(
 507                 bus, dev_fn, (unsigned char) PCI_DEVICE_ID, &device);
 508         for (i=0;i<PCI_DEVICE_NUM;i++)
 509                 if ((device==pci_device[i].device_id)
 510                  && (vendor==pci_device[i].vendor_id)) return i;
 511         printk("Device id=%x ",device);
 512         return i;
 513 }
 514 
 515 
 516 int vendor_decode(unsigned char bus,unsigned char dev_fn)
     /* [previous][next][first][last][top][bottom][index][help] */
 517 {
 518         struct pci_vendor_type  pci_vendor[PCI_VENDOR_NUM+1] = PCI_VENDOR_TYPE;
 519         int                     i;
 520         unsigned short          vendor;
 521 
 522                 pcibios_read_config_word(
 523                         bus, dev_fn, (unsigned char) PCI_VENDOR_ID, &vendor);
 524                 for (i=0;i<PCI_VENDOR_NUM;i++)
 525                         if (vendor==pci_vendor[i].vendor_id) return i;
 526                 printk("Vendor id=%x ",vendor);
 527                 return i;
 528 }
 529 
 530 
 531 /* In future version in case we detect a PCI to PCi bridge, we will go
 532 for a recursive device search*/
 533 
 534 void probe_devices(unsigned char bus)
     /* [previous][next][first][last][top][bottom][index][help] */
 535 {
 536         unsigned long   res;
 537         unsigned char   dev_fn;
 538 
 539 /* For a mysterious reason, my PC crash if I try to probe device 31 function 7  */
 540 /* (i.e. dev_fn=0xff) It can be a bug in my BIOS, or I haven't understood all about */
 541 /* PCI */
 542 
 543 
 544                 for (dev_fn=0x0;dev_fn<0xff;dev_fn++) {
 545                         pcibios_read_config_dword(
 546                                 bus, dev_fn, (unsigned char) PCI_CLASS_REVISION, &res);
 547 
 548 /* First we won't try to talk to non_present chip */
 549 /* Second, we get rid of non multi-function device that seems to be lazy  */
 550 /* and not fully decode the function number */
 551 
 552                         if ((res!=0xffffffff) &&
 553                                 (((dev_fn & 7) == 0) || multi_function(bus,dev_fn))) {
 554                                 add_pci_resource( bus, dev_fn);
 555                         }
 556                 }
 557 }
 558 
 559 
 560 void probe_pci(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 561 {
 562         if (pcibios_present()==0) {
 563                 printk("ProbePci PCI bios not detected.\n");
 564                 return;
 565         }
 566         printk( "Probing PCI hardware.\n");
 567         probe_devices(0);
 568 }
 569 
 570 
 571 /*
 572  * Function to add a resource to the pci list...
 573  */
 574 void add_pci_resource(unsigned char bus, unsigned char dev_fn)
     /* [previous][next][first][last][top][bottom][index][help] */
 575 {
 576         pci_resource_t* new_pci;
 577         pci_resource_t* temp;
 578 
 579         /*
 580          * Request and verify allocation of kernel RAM
 581          */
 582         if(pci_index > 31)
 583         {
 584                 printk("PCI resource list full.\n");
 585                 return;
 586         }
 587 
 588 
 589         new_pci = &pci_table[pci_index];
 590         pci_index++;
 591 
 592         /*
 593          * Enter the new node into the list....
 594          *
 595          */
 596         if(pci_list.next != NULL)
 597         {
 598                 for(temp = pci_list.next; (temp->next); temp = temp->next)
 599                         /* nothing */;
 600 
 601                 temp->next = new_pci;
 602         }
 603         else
 604                 pci_list.next = new_pci;
 605 
 606         /*
 607          * Set the information for the node
 608          */
 609         new_pci->next = NULL;
 610         new_pci->bus = bus;
 611         new_pci->dev_fn = dev_fn;
 612 
 613         return;
 614 }
 615 
 616 
 617 int get_pci_list(char* buf)
     /* [previous][next][first][last][top][bottom][index][help] */
 618 {
 619         int pr, length;
 620         pci_resource_t* temp = pci_list.next;
 621         struct  pci_class_type  pci_class[PCI_CLASS_NUM+1] = PCI_CLASS_TYPE;
 622         struct  pci_vendor_type pci_vendor[PCI_VENDOR_NUM+1] = PCI_VENDOR_TYPE;
 623         struct  pci_device_type pci_device[PCI_DEVICE_NUM+1] = PCI_DEVICE_TYPE;
 624 
 625         for (length = 0 ; (temp) && (length<4000); temp = temp->next)
 626         {
 627                 pr=vendor_decode(temp->bus,temp->dev_fn);
 628 
 629                 length += sprintf(buf+length, "Bus %2d Device %3d Function %2d.\n",
 630                         (int)temp->bus,
 631                         (int)((temp->dev_fn & 0xf8) >> 3),
 632                         (int) (temp->dev_fn & 7));
 633 
 634                 length += sprintf(buf+length, "    %s : %s %s (rev %d). ",
 635                         pci_class[class_decode(temp->bus, temp->dev_fn)].class_name,
 636                         pci_vendor[pr].vendor_name,
 637                         pci_device[device_decode(temp->bus, temp->dev_fn, pci_vendor[pr].vendor_id)].device_name,
 638                         revision_decode(temp->bus, temp->dev_fn));
 639 
 640                 if (bist_probe(temp->bus, temp->dev_fn))
 641                         length += sprintf(buf+length, "BIST capable. ");
 642 
 643                 if ((pr = interrupt_decode(temp->bus, temp->dev_fn)) != 0)
 644                         length += sprintf(buf+length, "8259's interrupt %d.", pr);
 645 
 646                 length += sprintf(buf+length, "\n");
 647         }
 648 
 649         if (temp)
 650                 length += sprintf(buf+length, "4K limit reached!\n");
 651 
 652         return length;
 653 }
 654 
 655 
 656 #endif
 657 
 658 unsigned long bios32_init(unsigned long memory_start, unsigned long memory_end)
     /* [previous][next][first][last][top][bottom][index][help] */
 659 {
 660         union bios32 *check;
 661         unsigned char sum;
 662         int i, length;
 663 
 664         /*
 665          * Follow the standard procedure for locating the BIOS32 Service
 666          * directory by scanning the permissible address range from
 667          * 0xe0000 through 0xfffff for a valid BIOS32 structure.
 668          *
 669          * The PCI BIOS doesn't seem to work too well on many machines,
 670          * so we disable this unless it's really needed (NCR SCSI driver)
 671          */
 672 
 673         for (check = (union bios32 *) 0xe0000; check <= (union bios32 *) 0xffff0; ++check) {
 674                 if (check->fields.signature != BIOS32_SIGNATURE)
 675                         continue;
 676                 length = check->fields.length * 16;
 677                 if (!length)
 678                         continue;
 679                 sum = 0;
 680                 for (i = 0; i < length ; ++i)
 681                         sum += check->chars[i];
 682                 if (sum != 0)
 683                         continue;
 684                 if (check->fields.revision != 0) {
 685                         printk("bios32_init : unsupported revision %d at 0x%p, mail drew@colorado.edu\n",
 686                                 check->fields.revision, check);
 687                         continue;
 688                 }
 689                 printk ("bios32_init : BIOS32 Service Directory structure at 0x%p\n", check);
 690                 if (!bios32_entry) {
 691                         bios32_indirect.address = bios32_entry = check->fields.entry;
 692                         printk ("bios32_init : BIOS32 Service Directory entry at 0x%lx\n", bios32_entry);
 693                 } else {
 694                         printk ("bios32_init : multiple entries, mail drew@colorado.edu\n");
 695                         /*
 696                          * Jeremy Fitzhardinge reports at least one PCI BIOS
 697                          * with two different service directories, and as both
 698                          * worked for him, we'll just mention the fact, and
 699                          * not actually disallow it..
 700                          */
 701 #if 0
 702                         return memory_start;
 703 #endif
 704                 }
 705         }
 706 #ifdef CONFIG_PCI
 707         if (bios32_entry) {
 708                 memory_start = pcibios_init (memory_start, memory_end);
 709                 probe_pci();
 710         }
 711 #endif
 712         return memory_start;
 713 }
 714 
 715 
 716 

/* [previous][next][first][last][top][bottom][index][help] */