Browse Source

Created a bus/device API that allows for the ROM prefix to specify an

initial device, and will also allow for e.g. a device menu to be presented
to the user.
tags/v0.9.3
Michael Brown 19 years ago
parent
commit
98ff29345e

+ 13
- 1
src/arch/i386/prefix/select_isapnp.c View File

1
+#include "dev.h"
1
 #include "isapnp.h"
2
 #include "isapnp.h"
2
 #include "registers.h"
3
 #include "registers.h"
3
 
4
 
16
 	 * address in %dx.
17
 	 * address in %dx.
17
 	 *
18
 	 *
18
 	 */
19
 	 */
19
-	select_isapnp_device ( regs->dx, regs->bx );
20
+	union {
21
+		struct bus_loc bus_loc;
22
+		struct isapnp_loc isapnp_loc;
23
+	} u;
24
+
25
+	/* Set ISAPnP read port */
26
+	isapnp_set_read_port ( regs->dx );
27
+	
28
+	/* Select ISAPnP bus and specified CSN as first boot device */
29
+	memset ( &u, 0, sizeof ( u ) );
30
+	u.isapnp_loc.csn = regs->bx;
31
+	select_device ( &dev, &isapnp_driver, &u.bus_loc );
20
 }
32
 }

+ 10
- 1
src/arch/i386/prefix/select_pci.c View File

1
+#include "dev.h"
1
 #include "pci.h"
2
 #include "pci.h"
2
 #include "registers.h"
3
 #include "registers.h"
3
 
4
 
15
 	 * PCI BIOS passes busdevfn in %ax
16
 	 * PCI BIOS passes busdevfn in %ax
16
 	 *
17
 	 *
17
 	 */
18
 	 */
18
-	select_pci_device ( regs->ax );
19
+	union {
20
+		struct bus_loc bus_loc;
21
+		struct pci_loc pci_loc;
22
+	} u;
23
+	
24
+	/* Select PCI bus and specified busdevfn as first boot device */
25
+	memset ( &u, 0, sizeof ( u ) );
26
+	u.pci_loc.busdevfn = regs->ax;
27
+	select_device ( &dev, &pci_driver, &u.bus_loc );
19
 }
28
 }

+ 9
- 3
src/arch/i386/scripts/i386.lds View File

142
 	*(.data.*)
142
 	*(.data.*)
143
 
143
 
144
 	/* Various tables */
144
 	/* Various tables */
145
-	boot_drivers = .;
146
-	*(.boot_drivers)
147
-	boot_drivers_end = .;
145
+	device_drivers = .;
146
+	*(.drivers.device)
147
+	device_drivers_end = .;
148
+	bus_drivers = .;
149
+	*(.drivers.bus)
150
+	bus_drivers_end = .;
151
+	type_drivers = .;
152
+	*(.drivers.type)
153
+	type_drivers_end = .;
148
 	console_drivers = .;
154
 	console_drivers = .;
149
 	*(.drivers.console)
155
 	*(.drivers.console)
150
 	console_drivers_end = .;
156
 	console_drivers_end = .;

+ 1
- 1
src/core/btext.c View File

408
 
408
 
409
     #warning "pci_find_device_x no longer exists; use find_pci_device instead"
409
     #warning "pci_find_device_x no longer exists; use find_pci_device instead"
410
     /*    pci_find_device_x(0x1002, 0x4752, 0, &dev); */
410
     /*    pci_find_device_x(0x1002, 0x4752, 0, &dev); */
411
-    if(dev.vendor==0) return; // no fb
411
+    if(dev.vendor_id==0) return; // no fb
412
 
412
 
413
     frame_buffer = (uint32_t)dev.membase;
413
     frame_buffer = (uint32_t)dev.membase;
414
 #else
414
 #else

+ 136
- 33
src/core/dev.c View File

16
  * function (probe).
16
  * function (probe).
17
  */
17
  */
18
 
18
 
19
-/* Defined by linker */
20
-extern struct boot_driver boot_drivers[];
21
-extern struct boot_driver boot_drivers_end[];
19
+/* Current attempted boot device */
20
+struct dev dev = {
21
+	.bus_driver = bus_drivers,
22
+	.device_driver = device_drivers,
23
+};
22
 
24
 
23
-/* Current attempted boot driver */
24
-static struct boot_driver *boot_driver = boot_drivers;
25
-
26
-/* Print all drivers */
25
+/*
26
+ * Print all drivers 
27
+ *
28
+ */
27
 void print_drivers ( void ) {
29
 void print_drivers ( void ) {
28
-	struct boot_driver *driver;
30
+	struct device_driver *driver;
29
 
31
 
30
-	for ( driver = boot_drivers ; driver < boot_drivers_end ; driver++ ) {
32
+	for ( driver = device_drivers ;
33
+	      driver < device_drivers_end ;
34
+	      driver++ ) {
31
 		printf ( "%s ", driver->name );
35
 		printf ( "%s ", driver->name );
32
 	}
36
 	}
33
 }
37
 }
34
 
38
 
35
-/* Get the next available boot device */
36
-int find_boot_device ( struct dev *dev ) {
37
-	for ( ; boot_driver < boot_drivers_end ; boot_driver++ ) {
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 );
46
-			return 1;
47
-		}
48
-	}
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 ( "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 ( "found device %s\n",
73
+		      (*bus_driver)->describe ( bus_dev ) );
74
+		return 1;
75
+	} while ( next_location ( bus_driver, bus_loc ) );
76
+
77
+	DBG ( "found no device\n" );
78
+	return 0;
79
+}
49
 
80
 
50
-	/* No more boot devices found */
51
-	boot_driver = boot_drivers;
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 ( "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 ( "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 ( "found no driver for device %s\n",
105
+	      bus_driver->describe ( bus_dev ) );
106
+	*device_driver = device_drivers;
52
 	return 0;
107
 	return 0;
53
 }
108
 }
54
 
109
 
55
-/* Probe the boot device */
56
-int probe ( struct dev *dev ) {
57
-	return dev->driver->probe ( dev, dev->bus );
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 ( "searching for a device for driver %s\n", device_driver->name );
122
+	do {
123
+		if ( --skip >= 0 )
124
+			continue;
125
+		if ( ! bus_driver->fill_device ( bus_dev, bus_loc ) )
126
+			continue;
127
+		if ( ! bus_driver->check_driver ( bus_dev, device_driver ) )
128
+			continue;
129
+		DBG ( "found device %s\n", bus_driver->describe ( bus_dev ) );
130
+		return 1;
131
+	} while ( bus_driver->next_location ( bus_loc ) );
132
+
133
+	DBG ( "found no device for driver %s\n" );
134
+	return 0;
58
 }
135
 }
59
 
136
 
60
-/* Disable a device */
61
-void disable ( struct dev *dev ) {
62
-	if ( dev->dev_op ) {
63
-		dev->dev_op->disable ( dev );
64
-		dev->dev_op = NULL;
137
+/*
138
+ * Find the next available (device,driver) combination
139
+ *
140
+ * Set skip=1 to skip over the current (device,driver)
141
+ *
142
+ * Note that the struct dev may not have been previously used, and so
143
+ * may not contain a valid (device,driver) combination.
144
+ *
145
+ */
146
+int find_any_with_driver ( struct dev *dev, signed int skip ) {
147
+	signed int skip_device = 0;
148
+	signed int skip_driver = skip;
149
+
150
+	while ( find_any ( &dev->bus_driver, &dev->bus_loc, &dev->bus_dev,
151
+			   skip_device ) ) {
152
+		if ( find_by_device ( &dev->device_driver, dev->bus_driver,
153
+				      &dev->bus_dev, skip_driver ) ) {
154
+			/* Set type_driver to be that of the device
155
+			 * driver
156
+			 */
157
+			dev->type_driver = dev->device_driver->type_driver;
158
+			/* Set type device instance to be the single
159
+			 * instance provided by the type driver
160
+			 */
161
+			dev->type_dev = dev->type_driver->type_dev;
162
+			return 1;
163
+		}
164
+		skip_driver = 0;
165
+		skip_device = 1;
65
 	}
166
 	}
167
+
168
+	return 0;
66
 }
169
 }

+ 18
- 26
src/core/main.c View File

143
 static int initialized;
143
 static int initialized;
144
 
144
 
145
 
145
 
146
-/* Global instance of the current boot device */
147
-DEV_BUS(struct bus_device, dev_bus);
148
-struct dev dev = {
149
-	.bus = &dev_bus,
150
-};
151
-
152
 /**************************************************************************
146
 /**************************************************************************
153
  * initialise() - perform any C-level initialisation
147
  * initialise() - perform any C-level initialisation
154
  *
148
  *
169
 MAIN - Kick off routine
163
 MAIN - Kick off routine
170
 **************************************************************************/
164
 **************************************************************************/
171
 int main ( void ) {
165
 int main ( void ) {
166
+	int skip = 0;
172
 
167
 
173
 	/* Print out configuration */
168
 	/* Print out configuration */
174
 	print_config();
169
 	print_config();
181
 	for ( ; ; disable ( &dev ), call_reset_fns() ) {
176
 	for ( ; ; disable ( &dev ), call_reset_fns() ) {
182
 
177
 
183
 		/* Get next boot device */
178
 		/* Get next boot device */
184
-		if ( ! find_boot_device ( &dev ) ) {
179
+		if ( ! find_any_with_driver ( &dev, skip ) ) {
185
 			/* Reached end of device list */
180
 			/* Reached end of device list */
186
 			printf ( "No more boot devices\n" );
181
 			printf ( "No more boot devices\n" );
182
+			skip = 0;
187
 			sleep ( 2 );
183
 			sleep ( 2 );
188
 			continue;
184
 			continue;
189
 		}
185
 		}
190
 
186
 
187
+		/* Skip this device the next time we encounter it */
188
+		skip = 1;
189
+
190
+		/* Print out what we're doing */
191
+		printf ( "Booting from %s %s at %s "
192
+			 "using the %s driver\n",
193
+			 dev.bus_driver->name ( &dev.bus_dev ),
194
+			 dev.type_driver->name,
195
+			 dev.bus_driver->describe ( &dev.bus_dev ),
196
+			 dev.device_driver->name );
197
+
191
 		/* Probe boot device */
198
 		/* Probe boot device */
192
 		if ( ! probe ( &dev ) ) {
199
 		if ( ! probe ( &dev ) ) {
193
 			/* Device found on bus, but probe failed */
200
 			/* Device found on bus, but probe failed */
194
-			printf ( "Probe failed on %s, trying next device\n",
195
-				 dev.name );
201
+			printf ( "...probe failed on %s\n" );
196
 			continue;
202
 			continue;
197
 		}
203
 		}
198
 		
204
 		
199
-		/* Print device info */
200
-		print_info ( &dev );
201
-
202
-		/* Load configuration (e.g. DHCP) */
203
-		if ( ! load_configuration ( &dev ) ) {
204
-			/* DHCP failed */
205
-			printf ( "Could not configure device %s\n", dev.name );
206
-			continue;
207
-		}
208
-
209
-		/* Load image */
210
-		if ( ! load ( &dev ) )
211
-			/* Load failed */
212
-			printf ( "Could not boot from device %s\n", dev.name );
213
-			continue;
205
+		printf ( "%s: %s\n", dev.bus_driver->name ( &dev.bus_dev ),
206
+			 dev.type_driver->describe ( dev.type_dev ) );
214
 	}
207
 	}
215
 
208
 
216
 	/* Call registered per-object exit functions */
209
 	/* Call registered per-object exit functions */
463
 	nfs_umountall(ARP_SERVER);
456
 	nfs_umountall(ARP_SERVER);
464
 #endif
457
 #endif
465
 	/* Stop receiving packets */
458
 	/* Stop receiving packets */
466
-	eth_disable();
467
-	disk_disable();
459
+	disable ( &dev );
468
 	initialized = 0;
460
 	initialized = 0;
469
 }
461
 }
