Use the magic of common symbols to allow struct dev to effectively grow at
[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         /* Pointer to bus information for device.  Whatever sets up
27          * the struct dev must make sure that this points to a buffer
28          * large enough for the required struct <bus>_device.
29          */
30         void *bus;
31         /* All possible device types */
32         union {
33                 struct nic      nic;
34         };
35 };
36
37 /*
38  * Macro to help create a common symbol with enough space for any
39  * struct <bus>_device.
40  *
41  * Use as e.g. DEV_BUS(struct pci_device);
42  */
43 #define DEV_BUS(datatype,symbol) datatype symbol __asm__ ( "_dev_bus" );
44
45 struct dev_operations {
46         void ( *disable ) ( struct dev * );
47         void ( *print_info ) ( struct dev * );
48         int ( *load_configuration ) ( struct dev * );
49         int ( *load ) ( struct dev * );
50 };
51
52 struct boot_driver {
53         char *name;
54         int (*probe) ( struct dev * );
55 };
56
57 #define BOOT_DRIVER( driver_name, probe_func )                                \
58         static struct boot_driver boot_driver                                 \
59             __attribute__ ((used,__section__(".boot_drivers"))) = {           \
60                 .name = driver_name,                                          \
61                 .probe = probe_func,                                          \
62         };
63
64 /* Functions in dev.c */
65 extern void print_drivers ( void );
66 extern int probe ( struct dev *dev );
67 extern void disable ( struct dev *dev );
68 static inline void print_info ( struct dev *dev ) {
69         dev->dev_op->print_info ( dev );
70 }
71 static inline int load_configuration ( struct dev *dev ) {
72         return dev->dev_op->load_configuration ( dev );
73 }
74 static inline int load ( struct dev *dev ) {
75         return dev->dev_op->load ( dev );
76 }
77
78 #endif /* DEV_H */