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.h 8.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. #ifndef DEV_H
  2. #define DEV_H
  3. #include "stdint.h"
  4. #include "string.h"
  5. #include "buffer.h"
  6. #include "dhcp.h" /* for dhcp_dev_id */
  7. #include "tables.h"
  8. /*
  9. * Forward declarations
  10. *
  11. */
  12. struct type_dev;
  13. struct type_driver;
  14. struct bus_driver;
  15. struct bus_dev;
  16. struct device_driver;
  17. /*
  18. * When looking at the following data structures, mentally substitute
  19. * "<bus>_" in place of "bus_" and everything will become clear.
  20. * "struct bus_location" becomes "struct <bus>_location", which means
  21. * "the location of a device on a <bus> bus", where <bus> is a
  22. * particular type of bus such as "pci" or "isapnp".
  23. *
  24. */
  25. /*
  26. * A physical device location on a bus.
  27. *
  28. */
  29. #define BUS_LOC_SIZE 8
  30. struct bus_loc {
  31. char bytes[BUS_LOC_SIZE];
  32. };
  33. /*
  34. * A structure fully describing a physical device on a bus.
  35. *
  36. */
  37. #define BUS_DEV_SIZE 32
  38. struct bus_dev {
  39. char bytes[BUS_DEV_SIZE];
  40. };
  41. /*
  42. * Individual buses will have different sizes for their <bus>_location
  43. * and <bus>_device structures. We need to be able to allocate static
  44. * storage that's large enough to contain these structures for any
  45. * bus type that's being used in the current binary.
  46. *
  47. * We can't just create a union of all the various types, because some
  48. * may be architecture-dependent (and some are even embedded in
  49. * specific drivers, e.g. 3c509), so this would quickly get messy.
  50. *
  51. * We could use the magic of common symbols. Each bus could declare a
  52. * common symbol with the name "_bus_dev" of the correct size; this
  53. * is easily done using code like
  54. * struct pci_device _bus_dev;
  55. * The linker would then use the largest size of the "_bus_dev" symbol
  56. * in any included object, thus giving us a single _bus_dev symbol of
  57. * *exactly* the required size. However, there's no way to extract
  58. * the size of this symbol, either directly as a linker symbol
  59. * ("_bus_dev_size = SIZEOF(_bus_dev)"; the linker language just
  60. * doesn't provide this construct) or via any linker trickery I can
  61. * think of (such as creating a special common symbol section just for
  62. * this symbol then using SIZE(section) to read the size of the
  63. * section; ld recognises only a single common symbol section called
  64. * "COMMON").
  65. *
  66. * Since there's no way to get the size of the symbol, this
  67. * effectively limits us to just one instance of the symbol. This is
  68. * all very well for the simple case of "just boot from any single
  69. * device you can", but becomes limiting when you want to do things
  70. * like introducing PCMCIA buses (which must instantiate other devices
  71. * such as PCMCIA controllers).
  72. *
  73. * So, we declare the maximum sizes of these constructions to be
  74. * compile-time constants. Each individual bus driver should define
  75. * its own struct <bus>_location and struct <bus>_device however it
  76. * likes, and can freely cast pointers from struct bus_loc to
  77. * struct <bus>_location (and similarly for bus_dev). To guard
  78. * against bounding errors, each bus driver *MUST* use the macros
  79. * BUS_LOC_CHECK() and BUS_DEV_CHECK(), as in:
  80. *
  81. * BUS_LOC_CHECK ( struct pci_location );
  82. * BUS_DEV_CHECK ( struct pci_device );
  83. *
  84. * These macros will generate a link-time error if the size of the
  85. * <bus> structure exceeds the declared maximum size.
  86. *
  87. * The macros will generate no binary object code, but must be placed
  88. * inside a function (in order to generate syntactically valid C).
  89. * The easiest wy to do this is to place them in the
  90. * <bus>_next_location() function.
  91. *
  92. * If anyone can think of a better way of doing this that avoids *ALL*
  93. * of the problems described above, please implement it!
  94. *
  95. */
  96. #define LINKER_ASSERT(test,error_symbol) \
  97. if ( ! (test) ) { \
  98. extern void error_symbol ( void ); \
  99. error_symbol(); \
  100. }
  101. #define BUS_LOC_CHECK(datatype) \
  102. LINKER_ASSERT( ( sizeof (datatype) <= sizeof (struct bus_loc) ), \
  103. __BUS_LOC_SIZE_is_too_small__see_dev_h )
  104. #define BUS_DEV_CHECK(datatype) \
  105. LINKER_ASSERT( ( sizeof (datatype) <= sizeof (struct bus_dev) ), \
  106. __BUS_DEV_SIZE_is_too_small__see_dev_h )
  107. /*
  108. * Bus-level operations.
  109. *
  110. * int next_location ( struct bus_loc * bus_loc )
  111. *
  112. * Increment bus_loc to point to the next possible device on
  113. * the bus (e.g. the next PCI busdevfn, or the next ISAPnP CSN).
  114. * If there are no more valid locations, return 0 and leave
  115. * struct bus_loc zeroed, otherwise return true.
  116. *
  117. * int fill_device ( struct bus_dev *bus_dev,
  118. * struct bus_loc *bus_loc )
  119. *
  120. * Fill out a bus_dev structure with the parameters for the
  121. * device at bus_loc. (For example, fill in the PCI vendor
  122. * and device IDs). Return true if there is a device physically
  123. * present at this location, otherwise 0.
  124. *
  125. * int check_driver ( struct bus_dev *bus_dev,
  126. * struct device_driver *device_driver )
  127. *
  128. * Test whether or not the specified driver is capable of driving
  129. * the specified device by, for example, comparing the device's
  130. * PCI IDs against the list of PCI IDs claimed by the driver.
  131. *
  132. * char * describe ( struct bus_dev *bus_dev )
  133. *
  134. * Return a text string describing the bus device bus_dev
  135. * (e.g. "PCI 00:01.2")
  136. *
  137. * char * name ( struct bus_dev *bus_dev )
  138. *
  139. * Return a text string describing the bus device bus_dev
  140. * (e.g. "dfe538")
  141. *
  142. */
  143. struct bus_driver {
  144. const char *name;
  145. int ( *next_location ) ( struct bus_loc *bus_loc );
  146. int ( *fill_device ) ( struct bus_dev *bus_dev,
  147. struct bus_loc *bus_loc );
  148. int ( *check_driver ) ( struct bus_dev *bus_dev,
  149. struct device_driver *device_driver );
  150. char * ( *describe_device ) ( struct bus_dev *bus_dev );
  151. const char * ( *name_device ) ( struct bus_dev *bus_dev );
  152. };
  153. #define __bus_driver __table ( bus_driver, 01 )
  154. /*
  155. * A structure fully describing the bus-independent parts of a
  156. * particular type (e.g. nic or disk) of device.
  157. *
  158. * Unlike struct bus_dev, e can limit ourselves to having no more than
  159. * one instance of this data structure. We therefore place an
  160. * instance in each type driver file (e.g. nic.c), and simply use a
  161. * pointer to the struct type_dev in the struct dev.
  162. *
  163. */
  164. struct type_dev;
  165. /*
  166. * A type driver (e.g. nic, disk)
  167. *
  168. */
  169. struct type_driver {
  170. char *name;
  171. struct type_dev *type_dev; /* single instance */
  172. char * ( * describe_device ) ( struct type_dev *type_dev );
  173. int ( * configure ) ( struct type_dev *type_dev );
  174. int ( * load ) ( struct type_dev *type_dev, struct buffer *buffer );
  175. };
  176. #define __type_driver __table ( type_driver, 01 )
  177. /*
  178. * A driver for a device.
  179. *
  180. */
  181. struct device_driver {
  182. const char *name;
  183. struct type_driver *type_driver;
  184. struct bus_driver *bus_driver;
  185. struct bus_driver_info *bus_driver_info;
  186. int ( * probe ) ( struct type_dev *type_dev,
  187. struct bus_dev *bus_dev );
  188. void ( * disable ) ( struct type_dev *type_dev,
  189. struct bus_dev *bus_dev );
  190. };
  191. #define __device_driver __table ( device_driver, 01 )
  192. #define DRIVER(_name,_type_driver,_bus_driver,_bus_info, \
  193. _probe,_disable) \
  194. static struct device_driver device_ ## _bus_info __device_driver = { \
  195. .name = _name, \
  196. .type_driver = &_type_driver, \
  197. .bus_driver = &_bus_driver, \
  198. .bus_driver_info = ( struct bus_driver_info * ) &_bus_info, \
  199. .probe = ( int (*) () ) _probe, \
  200. .disable = ( void (*) () ) _disable, \
  201. };
  202. /*
  203. * A bootable device, comprising a physical device on a bus, a driver
  204. * for that device, and a type device
  205. *
  206. */
  207. struct dev {
  208. struct bus_driver *bus_driver;
  209. struct bus_loc bus_loc;
  210. struct bus_dev bus_dev;
  211. struct device_driver *device_driver;
  212. struct type_driver *type_driver;
  213. struct type_dev *type_dev;
  214. };
  215. /* The current boot device */
  216. extern struct dev dev;
  217. /*
  218. * Functions in dev.c
  219. *
  220. */
  221. extern void print_drivers ( void );
  222. extern int find_any ( struct bus_driver **bus_driver, struct bus_loc *bus_loc,
  223. struct bus_dev *bus_dev, signed int skip );
  224. extern int find_by_device ( struct device_driver **device_driver,
  225. struct bus_driver *bus_driver,
  226. struct bus_dev *bus_dev,
  227. signed int skip );
  228. extern int find_by_driver ( struct bus_loc *bus_loc, struct bus_dev *bus_dev,
  229. struct device_driver *device_driver,
  230. signed int skip );
  231. extern int find_any_with_driver ( struct dev *dev, signed int skip );
  232. /*
  233. * Functions inlined to save space
  234. *
  235. */
  236. /* Probe a device */
  237. static inline int probe ( struct dev *dev ) {
  238. return dev->device_driver->probe ( dev->type_dev, &dev->bus_dev );
  239. }
  240. /* Disable a device */
  241. static inline void disable ( struct dev *dev ) {
  242. dev->device_driver->disable ( dev->type_dev, &dev->bus_dev );
  243. }
  244. /* Set the default boot device */
  245. static inline void select_device ( struct dev *dev,
  246. struct bus_driver *bus_driver,
  247. struct bus_loc *bus_loc ) {
  248. dev->bus_driver = bus_driver;
  249. memcpy ( &dev->bus_loc, bus_loc, sizeof ( dev->bus_loc ) );
  250. }
  251. /* Configure a device */
  252. static inline int configure ( struct dev *dev ) {
  253. return dev->type_driver->configure ( dev->type_dev );
  254. }
  255. /* Boot from a device */
  256. static inline int load ( struct dev *dev, struct buffer *buffer ) {
  257. return dev->type_driver->load ( dev->type_dev, buffer );
  258. }
  259. #endif /* DEV_H */