6 * Each bus driver defines several methods, which are described in
7 * dev.h. This file provides a centralised, bus-independent mechanism
8 * for locating devices and drivers.
12 /* Linker symbols for the various tables */
13 static struct bus_driver bus_drivers[0] __table_start ( bus_driver );
14 static struct bus_driver bus_drivers_end[0] __table_end ( bus_driver );
15 static struct device_driver device_drivers[0] __table_start ( device_driver );
16 static struct device_driver device_drivers_end[0] __table_end (device_driver );
18 /* Current attempted boot device */
20 .bus_driver = bus_drivers,
21 .device_driver = device_drivers,
28 void print_drivers ( void ) {
29 struct device_driver *driver;
31 for ( driver = device_drivers ;
32 driver < device_drivers_end ;
34 printf ( "%s ", driver->name );
39 * Move to the next location on any bus
42 static inline int next_location ( struct bus_driver **bus_driver,
43 struct bus_loc *bus_loc ) {
44 /* Move to next location on this bus, if any */
45 if ( (*bus_driver)->next_location ( bus_loc ) )
48 /* Move to first (zeroed) location on next bus, if any */
49 if ( ++(*bus_driver) < bus_drivers_end ) {
50 DBG ( "DEV scanning %s bus\n", (*bus_driver)->name );
54 /* Reset to first bus, return "no more locations" */
55 *bus_driver = bus_drivers;
60 * Find the next available device on any bus
62 * Set skip=1 to skip over the current device
65 int find_any ( struct bus_driver **bus_driver, struct bus_loc *bus_loc,
66 struct bus_dev *bus_dev, signed int skip ) {
67 DBG ( "DEV scanning %s bus\n", (*bus_driver)->name );
71 if ( ! (*bus_driver)->fill_device ( bus_dev, bus_loc ) )
73 DBG ( "DEV found device %s\n",
74 (*bus_driver)->describe_device ( bus_dev ) );
76 } while ( next_location ( bus_driver, bus_loc ) );
78 DBG ( "DEV found no more devices\n" );
83 * Find a driver by specified device.
85 * Set skip=1 to skip over the current driver
88 int find_by_device ( struct device_driver **device_driver,
89 struct bus_driver *bus_driver, struct bus_dev *bus_dev,
94 if ( (*device_driver)->bus_driver != bus_driver )
96 if ( ! bus_driver->check_driver ( bus_dev, *device_driver ))
98 DBG ( "DEV found driver %s for device %s\n",
99 (*device_driver)->name,
100 bus_driver->describe_device ( bus_dev ) );
102 } while ( ++(*device_driver) < device_drivers_end );
104 /* Reset to first driver, return "not found" */
105 DBG ( "DEV found no driver for device %s\n",
106 bus_driver->describe_device ( bus_dev ) );
107 *device_driver = device_drivers;
112 * Find a device by specified driver.
114 * Set skip=1 to skip over the current device
117 int find_by_driver ( struct bus_loc *bus_loc, struct bus_dev *bus_dev,
118 struct device_driver *device_driver,
120 struct bus_driver *bus_driver = device_driver->bus_driver;
125 if ( ! bus_driver->fill_device ( bus_dev, bus_loc ) )
127 if ( ! bus_driver->check_driver ( bus_dev, device_driver ) )
129 DBG ( "DEV found device %s for driver %s\n",
130 bus_driver->describe_device ( bus_dev ),
131 device_driver->name );
133 } while ( bus_driver->next_location ( bus_loc ) );
135 DBG ( "DEV found no device for driver %s\n" );
140 * Find the next available (device,driver) combination
142 * Set skip=1 to skip over the current (device,driver)
144 * Note that the struct dev may not have been previously used, and so
145 * may not contain a valid (device,driver) combination.
148 int find_any_with_driver ( struct dev *dev, signed int skip ) {
149 signed int skip_device = 0;
150 signed int skip_driver = skip;
152 while ( find_any ( &dev->bus_driver, &dev->bus_loc, &dev->bus_dev,
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
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
163 dev->type_dev = dev->type_driver->type_dev;