Browse Source

Updated ISAPnP, EISA, MCA and ISA buses to current device model.

ISA 3c509 is currently non-functional, although the EISA (3c509-eisa) and
MCA (3c529) variants should build OK.

None of this code is yet tested.
tags/v0.9.3
Michael Brown 17 years ago
parent
commit
520d9c36af

+ 5
- 8
src/arch/i386/drivers/net/undionly.c View File

@@ -62,15 +62,12 @@ static int undibus_probe ( struct root_device *rootdev ) {
62 62
 	strncpy ( undi->dev.name, "UNDI",
63 63
 		  ( sizeof ( undi->dev.name ) - 1 ) );
64 64
 	if ( undi->pci_busdevfn != UNDI_NO_PCI_BUSDEVFN ) {
65
-		struct pci_device_description *pcidesc = &undi->dev.desc.pci;
66
-		pcidesc->bus_type = BUS_TYPE_PCI;
67
-		pcidesc->busdevfn = undi->pci_busdevfn;
68
-		pcidesc->vendor = undi->pci_vendor;
69
-		pcidesc->device = undi->pci_device;
65
+		undi->dev.desc.bus_type = BUS_TYPE_PCI;
66
+		undi->dev.desc.location = undi->pci_busdevfn;
67
+		undi->dev.desc.vendor = undi->pci_vendor;
68
+		undi->dev.desc.device = undi->pci_device;
70 69
 	} else if ( undi->isapnp_csn != UNDI_NO_ISAPNP_CSN ) {
71
-		struct isapnp_device_description *isapnpdesc
72
-			= &undi->dev.desc.isapnp;
73
-		isapnpdesc->bus_type = BUS_TYPE_ISAPNP;
70
+		undi->dev.desc.bus_type = BUS_TYPE_ISAPNP;
74 71
 	}
75 72
 	undi->dev.parent = &rootdev->dev;
76 73
 	list_add ( &undi->dev.siblings, &rootdev->dev.children);

+ 0
- 32
src/arch/i386/prefix/select_isapnp.c View File

@@ -1,32 +0,0 @@
1
-#include "dev.h"
2
-#include "isapnp.h"
3
-#include "registers.h"
4
-
5
-/*
6
- * Register a device as the default ISAPnP boot device.  This code is
7
- * called by the ISAPnP ROM prefix.
8
- *
9
- * Do not move this code to drivers/bus/isapnp.c, because it is
10
- * i386-specific, and don't merge it with select_pci.c, because that
11
- * would cause linker symbol pollution.
12
- *
13
- */
14
-void i386_select_isapnp_device ( struct i386_all_regs *ix86 ) {
15
-	/*
16
-	 * PnP BIOS passes card select number in %bx and read port
17
-	 * address in %dx.
18
-	 *
19
-	 */
20
-	union {
21
-		struct bus_loc bus_loc;
22
-		struct isapnp_loc isapnp_loc;
23
-	} u;
24
-
25
-	/* Set ISAPnP read port */
26
-	isapnp_read_port = ix86->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 = ix86->regs.bx;
31
-	select_device ( &dev, &isapnp_driver, &u.bus_loc );
32
-}

+ 153
- 147
src/drivers/bus/eisa.c View File

@@ -1,179 +1,185 @@
1
-#include "string.h"
2
-#include "io.h"
3
-#include "timer.h"
4
-#include "console.h"
5
-#include "dev.h"
6
-#include "eisa.h"
7
-
8
-/*
9
- * Increment a bus_loc structure to the next possible EISA location.
10
- * Leave the structure zeroed and return 0 if there are no more valid
11
- * locations.
1
+#include <stdint.h>
2
+#include <string.h>
3
+#include <stdlib.h>
4
+#include <stdio.h>
5
+#include <errno.h>
6
+#include <io.h>
7
+#include <timer.h>
8
+#include <gpxe/eisa.h>
9
+
10
+static struct eisa_driver eisa_drivers[0]
11
+	__table_start ( struct eisa_driver, eisa_drivers );
12
+static struct eisa_driver eisa_drivers_end[0]
13
+	__table_end ( struct eisa_driver, eisa_drivers );
14
+
15
+static void eisabus_remove ( struct root_device *rootdev );
16
+
17
+/**
18
+ * Reset and enable/disable an EISA device
12 19
  *
20
+ * @v eisa		EISA device
21
+ * @v enabled		1=enable, 0=disable
13 22
  */
14
-static int eisa_next_location ( struct bus_loc *bus_loc ) {
15
-	struct eisa_loc *eisa_loc = ( struct eisa_loc * ) bus_loc;
16
-	
17
-	/*
18
-	 * Ensure that there is sufficient space in the shared bus
19
-	 * structures for a struct isa_loc and a struct
20
-	 * isa_dev, as mandated by bus.h.
21
-	 *
23
+void eisa_device_enabled ( struct eisa_device *eisa, int enabled ) {
24
+	/* Set reset line high for 1000 µs.  Spec says 500 µs, but
25
+	 * this doesn't work for all cards, so we are conservative.
22 26
 	 */
23
-	BUS_LOC_CHECK ( struct eisa_loc );
24
-	BUS_DEV_CHECK ( struct eisa_device );
25
-
26
-	return ( eisa_loc->slot = ( ++eisa_loc->slot & EISA_MAX_SLOT ) );
27
-}
28
-
29
-/*
30
- * Fill in parameters for an EISA device based on slot number
31
- *
32
- * Return 1 if device present, 0 otherwise
33
- *
34
- */
35
-static int eisa_fill_device  ( struct bus_dev *bus_dev,
36
-			       struct bus_loc *bus_loc ) {
37
-	struct eisa_loc *eisa_loc = ( struct eisa_loc * ) bus_loc;
38
-	struct eisa_device *eisa = ( struct eisa_device * ) bus_dev;
39
-	uint8_t present;
40
-
41
-	/* Copy slot number to struct eisa, set default values */
42
-	eisa->slot = eisa_loc->slot;
43
-	eisa->name = "?";
44
-
45
-	/* Slot 0 is never valid */
46
-	if ( ! eisa->slot )
47
-		return 0;
48
-
49
-	/* Set ioaddr */
50
-	eisa->ioaddr = EISA_SLOT_BASE ( eisa->slot );
51
-
52
-	/* Test for board present */
53
-	outb ( 0xff, eisa->ioaddr + EISA_MFG_ID_HI );
54
-	present = inb ( eisa->ioaddr + EISA_MFG_ID_HI );
55
-	if ( present & 0x80 ) {
56
-		/* No board present */
57
-		return 0;
58
-	}
27
+	outb ( EISA_CMD_RESET, eisa->ioaddr + EISA_GLOBAL_CONFIG );
28
+	udelay ( 1000 ); /* Must wait 800 */
59 29
 
60
-	/* Read mfg and product IDs.  Yes, the resulting uint16_ts
61
-	 * will be upside-down.  This appears to be by design.
30
+	/* Set reset low and write a 1 to ENABLE.  Delay again, in
31
+	 * case the card takes a while to wake up.
62 32
 	 */
63
-	eisa->mfg_id = ( inb ( eisa->ioaddr + EISA_MFG_ID_LO ) << 8 )
64
-		+ present;
65
-	eisa->prod_id = ( inb ( eisa->ioaddr + EISA_PROD_ID_LO ) << 8 )
66
-		+ inb ( eisa->ioaddr + EISA_PROD_ID_HI );
67
-
68
-	DBG ( "EISA found slot %hhx (base %#hx) ID %hx:%hx (\"%s\")\n",
69
-	      eisa->slot, eisa->ioaddr, eisa->mfg_id, eisa->prod_id,
70
-	      isa_id_string ( eisa->mfg_id, eisa->prod_id ) );
33
+	outb ( enabled ? EISA_CMD_ENABLE : 0,
34
+	       eisa->ioaddr + EISA_GLOBAL_CONFIG );
35
+	udelay ( 1000 ); /* Must wait 800 */
71 36
 
72
-	return 1;
37
+	DBG ( "EISA %s device %02x\n", ( enabled ? "enabled" : "disabled" ),
38
+	      eisa->slot );
73 39
 }
74 40
 
75
-/*
76
- * Test whether or not a driver is capable of driving the device.
41
+/**
42
+ * Probe an EISA device
43
+ *
44
+ * @v eisa		EISA device
45
+ * @ret rc		Return status code
77 46
  *
47
+ * Searches for a driver for the EISA device.  If a driver is found,
48
+ * its probe() routine is called.
78 49
  */
79
-static int eisa_check_driver ( struct bus_dev *bus_dev,
80
-				 struct device_driver *device_driver ) {
81
-	struct eisa_device *eisa = ( struct eisa_device * ) bus_dev;
82
-	struct eisa_driver *driver
83
-		= ( struct eisa_driver * ) device_driver->bus_driver_info;
50
+static int eisa_probe ( struct eisa_device *eisa ) {
51
+	struct eisa_driver *driver;
52
+	struct eisa_device_id *id;
84 53
 	unsigned int i;
85
-
86
-	/* Compare against driver's ID list */
87
-	for ( i = 0 ; i < driver->id_count ; i++ ) {
88
-		struct eisa_id *id = &driver->ids[i];
89
-		
90
-		if ( ( eisa->mfg_id == id->mfg_id ) &&
91
-		     ( ISA_PROD_ID ( eisa->prod_id ) ==
92
-		       ISA_PROD_ID ( id->prod_id ) ) ) {
93
-			DBG ( "EISA found ID %hx:%hx (\"%s\") "
94
-			      "(device %s) matching driver %s\n",
95
-			      eisa->mfg_id, eisa->prod_id,
96
-			      isa_id_string ( eisa->mfg_id,
97
-					      eisa->prod_id ),
98
-			      id->name, driver->name );
99
-			eisa->name = id->name;
100
-			return 1;
54
+	int rc;
55
+
56
+	DBG ( "Adding EISA device %02x (%04x:%04x (\"%s\") io %x)\n",
57
+	      eisa->slot, eisa->vendor_id, eisa->prod_id,
58
+	      isa_id_string ( eisa->vendor_id, eisa->prod_id ), eisa->ioaddr );
59
+
60
+	for ( driver = eisa_drivers; driver < eisa_drivers_end; driver++ ) {
61
+		for ( i = 0 ; i < driver->id_count ; i++ ) {
62
+			id = &driver->ids[i];
63
+			if ( id->vendor_id != eisa->vendor_id )
64
+				continue;
65
+			if ( ISA_PROD_ID ( id->prod_id ) !=
66
+			     ISA_PROD_ID ( eisa->prod_id ) )
67
+				continue;
68
+			eisa->driver = driver;
69
+			eisa->driver_name = id->name;
70
+			DBG ( "...using driver %s\n", eisa->driver_name );
71
+			if ( ( rc = driver->probe ( eisa, id ) ) != 0 ) {
72
+				DBG ( "......probe failed\n" );
73
+				continue;
74
+			}
75
+			return 0;
101 76
 		}
102 77
 	}
103 78
 
104
-	/* No device found */
105
-	return 0;
79
+	DBG ( "...no driver found\n" );
80
+	return -ENOTTY;
106 81
 }
107 82
 
108
-/*
109
- * Describe an EISA device
83
+/**
84
+ * Remove an EISA device
110 85
  *
86
+ * @v eisa		EISA device
111 87
  */
112
-static char * eisa_describe_device ( struct bus_dev *bus_dev ) {
113
-	struct eisa_device *eisa = ( struct eisa_device * ) bus_dev;
114
-	static char eisa_description[] = "EISA 00";
115
-
116
-	sprintf ( eisa_description + 5, "%hhx", eisa->slot );
117
-	return eisa_description;
88
+static void eisa_remove ( struct eisa_device *eisa ) {
89
+	eisa->driver->remove ( eisa );
90
+	DBG ( "Removed EISA device %02x\n", eisa->slot );
118 91
 }
119 92
 
120
-/*
121
- * Name an EISA device
93
+/**
94
+ * Probe EISA root bus
122 95
  *
123
- */
124
-static const char * eisa_name_device ( struct bus_dev *bus_dev ) {
125
-	struct eisa_device *eisa = ( struct eisa_device * ) bus_dev;
126
-	
127
-	return eisa->name;
128
-}
129
-
130
-/*
131
- * EISA bus operations table
96
+ * @v rootdev		EISA bus root device
132 97
  *
98
+ * Scans the EISA bus for devices and registers all devices it can
99
+ * find.
133 100
  */
134
-struct bus_driver eisa_driver __bus_driver = {
135
-	.name			= "EISA",
136
-	.next_location		= eisa_next_location,
137
-	.fill_device		= eisa_fill_device,
138
-	.check_driver		= eisa_check_driver,
139
-	.describe_device	= eisa_describe_device,
140
-	.name_device		= eisa_name_device,
141
-};
101
+static int eisabus_probe ( struct root_device *rootdev ) {
102
+	struct eisa_device *eisa = NULL;
103
+	unsigned int slot;
104
+	int rc;
105
+
106
+	for ( slot = EISA_MIN_SLOT ; slot <= EISA_MAX_SLOT ; slot++ ) {
107
+		/* Allocate struct eisa_device */
108
+		if ( ! eisa )
109
+			eisa = malloc ( sizeof ( *eisa ) );
110
+		if ( ! eisa ) {
111
+			rc = -ENOMEM;
112
+			goto err;
113
+		}
114
+		memset ( eisa, 0, sizeof ( *eisa ) );
115
+		eisa->slot = slot;
116
+		eisa->ioaddr = EISA_SLOT_BASE ( eisa->slot );
117
+
118
+		/* Test for board present */
119
+		outb ( 0xff, eisa->ioaddr + EISA_VENDOR_ID );
120
+		eisa->vendor_id =
121
+			le16_to_cpu ( inw ( eisa->ioaddr + EISA_VENDOR_ID ) );
122
+		eisa->prod_id =
123
+			le16_to_cpu ( inw ( eisa->ioaddr + EISA_PROD_ID ) );
124
+		if ( eisa->vendor_id & 0x80 ) {
125
+			/* No board present */
126
+			continue;
127
+		}
142 128
 
143
-/*
144
- * Fill in a nic structure
145
- *
146
- */
147
-void eisa_fill_nic ( struct nic *nic, struct eisa_device *eisa ) {
129
+		/* Add to device hierarchy */
130
+		snprintf ( eisa->dev.name, sizeof ( eisa->dev.name ),
131
+			   "EISA%02x", slot );
132
+		eisa->dev.desc.bus_type = BUS_TYPE_EISA;
133
+		eisa->dev.desc.vendor = eisa->vendor_id;
134
+		eisa->dev.desc.device = eisa->prod_id;
135
+		eisa->dev.parent = &rootdev->dev;
136
+		list_add ( &eisa->dev.siblings, &rootdev->dev.children );
137
+		INIT_LIST_HEAD ( &eisa->dev.children );
138
+
139
+		/* Look for a driver */
140
+		if ( eisa_probe ( eisa ) == 0 ) {
141
+			/* eisadev registered, we can drop our ref */
142
+			eisa = NULL;
143
+		} else {
144
+			/* Not registered; re-use struct */
145
+			list_del ( &eisa->dev.siblings );
146
+		}
147
+	}
148 148
 
149
-	/* Fill in ioaddr and irqno */
150
-	nic->ioaddr = eisa->ioaddr;
151
-	nic->irqno = 0;
149
+	free ( eisa );
150
+	return 0;
152 151
 
153
-	/* Fill in DHCP device ID structure */
154
-	nic->dhcp_dev_id.bus_type = ISA_BUS_TYPE;
155
-	nic->dhcp_dev_id.vendor_id = htons ( eisa->mfg_id );
156
-	nic->dhcp_dev_id.device_id = htons ( eisa->prod_id );
152
+ err:
153
+	free ( eisa );
154
+	eisabus_remove ( rootdev );
155
+	return rc;
157 156
 }
158 157
 
159
-/*
160
- * Reset and enable/disable an EISA device
158
+/**
159
+ * Remove EISA root bus
161 160
  *
161
+ * @v rootdev		EISA bus root device
162 162
  */
163
-void eisa_device_enabled ( struct eisa_device *eisa, int enabled ) {
164
-	/* Set reset line high for 1000 µs.  Spec says 500 µs, but
165
-	 * this doesn't work for all cards, so we are conservative.
166
-	 */
167
-	outb ( EISA_CMD_RESET, eisa->ioaddr + EISA_GLOBAL_CONFIG );
168
-	udelay ( 1000 ); /* Must wait 800 */
163
+static void eisabus_remove ( struct root_device *rootdev ) {
164
+	struct eisa_device *eisa;
165
+	struct eisa_device *tmp;
166
+
167
+	list_for_each_entry_safe ( eisa, tmp, &rootdev->dev.children,
168
+				   dev.siblings ) {
169
+		eisa_remove ( eisa );
170
+		list_del ( &eisa->dev.siblings );
171
+		free ( eisa );
172
+	}
173
+}
169 174
 
170
-	/* Set reset low and write a 1 to ENABLE.  Delay again, in
171
-	 * case the card takes a while to wake up.
172
-	 */
173
-	outb ( enabled ? EISA_CMD_ENABLE : 0,
174
-	       eisa->ioaddr + EISA_GLOBAL_CONFIG );
175
-	udelay ( 1000 ); /* Must wait 800 */
175
+/** EISA bus root device driver */
176
+static struct root_driver eisa_root_driver = {
177
+	.probe = eisabus_probe,
178
+	.remove = eisabus_remove,
179
+};
176 180
 
177
-	DBG ( "EISA %s device %hhx\n", ( enabled ? "enabled" : "disabled" ),
178
-	      eisa->slot );
179
-}
181
+/** EISA bus root device */
182
+struct root_device eisa_root_device __root_device = {
183
+	.dev = { .name = "EISA" },
184
+	.driver = &eisa_root_driver,
185
+};

+ 112
- 128
src/drivers/bus/isa.c View File

@@ -1,8 +1,10 @@
1
-#include "string.h"
2
-#include "console.h"
3
-#include "config/isa.h"
4
-#include "dev.h"
5
-#include "isa.h"
1
+#include <stdint.h>
2
+#include <string.h>
3
+#include <stdlib.h>
4
+#include <stdio.h>
5
+#include <errno.h>
6
+#include <io.h>
7
+#include <gpxe/isa.h>
6 8
 
7 9
 /*
8 10
  * isa.c implements a "classical" port-scanning method of ISA device
@@ -31,161 +33,143 @@ static isa_probe_addr_t isa_extra_probe_addrs[] = {
31 33
 	ISA_PROBE_ADDRS
32 34
 #endif
33 35
 };
34
-#define isa_extra_probe_addr_count \
36
+#define ISA_EXTRA_PROBE_ADDR_COUNT \
35 37
      ( sizeof ( isa_extra_probe_addrs ) / sizeof ( isa_extra_probe_addrs[0] ) )
36 38
 
39
+#define ISA_IOIDX_MIN( driver ) ( -ISA_EXTRA_PROBE_ADDR_COUNT )
37 40
 #ifdef ISA_PROBE_ONLY
38
-#define ISA_PROBE_ADDR_COUNT(driver) ( isa_extra_probe_addr_count )
41
+#define ISA_IOIDX_MAX( driver ) ( -1 )
39 42
 #else
40
-#define ISA_PROBE_ADDR_COUNT(driver) \
41
-	( isa_extra_probe_addr_count + (driver)->addr_count )
43
+#define ISA_IOIDX_MAX( driver ) ( (int) (driver)->addr_count - 1 )
42 44
 #endif
43 45
 
44
-/*
45
- * Symbols defined by linker
46
- *
47
- */
46
+#define ISA_IOADDR( driver, ioidx )					  \
47
+	( ( (ioidx) < 0 ) ?						  \
48
+	  isa_extra_probe_addrs[ (ioidx) + ISA_EXTRA_PROBE_ADDR_COUNT ] : \
49
+	  (driver)->probe_addrs[(ioidx)] )
50
+
48 51
 static struct isa_driver isa_drivers[0]
49 52
 	__table_start ( struct isa_driver, isa_driver );
50 53
 static struct isa_driver isa_drivers_end[0]
51 54
 	__table_end ( struct isa_driver, isa_driver );
52 55
 
53
-/*
54
- * Increment a bus_loc structure to the next possible ISA location.
55
- * Leave the structure zeroed and return 0 if there are no more valid
56
- * locations.
57
- *
58
- * There is no sensible concept of a device location on an ISA bus, so
59
- * we use the probe address list for each ISA driver to define the
60
- * list of ISA locations.
61
- *
62
- */
63
-static int isa_next_location ( struct bus_loc *bus_loc ) {
64
-	struct isa_loc *isa_loc = ( struct isa_loc * ) bus_loc;
65
-	struct isa_driver *driver;
66
-
67
-	/*
68
-	 * Ensure that there is sufficient space in the shared bus
69
-	 * structures for a struct isa_loc and a struct
70
-	 * isa_dev, as mandated by bus.h.
71
-	 *
72
-	 */
73
-	BUS_LOC_CHECK ( struct isa_loc );
74
-	BUS_DEV_CHECK ( struct isa_device );
75
-
76
-	/* Move to next probe address within this driver */
77
-	driver = &isa_drivers[isa_loc->driver];
78
-	if ( ++isa_loc->probe_idx < ISA_PROBE_ADDR_COUNT ( driver ) )
79
-		return 1;
80
-
81
-	/* Move to next driver */
82
-	isa_loc->probe_idx = 0;
83
-	if ( ( ++isa_loc->driver, ++driver ) < isa_drivers_end )
84
-		return 1;
85
-
86
-	isa_loc->driver = 0;
87
-	return 0;
88
-}
56
+static void isabus_remove ( struct root_device *rootdev );
89 57
 
90
-/*
91
- * Fill in parameters (vendor & device ids, class, membase etc.) for
92
- * an ISA device based on bus_loc.
93
- *
94
- * Returns 1 if a device was found, 0 for no device present.
58
+/**
59
+ * Probe an ISA device
95 60
  *
61
+ * @v isa		ISA device
62
+ * @ret rc		Return status code
96 63
  */
97
-static int isa_fill_device ( struct bus_dev *bus_dev,
98
-			     struct bus_loc *bus_loc ) {
99
-	struct isa_loc *isa_loc = ( struct isa_loc * ) bus_loc;
100
-	struct isa_device *isa = ( struct isa_device * ) bus_dev;
101
-	signed int driver_probe_idx;
102
-	
103
-	/* Fill in struct isa from struct isa_loc */
104
-	isa->driver = &isa_drivers[isa_loc->driver];
105
-	driver_probe_idx = isa_loc->probe_idx - isa_extra_probe_addr_count;
106
-	if ( driver_probe_idx < 0 ) {
107
-		isa->ioaddr = isa_extra_probe_addrs[isa_loc->probe_idx];
108
-	} else {
109
-		isa->ioaddr = isa->driver->probe_addrs[driver_probe_idx];
110
-	}
64
+static int isa_probe ( struct isa_device *isa ) {
65
+	int rc;
66
+
67
+	DBG ( "Trying ISA driver %s at I/O %04x\n",
68
+	      isa->driver->name, isa->ioaddr );
111 69
 
112
-	/* Call driver's probe_addr method to determine if a device is
113
-	 * physically present
114
-	 */
115
-	if ( isa->driver->probe_addr ( isa->ioaddr ) ) {
116
-		isa->name = isa->driver->name;
117
-		isa->mfg_id = isa->driver->mfg_id;
118
-		isa->prod_id = isa->driver->prod_id;
119
-		DBG ( "ISA found %s device at address %hx\n",
120
-		      isa->name, isa->ioaddr );
121
-		return 1;
70
+	if ( ( rc = isa->driver->probe ( isa ) ) != 0 ) {
71
+		DBG ( "...probe failed\n" );
72
+		return rc;
122 73
 	}
123 74
 
75
+	DBG ( "...device found\n" );
124 76
 	return 0;
125 77
 }
126 78
 
127
-/*
128
- * Test whether or not a driver is capable of driving the specified
129
- * device.
79
+/**
80
+ * Remove an ISA device
130 81
  *
82
+ * @v isa		ISA device
131 83
  */
132
-int isa_check_driver ( struct bus_dev *bus_dev,
133
-		       struct device_driver *device_driver ) {
134
-	struct isa_device *isa = ( struct isa_device * ) bus_dev;
135
-	struct isa_driver *driver
136
-		= ( struct isa_driver * ) device_driver->bus_driver_info;
137
-
138
-	return ( driver == isa->driver );
84
+static void isa_remove ( struct isa_device *isa ) {
85
+	isa->driver->remove ( isa );
86
+	DBG ( "Removed ISA%04x\n", isa->ioaddr );
139 87
 }
140 88
 
141
-/*
142
- * Describe a ISA device
89
+/**
90
+ * Probe ISA root bus
91
+ *
92
+ * @v rootdev		ISA bus root device
143 93
  *
94
+ * Scans the ISA bus for devices and registers all devices it can
95
+ * find.
144 96
  */
145
-static char * isa_describe_device ( struct bus_dev *bus_dev ) {
146
-	struct isa_device *isa = ( struct isa_device * ) bus_dev;
147
-	static char isa_description[] = "ISA 0000 (00)";
97
+static int isabus_probe ( struct root_device *rootdev ) {
98
+	struct isa_device *isa = NULL;
99
+	struct isa_driver *driver;
100
+	int ioidx;
101
+	int rc;
102
+
103
+	for ( driver = isa_drivers ; driver < isa_drivers_end ; driver++ ) {
104
+		for ( ioidx = ISA_IOIDX_MIN ( driver ) ;
105
+		      ioidx <= ISA_IOIDX_MAX ( driver ) ; ioidx++ ) {
106
+			/* Allocate struct isa_device */
107
+			if ( ! isa )
108
+				isa = malloc ( sizeof ( *isa ) );
109
+			if ( ! isa ) {
110
+				rc = -ENOMEM;
111
+				goto err;
112
+			}
113
+			memset ( isa, 0, sizeof ( *isa ) );
114
+			isa->driver = driver;
115
+			isa->ioaddr = ISA_IOADDR ( driver, ioidx );
116
+
117
+			/* Add to device hierarchy */
118
+			snprintf ( isa->dev.name, sizeof ( isa->dev.name ),
119
+				   "ISA%04x", isa->ioaddr );
120
+			isa->dev.desc.bus_type = BUS_TYPE_ISA;
121
+			isa->dev.desc.vendor = driver->vendor_id;
122
+			isa->dev.desc.device = driver->prod_id;
123
+			isa->dev.parent = &rootdev->dev;
124
+			list_add ( &isa->dev.siblings,
125
+				   &rootdev->dev.children );
126
+			INIT_LIST_HEAD ( &isa->dev.children );
127
+
128
+			/* Try probing at this I/O address */
129
+			if ( isa_probe ( isa ) == 0 ) {
130
+				/* isadev registered, we can drop our ref */
131
+				isa = NULL;
132
+			} else {
133
+				/* Not registered; re-use struct */
134
+				list_del ( &isa->dev.siblings );
135
+			}
136
+		}
137
+	}
148 138
 
149
-	sprintf ( isa_description + 4, "%hx (%hhx)", isa->ioaddr,
150
-		  isa->driver - isa_drivers );
151
-	return isa_description;
139
+	free ( isa );
140
+	return 0;
141
+
142
+ err:
143
+	free ( isa );
144
+	isabus_remove ( rootdev );
145
+	return rc;
152 146
 }
153 147
 
154
-/*
155
- * Name a ISA device
148
+/**
149
+ * Remove ISA root bus
156 150
  *
151
+ * @v rootdev		ISA bus root device
157 152
  */
158
-static const char * isa_name_device ( struct bus_dev *bus_dev ) {
159
-	struct isa_device *isa = ( struct isa_device * ) bus_dev;
160
-	
161
-	return isa->name;
153
+static void isabus_remove ( struct root_device *rootdev ) {
154
+	struct isa_device *isa;
155
+	struct isa_device *tmp;
156
+
157
+	list_for_each_entry_safe ( isa, tmp, &rootdev->dev.children,
158
+				   dev.siblings ) {
159
+		isa_remove ( isa );
160
+		list_del ( &isa->dev.siblings );
161
+		free ( isa );
162
+	}
162 163
 }
163 164
 
164
-/*
165
- * ISA bus operations table
166
- *
167
- */
168
-struct bus_driver isa_driver __bus_driver = {
169
-	.name			= "ISA",
170
-	.next_location		= isa_next_location,
171
-	.fill_device		= isa_fill_device,
172
-	.check_driver		= isa_check_driver,
173
-	.describe_device	= isa_describe_device,
174
-	.name_device		= isa_name_device,
165
+/** ISA bus root device driver */
166
+static struct root_driver isa_root_driver = {
167
+	.probe = isabus_probe,
168
+	.remove = isabus_remove,
175 169
 };
176 170
 
177
-/*
178
- * Fill in a nic structure
179
- *
180
- */
181
-void isa_fill_nic ( struct nic *nic, struct isa_device *isa ) {
182
-
183
-	/* Fill in ioaddr and irqno */
184
-	nic->ioaddr = isa->ioaddr;
185
-	nic->irqno = 0;
186
-
187
-	/* Fill in DHCP device ID structure */
188
-	nic->dhcp_dev_id.bus_type = ISA_BUS_TYPE;
189
-	nic->dhcp_dev_id.vendor_id = htons ( isa->mfg_id );
190
-	nic->dhcp_dev_id.device_id = htons ( isa->prod_id );
191
-}
171
+/** ISA bus root device */
172
+struct root_device isa_root_device __root_device = {
173
+	.dev = { .name = "ISA" },
174
+	.driver = &isa_root_driver,
175
+};

+ 7
- 7
src/drivers/bus/isa_ids.c View File

@@ -1,15 +1,15 @@
1
-#include "stdint.h"
2
-#include "byteswap.h"
3
-#include "console.h"
4
-#include "isa_ids.h"
1
+#include <stdint.h>
2
+#include <stdio.h>
3
+#include <byteswap.h>
4
+#include <gpxe/isa_ids.h>
5 5
 
6 6
 /* 
7 7
  * EISA and ISAPnP IDs are actually mildly human readable, though in a
8 8
  * somewhat brain-damaged way.
9 9
  *
10 10
  */
11
-char * isa_id_string ( uint16_t vendor, uint16_t product ) {
12
-	static unsigned char buf[7];
11
+char * isa_id_string ( unsigned int vendor, unsigned int product ) {
12
+	static char buf[7];
13 13
 	int i;
14 14
 
15 15
 	/* Vendor ID is a compressed ASCII string */
@@ -20,7 +20,7 @@ char * isa_id_string ( uint16_t vendor, uint16_t product ) {
20 20
 	}
21 21
 	
22 22
 	/* Product ID is a 4-digit hex string */
23
-	sprintf ( &buf[3], "%hx", bswap_16 ( product ) );
23
+	sprintf ( &buf[3], "%04x", bswap_16 ( product ) );
24 24
 
25 25
 	return buf;
26 26
 }

+ 273
- 331
src/drivers/bus/isapnp.c View File

@@ -60,80 +60,77 @@
60 60
  *
61 61
  */
62 62
 
63
-#include "string.h"
64
-#include "timer.h"
65
-#include "io.h"
66
-#include "console.h"
67
-#include "dev.h"
68
-#include "isapnp.h"
63
+#include <stdint.h>
64
+#include <stdlib.h>
65
+#include <string.h>
66
+#include <stdio.h>
67
+#include <errno.h>
68
+#include <io.h>
69
+#include <timer.h>
70
+#include <gpxe/isapnp.h>
69 71
 
70 72
 /**
71 73
  * ISAPnP Read Port address.
72 74
  *
75
+ * ROM prefix may be able to set this address, which is why this is
76
+ * non-static.
73 77
  */
74 78
 uint16_t isapnp_read_port;
75 79
 
76
-/**
77
- * Highest assigned CSN.
78
- *
79
- * Note that @b we do not necessarily assign CSNs; it could be done by
80
- * the PnP BIOS instead.  We therefore set this only when we first try
81
- * to Wake[CSN] a device and find that there's nothing there.  Page 16
82
- * (PDF page 22) of the ISAPnP spec states that "Valid Card Select
83
- * Numbers for identified ISA cards range from 1 to 255 and must be
84
- * assigned sequentially starting from 1", so we are (theoretically,
85
- * at least) safe to assume that there are no ISAPnP cards at CSNs
86
- * higher than the first unused CSN.
87
- *
88
- */
89
-static uint8_t isapnp_max_csn = 0xff;
80
+static struct isapnp_driver isapnp_drivers[0]
81
+	__table_start ( struct isapnp_driver, isapnp_drivers );
82
+static struct isapnp_driver isapnp_drivers_end[0]
83
+	__table_end ( struct isapnp_driver, isapnp_drivers );
84
+
85
+static void isapnpbus_remove ( struct root_device *rootdev );
90 86
 
91 87
 /*
92 88
  * ISAPnP utility functions
93 89
  *
94 90
  */
95 91
 
96
-#define ISAPNP_CARD_ID_FMT "ID %hx:%hx (\"%s\") serial %x"
92
+#define ISAPNP_CARD_ID_FMT "ID %04x:%04x (\"%s\") serial %lx"
97 93
 #define ISAPNP_CARD_ID_DATA(identifier)					  \
98 94
 	(identifier)->vendor_id, (identifier)->prod_id,			  \
99 95
 	isa_id_string ( (identifier)->vendor_id, (identifier)->prod_id ), \
100 96
 	(identifier)->serial
101
-#define ISAPNP_DEV_ID_FMT "ID %hx:%hx (\"%s\")"
97
+#define ISAPNP_DEV_ID_FMT "ID %04x:%04x (\"%s\")"
102 98
 #define ISAPNP_DEV_ID_DATA(isapnp)					  \
103 99
 	(isapnp)->vendor_id, (isapnp)->prod_id,				  \
104 100
 	isa_id_string ( (isapnp)->vendor_id, (isapnp)->prod_id )
105 101
 
106
-static inline void isapnp_write_address ( uint8_t address ) {
102
+static inline void isapnp_write_address ( unsigned int address ) {
107 103
 	outb ( address, ISAPNP_ADDRESS );
108 104
 }
109 105
 
110
-static inline void isapnp_write_data ( uint8_t data ) {
106
+static inline void isapnp_write_data ( unsigned int data ) {
111 107
 	outb ( data, ISAPNP_WRITE_DATA );
112 108
 }
113 109
 
114
-static inline uint8_t isapnp_read_data ( void ) {
110
+static inline unsigned int isapnp_read_data ( void ) {
115 111
 	return inb ( isapnp_read_port );
116 112
 }
117 113
 
118
-static inline void isapnp_write_byte ( uint8_t address, uint8_t value ) {
114
+static inline void isapnp_write_byte ( unsigned int address,
115
+				       unsigned int value ) {
119 116
 	isapnp_write_address ( address );
120 117
 	isapnp_write_data ( value );
121 118
 }
122 119
 
123
-static inline uint8_t isapnp_read_byte ( uint8_t address ) {
120
+static inline unsigned int isapnp_read_byte ( unsigned int address ) {
124 121
 	isapnp_write_address ( address );
125 122
 	return isapnp_read_data ();
126 123
 }
127 124
 
128
-static inline uint16_t isapnp_read_word ( uint8_t address ) {
125
+static inline unsigned int isapnp_read_word ( unsigned int address ) {
129 126
 	/* Yes, they're in big-endian order */
130 127
 	return ( ( isapnp_read_byte ( address ) << 8 )
131
-		 + isapnp_read_byte ( address + 1 ) );
128
+		 | isapnp_read_byte ( address + 1 ) );
132 129
 }
133 130
 
134 131
 /** Inform cards of a new read port address */
135 132
 static inline void isapnp_set_read_port ( void ) {
136
-	isapnp_write_byte ( ISAPNP_READPORT, isapnp_read_port >> 2 );
133
+	isapnp_write_byte ( ISAPNP_READPORT, ( isapnp_read_port >> 2 ) );
137 134
 }
138 135
 
139 136
 /**
@@ -141,7 +138,6 @@ static inline void isapnp_set_read_port ( void ) {
141 138
  *
142 139
  * Only cards currently in the Sleep state will respond to this
143 140
  * command.
144
- *
145 141
  */
146 142
 static inline void isapnp_serialisolation ( void ) {
147 143
 	isapnp_write_address ( ISAPNP_SERIALISOLATION );
@@ -152,7 +148,6 @@ static inline void isapnp_serialisolation ( void ) {
152 148
  *
153 149
  * All cards will respond to this command, regardless of their current
154 150
  * state.
155
- *
156 151
  */
157 152
 static inline void isapnp_wait_for_key ( void ) {
158 153
 	isapnp_write_byte ( ISAPNP_CONFIGCONTROL, ISAPNP_CONFIG_WAIT_FOR_KEY );
@@ -163,7 +158,6 @@ static inline void isapnp_wait_for_key ( void ) {
163 158
  *
164 159
  * Only cards currently in the Sleep state will respond to this
165 160
  * command.
166
- *
167 161
  */
168 162
 static inline void isapnp_reset_csn ( void ) {
169 163
 	isapnp_write_byte ( ISAPNP_CONFIGCONTROL, ISAPNP_CONFIG_RESET_CSN );
@@ -179,17 +173,16 @@ static inline void isapnp_reset_csn ( void ) {
179 173
  * Only cards currently in the Sleep, Isolation, or Config states will
180 174
  * respond to this command.  The card that has the specified CSN will
181 175
  * enter the Config state, all other cards will enter the Sleep state.
182
- *
183 176
  */
184 177
 static inline void isapnp_wake ( uint8_t csn ) {
185 178
 	isapnp_write_byte ( ISAPNP_WAKE, csn );
186 179
 }
187 180
 
188
-static inline uint8_t isapnp_read_resourcedata ( void ) {
181
+static inline unsigned int isapnp_read_resourcedata ( void ) {
189 182
 	return isapnp_read_byte ( ISAPNP_RESOURCEDATA );
190 183
 }
191 184
 
192
-static inline uint8_t isapnp_read_status ( void ) {
185
+static inline unsigned int isapnp_read_status ( void ) {
193 186
 	return isapnp_read_byte ( ISAPNP_STATUS );
194 187
 }
195 188
 
@@ -197,38 +190,35 @@ static inline uint8_t isapnp_read_status ( void ) {
197 190
  * Assign a Card Select Number to a card, and enter the Config state.
198 191
  *
199 192
  * @v csn		Card Select Number
200
- * @ret None		-
201
- * @err None		-
202 193
  *
203 194
  * Only cards in the Isolation state will respond to this command.
204 195
  * The isolation protocol is designed so that only one card will
205 196
  * remain in the Isolation state by the time the isolation protocol
206 197
  * completes.
207
- *
208 198
  */
209
-static inline void isapnp_write_csn ( uint8_t csn ) {
199
+static inline void isapnp_write_csn ( unsigned int csn ) {
210 200
 	isapnp_write_byte ( ISAPNP_CARDSELECTNUMBER, csn );
211 201
 }
212 202
 
213
-static inline void isapnp_logicaldevice ( uint8_t logdev ) {
203
+static inline void isapnp_logicaldevice ( unsigned int logdev ) {
214 204
 	isapnp_write_byte ( ISAPNP_LOGICALDEVICENUMBER, logdev );
215 205
 }
216 206
 
217
-static inline void isapnp_activate ( uint8_t logdev ) {
207
+static inline void isapnp_activate ( unsigned int logdev ) {
218 208
 	isapnp_logicaldevice ( logdev );
219 209
 	isapnp_write_byte ( ISAPNP_ACTIVATE, 1 );
220 210
 }
221 211
 
222
-static inline void isapnp_deactivate ( uint8_t logdev ) {
212
+static inline void isapnp_deactivate ( unsigned int logdev ) {
223 213
 	isapnp_logicaldevice ( logdev );
224 214
 	isapnp_write_byte ( ISAPNP_ACTIVATE, 0 );
225 215
 }
226 216
 
227
-static inline uint16_t isapnp_read_iobase ( unsigned int index ) {
217
+static inline unsigned int isapnp_read_iobase ( unsigned int index ) {
228 218
 	return isapnp_read_word ( ISAPNP_IOBASE ( index ) );
229 219
 }
230 220
 
231
-static inline uint8_t isapnp_read_irqno ( unsigned int index ) {
221
+static inline unsigned int isapnp_read_irqno ( unsigned int index ) {
232 222
 	return isapnp_read_byte ( ISAPNP_IRQNO ( index ) );
233 223
 }
234 224
 
@@ -242,7 +232,6 @@ static void isapnp_delay ( void ) {
242 232
  * @v lfsr		Current value of the LFSR
243 233
  * @v input_bit		Current input bit to the LFSR
244 234
  * @ret lfsr		Next value of the LFSR
245
- * @err None		-
246 235
  *
247 236
  * This routine implements the linear feedback shift register as
248 237
  * described in Appendix B of the PnP ISA spec.  The hardware
@@ -250,9 +239,9 @@ static void isapnp_delay ( void ) {
250 239
  * think this is probably the smallest possible implementation in
251 240
  * software.  Six instructions when input_bit is a constant 0 (for
252 241
  * isapnp_send_key).  :)
253
- *
254 242
  */
255
-static inline uint8_t isapnp_lfsr_next ( uint8_t lfsr, int input_bit ) {
243
+static inline unsigned int isapnp_lfsr_next ( unsigned int lfsr,
244
+					      unsigned int input_bit ) {
256 245
 	register uint8_t lfsr_next;
257 246
 
258 247
 	lfsr_next = lfsr >> 1;
@@ -265,11 +254,10 @@ static inline uint8_t isapnp_lfsr_next ( uint8_t lfsr, int input_bit ) {
265 254
  *
266 255
  * Sending the key causes all ISAPnP cards that are currently in the
267 256
  * Wait for Key state to transition into the Sleep state.
268
- *
269 257
  */
270 258
 static void isapnp_send_key ( void ) {
271 259
 	unsigned int i;
272
-	uint8_t lfsr;
260
+	unsigned int lfsr;
273 261
 
274 262
 	isapnp_delay();
275 263
 	isapnp_write_address ( 0x00 );
@@ -285,19 +273,17 @@ static void isapnp_send_key ( void ) {
285 273
 /**
286 274
  * Compute ISAPnP identifier checksum
287 275
  *
288
- * @v identifier		ISAPnP identifier
289
- * @ret checksum		Expected checksum value
290
- * @err None			-
291
- *
276
+ * @v identifier	ISAPnP identifier
277
+ * @ret checksum	Expected checksum value
292 278
  */
293
-static uint8_t isapnp_checksum ( struct isapnp_identifier *identifier ) {
294
-	int i, j;
295
-	uint8_t lfsr;
296
-	uint8_t byte;
279
+static unsigned int isapnp_checksum ( struct isapnp_identifier *identifier ) {
280
+	unsigned int i, j;
281
+	unsigned int lfsr;
282
+	unsigned int byte;
297 283
 
298 284
 	lfsr = ISAPNP_LFSR_SEED;
299 285
 	for ( i = 0 ; i < 8 ; i++ ) {
300
-		byte = ( (char *) identifier )[i];
286
+		byte = * ( ( ( uint8_t * ) identifier ) + i );
301 287
 		for ( j = 0 ; j < 8 ; j++ ) {
302 288
 			lfsr = isapnp_lfsr_next ( lfsr, byte );
303 289
 			byte >>= 1;
@@ -309,17 +295,18 @@ static uint8_t isapnp_checksum ( struct isapnp_identifier *identifier ) {
309 295
 /*
310 296
  * Read a byte of resource data from the current location
311 297
  *
298
+ * @ret byte		Byte of resource data
312 299
  */
313
-static inline uint8_t isapnp_peek_byte ( void ) {
314
-	int i;
300
+static inline unsigned int isapnp_peek_byte ( void ) {
301
+	unsigned int i;
315 302
 
316 303
 	/* Wait for data to be ready */
317
-	for ( i = 0 ; i < 20 ; i ++ ) {
304
+	for ( i = 0 ; i < 20 ; i++ ) {
318 305
 		if ( isapnp_read_status() & 0x01 ) {
319 306
 			/* Byte ready - read it */
320 307
 			return isapnp_read_resourcedata();
321 308
 		}
322
-		isapnp_delay ();
309
+		isapnp_delay();
323 310
 	}
324 311
 	/* Data never became ready - return 0xff */
325 312
 	return 0xff;
@@ -330,22 +317,18 @@ static inline uint8_t isapnp_peek_byte ( void ) {
330 317
  *
331 318
  * @v buf		Buffer in which to store data, or NULL
332 319
  * @v bytes		Number of bytes to read
333
- * @ret None		-
334
- * @err None		-
335 320
  *
336 321
  * Resource data is read from the current location.  If #buf is NULL,
337 322
  * the data is discarded.
338
- *
339 323
  */
340
-static void isapnp_peek ( uint8_t *buf, size_t bytes ) {
324
+static void isapnp_peek ( void *buf, size_t len ) {
341 325
 	unsigned int i;
342
-	uint8_t byte;
326
+	unsigned int byte;
343 327
 
344
-	for ( i = 0 ; i < bytes ; i++) {
328
+	for ( i = 0 ; i < len ; i++) {
345 329
 		byte = isapnp_peek_byte();
346
-		if ( buf ) {
347
-			buf[i] = byte;
348
-		}
330
+		if ( buf )
331
+			* ( ( uint8_t * ) buf + i ) = byte;
349 332
 	}
350 333
 }
351 334
 
@@ -354,40 +337,59 @@ static void isapnp_peek ( uint8_t *buf, size_t bytes ) {
354 337
  *
355 338
  * @v wanted_tag	The tag that we're looking for
356 339
  * @v buf		Buffer in which to store the tag's contents
357
- * @ret True		Tag was found
358
- * @ret False		Tag was not found
359
- * @err None		-
340
+ * @v len		Length of buffer
341
+ * @ret rc		Return status code
360 342
  *
361 343
  * Scan through the resource data until we find a particular tag, and
362
- * read its contents into a buffer.  It is the caller's responsibility
363
- * to ensure that #buf is large enough to contain a tag of the
364
- * requested size.
365
- *
344
+ * read its contents into a buffer.
366 345
  */
367
-static int isapnp_find_tag ( uint8_t wanted_tag, uint8_t *buf ) {
368
-	uint8_t tag;
369
-	uint16_t len;
346
+static int isapnp_find_tag ( unsigned int wanted_tag, void *buf, size_t len ) {
347
+	unsigned int tag;
348
+	unsigned int tag_len;
370 349
 
371 350
 	DBG2 ( "ISAPnP read tag" );
372 351
 	do {
373 352
 		tag = isapnp_peek_byte();
374 353
 		if ( ISAPNP_IS_SMALL_TAG ( tag ) ) {
375
-			len = ISAPNP_SMALL_TAG_LEN ( tag );
354
+			tag_len = ISAPNP_SMALL_TAG_LEN ( tag );
376 355
 			tag = ISAPNP_SMALL_TAG_NAME ( tag );
377 356
 		} else {
378
-			len = isapnp_peek_byte() + ( isapnp_peek_byte() << 8 );
357
+			tag_len = ( isapnp_peek_byte() +
358
+				    ( isapnp_peek_byte() << 8 ) );
379 359
 			tag = ISAPNP_LARGE_TAG_NAME ( tag );
380 360
 		}
381
-		DBG2 ( " %hhx (%hhx)", tag, len );
361
+		DBG2 ( " %02x (%02x)", tag, tag_len );
382 362
 		if ( tag == wanted_tag ) {
363
+			if ( len > tag_len )
364
+				len = tag_len;
383 365
 			isapnp_peek ( buf, len );
384 366
 			DBG2 ( "\n" );
385
-			return 1;
367
+			return 0;
386 368
 		} else {
387
-			isapnp_peek ( NULL, len );
369
+			isapnp_peek ( NULL, tag_len );
388 370
 		}
389 371
 	} while ( tag != ISAPNP_TAG_END );
390 372
 	DBG2 ( "\n" );
373
+	return -ENOENT;
374
+}
375
+
376
+/**
377
+ * Find specified Logical Device ID tag
378
+ *
379
+ * @v logdev		Logical device ID
380
+ * @v logdevid		Logical device ID structure to fill in
381
+ * @ret rc		Return status code
382
+ */
383
+static int isapnp_find_logdevid ( unsigned int logdev,
384
+				  struct isapnp_logdevid *logdevid ) {
385
+	unsigned int i;
386
+	int rc;
387
+
388
+	for ( i = 0 ; i <= logdev ; i++ ) {
389
+		if ( ( rc = isapnp_find_tag ( ISAPNP_TAG_LOGDEVID, logdevid,
390
+					      sizeof ( *logdevid ) ) ) != 0 )
391
+			return rc;
392
+	}
391 393
 	return 0;
392 394
 }
393 395
 
@@ -401,37 +403,36 @@ static int isapnp_find_tag ( uint8_t wanted_tag, uint8_t *buf ) {
401 403
  *
402 404
  * The state diagram on page 18 (PDF page 24) of the PnP ISA spec
403 405
  * gives the best overview of what happens here.
404
- *
405 406
  */
406 407
 static int isapnp_try_isolate ( void ) {
407 408
 	struct isapnp_identifier identifier;
408 409
 	unsigned int i, j;
409 410
 	unsigned int seen_55aa, seen_life;
410 411
 	unsigned int csn = 0;
411
-	uint16_t data;
412
-	uint8_t byte;
412
+	unsigned int data;
413
+	unsigned int byte;
413 414
 
414
-	DBG ( "ISAPnP attempting isolation at read port %hx\n",
415
+	DBG ( "ISAPnP attempting isolation at read port %04x\n",
415 416
 	      isapnp_read_port );
416 417
 
417 418
 	/* Place all cards into the Sleep state, whatever state
418 419
 	 * they're currently in.
419 420
 	 */
420
-	isapnp_wait_for_key ();
421
-	isapnp_send_key ();
421
+	isapnp_wait_for_key();
422
+	isapnp_send_key();
422 423
 
423 424
 	/* Reset all assigned CSNs */
424
-	isapnp_reset_csn ();
425
+	isapnp_reset_csn();
425 426
 	isapnp_delay();
426 427
 	isapnp_delay();
427 428
 	
428 429
 	/* Place all cards into the Isolation state */
429 430
 	isapnp_wait_for_key ();
430
-	isapnp_send_key ();
431
+	isapnp_send_key();
431 432
 	isapnp_wake ( 0x00 );
432 433
 	
433 434
 	/* Set the read port */
434
-	isapnp_set_read_port ();
435
+	isapnp_set_read_port();
435 436
 	isapnp_delay();
436 437
 
437 438
 	while ( 1 ) {
@@ -442,7 +443,7 @@ static int isapnp_try_isolate ( void ) {
442 443
 		 */
443 444
 
444 445
 		/* Initiate serial isolation */
445
-		isapnp_serialisolation ();
446
+		isapnp_serialisolation();
446 447
 		isapnp_delay();
447 448
 
448 449
 		/* Read identifier serially via the ISAPnP read port. */
@@ -451,9 +452,9 @@ static int isapnp_try_isolate ( void ) {
451 452
 		for ( i = 0 ; i < 9 ; i++ ) {
452 453
 			byte = 0;
453 454
 			for ( j = 0 ; j < 8 ; j++ ) {
454
-				data = isapnp_read_data ();
455
+				data = isapnp_read_data();
455 456
 				isapnp_delay();
456
-				data = ( data << 8 ) | isapnp_read_data ();
457
+				data = ( ( data << 8 ) | isapnp_read_data() );
457 458
 				isapnp_delay();
458 459
 				byte >>= 1;
459 460
 				if (  data != 0xffff ) {
@@ -464,7 +465,7 @@ static int isapnp_try_isolate ( void ) {
464 465
 					}
465 466
 				}
466 467
 			}
467
-			( (char *) &identifier )[i] = byte;
468
+			*( ( ( uint8_t * ) &identifier ) + i ) = byte;
468 469
 		}
469 470
 
470 471
 		/* If we didn't see any 55aa patterns, stop here */
@@ -487,8 +488,8 @@ static int isapnp_try_isolate ( void ) {
487 488
 		/* If the checksum was invalid stop here */
488 489
 		if ( identifier.checksum != isapnp_checksum ( &identifier) ) {
489 490
 			DBG ( "ISAPnP found malformed card "
490
-			      ISAPNP_CARD_ID_FMT "\n  with checksum %hhx "
491
-			      "(should be %hhx), trying new read port\n",
491
+			      ISAPNP_CARD_ID_FMT "\n  with checksum %02x "
492
+			      "(should be %02x), trying new read port\n",
492 493
 			      ISAPNP_CARD_ID_DATA ( &identifier ),
493 494
 			      identifier.checksum,
494 495
 			      isapnp_checksum ( &identifier) );
@@ -499,7 +500,7 @@ static int isapnp_try_isolate ( void ) {
499 500
 		/* Give the device a CSN */
500 501
 		csn++;
501 502
 		DBG ( "ISAPnP found card " ISAPNP_CARD_ID_FMT
502
-		      ", assigning CSN %hhx\n",
503
+		      ", assigning CSN %02x\n",
503 504
 		      ISAPNP_CARD_ID_DATA ( &identifier ), csn );
504 505
 		
505 506
 		isapnp_write_csn ( csn );
@@ -513,11 +514,11 @@ static int isapnp_try_isolate ( void ) {
513 514
 	}
514 515
 
515 516
 	/* Place all cards in Wait for Key state */
516
-	isapnp_wait_for_key ();
517
+	isapnp_wait_for_key();
517 518
 
518 519
 	/* Return number of cards found */
519 520
 	if ( csn > 0 ) {
520
-		DBG ( "ISAPnP found %d cards at read port %hx\n",
521
+		DBG ( "ISAPnP found %d cards at read port %04x\n",
521 522
 		      csn, isapnp_read_port );
522 523
 	}
523 524
 	return csn;
@@ -539,281 +540,222 @@ static void isapnp_isolate ( void ) {
539 540
 			continue;
540 541
 		
541 542
 		/* If we detect any ISAPnP cards at this location, stop */
542
-		if ( isapnp_try_isolate () >= 0 )
543
+		if ( isapnp_try_isolate() >= 0 )
543 544
 			return;
544 545
 	}
545 546
 }
546 547
 
547 548
 /**
548
- * Increment a #bus_loc structure to the next possible ISAPnP
549
- * location.
549
+ * Activate or deactivate an ISAPnP device.
550 550
  *
551
- * @v bus_loc		Bus location
552
- * @ret True		#bus_loc contains a valid ISAPnP location
553
- * @ret False		There are no more valid ISAPnP locations
551
+ * @v isapnp		ISAPnP device
552
+ * @v activation	True to enable, False to disable the device
553
+ * @ret None		-
554 554
  * @err None		-
555 555
  *
556
- * If there are no more valid locations, the #bus_loc structure will
557
- * be zeroed.
558
- *
559
- */
560
-static int isapnp_next_location ( struct bus_loc *bus_loc ) {
561
-	struct isapnp_loc *isapnp_loc = ( struct isapnp_loc * ) bus_loc;
562
-	
563
-	/*
564
-	 * Ensure that there is sufficient space in the shared bus
565
-	 * structures for a struct isapnp_loc and a struct isapnp_dev,
566
-	 * as mandated by bus.h.
567
-	 *
568
-	 */
569
-	BUS_LOC_CHECK ( struct isapnp_loc );
570
-	BUS_DEV_CHECK ( struct isapnp_device );
571
-
572
-	return ( ++isapnp_loc->logdev ? 1 : ++isapnp_loc->csn );
573
-}
574
-
575
-/**
576
- * Fill in parameters for an ISAPnP device based on CSN.
577
- *
578
- * @v bus_dev		Bus device to be filled in
579
- * @v bus_loc		Bus location as filled in by isapnp_next_location()
580
- * @ret True		A device is present at this location
581
- * @ret False		No device is present at this location
582
- * @err None		-
556
+ * This routine simply activates the device in its current
557
+ * configuration, or deactivates the device.  It does not attempt any
558
+ * kind of resource arbitration.
583 559
  *
584 560
  */
585
-static int isapnp_fill_device ( struct bus_dev *bus_dev,
586
-				struct bus_loc *bus_loc ) {
587
-	struct isapnp_device *isapnp = ( struct isapnp_device * ) bus_dev;
588
-	struct isapnp_loc *isapnp_loc = ( struct isapnp_loc * ) bus_loc;
589
-	unsigned int i;
590
-	struct isapnp_identifier identifier;
591
-	struct isapnp_logdevid logdevid;
592
-	static struct {
593
-		uint8_t csn;
594
-		uint8_t first_nonexistent_logdev;
595
-	} cache = { 0, 0 };
596
-
597
-	/* Copy CSN and logdev to isapnp_device, set default values */
598
-	isapnp->csn = isapnp_loc->csn;
599
-	isapnp->logdev = isapnp_loc->logdev;
600
-	isapnp->name = "?";
601
-
602
-	/* CSN 0 is never valid, but may be passed in */
603
-	if ( ! isapnp->csn )
604
-		return 0;
605
-
606
-	/* Check to see if we are already past the maximum CSN */
607
-	if ( isapnp->csn > isapnp_max_csn )
608
-		return 0;
609
-
610
-	/* Check cache to see if we are already past the highest
611
-	 * logical device of this CSN
612
-	 */
613
-	if ( ( isapnp->csn == cache.csn ) &&
614
-	     ( isapnp->logdev >= cache.first_nonexistent_logdev ) )
615
-		return 0;
616
-
617
-	/* Perform isolation if it hasn't yet been done */
618
-	if ( ! isapnp_read_port )
619
-		isapnp_isolate();
620
-
621
-	/* Wake the card */
561
+void isapnp_device_activation ( struct isapnp_device *isapnp,
562
+				int activation ) {
563
+	/* Wake the card and select the logical device */
622 564
 	isapnp_wait_for_key ();
623 565
 	isapnp_send_key ();
624 566
 	isapnp_wake ( isapnp->csn );
625
-
626
-	/* Read the card identifier */
627
-	isapnp_peek ( ( char * ) &identifier, sizeof ( identifier ) );
628
-
629
-	/* Need to return 0 if no device exists at this CSN */
630
-	if ( identifier.vendor_id & 0x80 ) {
631
-		isapnp_max_csn = isapnp->csn - 1;
632
-		return 0;
633
-	}
634
-
635
-	/* Find the Logical Device ID tag corresponding to this device */
636
-	for ( i = 0 ; i <= isapnp->logdev ; i++ ) {
637
-		if ( ! isapnp_find_tag ( ISAPNP_TAG_LOGDEVID,
638
-					 ( char * ) &logdevid ) ) {
639
-			/* No tag for this device */
640
-			if ( isapnp->logdev == 0 ) {
641
-				DBG ( "ISAPnP found no device %hhx.0 on card "
642
-				      ISAPNP_CARD_ID_FMT "\n", isapnp->csn,
643
-				      ISAPNP_CARD_ID_DATA ( &identifier ) );
644
-			}
645
-			cache.csn = isapnp->csn;
646
-			cache.first_nonexistent_logdev = isapnp->logdev;
647
-			return 0;
648
-		}
649
-	}
650
-
651
-	/* Read information from logdevid structure */
652
-	isapnp->vendor_id = logdevid.vendor_id;
653
-	isapnp->prod_id = logdevid.prod_id;
654
-
655
-	/* Select the logical device */
656 567
 	isapnp_logicaldevice ( isapnp->logdev );
657 568
 
658
-	/* Read the current ioaddr and irqno */
659
-	isapnp->ioaddr = isapnp_read_iobase ( 0 );
660
-	isapnp->irqno = isapnp_read_irqno ( 0 );
569
+	/* Activate/deactivate the logical device */
570
+	isapnp_activate ( activation );
571
+	isapnp_delay();
661 572
 
662 573
 	/* Return all cards to Wait for Key state */
663 574
 	isapnp_wait_for_key ();
664 575
 
665
-	DBG ( "ISAPnP found device %hhx.%hhx " ISAPNP_DEV_ID_FMT
666
-	      ", base %hx irq %d\n", isapnp->csn, isapnp->logdev,
667
-	      ISAPNP_DEV_ID_DATA ( isapnp ), isapnp->ioaddr, isapnp->irqno );
668
-	DBG ( "  on card " ISAPNP_CARD_ID_FMT "\n",
669
-	      ISAPNP_CARD_ID_DATA ( &identifier ) );
670
-
671
-	return 1;
576
+	DBG ( "ISAPnP %s device %02x:%02x\n",
577
+	      ( activation ? "activated" : "deactivated" ),
578
+	      isapnp->csn, isapnp->logdev );
672 579
 }
673 580
 
674 581
 /**
675
- * Test whether or not a driver is capable of driving the device.
582
+ * Probe an ISAPnP device
676 583
  *
677
- * @v bus_dev		Bus device as filled in by isapnp_fill_device()
678
- * @v device_driver	Device driver
679
- * @ret True		Driver is capable of driving this device
680
- * @ret False		Driver is not capable of driving this device
681
- * @err None		-
584
+ * @v isapnp		ISAPnP device
585
+ * @ret rc		Return status code
682 586
  *
587
+ * Searches for a driver for the ISAPnP device.  If a driver is found,
588
+ * its probe() routine is called.
683 589
  */
684
-static int isapnp_check_driver ( struct bus_dev *bus_dev,
685
-				 struct device_driver *device_driver ) {
686
-	struct isapnp_device *isapnp = ( struct isapnp_device * ) bus_dev;
687
-	struct isapnp_driver *driver
688
-		= ( struct isapnp_driver * ) device_driver->bus_driver_info;
590
+static int isapnp_probe ( struct isapnp_device *isapnp ) {
591
+	struct isapnp_driver *driver;
592
+	struct isapnp_device_id *id;
689 593
 	unsigned int i;
690
-
691
-	/* Compare against driver's ID list */
692
-	for ( i = 0 ; i < driver->id_count ; i++ ) {
693
-		struct isapnp_id *id = &driver->ids[i];
694
-		
695
-		if ( ( isapnp->vendor_id == id->vendor_id ) &&
696
-		     ( ISA_PROD_ID ( isapnp->prod_id ) ==
697
-		       ISA_PROD_ID ( id->prod_id ) ) ) {
698
-			DBG ( "ISAPnP found ID %hx:%hx (\"%s\") (device %s) "
699
-			      "matching driver %s\n",
700
-			      isapnp->vendor_id, isapnp->prod_id,
701
-			      isa_id_string( isapnp->vendor_id,
702
-					     isapnp->prod_id ),
703
-			      id->name, device_driver->name );
704
-			isapnp->name = id->name;
705
-			return 1;
594
+	int rc;
595
+
596
+	DBG ( "Adding ISAPnP device %02x:%02x (%04x:%04x (\"%s\") "
597
+	      "io %x irq %d)\n", isapnp->csn, isapnp->logdev,
598
+	      isapnp->vendor_id, isapnp->prod_id,
599
+	      isa_id_string ( isapnp->vendor_id, isapnp->prod_id ),
600
+	      isapnp->ioaddr, isapnp->irqno );
601
+
602
+	for ( driver = isapnp_drivers; driver < isapnp_drivers_end; driver++ ){
603
+		for ( i = 0 ; i < driver->id_count ; i++ ) {
604
+			id = &driver->ids[i];
605
+			if ( id->vendor_id != isapnp->vendor_id )
606
+				continue;
607
+			if ( ISA_PROD_ID ( id->prod_id ) !=
608
+			     ISA_PROD_ID ( isapnp->prod_id ) )
609
+				continue;
610
+			isapnp->driver = driver;
611
+			isapnp->driver_name = id->name;
612
+			DBG ( "...using driver %s\n", isapnp->driver_name );
613
+			if ( ( rc = driver->probe ( isapnp, id ) ) != 0 ) {
614
+				DBG ( "......probe failed\n" );
615
+				continue;
616
+			}
617
+			return 0;
706 618
 		}
707 619
 	}
708 620
 
709
-	return 0;
621
+	DBG ( "...no driver found\n" );
622
+	return -ENOTTY;
710 623
 }
711 624
 
712 625
 /**
713
- * Describe an ISAPnP device.
714
- *
715
- * @v bus_dev		Bus device as filled in by isapnp_fill_device()
716
- * @ret string		Printable string describing the device
717
- * @err None		-
718
- *
719
- * The string returned by isapnp_describe_device() is valid only until
720
- * the next call to isapnp_describe_device().
626
+ * Remove an ISAPnP device
721 627
  *
628
+ * @v isapnp		ISAPnP device
722 629
  */
723
-static char * isapnp_describe_device ( struct bus_dev *bus_dev ) {
724
-	struct isapnp_device *isapnp = ( struct isapnp_device * ) bus_dev;
725
-	static char isapnp_description[] = "ISAPnP 00:00";
726
-
727
-	sprintf ( isapnp_description + 7, "%hhx:%hhx",
728
-		  isapnp->csn, isapnp->logdev );
729
-	return isapnp_description;
630
+static void isapnp_remove ( struct isapnp_device *isapnp ) {
631
+	isapnp->driver->remove ( isapnp );
632
+	DBG ( "Removed ISAPnP device %02x:%02x\n",
633
+	      isapnp->csn, isapnp->logdev );
730 634
 }
731 635
 
732 636
 /**
733
- * Name an ISAPnP device.
637
+ * Probe ISAPnP root bus
734 638
  *
735
- * @v bus_dev		Bus device as filled in by isapnp_fill_device()
736
- * @ret string		Printable string naming the device
737
- * @err None		-
738
- *
739
- * The string returned by isapnp_name_device() is valid only until the
740
- * next call to isapnp_name_device().
639
+ * @v rootdev		ISAPnP bus root device
741 640
  *
641
+ * Scans the ISAPnP bus for devices and registers all devices it can
642
+ * find.
742 643
  */
743
-static const char * isapnp_name_device ( struct bus_dev *bus_dev ) {
744
-	struct isapnp_device *isapnp = ( struct isapnp_device * ) bus_dev;
745
-	
746
-	return isapnp->name;
747
-}
644
+static int isapnpbus_probe ( struct root_device *rootdev ) {
645
+	struct isapnp_device *isapnp = NULL;
646
+	struct isapnp_identifier identifier;
647
+	struct isapnp_logdevid logdevid;
648
+	unsigned int csn;
649
+	unsigned int logdev;
650
+	int rc;
748 651
 
749
-/*
750
- * ISAPnP bus operations table
751
- *
752
- */
753
-struct bus_driver isapnp_driver __bus_driver = {
754
-	.name			= "ISAPnP",
755
-	.next_location		= isapnp_next_location,
756
-	.fill_device		= isapnp_fill_device,
757
-	.check_driver		= isapnp_check_driver,
758
-	.describe_device	= isapnp_describe_device,
759
-	.name_device		= isapnp_name_device,
760
-};
652
+	/* Perform isolation if it hasn't yet been done */
653
+	if ( ! isapnp_read_port )
654
+		isapnp_isolate();
761 655
 
762
-/**
763
- * Activate or deactivate an ISAPnP device.
764
- *
765
- * @v isapnp		ISAPnP device
766
- * @v activation	True to enable, False to disable the device
767
- * @ret None		-
768
- * @err None		-
769
- *
770
- * This routine simply activates the device in its current
771
- * configuration, or deactivates the device.  It does not attempt any
772
- * kind of resource arbitration.
773
- *
774
- */
775
-void isapnp_device_activation ( struct isapnp_device *isapnp,
776
-				int activation ) {
777
-	/* Wake the card and select the logical device */
778
-	isapnp_wait_for_key ();
779
-	isapnp_send_key ();
780
-	isapnp_wake ( isapnp->csn );
781
-	isapnp_logicaldevice ( isapnp->logdev );
656
+	for ( csn = 1 ; csn <= 0xff ; csn++ ) {
657
+		for ( logdev = 0 ; logdev <= 0xff ; logdev++ ) {
782 658
 
783
-	/* Activate/deactivate the logical device */
784
-	isapnp_activate ( activation );
785
-	isapnp_delay();
659
+			/* Allocate struct isapnp_device */
660
+			if ( ! isapnp )
661
+				isapnp = malloc ( sizeof ( *isapnp ) );
662
+			if ( ! isapnp ) {
663
+				rc = -ENOMEM;
664
+				goto err;
665
+			}
666
+			memset ( isapnp, 0, sizeof ( *isapnp ) );
667
+			isapnp->csn = csn;
668
+			isapnp->logdev = logdev;
669
+
670
+			/* Wake the card */
671
+			isapnp_wait_for_key();
672
+			isapnp_send_key();
673
+			isapnp_wake ( csn );
674
+
675
+			/* Read the card identifier */
676
+			isapnp_peek ( &identifier, sizeof ( identifier ) );
677
+			
678
+			/* No card with this CSN; stop here */
679
+			if ( identifier.vendor_id & 0x80 )
680
+				goto done;
681
+
682
+			/* Find the Logical Device ID tag */
683
+			if ( ( rc = isapnp_find_logdevid ( logdev,
684
+							   &logdevid ) ) != 0){
685
+				/* No more logical devices; go to next CSN */
686
+				break;
687
+			}
688
+			
689
+			/* Select the logical device */
690
+			isapnp_logicaldevice ( logdev );
691
+
692
+			/* Populate struct isapnp_device */
693
+			isapnp->vendor_id = logdevid.vendor_id;
694
+			isapnp->prod_id = logdevid.prod_id;
695
+			isapnp->ioaddr = isapnp_read_iobase ( 0 );
696
+			isapnp->irqno = isapnp_read_irqno ( 0 );
697
+
698
+			/* Return all cards to Wait for Key state */
699
+			isapnp_wait_for_key();
700
+
701
+			/* Add to device hierarchy */
702
+			snprintf ( isapnp->dev.name,
703
+				   sizeof ( isapnp->dev.name ),
704
+				   "ISAPnP%02x:%02x", csn, logdev );
705
+			isapnp->dev.desc.bus_type = BUS_TYPE_ISAPNP;
706
+			isapnp->dev.desc.vendor = isapnp->vendor_id;
707
+			isapnp->dev.desc.device = isapnp->prod_id;
708
+			isapnp->dev.parent = &rootdev->dev;
709
+			list_add ( &isapnp->dev.siblings,
710
+				   &rootdev->dev.children );
711
+			INIT_LIST_HEAD ( &isapnp->dev.children );
712
+			
713
+			/* Look for a driver */
714
+			if ( isapnp_probe ( isapnp ) == 0 ) {
715
+				/* isapnpdev registered, we can drop our ref */
716
+				isapnp = NULL;
717
+			} else {
718
+				/* Not registered; re-use struct */
719
+				list_del ( &isapnp->dev.siblings );
720
+			}
721
+		}
722
+	}
786 723
 
787
-	/* Return all cards to Wait for Key state */
788
-	isapnp_wait_for_key ();
724
+ done:
725
+	free ( isapnp );
726
+	return 0;
789 727
 
790
-	DBG ( "ISAPnP %s device %hhx.%hhx\n",
791
-	      ( activation ? "activated" : "deactivated" ),
792
-	      isapnp->csn, isapnp->logdev );
728
+ err:
729
+	free ( isapnp );
730
+	isapnpbus_remove ( rootdev );
731
+	return rc;
793 732
 }
794 733
 
795 734
 /**
796
- * Fill in a nic structure.
797
- *
798
- * @v nic		NIC structure to be filled in
799
- * @v isapnp		ISAPnP device
800
- * @ret None		-
801
- * @err None		-
802
- *
803
- * This fills in generic NIC parameters (e.g. I/O address and IRQ
804
- * number) that can be determined directly from the ISAPnP device,
805
- * without any driver-specific knowledge.
735
+ * Remove ISAPnP root bus
806 736
  *
737
+ * @v rootdev		ISAPnP bus root device
807 738
  */
808
-void isapnp_fill_nic ( struct nic *nic, struct isapnp_device *isapnp ) {
809
-
810
-	/* Fill in ioaddr and irqno */
811
-	nic->ioaddr = isapnp->ioaddr;
812
-	nic->irqno = isapnp->irqno;
813
-
814
-	/* Fill in DHCP device ID structure */
815
-	nic->dhcp_dev_id.bus_type = ISA_BUS_TYPE;
816
-	nic->dhcp_dev_id.vendor_id = htons ( isapnp->vendor_id );
817
-	nic->dhcp_dev_id.device_id = htons ( isapnp->prod_id );
739
+static void isapnpbus_remove ( struct root_device *rootdev ) {
740
+	struct isapnp_device *isapnp;
741
+	struct isapnp_device *tmp;
742
+
743
+	list_for_each_entry_safe ( isapnp, tmp, &rootdev->dev.children,
744
+				   dev.siblings ) {
745
+		isapnp_remove ( isapnp );
746
+		list_del ( &isapnp->dev.siblings );
747
+		free ( isapnp );
748
+	}
818 749
 }
819 750
 
751
+/** ISAPnP bus root device driver */
752
+static struct root_driver isapnp_root_driver = {
753
+	.probe = isapnpbus_probe,
754
+	.remove = isapnpbus_remove,
755
+};
756
+
757
+/** ISAPnP bus root device */
758
+struct root_device isapnp_root_device __root_device = {
759
+	.dev = { .name = "ISAPnP" },
760
+	.driver = &isapnp_root_driver,
761
+};

+ 148
- 128
src/drivers/bus/mca.c View File

@@ -5,157 +5,177 @@
5 5
  *
6 6
  */
7 7
 
8
-#include "string.h"
9
-#include "io.h"
10
-#include "console.h"
11
-#include "dev.h"
12
-#include "mca.h"
13
-
14
-/*
15
- * Increment a bus_loc structure to the next possible MCA location.
16
- * Leave the structure zeroed and return 0 if there are no more valid
17
- * locations.
8
+#include <stdint.h>
9
+#include <string.h>
10
+#include <stdlib.h>
11
+#include <stdio.h>
12
+#include <errno.h>
13
+#include <io.h>
14
+#include <timer.h>
15
+#include <gpxe/mca.h>
16
+
17
+static struct mca_driver mca_drivers[0]
18
+	__table_start ( struct mca_driver, mca_drivers );
19
+static struct mca_driver mca_drivers_end[0]
20
+	__table_end ( struct mca_driver, mca_drivers );
21
+
22
+static void mcabus_remove ( struct root_device *rootdev );
23
+
24
+/**
25
+ * Probe an MCA device
18 26
  *
19
- */
20
-static int mca_next_location ( struct bus_loc *bus_loc ) {
21
-	struct mca_loc *mca_loc = ( struct mca_loc * ) bus_loc;
22
-	
23
-	/*
24
-	 * Ensure that there is sufficient space in the shared bus
25
-	 * structures for a struct mca_loc and a struct
26
-	 * mca_dev, as mandated by bus.h.
27
-	 *
28
-	 */
29
-	BUS_LOC_CHECK ( struct mca_loc );
30
-	BUS_DEV_CHECK ( struct mca_device );
31
-
32
-	return ( mca_loc->slot = ( ++mca_loc->slot & MCA_MAX_SLOT_NR ) );
33
-}
34
-
35
-/*
36
- * Fill in parameters for an MCA device based on slot number
27
+ * @v mca		MCA device
28
+ * @ret rc		Return status code
37 29
  *
30
+ * Searches for a driver for the MCA device.  If a driver is found,
31
+ * its probe() routine is called.
38 32
  */
39
-static int mca_fill_device ( struct bus_dev *bus_dev,
40
-			     struct bus_loc *bus_loc ) {
41
-	struct mca_loc *mca_loc = ( struct mca_loc * ) bus_loc;
42
-	struct mca_device *mca = ( struct mca_device * ) bus_dev;
43
-	unsigned int i, seen_non_ff;
44
-
45
-	/* Store slot in struct mca, set default values */
46
-	mca->slot = mca_loc->slot;
47
-	mca->name = "?";
48
-
49
-	/* Make sure motherboard setup is off */
50
-	outb_p ( 0xff, MCA_MOTHERBOARD_SETUP_REG );
51
-
52
-	/* Select the slot */
53
-	outb_p ( 0x8 | ( mca->slot & 0xf ), MCA_ADAPTER_SETUP_REG );
54
-
55
-	/* Read the POS registers */
56
-	seen_non_ff = 0;
57
-	for ( i = 0 ; i < ( sizeof ( mca->pos ) / sizeof ( mca->pos[0] ) ) ;
58
-	      i++ ) {
59
-		mca->pos[i] = inb_p ( MCA_POS_REG ( i ) );
60
-		if ( mca->pos[i] != 0xff )
61
-			seen_non_ff = 1;
62
-	}
63
-	
64
-	/* If all POS registers are 0xff, this means there's no device
65
-	 * present
66
-	 */
67
-	if ( ! seen_non_ff )
68
-		return 0;
69
-
70
-	/* Kill all setup modes */
71
-	outb_p ( 0, MCA_ADAPTER_SETUP_REG );
33
+static int mca_probe ( struct mca_device *mca ) {
34
+	struct mca_driver *driver;
35
+	struct mca_device_id *id;
36
+	unsigned int i;
37
+	int rc;
72 38
 
73
-	DBG ( "MCA found slot %d id %hx "
74
-	      "(POS %hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx)\n",
39
+	DBG ( "Adding MCA slot %02x (ID %04x POS "
40
+	      "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x)\n",
75 41
 	      mca->slot, MCA_ID ( mca ),
76 42
 	      mca->pos[0], mca->pos[1], mca->pos[2], mca->pos[3],
77 43
 	      mca->pos[4], mca->pos[5], mca->pos[6], mca->pos[7] );
78 44
 
79
-	return 1;
80
-}
81
-
82
-/*
83
- * Test whether or not a driver is capable of driving the device.
84
- *
85
- */
86
-static int mca_check_driver ( struct bus_dev *bus_dev,
87
-			      struct device_driver *device_driver ) {
88
-	struct mca_device *mca = ( struct mca_device * ) bus_dev;
89
-	struct mca_driver *driver
90
-		= ( struct mca_driver * ) device_driver->bus_driver_info;
91
-	unsigned int i;
92
-
93
-	/* Compare against driver's ID list */
94
-	for ( i = 0 ; i < driver->id_count ; i++ ) {
95
-		struct mca_id *id = &driver->ids[i];
96
-		
97
-		if ( MCA_ID ( mca ) == id->id ) {
98
-			DBG ( "MCA found ID %hx (device %s) "
99
-			      "matching driver %s\n",
100
-			      id->name, id->id, device_driver->name );
101
-			mca->name = id->name;
102
-			return 1;
45
+	for ( driver = mca_drivers; driver < mca_drivers_end; driver++ ){
46
+		for ( i = 0 ; i < driver->id_count ; i++ ) {
47
+			id = &driver->ids[i];
48
+			if ( id->id != MCA_ID ( mca ) )
49
+				continue;
50
+			mca->driver = driver;
51
+			mca->driver_name = id->name;
52
+			DBG ( "...using driver %s\n", mca->driver_name );
53
+			if ( ( rc = driver->probe ( mca, id ) ) != 0 ) {
54
+				DBG ( "......probe failed\n" );
55
+				continue;
56
+			}
57
+			return 0;
103 58
 		}
104 59
 	}
105 60
 
106
-	/* No device found */
107
-	return 0;
61
+	DBG ( "...no driver found\n" );
62
+	return -ENOTTY;
108 63
 }
109 64
 
110
-/*
111
- * Describe an MCA device
65
+/**
66
+ * Remove an MCA device
112 67
  *
68
+ * @v mca		MCA device
113 69
  */
114
-static char * mca_describe_device ( struct bus_dev *bus_dev ) {
115
-	struct mca_device *mca = ( struct mca_device * ) bus_dev;
116
-	static char mca_description[] = "MCA 00";
117
-
118
-	sprintf ( mca_description + 4, "%hhx", mca->slot );
119
-	return mca_description;
70
+static void mca_remove ( struct mca_device *mca ) {
71
+	mca->driver->remove ( mca );
72
+	DBG ( "Removed MCA device %02x\n", mca->slot );
120 73
 }
121 74
 
122
-/*
123
- * Name an MCA device
75
+/**
76
+ * Probe MCA root bus
77
+ *
78
+ * @v rootdev		MCA bus root device
124 79
  *
80
+ * Scans the MCA bus for devices and registers all devices it can
81
+ * find.
125 82
  */
126
-static const char * mca_name_device ( struct bus_dev *bus_dev ) {
127
-	struct mca_device *mca = ( struct mca_device * ) bus_dev;
83
+static int mcabus_probe ( struct root_device *rootdev ) {
84
+	struct mca_device *mca = NULL;
85
+	unsigned int slot;
86
+	int seen_non_ff;
87
+	unsigned int i;
88
+	int rc;
89
+
90
+	for ( slot = 0 ; slot <= MCA_MAX_SLOT_NR ; slot++ ) {
91
+		/* Allocate struct mca_device */
92
+		if ( ! mca )
93
+			mca = malloc ( sizeof ( *mca ) );
94
+		if ( ! mca ) {
95
+			rc = -ENOMEM;
96
+			goto err;
97
+		}
98
+		memset ( mca, 0, sizeof ( *mca ) );
99
+		mca->slot = slot;
100
+
101
+		/* Make sure motherboard setup is off */
102
+		outb_p ( 0xff, MCA_MOTHERBOARD_SETUP_REG );
103
+
104
+		/* Select the slot */
105
+		outb_p ( 0x8 | ( mca->slot & 0xf ), MCA_ADAPTER_SETUP_REG );
106
+
107
+		/* Read the POS registers */
108
+		seen_non_ff = 0;
109
+		for ( i = 0 ; i < ( sizeof ( mca->pos ) /
110
+				    sizeof ( mca->pos[0] ) ) ; i++ ) {
111
+			mca->pos[i] = inb_p ( MCA_POS_REG ( i ) );
112
+			if ( mca->pos[i] != 0xff )
113
+				seen_non_ff = 1;
114
+		}
128 115
 	
129
-	return mca->name;
116
+		/* Kill all setup modes */
117
+		outb_p ( 0, MCA_ADAPTER_SETUP_REG );
118
+
119
+		/* If all POS registers are 0xff, this means there's no device
120
+		 * present
121
+		 */
122
+		if ( ! seen_non_ff )
123
+			continue;
124
+
125
+		/* Add to device hierarchy */
126
+		snprintf ( mca->dev.name, sizeof ( mca->dev.name ),
127
+			   "MCA%02x", slot );
128
+		mca->dev.desc.bus_type = BUS_TYPE_MCA;
129
+		mca->dev.desc.vendor = GENERIC_MCA_VENDOR;
130
+		mca->dev.desc.device = MCA_ID ( mca );
131
+		mca->dev.parent = &rootdev->dev;
132
+		list_add ( &mca->dev.siblings, &rootdev->dev.children );
133
+		INIT_LIST_HEAD ( &mca->dev.children );
134
+
135
+		/* Look for a driver */
136
+		if ( mca_probe ( mca ) == 0 ) {
137
+			/* mcadev registered, we can drop our ref */
138
+			mca = NULL;
139
+		} else {
140
+			/* Not registered; re-use struct */
141
+			list_del ( &mca->dev.siblings );
142
+		}
143
+	}
144
+
145
+	free ( mca );
146
+	return 0;
147
+
148
+ err:
149
+	free ( mca );
150
+	mcabus_remove ( rootdev );
151
+	return rc;
130 152
 }
131 153
 
132
-/*
133
- * MCA bus operations table
154
+/**
155
+ * Remove MCA root bus
134 156
  *
157
+ * @v rootdev		MCA bus root device
135 158
  */
136
-struct bus_driver mca_driver __bus_driver = {
137
-	.name			= "MCA",
138
-	.next_location		= mca_next_location,
139
-	.fill_device		= mca_fill_device,
140
-	.check_driver		= mca_check_driver,
141
-	.describe_device	= mca_describe_device,
142
-	.name_device		= mca_name_device,
159
+static void mcabus_remove ( struct root_device *rootdev ) {
160
+	struct mca_device *mca;
161
+	struct mca_device *tmp;
162
+
163
+	list_for_each_entry_safe ( mca, tmp, &rootdev->dev.children,
164
+				   dev.siblings ) {
165
+		mca_remove ( mca );
166
+		list_del ( &mca->dev.siblings );
167
+		free ( mca );
168
+	}
169
+}
170
+
171
+/** MCA bus root device driver */
172
+static struct root_driver mca_root_driver = {
173
+	.probe = mcabus_probe,
174
+	.remove = mcabus_remove,
143 175
 };
144 176
 
145
-/*
146
- * Fill in a nic structure
147
- *
148
- */
149
-void mca_fill_nic ( struct nic *nic, struct mca_device *mca ) {
150
-
151
-	/* ioaddr and irqno must be read in a device-dependent way
152
-	 * from the POS registers
153
-	 */
154
-	nic->ioaddr = 0;
155
-	nic->irqno = 0;
156
-
157
-	/* Fill in DHCP device ID structure */
158
-	nic->dhcp_dev_id.bus_type = MCA_BUS_TYPE;
159
-	nic->dhcp_dev_id.vendor_id = htons ( GENERIC_MCA_VENDOR );
160
-	nic->dhcp_dev_id.device_id = htons ( MCA_ID ( mca ) );
161
-}
177
+/** MCA bus root device */
178
+struct root_device mca_root_device __root_device = {
179
+	.dev = { .name = "MCA" },
180
+	.driver = &mca_root_driver,
181
+};

+ 3
- 3
src/drivers/bus/pci.c View File

@@ -283,9 +283,9 @@ static int pcibus_probe ( struct root_device *rootdev ) {
283 283
 				   "PCI%02x:%02x.%x", bus,
284 284
 				   PCI_SLOT ( devfn ), PCI_FUNC ( devfn ) );
285 285
 			pci->dev.desc.bus_type = BUS_TYPE_PCI;
286
-			pci->dev.desc.pci.busdevfn = PCI_BUSDEVFN (bus, devfn);
287
-			pci->dev.desc.pci.vendor = pci->vendor;
288
-			pci->dev.desc.pci.device = pci->device;
286
+			pci->dev.desc.location = PCI_BUSDEVFN (bus, devfn);
287
+			pci->dev.desc.vendor = pci->vendor;
288
+			pci->dev.desc.device = pci->device;
289 289
 			pci->dev.parent = &rootdev->dev;
290 290
 			list_add ( &pci->dev.siblings, &rootdev->dev.children);
291 291
 			INIT_LIST_HEAD ( &pci->dev.children );

+ 3
- 3
src/drivers/net/3c509-eisa.c View File

@@ -4,8 +4,8 @@
4 4
  *
5 5
  */
6 6
 
7
-#include "eisa.h"
8
-#include "isa.h"
7
+#include <gpxe/eisa.h>
8
+#include <gpxe/isa.h>
9 9
 #include "console.h"
10 10
 #include "3c509.h"
11 11
 
@@ -27,7 +27,7 @@ static void el3_eisa_disable ( struct nic *nic, struct eisa_device *eisa ) {
27 27
 	disable_eisa_device ( eisa );
28 28
 }
29 29
 
30
-static struct eisa_id el3_eisa_adapters[] = {
30
+static struct eisa_device_id el3_eisa_adapters[] = {
31 31
 	{ "3Com 3c509 EtherLink III (EISA)", MFG_ID, PROD_ID },
32 32
 };
33 33
 

+ 5
- 1
src/drivers/net/3c509.c View File

@@ -4,7 +4,9 @@
4 4
  *
5 5
  */
6 6
 
7
-#include "isa.h"
7
+#if 0
8
+
9
+#include <gpxe/isa.h>
8 10
 #include "io.h"
9 11
 #include "timer.h"
10 12
 #include "string.h"
@@ -399,3 +401,5 @@ DRIVER ( "3c509", nic_driver, t509_driver, el3_t509_driver,
399 401
 	 el3_t509_probe, el3_t509_disable );
400 402
 
401 403
 ISA_ROM ( "3c509", "3c509" );
404
+
405
+#endif

+ 2
- 0
src/drivers/net/3c509.h View File

@@ -31,6 +31,8 @@
31 31
 
32 32
  */
33 33
 
34
+#include "nic.h"
35
+
34 36
 /*
35 37
  * Ethernet software status per interface.
36 38
  */

+ 3
- 3
src/drivers/net/3c515.c View File

@@ -48,8 +48,8 @@
48 48
 #include "etherboot.h"
49 49
 /* to get the interface to the body of the program */
50 50
 #include "nic.h"
51
-#include "isapnp.h"
52
-#include "isa.h" /* for ISA_ROM */
51
+#include <gpxe/isapnp.h>
52
+#include <gpxe/isa.h> /* for ISA_ROM */
53 53
 #include "timer.h"
54 54
 #include <gpxe/ethernet.h>
55 55
 
@@ -753,7 +753,7 @@ corkscrew_probe1(int ioaddr, int irq, int product_index __unused,
753 753
 	return 0;
754 754
 }
755 755
 
756
-static struct isapnp_id t515_adapters[] = {
756
+static struct isapnp_device_id t515_adapters[] = {
757 757
 	{ "3c515 (ISAPnP)", ISAPNP_VENDOR('T','C','M'), 0x5051 },
758 758
 };
759 759
 

+ 3
- 3
src/drivers/net/3c529.c View File

@@ -4,8 +4,8 @@
4 4
  */
5 5
 
6 6
 #include "etherboot.h"
7
-#include "mca.h"
8
-#include "isa.h" /* for ISA_ROM */
7
+#include <gpxe/mca.h>
8
+#include <gpxe/isa.h> /* for ISA_ROM */
9 9
 #include "nic.h"
10 10
 #include "3c509.h"
11 11
 
@@ -37,7 +37,7 @@ static void t529_disable ( struct nic *nic, struct mca_device *mca __unused ) {
37 37
 	t5x9_disable ( nic );
38 38
 }
39 39
 
40
-static struct mca_id el3_mca_adapters[] = {
40
+static struct mca_device_id el3_mca_adapters[] = {
41 41
         { "3Com 3c529 EtherLink III (10base2)", 0x627c },
42 42
         { "3Com 3c529 EtherLink III (10baseT)", 0x627d },
43 43
         { "3Com 3c529 EtherLink III (test mode)", 0x62db },

+ 1
- 1
src/drivers/net/3c5x9.c View File

@@ -27,7 +27,7 @@ $Id$
27 27
 #include <gpxe/ethernet.h>
28 28
 #include "etherboot.h"
29 29
 #include "nic.h"
30
-#include "isa.h"
30
+#include <gpxe/isa.h>
31 31
 #include "timer.h"
32 32
 #include "3c509.h"
33 33
 

+ 1
- 1
src/drivers/net/cs89x0.c View File

@@ -69,7 +69,7 @@
69 69
 #include <gpxe/ethernet.h>
70 70
 #include "etherboot.h"
71 71
 #include "nic.h"
72
-#include "isa.h"
72
+#include <gpxe/isa.h>
73 73
 #include "console.h"
74 74
 #include "cs89x0.h"
75 75
 

+ 1
- 1
src/drivers/net/depca.c View File

@@ -236,7 +236,7 @@
236 236
 
237 237
 #include "etherboot.h"
238 238
 #include "nic.h"
239
-#include "isa.h"
239
+#include <gpxe/isa.h>
240 240
 #include "console.h"
241 241
 #include <gpxe/ethernet.h>
242 242
 

+ 7
- 6
src/drivers/net/eepro.c View File

@@ -33,7 +33,7 @@ has 34 pins, the top row of 2 are not used.
33 33
 
34 34
 #include "etherboot.h"
35 35
 #include "nic.h"
36
-#include "isa.h"
36
+#include <gpxe/isa.h>
37 37
 #include "timer.h"
38 38
 #include <gpxe/ethernet.h>
39 39
 
@@ -557,6 +557,7 @@ static int eepro_probe ( struct nic *nic, struct isa_device *isa ) {
557 557
 		unsigned char	caddr[ETH_ALEN];
558 558
 		unsigned short	saddr[ETH_ALEN/2];
559 559
 	} station_addr;
560
+	const char *name;
560 561
 
561 562
 	nic->irqno  = 0;
562 563
 	isa_fill_nic ( nic, isa );
@@ -576,16 +577,16 @@ static int eepro_probe ( struct nic *nic, struct isa_device *isa ) {
576 577
 	station_addr.saddr[1] = read_eeprom(nic->ioaddr,3);
577 578
 	station_addr.saddr[0] = read_eeprom(nic->ioaddr,4);
578 579
 	if (l_eepro)
579
-		isa->name = "Intel EtherExpress 10 ISA";
580
+		name = "Intel EtherExpress 10 ISA";
580 581
 	else if (read_eeprom(nic->ioaddr,7) == ee_FX_INT2IRQ) {
581
-		isa->name = "Intel EtherExpress Pro/10+ ISA";
582
+		name = "Intel EtherExpress Pro/10+ ISA";
582 583
 		l_eepro = 2;
583 584
 	} else if (station_addr.saddr[0] == SA_ADDR1) {
584
-		isa->name = "Intel EtherExpress Pro/10 ISA";
585
+		name = "Intel EtherExpress Pro/10 ISA";
585 586
 		l_eepro = 1;
586 587
 	} else {
587 588
 		l_eepro = 0;
588
-		isa->name = "Intel 82595-based LAN card";
589
+		name = "Intel 82595-based LAN card";
589 590
 	}
590 591
 	station_addr.saddr[0] = swap16(station_addr.saddr[0]);
591 592
 	station_addr.saddr[1] = swap16(station_addr.saddr[1]);
@@ -594,7 +595,7 @@ static int eepro_probe ( struct nic *nic, struct isa_device *isa ) {
594 595
 		nic->node_addr[i] = station_addr.caddr[i];
595 596
 	}
596 597
 
597
-	DBG ( "%s ioaddr %#hX, addr %s", isa->name, nic->ioaddr, eth_ntoa ( nic->node_addr ) );
598
+	DBG ( "%s ioaddr %#hX, addr %s", name, nic->ioaddr, eth_ntoa ( nic->node_addr ) );
598 599
 
599 600
 	mem_start = RCV_LOWER_LIMIT << 8;
600 601
 	if ((mem_end & 0x3F) < 3 || (mem_end & 0x3F) > 29)

+ 14
- 20
src/drivers/net/legacy.c View File

@@ -64,11 +64,11 @@ static void legacy_close ( struct net_device *netdev __unused ) {
64 64
 	/* Nothing to do */
65 65
 }
66 66
 
67
-int legacy_probe ( struct pci_device *pci,
68
-		   const struct pci_device_id *id __unused,
69
-		   int ( * probe ) ( struct nic *nic,
70
-				     struct pci_device *pci ),
71
-		   void ( * disable ) ( struct nic *nic ) ) {
67
+int legacy_probe ( void *hwdev,
68
+		   void ( * set_drvdata ) ( void *hwdev, void *priv ),
69
+		   struct device *dev,
70
+		   int ( * probe ) ( struct nic *nic, void *hwdev ),
71
+		   void ( * disable ) ( struct nic *nic, void *hwdev ) ) {
72 72
 	struct net_device *netdev;
73 73
 	int rc;
74 74
 
@@ -80,8 +80,8 @@ int legacy_probe ( struct pci_device *pci,
80 80
 		return -ENOMEM;
81 81
 	netdev->priv = &nic;
82 82
 	memset ( &nic, 0, sizeof ( nic ) );
83
-	pci_set_drvdata ( pci, netdev );
84
-	netdev->dev = &pci->dev;
83
+	set_drvdata ( hwdev, netdev );
84
+	netdev->dev = dev;
85 85
 
86 86
 	netdev->open = legacy_open;
87 87
 	netdev->close = legacy_close;
@@ -89,13 +89,13 @@ int legacy_probe ( struct pci_device *pci,
89 89
 	netdev->poll = legacy_poll;
90 90
 	nic.node_addr = netdev->ll_addr;
91 91
 
92
-	if ( ! probe ( &nic, pci ) ) {
92
+	if ( ! probe ( &nic, hwdev ) ) {
93 93
 		free_netdev ( netdev );
94 94
 		return -ENODEV;
95 95
 	}
96 96
 
97 97
 	if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
98
-		disable ( &nic );
98
+		disable ( &nic, hwdev );
99 99
 		free_netdev ( netdev );
100 100
 		return rc;
101 101
 	}
@@ -108,22 +108,18 @@ int legacy_probe ( struct pci_device *pci,
108 108
 	return 0;
109 109
 }
110 110
 
111
-void legacy_remove ( struct pci_device *pci,
112
-		     void ( * disable ) ( struct nic *nic ) ) {
113
-	struct net_device *netdev = pci_get_drvdata ( pci );
111
+void legacy_remove ( void *hwdev,
112
+		     void * ( * get_drvdata ) ( void *hwdev ),
113
+		     void ( * disable ) ( struct nic *nic, void *hwdev ) ) {
114
+	struct net_device *netdev = get_drvdata ( hwdev );
114 115
 	struct nic *nic = netdev->priv;
115 116
 
116 117
 	unregister_netdev ( netdev );
117
-	disable ( nic );
118
+	disable ( nic, hwdev );
118 119
 	free_netdev ( netdev );
119 120
 	legacy_registered = 0;
120 121
 }
121 122
 
122
-void pci_fill_nic ( struct nic *nic, struct pci_device *pci ) {
123
-	nic->ioaddr = pci->ioaddr;
124
-	nic->irqno = pci->irq;
125
-}
126
-
127 123
 int dummy_connect ( struct nic *nic __unused ) {
128 124
 	return 1;
129 125
 }
@@ -131,5 +127,3 @@ int dummy_connect ( struct nic *nic __unused ) {
131 127
 void dummy_irq ( struct nic *nic __unused, irq_action_t irq_action __unused ) {
132 128
 	return;
133 129
 }
134
-
135
-REQUIRE_OBJECT ( pci );

+ 1
- 1
src/drivers/net/mlx_ipoib/mt23108.c View File

@@ -17,7 +17,7 @@ Skeleton NIC driver for Etherboot
17 17
 /* to get the PCI support functions, if this is a PCI NIC */
18 18
 #include <gpxe/pci.h>
19 19
 /* to get the ISA support functions, if this is an ISA NIC */
20
-#include "isa.h"
20
+#include <gpxe/isa.h>
21 21
 
22 22
 #include "mt_version.c"
23 23
 #include "mt23108_imp.c"

+ 1
- 1
src/drivers/net/mlx_ipoib/mt25218.c View File

@@ -17,7 +17,7 @@ Skeleton NIC driver for Etherboot
17 17
 /* to get the PCI support functions, if this is a PCI NIC */
18 18
 #include <gpxe/pci.h>
19 19
 /* to get the ISA support functions, if this is an ISA NIC */
20
-#include "isa.h"
20
+#include <gpxe/isa.h>
21 21
 
22 22
 #include "mt_version.c"
23 23
 #include "mt25218_imp.c"

+ 1
- 1
src/drivers/net/ns8390.c View File

@@ -36,7 +36,7 @@ SMC8416 PIO support added by Andrew Bettison (andrewb@zip.com.au) on 4/3/02
36 36
 #ifdef	INCLUDE_NS8390
37 37
 #include <gpxe/pci.h>
38 38
 #else
39
-#include "isa.h"
39
+#include <gpxe/isa.h>
40 40
 #endif
41 41
 
42 42
 static unsigned char	eth_vendor, eth_flags;

+ 0
- 419
src/drivers/net/skel.c View File

@@ -1,419 +0,0 @@
1
-/**************************************************************************
2
-Etherboot -  BOOTP/TFTP Bootstrap Program
3
-Skeleton NIC driver for Etherboot
4
-***************************************************************************/
5
-
6
-/*
7
- * This program is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU General Public License as
9
- * published by the Free Software Foundation; either version 2, or (at
10
- * your option) any later version.
11
- */
12
-
13
-#include "etherboot.h"
14
-#include "nic.h"
15
-#include <gpxe/pci.h>
16
-#include <gpxe/ethernet.h>
17
-#include "isa.h"
18
-#include "eisa.h"
19
-#include "isapnp.h"
20
-#include "mca.h"
21
-
22
-/*
23
- * NIC specific static variables go here.  Try to avoid using static
24
- * variables wherever possible.  In particular, the I/O address can
25
- * always be accessed via nic->ioaddr.
26
- */
27
-
28
-/*
29
- * If you have large static variables (e.g. transmit and receive
30
- * buffers), you should place them together in a single structure and
31
- * mark the structure as "shared".  This enables this space to be
32
- * shared between drivers in multi-driver images, which can easily
33
- * reduce the runtime size by 50%.
34
- *
35
- */
36
-#define SKEL_RX_BUFS	1
37
-#define SKEL_TX_BUFS	1
38
-#define SKEL_RX_BUFSIZE	0
39
-#define SKEL_TX_BUFSIZE 0
40
-struct skel_rx_desc {};
41
-struct skel_tx_desc {};
42
-struct {
43
-	struct skel_rx_desc	rxd[SKEL_RX_BUFS];
44
-	unsigned char		rxb[SKEL_RX_BUFS][SKEL_RX_BUFSIZE];
45
-	struct skel_tx_desc	txd[SKEL_TX_BUFS];
46
-	unsigned char		txb[SKEL_TX_BUFS][SKEL_TX_BUFSIZE];
47
-} skel_bufs __shared;
48
-
49
-/*
50
- * Don't forget to remove "__unused" from all the function parameters!
51
- *
52
- */
53
-
54
-/**************************************************************************
55
- * CONNECT - Connect to the network
56
- **************************************************************************
57
-*/
58
-static int skel_connect ( struct nic *nic __unused ) {
59
-	/*
60
-	 * Connect to the network.  For most NICs, this will probably
61
-	 * be a no-op.  For wireless NICs, this should be the point at
62
-	 * which you attempt to join to an access point.
63
-	 *
64
-	 * Return 0 if the connection failed (e.g. no cable plugged
65
-	 * in), 1 for success.
66
-	 *
67
-	 */
68
-	return 1;
69
-}
70
-
71
-/**************************************************************************
72
- * TRANSMIT - Transmit a frame
73
- **************************************************************************
74
-*/
75
-static void skel_transmit ( struct nic *nic __unused,
76
-			    const char *dest __unused,
77
-			    unsigned int type __unused,
78
-			    unsigned int size __unused,
79
-			    const char *packet __unused ) {
80
-	/* Transmit packet to dest MAC address.  You will need to
81
-	 * construct the link-layer header (dest MAC, source MAC,
82
-	 * type).
83
-	 */
84
-	/*
85
-	   unsigned int nstype = htons ( type );
86
-	   memcpy ( <tx_buffer>, dest, ETH_ALEN );
87
-	   memcpy ( <tx_buffer> + ETH_ALEN, nic->node_addr, ETH_ALEN );
88
-	   memcpy ( <tx_buffer> + 2 * ETH_ALEN, &nstype, 2 );
89
-	   memcpy ( <tx_buffer> + ETH_HLEN, data, size );
90
-	   <transmit_data> ( <tx_buffer>, size + ETH_HLEN );
91
-	 */
92
-}
93
-
94
-/**************************************************************************
95
- * POLL - Wait for a frame
96
- **************************************************************************
97
-*/
98
-static int skel_poll ( struct nic *nic __unused, int retrieve __unused ) {
99
-	/* Work out whether or not there's an ethernet packet ready to
100
-	 * read.  Return 0 if not.
101
-	 */
102
-	/* 
103
-	   if ( ! <packet_ready> ) return 0;
104
-	*/
105
-
106
-	/* retrieve==0 indicates that we are just checking for the
107
-	 * presence of a packet but don't want to read it just yet.
108
-	 */
109
-	/*
110
-	   if ( ! retrieve ) return 1;
111
-	*/
112
-
113
-	/* Copy data to nic->packet.  Data should include the
114
-	 * link-layer header (dest MAC, source MAC, type).
115
-	 * Store length of data in nic->packetlen.
116
-	 * Return true to indicate a packet has been read.
117
-	 */
118
-	/* 
119
-	   nic->packetlen = <packet_length>;
120
-	   memcpy ( nic->packet, <packet_data>, <packet_length> );
121
-	   return 1;
122
-	*/
123
-
124
-	return 0;	/* Remove this line once this method is implemented */
125
-}
126
-
127
-/**************************************************************************
128
- * IRQ - handle interrupts
129
- **************************************************************************
130
-*/
131
-static void skel_irq ( struct nic *nic __unused, irq_action_t action ) {
132
-	/* This routine is somewhat optional.  Etherboot itself
133
-	 * doesn't use interrupts, but they are required under some
134
-	 * circumstances when we're acting as a PXE stack.
135
-	 *
136
-	 * If you don't implement this routine, the only effect will
137
-	 * be that your driver cannot be used via Etherboot's UNDI
138
-	 * API.  This won't affect programs that use only the UDP
139
-	 * portion of the PXE API, such as pxelinux.
140
-	 */
141
-       
142
-	switch ( action ) {
143
-	case DISABLE :
144
-	case ENABLE :
145
-		/* Set receive interrupt enabled/disabled state */
146
-		/*
147
-		  outb ( action == ENABLE ? IntrMaskEnabled : IntrMaskDisabled,
148
-		  	 nic->ioaddr + IntrMaskRegister );
149
-		 */
150
-		break;
151
-	case FORCE :
152
-		/* Force NIC to generate a receive interrupt */
153
-		/*
154
-		  outb ( ForceInterrupt, nic->ioaddr + IntrForceRegister );
155
-		 */
156
-		break;
157
-	}
158
-}
159
-
160
-/**************************************************************************
161
- * OPERATIONS TABLE - Pointers to all the above methods
162
- **************************************************************************
163
- */
164
-static struct nic_operations skel_operations = {
165
-	.connect	= skel_connect,
166
-	.transmit	= skel_transmit,
167
-	.poll		= skel_poll,
168
-	.irq		= skel_irq,
169
-};
170
-
171
-/**************************************************************************
172
- * PROBE - Look for an adapter
173
- *
174
- * You need to define a probe routine and a disable routine for each
175
- * bus type that your driver supports, together with tables that
176
- * enable Etherboot to identify that your driver should be used for a
177
- * particular device.
178
- *
179
- * Delete whichever of the following sections you don't need.  For
180
- * example, most PCI devices will only need the PCI probing section;
181
- * ISAPnP, EISA, etc. can all be deleted.
182
- *
183
- * Some devices will need custom bus logic.  The ISA 3c509 is a good
184
- * example of this; it has a contention-resolution mechanism that is
185
- * similar to ISAPnP, but not close enough to use the generic ISAPnP
186
- * code.  Look at 3c509.c to see how it works.
187
- *
188
- **************************************************************************
189
- */
190
-
191
-/**************************************************************************
192
- * PCI PROBE and DISABLE
193
- **************************************************************************
194
- */
195
-static int skel_pci_probe ( struct nic *nic, struct pci_device *pci ) {
196
-
197
-	pci_fill_nic ( nic, pci );
198
-
199
-	/* Test for physical presence of NIC */
200
-	/*
201
-	   if ( ! my_tests ) {
202
-	  	DBG ( "Could not find NIC: my explanation\n" );
203
-		return 0;
204
-	   }
205
-	*/
206
-
207
-	/* point to NIC specific routines */
208
-	nic->nic_op = &skel_operations;
209
-	return 1;
210
-}
211
-
212
-static void skel_pci_disable ( struct nic *nic __unused ) {
213
-	/* Reset the card to its initial state, disable DMA and
214
-	 * interrupts
215
-	 */
216
-}
217
-
218
-static struct pci_device_id skel_pci_nics[] = {
219
-PCI_ROM ( 0x0000, 0x0000, "skel-pci", "Skeleton PCI Adapter" ),
220
-};
221
-
222
-PCI_DRIVER ( skel_pci_driver, skel_pci_nics, PCI_NO_CLASS );
223
-
224
-DRIVER ( "SKEL/PCI", nic_driver, pci_driver, skel_pci_driver,
225
-	 skel_pci_probe, skel_pci_disable );
226
-
227
-/**************************************************************************
228
- * EISA PROBE and DISABLE
229
- **************************************************************************
230
- */
231
-static int skel_eisa_probe ( struct nic *nic, struct eisa_device *eisa ) {
232
-
233
-	eisa_fill_nic ( nic, eisa );
234
-	enable_eisa_device ( eisa );
235
-	nic->irqno = 0; /* No standard way to get irq from EISA cards */
236
-
237
-	/* Test for physical presence of NIC */
238
-	/*
239
-	   if ( ! my_tests ) {
240
-	  	DBG ( "Could not find NIC: my explanation\n" );
241
-		return 0;
242
-	   }
243
-	*/
244
-
245
-	/* point to NIC specific routines */
246
-	nic->nic_op = &skel_operations;
247
-	return 1;
248
-}
249
-
250
-static void skel_eisa_disable ( struct nic *nic __unused,
251
-				struct eisa_device *eisa ) {
252
-	/* Reset the card to its initial state, disable DMA and
253
-	 * interrupts
254
-	 */
255
-	disable_eisa_device ( eisa );
256
-}
257
-
258
-static struct eisa_id skel_eisa_nics[] = {
259
-	{ "Skeleton EISA Adapter", EISA_VENDOR('S','K','L'), 0x0000 },
260
-};
261
-
262
-EISA_DRIVER ( skel_eisa_driver, skel_eisa_nics );
263
-
264
-DRIVER ( "SKEL/EISA", nic_driver, eisa_driver, skel_eisa_driver,
265
-	 skel_eisa_probe, skel_eisa_disable );
266
-
267
-ISA_ROM ( "skel-eisa", "Skeleton EISA Adapter" );
268
-
269
-/**************************************************************************
270
- * ISAPnP PROBE and DISABLE
271
- **************************************************************************
272
- */
273
-static int skel_isapnp_probe ( struct nic *nic,
274
-			       struct isapnp_device *isapnp ) {
275
-
276
-	isapnp_fill_nic ( nic, isapnp );
277
-	activate_isapnp_device ( isapnp );
278
-
279
-	/* Test for physical presence of NIC */
280
-	/*
281
-	   if ( ! my_tests ) {
282
-	  	DBG ( "Could not find NIC: my explanation\n" );
283
-		return 0;
284
-	   }
285
-	*/
286
-
287
-	/* point to NIC specific routines */
288
-	nic->nic_op = &skel_operations;
289
-	return 1;
290
-}
291
-
292
-static void skel_isapnp_disable ( struct nic *nic __unused,
293
-				  struct isapnp_device *isapnp ) {
294
-	/* Reset the card to its initial state, disable DMA and
295
-	 * interrupts
296
-	 */
297
-	deactivate_isapnp_device ( isapnp );
298
-}
299
-
300
-static struct isapnp_id skel_isapnp_nics[] = {
301
-	{ "Skeleton ISAPnP Adapter", ISAPNP_VENDOR('S','K','L'), 0x0000 },
302
-};
303
-
304
-ISAPNP_DRIVER ( skel_isapnp_driver, skel_isapnp_nics );
305
-
306
-DRIVER ( "SKEL/ISAPnP", nic_driver, isapnp_driver, skel_isapnp_driver,
307
-	 skel_isapnp_probe, skel_isapnp_disable );
308
-
309
-ISA_ROM ( "skel-isapnp", "Skeleton ISAPnP Adapter" );
310
-
311
-/**************************************************************************
312
- * MCA PROBE and DISABLE
313
- **************************************************************************
314
- */
315
-static int skel_mca_probe ( struct nic *nic,
316
-			    struct mca_device *mca ) {
317
-
318
-	mca_fill_nic ( nic, mca );
319
-
320
-	/* MCA parameters are available in the mca->pos[] array */
321
-	/*
322
-	   nic->ioaddr = ( mca->pos[xxx] << 8 ) + mca->pos[yyy];
323
-	   nic->irqno = mca->pos[zzz] & 0x0f;
324
-	*/
325
-
326
-	/* Test for physical presence of NIC */
327
-	/*
328
-	   if ( ! my_tests ) {
329
-	  	DBG ( "Could not find NIC: my explanation\n" );
330
-		return 0;
331
-	   }
332
-	*/
333
-
334
-	/* point to NIC specific routines */
335
-	nic->nic_op = &skel_operations;
336
-	return 1;
337
-}
338
-
339
-static void skel_mca_disable ( struct nic *nic __unused,
340
-			       struct mca_device *mca __unused ) {
341
-	/* Reset the card to its initial state, disable DMA and
342
-	 * interrupts
343
-	 */
344
-}
345
-
346
-static struct mca_id skel_mca_nics[] = {
347
-	{ "Skeleton MCA Adapter", 0x0000 },
348
-};
349
-
350
-MCA_DRIVER ( skel_mca_driver, skel_mca_nics );
351
-
352
-DRIVER ( "SKEL/MCA", nic_driver, mca_driver, skel_mca_driver,
353
-	 skel_mca_probe, skel_mca_disable );
354
-
355
-ISA_ROM ( "skel-mca", "Skeleton MCA Adapter" );
356
-
357
-/**************************************************************************
358
- * ISA PROBE and DISABLE
359
- *
360
- * The "classical" ISA probe is split into two stages: trying a list
361
- * of I/O addresses to see if there's anything listening, and then
362
- * using that I/O address to fill in the information in the nic
363
- * structure.
364
- *
365
- * The list of probe addresses defined in skel_isa_probe_addrs[] will
366
- * be passed to skel_isa_probe_addr().  If skel_isa_probe_addr()
367
- * returns true, a struct isa_device will be created with isa->ioaddr
368
- * set to the working I/O address, and skel_isa_probe() will be
369
- * called.
370
- *
371
- * There is a standard mechanism for overriding the probe address list
372
- * using ISA_PROBE_ADDRS.  Do not implement any custom code to
373
- * override the probe address list.
374
- *
375
- **************************************************************************
376
- */
377
-static int skel_isa_probe_addr ( isa_probe_addr_t ioaddr __unused ) {
378
-	return 0;
379
-}
380
-
381
-static int skel_isa_probe ( struct nic *nic, struct isa_device *isa ) {
382
-
383
-	isa_fill_nic ( nic, isa );
384
-	nic->irqno = 0; /* No standard way to get IRQ for ISA */
385
-
386
-	/* Test for physical presence of NIC */
387
-	/*
388
-	   if ( ! my_tests ) {
389
-	  	DBG ( "Could not find NIC: my explanation\n" );
390
-		return 0;
391
-	   }
392
-	*/
393
-
394
-	/* point to NIC specific routines */
395
-	nic->nic_op = &skel_operations;
396
-	return 1;
397
-}
398
-
399
-static void skel_isa_disable ( struct nic *nic __unused,
400
-			      struct isa_device *isa __unused ) {
401
-	/* Reset the card to its initial state, disable DMA and
402
-	 * interrupts
403
-	 */
404
-}
405
-
406
-static isa_probe_addr_t skel_isa_probe_addrs[] = {
407
-	/*
408
-	   0x200, 0x240,
409
-	*/
410
-};
411
-
412
-ISA_DRIVER ( skel_isa_driver, skel_isa_probe_addrs, skel_isa_probe_addr,
413
-		     ISA_VENDOR('S','K','L'), 0x0000 );
414
-
415
-DRIVER ( "SKEL/ISA", nic_driver, isa_driver, skel_isa_driver,
416
-	 skel_isa_probe, skel_isa_disable );
417
-
418
-ISA_ROM ( "skel-isa", "Skeleton ISA Adapter" );
419
-

+ 1
- 1
src/drivers/net/smc9000.c View File

@@ -38,7 +38,7 @@
38 38
 #include <gpxe/ethernet.h>
39 39
 #include "etherboot.h"
40 40
 #include "nic.h"
41
-#include "isa.h"
41
+#include <gpxe/isa.h>
42 42
 #include "timer.h"
43 43
 #include "smc9000.h"
44 44
 

+ 0
- 7
src/drivers/net/tg3.c View File

@@ -28,13 +28,6 @@
28 28
 
29 29
 static struct tg3 tg3;
30 30
 
31
-/* Dummy defines for error handling */
32
-#define EBUSY  1
33
-#define ENODEV 2
34
-#define EINVAL 3
35
-#define ENOMEM 4
36
-
37
-
38 31
 /* These numbers seem to be hard coded in the NIC firmware somehow.
39 32
  * You can't change the ring sizes, but you can change where you place
40 33
  * them in the NIC onboard memory.

+ 2
- 2
src/drivers/net/via-velocity.h View File

@@ -1768,11 +1768,11 @@ struct velocity_opt {
1768 1768
 
1769 1769
 #define RX_DESC_MIN     4
1770 1770
 #define RX_DESC_MAX     255
1771
-#define RX_DESC_DEF     64
1771
+#define RX_DESC_DEF     RX_DESC_MIN
1772 1772
 
1773 1773
 #define TX_DESC_MIN     1
1774 1774
 #define TX_DESC_MAX     256
1775
-#define TX_DESC_DEF     4
1775
+#define TX_DESC_DEF     TX_DESC_MIN
1776 1776
 
1777 1777
 struct velocity_info {
1778 1778
 //      struct list_head list;

+ 0
- 95
src/include/eisa.h View File

@@ -1,95 +0,0 @@
1
-#ifndef EISA_H
2
-#define EISA_H
3
-
4
-#include "stdint.h"
5
-#include "isa_ids.h"
6
-#include "nic.h"
7
-
8
-/*
9
- * EISA constants
10
- *
11
- */
12
-
13
-#define EISA_MIN_SLOT (0x1)
14
-#define EISA_MAX_SLOT (0xf)	/* Must be 2^n - 1 */
15
-#define EISA_SLOT_BASE( n ) ( 0x1000 * (n) )
16
-
17
-#define EISA_MFG_ID_HI ( 0xc80 )
18
-#define EISA_MFG_ID_LO ( 0xc81 )
19
-#define EISA_PROD_ID_HI ( 0xc82 )
20
-#define EISA_PROD_ID_LO ( 0xc83 )
21
-#define EISA_GLOBAL_CONFIG ( 0xc84 )
22
-
23
-#define EISA_CMD_RESET ( 1 << 2 )
24
-#define EISA_CMD_ENABLE ( 1 << 0 )
25
-
26
-/*
27
- * A location on an EISA bus
28
- *
29
- */
30
-struct eisa_loc {
31
-	unsigned int slot;
32
-};
33
-
34
-/*
35
- * A physical EISA device
36
- *
37
- */
38
-struct eisa_device {
39
-	const char *name;
40
-	unsigned int slot;
41
-	uint16_t ioaddr;
42
-	uint16_t mfg_id;
43
-	uint16_t prod_id;
44
-};
45
-
46
-/*
47
- * An individual EISA device identified by ID
48
- *
49
- */
50
-struct eisa_id {
51
-        const char *name;
52
-	uint16_t mfg_id, prod_id;
53
-};
54
-
55
-/*
56
- * An EISA driver, with a device ID (struct eisa_id) table.
57
- *
58
- */
59
-struct eisa_driver {
60
-	const char *name;
61
-	struct eisa_id *ids;
62
-	unsigned int id_count;
63
-};
64
-
65
-/*
66
- * Define an EISA driver
67
- *
68
- */
69
-#define EISA_DRIVER( _name, _ids ) 					\
70
-	static struct eisa_driver _name = {				\
71
-		.ids = _ids,						\
72
-		.id_count = sizeof ( _ids ) / sizeof ( _ids[0] ),	\
73
-	}
74
-
75
-/*
76
- * Functions in eisa.c
77
- *
78
- */
79
-extern void eisa_device_enabled ( struct eisa_device *eisa, int enabled );
80
-extern void eisa_fill_nic ( struct nic *nic, struct eisa_device *eisa );
81
-
82
-static inline void enable_eisa_device ( struct eisa_device *eisa ) {
83
-	eisa_device_enabled ( eisa, 1 );
84
-}
85
-static inline void disable_eisa_device ( struct eisa_device *eisa ) {
86
-	eisa_device_enabled ( eisa, 0 );
87
-}
88
-
89
-/*
90
- * EISA bus global definition
91
- *
92
- */
93
-extern struct bus_driver eisa_driver;
94
-
95
-#endif /* EISA_H */

+ 16
- 29
src/include/gpxe/device.h View File

@@ -11,18 +11,18 @@
11 11
 #include <gpxe/list.h>
12 12
 #include <gpxe/tables.h>
13 13
 
14
-/** A PCI device description */
15
-struct pci_device_description {
14
+/** A hardware device description */
15
+struct device_description {
16 16
 	/** Bus type
17 17
 	 *
18
-	 * Must be @c BUS_TYPE_PCI.
18
+	 * This must be a BUS_TYPE_XXX constant.
19 19
 	 */
20 20
 	unsigned int bus_type;
21
-	/** Bus:dev.fn address
21
+	/** Location
22 22
 	 *
23
-	 * As constructed by PCI_BUSDEVFN().
23
+	 * The interpretation of this field is bus-type-specific.
24 24
 	 */
25
-	unsigned int busdevfn;
25
+	unsigned int location;
26 26
 	/** Vendor ID */
27 27
 	unsigned int vendor;
28 28
 	/** Device ID */
@@ -32,37 +32,24 @@ struct pci_device_description {
32 32
 /** PCI bus type */
33 33
 #define BUS_TYPE_PCI 1
34 34
 
35
-/** An ISAPnP device description */
36
-struct isapnp_device_description {
37
-	/** Bus type
38
-	 *
39
-	 * Must be @c BUS_TYPE_ISAPNP.
40
-	 */
41
-	unsigned int bus_type;
42
-};
43
-
44
-/** PCI bus type */
35
+/** ISAPnP bus type */
45 36
 #define BUS_TYPE_ISAPNP 2
46 37
 
47
-/** A hardware device description */
48
-union device_description {
49
-	/** Bus type
50
-	 *
51
-	 * This must be a BUS_TYPE_XXX constant.
52
-	 */
53
-	unsigned int bus_type;
54
-	/** PCI device description */
55
-	struct pci_device_description pci;
56
-	/** ISAPnP device description */
57
-	struct isapnp_device_description isapnp;
58
-};
38
+/** EISA bus type */
39
+#define BUS_TYPE_EISA 3
40
+
41
+/** MCA bus type */
42
+#define BUS_TYPE_MCA 4
43
+
44
+/** ISA bus type */
45
+#define BUS_TYPE_ISA 5
59 46
 
60 47
 /** A hardware device */
61 48
 struct device {
62 49
 	/** Name */
63 50
 	char name[16];
64 51
 	/** Device description */
65
-	union device_description desc;
52
+	struct device_description desc;
66 53
 	/** Devices on the same bus */
67 54
 	struct list_head siblings;
68 55
 	/** Devices attached to this device */

+ 125
- 0
src/include/gpxe/eisa.h View File

@@ -0,0 +1,125 @@
1
+#ifndef EISA_H
2
+#define EISA_H
3
+
4
+#include <stdint.h>
5
+#include <gpxe/isa_ids.h>
6
+#include <gpxe/device.h>
7
+#include <gpxe/tables.h>
8
+
9
+/*
10
+ * EISA constants
11
+ *
12
+ */
13
+
14
+#define EISA_MIN_SLOT (0x1)
15
+#define EISA_MAX_SLOT (0xf)	/* Must be 2^n - 1 */
16
+#define EISA_SLOT_BASE( n ) ( 0x1000 * (n) )
17
+
18
+#define EISA_VENDOR_ID ( 0xc80 )
19
+#define EISA_PROD_ID ( 0xc82 )
20
+#define EISA_GLOBAL_CONFIG ( 0xc84 )
21
+
22
+#define EISA_CMD_RESET ( 1 << 2 )
23
+#define EISA_CMD_ENABLE ( 1 << 0 )
24
+
25
+/** An EISA device ID list entry */
26
+struct eisa_device_id {
27
+	/** Name */
28
+        const char *name;
29
+	/** Manufacturer ID */
30
+	uint16_t vendor_id;
31
+	/** Product ID */
32
+	uint16_t prod_id;
33
+};
34
+
35
+/** An EISA device */
36
+struct eisa_device {
37
+	/** Generic device */
38
+	struct device dev;
39
+	/** Slot number */
40
+	unsigned int slot;
41
+	/** I/O address */
42
+	uint16_t ioaddr;
43
+	/** Manufacturer ID */
44
+	uint16_t vendor_id;
45
+	/** Product ID */
46
+	uint16_t prod_id;
47
+	/** Driver for this device */
48
+	struct eisa_driver *driver;
49
+	/** Driver-private data
50
+	 *
51
+	 * Use eisa_set_drvdata() and eisa_get_drvdata() to access
52
+	 * this field.
53
+	 */
54
+	void *priv;
55
+	/** Driver name */
56
+	const char *driver_name;
57
+};
58
+
59
+/** An EISA driver */
60
+struct eisa_driver {
61
+	/** EISA ID table */
62
+	struct eisa_device_id *ids;
63
+	/** Number of entries in EISA ID table */
64
+	unsigned int id_count;
65
+	/**
66
+	 * Probe device
67
+	 *
68
+	 * @v eisa	EISA device
69
+	 * @v id	Matching entry in ID table
70
+	 * @ret rc	Return status code
71
+	 */
72
+	int ( * probe ) ( struct eisa_device *eisa,
73
+			  const struct eisa_device_id *id );
74
+	/**
75
+	 * Remove device
76
+	 *
77
+	 * @v eisa	EISA device
78
+	 */
79
+	void ( * remove ) ( struct eisa_device *eisa );
80
+};
81
+
82
+/** Declare an EISA driver */
83
+#define __eisa_driver __table ( struct eisa_driver, eisa_drivers, 01 )
84
+
85
+extern void eisa_device_enabled ( struct eisa_device *eisa, int enabled );
86
+
87
+/**
88
+ * Enable EISA device
89
+ *
90
+ * @v eisa		EISA device
91
+ */
92
+static inline void enable_eisa_device ( struct eisa_device *eisa ) {
93
+	eisa_device_enabled ( eisa, 1 );
94
+}
95
+
96
+/**
97
+ * Disable EISA device
98
+ *
99
+ * @v eisa		EISA device
100
+ */
101
+static inline void disable_eisa_device ( struct eisa_device *eisa ) {
102
+	eisa_device_enabled ( eisa, 0 );
103
+}
104
+
105
+/**
106
+ * Set EISA driver-private data
107
+ *
108
+ * @v eisa		EISA device
109
+ * @v priv		Private data
110
+ */
111
+static inline void eisa_set_drvdata ( struct eisa_device *eisa, void *priv ) {
112
+	eisa->priv = priv;
113
+}
114
+
115
+/**
116
+ * Get EISA driver-private data
117
+ *
118
+ * @v eisa		EISA device
119
+ * @ret priv		Private data
120
+ */
121
+static inline void * eisa_get_drvdata ( struct eisa_device *eisa ) {
122
+	return eisa->priv;
123
+}
124
+
125
+#endif /* EISA_H */

+ 92
- 0
src/include/gpxe/isa.h View File

@@ -0,0 +1,92 @@
1
+#ifndef	ISA_H
2
+#define ISA_H
3
+
4
+#include <stdint.h>
5
+#include <gpxe/isa_ids.h>
6
+#include <gpxe/device.h>
7
+#include <gpxe/tables.h>
8
+
9
+/** An ISA device */
10
+struct isa_device {
11
+	/** Generic device */
12
+	struct device dev;
13
+	/** I/O address */
14
+	uint16_t ioaddr;
15
+	/** Driver for this device */
16
+	struct isa_driver *driver;
17
+	/** Driver-private data
18
+	 *
19
+	 * Use isa_set_drvdata() and isa_get_drvdata() to access
20
+	 * this field.
21
+	 */
22
+	void *priv;
23
+	/** Driver name */
24
+	const char *driver_name;
25
+};
26
+
27
+/*
28
+ * An individual ISA device, identified by probe address
29
+ *
30
+ */
31
+typedef uint16_t isa_probe_addr_t;
32
+
33
+/** An ISA driver */
34
+struct isa_driver {
35
+	/** Name */
36
+	const char *name;
37
+	/** Probe address list */
38
+	isa_probe_addr_t *probe_addrs;
39
+	/** Number of entries in probe address list */
40
+	unsigned int addr_count;
41
+	/** Manufacturer ID to be assumed for this device */
42
+	uint16_t vendor_id;
43
+	/** Product ID to be assumed for this device */
44
+	uint16_t prod_id;
45
+	/**
46
+	 * Probe device
47
+	 *
48
+	 * @v isa	ISA device
49
+	 * @v id	Matching entry in ID table
50
+	 * @ret rc	Return status code
51
+	 */
52
+	int ( * probe ) ( struct isa_device *isa );
53
+	/**
54
+	 * Remove device
55
+	 *
56
+	 * @v isa	ISA device
57
+	 */
58
+	void ( * remove ) ( struct isa_device *isa );
59
+};
60
+
61
+/** Declare an ISA driver */
62
+#define __isa_driver __table ( struct isa_driver, isa_drivers, 01 )
63
+
64
+/**
65
+ * Set ISA driver-private data
66
+ *
67
+ * @v isa		ISA device
68
+ * @v priv		Private data
69
+ */
70
+static inline void isa_set_drvdata ( struct isa_device *isa, void *priv ) {
71
+	isa->priv = priv;
72
+}
73
+
74
+/**
75
+ * Get ISA driver-private data
76
+ *
77
+ * @v isa		ISA device
78
+ * @ret priv		Private data
79
+ */
80
+static inline void * isa_get_drvdata ( struct isa_device *isa ) {
81
+	return isa->priv;
82
+}
83
+
84
+/*
85
+ * ISA_ROM is parsed by parserom.pl to generate Makefile rules and
86
+ * files for rom-o-matic.
87
+ *
88
+ */
89
+#define ISA_ROM( IMAGE, DESCRIPTION )
90
+
91
+#endif /* ISA_H */
92
+

src/include/isa_ids.h → src/include/gpxe/isa_ids.h View File

@@ -15,23 +15,25 @@
15 15
  *	   byte 1 bits 7-4  third hex digit of product number
16 16
  *		  bits 3-0  hex digit of revision level
17 17
  *
18
+ * ISA IDs are always expressed in little-endian order, even though
19
+ * the underlying "meaning" is big-endian.
18 20
  */
19 21
 
20
-#include "stdint.h"
21
-
22
-#define	ISA_BUS_TYPE	2
22
+#include <byteswap.h>
23 23
 
24 24
 /*
25 25
  * Construct a vendor ID from three ASCII characters
26 26
  *
27 27
  */
28
-#define ISA_VENDOR(a,b,c)	(((((a)-'A'+1)&0x3f)<<2)|\
29
-				((((b)-'A'+1)&0x18)>>3)|((((b)-'A'+1)&7)<<13)|\
30
-				((((c)-'A'+1)&0x1f)<<8))
31
-#define ISAPNP_VENDOR(a,b,c)	ISA_VENDOR(a,b,c)
32
-#define EISA_VENDOR(a,b,c)	ISA_VENDOR(a,b,c)
28
+#define ISA_VENDOR( a, b, c )					\
29
+	bswap_16 ( ( ( ( (a) - 'A' + 1 ) & 0x1f ) << 10 ) |	\
30
+		   ( ( ( (b) - 'A' + 1 ) & 0x1f ) << 5 ) |	\
31
+		   ( ( ( (c) - 'A' + 1 ) & 0x1f ) << 0 ) )
32
+
33
+#define ISAPNP_VENDOR( a, b, c )	ISA_VENDOR ( a, b, c )
34
+#define EISA_VENDOR( a, b, c )		ISA_VENDOR ( a, b, c )
33 35
 
34
-#define	GENERIC_ISAPNP_VENDOR	ISAPNP_VENDOR('P','N','P')
36
+#define	GENERIC_ISAPNP_VENDOR		ISAPNP_VENDOR ( 'P','N','P' )
35 37
 
36 38
 /*
37 39
  * Extract product ID and revision from combined product field
@@ -42,6 +44,6 @@
42 44
 #define ISA_PROD_REV(product)	( ( (product) & ~ISA_PROD_ID_MASK ) >> 8 )
43 45
 
44 46
 /* Functions in isa_ids.c */
45
-extern char * isa_id_string ( uint16_t vendor, uint16_t product );
47
+extern char * isa_id_string ( unsigned int vendor, unsigned int product );
46 48
 
47 49
 #endif /* ISA_IDS_H */

src/include/isapnp.h → src/include/gpxe/isapnp.h View File

@@ -36,9 +36,10 @@
36 36
 #ifndef ISAPNP_H
37 37
 #define ISAPNP_H
38 38
 
39
-#include "stdint.h"
40
-#include "nic.h"
41
-#include "isa_ids.h"
39
+#include <stdint.h>
40
+#include <gpxe/isa_ids.h>
41
+#include <gpxe/device.h>
42
+#include <gpxe/tables.h>
42 43
 
43 44
 /*
44 45
  * ISAPnP constants
@@ -134,103 +135,134 @@
134 135
 #define ISAPNP_TAG_RSVDLONGF		0xFF
135 136
 #define ISAPNP_TAG_PSEUDO_NEWBOARD	0x100
136 137
 
137
-/*
138
- * An ISAPnP serial identifier
139
- *
140
- */
138
+/** An ISAPnP serial identifier */
141 139
 struct isapnp_identifier {
140
+	/** Vendor ID */
142 141
 	uint16_t vendor_id;
142
+	/** Product ID */
143 143
 	uint16_t prod_id;
144
+	/** Serial number */
144 145
 	uint32_t serial;
146
+	/** Checksum */
145 147
 	uint8_t checksum;
146 148
 } __attribute__ (( packed ));
147 149
 
148
-/*
149
- * An ISAPnP logical device ID structure
150
- *
151
- */
150
+/** An ISAPnP logical device ID structure */
152 151
 struct isapnp_logdevid {
152
+	/** Vendor ID */
153 153
 	uint16_t vendor_id;
154
+	/** Product ID */
154 155
 	uint16_t prod_id;
156
+	/** Flags */
155 157
 	uint16_t flags;
156 158
 } __attribute__ (( packed ));
157 159
 
158
-/*
159
- * A location on an ISAPnP bus
160
- *
161
- */
162
-struct isapnp_loc {
163
-	uint8_t csn;
164
-	uint8_t logdev;
160
+/** An ISAPnP device ID list entry */
161
+struct isapnp_device_id {
162
+	/** Name */
163
+        const char *name;
164
+	/** Vendor ID */
165
+	uint16_t vendor_id;
166
+	/** Product ID */
167
+	uint16_t prod_id;
165 168
 };
166 169
 
167
-/*
168
- * A physical ISAPnP device
169
- *
170
- */
170
+/** An ISAPnP device */
171 171
 struct isapnp_device {
172
-	const char *name;
173
-	uint8_t csn;
174
-	uint8_t logdev;
172
+	/** Generic device */
173
+	struct device dev;
174
+	/** Vendor ID */
175 175
 	uint16_t vendor_id;
176
+	/** Product ID */
176 177
 	uint16_t prod_id;
178
+	/** I/O address */
177 179
 	uint16_t ioaddr;
180
+	/** Interrupt number */
178 181
 	uint8_t irqno;
182
+	/** Card Select Number */
183
+	uint8_t csn;
184
+	/** Logical Device ID */
185
+	uint8_t logdev;
186
+	/** Driver for this device */
187
+	struct isapnp_driver *driver;
188
+	/** Driver-private data
189
+	 *
190
+	 * Use isapnp_set_drvdata() and isapnp_get_drvdata() to access
191
+	 * this field.
192
+	 */
193
+	void *priv;
194
+	/** Driver name */
195
+	const char *driver_name;
179 196
 };
180 197
 
181
-/*
182
- * An individual ISAPnP device identified by ID
183
- *
184
- */
185
-struct isapnp_id {
186
-        const char *name;
187
-	uint16_t vendor_id, prod_id;
188
-};
189
-
190
-/*
191
- * An ISAPnP driver, with a device ID (struct isapnp_id) table.
192
- *
193
- */
198
+/** An ISAPnP driver */
194 199
 struct isapnp_driver {
195
-	struct isapnp_id *ids;
200
+	/** ISAPnP ID table */
201
+	struct isapnp_device_id *ids;
202
+	/** Number of entries in ISAPnP ID table */
196 203
 	unsigned int id_count;
204
+	/**
205
+	 * Probe device
206
+	 *
207
+	 * @v isapnp	ISAPnP device
208
+	 * @v id	Matching entry in ID table
209
+	 * @ret rc	Return status code
210
+	 */
211
+	int ( * probe ) ( struct isapnp_device *isapnp,
212
+			  const struct isapnp_device_id *id );
213
+	/**
214
+	 * Remove device
215
+	 *
216
+	 * @v isapnp	ISAPnP device
217
+	 */
218
+	void ( * remove ) ( struct isapnp_device *isapnp );
197 219
 };
198 220
 
199
-/*
200
- * Define an ISAPnP driver
201
- *
202
- */
203
-#define ISAPNP_DRIVER( _name, _ids ) 					\
204
-	static struct isapnp_driver _name = {				\
205
-		.ids = _ids,						\
206
-		.id_count = sizeof ( _ids ) / sizeof ( _ids[0] ),	\
207
-	}
221
+/** Declare an ISAPnP driver */
222
+#define __isapnp_driver __table ( struct isapnp_driver, isapnp_drivers, 01 )
223
+
224
+extern uint16_t isapnp_read_port;
208 225
 
209
-/*
210
- * Functions in isapnp.c
211
- *
212
- */
213 226
 extern void isapnp_device_activation ( struct isapnp_device *isapnp,
214 227
 				       int activation );
215
-extern void isapnp_fill_nic ( struct nic *nic, struct isapnp_device *isapnp );
216 228
 
229
+/**
230
+ * Activate ISAPnP device
231
+ *
232
+ * @v isapnp		ISAPnP device
233
+ */
217 234
 static inline void activate_isapnp_device ( struct isapnp_device *isapnp ) {
218 235
 	isapnp_device_activation ( isapnp, 1 );
219 236
 }
237
+
238
+/**
239
+ * Deactivate ISAPnP device
240
+ *
241
+ * @v isapnp		ISAPnP device
242
+ */
220 243
 static inline void deactivate_isapnp_device ( struct isapnp_device *isapnp ) {
221 244
 	isapnp_device_activation ( isapnp, 0 );
222 245
 }
223 246
 
224
-/*
225
- * ISAPnP bus global definition
247
+/**
248
+ * Set ISAPnP driver-private data
226 249
  *
250
+ * @v isapnp		ISAPnP device
251
+ * @v priv		Private data
227 252
  */
228
-extern struct bus_driver isapnp_driver;
253
+static inline void isapnp_set_drvdata ( struct isapnp_device *isapnp,
254
+					void *priv ) {
255
+	isapnp->priv = priv;
256
+}
229 257
 
230
-/*
231
- * ISAPnP read port.  ROM prefix may be able to set this address.
258
+/**
259
+ * Get ISAPnP driver-private data
232 260
  *
261
+ * @v isapnp		ISAPnP device
262
+ * @ret priv		Private data
233 263
  */
234
-extern uint16_t isapnp_read_port;
264
+static inline void * isapnp_get_drvdata ( struct isapnp_device *isapnp ) {
265
+	return isapnp->priv;
266
+}
235 267
 
236 268
 #endif /* ISAPNP_H */

+ 103
- 0
src/include/gpxe/mca.h View File

@@ -0,0 +1,103 @@
1
+/*
2
+ * MCA bus driver code
3
+ *
4
+ * Abstracted from 3c509.c.
5
+ *
6
+ */
7
+
8
+#ifndef MCA_H
9
+#define MCA_H
10
+
11
+#include <gpxe/isa_ids.h>
12
+#include <gpxe/device.h>
13
+#include <gpxe/tables.h>
14
+
15
+/*
16
+ * MCA constants
17
+ *
18
+ */
19
+#define MCA_MOTHERBOARD_SETUP_REG	0x94
20
+#define MCA_ADAPTER_SETUP_REG		0x96
21
+#define MCA_MAX_SLOT_NR			0x07	/* Must be 2^n - 1 */
22
+#define MCA_POS_REG(n)			(0x100+(n))
23
+
24
+/* Is there a standard that would define this? */
25
+#define GENERIC_MCA_VENDOR ISA_VENDOR ( 'M', 'C', 'A' )
26
+
27
+/** An MCA device ID list entry */
28
+struct mca_device_id {
29
+	/** Name */
30
+        const char *name;
31
+	/** Device ID */
32
+	uint16_t id;
33
+};
34
+
35
+/** An MCA device */
36
+struct mca_device {
37
+	/** Generic device */
38
+	struct device dev;
39
+	/** Slot number */
40
+	unsigned int slot;
41
+	/** POS register values */
42
+	unsigned char pos[8];
43
+	/** Driver for this device */
44
+	struct mca_driver *driver;
45
+	/** Driver-private data
46
+	 *
47
+	 * Use mca_set_drvdata() and mca_get_drvdata() to access
48
+	 * this field.
49
+	 */
50
+	void *priv;
51
+	/** Driver name */
52
+	const char *driver_name;
53
+};
54
+
55
+#define MCA_ID(mca) ( ( (mca)->pos[1] << 8 ) + (mca)->pos[0] )
56
+
57
+/** An MCA driver */
58
+struct mca_driver {
59
+	/** MCA ID table */
60
+	struct mca_device_id *ids;
61
+	/** Number of entries in MCA ID table */
62
+	unsigned int id_count;
63
+	/**
64
+	 * Probe device
65
+	 *
66
+	 * @v mca	MCA device
67
+	 * @v id	Matching entry in ID table
68
+	 * @ret rc	Return status code
69
+	 */
70
+	int ( * probe ) ( struct mca_device *mca,
71
+			  const struct mca_device_id *id );
72
+	/**
73
+	 * Remove device
74
+	 *
75
+	 * @v mca	MCA device
76
+	 */
77
+	void ( * remove ) ( struct mca_device *mca );
78
+};
79
+
80
+/** Declare an MCA driver */
81
+#define __mca_driver __table ( struct mca_driver, mca_drivers, 01 )
82
+
83
+/**
84
+ * Set MCA driver-private data
85
+ *
86
+ * @v mca		MCA device
87
+ * @v priv		Private data
88
+ */
89
+static inline void mca_set_drvdata ( struct mca_device *mca, void *priv ) {
90
+	mca->priv = priv;
91
+}
92
+
93
+/**
94
+ * Get MCA driver-private data
95
+ *
96
+ * @v mca		MCA device
97
+ * @ret priv		Private data
98
+ */
99
+static inline void * mca_get_drvdata ( struct mca_device *mca ) {
100
+	return mca->priv;
101
+}
102
+
103
+#endif

+ 0
- 85
src/include/isa.h View File

@@ -1,85 +0,0 @@
1
-#ifndef	ISA_H
2
-#define ISA_H
3
-
4
-#include "stdint.h"
5
-#include "isa_ids.h"
6
-#include "nic.h"
7
-
8
-/*
9
- * A location on an ISA bus
10
- *
11
- */
12
-struct isa_driver;
13
-struct isa_loc {
14
-	unsigned int driver;
15
-	unsigned int probe_idx;
16
-};
17
-
18
-/*
19
- * A physical ISA device
20
- *
21
- */
22
-struct isa_device {
23
-	const char *name;
24
-	struct isa_driver *driver;
25
-	uint16_t ioaddr;
26
-	uint16_t mfg_id;
27
-	uint16_t prod_id;
28
-};
29
-
30
-/*
31
- * An individual ISA device, identified by probe address
32
- *
33
- */
34
-typedef uint16_t isa_probe_addr_t;
35
-
36
-/*
37
- * An ISA driver, with a probe address list and a probe_addr method.
38
- * probe_addr() should return 1 if a card is physically present,
39
- * leaving the other operations (read MAC address etc.) down to the
40
- * main probe() routine.
41
- *
42
- */
43
-struct isa_driver {
44
-	const char *name;
45
-	isa_probe_addr_t *probe_addrs;
46
-	unsigned int addr_count;
47
-	int ( * probe_addr ) ( isa_probe_addr_t addr );
48
-	uint16_t mfg_id;
49
-	uint16_t prod_id;
50
-};
51
-
52
-/*
53
- * Define an ISA driver
54
- *
55
- */
56
-#define ISA_DRIVER( _name, _probe_addrs, _probe_addr, _mfg_id, _prod_id )   \
57
-struct isa_driver _name __table ( struct isa_driver, isa_driver, 01 ) = {   \
58
-	.probe_addrs = _probe_addrs,					    \
59
-	.addr_count = sizeof ( _probe_addrs ) / sizeof ( _probe_addrs[0] ), \
60
-	.probe_addr = _probe_addr,					    \
61
-	.mfg_id = _mfg_id,						    \
62
-	.prod_id = _prod_id,						    \
63
-}
64
-
65
-/*
66
- * ISA_ROM is parsed by parserom.pl to generate Makefile rules and
67
- * files for rom-o-matic.
68
- *
69
- */
70
-#define ISA_ROM( IMAGE, DESCRIPTION )
71
-
72
-/*
73
- * Functions in isa.c
74
- *
75
- */
76
-extern void isa_fill_nic ( struct nic *nic, struct isa_device *isa );
77
-
78
-/*
79
- * ISA bus global definition
80
- *
81
- */
82
-extern struct bus_driver isa_driver;
83
-
84
-#endif /* ISA_H */
85
-

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

@@ -1,88 +0,0 @@
1
-/*
2
- * MCA bus driver code
3
- *
4
- * Abstracted from 3c509.c.
5
- *
6
- */
7
-
8
-#ifndef MCA_H
9
-#define MCA_H
10
-
11
-#include "isa_ids.h"
12
-#include "nic.h"
13
-
14
-#define MCA_BUS_TYPE	3
15
-
16
-/*
17
- * MCA constants
18
- *
19
- */
20
-
21
-#define MCA_MOTHERBOARD_SETUP_REG	0x94
22
-#define MCA_ADAPTER_SETUP_REG		0x96
23
-#define MCA_MAX_SLOT_NR			0x07	/* Must be 2^n - 1 */
24
-#define MCA_POS_REG(n)			(0x100+(n))
25
-
26
-/* Is there a standard that would define this? */
27
-#define GENERIC_MCA_VENDOR ISA_VENDOR ( 'M', 'C', 'A' )
28
-
29
-/*
30
- * A location on an MCA bus
31
- *
32
- */
33
-struct mca_loc {
34
-	unsigned int slot;
35
-};
36
-
37
-/*
38
- * A physical MCA device
39
- *
40
- */
41
-struct mca_device {
42
-	const char *name;
43
-	unsigned int slot;
44
-	unsigned char pos[8];
45
-};
46
-#define MCA_ID(mca) ( ( (mca)->pos[1] << 8 ) + (mca)->pos[0] )
47
-
48
-/*
49
- * An individual MCA device identified by ID
50
- *
51
- */
52
-struct mca_id {
53
-        const char *name;
54
-        int id;
55
-};
56
-
57
-/*
58
- * An MCA driver, with a device ID (struct mca_id) table.
59
- *
60
- */
61
-struct mca_driver {
62
-	struct mca_id *ids;
63
-	unsigned int id_count;
64
-};
65
-
66
-/*
67
- * Define an MCA driver
68
- *
69
- */
70
-#define MCA_DRIVER( _name, _ids )					\
71
-	static struct mca_driver _name = {				\
72
-		.ids = _ids,						\
73
-		.id_count = sizeof ( _ids ) / sizeof ( _ids[0] ),	\
74
-	}
75
-
76
-/*
77
- * Functions in mca.c
78
- *
79
- */
80
-extern void mca_fill_nic ( struct nic *nic, struct mca_device *mca );
81
-
82
-/*
83
- * MCA bus global definition
84
- *
85
- */
86
-extern struct bus_driver mca_driver;
87
-
88
-#endif

+ 231
- 26
src/include/nic.h View File

@@ -8,8 +8,16 @@
8 8
 #ifndef	NIC_H
9 9
 #define NIC_H
10 10
 
11
+#include <stdint.h>
12
+#include <string.h>
13
+#include <stdio.h>
14
+#include <errno.h>
11 15
 #include <byteswap.h>
12 16
 #include <gpxe/pci.h>
17
+#include <gpxe/isapnp.h>
18
+#include <gpxe/isa.h>
19
+#include <gpxe/eisa.h>
20
+#include <gpxe/mca.h>
13 21
 #include "dhcp.h"
14 22
 
15 23
 typedef enum {
@@ -66,34 +74,231 @@ static inline void eth_transmit ( const char *dest, unsigned int type,
66 74
  */
67 75
 extern int dummy_connect ( struct nic *nic );
68 76
 extern void dummy_irq ( struct nic *nic, irq_action_t irq_action );
69
-extern int legacy_probe ( struct pci_device *pci,
70
-			  const struct pci_device_id *id,
71
-			  int ( * probe ) ( struct nic *nic,
72
-					    struct pci_device *pci ),
73
-			  void ( * disable ) ( struct nic *nic ) );
74
-extern void legacy_remove ( struct pci_device *pci,
75
-			    void ( * disable ) ( struct nic *nic ) );
76
-extern void pci_fill_nic ( struct nic *nic, struct pci_device *pci );
77
-
78
-#define PCI_DRIVER(_name,_ids,_class) 					\
79
-	static int _name ## _legacy_probe ( struct pci_device *pci,	\
80
-					    const struct pci_device_id *id ); \
81
-	static void _name ## _legacy_remove ( struct pci_device *pci );	\
82
-	struct pci_driver _name __pci_driver = {			\
83
-		.ids = _ids,						\
84
-		.id_count = sizeof ( _ids ) / sizeof ( _ids[0] ),	\
85
-		.probe = _name ## _legacy_probe,			\
86
-		.remove = _name ## _legacy_remove,			\
87
-	};
77
+extern int legacy_probe ( void *hwdev,
78
+			  void ( * set_drvdata ) ( void *hwdev, void *priv ),
79
+			  struct device *dev,
80
+			  int ( * probe ) ( struct nic *nic, void *hwdev ),
81
+			  void ( * disable ) ( struct nic *nic, void *hwdev ));
82
+void legacy_remove ( void *hwdev,
83
+		     void * ( * get_drvdata ) ( void *hwdev ),
84
+		     void ( * disable ) ( struct nic *nic, void *hwdev ) );
85
+
86
+#define PCI_DRIVER(_name,_ids,_class) 					  \
87
+	static inline int						  \
88
+	_name ## _pci_legacy_probe ( struct pci_device *pci,		  \
89
+				     const struct pci_device_id *id );	  \
90
+	static inline void						  \
91
+	_name ## _pci_legacy_remove ( struct pci_device *pci );		  \
92
+	struct pci_driver _name __pci_driver = {			  \
93
+		.ids = _ids,						  \
94
+		.id_count = sizeof ( _ids ) / sizeof ( _ids[0] ),	  \
95
+		.probe = _name ## _pci_legacy_probe,			  \
96
+		.remove = _name ## _pci_legacy_remove,			  \
97
+	};								  \
98
+	REQUIRE_OBJECT ( pci );
99
+
100
+static inline void legacy_pci_set_drvdata ( void *hwdev, void *priv ) {
101
+	pci_set_drvdata ( hwdev, priv );
102
+}
103
+static inline void * legacy_pci_get_drvdata ( void *hwdev ) {
104
+	return pci_get_drvdata ( hwdev );
105
+}
106
+
107
+#define ISAPNP_DRIVER(_name,_ids)					  \
108
+	static inline int						  \
109
+	_name ## _isapnp_legacy_probe ( struct isapnp_device *isapnp,	  \
110
+					const struct isapnp_device_id *id ); \
111
+	static inline void						  \
112
+	_name ## _isapnp_legacy_remove ( struct isapnp_device *isapnp );  \
113
+	struct isapnp_driver _name __isapnp_driver = {			  \
114
+		.ids = _ids,						  \
115
+		.id_count = sizeof ( _ids ) / sizeof ( _ids[0] ),	  \
116
+		.probe = _name ## _isapnp_legacy_probe,			  \
117
+		.remove = _name ## _isapnp_legacy_remove,		  \
118
+	};								  \
119
+	REQUIRE_OBJECT ( isapnp );
120
+
121
+static inline void legacy_isapnp_set_drvdata ( void *hwdev, void *priv ) {
122
+	isapnp_set_drvdata ( hwdev, priv );
123
+}
124
+static inline void * legacy_isapnp_get_drvdata ( void *hwdev ) {
125
+	return isapnp_get_drvdata ( hwdev );
126
+}
127
+
128
+#define EISA_DRIVER(_name,_ids)						  \
129
+	static inline int						  \
130
+	_name ## _eisa_legacy_probe ( struct eisa_device *eisa,		  \
131
+				      const struct eisa_device_id *id );  \
132
+	static inline void						  \
133
+	_name ## _eisa_legacy_remove ( struct eisa_device *eisa );	  \
134
+	struct eisa_driver _name __eisa_driver = {			  \
135
+		.ids = _ids,						  \
136
+		.id_count = sizeof ( _ids ) / sizeof ( _ids[0] ),	  \
137
+		.probe = _name ## _eisa_legacy_probe,			  \
138
+		.remove = _name ## _eisa_legacy_remove,			  \
139
+	};								  \
140
+	REQUIRE_OBJECT ( eisa );
141
+
142
+static inline void legacy_eisa_set_drvdata ( void *hwdev, void *priv ) {
143
+	eisa_set_drvdata ( hwdev, priv );
144
+}
145
+static inline void * legacy_eisa_get_drvdata ( void *hwdev ) {
146
+	return eisa_get_drvdata ( hwdev );
147
+}
148
+
149
+#define MCA_DRIVER(_name,_ids)						  \
150
+	static inline int						  \
151
+	_name ## _mca_legacy_probe ( struct mca_device *mca,		  \
152
+				     const struct mca_device_id *id );	  \
153
+	static inline void						  \
154
+	_name ## _mca_legacy_remove ( struct mca_device *mca );		  \
155
+	struct mca_driver _name __mca_driver = {			  \
156
+		.ids = _ids,						  \
157
+		.id_count = sizeof ( _ids ) / sizeof ( _ids[0] ),	  \
158
+		.probe = _name ## _mca_legacy_probe,			  \
159
+		.remove = _name ## _mca_legacy_remove,			  \
160
+	};								  \
161
+	REQUIRE_OBJECT ( mca );
162
+
163
+static inline void legacy_mca_set_drvdata ( void *hwdev, void *priv ) {
164
+	mca_set_drvdata ( hwdev, priv );
165
+}
166
+static inline void * legacy_mca_get_drvdata ( void *hwdev ) {
167
+	return mca_get_drvdata ( hwdev );
168
+}
169
+
170
+#define ISA_DRIVER(_name,_probe_addrs,_probe_addr,_vendor_id,_prod_id)	  \
171
+	static inline int						  \
172
+	_name ## _isa_legacy_probe ( struct isa_device *isa );		  \
173
+	static inline int						  \
174
+	_name ## _isa_legacy_probe_at_addr ( struct isa_device *isa ) {	  \
175
+		if ( ! _probe_addr ( isa->ioaddr ) )			  \
176
+			return -ENODEV; 				  \
177
+		return _name ## _isa_legacy_probe ( isa );		  \
178
+	}								  \
179
+	static inline void						  \
180
+	_name ## _isa_legacy_remove ( struct isa_device *isa );		  \
181
+	static const char _name ## _text[];				  \
182
+	struct isa_driver _name __isa_driver = {			  \
183
+		.name = _name ## _text,					  \
184
+		.probe_addrs = _probe_addrs,				  \
185
+		.addr_count = ( sizeof ( _probe_addrs ) /		  \
186
+				sizeof ( _probe_addrs[0] ) ),		  \
187
+		.vendor_id = _vendor_id,				  \
188
+		.prod_id = _prod_id,					  \
189
+		.probe = _name ## _isa_legacy_probe_at_addr,		  \
190
+		.remove = _name ## _isa_legacy_remove,			  \
191
+	};								  \
192
+	REQUIRE_OBJECT ( isa );
193
+
194
+static inline void legacy_isa_set_drvdata ( void *hwdev, void *priv ) {
195
+	isa_set_drvdata ( hwdev, priv );
196
+}
197
+static inline void * legacy_isa_get_drvdata ( void *hwdev ) {
198
+	return isa_get_drvdata ( hwdev );
199
+}
88 200
 
89 201
 #undef DRIVER
90
-#define DRIVER(_unused1,_unused2,_unused3,_name,_probe,_disable)	\
91
-	static int _name ## _legacy_probe ( struct pci_device *pci,	\
92
-					    const struct pci_device_id *id ) {\
93
-		return legacy_probe ( pci, id, _probe, _disable );	\
94
-	}								\
95
-	static void _name ## _legacy_remove ( struct pci_device *pci ) {\
96
-		return legacy_remove ( pci, _disable );			\
202
+#define DRIVER(_name_text,_unused2,_unused3,_name,_probe,_disable)	  \
203
+	static const char _name ## _text[] = _name_text;		  \
204
+	static inline int						  \
205
+	_name ## _probe ( struct nic *nic, void *hwdev ) {		  \
206
+		return _probe ( nic, hwdev );				  \
207
+	}								  \
208
+	static inline void						  \
209
+	_name ## _disable ( struct nic *nic, void *hwdev ) {		  \
210
+		void ( * _unsafe_disable ) () = _disable;		  \
211
+		_unsafe_disable ( nic, hwdev );				  \
212
+	}								  \
213
+	static inline int						  \
214
+	_name ## _pci_legacy_probe ( struct pci_device *pci,		  \
215
+			    const struct pci_device_id *id __unused ) {	  \
216
+		return legacy_probe ( pci, legacy_pci_set_drvdata,	  \
217
+				      &pci->dev, _name ## _probe,	  \
218
+				      _name ## _disable );		  \
219
+	}								  \
220
+	static inline void						  \
221
+	_name ## _pci_legacy_remove ( struct pci_device *pci ) {	  \
222
+		return legacy_remove ( pci, legacy_pci_get_drvdata,	  \
223
+				       _name ## _disable );		  \
224
+	}								  \
225
+	static inline int						  \
226
+	_name ## _isapnp_legacy_probe ( struct isapnp_device *isapnp,	  \
227
+			 const struct isapnp_device_id *id __unused ) {	  \
228
+		return legacy_probe ( isapnp, legacy_isapnp_set_drvdata,  \
229
+				      &isapnp->dev, _name ## _probe,	  \
230
+				      _name ## _disable );		  \
231
+	}								  \
232
+	static inline void						  \
233
+	_name ## _isapnp_legacy_remove ( struct isapnp_device *isapnp ) { \
234
+		return legacy_remove ( isapnp, legacy_isapnp_get_drvdata, \
235
+				       _name ## _disable );		  \
236
+	}								  \
237
+	static inline int						  \
238
+	_name ## _eisa_legacy_probe ( struct eisa_device *eisa,		  \
239
+			     const struct eisa_device_id *id __unused ) { \
240
+		return legacy_probe ( eisa, legacy_eisa_set_drvdata,	  \
241
+				      &eisa->dev, _name ## _probe,	  \
242
+				      _name ## _disable );		  \
243
+	}								  \
244
+	static inline void						  \
245
+	_name ## _eisa_legacy_remove ( struct eisa_device *eisa ) {	  \
246
+		return legacy_remove ( eisa, legacy_eisa_get_drvdata,	  \
247
+				       _name ## _disable );		  \
248
+	}								  \
249
+	static inline int						  \
250
+	_name ## _mca_legacy_probe ( struct mca_device *mca,		  \
251
+			      const struct mca_device_id *id __unused ) { \
252
+		return legacy_probe ( mca, legacy_mca_set_drvdata,	  \
253
+				      &mca->dev, _name ## _probe,	  \
254
+				      _name ## _disable );		  \
255
+	}								  \
256
+	static inline void						  \
257
+	_name ## _mca_legacy_remove ( struct mca_device *mca ) {	  \
258
+		return legacy_remove ( mca, legacy_mca_get_drvdata,	  \
259
+				       _name ## _disable );		  \
260
+	}								  \
261
+	static inline int						  \
262
+	_name ## _isa_legacy_probe ( struct isa_device *isa ) {		  \
263
+		return legacy_probe ( isa, legacy_isa_set_drvdata,	  \
264
+				      &isa->dev, _name ## _probe,	  \
265
+				      _name ## _disable );		  \
266
+	}								  \
267
+	static inline void						  \
268
+	_name ## _isa_legacy_remove ( struct isa_device *isa ) {	  \
269
+		return legacy_remove ( isa, legacy_isa_get_drvdata,	  \
270
+				       _name ## _disable );		  \
97 271
 	}
98 272
 
273
+static inline void pci_fill_nic ( struct nic *nic, struct pci_device *pci ) {
274
+	nic->ioaddr = pci->ioaddr;
275
+	nic->irqno = pci->irq;
276
+}
277
+
278
+static inline void isapnp_fill_nic ( struct nic *nic,
279
+				     struct isapnp_device *isapnp ) {
280
+	nic->ioaddr = isapnp->ioaddr;
281
+	nic->irqno = isapnp->irqno;
282
+}
283
+
284
+static inline void eisa_fill_nic ( struct nic *nic,
285
+				   struct eisa_device *eisa ) {
286
+	nic->ioaddr = eisa->ioaddr;
287
+	nic->irqno = 0;
288
+}
289
+
290
+static inline void mca_fill_nic ( struct nic *nic,
291
+				  struct mca_device *mca __unused ) {
292
+	/* ioaddr and irqno must be read in a device-dependent way
293
+	 * from the POS registers
294
+	 */
295
+	nic->ioaddr = 0;
296
+	nic->irqno = 0;
297
+}
298
+
299
+static inline void isa_fill_nic ( struct nic *nic, struct isa_device *isa ) {
300
+	nic->ioaddr = isa->ioaddr;
301
+	nic->irqno = 0;
302
+}
303
+
99 304
 #endif	/* NIC_H */

+ 1
- 1
src/net/netdevice.c View File

@@ -331,7 +331,7 @@ struct net_device * find_pci_netdev ( unsigned int busdevfn ) {
331 331
 
332 332
 	list_for_each_entry ( netdev, &net_devices, list ) {
333 333
 		if ( ( netdev->dev->desc.bus_type == BUS_TYPE_PCI ) &&
334
-		     ( netdev->dev->desc.pci.busdevfn == busdevfn ) )
334
+		     ( netdev->dev->desc.location == busdevfn ) )
335 335
 			return netdev;
336 336
 	}
337 337
 

Loading…
Cancel
Save