Standardised debug mechanism in place now.
[people/xl0/gpxe.git] / src / drivers / bus / eisa.c
1 #include "etherboot.h"
2 #include "dev.h"
3 #include "io.h"
4 #include "timer.h"
5 #include "eisa.h"
6
7 /*
8  * Ensure that there is sufficient space in the shared dev_bus
9  * structure for a struct pci_device.
10  *
11  */
12 DEV_BUS( struct eisa_device, eisa_dev );
13 static char eisa_magic[0]; /* guaranteed unique symbol */
14
15 /*
16  * Fill in parameters for an EISA device based on slot number
17  *
18  * Return 1 if device present, 0 otherwise
19  *
20  */
21 static int fill_eisa_device ( struct eisa_device *eisa ) {
22         uint8_t present;
23
24         /* Set ioaddr */
25         eisa->ioaddr = EISA_SLOT_BASE ( eisa->slot );
26
27         /* Test for board present */
28         outb ( 0xff, eisa->ioaddr + EISA_MFG_ID_HI );
29         present = inb ( eisa->ioaddr + EISA_MFG_ID_HI );
30         if ( present & 0x80 ) {
31                 /* No board present */
32                 return 0;
33         }
34
35         /* Read mfg and product IDs.  Yes, the resulting uint16_ts
36          * will be upside-down.  This appears to be by design.
37          */
38         eisa->mfg_id = ( inb ( eisa->ioaddr + EISA_MFG_ID_LO ) << 8 )
39                 + present;
40         eisa->prod_id = ( inb ( eisa->ioaddr + EISA_PROD_ID_LO ) << 8 )
41                 + inb ( eisa->ioaddr + EISA_PROD_ID_HI );
42
43         DBG ( "EISA slot %d (base %#hx) ID %hx:%hx (\"%s\")\n",
44               eisa->slot, eisa->ioaddr, eisa->mfg_id, eisa->prod_id,
45               isa_id_string ( eisa->mfg_id, eisa->prod_id ) );
46
47         return 1;
48 }
49
50 /*
51  * Obtain a struct eisa * from a struct dev *
52  *
53  * If dev has not previously been used for an EISA device scan, blank
54  * out struct eisa
55  */
56 struct eisa_device * eisa_device ( struct dev *dev ) {
57         struct eisa_device *eisa = dev->bus;;
58
59         if ( eisa->magic != eisa_magic ) {
60                 memset ( eisa, 0, sizeof ( *eisa ) );
61                 eisa->magic = eisa_magic;
62         }
63         eisa->dev = dev;
64         return eisa;
65 }
66
67 /*
68  * Find an EISA device matching the specified driver
69  *
70  */
71 int find_eisa_device ( struct eisa_device *eisa, struct eisa_driver *driver ) {
72         unsigned int i;
73
74         /* Iterate through all possible EISA slots, starting where we
75          * left off.  If eisa->slot is zero (which it will be if we
76          * have a zeroed structure), start from slot EISA_MIN_SLOT,
77          * since slot 0 doesn't exist.
78          */
79         if ( ! eisa->slot ) {
80                 eisa->slot = EISA_MIN_SLOT;
81         }
82         for ( ; eisa->slot <= EISA_MAX_SLOT ; eisa->slot++ ) {
83                 /* If we've already used this device, skip it */
84                 if ( eisa->already_tried ) {
85                         eisa->already_tried = 0;
86                         continue;
87                 }
88
89                 /* Fill in device parameters */
90                 if ( ! fill_eisa_device ( eisa ) ) {
91                         continue;
92                 }
93
94                 /* Compare against driver's ID list */
95                 for ( i = 0 ; i < driver->id_count ; i++ ) {
96                         struct eisa_id *id = &driver->ids[i];
97                         
98                         if ( ( eisa->mfg_id == id->mfg_id ) &&
99                              ( ISA_PROD_ID ( eisa->prod_id ) ==
100                                ISA_PROD_ID ( id->prod_id ) ) ) {
101                                 DBG ( "Device %s (driver %s) matches ID %s\n",
102                                       id->name, driver->name,
103                                       isa_id_string ( eisa->mfg_id,
104                                                       eisa->prod_id ) );
105                                 if ( eisa->dev ) {
106                                         eisa->dev->name = driver->name;
107                                         eisa->dev->devid.bus_type
108                                                 = ISA_BUS_TYPE;
109                                         eisa->dev->devid.vendor_id
110                                                 = eisa->mfg_id;
111                                         eisa->dev->devid.device_id
112                                                 = eisa->prod_id;
113                                 }
114                                 eisa->already_tried = 1;
115                                 return 1;
116                         }
117                 }
118         }
119
120         /* No device found */
121         eisa->slot = EISA_MIN_SLOT;
122         return 0;
123 }
124
125 /*
126  * Reset and enable an EISA device
127  *
128  */
129 void enable_eisa_device ( struct eisa_device *eisa ) {
130         /* Set reset line high for 1000 µs.  Spec says 500 µs, but
131          * this doesn't work for all cards, so we are conservative.
132          */
133         outb ( EISA_CMD_RESET, eisa->ioaddr + EISA_GLOBAL_CONFIG );
134         udelay ( 1000 ); /* Must wait 800 */
135
136         /* Set reset low and write a 1 to ENABLE.  Delay again, in
137          * case the card takes a while to wake up.
138          */
139         outb ( EISA_CMD_ENABLE, eisa->ioaddr + EISA_GLOBAL_CONFIG );
140         udelay ( 1000 ); /* Must wait 800 */
141 }