mca.c File Reference

#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <gpxe/io.h>
#include <gpxe/mca.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (BSD2)
static void mcabus_remove (struct root_device *rootdev)
 Remove MCA root bus.
static int mca_probe (struct mca_device *mca)
 Probe an MCA device.
static void mca_remove (struct mca_device *mca)
 Remove an MCA device.
static int mcabus_probe (struct root_device *rootdev)
 Probe MCA root bus.

Variables

static struct root_driver mca_root_driver
 MCA bus root device driver.
struct root_device mca_root_device __root_device
 MCA bus root device.


Function Documentation

FILE_LICENCE ( BSD2   ) 

static void mcabus_remove ( struct root_device rootdev  )  [static]

Remove MCA root bus.

Parameters:
rootdev MCA bus root device

Definition at line 155 of file mca.c.

References device::children, mca_device::dev, root_device::dev, free(), list_del, list_for_each_entry_safe, mca_remove(), and device::siblings.

Referenced by mcabus_probe().

00155                                                           {
00156         struct mca_device *mca;
00157         struct mca_device *tmp;
00158 
00159         list_for_each_entry_safe ( mca, tmp, &rootdev->dev.children,
00160                                    dev.siblings ) {
00161                 mca_remove ( mca );
00162                 list_del ( &mca->dev.siblings );
00163                 free ( mca );
00164         }
00165 }

static int mca_probe ( struct mca_device mca  )  [static]

Probe an MCA device.

Parameters:
mca MCA device
Return values:
rc Return status code
Searches for a driver for the MCA device. If a driver is found, its probe() routine is called.

Definition at line 29 of file mca.c.

References DBG, mca_device::driver, mca_device::driver_name, ENOTTY, for_each_table_entry, mca_device_id::id, id, mca_driver::id_count, mca_driver::ids, MCA_DRIVERS, MCA_ID, mca_device::pos, mca_driver::probe, and mca_device::slot.

Referenced by mcabus_probe().

00029                                                 {
00030         struct mca_driver *driver;
00031         struct mca_device_id *id;
00032         unsigned int i;
00033         int rc;
00034 
00035         DBG ( "Adding MCA slot %02x (ID %04x POS "
00036               "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x)\n",
00037               mca->slot, MCA_ID ( mca ),
00038               mca->pos[0], mca->pos[1], mca->pos[2], mca->pos[3],
00039               mca->pos[4], mca->pos[5], mca->pos[6], mca->pos[7] );
00040 
00041         for_each_table_entry ( driver, MCA_DRIVERS ) {
00042                 for ( i = 0 ; i < driver->id_count ; i++ ) {
00043                         id = &driver->ids[i];
00044                         if ( id->id != MCA_ID ( mca ) )
00045                                 continue;
00046                         mca->driver = driver;
00047                         mca->driver_name = id->name;
00048                         DBG ( "...using driver %s\n", mca->driver_name );
00049                         if ( ( rc = driver->probe ( mca, id ) ) != 0 ) {
00050                                 DBG ( "......probe failed\n" );
00051                                 continue;
00052                         }
00053                         return 0;
00054                 }
00055         }
00056 
00057         DBG ( "...no driver found\n" );
00058         return -ENOTTY;
00059 }

static void mca_remove ( struct mca_device mca  )  [static]

Remove an MCA device.

Parameters:
mca MCA device

Definition at line 66 of file mca.c.

References DBG, mca_device::driver, mca_driver::remove, and mca_device::slot.

Referenced by mcabus_remove().

00066                                                   {
00067         mca->driver->remove ( mca );
00068         DBG ( "Removed MCA device %02x\n", mca->slot );
00069 }

static int mcabus_probe ( struct root_device rootdev  )  [static]

Probe MCA root bus.

Parameters:
rootdev MCA bus root device
Scans the MCA bus for devices and registers all devices it can find.

Definition at line 79 of file mca.c.

