Updated debug messages
[people/xl0/gpxe.git] / src / core / dev.c
1 #include "etherboot.h"
2 #include "stddef.h"
3 #include "dev.h"
4
5 /*
6  * Each driver specifies a name, the bus-scanning function
7  * (find_bus_boot_device) that it wants to use, a driver information
8  * structure (bus_driver) containing e.g. device IDs to be passed to
9  * find_bus_boot_device, and a probe function (probe) to be called
10  * whenever a suitable device is found.
11  *
12  * The generic device-probing code knows nothing about particular bus
13  * types; it simply passes the driver information structure
14  * (bus_driver) to the bus-scanning function (find_bus_boot_device),
15  * then passes the result of that function (if not NULL) to the probe
16  * function (probe).
17  */
18
19 /* Current attempted boot device */
20 struct dev dev = {
21         .bus_driver = bus_drivers,
22         .device_driver = device_drivers,
23 };
24
25 /*
26  * Print all drivers 
27  *
28  */
29 void print_drivers ( void ) {
30         struct device_driver *driver;
31
32         for ( driver = device_drivers ;
33               driver < device_drivers_end ;
34               driver++ ) {
35                 printf ( "%s ", driver->name );
36         }
37 }
38
39 /*
40  * Move to the next location on any bus
41  *
42  */
43 static inline int next_location ( struct bus_driver **bus_driver,
44                                   struct bus_loc *bus_loc ) {
45         /* Move to next location on this bus, if any */
46         if ( (*bus_driver)->next_location ( bus_loc ) )
47                 return 1;
48
49         /* Move to first (zeroed) location on next bus, if any */
50         if ( ++(*bus_driver) < bus_drivers_end )
51                 return 1;
52
53         /* Reset to first bus, return "no more locations" */
54         *bus_driver = bus_drivers;
55         return 0;
56 }
57
58 /*
59  * Find the next available device on any bus
60  *
61  * Set skip=1 to skip over the current device
62  *
63  */
64 int find_any ( struct bus_driver **bus_driver, struct bus_loc *bus_loc,
65                struct bus_dev *bus_dev, signed int skip ) {
66         DBG ( "DEV searching for any device\n" );
67         do {
68                 if ( --skip >= 0 )
69                         continue;
70                 if ( ! (*bus_driver)->fill_device ( bus_dev, bus_loc ) )
71                         continue;
72                 DBG ( "DEV found device %s\n",
73                       (*bus_driver)->describe ( bus_dev ) );
74                 return 1;
75         } while ( next_location ( bus_driver, bus_loc ) );
76
77         DBG ( "DEV found no device\n" );
78         return 0;
79 }
80
81 /*
82  * Find a driver by specified device.
83  *
84  * Set skip=1 to skip over the current driver
85  *
86  */
87 int find_by_device ( struct device_driver **device_driver,
88                      struct bus_driver *bus_driver, struct bus_dev *bus_dev,
89                      signed int skip ) {
90         DBG ( "DEV searching for a driver for device %s\n",
91               bus_driver->describe ( bus_dev ) );
92         do {
93                 if ( --skip >= 0 )
94                         continue;
95                 if ( (*device_driver)->bus_driver != bus_driver )
96                         continue;
97                 if ( ! bus_driver->check_driver ( bus_dev, *device_driver ))
98                         continue;
99                 DBG ( "DEV found driver %s\n", (*device_driver)->name );
100                 return 1;
101         } while ( ++(*device_driver) < device_drivers_end );
102         
103         /* Reset to first driver, return "not found" */
104         DBG ( "DEV found no driver for device %s\n",
105               bus_driver->describe ( bus_dev ) );
106         *device_driver = device_drivers;
107         return 0;
108 }
109
110 /*
111  * Find a device by specified driver.
112  *
113  * Set skip=1 to skip over the current device
114  *
115  */
116 int find_by_driver ( struct bus_loc *bus_loc, struct bus_dev *bus_dev,
117                      struct device_driver *device_driver,
118                      signed int skip ) {
119         struct bus_driver *bus_driver = device_driver->bus_driver;
120         
121         DBG ( "DEV searching for a device for driver %s\n",
122               device_driver->name );
123         do {
124                 if ( --skip >= 0 )
125                         continue;
126                 if ( ! bus_driver->fill_device ( bus_dev, bus_loc ) )
127                         continue;
128                 if ( ! bus_driver->check_driver ( bus_dev, device_driver ) )
129                         continue;
130                 DBG ( "DEV found device %s\n",
131                       bus_driver->describe ( bus_dev ) );
132                 return 1;
133         } while ( bus_driver->next_location ( bus_loc ) );
134
135         DBG ( "DEV found no device for driver %s\n" );
136         return 0;
137 }
138
139 /*
140  * Find the next available (device,driver) combination
141  *
142  * Set skip=1 to skip over the current (device,driver)
143  *
144  * Note that the struct dev may not have been previously used, and so
145  * may not contain a valid (device,driver) combination.
146  *
147  */
148 int find_any_with_driver ( struct dev *dev, signed int skip ) {
149         signed int skip_device = 0;
150         signed int skip_driver = skip;
151
152         while ( find_any ( &dev->bus_driver, &dev->bus_loc, &dev->bus_dev,
153                            skip_device ) ) {
154                 if ( find_by_device ( &dev->device_driver, dev->bus_driver,
155                                       &dev->bus_dev, skip_driver ) ) {
156                         /* Set type_driver to be that of the device
157                          * driver
158                          */
159                         dev->type_driver = dev->device_driver->type_driver;
160                         /* Set type device instance to be the single
161                          * instance provided by the type driver
162                          */
163                         dev->type_dev = dev->type_driver->type_dev;
164                         return 1;
165                 }
166                 skip_driver = 0;
167                 skip_device = 1;
168         }
169
170         return 0;
171 }