瀏覽代碼

Added a generalised ISA device-probing mechanism.

tags/v0.9.3
Michael Brown 19 年之前
父節點
當前提交
9eac705dd2
共有 2 個文件被更改,包括 188 次插入14 次删除
  1. 123
    0
      src/drivers/bus/isa.c
  2. 65
    14
      src/include/isa.h

+ 123
- 0
src/drivers/bus/isa.c 查看文件

@@ -0,0 +1,123 @@
1
+#include "etherboot.h"
2
+#include "isa.h"
3
+
4
+/*
5
+ * isa.c implements a "classical" port-scanning method of ISA device
6
+ * detection.  The driver must provide a list of probe addresses
7
+ * (probe_addrs), together with a function (probe_addr) that can be
8
+ * used to test for the physical presence of a device at any given
9
+ * address.
10
+ *
11
+ * Note that this should probably be considered the "last resort" for
12
+ * device probing.  If the card supports ISAPnP or EISA, use that
13
+ * instead.  Some cards (e.g. the 3c509) implement a proprietary
14
+ * ISAPnP-like mechanism.
15
+ *
16
+ * The ISA probe address list can be overridden by config.c; if 
17
+ */
18
+
19
+/*
20
+ * Ensure that there is sufficient space in the shared dev_bus
21
+ * structure for a struct isa_device.
22
+ *
23
+ */
24
+DEV_BUS( struct isa_device, isa_dev );
25
+static char isa_magic[0]; /* guaranteed unique symbol */
26
+
27
+/*
28
+ * Find an ISA device matching the specified driver
29
+ *
30
+ */
31
+int find_isa_device ( struct isa_device *isa, struct isa_driver *driver ) {
32
+	unsigned int i;
33
+	uint16_t ioaddr;
34
+
35
+	/* Initialise struct isa if it's the first time it's been used. */
36
+	if ( isa->magic != isa_magic ) {
37
+		memset ( isa, 0, sizeof ( *isa ) );
38
+		isa->magic = isa_magic;
39
+	}
40
+
41
+	/* Iterate through any ISA probe addresses specified by
42
+	 * config.c, starting where we left off.
43
+	 */
44
+	for ( i = isa->probe_idx ; i < isa_extra_probe_addr_count ; i++ ) {
45
+		/* If we've already used this device, skip it */
46
+		if ( isa->already_tried ) {
47
+			isa->already_tried = 0;
48
+			continue;
49
+		}
50
+
51
+		/* Set I/O address */
52
+		ioaddr = isa_extra_probe_addrs[i].addr;
53
+
54
+		/* An I/O address of 0 in extra_probe_addrs list means
55
+		 * stop probing (i.e. don't continue to the
56
+		 * driver-provided list)
57
+		 */
58
+		if ( ! ioaddr )
59
+			goto notfound;
60
+
61
+		/* Use probe_addr method to see if there's a device
62
+		 * present at this address.
63
+		 */
64
+		if ( driver->probe_addr ( ioaddr ) ) {
65
+			isa->probe_idx = i;
66
+			goto found;
67
+		}
68
+	}
69
+
70
+	/* Iterate through all ISA probe addresses provided by the
71
+	 * driver, starting where we left off.
72
+	 */
73
+	for ( i = isa->probe_idx - isa_extra_probe_addr_count ;
74
+	      i < driver->addr_count ; i++ ) {
75
+
76
+		/* If we've already used this device, skip it */
77
+		if ( isa->already_tried ) {
78
+			isa->already_tried = 0;
79
+			continue;
80
+		}
81
+
82
+		/* Set I/O address */
83
+		ioaddr = driver->probe_addrs[i].addr;
84
+
85
+		/* Use probe_addr method to see if there's a device
86
+		 * present at this address.
87
+		 */
88
+		if ( driver->probe_addr ( ioaddr ) ) {
89
+			isa->probe_idx = i + isa_extra_probe_addr_count;
90
+			goto found;
91
+		}
92
+	}
93
+
94
+ notfound:
95
+	/* No device found */
96
+	isa->probe_idx = 0;
97
+	return 0;
98
+
99
+ found:
100
+	DBG ( "Found %s ISA device at address %hx\n", driver->name, ioaddr );
101
+	isa->ioaddr = ioaddr;
102
+	isa->already_tried = 1;
103
+	return 1;
104
+}
105
+
106
+/*
107
+ * Find the next ISA device that can be used to boot using the
108
+ * specified driver.
109
+ *
110
+ */
111
+int find_isa_boot_device ( struct dev *dev, struct isa_driver *driver ) {
112
+	struct isa_device *isa = ( struct isa_device * )dev->bus;
113
+
114
+	if ( ! find_isa_device ( isa, driver ) )
115
+		return 0;
116
+
117
+	dev->name = driver->name;
118
+	dev->devid.bus_type = ISA_BUS_TYPE;
119
+	dev->devid.vendor_id = driver->mfg_id;
120
+	dev->devid.device_id = driver->prod_id;
121
+
122
+	return 1;
123
+}

