|
|
1.1 root 1: #include <stdint.h>
2: #include <string.h>
3: #include <stdlib.h>
4: #include <stdio.h>
5: #include <errno.h>
6: #include <ipxe/io.h>
7: #include <unistd.h>
8: #include <ipxe/eisa.h>
9:
10: FILE_LICENCE ( GPL2_OR_LATER );
11:
12: static void eisabus_remove ( struct root_device *rootdev );
13:
14: /**
15: * Reset and enable/disable an EISA device
16: *
17: * @v eisa EISA device
18: * @v enabled 1=enable, 0=disable
19: */
20: void eisa_device_enabled ( struct eisa_device *eisa, int enabled ) {
21: /* Set reset line high for 1000 �s. Spec says 500 �s, but
22: * this doesn't work for all cards, so we are conservative.
23: */
24: outb ( EISA_CMD_RESET, eisa->ioaddr + EISA_GLOBAL_CONFIG );
25: udelay ( 1000 ); /* Must wait 800 */
26:
27: /* Set reset low and write a 1 to ENABLE. Delay again, in
28: * case the card takes a while to wake up.
29: */
30: outb ( enabled ? EISA_CMD_ENABLE : 0,
31: eisa->ioaddr + EISA_GLOBAL_CONFIG );
32: udelay ( 1000 ); /* Must wait 800 */
33:
34: DBG ( "EISA %s device %02x\n", ( enabled ? "enabled" : "disabled" ),
35: eisa->slot );
36: }
37:
38: /**
39: * Probe an EISA device
40: *
41: * @v eisa EISA device
42: * @ret rc Return status code
43: *
44: * Searches for a driver for the EISA device. If a driver is found,
45: * its probe() routine is called.
46: */
47: static int eisa_probe ( struct eisa_device *eisa ) {
48: struct eisa_driver *driver;
49: struct eisa_device_id *id;
50: unsigned int i;
51: int rc;
52:
53: DBG ( "Adding EISA device %02x (%04x:%04x (\"%s\") io %x)\n",
54: eisa->slot, eisa->vendor_id, eisa->prod_id,
55: isa_id_string ( eisa->vendor_id, eisa->prod_id ), eisa->ioaddr );
56:
57: for_each_table_entry ( driver, EISA_DRIVERS ) {
58: for ( i = 0 ; i < driver->id_count ; i++ ) {
59: id = &driver->ids[i];
60: if ( id->vendor_id != eisa->vendor_id )
61: continue;
62: if ( ISA_PROD_ID ( id->prod_id ) !=
63: ISA_PROD_ID ( eisa->prod_id ) )
64: continue;
65: eisa->driver = driver;
66: eisa->dev.driver_name = id->name;
67: DBG ( "...using driver %s\n", eisa->dev.driver_name );
68: if ( ( rc = driver->probe ( eisa, id ) ) != 0 ) {
69: DBG ( "......probe failed\n" );
70: continue;
71: }
72: return 0;
73: }
74: }
75:
76: DBG ( "...no driver found\n" );
77: return -ENOTTY;
78: }
79:
80: /**
81: * Remove an EISA device
82: *
83: * @v eisa EISA device
84: */
85: static void eisa_remove ( struct eisa_device *eisa ) {
86: eisa->driver->remove ( eisa );
87: DBG ( "Removed EISA device %02x\n", eisa->slot );
88: }
89:
90: /**
91: * Probe EISA root bus
92: *
93: * @v rootdev EISA bus root device
94: *
95: * Scans the EISA bus for devices and registers all devices it can
96: * find.
97: */
98: static int eisabus_probe ( struct root_device *rootdev ) {
99: struct eisa_device *eisa = NULL;
100: unsigned int slot;
101: int rc;
102:
103: for ( slot = EISA_MIN_SLOT ; slot <= EISA_MAX_SLOT ; slot++ ) {
104: /* Allocate struct eisa_device */
105: if ( ! eisa )
106: eisa = malloc ( sizeof ( *eisa ) );
107: if ( ! eisa ) {
108: rc = -ENOMEM;
109: goto err;
110: }
111: memset ( eisa, 0, sizeof ( *eisa ) );
112: eisa->slot = slot;
113: eisa->ioaddr = EISA_SLOT_BASE ( eisa->slot );
114:
115: /* Test for board present */
116: outb ( 0xff, eisa->ioaddr + EISA_VENDOR_ID );
117: eisa->vendor_id =
118: le16_to_cpu ( inw ( eisa->ioaddr + EISA_VENDOR_ID ) );
119: eisa->prod_id =
120: le16_to_cpu ( inw ( eisa->ioaddr + EISA_PROD_ID ) );
121: if ( eisa->vendor_id & 0x80 ) {
122: /* No board present */
123: continue;
124: }
125:
126: /* Add to device hierarchy */
127: snprintf ( eisa->dev.name, sizeof ( eisa->dev.name ),
128: "EISA%02x", slot );
129: eisa->dev.desc.bus_type = BUS_TYPE_EISA;
130: eisa->dev.desc.vendor = eisa->vendor_id;
131: eisa->dev.desc.device = eisa->prod_id;
132: eisa->dev.parent = &rootdev->dev;
133: list_add ( &eisa->dev.siblings, &rootdev->dev.children );
134: INIT_LIST_HEAD ( &eisa->dev.children );
135:
136: /* Look for a driver */
137: if ( eisa_probe ( eisa ) == 0 ) {
138: /* eisadev registered, we can drop our ref */
139: eisa = NULL;
140: } else {
141: /* Not registered; re-use struct */
142: list_del ( &eisa->dev.siblings );
143: }
144: }
145:
146: free ( eisa );
147: return 0;
148:
149: err:
150: free ( eisa );
151: eisabus_remove ( rootdev );
152: return rc;
153: }
154:
155: /**
156: * Remove EISA root bus
157: *
158: * @v rootdev EISA bus root device
159: */
160: static void eisabus_remove ( struct root_device *rootdev ) {
161: struct eisa_device *eisa;
162: struct eisa_device *tmp;
163:
164: list_for_each_entry_safe ( eisa, tmp, &rootdev->dev.children,
165: dev.siblings ) {
166: eisa_remove ( eisa );
167: list_del ( &eisa->dev.siblings );
168: free ( eisa );
169: }
170: }
171:
172: /** EISA bus root device driver */
173: static struct root_driver eisa_root_driver = {
174: .probe = eisabus_probe,
175: .remove = eisabus_remove,
176: };
177:
178: /** EISA bus root device */
179: struct root_device eisa_root_device __root_device = {
180: .dev = { .name = "EISA" },
181: .driver = &eisa_root_driver,
182: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.