470
 
462
 

+ 45
- 68
src/core/nic.c View File

52
 	/* Our enclosing DHCP tag */
52
 	/* Our enclosing DHCP tag */
53
 	RFC1533_VENDOR_ETHERBOOT_ENCAP, 11,
53
 	RFC1533_VENDOR_ETHERBOOT_ENCAP, 11,
54
 	/* Our boot device */
54
 	/* Our boot device */
55
-	RFC1533_VENDOR_NIC_DEV_ID, 5, PCI_BUS_TYPE, 0, 0, 0, 0,
55
+	RFC1533_VENDOR_NIC_DEV_ID, 5, 0, 0, 0, 0, 0,
56
 	/* Our current architecture */
56
 	/* Our current architecture */
57
 	RFC1533_VENDOR_ARCH, 2, EM_CURRENT & 0xff, (EM_CURRENT >> 8) & 0xff,
57
 	RFC1533_VENDOR_ARCH, 2, EM_CURRENT & 0xff, (EM_CURRENT >> 8) & 0xff,
58
 #ifdef EM_CURRENT_64
58
 #ifdef EM_CURRENT_64
231
 static unsigned short tcpudpchksum(struct iphdr *ip);
231
 static unsigned short tcpudpchksum(struct iphdr *ip);
232
 
232
 
233
 
233
 
234
-struct nic *nic = &dev.nic;
235
-
236
 /*
234
 /*
237
  * Find out what our boot parameters are
235
  * Find out what our boot parameters are
238
  */
236
  */
239
-static int nic_load_configuration ( struct dev *dev ) {
240
-	struct nic *nic = &dev->nic;
237
+static int nic_load_configuration ( struct nic *nic ) {
241
 	int server_found;
238
 	int server_found;
242
 
239
 
243
 	if ( ! nic->nic_op->connect ( nic ) ) {
240
 	if ( ! nic->nic_op->connect ( nic ) ) {
321
 	return 0;
318
 	return 0;
322
 }
319
 }
323
 
320
 
324
-
325
-static void nic_disable ( struct dev *dev ) {
326
-	struct nic *nic = &dev->nic;
327
-
321
+void nic_disable ( struct nic *nic __unused ) {
328
 #ifdef MULTICAST_LEVEL2
322
 #ifdef MULTICAST_LEVEL2
329
 	int i;
323
 	int i;
330
 	for(i = 0; i < MAX_IGMP; i++) {
324
 	for(i = 0; i < MAX_IGMP; i++) {
331
 		leave_group(i);
325
 		leave_group(i);
332
 	}
326
 	}
333
 #endif
327
 #endif
334
-	
335
-	nic->nic_op->disable ( nic );
336
 }
328
 }
337
 
329
 
338
-static void nic_print_info ( struct dev *dev ) {
339
-	struct nic *nic = &dev->nic;
340
-
341
-	printf ( "Found %s NIC (MAC %!)\n", dev->name, nic->node_addr );
330
+static char * nic_describe ( struct type_dev *type_dev ) {
331
+	struct nic *nic = ( struct nic * ) type_dev;
332
+	static char nic_description[] = "MAC 00:00:00:00:00:00";
333
+	
334
+	sprintf ( nic_description + 4, "%!", nic->node_addr );
335
+	return nic_description;
342
 }
336
 }
343
 
337
 
344
 /* 
338
 /* 
345
  * Device operations tables
339
  * Device operations tables
346
  *
340
  *
347
  */
341
  */
348
-static struct dev_operations nic_operations = {
349
-	.disable = nic_disable,
350
-	.print_info = nic_print_info,
351
-	.load_configuration = nic_load_configuration,
352
-	.load = nic_load,
342
+struct type_driver nic_driver = {
343
+	.name		= "NIC",
344
+	.type_dev	= ( struct type_dev * ) &nic,
345
+	.describe	= nic_describe,
353
 };
346
 };
354
 
347
 
355
 /* Careful.  We need an aligned buffer to avoid problems on machines
348
 /* Careful.  We need an aligned buffer to avoid problems on machines
360
  */
353
  */
361
 static char	packet[ETH_FRAME_LEN + ETH_DATA_ALIGN] __aligned;
354
 static char	packet[ETH_FRAME_LEN + ETH_DATA_ALIGN] __aligned;
362
 
355
 
363
-/*
364
- * Set up a struct dev to operate as a NIC, return the struct nic *
365
- *
366
- */
367
-struct nic * nic_device ( struct dev *dev ) {
368
-	struct nic *nic = &dev->nic;
369
-
370
-	memset ( nic, 0, sizeof ( *nic ) );
371
-	nic->node_addr = arptable[ARP_CLIENT].node;
372
-	nic->packet = packet + ETH_DATA_ALIGN;
373
-	dev->dev_op = &nic_operations;
374
-	return nic;
375
-}
356
+struct nic nic = {
357
+	.node_addr = arptable[ARP_CLIENT].node,
358
+	.packet = packet + ETH_DATA_ALIGN,
359
+};
376
 
360
 
377
 
361
 
378
 
362
 
408
 	struct	arprequest *arpreply;
392
 	struct	arprequest *arpreply;
409
 	if (ptype != ETH_P_ARP)
393
 	if (ptype != ETH_P_ARP)
410
 		return 0;
394
 		return 0;
411
-	if (nic->packetlen < ETH_HLEN + sizeof(struct arprequest))
395
+	if (nic.packetlen < ETH_HLEN + sizeof(struct arprequest))
412
 		return 0;
396
 		return 0;
413
-	arpreply = (struct arprequest *)&nic->packet[ETH_HLEN];
397
+	arpreply = (struct arprequest *)&nic.packet[ETH_HLEN];
414
 
398
 
415
 	if (arpreply->opcode != htons(ARP_REPLY)) 
399
 	if (arpreply->opcode != htons(ARP_REPLY)) 
416
 		return 0;
400
 		return 0;
697
 			continue; /* Back to waiting for packet */
681
 			continue; /* Back to waiting for packet */
698
 		}
682
 		}
699
 		/* Packet has been received */
683
 		/* Packet has been received */
700
-		rcvd = (struct tftp_t *)&nic->packet[ETH_HLEN];
684
+		rcvd = (struct tftp_t *)&nic.packet[ETH_HLEN];
701
 		recvlen = ntohs(rcvd->udp.len) - sizeof(struct udphdr)
685
 		recvlen = ntohs(rcvd->udp.len) - sizeof(struct udphdr)
702
 			- sizeof(rcvd->opcode);
686
 			- sizeof(rcvd->opcode);
703
 		rport = ntohs(rcvd->udp.src);
687
 		rport = ntohs(rcvd->udp.src);
777
 	struct arprequest *arpreply;
761
 	struct arprequest *arpreply;
778
 	if (ptype != ETH_P_RARP)
762
 	if (ptype != ETH_P_RARP)
779
 		return 0;
763
 		return 0;
780
-	if (nic->packetlen < ETH_HLEN + sizeof(struct arprequest))
764
+	if (nic.packetlen < ETH_HLEN + sizeof(struct arprequest))
781
 		return 0;
765
 		return 0;
782
-	arpreply = (struct arprequest *)&nic->packet[ETH_HLEN];
766
+	arpreply = (struct arprequest *)&nic.packet[ETH_HLEN];
783
 	if (arpreply->opcode != htons(RARP_REPLY))
767
 	if (arpreply->opcode != htons(RARP_REPLY))
784
 		return 0;
768
 		return 0;