+ 65
- 14
src/include/isa.h 查看文件

@@ -2,27 +2,78 @@
2 2
 #define ISA_H
3 3
 
4 4
 #include "isa_ids.h"
5
+#include "dev.h"
5 6
 
6
-struct dev;
7
+/*
8
+ * A physical ISA device
9
+ *
10
+ */
11
+struct isa_device {
12
+	char *magic; /* must be first */
13
+	unsigned int probe_idx;
14
+	uint16_t ioaddr;
15
+	int already_tried;
16
+};
17
+
18
+/*
19
+ * An individual ISA device, identified by probe address
20
+ *
21
+ */
22
+struct isa_probe_addr {
23
+	uint16_t addr;
24
+} __attribute__ (( packed ));
7 25
 
8
-struct isa_driver
9
-{
10
-	int type;
26
+/*
27
+ * An ISA driver, with a probe address list and a probe_addr method.
28
+ * probe_addr() should return 1 if a card is physically present,
29
+ * leaving the other operations (read MAC address etc.) down to the
30
+ * main probe() routine.
31
+ *
32
+ */
33
+struct isa_driver {
11 34
 	const char *name;
12
-	int (*probe)(struct dev *, unsigned short *);
13
-	unsigned short *ioaddrs;
35
+	struct isa_probe_addr *probe_addrs;
36
+	unsigned int addr_count;
37
+	int ( * probe_addr ) ( uint16_t addr );
38
+	uint16_t mfg_id;
39
+	uint16_t prod_id;
14 40
 };
15 41
 
16
-#ifndef __HYPERSTONE__
17
-#define __isa_driver	__attribute__ ((used,__section__(".drivers.isa")))
18
-#else 
19
-#define __isa_driver	__attribute__ ((used,__section__(".drivisa")))
20
-#endif
42
+/*
43
+ * Define an ISA driver
44
+ *
45
+ */
46
+#define ISA_DRIVER( _name, _probe_addrs, _probe_addr, _mfg_id, _prod_id ) { \
47
+	.name = _name,							    \
48
+	.probe_addrs = _probe_addrs,					    \
49
+	.addr_count = sizeof ( _probe_addrs ) / sizeof ( probe_addrs[0] ),  \
50
+	.probe_addr = _probe_addr,					    \
51
+	.mfg_id = _mfg_id,						    \
52
+	.prod_id = _prod_id,						    \
53
+}
54
+
55
+/*
56
+ * ISA_ROM is parsed by parserom.pl to generate Makefile rules and
57
+ * files for rom-o-matic.
58
+ *
59
+ */
60
+#define ISA_ROM( IMAGE, DESCRIPTION )
21 61
 
22
-extern const struct isa_driver isa_drivers[];
23
-extern const struct isa_driver isa_drivers_end[];
62
+/*
63
+ * Functions in isa.c
64
+ *
65
+ */
66
+extern int find_isa_device ( struct isa_device *eisa,
67
+			     struct isa_driver *driver );
68
+extern int find_isa_boot_device ( struct dev *dev,
69
+				  struct isa_driver *driver );
24 70
 
25
-#define ISA_ROM(IMAGE, DESCRIPTION)
71
+/*
72
+ * config.c defines isa_extra_probe_addrs and isa_extra_probe_addr_count.
73
+ *
74
+ */
75
+extern struct isa_probe_addr isa_extra_probe_addrs[];
76
+extern unsigned int isa_extra_probe_addr_count;
26 77
 
27 78
 #endif /* ISA_H */
28 79
 

Loading…
取消
儲存