Procházet zdrojové kódy

Separate out bus-scanning and device-probing logic.

tags/v0.9.3
Michael Brown před 19 roky
rodič
revize
ce8dea0dff
3 změnil soubory, kde provedl 62 přidání a 12 odebrání
  1. 30
    5
      src/core/dev.c
  2. 13
    2
      src/core/main.c
  3. 19
    5
      src/include/dev.h

+ 30
- 5
src/core/dev.c Zobrazit soubor

@@ -2,6 +2,20 @@
2 2
 #include "stddef.h"
3 3
 #include "dev.h"
4 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
+
5 19
 /* Defined by linker */
6 20
 extern struct boot_driver boot_drivers[];
7 21
 extern struct boot_driver boot_drivers_end[];
@@ -19,19 +33,30 @@ void print_drivers ( void ) {
19 33
 }
20 34
 
21 35
 /* Get the next available boot device */
22
-int probe ( struct dev *dev ) {
23
-	
36
+int find_boot_device ( struct dev *dev ) {
24 37
 	for ( ; boot_driver < boot_drivers_end ; boot_driver++ ) {
25
-		dev->name = "unknown";
26
-		if ( boot_driver->probe ( dev ) )
38
+		dev->driver = boot_driver;
39
+		dev->name = boot_driver->name;
40
+		DBG ( "Probing driver %s...\n", dev->name );
41
+		if (  boot_driver->find_bus_boot_device ( dev,
42
+						  boot_driver->bus_driver ) ) {
43
+			DBG ( "Found device %s (ID %hhx:%hx:%hx)\n",
44
+			      dev->name, dev->devid->bus_type,
45
+			      dev->devid->vendor_id, dev->devid->device_id );
27 46
 			return 1;
47
+		}
28 48
 	}
29
-	
49
+
30 50
 	/* No more boot devices found */
31 51
 	boot_driver = boot_drivers;
32 52
 	return 0;
33 53
 }
34 54
 
55
+/* Probe the boot device */
56
+int probe ( struct dev *dev ) {
57
+	return dev->driver->probe ( dev, dev->bus );
58
+}
59
+
35 60
 /* Disable a device */
36 61
 void disable ( struct dev *dev ) {
37 62
 	if ( dev->dev_op ) {

+ 13
- 2
src/core/main.c Zobrazit soubor

@@ -144,7 +144,7 @@ static int initialized;
144 144
 
145 145
 
146 146
 /* Global instance of the current boot device */
147
-DEV_BUS(struct {}, dev_bus);
147
+DEV_BUS(struct bus_device, dev_bus);
148 148
 struct dev dev = {
149 149
 	.bus = &dev_bus,
150 150
 };
@@ -181,8 +181,17 @@ int main ( void ) {
181 181
 	for ( ; ; disable ( &dev ), call_reset_fns() ) {
182 182
 
183 183
 		/* Get next boot device */
184
-		if ( ! probe ( &dev ) ) {
184
+		if ( ! find_boot_device ( &dev ) ) {
185 185
 			/* Reached end of device list */
186
+			printf ( "No more boot devices\n" );
187
+			continue;
188
+		}
189
+
190
+		/* Probe boot device */
191
+		if ( ! probe ( &dev ) ) {
192
+			/* Device found on bus, but probe failed */
193
+			printf ( "Probe failed on %s, trying next device\n",
194
+				 dev.name );
186 195
 			continue;
187 196
 		}
188 197
 		
@@ -192,12 +201,14 @@ int main ( void ) {
192 201
 		/* Load configuration (e.g. DHCP) */
193 202
 		if ( ! load_configuration ( &dev ) ) {
194 203
 			/* DHCP failed */
204
+			printf ( "Could not configure device %s\n", dev.name );
195 205
 			continue;
196 206
 		}
197 207
 
198 208
 		/* Load image */
199 209
 		if ( ! load ( &dev ) )
200 210
 			/* Load failed */
211
+			printf ( "Could not boot from device %s\n", dev.name );
201 212
 			continue;
202 213
 	}
203 214
 

+ 19
- 5
src/include/dev.h Zobrazit soubor

@@ -23,11 +23,12 @@ struct dev {
23 23
 	struct dev_operations *dev_op;
24 24
 	const char *name;
25 25
 	struct dev_id	devid;	/* device ID string (sent to DHCP server) */
26
+	struct boot_driver *driver; /* driver being used for boot */
26 27
 	/* Pointer to bus information for device.  Whatever sets up
27 28
 	 * the struct dev must make sure that this points to a buffer
28 29
 	 * large enough for the required struct <bus>_device.
29 30
 	 */
30
-	void *bus;
31
+	struct bus_device *bus;
31 32
 	/* All possible device types */
32 33
 	union {
33 34
 		struct nic	nic;
@@ -49,20 +50,33 @@ struct dev_operations {
49 50
 	int ( *load ) ( struct dev * );
50 51
 };
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 {};
52 60
 struct boot_driver {
53 61
 	char *name;
54
-	int (*probe) ( struct dev * );
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 );
55 66
 };
56 67
 
57
-#define BOOT_DRIVER( driver_name, probe_func )				      \
68
+#define BOOT_DRIVER( _name, _find_bus_boot_device, _bus_driver,	_probe )      \
58 69
 	static struct boot_driver boot_driver_ ## probe_func		      \
59 70
 	    __attribute__ ((used,__section__(".boot_drivers"))) = {	      \
60
-		.name = driver_name,					      \
61
-		.probe = probe_func,					      \
71
+		.name = _name,						      \
72
+		.find_bus_boot_device = ( void * ) _find_bus_boot_device,     \
73
+		.bus_driver = ( void * ) _bus_driver,			      \
74
+		.probe = ( void * ) _probe,				      \
62 75
 	};
63 76
 
64 77
 /* Functions in dev.c */
65 78
 extern void print_drivers ( void );
79
+extern int find_boot_device ( struct dev *dev );
66 80
 extern int probe ( struct dev *dev );
67 81
 extern void disable ( struct dev *dev );
68 82
 static inline void print_info ( struct dev *dev ) {

Načítá se…
Zrušit
Uložit