Browse Source

Add device to hierarchy before calling the driver's probe() function; this

way everything remains consistent if the probe() ends up creating child
devices.
tags/v0.9.3
Michael Brown 18 years ago
parent
commit
7b9617f5df
2 changed files with 34 additions and 36 deletions
  1. 18
    15
      src/core/device.c
  2. 16
    21
      src/drivers/bus/pci.c

+ 18
- 15
src/core/device.c View File

16
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
  */
17
  */
18
 
18
 
19
+#include <string.h>
19
 #include <gpxe/list.h>
20
 #include <gpxe/list.h>
20
 #include <gpxe/tables.h>
21
 #include <gpxe/tables.h>
21
 #include <gpxe/device.h>
22
 #include <gpxe/device.h>
34
 static LIST_HEAD ( devices );
35
 static LIST_HEAD ( devices );
35
 
36
 
36
 /**
37
 /**
37
- * Register a root device
38
+ * Probe a root device
38
  *
39
  *
39
  * @v rootdev		Root device
40
  * @v rootdev		Root device
40
  * @ret rc		Return status code
41
  * @ret rc		Return status code
41
- *
42
- * Calls the root device driver's probe() method, and adds it to the
43
- * list of registered root devices if successful.
44
  */
42
  */
45
-static int register_rootdev ( struct root_device *rootdev ) {
43
+static int rootdev_probe ( struct root_device *rootdev ) {
46
 	int rc;
44
 	int rc;
47
 
45
 
48
-	DBG ( "Registering %s root bus\n", rootdev->name );
49
-
50
-	if ( ( rc = rootdev->driver->probe ( rootdev ) ) != 0 )
46
+	DBG ( "Adding %s root bus\n", rootdev->name );
47
+	if ( ( rc = rootdev->driver->probe ( rootdev ) ) != 0 ) {
48
+		DBG ( "Failed to add %s root bus: %s\n",
49
+		      rootdev->name, strerror ( rc ) );
51
 		return rc;
50
 		return rc;
51
+	}
52
 
52
 
53
-	list_add ( &rootdev->dev.siblings, &devices );
54
 	return 0;
53
 	return 0;
55
 }
54
 }
56
 
55
 
57
 /**
56
 /**
58
- * Unregister a root device
57
+ * Remove a root device
59
  *
58
  *
60
  * @v rootdev		Root device
59
  * @v rootdev		Root device
61
  */
60
  */
62
-static void unregister_rootdev ( struct root_device *rootdev ) {
61
+static void rootdev_remove ( struct root_device *rootdev ) {
63
 	rootdev->driver->remove ( rootdev );
62
 	rootdev->driver->remove ( rootdev );
64
-	list_del ( &rootdev->dev.siblings );
65
-	DBG ( "Unregistered %s root bus\n", rootdev->name );
63
+	DBG ( "Removed %s root bus\n", rootdev->name );
66
 }
64
 }
67
 
65
 
68
 /**
66
 /**
76
  */
74
  */
77
 int probe_devices ( void ) {
75
 int probe_devices ( void ) {
78
 	struct root_device *rootdev;
76
 	struct root_device *rootdev;
77
+	int rc;
79
 
78
 
80
 	for ( rootdev = root_devices; rootdev < root_devices_end; rootdev++ ) {
79
 	for ( rootdev = root_devices; rootdev < root_devices_end; rootdev++ ) {
81
-		register_rootdev ( rootdev );
80
+		list_add ( &rootdev->dev.siblings, &devices );
81
+		INIT_LIST_HEAD ( &rootdev->dev.children );
82
+		if ( ( rc = rootdev_probe ( rootdev ) ) != 0 )
83
+			list_del ( &rootdev->dev.siblings );
82
 	}
84
 	}
83
 	return 0;
85
 	return 0;
84
 }
86
 }
92
 	struct root_device *tmp;
94
 	struct root_device *tmp;
93
 
95
 
94
 	list_for_each_entry_safe ( rootdev, tmp, &devices, dev.siblings ) {
96
 	list_for_each_entry_safe ( rootdev, tmp, &devices, dev.siblings ) {
95
-		unregister_rootdev ( rootdev );
97
+		rootdev_remove ( rootdev );
98
+		list_del ( &rootdev->dev.siblings );
96
 	}
99
 	}
97
 }
100
 }

+ 16
- 21
src/drivers/bus/pci.c View File

165
 }
165
 }
166
 
166
 
167
 /**
167
 /**
168
- * Register PCI device
168
+ * Probe a PCI device
169
  *
169
  *
170
  * @v pci		PCI device
170
  * @v pci		PCI device
171
  * @ret rc		Return status code
171
  * @ret rc		Return status code
172
  *
172
  *
173
  * Searches for a driver for the PCI device.  If a driver is found,
173
  * Searches for a driver for the PCI device.  If a driver is found,
174
- * its probe() routine is called, and the device is added to the
175
- * device hierarchy.
174
+ * its probe() routine is called.
176
  */
175
  */
