Separate out bus-scanning and device-probing logic.
[people/xl0/gpxe.git] / src / include / dev.h
1 #ifndef DEV_H
2 #define DEV_H
3
4 #include "stdint.h"
5
6 /* Device types */
7 #include "nic.h"
8
9 /* Need to check the packing of this struct if Etherboot is ported */
10 struct dev_id {
11         uint16_t        vendor_id;
12         uint16_t        device_id;
13         uint8_t         bus_type;
14 #define PCI_BUS_TYPE    1
15 #define ISA_BUS_TYPE    2
16 #define MCA_BUS_TYPE    3
17 } __attribute__ ((packed));
18
19 /* Dont use sizeof, that will include the padding */
20 #define DEV_ID_SIZE     8
21
22 struct dev {
23         struct dev_operations *dev_op;
24         const char *name;
25         struct dev_id   devid;  /* device ID string (sent to DHCP server) */
26         struct boot_driver *driver; /* driver being used for boot */
27         /* Pointer to bus information for device.  Whatever sets up
28          * the struct dev must make sure that this points to a buffer
29          * large enough for the required struct <bus>_device.
30          */
31         struct bus_device *bus;
32         /* All possible device types */
33         union {
34                 struct nic      nic;
35         };
36 };
37
38 /*
39  * Macro to help create a common symbol with enough space for any
40  * struct <bus>_device.
41  *
42  * Use as e.g. DEV_BUS(struct pci_device);
43  */
44 #define DEV_BUS(datatype,symbol) datatype symbol __asm__ ( "_dev_bus" );
45
46 struct dev_operations {
47         void ( *disable ) ( struct dev * );
48         void ( *print_info ) ( struct dev * );
49         int ( *load_configuration ) ( struct dev * );
50         int ( *load ) ( struct dev * );
51 };
52
53 /*
54  * Table to describe a bootable device driver.  See comments in dev.c
55  * for an explanation.
56  *
57  */
58 struct bus_device {};
59 struct bus_driver {};
60 struct boot_driver {
61         char *name;
62         struct bus_device * ( *find_bus_boot_device ) ( struct dev *dev,
63                                                    struct bus_driver *driver );
64         struct bus_driver *bus_driver;
65         int ( *probe ) ( struct dev *dev, struct bus_device *bus_device );
66 };
67
68 #define BOOT_DRIVER( _name, _find_bus_boot_device, _bus_driver, _probe )      \
69         static struct boot_driver boot_driver_ ## probe_func                  \
70             __attribute__ ((used,__section__(".boot_drivers"))) = {           \
71                 .name = _name,                                                \
72                 .find_bus_boot_device = ( void * ) _find_bus_boot_device,     \
73                 .bus_driver = ( void * ) _bus_driver,                         \
74                 .probe = ( void * ) _probe,                                   \
75         };
76
77 /* Functions in dev.c */
78 extern void print_drivers ( void );
79 extern int find_boot_device ( struct dev *dev );
80 extern int probe ( struct dev *dev );
81 extern void disable ( struct dev *dev );
82 static inline void print_info ( struct dev *dev ) {
83         dev->dev_op->print_info ( dev );
84 }
85 static inline int load_configuration ( struct dev *dev ) {
86         return dev->dev_op->load_configuration ( dev );
87 }
88 static inline int load ( struct dev *dev ) {
89         return dev->dev_op->load ( dev );
90 }
91
92 #endif /* DEV_H */