You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

isa.c 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #include "etherboot.h"
  2. #include "isa.h"
  3. /*
  4. * isa.c implements a "classical" port-scanning method of ISA device
  5. * detection. The driver must provide a list of probe addresses
  6. * (probe_addrs), together with a function (probe_addr) that can be
  7. * used to test for the physical presence of a device at any given
  8. * address.
  9. *
  10. * Note that this should probably be considered the "last resort" for
  11. * device probing. If the card supports ISAPnP or EISA, use that
  12. * instead. Some cards (e.g. the 3c509) implement a proprietary
  13. * ISAPnP-like mechanism.
  14. *
  15. * The ISA probe address list can be overridden by config.c; if the
  16. * user specifies ISA_PROBE_ADDRS then that list will be used first.
  17. * (If ISA_PROBE_ADDRS ends with a zero, the driver's own list will
  18. * never be used).
  19. */
  20. /*
  21. * Ensure that there is sufficient space in the shared dev_bus
  22. * structure for a struct isa_device.
  23. *
  24. */
  25. DEV_BUS( struct isa_device, isa_dev );
  26. static char isa_magic[0]; /* guaranteed unique symbol */
  27. /*
  28. * Find an ISA device matching the specified driver
  29. *
  30. */
  31. int find_isa_device ( struct isa_device *isa, struct isa_driver *driver ) {
  32. unsigned int i;
  33. uint16_t ioaddr;
  34. /* Initialise struct isa if it's the first time it's been used. */
  35. if ( isa->magic != isa_magic ) {
  36. memset ( isa, 0, sizeof ( *isa ) );
  37. isa->magic = isa_magic;
  38. }
  39. /* Iterate through any ISA probe addresses specified by
  40. * config.c, starting where we left off.
  41. */
  42. for ( i = isa->probe_idx ; i < isa_extra_probe_addr_count ; i++ ) {
  43. /* If we've already used this device, skip it */
  44. if ( isa->already_tried ) {
  45. isa->already_tried = 0;
  46. continue;
  47. }
  48. /* Set I/O address */
  49. ioaddr = isa_extra_probe_addrs[i];
  50. /* An I/O address of 0 in extra_probe_addrs list means
  51. * stop probing (i.e. don't continue to the
  52. * driver-provided list)
  53. */
  54. if ( ! ioaddr )
  55. goto notfound;
  56. /* Use probe_addr method to see if there's a device
  57. * present at this address.
  58. */
  59. if ( driver->probe_addr ( ioaddr ) ) {
  60. isa->probe_idx = i;
  61. goto found;
  62. }
  63. }
  64. /* Iterate through all ISA probe addresses provided by the
  65. * driver, starting where we left off.
  66. */
  67. for ( i = isa->probe_idx - isa_extra_probe_addr_count ;
  68. i < driver->addr_count ; i++ ) {
  69. /* If we've already used this device, skip it */
  70. if ( isa->already_tried ) {
  71. isa->already_tried = 0;
  72. continue;
  73. }
  74. /* Set I/O address */
  75. ioaddr = driver->probe_addrs[i];
  76. /* Use probe_addr method to see if there's a device
  77. * present at this address.
  78. */
  79. if ( driver->probe_addr ( ioaddr ) ) {
  80. isa->probe_idx = i + isa_extra_probe_addr_count;
  81. goto found;
  82. }
  83. }
  84. notfound:
  85. /* No device found */
  86. isa->probe_idx = 0;
  87. return 0;
  88. found:
  89. DBG ( "ISA found %s device at address %hx\n", driver->name, ioaddr );
  90. isa->ioaddr = ioaddr;
  91. isa->already_tried = 1;
  92. return 1;
  93. }
  94. /*
  95. * Find the next ISA device that can be used to boot using the
  96. * specified driver.
  97. *
  98. */
  99. int find_isa_boot_device ( struct dev *dev, struct isa_driver *driver ) {
  100. struct isa_device *isa = ( struct isa_device * )dev->bus;
  101. if ( ! find_isa_device ( isa, driver ) )
  102. return 0;
  103. dev->name = driver->name;
  104. dev->devid.bus_type = ISA_BUS_TYPE;
  105. dev->devid.vendor_id = driver->mfg_id;
  106. dev->devid.device_id = driver->prod_id;
  107. return 1;
  108. }