177
-static int register_pcidev ( struct pci_device *pci ) {
176
+static int pci_probe ( struct pci_device *pci ) {
178
 	struct pci_driver *driver;
177
 	struct pci_driver *driver;
179
 	struct pci_device_id *id;
178
 	struct pci_device_id *id;
180
 	unsigned int i;
179
 	unsigned int i;
181
 	int rc;
180
 	int rc;
182
 
181
 
183
-	DBG ( "Registering PCI device %02x:%02x.%x (%04x:%04x mem %lx "
184
-	      "io %lx irq %d)\n", pci->bus, PCI_SLOT ( pci->devfn ),
182
+	DBG ( "Adding PCI device %02x:%02x.%x (%04x:%04x mem %lx io %lx "
183
+	      "irq %d)\n", pci->bus, PCI_SLOT ( pci->devfn ),
185
 	      PCI_FUNC ( pci->devfn ), pci->vendor, pci->device,
184
 	      PCI_FUNC ( pci->devfn ), pci->vendor, pci->device,
186
 	      pci->membase, pci->ioaddr, pci->irq );
185
 	      pci->membase, pci->ioaddr, pci->irq );
187
 
186
 
198
 				DBG ( "......probe failed\n" );
197
 				DBG ( "......probe failed\n" );
199
 				continue;
198
 				continue;
200
 			}
199
 			}
201
-			list_add ( &pci->dev.siblings,
202
-				   &pci->dev.parent->children );
203
 			return 0;
200
 			return 0;
204
 		}
201
 		}
205
 	}
202
 	}
209
 }
206
 }
210
 
207
 
211
 /**
208
 /**
212
- * Unregister a PCI device
209
+ * Remove a PCI device
213
  *
210
  *
214
  * @v pci		PCI device
211
  * @v pci		PCI device
215
- *
216
- * Calls the device's driver's remove() routine, and removes the
217
- * device from the device hierarchy.
218
  */
212
  */
219
-static void unregister_pcidev ( struct pci_device *pci ) {
213
+static void pci_remove ( struct pci_device *pci ) {
220
 	pci->driver->remove ( pci );
214
 	pci->driver->remove ( pci );
221
-	list_del ( &pci->dev.siblings );
222
-	DBG ( "Unregistered PCI device %02x:%02x.%x\n", pci->bus,
215
+	DBG ( "Removed PCI device %02x:%02x.%x\n", pci->bus,
223
 	      PCI_SLOT ( pci->devfn ), PCI_FUNC ( pci->devfn ) );
216
 	      PCI_SLOT ( pci->devfn ), PCI_FUNC ( pci->devfn ) );
224
 }
217
 }
225
 
218
 
278
 			pci_read_config_byte ( pci, PCI_INTERRUPT_LINE,
271
 			pci_read_config_byte ( pci, PCI_INTERRUPT_LINE,
279
 					       &pci->irq );
272
 					       &pci->irq );
280
 			pci_read_bases ( pci );
273
 			pci_read_bases ( pci );
281
-			INIT_LIST_HEAD ( &pci->dev.children );
274
+
275
+			/* Add to device hierarchy */
282
 			pci->dev.parent = &rootdev->dev;
276
 			pci->dev.parent = &rootdev->dev;
277
+			list_add ( &pci->dev.siblings, &rootdev->dev.children);
278
+			INIT_LIST_HEAD ( &pci->dev.children );
283
 			
279
 			
284
 			/* Look for a driver */
280
 			/* Look for a driver */
285
-			if ( register_pcidev ( pci ) == 0 ) {
281
+			if ( pci_probe ( pci ) == 0 ) {
286
 				/* pcidev registered, we can drop our ref */
282
 				/* pcidev registered, we can drop our ref */
287
 				pci = NULL;
283
 				pci = NULL;
288
 			} else {
284
 			} else {
289
 				/* Not registered; re-use struct pci_device */
285
 				/* Not registered; re-use struct pci_device */
286
+				list_del ( &pci->dev.siblings );
290
 			}
287
 			}
291
 		}
288
 		}
292
 	}
289
 	}
311
 
308
 
312
 	list_for_each_entry_safe ( pci, tmp, &rootdev->dev.children,
309
 	list_for_each_entry_safe ( pci, tmp, &rootdev->dev.children,
313
 				   dev.siblings ) {
310
 				   dev.siblings ) {
314
-		unregister_pcidev ( pci );
311
+		pci_remove ( pci );
312
+		list_del ( &pci->dev.siblings );
315
 		free ( pci );
313
 		free ( pci );
316
 	}
314
 	}
317
 }
315
 }
326
 struct root_device pci_root_device __root_device = {
324
 struct root_device pci_root_device __root_device = {
327
 	.name = "PCI",
325
 	.name = "PCI",
328
 	.driver = &pci_root_driver,
326
 	.driver = &pci_root_driver,
329
-	.dev = {
330
-		.children = LIST_HEAD_INIT ( pci_root_device.dev.children ),
331
-	},
332
 };
327
 };

Loading…
Cancel
Save