iPXE
eisa.c
Go to the documentation of this file.
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
10FILE_LICENCE ( GPL2_OR_LATER );
11
12static 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 */
20void 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 */
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 */
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 */
47static 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
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 */
85static 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 */
98static int eisabus_probe ( struct root_device *rootdev ) {
99 struct eisa_device *eisa = NULL;
100 unsigned int slot;
102 int rc;
103
104 /* Check for EISA system board */
106 if ( system & 0x80 ) {
107 DBG ( "No EISA system board (read %02x)\n", system );
108 return -ENODEV;
109 }
110
111 for ( slot = EISA_MIN_SLOT ; slot <= EISA_MAX_SLOT ; slot++ ) {
112 /* Allocate struct eisa_device */
113 if ( ! eisa )
114 eisa = malloc ( sizeof ( *eisa ) );
115 if ( ! eisa ) {
116 rc = -ENOMEM;
117 goto err;
118 }
119 memset ( eisa, 0, sizeof ( *eisa ) );
120 eisa->slot = slot;
121 eisa->ioaddr = EISA_SLOT_BASE ( eisa->slot );
122
123 /* Test for board present */
124 outb ( 0xff, eisa->ioaddr + EISA_VENDOR_ID );
125 eisa->vendor_id =
126 le16_to_cpu ( inw ( eisa->ioaddr + EISA_VENDOR_ID ) );
127 eisa->prod_id =
128 le16_to_cpu ( inw ( eisa->ioaddr + EISA_PROD_ID ) );
129 if ( eisa->vendor_id & 0x80 ) {
130 /* No board present */
131 continue;
132 }
133
134 /* Add to device hierarchy */
135 snprintf ( eisa->dev.name, sizeof ( eisa->dev.name ),
136 "EISA%02x", slot );
138 eisa->dev.desc.vendor = eisa->vendor_id;
139 eisa->dev.desc.device = eisa->prod_id;
140 eisa->dev.parent = &rootdev->dev;
141 list_add ( &eisa->dev.siblings, &rootdev->dev.children );
142 INIT_LIST_HEAD ( &eisa->dev.children );
143
144 /* Look for a driver */
145 if ( eisa_probe ( eisa ) == 0 ) {
146 /* eisadev registered, we can drop our ref */
147 eisa = NULL;
148 } else {
149 /* Not registered; re-use struct */
150 list_del ( &eisa->dev.siblings );
151 }
152 }
153
154 free ( eisa );
155 return 0;
156
157 err:
158 free ( eisa );
159 eisabus_remove ( rootdev );
160 return rc;
161}
162
163/**
164 * Remove EISA root bus
165 *
166 * @v rootdev EISA bus root device
167 */
168static void eisabus_remove ( struct root_device *rootdev ) {
169 struct eisa_device *eisa;
170 struct eisa_device *tmp;
171
172 list_for_each_entry_safe ( eisa, tmp, &rootdev->dev.children,
173 dev.siblings ) {
174 eisa_remove ( eisa );
175 list_del ( &eisa->dev.siblings );
176 free ( eisa );
177 }
178}
179
180/** EISA bus root device driver */
182 .probe = eisabus_probe,
183 .remove = eisabus_remove,
184};
185
186/** EISA bus root device */
187struct root_device eisa_root_device __root_device = {
188 .dev = { .name = "EISA" },
189 .driver = &eisa_root_driver,
190};
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned char uint8_t
Definition stdint.h:10
#define BUS_TYPE_EISA
EISA bus type.
Definition device.h:50
#define __root_device
Declare a root device.
Definition device.h:136
uint8_t slot
Slot.
Definition edd.h:3
static int eisa_probe(struct eisa_device *eisa)
Probe an EISA device.
Definition eisa.c:47
static int eisabus_probe(struct root_device *rootdev)
Probe EISA root bus.
Definition eisa.c:98
static struct root_driver eisa_root_driver
EISA bus root device driver.
Definition eisa.c:181
void eisa_device_enabled(struct eisa_device *eisa, int enabled)
Reset and enable/disable an EISA device.
Definition eisa.c:20
static void eisabus_remove(struct root_device *rootdev)
Remove EISA root bus.
Definition eisa.c:168
static void eisa_remove(struct eisa_device *eisa)
Remove an EISA device.
Definition eisa.c:85
#define EISA_CMD_RESET
Definition eisa.h:24
#define EISA_PROD_ID
Definition eisa.h:21
#define EISA_CMD_ENABLE
Definition eisa.h:25
#define EISA_SLOT_BASE(n)
Definition eisa.h:18
#define EISA_MIN_SLOT
Definition eisa.h:16
#define EISA_GLOBAL_CONFIG
Definition eisa.h:22
#define EISA_VENDOR_ID
Definition eisa.h:20
#define EISA_DRIVERS
EISA driver table.
Definition eisa.h:83
#define EISA_MAX_SLOT
Definition eisa.h:17
uint8_t id
Request identifier.
Definition ena.h:1
uint16_t enabled
Single-entry bitmask of the enabled option value.
Definition ena.h:3
Error codes.
uint8_t system[ETH_ALEN]
System identifier.
Definition eth_slow.h:13
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define ENOMEM
Not enough space.
Definition errno.h:535
#define ENODEV
No such device.
Definition errno.h:510
#define ENOTTY
Inappropriate I/O control operation.
Definition errno.h:595
#define le16_to_cpu(value)
Definition byteswap.h:113
iPXE I/O API
#define inw(io_addr)
Definition io.h:292
#define outb(data, io_addr)
Definition io.h:310
#define inb(io_addr)
Definition io.h:283
String functions.
void * memset(void *dest, int character, size_t len) __nonnull
char * isa_id_string(unsigned int vendor, unsigned int product)
Definition isa_ids.c:11
#define ISA_PROD_ID(product)
Definition isa_ids.h:45
unsigned long tmp
Definition linux_pci.h:65
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition list.h:459
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
unsigned int bus_type
Bus type.
Definition device.h:25
unsigned int device
Device ID.
Definition device.h:34
unsigned int vendor
Vendor ID.
Definition device.h:32
struct device_description desc
Device description.
Definition device.h:83
struct device * parent
Bus device.
Definition device.h:89
struct list_head children
Devices attached to this device.
Definition device.h:87
struct list_head siblings
Devices on the same bus.
Definition device.h:85
const char * driver_name
Driver name.
Definition device.h:81
char name[40]
Name.
Definition device.h:79
An EISA device ID list entry.
Definition eisa.h:28
An EISA device.
Definition eisa.h:38
struct device dev
Generic device.
Definition eisa.h:40
uint16_t prod_id
Product ID.
Definition eisa.h:48
uint16_t ioaddr
I/O address.
Definition eisa.h:44
unsigned int slot
Slot number.
Definition eisa.h:42
uint16_t vendor_id
Manufacturer ID.
Definition eisa.h:46
struct eisa_driver * driver
Driver for this device.
Definition eisa.h:50
An EISA driver.
Definition eisa.h:60
int(* probe)(struct eisa_device *eisa, const struct eisa_device_id *id)
Probe device.
Definition eisa.h:72
unsigned int id_count
Number of entries in EISA ID table.
Definition eisa.h:64
void(* remove)(struct eisa_device *eisa)
Remove device.
Definition eisa.h:79
struct eisa_device_id * ids
EISA ID table.
Definition eisa.h:62
A root device.
Definition device.h:98
struct device dev
Device chain.
Definition device.h:103
A root device driver.
Definition device.h:111
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition tables.h:386
void udelay(unsigned long usecs)
Delay for a fixed number of microseconds.
Definition timer.c:61
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383