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,3 +1,4 @@
1
+#include "dev.h"
1 2
 #include "isapnp.h"
2 3
 #include "registers.h"
3 4
 
@@ -16,5 +17,16 @@ void i386_select_isapnp_device ( struct i386_all_regs *regs ) {
16 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,3 +1,4 @@
1
+#include "dev.h"
1 2
 #include "pci.h"
2 3
 #include "registers.h"
3 4
 
@@ -15,5 +16,13 @@ void i386_select_pci_device ( struct i386_all_regs *regs ) {
15 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,9 +142,15 @@ SECTIONS {
142 142
 	*(.data.*)
143 143
 
144 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 154
 	console_drivers = .;
149 155
 	*(.drivers.console)
150 156
 	console_drivers_end = .;

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

@@ -408,7 +408,7 @@ static void btext_init(void)
408 408
 
409 409
     #warning "pci_find_device_x no longer exists; use find_pci_device instead"
410 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 413
     frame_buffer = (uint32_t)dev.membase;
414 414
 #else

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

@@ -16,51 +16,154 @@
16 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 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 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 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,12 +143,6 @@ static int exit_status;
143 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 147
  * initialise() - perform any C-level initialisation
154 148
  *
@@ -169,6 +163,7 @@ void initialise ( void ) {
169 163
 MAIN - Kick off routine
170 164
 **************************************************************************/
171 165
 int main ( void ) {
166
+	int skip = 0;
172 167
 
173 168
 	/* Print out configuration */
174 169
 	print_config();
@@ -181,36 +176,34 @@ int main ( void ) {
181 176
 	for ( ; ; disable ( &dev ), call_reset_fns() ) {
182 177
 
183 178
 		/* Get next boot device */
184
-		if ( ! find_boot_device ( &dev ) ) {
179
+		if ( ! find_any_with_driver ( &dev, skip ) ) {
185 180
 			/* Reached end of device list */
186 181
 			printf ( "No more boot devices\n" );
182
+			skip = 0;
187 183
 			sleep ( 2 );
188 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 198
 		/* Probe boot device */
192 199
 		if ( ! probe ( &dev ) ) {
193 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 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 209
 	/* Call registered per-object exit functions */
@@ -463,8 +456,7 @@ void cleanup(void)
463 456
 	nfs_umountall(ARP_SERVER);
464 457
 #endif
465 458
 	/* Stop receiving packets */
466
-	eth_disable();
467
-	disk_disable();
459
+	disable ( &dev );
468 460
 	initialized = 0;
469 461
 }
470 462
 

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

@@ -52,7 +52,7 @@ static unsigned char dhcp_machine_info[] = {
52 52
 	/* Our enclosing DHCP tag */
53 53
 	RFC1533_VENDOR_ETHERBOOT_ENCAP, 11,
54 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 56
 	/* Our current architecture */
57 57
 	RFC1533_VENDOR_ARCH, 2, EM_CURRENT & 0xff, (EM_CURRENT >> 8) & 0xff,
58 58
 #ifdef EM_CURRENT_64
@@ -231,13 +231,10 @@ static int bootp(void);
231 231
 static unsigned short tcpudpchksum(struct iphdr *ip);
232 232
 
233 233
 
234
-struct nic *nic = &dev.nic;
235
-
236 234
 /*
237 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 238
 	int server_found;
242 239
 
243 240
 	if ( ! nic->nic_op->connect ( nic ) ) {
@@ -321,35 +318,31 @@ static int nic_load(struct dev *dev __unused)
321 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 322
 #ifdef MULTICAST_LEVEL2
329 323
 	int i;
330 324
 	for(i = 0; i < MAX_IGMP; i++) {
331 325
 		leave_group(i);
332 326
 	}
333 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 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 348
 /* Careful.  We need an aligned buffer to avoid problems on machines
@@ -360,19 +353,10 @@ static struct dev_operations nic_operations = {
360 353
  */
361 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,9 +392,9 @@ static int await_arp(int ival, void *ptr,
408 392
 	struct	arprequest *arpreply;
409 393
 	if (ptype != ETH_P_ARP)
410 394
 		return 0;
411
-	if (nic->packetlen < ETH_HLEN + sizeof(struct arprequest))
395
+	if (nic.packetlen < ETH_HLEN + sizeof(struct arprequest))
412 396
 		return 0;
413
-	arpreply = (struct arprequest *)&nic->packet[ETH_HLEN];
397
+	arpreply = (struct arprequest *)&nic.packet[ETH_HLEN];
414 398
 
415 399
 	if (arpreply->opcode != htons(ARP_REPLY)) 
416 400
 		return 0;
@@ -697,7 +681,7 @@ int tftp_block ( struct tftpreq_info_t *request, struct tftpblk_info_t *block )
697 681
 			continue; /* Back to waiting for packet */
698 682
 		}
699 683
 		/* Packet has been received */
700
-		rcvd = (struct tftp_t *)&nic->packet[ETH_HLEN];
684
+		rcvd = (struct tftp_t *)&nic.packet[ETH_HLEN];
701 685
 		recvlen = ntohs(rcvd->udp.len) - sizeof(struct udphdr)
702 686
 			- sizeof(rcvd->opcode);
703 687
 		rport = ntohs(rcvd->udp.src);
@@ -777,9 +761,9 @@ static int await_rarp(int ival, void *ptr,
777 761
 	struct arprequest *arpreply;
778 762
 	if (ptype != ETH_P_RARP)
779 763
 		return 0;
780
-	if (nic->packetlen < ETH_HLEN + sizeof(struct arprequest))
764
+	if (nic.packetlen < ETH_HLEN + sizeof(struct arprequest))
781 765
 		return 0;
782
-	arpreply = (struct arprequest *)&nic->packet[ETH_HLEN];
766
+	arpreply = (struct arprequest *)&nic.packet[ETH_HLEN];
783 767
 	if (arpreply->opcode != htons(RARP_REPLY))
784 768
 		return 0;
785 769
 	if ((arpreply->opcode == htons(RARP_REPLY)) &&
@@ -841,9 +825,9 @@ static int await_bootp(int ival __unused, void *ptr __unused,
841 825
 	if (!udp) {
842 826
 		return 0;
843 827
 	}
844
-	bootpreply = (struct bootp_t *)&nic->packet[ETH_HLEN + 
828
+	bootpreply = (struct bootp_t *)&nic.packet[ETH_HLEN + 
845 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 831
 		sizeof(struct udphdr) + 
848 832
 #ifdef NO_DHCP_SUPPORT
849 833
 		sizeof(struct bootp_t)
@@ -916,14 +900,7 @@ static int bootp(void)
916 900
 	unsigned char *bp_vend;
917 901
 
918 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 904
 #endif	/* NO_DHCP_SUPPORT */
928 905
 	memset(&ip, 0, sizeof(struct bootpip_t));
929 906
 	ip.bp.bp_op = BOOTP_REQUEST;
@@ -1089,11 +1066,11 @@ static void process_igmp(struct iphdr *ip, unsigned long now)
1089 1066
 	int i;
1090 1067
 	unsigned iplen;
1091 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 1070
 		return;
1094 1071
 	}
1095 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 1074
 	if (ipchksum(igmp, ntohs(ip->len) - iplen) != 0)
1098 1075
 		return;
1099 1076
 	if ((igmp->type == IGMP_QUERY) && 
@@ -1300,7 +1277,7 @@ int tcp_transaction(unsigned long destip, unsigned int destsock, void *ptr,
1300 1277
 	       syn_ack = state == CLOSED || state == SYN_RCVD;
1301 1278
 	       consumed = ntohl(tcp->ack) - send_seq - syn_ack;
1302 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 1281
 		       goto recv_data;
1305 1282
 	       }
1306 1283
 
@@ -1342,7 +1319,7 @@ int tcp_transaction(unsigned long destip, unsigned int destsock, void *ptr,
1342 1319
        }
1343 1320
 
1344 1321
  consume_data:
1345
-       ip  = (struct iphdr *)&nic->packet[ETH_HLEN];
1322
+       ip  = (struct iphdr *)&nic.packet[ETH_HLEN];
1346 1323
        header_size = sizeof(struct iphdr) + ((ntohs(tcp->ctrl)>>10)&0x3C);
1347 1324
        payload = ntohs(ip->len) - header_size;
1348 1325
        if (payload > 0 && state == ESTABLISHED) {
@@ -1351,7 +1328,7 @@ int tcp_transaction(unsigned long destip, unsigned int destsock, void *ptr,
1351 1328
 		       recv_seq += payload - old_bytes;
1352 1329
 		       if (state != FIN_WAIT_1 && state != FIN_WAIT_2 &&
1353 1330
 			   !recv(payload - old_bytes,
1354
-				 &nic->packet[ETH_HLEN+header_size+old_bytes],
1331
+				 &nic.packet[ETH_HLEN+header_size+old_bytes],
1355 1332
 				 ptr)) {
1356 1333
 			       goto close;
1357 1334
 		       }
@@ -1463,15 +1440,15 @@ int await_reply(reply_t reply, int ival, void *ptr, long timeout)
1463 1440
 		/* We have something! */
1464 1441
 
1465 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 1446
 		} else continue; /* what else could we do with it? */
1470 1447
 		/* Verify an IP header */
1471 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 1450
 			unsigned ipoptlen;
1474
-			ip = (struct iphdr *)&nic->packet[ETH_HLEN];
1451
+			ip = (struct iphdr *)&nic.packet[ETH_HLEN];
1475 1452
 			if ((ip->verhdrlen < 0x45) || (ip->verhdrlen > 0x4F)) 
1476 1453
 				continue;
1477 1454
 			iplen = (ip->verhdrlen & 0xf) * 4;
@@ -1493,17 +1470,17 @@ int await_reply(reply_t reply, int ival, void *ptr, long timeout)
1493 1470
 				/* Delete the ip options, to guarantee
1494 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 1479
 		udp = 0;
1503 1480
 		if (ip && (ip->protocol == IP_UDP) && 
1504
-			(nic->packetlen >= 
1481
+			(nic.packetlen >= 
1505 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 1485
 			/* Make certain we have a reasonable packet length */
1509 1486
 			if (ntohs(udp->len) > (ntohs(ip->len) - iplen))
@@ -1517,9 +1494,9 @@ int await_reply(reply_t reply, int ival, void *ptr, long timeout)
1517 1494
 		tcp = 0;
1518 1495
 #ifdef DOWNLOAD_PROTO_HTTP
1519 1496
 		if (ip && (ip->protocol == IP_TCP) &&
1520
-		    (nic->packetlen >=
1497
+		    (nic.packetlen >=
1521 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 1500
 							 sizeof(struct iphdr)];
1524 1501
 			/* Make certain we have a reasonable packet length */
1525 1502
 			if (((ntohs(tcp->ctrl) >> 10) & 0x3C) >
@@ -1541,11 +1518,11 @@ int await_reply(reply_t reply, int ival, void *ptr, long timeout)
1541 1518
 		 * action.  This allows us reply to arp, igmp, and lacp queries.
1542 1519
 		 */
1543 1520
 		if ((ptype == ETH_P_ARP) &&
1544
-			(nic->packetlen >= ETH_HLEN + sizeof(struct arprequest))) {
1521
+			(nic.packetlen >= ETH_HLEN + sizeof(struct arprequest))) {
1545 1522
 			struct	arprequest *arpreply;
1546 1523
 			unsigned long tmp;
1547 1524
 		
1548
-			arpreply = (struct arprequest *)&nic->packet[ETH_HLEN];
1525
+			arpreply = (struct arprequest *)&nic.packet[ETH_HLEN];
1549 1526
 			memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr));
1550 1527
 			if ((arpreply->opcode == htons(ARP_REQUEST)) &&
1551 1528
 				(tmp == arptable[ARP_CLIENT].ipaddr.s_addr)) {

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

@@ -169,7 +169,7 @@ int pxe_shutdown_nic ( void ) {
169 169
 	if ( pxe_stack->state <= MIDWAY ) return 1;
170 170
 
171 171
 	eth_irq ( DISABLE );
172
-	eth_disable();
172
+	disable ( &dev );
173 173
 	pxe_stack->state = MIDWAY;
174 174
 	return 1;
175 175
 }
@@ -433,7 +433,7 @@ PXENV_EXIT_t pxenv_undi_set_station_address ( t_PXENV_UNDI_SET_STATION_ADDRESS
433 433
 	 * the current value anyway then return success, otherwise
434 434
 	 * return UNSUPPORTED.
435 435
 	 */
436
-	if ( memcmp ( nic->node_addr,
436
+	if ( memcmp ( nic.node_addr,
437 437
 		      &undi_set_station_address->StationAddress,
438 438
 		      ETH_ALEN ) == 0 ) {
439 439
 		undi_set_station_address->Status = PXENV_STATUS_SUCCESS;
@@ -465,8 +465,8 @@ PXENV_EXIT_t pxenv_undi_get_information ( t_PXENV_UNDI_GET_INFORMATION
465 465
 	DBG ( "PXENV_UNDI_GET_INFORMATION" );
466 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 470
 	/* Cheat: assume all cards can cope with this */
471 471
 	undi_get_information->MaxTranUnit = ETH_MAX_MTU;
472 472
 	/* Cheat: we only ever have Ethernet cards */
@@ -476,12 +476,12 @@ PXENV_EXIT_t pxenv_undi_get_information ( t_PXENV_UNDI_GET_INFORMATION
476 476
 	 * node address.  This is a valid assumption within Etherboot
477 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 480
 		 ETH_ALEN );
481
-	memcpy ( &undi_get_information->PermNodeAddress, nic->node_addr,
481
+	memcpy ( &undi_get_information->PermNodeAddress, nic.node_addr,
482 482
 		 ETH_ALEN );
483 483
 	undi_get_information->ROMAddress = 0;
484
-		/* nic->rom_info->rom_segment; */
484
+		/* nic.rom_info->rom_segment; */
485 485
 	/* We only provide the ability to receive or transmit a single
486 486
 	 * packet at a time.  This is a bootloader, not an OS.
487 487
 	 */
@@ -637,7 +637,7 @@ PXENV_EXIT_t pxenv_undi_get_iface_info ( t_PXENV_UNDI_GET_IFACE_INFO
637 637
  * Status: working
638 638
  */
639 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 642
 	DBG ( "PXENV_UNDI_ISR" );
643 643
 	/* We can't call ENSURE_READY, because this could be being
@@ -683,8 +683,8 @@ PXENV_EXIT_t pxenv_undi_isr ( t_PXENV_UNDI_ISR *undi_isr ) {
683 683
 		 */
684 684
 		DBG ( " PROCESS" );
685 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 688
 				/* Should never happen */
689 689
 				undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_DONE;
690 690
 				undi_isr->Status =
@@ -692,10 +692,10 @@ PXENV_EXIT_t pxenv_undi_isr ( t_PXENV_UNDI_ISR *undi_isr ) {
692 692
 				return PXENV_EXIT_FAILURE;
693 693
 			}
694 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 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 699
 			PTR_TO_SEGOFF16 ( pxe_stack->packet, undi_isr->Frame );
700 700
 			switch ( ntohs(media_header->nstype) ) {
701 701
 			case IP :	undi_isr->ProtType = P_IP;	break;
@@ -1026,7 +1026,7 @@ PXENV_EXIT_t pxenv_udp_read ( t_PXENV_UDP_READ *udp_read ) {
1026 1026
 PXENV_EXIT_t pxenv_udp_write ( t_PXENV_UDP_WRITE *udp_write ) {
1027 1027
 	uint16_t src_port;
1028 1028
 	uint16_t dst_port;
1029
-	struct udppacket *packet = (struct udppacket *)nic->packet;
1029
+	struct udppacket *packet = (struct udppacket *)nic.packet;
1030 1030
 	int packet_size;
1031 1031
 
1032 1032
 	DBG ( "PXENV_UDP_WRITE" );

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

@@ -1,30 +1,49 @@
1 1
 #include "stdint.h"
2 2
 #include "string.h"
3 3
 #include "console.h"
4
+#include "nic.h"
4 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 36
  * Fill in parameters (vendor & device ids, class, membase etc.) for a
23 37
  * PCI device based on bus & devfn.
24 38
  *
25 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 47
 	static struct {
29 48
 		uint16_t devfn0;
30 49
 		int is_present;
@@ -32,8 +51,12 @@ static int fill_pci_device ( struct pci_device *pci ) {
32 51
 	uint32_t l;
33 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 58
 	/* Check bus is within range */
36
-	if ( PCI_BUS ( pci->busdevfn ) > pci_max_bus ) {
59
+	if ( PCI_BUS ( busdevfn ) > pci_max_bus ) {
37 60
 		return 0;
38 61
 	}
39 62
 
@@ -41,8 +64,8 @@ static int fill_pci_device ( struct pci_device *pci ) {
41 64
 	 * non-zero function on a non-existent card.  This is done to
42 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 69
 	     ( ! cache.is_present ) ) {
47 70
 		return 0;
48 71
 	}
@@ -52,28 +75,27 @@ static int fill_pci_device ( struct pci_device *pci ) {
52 75
 	pci_read_config_dword ( pci, PCI_VENDOR_ID, &l );
53 76
 	/* some broken boards return 0 if a slot is empty: */
54 77
 	if ( ( l == 0xffffffff ) || ( l == 0x00000000 ) ) {
55
-		if ( PCI_FUNC ( pci->busdevfn ) == 0 ) {
78
+		if ( PCI_FUNC ( busdevfn ) == 0 ) {
56 79
 			/* Don't look for subsequent functions if the
57 80
 			 * card itself is not present.
58 81
 			 */
59
-			cache.devfn0 = pci->busdevfn;
82
+			cache.devfn0 = busdevfn;
60 83
 			cache.is_present = 0;
61 84
 		}
62 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 90
 	/* Check that we're not a duplicate function on a
68 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 94
 		uint8_t header_type;
73 95
 
74
-		pci->busdevfn &= PCI_FN0 ( pci->busdevfn );
96
+		pci->busdevfn &= PCI_FN0 ( busdevfn );
75 97
 		pci_read_config_byte ( pci, PCI_HEADER_TYPE, &header_type );
76
-		pci->busdevfn = save_busdevfn;
98
+		pci->busdevfn = busdevfn;
77 99
 
78 100
 		if ( ! ( header_type & 0x80 ) ) {
79 101
 			return 0;
@@ -108,14 +130,87 @@ static int fill_pci_device ( struct pci_device *pci ) {
108 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 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 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 215
  * Set device to be a busmaster in case BIOS neglected to do so.  Also
121 216
  * adjust PCI latency timer to a reasonable value, 32.
@@ -127,7 +222,7 @@ void adjust_pci_device ( struct pci_device *pci ) {
127 222
 	pci_read_config_word ( pci, PCI_COMMAND, &pci_command );
128 223
 	new_command = pci_command | PCI_COMMAND_MASTER | PCI_COMMAND_IO;
129 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 226
 		      "Updating PCI command %hX->%hX\n",
132 227
 		      PCI_BUS ( pci->busdevfn ), PCI_DEV ( pci->busdevfn ),
133 228
 		      PCI_FUNC ( pci->busdevfn ), pci_command, new_command );
@@ -135,7 +230,7 @@ void adjust_pci_device ( struct pci_device *pci ) {
135 230
 	}
136 231
 	pci_read_config_byte ( pci, PCI_LATENCY_TIMER, &pci_latency);
137 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 234
 		      "unreasonably low at %d. Setting to 32.\n",
140 235
 		      PCI_BUS ( pci->busdevfn ), PCI_DEV ( pci->busdevfn ),
141 236
 		      PCI_FUNC ( pci->busdevfn ), pci_latency );
@@ -143,100 +238,6 @@ void adjust_pci_device ( struct pci_device *pci ) {
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 242
  * Find the start of a pci resource.
242 243
  */
@@ -346,3 +347,19 @@ int pci_find_capability ( struct pci_device *pci, int cap ) {
346 347
 	}
347 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,161 +0,0 @@
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,91 +2,276 @@
2 2
 #define DEV_H
3 3
 
4 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 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 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 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 277
 #endif /* DEV_H */

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

@@ -0,0 +1,12 @@
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,6 +19,8 @@
19 19
 
20 20
 #include "stdint.h"
21 21
 
22
+#define	ISA_BUS_TYPE	2
23
+
22 24
 /*
23 25
  * Construct a vendor ID from three ASCII characters
24 26
  *

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

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

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

@@ -8,6 +8,10 @@
8 8
 #ifndef	NIC_H
9 9
 #define NIC_H
10 10
 
11
+#include "dev.h"
12
+#include "byteswap.h"
13
+#include "dhcp.h"
14
+
11 15
 typedef enum {
12 16
 	DISABLE = 0,
13 17
 	ENABLE,
@@ -24,16 +28,17 @@ typedef enum duplex {
24 28
  *	functions.
25 29
  */
26 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 44
 struct nic_operations {
@@ -42,52 +47,43 @@ struct nic_operations {
42 47
 	void ( *transmit ) ( struct nic *, const char *,
43 48
 			     unsigned int, unsigned int, const char * );
44 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 55
  * Function prototypes
50 56
  *
51 57
  */
52
-struct dev;
53
-extern struct nic * nic_device ( struct dev * dev );
54 58
 extern int dummy_connect ( struct nic *nic );
55 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 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 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 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 77
 static inline void eth_transmit ( const char *dest, unsigned int type,
74 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 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 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 89
 #endif	/* NIC_H */

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

@@ -22,8 +22,10 @@
22 22
  */
23 23
 
24 24
 #include "stdint.h"
25
+#include "nic.h"
25 26
 #include "pci_ids.h"
26
-#include "dev.h"
27
+
28
+#define	PCI_BUS_TYPE	1
27 29
 
28 30
 /*
29 31
  * PCI constants
@@ -234,32 +236,44 @@
234 236
 #define PCI_MSI_DATA_32		8	/* 16 bits of data for 32-bit devices */
235 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 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 265
 #define PCI_BUS(busdevfn)	( ( uint8_t ) ( ( (busdevfn) >> 8 ) & 0xff ) )
253 266
 #define PCI_DEV(busdevfn)	( ( uint8_t ) ( ( (busdevfn) >> 3 ) & 0x1f ) )
254 267
 #define PCI_FUNC(busdevfn)      ( ( uint8_t ) ( (busdevfn) & 0x07 ) )
255 268
 #define PCI_FN0(busdevfn)	( ( uint16_t ) ( (busdevfn) & 0xfff8 ) )
269
+#define PCI_MAX_BUSDEVFN	0xffff
256 270
 
257 271
 /*
258 272
  * An individual PCI device identified by vendor and device IDs
259 273
  *
260 274
  */
261 275
 struct pci_id {
262
-	unsigned short vendor, dev_id;
276
+	unsigned short vendor_id, device_id;
263 277
 	const char *name;
264 278
 };
265 279
 
@@ -268,24 +282,23 @@ struct pci_id {
268 282
  * is also parsed by parserom.pl to generate Makefile rules and files
269 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 295
  * Set the class to something other than PCI_NO_CLASS if the driver
282 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 300
 	struct pci_id *ids;
288
-	int id_count;
301
+	unsigned int id_count;
289 302
 	uint16_t class;
290 303
 };
291 304
 #define PCI_NO_CLASS 0
@@ -294,30 +307,30 @@ struct pci_driver {
294 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 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 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 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 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 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 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 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 336
  * pci_io.c is allowed to overwrite pci_max_bus if it knows what the
@@ -330,13 +343,17 @@ extern unsigned int pci_max_bus;
330 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 346
 extern void adjust_pci_device ( struct pci_device *pci );
337 347
 extern unsigned long pci_bar_start ( struct pci_device *pci,
338 348
 				     unsigned int bar );
339 349
 extern unsigned long pci_bar_size ( struct pci_device *pci, unsigned int bar );
340 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 359
 #endif	/* PCI_H */

Loading…
Cancel
Save