Browse Source

Fix up find_pci_device so that it can be used for scanning for devices

*other* than the main boot device.
tags/v0.9.3
Michael Brown 19 years ago
parent
commit
762fa9a478
5 changed files with 66 additions and 44 deletions
  1. 19
    1
      src/core/main.c
  2. 32
    37
      src/drivers/bus/pci.c
  3. 6
    1
      src/include/dev.h
  4. 3
    2
      src/include/main.h
  5. 6
    3
      src/include/pci.h

+ 19
- 1
src/core/main.c View File

@@ -176,7 +176,7 @@ int main ( void ) {
176 176
 	 *
177 177
 	 */
178 178
 	for ( ; ; disable ( &dev ), call_reset_fns() ) {
179
-	
179
+
180 180
 		/* Get next boot device */
181 181
 		if ( ! probe ( &dev ) ) {
182 182
 			/* Reached end of device list */
@@ -210,6 +210,24 @@ void exit(int status)
210 210
 }
211 211
 
212 212
 
213
+/*
214
+ * Set PCI device to use.
215
+ *
216
+ * This routine can be called by e.g. the ROM prefix to specify that
217
+ * the first device to be tried should be the device on which the ROM
218
+ * was physically located.
219
+ *
220
+ * Note that this is deliberately in main.c rather than pci.c, because
221
+ * this function should generalise to other bus types (e.g. ISAPnP),
222
+ * and we don't want to end up dragging in pci.o unnecessarily.
223
+ */
224
+void set_pci_device ( uint16_t busdevfn ) {
225
+	dev.devid.bus_type = PCI_BUS_TYPE;
226
+	dev.pci.busdevfn = busdevfn;
227
+	dev.pci.already_tried = 0;
228
+}
229
+
230
+
213 231
 #if 0
214 232
 
215 233
 static int main_loop(int state)

+ 32
- 37
src/drivers/bus/pci.c View File

@@ -11,9 +11,6 @@
11 11
 #define DBG(...)
12 12
 #endif
13 13
 
14
-static struct pci_device current;
15
-static char used_current;
16
-
17 14
 /*
18 15
  * Fill in parameters (vendor & device ids, class, membase etc.) for a
19 16
  * PCI device based on bus & devfn.
@@ -114,77 +111,76 @@ static void adjust_pci_device ( struct pci_device *pci ) {
114 111
 }
115 112
 
116 113
 /*
117
- * Set PCI device to use.
118
- *
119
- * This routine can be called by e.g. the ROM prefix to specify that
120
- * the first device to be tried should be the device on which the ROM
121
- * was physically located.
114
+ * Obtain a struct pci * from a struct dev *
122 115
  *
116
+ * If dev has not previously been used for a PCI device scan, blank
117
+ * out dev.pci
123 118
  */
124
-void set_pci_device ( uint16_t busdevfn ) {
125
-	current.busdevfn = busdevfn;
126
-	used_current = 0;
119
+struct pci_device * pci_device ( struct dev *dev ) {
120
+	struct pci_device *pci = &dev->pci;
121
+
122
+	if ( dev->devid.bus_type != PCI_BUS_TYPE ) {
123
+		memset ( pci, 0, sizeof ( *pci ) );
124
+	}
125
+	pci->dev = dev;
126
+	return pci;
127 127
 }
128 128
 
129 129
 /*
130 130
  * Find a PCI device matching the specified driver
131 131
  *
132
- * If "dev" is non-NULL, the struct dev will be filled in with any
133
- * relevant information.
134
- *
135 132
  */
136
-struct pci_device * find_pci_device ( struct pci_driver *driver,
137
-				      struct dev *dev ) {
133
+int find_pci_device ( struct pci_device *pci,
134
+		      struct pci_driver *driver ) {
138 135
 	int i;
139 136
 
140 137
 	/* Iterate through all possible PCI bus:dev.fn combinations,
141 138
 	 * starting where we left off.
142 139
 	 */
143
-	for ( ; current.busdevfn <= 0xffff ; current.busdevfn++ ) {
140
+	for ( ; pci->busdevfn <= 0xffff ; pci->busdevfn++ ) {
144 141
 		/* If we've already used this device, skip it */
145
-		if ( used_current ) {
146
-			used_current = 0;
142
+		if ( pci->already_tried ) {
143
+			pci->already_tried = 0;
147 144
 			continue;
148 145
 		}
149 146
 		
150 147
 		/* Fill in device parameters, if device present */
151
-		if ( ! fill_pci_device ( &current ) ) {
148
+		if ( ! fill_pci_device ( pci ) ) {
152 149
 			continue;
153 150
 		}
154 151
 		
155 152
 		/* Fix up PCI device */
156
-		adjust_pci_device ( &current );
153
+		adjust_pci_device ( pci );
157 154
 		
158 155
 		/* Fill in dev structure, if present */
159
-		if ( dev ) {
160
-			dev->name = driver->name;
161
-			dev->devid.vendor_id = current.vendor;
162
-			dev->devid.device_id = current.dev_id;
163
-			dev->devid.bus_type = PCI_BUS_TYPE;
156
+		if ( pci->dev ) {
157
+			pci->dev->name = driver->name;
158
+			pci->dev->devid.vendor_id = pci->vendor;
159
+			pci->dev->devid.device_id = pci->dev_id;
164 160
 		}
165 161
 
166 162
 		/* If driver has a class, and class matches, use it */
167 163
 		if ( driver->class && 
168
-		     ( driver->class == current.class ) ) {
164
+		     ( driver->class == pci->class ) ) {
169 165
 			DBG ( "Driver %s matches class %hx\n",
170 166
 			      driver->name, driver->class );
171
-			used_current = 1;
172
-			return &current;
167
+			pci->already_tried = 1;
168
+			return 1;
173 169
 		}
174 170
 		
175 171
 		/* If any of driver's IDs match, use it */
176 172
 		for ( i = 0 ; i < driver->id_count; i++ ) {
177 173
 			struct pci_id *id = &driver->ids[i];
178 174
 			
179
-			if ( ( current.vendor == id->vendor ) &&
180
-			     ( current.dev_id == id->dev_id ) ) {
175
+			if ( ( pci->vendor == id->vendor ) &&
176
+			     ( pci->dev_id == id->dev_id ) ) {
181 177
 				DBG ( "Device %s (driver %s) matches "
182 178
 				      "ID %hx:%hx\n", id->name, driver->name,
183 179
 				      id->vendor, id->dev_id );
184
-				if ( dev )
185
-					dev->name = id->name;
186
-				used_current = 1;
187
-				return &current;
180
+				if ( pci->dev )
181
+					pci->dev->name = id->name;
182
+				pci->already_tried = 1;
183
+				return 1;
188 184
 			}
189 185
 		}
190 186
 
@@ -192,8 +188,7 @@ struct pci_device * find_pci_device ( struct pci_driver *driver,
192 188
 	}
193 189
 
194 190
 	/* No device found */
195
-	memset ( &current, 0, sizeof ( current ) );
196
-	return NULL;
191
+	return 0;
197 192
 }
198 193
 
199 194
 /*

+ 6
- 1
src/include/dev.h View File

@@ -3,6 +3,7 @@
3 3
 
4 4
 #include "stdint.h"
5 5
 #include "nic.h"
6
+#include "pci.h"
6 7
 
7 8
 /* Need to check the packing of this struct if Etherboot is ported */
8 9
 struct dev_id {
@@ -17,9 +18,13 @@ struct dev_id {
17 18
 #define	DEV_ID_SIZE	8
18 19
 
19 20
 struct dev {
21
+	struct dev_operations *dev_op;
20 22
 	const char *name;
21 23
 	struct dev_id	devid;	/* device ID string (sent to DHCP server) */
22
-	struct dev_operations *dev_op;
24
+	/* All possible bus types */
25
+	union {
26
+		struct pci_device pci;
27
+	};
23 28
 	/* All possible device types */
24 29
 	union {
25 30
 		struct nic	nic;

+ 3
- 2
src/include/main.h View File

@@ -3,8 +3,9 @@
3 3
 
4 4
 #include "dev.h"
5 5
 
6
-extern int main ( void );
7
-
8 6
 extern struct dev dev;
9 7
 
8
+extern int main ( void );
9
+extern void set_pci_device ( uint16_t busdevfn );
10
+
10 11
 #endif /* MAIN_H */

+ 6
- 3
src/include/pci.h View File

@@ -237,7 +237,9 @@
237 237
  * A physical PCI device
238 238
  *
239 239
  */
240
+struct dev;
240 241
 struct pci_device {
242
+	struct dev *		dev;
241 243
 	uint32_t		membase;	/* BAR 1 */
242 244
 	uint32_t		ioaddr;		/* first IO BAR */
243 245
 	uint16_t		vendor, dev_id;
@@ -245,6 +247,7 @@ struct pci_device {
245 247
 	uint16_t		busdevfn;
246 248
 	uint8_t			revision;
247 249
 	uint8_t			irq;
250
+	uint8_t			already_tried;
248 251
 };
249 252
 #define PCI_BUS(busdevfn)	( ( (busdevfn) >> 8 ) & 0xff )
250 253
 #define PCI_DEV(busdevfn)	( ( (busdevfn) >> 3 ) & 0x1f )
@@ -319,9 +322,9 @@ extern unsigned long pci_bus_base ( struct pci_device *dev );
319 322
  * Functions in pci.c
320 323
  *
321 324
  */
322
-extern void set_pci_device ( uint16_t busdevfn );
323
-extern struct pci_device * find_pci_device ( struct pci_driver *driver,
324
-					     struct dev *dev );
325
+extern struct pci_device * pci_device ( struct dev *dev );
326
+extern int find_pci_device ( struct pci_device *pci,
327
+			     struct pci_driver *driver );
325 328
 extern unsigned long pci_bar_start ( struct pci_device *pci,
326 329
 				     unsigned int bar );
327 330
 extern unsigned long pci_bar_size ( struct pci_device *pci, unsigned int bar );

Loading…
Cancel
Save