785
 	if ((arpreply->opcode == htons(RARP_REPLY)) &&
769
 	if ((arpreply->opcode == htons(RARP_REPLY)) &&
841
 	if (!udp) {
825
 	if (!udp) {
842
 		return 0;
826
 		return 0;
843
 	}
827
 	}
844
-	bootpreply = (struct bootp_t *)&nic->packet[ETH_HLEN + 
828
+	bootpreply = (struct bootp_t *)&nic.packet[ETH_HLEN + 
845
 		sizeof(struct iphdr) + sizeof(struct udphdr)];
829
 		sizeof(struct iphdr) + sizeof(struct udphdr)];
846
-	if (nic->packetlen < ETH_HLEN + sizeof(struct iphdr) + 
830
+	if (nic.packetlen < ETH_HLEN + sizeof(struct iphdr) + 
847
 		sizeof(struct udphdr) + 
831
 		sizeof(struct udphdr) + 
848
 #ifdef NO_DHCP_SUPPORT
832
 #ifdef NO_DHCP_SUPPORT
849
 		sizeof(struct bootp_t)
833
 		sizeof(struct bootp_t)
916
 	unsigned char *bp_vend;
900
 	unsigned char *bp_vend;
917
 
901
 
918
 #ifndef	NO_DHCP_SUPPORT
902
 #ifndef	NO_DHCP_SUPPORT
919
-	struct {
920
-		uint8_t bus_type;
921
-		uint16_t vendor_id;
922
-		uint16_t device_id;
923
-	} __attribute__((packed)) *dhcp_dev_id = (void*)&dhcp_machine_info[4];
924
-	dhcp_dev_id->bus_type = dev.devid.bus_type;
925
-	dhcp_dev_id->vendor_id = htons ( dev.devid.vendor_id );
926
-	dhcp_dev_id->device_id = htons ( dev.devid.device_id );
903
+	* ( ( struct dhcp_dev_id * ) &dhcp_machine_info[4] ) = nic.dhcp_dev_id;
927
 #endif	/* NO_DHCP_SUPPORT */
904
 #endif	/* NO_DHCP_SUPPORT */
928
 	memset(&ip, 0, sizeof(struct bootpip_t));
905
 	memset(&ip, 0, sizeof(struct bootpip_t));
929
 	ip.bp.bp_op = BOOTP_REQUEST;
906
 	ip.bp.bp_op = BOOTP_REQUEST;
1089
 	int i;
1066
 	int i;
1090
 	unsigned iplen;
1067
 	unsigned iplen;
1091
 	if (!ip || (ip->protocol == IP_IGMP) ||
1068
 	if (!ip || (ip->protocol == IP_IGMP) ||
1092
-		(nic->packetlen < sizeof(struct iphdr) + sizeof(struct igmp))) {
1069
+		(nic.packetlen < sizeof(struct iphdr) + sizeof(struct igmp))) {
1093
 		return;
1070
 		return;
1094
 	}
1071
 	}
1095
 	iplen = (ip->verhdrlen & 0xf)*4;
1072
 	iplen = (ip->verhdrlen & 0xf)*4;
1096
-	igmp = (struct igmp *)&nic->packet[sizeof(struct iphdr)];
1073
+	igmp = (struct igmp *)&nic.packet[sizeof(struct iphdr)];
1097
 	if (ipchksum(igmp, ntohs(ip->len) - iplen) != 0)
1074
 	if (ipchksum(igmp, ntohs(ip->len) - iplen) != 0)
1098
 		return;
1075
 		return;
1099
 	if ((igmp->type == IGMP_QUERY) && 
1076
 	if ((igmp->type == IGMP_QUERY) && 
1300
 	       syn_ack = state == CLOSED || state == SYN_RCVD;
1277
 	       syn_ack = state == CLOSED || state == SYN_RCVD;
1301
 	       consumed = ntohl(tcp->ack) - send_seq - syn_ack;
1278
 	       consumed = ntohl(tcp->ack) - send_seq - syn_ack;
1302
 	       if (consumed < 0 || consumed > can_send) {
1279
 	       if (consumed < 0 || consumed > can_send) {
1303
-		       tcp_reset((struct iphdr *)&nic->packet[ETH_HLEN]);
1280
+		       tcp_reset((struct iphdr *)&nic.packet[ETH_HLEN]);
1304
 		       goto recv_data;
1281
 		       goto recv_data;
1305
 	       }
1282
 	       }
1306
 
1283
 
1342
        }
1319
        }
1343
 
1320
 
1344
  consume_data:
1321
  consume_data:
1345
-       ip  = (struct iphdr *)&nic->packet[ETH_HLEN];
1322
+       ip  = (struct iphdr *)&nic.packet[ETH_HLEN];
1346
        header_size = sizeof(struct iphdr) + ((ntohs(tcp->ctrl)>>10)&0x3C);
1323
        header_size = sizeof(struct iphdr) + ((ntohs(tcp->ctrl)>>10)&0x3C);
1347
        payload = ntohs(ip->len) - header_size;
1324
        payload = ntohs(ip->len) - header_size;
1348
        if (payload > 0 && state == ESTABLISHED) {
1325
        if (payload > 0 && state == ESTABLISHED) {
1351
 		       recv_seq += payload - old_bytes;
1328
 		       recv_seq += payload - old_bytes;
1352
 		       if (state != FIN_WAIT_1 && state != FIN_WAIT_2 &&
1329
 		       if (state != FIN_WAIT_1 && state != FIN_WAIT_2 &&
1353
 			   !recv(payload - old_bytes,
1330
 			   !recv(payload - old_bytes,
1354
-				 &nic->packet[ETH_HLEN+header_size+old_bytes],
1331
+				 &nic.packet[ETH_HLEN+header_size+old_bytes],
1355
 				 ptr)) {
1332
 				 ptr)) {
1356
 			       goto close;
1333
 			       goto close;
1357
 		       }
1334
 		       }
1463
 		/* We have something! */
1440
 		/* We have something! */
1464
 
1441
 
1465
 		/* Find the Ethernet packet type */
1442
 		/* Find the Ethernet packet type */
1466
-		if (nic->packetlen >= ETH_HLEN) {
1467
-			ptype = ((unsigned short) nic->packet[12]) << 8
1468
-				| ((unsigned short) nic->packet[13]);
1443
+		if (nic.packetlen >= ETH_HLEN) {
1444
+			ptype = ((unsigned short) nic.packet[12]) << 8
1445
+				| ((unsigned short) nic.packet[13]);
1469
 		} else continue; /* what else could we do with it? */
1446
 		} else continue; /* what else could we do with it? */
1470
 		/* Verify an IP header */
1447
 		/* Verify an IP header */
1471
 		ip = 0;
1448
 		ip = 0;
1472
-		if ((ptype == ETH_P_IP) && (nic->packetlen >= ETH_HLEN + sizeof(struct iphdr))) {
1449
+		if ((ptype == ETH_P_IP) && (nic.packetlen >= ETH_HLEN + sizeof(struct iphdr))) {
1473
 			unsigned ipoptlen;
1450
 			unsigned ipoptlen;
1474
-			ip = (struct iphdr *)&nic->packet[ETH_HLEN];
1451
+			ip = (struct iphdr *)&nic.packet[ETH_HLEN];
1475
 			if ((ip->verhdrlen < 0x45) || (ip->verhdrlen > 0x4F)) 
1452
 			if ((ip->verhdrlen < 0x45) || (ip->verhdrlen > 0x4F)) 
1476
 				continue;
1453
 				continue;
1477
 			iplen = (ip->verhdrlen & 0xf) * 4;
1454
 			iplen = (ip->verhdrlen & 0xf) * 4;
1493
 				/* Delete the ip options, to guarantee
1470
 				/* Delete the ip options, to guarantee
1494
 				 * good alignment, and make etherboot simpler.
1471
 				 * good alignment, and make etherboot simpler.
1495
 				 */
1472
 				 */
1496
-				memmove(&nic->packet[ETH_HLEN + sizeof(struct iphdr)], 
1497
-					&nic->packet[ETH_HLEN + iplen],
1498
-					nic->packetlen - ipoptlen);
1499
-				nic->packetlen -= ipoptlen;
1473
+				memmove(&nic.packet[ETH_HLEN + sizeof(struct iphdr)], 
1474
+					&nic.packet[ETH_HLEN + iplen],
1475
+					nic.packetlen - ipoptlen);
1476
+				nic.packetlen -= ipoptlen;
1500
 			}
1477
 			}
1501
 		}
1478
 		}
1502
 		udp = 0;
1479
 		udp = 0;
1503
 		if (ip && (ip->protocol == IP_UDP) && 
1480
 		if (ip && (ip->protocol == IP_UDP) && 
1504
-			(nic->packetlen >= 
1481
+			(nic.packetlen >= 
1505
 			ETH_HLEN + sizeof(struct iphdr) + sizeof(struct udphdr))) {
1482
 			ETH_HLEN + sizeof(struct iphdr) + sizeof(struct udphdr))) {
1506
-			udp = (struct udphdr *)&nic->packet[ETH_HLEN + sizeof(struct iphdr)];
1483
+			udp = (struct udphdr *)&nic.packet[ETH_HLEN + sizeof(struct iphdr)];
1507
 
1484
 
1508
 			/* Make certain we have a reasonable packet length */
1485
 			/* Make certain we have a reasonable packet length */
1509
 			if (ntohs(udp->len) > (ntohs(ip->len) - iplen))
1486
 			if (ntohs(udp->len) > (ntohs(ip->len) - iplen))
1517
 		tcp = 0;
1494
 		tcp = 0;
1518
 #ifdef DOWNLOAD_PROTO_HTTP
1495
 #ifdef DOWNLOAD_PROTO_HTTP
1519
 		if (ip && (ip->protocol == IP_TCP) &&
1496
 		if (ip && (ip->protocol == IP_TCP) &&
1520
-		    (nic->packetlen >=
1497
+		    (nic.packetlen >=
1521
 		     ETH_HLEN + sizeof(struct iphdr) + sizeof(struct tcphdr))){
1498
 		     ETH_HLEN + sizeof(struct iphdr) + sizeof(struct tcphdr))){
1522
-			tcp = (struct tcphdr *)&nic->packet[ETH_HLEN +
1499
+			tcp = (struct tcphdr *)&nic.packet[ETH_HLEN +
1523
 							 sizeof(struct iphdr)];
1500
 							 sizeof(struct iphdr)];
1524
 			/* Make certain we have a reasonable packet length */
1501
 			/* Make certain we have a reasonable packet length */
1525
 			if (((ntohs(tcp->ctrl) >> 10) & 0x3C) >
1502
 			if (((ntohs(tcp->ctrl) >> 10) & 0x3C) >
1541
 		 * action.  This allows us reply to arp, igmp, and lacp queries.
1518
 		 * action.  This allows us reply to arp, igmp, and lacp queries.
1542
 		 */
1519
 		 */
1543
 		if ((ptype == ETH_P_ARP) &&
1520
 		if ((ptype == ETH_P_ARP) &&
1544
-			(nic->packetlen >= ETH_HLEN + sizeof(struct arprequest))) {
1521
+			(nic.packetlen >= ETH_HLEN + sizeof(struct arprequest))) {
1545
 			struct	arprequest *arpreply;
1522
 			struct	arprequest *arpreply;
1546
 			unsigned long tmp;
1523
 			unsigned long tmp;
1547
 		
1524
 		
1548
-			arpreply = (struct arprequest *)&nic->packet[ETH_HLEN];
1525
+			arpreply = (struct arprequest *)&nic.packet[ETH_HLEN];
1549
 			memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr));
1526
 			memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr));
1550
 			if ((arpreply->opcode == htons(ARP_REQUEST)) &&
1527
 			if ((arpreply->opcode == htons(ARP_REQUEST)) &&
1551
 				(tmp == arptable[ARP_CLIENT].ipaddr.s_addr)) {
1528
 				(tmp == arptable[ARP_CLIENT].ipaddr.s_addr)) {

+ 14
- 14
src/core/pxe_export.c View File

169
 	if ( pxe_stack->state <= MIDWAY ) return 1;
169
 	if ( pxe_stack->state <= MIDWAY ) return 1;
170
 
170
 
171
 	eth_irq ( DISABLE );
171
 	eth_irq ( DISABLE );
172
-	eth_disable();
172
+	disable ( &dev );
173
 	pxe_stack->state = MIDWAY;
173
 	pxe_stack->state = MIDWAY;
174
 	return 1;
174
 	return 1;
175
 }
175
 }
433
 	 * the current value anyway then return success, otherwise
433
 	 * the current value anyway then return success, otherwise
434
 	 * return UNSUPPORTED.
434
 	 * return UNSUPPORTED.
435
 	 */
435
 	 */
436
-	if ( memcmp ( nic->node_addr,
436
+	if ( memcmp ( nic.node_addr,
437
 		      &undi_set_station_address->StationAddress,
437
 		      &undi_set_station_address->StationAddress,
438
 		      ETH_ALEN ) == 0 ) {
438
 		      ETH_ALEN ) == 0 ) {
439
 		undi_set_station_address->Status = PXENV_STATUS_SUCCESS;
439
 		undi_set_station_address->Status = PXENV_STATUS_SUCCESS;
465
 	DBG ( "PXENV_UNDI_GET_INFORMATION" );
465
 	DBG ( "PXENV_UNDI_GET_INFORMATION" );
466
 	ENSURE_READY ( undi_get_information );
466
 	ENSURE_READY ( undi_get_information );
467
 
467
 
468
-	undi_get_information->BaseIo = nic->ioaddr;
469
-	undi_get_information->IntNumber = nic->irqno;
468
+	undi_get_information->BaseIo = nic.ioaddr;
469
+	undi_get_information->IntNumber = nic.irqno;
470
 	/* Cheat: assume all cards can cope with this */
470
 	/* Cheat: assume all cards can cope with this */
471
 	undi_get_information->MaxTranUnit = ETH_MAX_MTU;
471
 	undi_get_information->MaxTranUnit = ETH_MAX_MTU;
472
 	/* Cheat: we only ever have Ethernet cards */
472
 	/* Cheat: we only ever have Ethernet cards */
476
 	 * node address.  This is a valid assumption within Etherboot
476
 	 * node address.  This is a valid assumption within Etherboot
477
 	 * at the time of writing.
477
 	 * at the time of writing.
478
 	 */
478
 	 */
479
-	memcpy ( &undi_get_information->CurrentNodeAddress, nic->node_addr,
479
+	memcpy ( &undi_get_information->CurrentNodeAddress, nic.node_addr,
480
 		 ETH_ALEN );
480
 		 ETH_ALEN );
481
-	memcpy ( &undi_get_information->PermNodeAddress, nic->node_addr,
481
+	memcpy ( &undi_get_information->PermNodeAddress, nic.node_addr,
482
 		 ETH_ALEN );
482
 		 ETH_ALEN );
483
 	undi_get_information->ROMAddress = 0;
483
 	undi_get_information->ROMAddress = 0;
484
-		/* nic->rom_info->rom_segment; */
484
+		/* nic.rom_info->rom_segment; */
485
 	/* We only provide the ability to receive or transmit a single
485
 	/* We only provide the ability to receive or transmit a single
486
 	 * packet at a time.  This is a bootloader, not an OS.
486
 	 * packet at a time.  This is a bootloader, not an OS.
487
 	 */
487
 	 */
637
  * Status: working
637
  * Status: working
638
  */
638
  */
639
 PXENV_EXIT_t pxenv_undi_isr ( t_PXENV_UNDI_ISR *undi_isr ) {
639
 PXENV_EXIT_t pxenv_undi_isr ( t_PXENV_UNDI_ISR *undi_isr ) {
640
-	media_header_t *media_header = (media_header_t*)nic->packet;
640
+	media_header_t *media_header = (media_header_t*)nic.packet;
641
 
641
 
642
 	DBG ( "PXENV_UNDI_ISR" );
642
 	DBG ( "PXENV_UNDI_ISR" );
643
 	/* We can't call ENSURE_READY, because this could be being
643
 	/* We can't call ENSURE_READY, because this could be being
683
 		 */
683
 		 */
684
 		DBG ( " PROCESS" );
684
 		DBG ( " PROCESS" );
685
 		if ( eth_poll ( 1 ) ) {
685
 		if ( eth_poll ( 1 ) ) {
686
-			DBG ( " RECEIVE %d", nic->packetlen );
687
-			if ( nic->packetlen > sizeof(pxe_stack->packet) ) {
686
+			DBG ( " RECEIVE %d", nic.packetlen );
687
+			if ( nic.packetlen > sizeof(pxe_stack->packet) ) {
688
 				/* Should never happen */
688
 				/* Should never happen */
689
 				undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_DONE;
689
 				undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_DONE;
690
 				undi_isr->Status =
690
 				undi_isr->Status =
692
 				return PXENV_EXIT_FAILURE;
692
 				return PXENV_EXIT_FAILURE;
693
 			}
693
 			}
694
 			undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_RECEIVE;
694
 			undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_RECEIVE;
695
-			undi_isr->BufferLength = nic->packetlen;
696
-			undi_isr->FrameLength = nic->packetlen;
695
+			undi_isr->BufferLength = nic.packetlen;
696
+			undi_isr->FrameLength = nic.packetlen;
697
 			undi_isr->FrameHeaderLength = ETH_HLEN;
697
 			undi_isr->FrameHeaderLength = ETH_HLEN;
698
-			memcpy ( pxe_stack->packet, nic->packet, nic->packetlen);
698
+			memcpy ( pxe_stack->packet, nic.packet, nic.packetlen);
699
 			PTR_TO_SEGOFF16 ( pxe_stack->packet, undi_isr->Frame );
699
 			PTR_TO_SEGOFF16 ( pxe_stack->packet, undi_isr->Frame );
700
 			switch ( ntohs(media_header->nstype) ) {
700
 			switch ( ntohs(media_header->nstype) ) {
701
 			case IP :	undi_isr->ProtType = P_IP;	break;
701
 			case IP :	undi_isr->ProtType = P_IP;	break;
1026
 PXENV_EXIT_t pxenv_udp_write ( t_PXENV_UDP_WRITE *udp_write ) {
1026
 PXENV_EXIT_t pxenv_udp_write ( t_PXENV_UDP_WRITE *udp_write ) {
1027
 	uint16_t src_port;
1027
 	uint16_t src_port;
1028
 	uint16_t dst_port;
1028
 	uint16_t dst_port;
1029
-	struct udppacket *packet = (struct udppacket *)nic->packet;
1029
+	struct udppacket *packet = (struct udppacket *)nic.packet;
1030
 	int packet_size;
1030
 	int packet_size;
1031
 
1031
 
1032
 	DBG ( "PXENV_UDP_WRITE" );
1032
 	DBG ( "PXENV_UDP_WRITE" );

+ 135
- 118
src/drivers/bus/pci.c View File

1
 #include "stdint.h"
1
 #include "stdint.h"
2
 #include "string.h"
2
 #include "string.h"
3
 #include "console.h"
3
 #include "console.h"
4
+#include "nic.h"
4
 #include "pci.h"
5
 #include "pci.h"
5
 
6
 
6
 /*
7
 /*
7
- * Ensure that there is sufficient space in the shared dev_bus
8
- * structure for a struct pci_device.
8
+ * pci_io.c may know how many buses we have, in which case it can
9
+ * overwrite this value.
9
  *
10
  *
10
  */
11
  */
11
-DEV_BUS( struct pci_device, pci_dev );
12
-static char pci_magic[0]; /* guaranteed unique symbol */
12
+unsigned int pci_max_bus = 0xff;
13
 
13
 
14
 /*
14
 /*
15
- * pci_io.c may know how many buses we have, in which case it can
16
- * overwrite this value.
15
+ * Increment a bus_loc structure to the next possible PCI location.
16
+ * Leave the structure zeroed and return 0 if there are no more valid
17
+ * locations.
17
  *
18
  *
18
  */
19
  */
19
-unsigned int pci_max_bus = 0xff;
20
+static int pci_next_location ( struct bus_loc *bus_loc ) {
21
+	struct pci_loc *pci_loc = ( struct pci_loc * ) bus_loc;
22
+	
23
+	/*
24
+	 * Ensure that there is sufficient space in the shared bus
25
+	 * structures for a struct pci_loc and a struct
26
+	 * pci_dev, as mandated by bus.h.
27
+	 *
28
+	 */
29
+	BUS_LOC_CHECK ( struct pci_loc );
30
+	BUS_DEV_CHECK ( struct pci_device );
31
+
32
+	return ( ++pci_loc->busdevfn );
33
+}
20
 
34
 
21
 /*
35
 /*
22
  * Fill in parameters (vendor & device ids, class, membase etc.) for a
36
  * Fill in parameters (vendor & device ids, class, membase etc.) for a
23
  * PCI device based on bus & devfn.
37
  * PCI device based on bus & devfn.
24
  *
38
  *
25
  * Returns 1 if a device was found, 0 for no device present.
39
  * Returns 1 if a device was found, 0 for no device present.
40
+ *
26
  */
41
  */
27
-static int fill_pci_device ( struct pci_device *pci ) {
42
+static int pci_fill_device ( struct bus_dev *bus_dev,
43
+			     struct bus_loc *bus_loc ) {
44
+	struct pci_loc *pci_loc = ( struct pci_loc * ) bus_loc;
45
+	struct pci_device *pci = ( struct pci_device * ) bus_dev;
46
+	uint16_t busdevfn = pci_loc->busdevfn;
28
 	static struct {
47
 	static struct {
29
 		uint16_t devfn0;
48
 		uint16_t devfn0;
30
 		int is_present;
49
 		int is_present;
32
 	uint32_t l;
51
 	uint32_t l;
33
 	int reg;
52
 	int reg;
34
 
53
 
54
+	/* Store busdevfn in struct pci_device and set default values */
55
+	pci->busdevfn = busdevfn;
56
+	pci->name = "?";
57
+
35
 	/* Check bus is within range */
58
 	/* Check bus is within range */
36
-	if ( PCI_BUS ( pci->busdevfn ) > pci_max_bus ) {
59
+	if ( PCI_BUS ( busdevfn ) > pci_max_bus ) {
37
 		return 0;
60
 		return 0;
38
 	}
61
 	}
39
 
62
 
41
 	 * non-zero function on a non-existent card.  This is done to
64
 	 * non-zero function on a non-existent card.  This is done to
42
 	 * increase scan speed by a factor of 8.
65
 	 * increase scan speed by a factor of 8.
43
 	 */
66
 	 */
44
-	if ( ( PCI_FUNC ( pci->busdevfn ) != 0 ) &&
45
-	     ( PCI_FN0 ( pci->busdevfn ) == cache.devfn0 ) &&
67
+	if ( ( PCI_FUNC ( busdevfn ) != 0 ) &&
68
+	     ( PCI_FN0 ( busdevfn ) == cache.devfn0 ) &&
46
 	     ( ! cache.is_present ) ) {
69
 	     ( ! cache.is_present ) ) {
47
 		return 0;
70
 		return 0;
48
 	}
71
 	}
52
 	pci_read_config_dword ( pci, PCI_VENDOR_ID, &l );
75
 	pci_read_config_dword ( pci, PCI_VENDOR_ID, &l );
53
 	/* some broken boards return 0 if a slot is empty: */
76
 	/* some broken boards return 0 if a slot is empty: */
54
 	if ( ( l == 0xffffffff ) || ( l == 0x00000000 ) ) {
77
 	if ( ( l == 0xffffffff ) || ( l == 0x00000000 ) ) {
55
-		if ( PCI_FUNC ( pci->busdevfn ) == 0 ) {
78
+		if ( PCI_FUNC ( busdevfn ) == 0 ) {
56
 			/* Don't look for subsequent functions if the
79
 			/* Don't look for subsequent functions if the
57
 			 * card itself is not present.
80
 			 * card itself is not present.
58
 			 */
81
 			 */
59
-			cache.devfn0 = pci->busdevfn;
82
+			cache.devfn0 = busdevfn;
60
 			cache.is_present = 0;
83
 			cache.is_present = 0;
61
 		}
84
 		}
62
 		return 0;
85
 		return 0;
63
 	}
86
 	}
64
-	pci->vendor = l & 0xffff;
65
-	pci->dev_id = ( l >> 16 ) & 0xffff;
87
+	pci->vendor_id = l & 0xffff;
88
+	pci->device_id = ( l >> 16 ) & 0xffff;
66
 	
89
 	
67
 	/* Check that we're not a duplicate function on a
90
 	/* Check that we're not a duplicate function on a
68
 	 * non-multifunction device.
91
 	 * non-multifunction device.
69
 	 */
92
 	 */
70
-	if ( PCI_FUNC ( pci->busdevfn ) != 0 ) {
71
-		uint16_t save_busdevfn = pci->busdevfn;
93
+	if ( PCI_FUNC ( busdevfn ) != 0 ) {
72
 		uint8_t header_type;
94
 		uint8_t header_type;
73
 
95
 
74
-		pci->busdevfn &= PCI_FN0 ( pci->busdevfn );
96
+		pci->busdevfn &= PCI_FN0 ( busdevfn );
75
 		pci_read_config_byte ( pci, PCI_HEADER_TYPE, &header_type );
97
 		pci_read_config_byte ( pci, PCI_HEADER_TYPE, &header_type );
76
-		pci->busdevfn = save_busdevfn;
98
+		pci->busdevfn = busdevfn;
77
 
99
 
78
 		if ( ! ( header_type & 0x80 ) ) {
100
 		if ( ! ( header_type & 0x80 ) ) {
79
 			return 0;
101
 			return 0;
108
 		pci_read_config_byte ( pci, PCI_INTERRUPT_LINE, &pci->irq );
130
 		pci_read_config_byte ( pci, PCI_INTERRUPT_LINE, &pci->irq );
109
 	}
131
 	}
110
 
132
 
111
-	DBG ( "PCI found device %hhx:%hhx.%d Class %hx: %hx:%hx (rev %hhx)\n",
133
+	DBG ( "found device %hhx:%hhx.%d Class %hx: %hx:%hx (rev %hhx)\n",
112
 	      PCI_BUS ( pci->busdevfn ), PCI_DEV ( pci->busdevfn ),
134
 	      PCI_BUS ( pci->busdevfn ), PCI_DEV ( pci->busdevfn ),
113
-	      PCI_FUNC ( pci->busdevfn ), pci->class, pci->vendor, pci->dev_id,
114
-	      pci->revision );
135
+	      PCI_FUNC ( pci->busdevfn ), pci->class, pci->vendor_id,
136
+	      pci->device_id, pci->revision );
115
 
137
 
116
 	return 1;
138
 	return 1;
117
 }
139
 }
118
 
140
 
141
+/*
142
+ * Test whether or not a driver is capable of driving the device.
143
+ *
144
+ */
145
+static int pci_check_driver ( struct bus_dev *bus_dev,
146
+		       struct device_driver *device_driver ) {
147
+	struct pci_device *pci = ( struct pci_device * ) bus_dev;
148
+	struct pci_driver_info *pci_driver_info
149
+		= ( struct pci_driver_info * ) device_driver->bus_driver_info;
150
+	unsigned int i;
151
+
152
+	/* If driver has a class, and class matches, use it */
153
+	if ( pci_driver_info->class && 
154
+	     ( pci_driver_info->class == pci->class ) ) {
155
+		DBG ( "driver %s matches class %hx\n",
156
+		      device_driver->name, pci_driver_info->class );
157
+		pci->name = device_driver->name;
158
+		return 1;
159
+	}
160
+		
161
+	/* If any of driver's IDs match, use it */
162
+	for ( i = 0 ; i < pci_driver_info->id_count; i++ ) {
163
+		struct pci_id *id = &pci_driver_info->ids[i];
164
+		
165
+		if ( ( pci->vendor_id == id->vendor_id ) &&
166
+		     ( pci->device_id == id->device_id ) ) {
167
+			DBG ( "driver %s device %s matches ID %hx:%hx\n",
168
+			      device_driver->name, id->name,
169
+			      id->vendor_id, id->device_id );
170
+			pci->name = id->name;
171
+			return 1;
172
+		}
173
+	}
174
+
175
+	return 0;
176
+}
177
+
178
+/*
179
+ * Describe a PCI device
180
+ *
181
+ */
182
+static char * pci_describe ( struct bus_dev *bus_dev ) {
183
+	struct pci_device *pci = ( struct pci_device * ) bus_dev;
184
+	static char pci_description[] = "PCI 00:00.0";
185
+
186
+	sprintf ( pci_description + 4, "%hhx:%hhx.%d",
187
+		  PCI_BUS ( pci->busdevfn ), PCI_DEV ( pci->busdevfn ),
188
+		  PCI_FUNC ( pci->busdevfn ) );
189
+	return pci_description;
190
+}
191
+
192
+/*
193
+ * Name a PCI device
194
+ *
195
+ */
196
+static char * pci_name ( struct bus_dev *bus_dev ) {
197
+	struct pci_device *pci = ( struct pci_device * ) bus_dev;
198
+	
199
+	return pci->name;
200
+}
201
+
202
+/*
203
+ * PCI bus operations table
204
+ *
205
+ */
206
+struct bus_driver pci_driver __bus_driver = {
207
+	.next_location	= pci_next_location,
208
+	.fill_device	= pci_fill_device,
209
+	.check_driver	= pci_check_driver,
210
+	.describe	= pci_describe,
211
+	.name		= pci_name,
212
+};
213
+
119
 /*
214
 /*
120
  * Set device to be a busmaster in case BIOS neglected to do so.  Also
215
  * Set device to be a busmaster in case BIOS neglected to do so.  Also
121
  * adjust PCI latency timer to a reasonable value, 32.
216
  * adjust PCI latency timer to a reasonable value, 32.
127
 	pci_read_config_word ( pci, PCI_COMMAND, &pci_command );
222
 	pci_read_config_word ( pci, PCI_COMMAND, &pci_command );
128
 	new_command = pci_command | PCI_COMMAND_MASTER | PCI_COMMAND_IO;
223
 	new_command = pci_command | PCI_COMMAND_MASTER | PCI_COMMAND_IO;
129
 	if ( pci_command != new_command ) {
224
 	if ( pci_command != new_command ) {
130
-		DBG ( "PCI BIOS has not enabled device %hhx:%hhx.%d! "
225
+		DBG ( "BIOS has not enabled device %hhx:%hhx.%d! "
131
 		      "Updating PCI command %hX->%hX\n",
226
 		      "Updating PCI command %hX->%hX\n",
132
 		      PCI_BUS ( pci->busdevfn ), PCI_DEV ( pci->busdevfn ),
227
 		      PCI_BUS ( pci->busdevfn ), PCI_DEV ( pci->busdevfn ),
133
 		      PCI_FUNC ( pci->busdevfn ), pci_command, new_command );
228
 		      PCI_FUNC ( pci->busdevfn ), pci_command, new_command );
135
 	}
230
 	}
136
 	pci_read_config_byte ( pci, PCI_LATENCY_TIMER, &pci_latency);
231
 	pci_read_config_byte ( pci, PCI_LATENCY_TIMER, &pci_latency);
137
 	if ( pci_latency < 32 ) {
232
 	if ( pci_latency < 32 ) {
138
-		DBG ( "PCI device %hhx:%hhx.%d latency timer is "
233
+		DBG ( "device %hhx:%hhx.%d latency timer is "
139
 		      "unreasonably low at %d. Setting to 32.\n",
234
 		      "unreasonably low at %d. Setting to 32.\n",
140
 		      PCI_BUS ( pci->busdevfn ), PCI_DEV ( pci->busdevfn ),
235
 		      PCI_BUS ( pci->busdevfn ), PCI_DEV ( pci->busdevfn ),
141
 		      PCI_FUNC ( pci->busdevfn ), pci_latency );
236
 		      PCI_FUNC ( pci->busdevfn ), pci_latency );
143
 	}
238
 	}
144
 }
239
 }
145
 
240
 
146
-/*
147
- * Set PCI device to use.
148
- *
149
- * This routine can be called by e.g. the ROM prefix to specify that
150
- * the first device to be tried should be the device on which the ROM
151
- * was physically located.
152
- *
153
- */
154
-void set_pci_device ( uint16_t busdevfn ) {
155
-	pci_dev.magic = pci_magic;
156
-	pci_dev.busdevfn = busdevfn;
157
-	pci_dev.already_tried = 0;
158
-}
159
-
160
-/*
161
- * Find a PCI device matching the specified driver
162
- *
163
- */
164
-int find_pci_device ( struct pci_device *pci,
165
-		      struct pci_driver *driver ) {
166
-	int i;
167
-
168
-	/* Initialise struct pci if it's the first time it's been used. */
169
-	if ( pci->magic != pci_magic ) {
170
-		memset ( pci, 0, sizeof ( *pci ) );
171
-		pci->magic = pci_magic;
172
-	}
173
-
174
-	/* Iterate through all possible PCI bus:dev.fn combinations,
175
-	 * starting where we left off.
176
-	 */
177
-	DBG ( "PCI searching for device matching driver %s\n", driver->name );
178
-	do {
179
-		/* If we've already used this device, skip it */
180
-		if ( pci->already_tried ) {
181
-			pci->already_tried = 0;
182
-			continue;
183
-		}
184
-		
185
-		/* Fill in device parameters, if device present */
186
-		if ( ! fill_pci_device ( pci ) ) {
187
-			continue;
188
-		}
189
-		
190
-		/* If driver has a class, and class matches, use it */
191
-		if ( driver->class && 
192
-		     ( driver->class == pci->class ) ) {
193
-			DBG ( "PCI found class %hx matching driver %s\n",
194
-			      driver->class, driver->name );
195
-			pci->name = driver->name;
196
-			pci->already_tried = 1;
197
-			return 1;
198
-		}
199
-		
200
-		/* If any of driver's IDs match, use it */
201
-		for ( i = 0 ; i < driver->id_count; i++ ) {
202
-			struct pci_id *id = &driver->ids[i];
203
-			
204
-			if ( ( pci->vendor == id->vendor ) &&
205
-			     ( pci->dev_id == id->dev_id ) ) {
206
-				DBG ( "PCI found ID %hx:%hx (device %s) "
207
-				      "matching driver %s\n", id->vendor,
208
-				      id->dev_id, id->name, driver->name );
209
-				pci->name = id->name;
210
-				pci->already_tried = 1;
211
-				return 1;
212
-			}
213
-		}
214
-	} while ( ++pci->busdevfn );
215
-
216
-	/* No device found */
217
-	DBG ( "PCI found no device matching driver %s\n", driver->name );
218
-	return 0;
219
-}
220
-
221
-/*
222
- * Find the next PCI device that can be used to boot using the
223
- * specified driver.
224
- *
225
- */
226
-int find_pci_boot_device ( struct dev *dev, struct pci_driver *driver ) {
227
-	struct pci_device *pci = ( struct pci_device * )dev->bus;
228
-
229
-	if ( ! find_pci_device ( pci, driver ) )
230
-		return 0;
231
-
232
-	dev->name = pci->name;
233
-	dev->devid.bus_type = PCI_BUS_TYPE;
234
-	dev->devid.vendor_id = pci->vendor;
235
-	dev->devid.device_id = pci->dev_id;
236
-
237
-	return 1;
238
-}
239
-
240
 /*
241
 /*
241
  * Find the start of a pci resource.
242
  * Find the start of a pci resource.
242
  */
243
  */
346
 	}
347
 	}
347
 	return 0;
348
 	return 0;
348
 }
349
 }
350
+
351
+/*
352
+ * Fill in a DHCP device ID structure
353
+ *
354
+ */
355
+void pci_fill_nic ( struct nic *nic, struct pci_device *pci ) {
356
+
357
+	/* Fill in ioaddr and irqno */
358
+	nic->ioaddr = pci->ioaddr;
359
+	nic->irqno = pci->irq;
360
+
361
+	/* Fill in DHCP device ID structure */
362
+	nic->dhcp_dev_id.bus_type = PCI_BUS_TYPE;
363
+	nic->dhcp_dev_id.vendor_id = htons ( pci->vendor_id );
364
+	nic->dhcp_dev_id.device_id = htons ( pci->device_id );
365
+}

+ 0
- 161
src/include/bus.h View File

1
-#ifndef BUS_H
2
-#define BUS_H
3
-
4
-#include "stdint.h"
5
-
6
-/*
7
- * When looking at the following data structures, mentally substitute
8
- * "<bus>_" in place of "bus_" and everything will become clear.
9
- * "struct bus_location" becomes "struct <bus>_location", which means
10
- * "the location of a device on a <bus> bus", where <bus> is a
11
- * particular type of bus such as "pci" or "isapnp".
12
- *
13
- */
14
-
15
-/*
16
- * A physical device location.
17
- *
18
- */
19
-#define BUS_LOCATION_SIZE 4
20
-struct bus_location {
21
-	char bytes[BUS_LOCATION_SIZE];
22
-};
23
-
24
-/* 
25
- * A structure fully describing a physical device.
26
- *
27
- */
28
-#define BUS_DEVICE_SIZE 32
29
-struct bus_device {
30
-	char bytes[BUS_DEVICE_SIZE];
31
-};
32
-
33
-/*
34
- * Individual buses will have different sizes for their <bus>_location
35
- * and <bus>_device structures.  We need to be able to allocate static
36
- * storage that's large enough to contain these structures for any
37
- * bus type that's being used in the current binary.
38
- *
39
- * We can't just create a union of all the various types, because some
40
- * may be architecture-dependent (and some are even embedded in
41
- * specific drivers, e.g. 3c509), so this would quickly get messy.
42
- *
43
- * We could use the magic of common symbols.  Each bus could declare a
44
- * common symbol with the name "_bus_device" of the correct size; this
45
- * is easily done using code like
46
- *	struct pci_device _bus_device;
47
- * The linker would then use the largest size of the "_bus_device"
48
- * symbol in any included object, thus giving us a single _bus_device
49
- * symbol of *exactly* the required size.  However, there's no way to
50
- * extract the size of this symbol, either directly as a linker symbol
51
- * ("_bus_device_size = SIZEOF(_bus_device)"; the linker language just
52
- * doesn't provide this construct) or via any linker trickery I can
53
- * think of (such as creating a special common symbol section just for
54
- * this symbol then using SIZE(section) to read the size of the
55
- * section; ld recognises only a single common symbol section called
56
- * "COMMON").
57
- *
58
- * Since there's no way to get the size of the symbol, this
59
- * effectively limits us to just one instance of the symbol.  This is
60
- * all very well for the simple case of "just boot from any single
61
- * device you can", but becomes limiting when you want to do things
62
- * like introducing PCMCIA buses (which must instantiate other devices
63
- * such as PCMCIA controllers).
64
- *
65
- * So, we declare the maximum sizes of these constructions to be
66
- * compile-time constants.  Each individual bus driver should define
67
- * its own struct <bus>_location and struct <bus>_device however it
68
- * likes, and can freely cast pointers from struct bus_location to
69
- * struct <bus>_location (and similarly for bus_device).  To guard
70
- * against bounding errors, each bus driver *MUST* use the macros
71
- * BUS_LOCATION_CHECK() and BUS_DEVICE_CHECK(), as in:
72
- *
73
- *   BUS_LOCATION_CHECK ( struct pci_location );
74
- *   BUS_DEVICE_CHECK ( struct pci_device );
75
- *
76
- * These macros will generate a link-time error if the size of the
77
- * <bus> structure exceeds the declared maximum size.
78
- *
79
- * The macros will generate no binary object code, but must be placed
80
- * inside a function (in order to generate syntactically valid C).
81
- * The easiest wy to do this is to place them in the
82
- * <bus>_next_location() function.
83
- *
84
- * If anyone can think of a better way of doing this that avoids *ALL*
85
- * of the problems described above, please implement it!
86
- *
87
- */
88
-
89
-#define LINKER_ASSERT(test,error_symbol)		\
90
-	if ( ! (test) ) {				\
91
-		extern void error_symbol ( void );	\
92
-		error_symbol();				\
93
-	}
94
-
95
-#define BUS_LOCATION_CHECK(datatype) \
96
-	LINKER_ASSERT( ( sizeof (datatype) < sizeof (struct bus_location) ),
97
-		       __BUS_LOCATION_SIZE_is_too_small__see_dev_h )
98
-#define BUS_DEVICE_CHECK(datatype) \
99
-	LINKER_ASSERT( ( sizeof (datatype) < sizeof (struct bus_device) ),
100
-		       __BUS_DEVICE_SIZE_is_too_small__see_dev_h )
101
-
102
-/*
103
- * A description of a device.  This is used to send information about
104
- * the device to a DHCP server, and to provide a text string to
105
- * describe the device to the user.
106
- *
107
- * Note that "text" is allowed to be NULL, in which case the
108
- * describe_device() method will print the information directly to the
109
- * console rather than writing it into a buffer.  (This happens
110
- * transparently because sprintf(NULL,...) is exactly equivalent to
111
- * printf(...) in our vsprintf.c).
112
- *
113
- */
114
-struct bus_description {
115
-	char *text;
116
-	uint16_t	vendor_id;
117
-	uint16_t	device_id;
118
-	uint8_t		bus_type;
119
-};
120
-
121
-/*
122
- * A driver definition
123
- *
124
- */
125
-struct bus_driver;
126
-
127
-/*
128
- * Bus-level operations.
129
- *
130
- * int next_location ( struct bus_location * bus_location )
131
- *
132
- *	Increment bus_location to point to the next possible device on
133
- *	the bus (e.g. the next PCI busdevfn, or the next ISAPnP CSN).
134
- *	If there are no more valid locations, return 0 and leave
135
- *	struct bus_location zeroed, otherwise return true.
136
- *
137
- * int fill_device ( struct bus_location *bus_location,
138
- *		     struct bus_device *bus_device )
139
- *
140
- *	Fill out a bus_device structure with the parameters for the
141
- *	device at bus_location.  (For example, fill in the PCI vendor
142
- *	and device IDs).  Return true if there is a device physically
143
- *	present at this location, otherwise 0.
144
- *
145
- * int check_driver ( )
146
- *
147
- */
148
-struct bus_operations {
149
-	int ( *next_location ) ( struct bus_location * bus_location );
150
-	int ( *fill_device ) ( struct bus_location * bus_location,
151
-			       struct bus_device * bus_device );
152
-	int ( *check_driver ) ( struct bus_device * bus_device,
153
-				struct bus_driver * bus_driver );
154
-	void ( *describe_device ) ( struct bus_device * bus_device,
155
-				    struct bus_driver * bus_driver,
156
-				    struct bus_description * bus_description );
157
-};
158
-
159
-
160
-
161
-#endif /* BUS_H */

+ 246
- 61
src/include/dev.h View File

2
 #define DEV_H
2
 #define DEV_H
3
 
3
 
4
 #include "stdint.h"
4
 #include "stdint.h"
5
+#include "string.h"
6
+#include "dhcp.h" /* for dhcp_dev_id */
5
 
7
 
6
-/* Device types */
7
-#include "nic.h"
8
+/*
9
+ * Forward declarations
10
+ *
11
+ */
12
+struct type_dev;
13
+struct type_driver;
14
+struct bus_driver;
15
+struct bus_dev;
16
+struct device_driver;
8
 
17
 
9
-/* Need to check the packing of this struct if Etherboot is ported */
10
-struct dev_id {
11
-	uint16_t	vendor_id;
12
-	uint16_t	device_id;
13
-	uint8_t		bus_type;
14
-#define	PCI_BUS_TYPE	1
15
-#define	ISA_BUS_TYPE	2
16
-#define MCA_BUS_TYPE	3
17
-} __attribute__ ((packed));
18
+/*
19
+ * When looking at the following data structures, mentally substitute
20
+ * "<bus>_" in place of "bus_" and everything will become clear.
21
+ * "struct bus_location" becomes "struct <bus>_location", which means
22
+ * "the location of a device on a <bus> bus", where <bus> is a
23
+ * particular type of bus such as "pci" or "isapnp".
24
+ *
25
+ */
18
 
26
 
19
-/* Dont use sizeof, that will include the padding */
20
-#define	DEV_ID_SIZE	8
27
+/*
28
+ * A physical device location on a bus.
29
+ *
30
+ */
31
+#define BUS_LOC_SIZE 4
32
+struct bus_loc {
33
+	char bytes[BUS_LOC_SIZE];
34
+};
21
 
35
 
22
-struct dev {
23
-	struct dev_operations *dev_op;
24
-	const char *name;
25
-	struct dev_id	devid;	/* device ID string (sent to DHCP server) */
26
-	struct boot_driver *driver; /* driver being used for boot */
27
-	/* Pointer to bus information for device.  Whatever sets up
28
-	 * the struct dev must make sure that this points to a buffer
29
-	 * large enough for the required struct <bus>_device.
30
-	 */
31
-	struct bus_device *bus;
32
-	/* All possible device types */
33
-	union {
34
-		struct nic	nic;
35
-	};
36
+/* 
37
+ * A structure fully describing a physical device on a bus.
38
+ *
39
+ */
40
+#define BUS_DEV_SIZE 32
41
+struct bus_dev {
42
+	char bytes[BUS_DEV_SIZE];
36
 };
43
 };
37
 
44
 
38
 /*
45
 /*
39
- * Macro to help create a common symbol with enough space for any
40
- * struct <bus>_device.
46
+ * Individual buses will have different sizes for their <bus>_location
47
+ * and <bus>_device structures.  We need to be able to allocate static
48
+ * storage that's large enough to contain these structures for any
49
+ * bus type that's being used in the current binary.
50
+ *
51
+ * We can't just create a union of all the various types, because some
52
+ * may be architecture-dependent (and some are even embedded in
53
+ * specific drivers, e.g. 3c509), so this would quickly get messy.
54
+ *
55
+ * We could use the magic of common symbols.  Each bus could declare a
56
+ * common symbol with the name "_bus_dev" of the correct size; this
57
+ * is easily done using code like
58
+ *	struct pci_device _bus_dev;
59
+ * The linker would then use the largest size of the "_bus_dev" symbol
60
+ * in any included object, thus giving us a single _bus_dev symbol of
61
+ * *exactly* the required size.  However, there's no way to extract
62
+ * the size of this symbol, either directly as a linker symbol
63
+ * ("_bus_dev_size = SIZEOF(_bus_dev)"; the linker language just
64
+ * doesn't provide this construct) or via any linker trickery I can
65
+ * think of (such as creating a special common symbol section just for
66
+ * this symbol then using SIZE(section) to read the size of the
67
+ * section; ld recognises only a single common symbol section called
68
+ * "COMMON").
69
+ *
70
+ * Since there's no way to get the size of the symbol, this
71
+ * effectively limits us to just one instance of the symbol.  This is
72
+ * all very well for the simple case of "just boot from any single
73
+ * device you can", but becomes limiting when you want to do things
74
+ * like introducing PCMCIA buses (which must instantiate other devices
75
+ * such as PCMCIA controllers).
76
+ *
77
+ * So, we declare the maximum sizes of these constructions to be
78
+ * compile-time constants.  Each individual bus driver should define
79
+ * its own struct <bus>_location and struct <bus>_device however it
80
+ * likes, and can freely cast pointers from struct bus_loc to
81
+ * struct <bus>_location (and similarly for bus_dev).  To guard
82
+ * against bounding errors, each bus driver *MUST* use the macros
83
+ * BUS_LOC_CHECK() and BUS_DEV_CHECK(), as in:
84
+ *
85
+ *   BUS_LOC_CHECK ( struct pci_location );
86
+ *   BUS_DEV_CHECK ( struct pci_device );
87
+ *
88
+ * These macros will generate a link-time error if the size of the
89
+ * <bus> structure exceeds the declared maximum size.
90
+ *
91
+ * The macros will generate no binary object code, but must be placed
92
+ * inside a function (in order to generate syntactically valid C).
93
+ * The easiest wy to do this is to place them in the
94
+ * <bus>_next_location() function.
95
+ *
96
+ * If anyone can think of a better way of doing this that avoids *ALL*
97
+ * of the problems described above, please implement it!
41
  *
98
  *
42
- * Use as e.g. DEV_BUS(struct pci_device);
43
  */
99
  */
44
-#define DEV_BUS(datatype,symbol) datatype symbol __asm__ ( "_dev_bus" );
45
 
100
 
46
-struct dev_operations {
47
-	void ( *disable ) ( struct dev * );
48
-	void ( *print_info ) ( struct dev * );
49
-	int ( *load_configuration ) ( struct dev * );
50
-	int ( *load ) ( struct dev * );
101
+#define LINKER_ASSERT(test,error_symbol)		\
102
+	if ( ! (test) ) {				\
103
+		extern void error_symbol ( void );	\
104
+		error_symbol();				\
105
+	}
106
+
107
+#define BUS_LOC_CHECK(datatype)					      \
108
+	LINKER_ASSERT( ( sizeof (datatype) < sizeof (struct bus_loc) ),  \
109
+		       __BUS_LOC_SIZE_is_too_small__see_dev_h )
110
+#define BUS_DEV_CHECK(datatype)					      \
111
+	LINKER_ASSERT( ( sizeof (datatype) < sizeof (struct bus_dev) ),    \
112
+		       __BUS_DEV_SIZE_is_too_small__see_dev_h )
113
+
114
+/*
115
+ * Bus-level operations.
116
+ *
117
+ * int next_location ( struct bus_loc * bus_loc )
118
+ *
119
+ *	Increment bus_loc to point to the next possible device on
120
+ *	the bus (e.g. the next PCI busdevfn, or the next ISAPnP CSN).
121
+ *	If there are no more valid locations, return 0 and leave
122
+ *	struct bus_loc zeroed, otherwise return true.
123
+ *
124
+ * int fill_device ( struct bus_dev *bus_dev,
125
+ *		     struct bus_loc *bus_loc )
126
+ *
127
+ *	Fill out a bus_dev structure with the parameters for the
128
+ *	device at bus_loc.  (For example, fill in the PCI vendor
129
+ *	and device IDs).  Return true if there is a device physically
130
+ *	present at this location, otherwise 0.
131
+ *
132
+ * int check_driver ( struct bus_dev *bus_dev,
133
+ *		      struct device_driver *device_driver )
134
+ *
135
+ *	Test whether or not the specified driver is capable of driving
136
+ *	the specified device by, for example, comparing the device's
137
+ *	PCI IDs against the list of PCI IDs claimed by the driver.
138
+ *
139
+ * char * describe ( struct bus_dev *bus_dev )
140
+ *
141
+ *	Return a text string describing the bus device bus_dev
142
+ *	(e.g. "PCI 00:01.2")
143
+ *
144
+ * char * name ( struct bus_dev *bus_dev )
145
+ *
146
+ *	Return a text string describing the bus device bus_dev
147
+ *	(e.g. "dfe538")
148
+ *
149
+ */
150
+struct bus_driver {
151
+	int ( *next_location ) ( struct bus_loc *bus_loc );
152
+	int ( *fill_device ) ( struct bus_dev *bus_dev,
153
+			       struct bus_loc *bus_loc );
154
+	int ( *check_driver ) ( struct bus_dev *bus_dev,
155
+				struct device_driver *device_driver );
156
+	char * ( *describe ) ( struct bus_dev *bus_dev );
157
+	char * ( *name ) ( struct bus_dev *bus_dev );
51
 };
158
 };
52
 
159
 
160
+#define __bus_driver __attribute__ (( used, __section__ ( ".drivers.bus" ) ))
161
+
53
 /*
162
 /*
54
- * Table to describe a bootable device driver.  See comments in dev.c
55
- * for an explanation.
163
+ * A structure fully describing the bus-independent parts of a
164
+ * particular type (e.g. nic or disk) of device.
165
+ *
166
+ * Unlike struct bus_dev, e can limit ourselves to having no more than
167
+ * one instance of this data structure.  We therefore place an
168
+ * instance in each type driver file (e.g. nic.c), and simply use a
169
+ * pointer to the struct type_dev in the struct dev.
56
  *
170
  *
57
  */
171
  */
58
-struct bus_device {};
59
-struct bus_driver {};
60
-struct boot_driver {
172
+struct type_dev;
173
+
174
+/*
175
+ * A type driver (e.g. nic, disk)
176
+ *
177
+ */
178
+struct type_driver {
61
 	char *name;
179
 	char *name;
62
-	struct bus_device * ( *find_bus_boot_device ) ( struct dev *dev,
63
-						   struct bus_driver *driver );
180
+	struct type_dev *type_dev; /* single instance */
181
+	char * ( * describe ) ( struct type_dev *type_dev );
182
+};
183
+
184
+#define __type_driver __attribute__ (( used, __section__ ( ".drivers.type" ) ))
185
+
186
+/*
187
+ * A driver for a device.
188
+ *
189
+ */
190
+struct device_driver {
191
+	const char *name;
192
+	struct type_driver *type_driver;
64
 	struct bus_driver *bus_driver;
193
 	struct bus_driver *bus_driver;
65
-	int ( *probe ) ( struct dev *dev, struct bus_device *bus_device );
194
+	struct bus_driver_info *bus_driver_info;
195
+	int ( * probe ) ( struct type_dev *type_dev,
196
+			  struct bus_dev *bus_dev );
197
+	void ( * disable ) ( struct type_dev *type_dev,
198
+			     struct bus_dev *bus_dev );
66
 };
199
 };
67
 
200
 
68
-#define BOOT_DRIVER( _name, _find_bus_boot_device, _bus_driver,	_probe )      \
69
-	static struct boot_driver boot_ ## _bus_driver			      \
70
-	    __attribute__ ((used,__section__(".boot_drivers"))) = {	      \
71
-		.name = _name,						      \
72
-		.find_bus_boot_device = ( void * ) _find_bus_boot_device,     \
73
-		.bus_driver = ( void * ) &_bus_driver,			      \
74
-		.probe = ( void * ) _probe,				      \
201
+#define __device_driver \
202
+	__attribute__ (( used, __section__ ( ".drivers.device" ) ))
203
+
204
+#define DRIVER(_name,_name_string,_type_driver,_bus_driver,_bus_info,	      \
205
+	       _probe,_disable) 		 			      \
206
+	static struct device_driver _name __device_driver = {		      \
207
+		.name = _name_string,					      \
208
+		.type_driver = &_type_driver,				      \
209
+		.bus_driver = &_bus_driver,				      \
210
+		.bus_driver_info = ( struct bus_driver_info * ) &_bus_info,   \
211
+		.probe = ( int (*) () ) _probe,				      \
212
+		.disable = ( void (*) () ) _disable,			      \
75
 	};
213
 	};
76
 
214
 
77
-/* Functions in dev.c */
215
+/*
216
+ * A bootable device, comprising a physical device on a bus, a driver
217
+ * for that device, and a type device
218
+ *
219
+ */
220
+struct dev {
221
+	struct bus_driver	*bus_driver;
222
+	struct bus_loc		bus_loc;
223
+	struct bus_dev		bus_dev;
224
+	struct device_driver	*device_driver;
225
+	struct type_driver	*type_driver;
226
+	struct type_dev		*type_dev;
227
+};
228
+
229
+/* The current boot device */
230
+extern struct dev dev;
231
+
232
+/*
233
+ * Functions in dev.c 
234
+ *
235
+ */
78
 extern void print_drivers ( void );
236
 extern void print_drivers ( void );
79
-extern int find_boot_device ( struct dev *dev );
80
-extern int probe ( struct dev *dev );
81
-extern void disable ( struct dev *dev );
82
-static inline void print_info ( struct dev *dev ) {
83
-	dev->dev_op->print_info ( dev );
237
+extern int find_any ( struct bus_driver **bus_driver, struct bus_loc *bus_loc,
238
+		      struct bus_dev *bus_dev, signed int skip );
239
+extern int find_by_device ( struct device_driver **device_driver,
240
+			    struct bus_driver *bus_driver,
241
+			    struct bus_dev *bus_dev,
242
+			    signed int skip );
243
+extern int find_by_driver ( struct bus_loc *bus_loc, struct bus_dev *bus_dev,
244
+			    struct device_driver *device_driver,
245
+			    signed int skip );
246
+extern int find_any_with_driver ( struct dev *dev, signed int skip );
247
+
248
+/*
249
+ * Functions inlined to save space
250
+ *
251
+ */
252
+
253
+/* Probe a device */
254
+static inline int probe ( struct dev *dev ) {
255
+	return dev->device_driver->probe ( dev->type_dev, &dev->bus_dev );
84
 }
256
 }
85
-static inline int load_configuration ( struct dev *dev ) {
86
-	return dev->dev_op->load_configuration ( dev );
257
+/* Disable a device */
258
+static inline void disable ( struct dev *dev ) {
259
+	dev->device_driver->disable ( dev->type_dev, &dev->bus_dev );
87
 }
260
 }
88
-static inline int load ( struct dev *dev ) {
89
-	return dev->dev_op->load ( dev );
261
+/* Set the default boot device */
262
+static inline void select_device ( struct dev *dev,
263
+				   struct bus_driver *bus_driver,
264
+				   struct bus_loc *bus_loc ) {
265
+	dev->bus_driver = bus_driver;
266
+	memcpy ( &dev->bus_loc, bus_loc, sizeof ( dev->bus_loc ) );
90
 }
267
 }
91
 
268
 
269
+/* Linker symbols for the various tables */
270
+extern struct bus_driver bus_drivers[];
271
+extern struct bus_driver bus_drivers_end[];
272
+extern struct type_driver type_drivers[];
273
+extern struct type_driver type_drivers_end[];
274
+extern struct device_driver device_drivers[];
275
+extern struct device_driver device_drivers_end[];
276
+
92
 #endif /* DEV_H */
277
 #endif /* DEV_H */

+ 12
- 0
src/include/dhcp.h View File

1
+#ifndef DHCP_H
2
+#define DHCP_H
3
+
4
+#include "stdint.h"
5
+
6
+struct dhcp_dev_id {
7
+	uint8_t		bus_type;
8
+	uint16_t	vendor_id;
9
+	uint16_t	device_id;
10
+} __attribute__ (( packed ));
11
+
12
+#endif /* DHCP_H */

+ 2
- 0
src/include/isa_ids.h View File

19
 
19
 
20
 #include "stdint.h"
20
 #include "stdint.h"
21
 
21
 
22
+#define	ISA_BUS_TYPE	2
23
+
22
 /*
24
 /*
23
  * Construct a vendor ID from three ASCII characters
25
  * Construct a vendor ID from three ASCII characters
24
  *
26
  *

+ 2
- 0
src/include/mca.h View File

11
 #include "isa_ids.h"
11
 #include "isa_ids.h"
12
 #include "dev.h"
12
 #include "dev.h"
13
 
13
 
14
+#define MCA_BUS_TYPE	3
15
+
14
 /*
16
 /*
15
  * MCA constants
17
  * MCA constants
16
  *
18
  *

+ 24
- 28
src/include/nic.h View File

8
 #ifndef	NIC_H
8
 #ifndef	NIC_H
9
 #define NIC_H
9
 #define NIC_H
10
 
10
 
11
+#include "dev.h"
12
+#include "byteswap.h"
13
+#include "dhcp.h"
14
+
11
 typedef enum {
15
 typedef enum {
12
 	DISABLE = 0,
16
 	DISABLE = 0,
13
 	ENABLE,
17
 	ENABLE,
24
  *	functions.
28
  *	functions.
25
  */
29
  */
26
 struct nic {
30
 struct nic {
27
-	struct nic_operations *nic_op;
28
-	int		flags;	/* driver specific flags */
29
-	unsigned char	*node_addr;
30
-	unsigned char	*packet;
31
-	unsigned int	packetlen;
32
-	unsigned int	ioaddr;
33
-	unsigned char	irqno;
34
-	unsigned int	mbps;
35
-	duplex_t	duplex;
36
-	void		*priv_data;	/* driver can hang private data here */
31
+	struct nic_operations	*nic_op;
32
+	int			flags;	/* driver specific flags */
33
+	unsigned char		*node_addr;
34
+	unsigned char		*packet;
35
+	unsigned int		packetlen;
36
+	unsigned int		ioaddr;
37
+	unsigned char		irqno;
38
+	unsigned int		mbps;
39
+	duplex_t		duplex;
40
+	struct dhcp_dev_id	dhcp_dev_id;
41
+	void			*priv_data;	/* driver private data */
37
 };
42
 };
38
 
43
 
39
 struct nic_operations {
44
 struct nic_operations {
42
 	void ( *transmit ) ( struct nic *, const char *,
47
 	void ( *transmit ) ( struct nic *, const char *,
43
 			     unsigned int, unsigned int, const char * );
48
 			     unsigned int, unsigned int, const char * );
44
 	void ( *irq ) ( struct nic *, irq_action_t );
49
 	void ( *irq ) ( struct nic *, irq_action_t );
45
-	void ( *disable ) ( struct nic * );
46
 };
50
 };
47
 
51
 
52
+extern struct type_driver nic_driver;
53
+
48
 /*
54
 /*
49
  * Function prototypes
55
  * Function prototypes
50
  *
56
  *
51
  */
57
  */
52
-struct dev;
53
-extern struct nic * nic_device ( struct dev * dev );
54
 extern int dummy_connect ( struct nic *nic );
58
 extern int dummy_connect ( struct nic *nic );
55
 extern void dummy_irq ( struct nic *nic, irq_action_t irq_action );
59
 extern void dummy_irq ( struct nic *nic, irq_action_t irq_action );
60
+extern void nic_disable ( struct nic *nic );
56
 
61
 
57
 /*
62
 /*
58
  * Functions that implicitly operate on the current boot device
63
  * Functions that implicitly operate on the current boot device
59
  *
64
  *
60
- * "nic" always points to &dev.nic
61
  */
65
  */
62
 
66
 
63
-extern struct nic *nic;
67
+extern struct nic nic;
64
 
68
 
65
 static inline int eth_connect ( void ) {
69
 static inline int eth_connect ( void ) {
66
-	return nic->nic_op->connect ( nic );
70
+	return nic.nic_op->connect ( &nic );
67
 }
71
 }
68
 
72
 
69
 static inline int eth_poll ( int retrieve ) {
73
 static inline int eth_poll ( int retrieve ) {
70
-	return nic->nic_op->poll ( nic, retrieve );
74
+	return nic.nic_op->poll ( &nic, retrieve );
71
 }
75
 }
72
 
76
 
73
 static inline void eth_transmit ( const char *dest, unsigned int type,
77
 static inline void eth_transmit ( const char *dest, unsigned int type,
74
 				  unsigned int size, const void *packet ) {
78
 				  unsigned int size, const void *packet ) {
75
-	nic->nic_op->transmit ( nic, dest, type, size, packet );
79
+	nic.nic_op->transmit ( &nic, dest, type, size, packet );
76
 }
80
 }
77
 
81
 
78
 static inline void eth_irq ( irq_action_t action ) {
82
 static inline void eth_irq ( irq_action_t action ) {
79
-	nic->nic_op->irq ( nic, action );
83
+	nic.nic_op->irq ( &nic, action );
80
 }
84
 }
81
 
85
 
82
 /* Should be using disable() rather than eth_disable() */
86
 /* Should be using disable() rather than eth_disable() */
83
-static inline void eth_disable ( void ) __attribute__ (( deprecated ));
84
-static inline void eth_disable ( void ) {
85
-	nic->nic_op->disable ( nic );
86
-}
87
-
88
-/* dev.h needs declarations from nic.h */
89
-#include "dev.h"
90
-/* to get global "dev" */
91
-#include "main.h"
87
+extern void eth_disable ( void ) __attribute__ (( deprecated ));
92
 
88
 
93
 #endif	/* NIC_H */
89
 #endif	/* NIC_H */

+ 55
- 38
src/include/pci.h View File

22
  */
22
  */
23
 
23
 
24
 #include "stdint.h"
24
 #include "stdint.h"
25
+#include "nic.h"
25
 #include "pci_ids.h"
26
 #include "pci_ids.h"
26
-#include "dev.h"
27
+
28
+#define	PCI_BUS_TYPE	1
27
 
29
 
28
 /*
30
 /*
29
  * PCI constants
31
  * PCI constants
234
 #define PCI_MSI_DATA_32		8	/* 16 bits of data for 32-bit devices */
236
 #define PCI_MSI_DATA_32		8	/* 16 bits of data for 32-bit devices */
235
 #define PCI_MSI_DATA_64		12	/* 16 bits of data for 64-bit devices */
237
 #define PCI_MSI_DATA_64		12	/* 16 bits of data for 64-bit devices */
236
 /*
238
 /*
237
- * A physical PCI device
239
+ * A location on a PCI bus
238
  *
240
  *
239
  */
241
  */
240
-struct pci_device {
241
-	char *			magic; /* must be first */
242
-	const char *		name;
243
-	uint32_t		membase;	/* BAR 1 */
244
-	uint32_t		ioaddr;		/* first IO BAR */
245
-	uint16_t		vendor, dev_id;
246
-	uint16_t		class;
242
+struct pci_loc {
247
 	uint16_t		busdevfn;
243
 	uint16_t		busdevfn;
248
-	uint8_t			revision;
249
-	uint8_t			irq;
250
-	uint8_t			already_tried;
251
 };
244
 };
245
+
246
+/*
247
+ * A physical PCI device
248
+ *
249
+ */
250
+struct pci_device {
251
+	const char *	name;
252
+	uint32_t	membase;	/* BAR 1 */
253
+	uint32_t	ioaddr;		/* first IO BAR */
254
+	uint16_t	vendor_id, device_id;
255
+	uint16_t	class;
256
+	uint16_t	busdevfn;
257
+	uint8_t		revision;
258
+	uint8_t		irq;
259
+} __attribute__ (( packed ));
260
+
261
+/*
262
+ * Useful busdevfn calculations
263
+ *
264
+ */
252
 #define PCI_BUS(busdevfn)	( ( uint8_t ) ( ( (busdevfn) >> 8 ) & 0xff ) )
265
 #define PCI_BUS(busdevfn)	( ( uint8_t ) ( ( (busdevfn) >> 8 ) & 0xff ) )
253
 #define PCI_DEV(busdevfn)	( ( uint8_t ) ( ( (busdevfn) >> 3 ) & 0x1f ) )
266
 #define PCI_DEV(busdevfn)	( ( uint8_t ) ( ( (busdevfn) >> 3 ) & 0x1f ) )
254
 #define PCI_FUNC(busdevfn)      ( ( uint8_t ) ( (busdevfn) & 0x07 ) )
267
 #define PCI_FUNC(busdevfn)      ( ( uint8_t ) ( (busdevfn) & 0x07 ) )
255
 #define PCI_FN0(busdevfn)	( ( uint16_t ) ( (busdevfn) & 0xfff8 ) )
268
 #define PCI_FN0(busdevfn)	( ( uint16_t ) ( (busdevfn) & 0xfff8 ) )
269
+#define PCI_MAX_BUSDEVFN	0xffff
256
 
270
 
257
 /*
271
 /*
258
  * An individual PCI device identified by vendor and device IDs
272
  * An individual PCI device identified by vendor and device IDs
259
  *
273
  *
260
  */
274
  */
261
 struct pci_id {
275
 struct pci_id {
262
-	unsigned short vendor, dev_id;
276
+	unsigned short vendor_id, device_id;
263
 	const char *name;
277
 	const char *name;
264
 };
278
 };
265
 
279
 
268
  * is also parsed by parserom.pl to generate Makefile rules and files
282
  * is also parsed by parserom.pl to generate Makefile rules and files
269
  * for rom-o-matic.
283
  * for rom-o-matic.
270
  */
284
  */
271
-#define PCI_ROM( rom_vendor, rom_dev_id, rom_name, rom_description ) {	\
272
-	.vendor = rom_vendor,						\
273
-	.dev_id = rom_dev_id,						\
274
-	.name = rom_name,						\
285
+#define PCI_ROM( _vendor_id, _device_id, _name, _description ) {	\
286
+	.vendor_id = _vendor_id,					\
287
+	.device_id = _device_id,					\
288
+	.name = _name,							\
275
 }
289
 }
276
 
290
 
277
 /*
291
 /*
278
- * A PCI driver, with a device ID (struct pci_id) table and an
279
- * optional class.
292
+ * A PCI driver information table, with a device ID (struct pci_id)
293
+ * table and an optional class.
280
  *
294
  *
281
  * Set the class to something other than PCI_NO_CLASS if the driver
295
  * Set the class to something other than PCI_NO_CLASS if the driver
282
  * can handle an entire class of devices.
296
  * can handle an entire class of devices.
283
  *
297
  *
284
  */
298
  */
285
-struct pci_driver {
286
-	const char *name;
299
+struct pci_driver_info {
287
 	struct pci_id *ids;
300
 	struct pci_id *ids;
288
-	int id_count;
301
+	unsigned int id_count;
289
 	uint16_t class;
302
 	uint16_t class;
290
 };
303
 };
291
 #define PCI_NO_CLASS 0
304
 #define PCI_NO_CLASS 0
294
  * Define a PCI driver.
307
  * Define a PCI driver.
295
  *
308
  *
296
  */
309
  */
297
-#define PCI_DRIVER( driver_name, pci_ids, pci_class ) {			\
298
-	.name = driver_name,						\
299
-	.ids = pci_ids,							\
300
-	.id_count = sizeof ( pci_ids ) / sizeof ( pci_ids[0] ),		\
301
-	.class = pci_class,						\
302
-}
310
+#define PCI_DRIVER( _info_name, _ids, _class )				\
311
+	static struct pci_driver_info _info_name = {			\
312
+		.ids = _ids,						\
313
+		.id_count = sizeof ( _ids ) / sizeof ( _ids[0] ),	\
314
+		.class = _class,					\
315
+	};
303
 
316
 
304
 /*
317
 /*
305
  * These are the functions we expect pci_io.c to provide.
318
  * These are the functions we expect pci_io.c to provide.
306
  *
319
  *
307
  */
320
  */
308
-extern int pci_read_config_byte	( struct pci_device *dev, unsigned int where,
321
+extern int pci_read_config_byte	( struct pci_device *pci, unsigned int where,
309
 				  uint8_t *value );
322
 				  uint8_t *value );
310
-extern int pci_write_config_byte ( struct pci_device *dev, unsigned int where,
323
+extern int pci_write_config_byte ( struct pci_device *pci, unsigned int where,
311
 				   uint8_t value );
324
 				   uint8_t value );
312
-extern int pci_read_config_word ( struct pci_device *dev, unsigned int where,
325
+extern int pci_read_config_word ( struct pci_device *pci, unsigned int where,
313
 				  uint16_t *value );
326
 				  uint16_t *value );
314
-extern int pci_write_config_word ( struct pci_device *dev, unsigned int where,
327
+extern int pci_write_config_word ( struct pci_device *pci, unsigned int where,
315
 				   uint16_t value );
328
 				   uint16_t value );
316
-extern int pci_read_config_dword ( struct pci_device *dev, unsigned int where,
329
+extern int pci_read_config_dword ( struct pci_device *pci, unsigned int where,
317
 				   uint32_t *value );
330
 				   uint32_t *value );
318
-extern int pci_write_config_dword ( struct pci_device *dev, unsigned int where,
331
+extern int pci_write_config_dword ( struct pci_device *pci, unsigned int where,
319
 				    uint32_t value );
332
 				    uint32_t value );
320
-extern unsigned long pci_bus_base ( struct pci_device *dev );
333
+extern unsigned long pci_bus_base ( struct pci_device *pci );
321
 
334
 
322
 /*
335
 /*
323
  * pci_io.c is allowed to overwrite pci_max_bus if it knows what the
336
  * pci_io.c is allowed to overwrite pci_max_bus if it knows what the
330
  * Functions in pci.c
343
  * Functions in pci.c
331
  *
344
  *
332
  */
345
  */
333
-extern int find_pci_device ( struct pci_device *pci,
334
-			     struct pci_driver *driver );
335
-extern int find_pci_boot_device ( struct dev *dev, struct pci_driver *driver );
336
 extern void adjust_pci_device ( struct pci_device *pci );
346
 extern void adjust_pci_device ( struct pci_device *pci );
337
 extern unsigned long pci_bar_start ( struct pci_device *pci,
347
 extern unsigned long pci_bar_start ( struct pci_device *pci,
338
 				     unsigned int bar );
348
 				     unsigned int bar );
339
 extern unsigned long pci_bar_size ( struct pci_device *pci, unsigned int bar );
349
 extern unsigned long pci_bar_size ( struct pci_device *pci, unsigned int bar );
340
 extern int pci_find_capability ( struct pci_device *pci, int capability );
350
 extern int pci_find_capability ( struct pci_device *pci, int capability );
351
+extern void pci_fill_nic ( struct nic *nic, struct pci_device *pci );
352
+
353
+/*
354
+ * PCI bus global definition
355
+ *
356
+ */
357
+extern struct bus_driver pci_driver;
341
 
358
 
342
 #endif	/* PCI_H */
359
 #endif	/* PCI_H */

Loading…
Cancel
Save