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.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #include "string.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. DBG ( "ISA searching for device matching driver %s\n", driver->name );
  43. for ( i = isa->probe_idx ; i < isa_extra_probe_addr_count ; i++ ) {
  44. /* If we've already used this device, skip it */
  45. if ( isa->already_tried ) {
  46. isa->already_tried = 0;
  47. continue;
  48. }
  49. /* Set I/O address */
  50. ioaddr = isa_extra_probe_addrs[i];
  51. /* An I/O address of 0 in extra_probe_addrs list means
  52. * stop probing (i.e. don't continue to the
  53. * driver-provided list)
  54. */
  55. if ( ! ioaddr )
  56. goto notfound;
  57. /* Use probe_addr method to see if there's a device
  58. * present at this address.
  59. */
  60. if ( driver->probe_addr ( ioaddr ) ) {
  61. isa->probe_idx = i;
  62. goto found;
  63. }
  64. }
  65. /* Iterate through all ISA probe addresses provided by the
  66. * driver, starting where we left off.
  67. */
  68. for ( i = isa->probe_idx - isa_extra_probe_addr_count ;
  69. i < driver->addr_count ; i++ ) {
  70. /* If we've already used this device, skip it */
  71. if ( isa->already_tried ) {
  72. isa->already_tried = 0;
  73. continue;
  74. }
  75. /* Set I/O address */
  76. ioaddr = driver->probe_addrs[i];
  77. /* Use probe_addr method to see if there's a device
  78. * present at this address.
  79. */
  80. if ( driver->probe_addr ( ioaddr ) ) {
  81. isa->probe_idx = i + isa_extra_probe_addr_count;
  82. goto found;
  83. }
  84. }
  85. notfound:
  86. /* No device found */
  87. DBG ( "ISA found no device matching driver %s\n", driver->name );
  88. isa->probe_idx = 0;
  89. return 0;
  90. found:
  91. DBG ( "ISA found %s device at address %hx\n", driver->name, ioaddr );
  92. isa->ioaddr = ioaddr;
  93. isa->already_tried = 1;
  94. return 1;
  95. }
  96. /*
  97. * Find the next ISA device that can be used to boot using the
  98. * specified driver.
  99. *
  100. */
  101. int find_isa_boot_device ( struct dev *dev, struct isa_driver *driver ) {
  102. struct isa_device *isa = ( struct isa_device * )dev->bus;
  103. if ( ! find_isa_device ( isa, driver ) )
  104. return 0;
  105. dev->name = driver->name;
  106. dev->devid.bus_type = ISA_BUS_TYPE;
  107. dev->devid.vendor_id = driver->mfg_id;
  108. dev->devid.device_id = driver->prod_id;
  109. return 1;
  110. }