iPXE
Functions | Variables
eisa.c File Reference
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ipxe/io.h>
#include <unistd.h>
#include <ipxe/eisa.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER)
static void eisabus_remove (struct root_device *rootdev)
 Remove EISA root bus.
void eisa_device_enabled (struct eisa_device *eisa, int enabled)
 Reset and enable/disable an EISA device.
static int eisa_probe (struct eisa_device *eisa)
 Probe an EISA device.
static void eisa_remove (struct eisa_device *eisa)
 Remove an EISA device.
static int eisabus_probe (struct root_device *rootdev)
 Probe EISA root bus.

Variables

static struct root_driver eisa_root_driver
 EISA bus root device driver.
struct root_device eisa_root_device __root_device
 EISA bus root device.

Function Documentation

FILE_LICENCE ( GPL2_OR_LATER  )
static void eisabus_remove ( struct root_device rootdev) [static]

Remove EISA root bus.

Parameters:
rootdevEISA bus root device

Definition at line 160 of file eisa.c.

References device::children, eisa_device::dev, root_device::dev, eisa_remove(), free, list_del, list_for_each_entry_safe, and device::siblings.

Referenced by eisabus_probe().

                                                           {
        struct eisa_device *eisa;
        struct eisa_device *tmp;

        list_for_each_entry_safe ( eisa, tmp, &rootdev->dev.children,
                                   dev.siblings ) {
                eisa_remove ( eisa );
                list_del ( &eisa->dev.siblings );
                free ( eisa );
        }
}
void eisa_device_enabled ( struct eisa_device eisa,
int  enabled 
)

Reset and enable/disable an EISA device.

Parameters:
eisaEISA device
enabled1=enable, 0=disable

Definition at line 20 of file eisa.c.

References DBG, EISA_CMD_ENABLE, EISA_CMD_RESET, EISA_GLOBAL_CONFIG, eisa_device::ioaddr, outb(), eisa_device::slot, and udelay().

Referenced by disable_eisa_device(), and enable_eisa_device().

                                                                   {
        /* Set reset line high for 1000 Ás.  Spec says 500 Ás, but
         * this doesn't work for all cards, so we are conservative.
         */
        outb ( EISA_CMD_RESET, eisa->ioaddr + EISA_GLOBAL_CONFIG );
        udelay ( 1000 ); /* Must wait 800 */

        /* Set reset low and write a 1 to ENABLE.  Delay again, in
         * case the card takes a while to wake up.
         */
        outb ( enabled ? EISA_CMD_ENABLE : 0,
               eisa->ioaddr + EISA_GLOBAL_CONFIG );
        udelay ( 1000 ); /* Must wait 800 */

        DBG ( "EISA %s device %02x\n", ( enabled ? "enabled" : "disabled" ),
              eisa->slot );
}
static int eisa_probe ( struct eisa_device eisa) [static]

Probe an EISA device.

Parameters:
eisaEISA device
Return values:
rcReturn status code

Searches for a driver for the EISA device. If a driver is found, its probe() routine is called.

Definition at line 47 of file eisa.c.

References DBG, eisa_device::dev, eisa_device::driver, device::driver_name, EISA_DRIVERS, ENOTTY, for_each_table_entry, id, eisa_driver::id_count, eisa_driver::ids, eisa_device::ioaddr, isa_id_string(), ISA_PROD_ID, eisa_driver::probe, eisa_device_id::prod_id, eisa_device::prod_id, rc, eisa_device::slot, eisa_device_id::vendor_id, and eisa_device::vendor_id.

Referenced by eisabus_probe().

                                                   {
        struct eisa_driver *driver;
        struct eisa_device_id *id;
        unsigned int i;
        int rc;

        DBG ( "Adding EISA device %02x (%04x:%04x (\"%s\") io %x)\n",
              eisa->slot, eisa->vendor_id, eisa->prod_id,
              isa_id_string ( eisa->vendor_id, eisa->prod_id ), eisa->ioaddr );

        for_each_table_entry ( driver, EISA_DRIVERS ) {
                for ( i = 0 ; i < driver->id_count ; i++ ) {
                        id = &driver->ids[i];
                        if ( id->vendor_id != eisa->vendor_id )
                                continue;
                        if ( ISA_PROD_ID ( id->prod_id ) !=
                             ISA_PROD_ID ( eisa->prod_id ) )
                                continue;
                        eisa->driver = driver;
                        eisa->dev.driver_name = id->name;
                        DBG ( "...using driver %s\n", eisa->dev.driver_name );
                        if ( ( rc = driver->probe ( eisa, id ) ) != 0 ) {
                                DBG ( "......probe failed\n" );
                                continue;
                        }
                        return 0;
                }
        }

        DBG ( "...no driver found\n" );
        return -ENOTTY;
}
static void eisa_remove ( struct eisa_device eisa) [static]

