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.

dev.c 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #include "etherboot.h"
  2. #include "stddef.h"
  3. #include "dev.h"
  4. /*
  5. * Each bus driver defines several methods, which are described in
  6. * dev.h. This file provides a centralised, bus-independent mechanism
  7. * for locating devices and drivers.
  8. *
  9. */
  10. /* Linker symbols for the various tables */
  11. static struct bus_driver bus_drivers[0]
  12. __table_start ( struct bus_driver, bus_driver );
  13. static struct bus_driver bus_drivers_end[0]
  14. __table_end ( struct bus_driver, bus_driver );
  15. static struct device_driver device_drivers[0]
  16. __table_start ( struct device_driver, device_driver );
  17. static struct device_driver device_drivers_end[0]
  18. __table_end ( struct device_driver, device_driver );
  19. /* Current attempted boot device */
  20. struct dev dev = {
  21. .bus_driver = bus_drivers,
  22. .device_driver = device_drivers,
  23. };
  24. /*
  25. * Print all drivers
  26. *
  27. */
  28. void print_drivers ( void ) {
  29. struct device_driver *driver;
  30. for ( driver = device_drivers ;
  31. driver < device_drivers_end ;
  32. driver++ ) {
  33. printf ( "%s ", driver->name );
  34. }
  35. }
  36. /*
  37. * Move to the next location on any bus
  38. *
  39. */
  40. static inline int next_location ( struct bus_driver **bus_driver,
  41. struct bus_loc *bus_loc ) {
  42. /* Move to next location on this bus, if any */
  43. if ( (*bus_driver)->next_location ( bus_loc ) )
  44. return 1;
  45. /* Move to first (zeroed) location on next bus, if any */
  46. if ( ++(*bus_driver) < bus_drivers_end ) {
  47. DBG ( "DEV scanning %s bus\n", (*bus_driver)->name );
  48. return 1;
  49. }
  50. /* Reset to first bus, return "no more locations" */
  51. *bus_driver = bus_drivers;
  52. return 0;
  53. }
  54. /*
  55. * Find the next available device on any bus
  56. *
  57. * Set skip=1 to skip over the current device
  58. *
  59. */
  60. int find_any ( struct bus_driver **bus_driver, struct bus_loc *bus_loc,
  61. struct bus_dev *bus_dev, signed int skip ) {
  62. DBG ( "DEV scanning %s bus\n", (*bus_driver)->name );
  63. do {
  64. if ( --skip >= 0 )
  65. continue;
  66. if ( ! (*bus_driver)->fill_device ( bus_dev, bus_loc ) )
  67. continue;
  68. DBG ( "DEV found device %s\n",
  69. (*bus_driver)->describe_device ( bus_dev ) );
  70. return 1;
  71. } while ( next_location ( bus_driver, bus_loc ) );
  72. DBG ( "DEV found no more devices\n" );
  73. return 0;
  74. }
  75. /*
  76. * Find a driver by specified device.
  77. *
  78. * Set skip=1 to skip over the current driver
  79. *
  80. */
  81. int find_by_device ( struct device_driver **device_driver,
  82. struct bus_driver *bus_driver, struct bus_dev *bus_dev,
  83. signed int skip ) {
  84. do {
  85. if ( --skip >= 0 )
  86. continue;
  87. if ( (*device_driver)->bus_driver != bus_driver )
  88. continue;
  89. if ( ! bus_driver->check_driver ( bus_dev, *device_driver ))
  90. continue;
  91. DBG ( "DEV found driver %s for device %s\n",
  92. (*device_driver)->name,
  93. bus_driver->describe_device ( bus_dev ) );
  94. return 1;
  95. } while ( ++(*device_driver) < device_drivers_end );
  96. /* Reset to first driver, return "not found" */
  97. DBG ( "DEV found no driver for device %s\n",
  98. bus_driver->describe_device ( bus_dev ) );
  99. *device_driver = device_drivers;
  100. return 0;
  101. }
  102. /*
  103. * Find a device by specified driver.
  104. *
  105. * Set skip=1 to skip over the current device
  106. *
  107. */
  108. int find_by_driver ( struct bus_loc *bus_loc, struct bus_dev *bus_dev,
  109. struct device_driver *device_driver,
  110. signed int skip ) {
  111. struct bus_driver *bus_driver = device_driver->bus_driver;
  112. do {
  113. if ( --skip >= 0 )
  114. continue;
  115. if ( ! bus_driver->fill_device ( bus_dev, bus_loc ) )
  116. continue;
  117. if ( ! bus_driver->check_driver ( bus_dev, device_driver ) )
  118. continue;
  119. DBG ( "DEV found device %s for driver %s\n",
  120. bus_driver->describe_device ( bus_dev ),
  121. device_driver->name );
  122. return 1;
  123. } while ( bus_driver->next_location ( bus_loc ) );
  124. DBG ( "DEV found no device for driver %s\n", device_driver->name );
  125. return 0;
  126. }
  127. /*
  128. * Find the next available (device,driver) combination
  129. *
  130. * Set skip=1 to skip over the current (device,driver)
  131. *
  132. * Note that the struct dev may not have been previously used, and so
  133. * may not contain a valid (device,driver) combination.
  134. *
  135. */
  136. int find_any_with_driver ( struct dev *dev, signed int skip ) {
  137. signed int skip_device = 0;
  138. signed int skip_driver = skip;
  139. while ( find_any ( &dev->bus_driver, &dev->bus_loc, &dev->bus_dev,
  140. skip_device ) ) {
  141. if ( find_by_device ( &dev->device_driver, dev->bus_driver,
  142. &dev->bus_dev, skip_driver ) ) {
  143. /* Set type_driver to be that of the device
  144. * driver
  145. */
  146. dev->type_driver = dev->device_driver->type_driver;
  147. /* Set type device instance to be the single
  148. * instance provided by the type driver
  149. */
  150. dev->type_dev = dev->type_driver->type_dev;
  151. return 1;
  152. }
  153. skip_driver = 0;
  154. skip_device = 1;
  155. }
  156. return 0;
  157. }