Consistency
[people/xl0/gpxe.git] / src / drivers / bus / mca.c
1 /*
2  * MCA bus driver code
3  *
4  * Abstracted from 3c509.c.
5  *
6  */
7
8 #include "etherboot.h"
9 #include "io.h"
10 #include "mca.h"
11
12 /*
13  * Ensure that there is sufficient space in the shared dev_bus
14  * structure for a struct pci_device.
15  *
16  */
17 DEV_BUS( struct mca_device, mca_dev );
18 static char mca_magic[0]; /* guaranteed unique symbol */
19
20 /*
21  * Fill in parameters for an MCA device based on slot number
22  *
23  */
24 static int fill_mca_device ( struct mca_device *mca ) {
25         unsigned int i, seen_non_ff;
26
27         /* Make sure motherboard setup is off */
28         outb_p ( 0xff, MCA_MOTHERBOARD_SETUP_REG );
29
30         /* Select the slot */
31         outb_p ( 0x8 | ( mca->slot & 0xf ), MCA_ADAPTER_SETUP_REG );
32
33         /* Read the POS registers */
34         seen_non_ff = 0;
35         for ( i = 0 ; i < ( sizeof ( mca->pos ) / sizeof ( mca->pos[0] ) ) ;
36               i++ ) {
37                 mca->pos[i] = inb_p ( MCA_POS_REG ( i ) );
38                 if ( mca->pos[i] != 0xff )
39                         seen_non_ff = 1;
40         }
41         
42         /* If all POS registers are 0xff, this means there's no device
43          * present
44          */
45         if ( ! seen_non_ff )
46                 return 0;
47
48         /* Kill all setup modes */
49         outb_p ( 0, MCA_ADAPTER_SETUP_REG );
50
51         DBG ( "MCA found slot %d id %hx "
52               "(POS %hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx)\n",
53               mca->slot, MCA_ID ( mca ),
54               mca->pos[0], mca->pos[1], mca->pos[2], mca->pos[3],
55               mca->pos[4], mca->pos[5], mca->pos[6], mca->pos[7] );
56
57         return 1;
58 }
59
60 /*
61  * Find an MCA device matching the specified driver
62  *
63  */
64 int find_mca_device ( struct mca_device *mca, struct mca_driver *driver ) {
65         unsigned int i;
66
67         /* Initialise struct mca if it's the first time it's been used. */
68         if ( mca->magic != mca_magic ) {
69                 memset ( mca, 0, sizeof ( *mca ) );
70                 mca->magic = mca_magic;
71         }
72
73         /* Iterate through all possible MCA slots, starting where we
74          * left off
75          */
76         DBG ( "MCA searching for device matching driver %s\n", driver->name );
77         for ( ; mca->slot < MCA_MAX_SLOT_NR ; mca->slot++ ) {
78                 /* If we've already used this device, skip it */
79                 if ( mca->already_tried ) {
80                         mca->already_tried = 0;
81                         continue;
82                 }
83
84                 /* Fill in device parameters */
85                 if ( ! fill_mca_device ( mca ) ) {
86                         continue;
87                 }
88
89                 /* Compare against driver's ID list */
90                 for ( i = 0 ; i < driver->id_count ; i++ ) {
91                         struct mca_id *id = &driver->ids[i];
92
93                         if ( MCA_ID ( mca ) == id->id ) {
94                                 DBG ( "MCA found ID %hx (device %s) "
95                                       "matching driver %s\n",
96                                       id->name, id->id, driver->name );
97                                 mca->name = id->name;
98                                 mca->already_tried = 1;
99                                 return 1;
100                         }
101                 }
102         }
103
104         /* No device found */
105         DBG ( "MCA found no device matching driver %s\n", driver->name );
106         mca->slot = 0;
107         return 0;
108 }
109
110 /*
111  * Find the next MCA device that can be used to boot using the
112  * specified driver.
113  *
114  */
115 int find_mca_boot_device ( struct dev *dev, struct mca_driver *driver ) {
116         struct mca_device *mca = ( struct mca_device * )dev->bus;
117
118         if ( ! find_mca_device ( mca, driver ) )
119                 return 0;
120
121         dev->name = mca->name;
122         dev->devid.bus_type = MCA_BUS_TYPE;
123         dev->devid.vendor_id = GENERIC_MCA_VENDOR;
124         dev->devid.device_id = MCA_ID ( mca );
125
126         return 1;
127 }