References device_description::bus_type, BUS_TYPE_MCA, device::children, device::desc, root_device::dev, mca_device::dev, device_description::device, ENOMEM, free(), GENERIC_MCA_VENDOR, inb_p, INIT_LIST_HEAD, list_add, list_del, malloc(), MCA_ADAPTER_SETUP_REG, MCA_ID, MCA_MAX_SLOT_NR, MCA_MOTHERBOARD_SETUP_REG, MCA_POS_REG, mca_probe(), mcabus_remove(), memset(), device::name, NULL, outb_p, device::parent, mca_device::pos, device::siblings, mca_device::slot, snprintf(), and device_description::vendor.

00079                                                         {
00080         struct mca_device *mca = NULL;
00081         unsigned int slot;
00082         int seen_non_ff;
00083         unsigned int i;
00084         int rc;
00085 
00086         for ( slot = 0 ; slot <= MCA_MAX_SLOT_NR ; slot++ ) {
00087                 /* Allocate struct mca_device */
00088                 if ( ! mca )
00089                         mca = malloc ( sizeof ( *mca ) );
00090                 if ( ! mca ) {
00091                         rc = -ENOMEM;
00092                         goto err;
00093                 }
00094                 memset ( mca, 0, sizeof ( *mca ) );
00095                 mca->slot = slot;
00096 
00097                 /* Make sure motherboard setup is off */
00098                 outb_p ( 0xff, MCA_MOTHERBOARD_SETUP_REG );
00099 
00100                 /* Select the slot */
00101                 outb_p ( 0x8 | ( mca->slot & 0xf ), MCA_ADAPTER_SETUP_REG );
00102 
00103                 /* Read the POS registers */
00104                 seen_non_ff = 0;
00105                 for ( i = 0 ; i < ( sizeof ( mca->pos ) /
00106                                     sizeof ( mca->pos[0] ) ) ; i++ ) {
00107                         mca->pos[i] = inb_p ( MCA_POS_REG ( i ) );
00108                         if ( mca->pos[i] != 0xff )
00109                                 seen_non_ff = 1;
00110                 }
00111         
00112                 /* Kill all setup modes */
00113                 outb_p ( 0, MCA_ADAPTER_SETUP_REG );
00114 
00115                 /* If all POS registers are 0xff, this means there's no device
00116                  * present
00117                  */
00118                 if ( ! seen_non_ff )
00119                         continue;
00120 
00121                 /* Add to device hierarchy */
00122                 snprintf ( mca->dev.name, sizeof ( mca->dev.name ),
00123                            "MCA%02x", slot );
00124                 mca->dev.desc.bus_type = BUS_TYPE_MCA;
00125                 mca->dev.desc.vendor = GENERIC_MCA_VENDOR;
00126                 mca->dev.desc.device = MCA_ID ( mca );
00127                 mca->dev.parent = &rootdev->dev;
00128                 list_add ( &mca->dev.siblings, &rootdev->dev.children );
00129                 INIT_LIST_HEAD ( &mca->dev.children );
00130 
00131                 /* Look for a driver */
00132                 if ( mca_probe ( mca ) == 0 ) {
00133                         /* mcadev registered, we can drop our ref */
00134                         mca = NULL;
00135                 } else {
00136                         /* Not registered; re-use struct */
00137                         list_del ( &mca->dev.siblings );
00138                 }
00139         }
00140 
00141         free ( mca );
00142         return 0;
00143 
00144  err:
00145         free ( mca );
00146         mcabus_remove ( rootdev );
00147         return rc;
00148 }


Variable Documentation

struct root_driver mca_root_driver [static]

Initial value:

 {
        .probe = mcabus_probe,
        .remove = mcabus_remove,
}
MCA bus root device driver.

Definition at line 168 of file mca.c.

struct root_device mca_root_device __root_device

Initial value:

 {
        .dev = { .name = "MCA" },
        .driver = &mca_root_driver,
}
MCA bus root device.

Definition at line 174 of file mca.c.


Generated on Tue Apr 6 20:01:16 2010 for gPXE by  doxygen 1.5.7.1