Remove an EISA device.

Parameters:
eisaEISA device

Definition at line 85 of file eisa.c.

References DBG, eisa_device::driver, eisa_driver::remove, and eisa_device::slot.

Referenced by eisabus_remove().

                                                     {
        eisa->driver->remove ( eisa );
        DBG ( "Removed EISA device %02x\n", eisa->slot );
}
static int eisabus_probe ( struct root_device rootdev) [static]

Probe EISA root bus.

Parameters:
rootdevEISA bus root device

Scans the EISA bus for devices and registers all devices it can find.

Definition at line 98 of file eisa.c.

References device_description::bus_type, BUS_TYPE_EISA, device::children, device::desc, eisa_device::dev, root_device::dev, device_description::device, EISA_MAX_SLOT, EISA_MIN_SLOT, eisa_probe(), EISA_PROD_ID, EISA_SLOT_BASE, EISA_VENDOR_ID, eisabus_remove(), ENOMEM, free, INIT_LIST_HEAD, inw(), eisa_device::ioaddr, le16_to_cpu, list_add, list_del, malloc(), memset(), device::name, NULL, outb(), device::parent, eisa_device::prod_id, rc, device::siblings, eisa_device::slot, slot, snprintf(), device_description::vendor, and eisa_device::vendor_id.

                                                         {
        struct eisa_device *eisa = NULL;
        unsigned int slot;
        int rc;

        for ( slot = EISA_MIN_SLOT ; slot <= EISA_MAX_SLOT ; slot++ ) {
                /* Allocate struct eisa_device */
                if ( ! eisa )
                        eisa = malloc ( sizeof ( *eisa ) );
                if ( ! eisa ) {
                        rc = -ENOMEM;
                        goto err;
                }
                memset ( eisa, 0, sizeof ( *eisa ) );
                eisa->slot = slot;
                eisa->ioaddr = EISA_SLOT_BASE ( eisa->slot );

                /* Test for board present */
                outb ( 0xff, eisa->ioaddr + EISA_VENDOR_ID );
                eisa->vendor_id =
                        le16_to_cpu ( inw ( eisa->ioaddr + EISA_VENDOR_ID ) );
                eisa->prod_id =
                        le16_to_cpu ( inw ( eisa->ioaddr + EISA_PROD_ID ) );
                if ( eisa->vendor_id & 0x80 ) {
                        /* No board present */
                        continue;
                }

                /* Add to device hierarchy */
                snprintf ( eisa->dev.name, sizeof ( eisa->dev.name ),
                           "EISA%02x", slot );
                eisa->dev.desc.bus_type = BUS_TYPE_EISA;
                eisa->dev.desc.vendor = eisa->vendor_id;
                eisa->dev.desc.device = eisa->prod_id;
                eisa->dev.parent = &rootdev->dev;
                list_add ( &eisa->dev.siblings, &rootdev->dev.children );
                INIT_LIST_HEAD ( &eisa->dev.children );

                /* Look for a driver */
                if ( eisa_probe ( eisa ) == 0 ) {
                        /* eisadev registered, we can drop our ref */
                        eisa = NULL;
                } else {
                        /* Not registered; re-use struct */
                        list_del ( &eisa->dev.siblings );
                }
        }

        free ( eisa );
        return 0;

 err:
        free ( eisa );
        eisabus_remove ( rootdev );
        return rc;
}

Variable Documentation

struct root_driver eisa_root_driver [static]
Initial value:
 {
        .probe = eisabus_probe,
        .remove = eisabus_remove,
}

EISA bus root device driver.

Definition at line 173 of file eisa.c.

struct root_device eisa_root_device __root_device
Initial value:
 {
        .dev = { .name = "EISA" },
        .driver = &eisa_root_driver,
}

EISA bus root device.

Definition at line 179 of file eisa.c.