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 
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  */
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 
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 };
static int eisa_probe(struct eisa_device *eisa)
Probe an EISA device.
Definition: eisa.c:47
iPXE I/O API
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint16_t inw(volatile uint16_t *io_addr)
Read 16-bit word from I/O-mapped device.
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:69
#define EISA_PROD_ID
Definition: eisa.h:21
Error codes.
uint16_t vendor_id
Manufacturer ID.
Definition: eisa.h:46
FILE_LICENCE(GPL2_OR_LATER)
char name[40]
Name.
Definition: device.h:75
A root device.
Definition: device.h:94
void eisa_device_enabled(struct eisa_device *eisa, int enabled)
Reset and enable/disable an EISA device.
Definition: eisa.c:20
#define EISA_MIN_SLOT
Definition: eisa.h:16
An EISA device.
Definition: eisa.h:38
struct device dev
Device chain.
Definition: device.h:99
char * isa_id_string(unsigned int vendor, unsigned int product)
Definition: isa_ids.c:11
unsigned int vendor
Vendor ID.
Definition: device.h:31
struct device * parent
Bus device.
Definition: device.h:85
int(* probe)(struct eisa_device *eisa, const struct eisa_device_id *id)
Probe device.
Definition: eisa.h:72
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
static void eisabus_remove(struct root_device *rootdev)
Remove EISA root bus.
Definition: eisa.c:160
#define ENOMEM
Not enough space.
Definition: errno.h:534
static int eisabus_probe(struct root_device *rootdev)
Probe EISA root bus.
Definition: eisa.c:98
struct eisa_driver * driver
Driver for this device.
Definition: eisa.h:50
void udelay(unsigned long usecs)
Delay for a fixed number of microseconds.
Definition: timer.c:60
static struct root_driver eisa_root_driver
EISA bus root device driver.
Definition: eisa.c:173
An EISA device ID list entry.
Definition: eisa.h:28
unsigned int slot
Slot number.
Definition: eisa.h:42
struct root_device eisa_root_device __root_device
EISA bus root device.
Definition: eisa.c:179
const char * driver_name
Driver name.
Definition: device.h:77
void(* remove)(struct eisa_device *eisa)
Remove device.
Definition: eisa.h:79
#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:447
uint8_t id
Request identifier.
Definition: ena.h:12
unsigned int id_count
Number of entries in EISA ID table.
Definition: eisa.h:64
#define BUS_TYPE_EISA
EISA bus type.
Definition: device.h:49
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define EISA_VENDOR_ID
Definition: eisa.h:20
struct list_head siblings
Devices on the same bus.
Definition: device.h:81
An EISA driver.
Definition: eisa.h:60
uint8_t * tmp
Definition: entropy.h:156
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:358
A root device driver.
Definition: device.h:107
uint8_t slot
Slot.
Definition: edd.h:16
#define le16_to_cpu(value)
Definition: byteswap.h:112
int(* probe)(struct root_device *rootdev)
Add root device.
Definition: device.h:116
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
#define EISA_CMD_RESET
Definition: eisa.h:24
uint16_t ioaddr
I/O address.
Definition: eisa.h:44
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
#define ISA_PROD_ID(product)
Definition: isa_ids.h:45
#define outb(data, io_addr)
Definition: io.h:309
unsigned int bus_type
Bus type.
Definition: device.h:24
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:594
unsigned int device
Device ID.
Definition: device.h:33
#define EISA_MAX_SLOT
Definition: eisa.h:17
struct list_head children
Devices attached to this device.
Definition: device.h:83
#define EISA_DRIVERS
EISA driver table.
Definition: eisa.h:83
struct eisa_device_id * ids
EISA ID table.
Definition: eisa.h:62
struct device_description desc
Device description.
Definition: device.h:79
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
#define EISA_CMD_ENABLE
Definition: eisa.h:25
#define EISA_GLOBAL_CONFIG
Definition: eisa.h:22
struct device dev
Generic device.
Definition: eisa.h:40
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
uint16_t prod_id
Product ID.
Definition: eisa.h:48
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
String functions.
static void eisa_remove(struct eisa_device *eisa)
Remove an EISA device.
Definition: eisa.c:85
void * memset(void *dest, int character, size_t len) __nonnull
#define EISA_SLOT_BASE(n)
Definition: eisa.h:18