Annotation of qemu/roms/ipxe/src/drivers/bus/isa.c, revision 1.1

1.1     ! root        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 <ipxe/isa.h>
        !             8: 
        !             9: FILE_LICENCE ( GPL2_OR_LATER );
        !            10: 
        !            11: /*
        !            12:  * isa.c implements a "classical" port-scanning method of ISA device
        !            13:  * detection.  The driver must provide a list of probe addresses
        !            14:  * (probe_addrs), together with a function (probe_addr) that can be
        !            15:  * used to test for the physical presence of a device at any given
        !            16:  * address.
        !            17:  *
        !            18:  * Note that this should probably be considered the "last resort" for
        !            19:  * device probing.  If the card supports ISAPnP or EISA, use that
        !            20:  * instead.  Some cards (e.g. the 3c509) implement a proprietary
        !            21:  * ISAPnP-like mechanism.
        !            22:  *
        !            23:  * The ISA probe address list can be overridden by config.h; if the
        !            24:  * user specifies ISA_PROBE_ADDRS then that list will be used first.
        !            25:  * (If ISA_PROBE_ONLY is defined, the driver's own list will never be
        !            26:  * used).
        !            27:  */
        !            28: 
        !            29: /*
        !            30:  * User-supplied probe address list
        !            31:  *
        !            32:  */
        !            33: static isa_probe_addr_t isa_extra_probe_addrs[] = {
        !            34: #ifdef ISA_PROBE_ADDRS
        !            35:        ISA_PROBE_ADDRS
        !            36: #endif
        !            37: };
        !            38: #define ISA_EXTRA_PROBE_ADDR_COUNT \
        !            39:      ( sizeof ( isa_extra_probe_addrs ) / sizeof ( isa_extra_probe_addrs[0] ) )
        !            40: 
        !            41: #define ISA_IOIDX_MIN( driver ) ( -ISA_EXTRA_PROBE_ADDR_COUNT )
        !            42: #ifdef ISA_PROBE_ONLY
        !            43: #define ISA_IOIDX_MAX( driver ) ( -1 )
        !            44: #else
        !            45: #define ISA_IOIDX_MAX( driver ) ( (int) (driver)->addr_count - 1 )
        !            46: #endif
        !            47: 
        !            48: #define ISA_IOADDR( driver, ioidx )                                      \
        !            49:        ( ( (ioidx) < 0 ) ?                                               \
        !            50:          isa_extra_probe_addrs[ (ioidx) + ISA_EXTRA_PROBE_ADDR_COUNT ] : \
        !            51:          (driver)->probe_addrs[(ioidx)] )
        !            52: 
        !            53: static void isabus_remove ( struct root_device *rootdev );
        !            54: 
        !            55: /**
        !            56:  * Probe an ISA device
        !            57:  *
        !            58:  * @v isa              ISA device
        !            59:  * @ret rc             Return status code
        !            60:  */
        !            61: static int isa_probe ( struct isa_device *isa ) {
        !            62:        int rc;
        !            63: 
        !            64:        DBG ( "Trying ISA driver %s at I/O %04x\n",
        !            65:              isa->driver->name, isa->ioaddr );
        !            66: 
        !            67:        if ( ( rc = isa->driver->probe ( isa ) ) != 0 ) {
        !            68:                DBG ( "...probe failed\n" );
        !            69:                return rc;
        !            70:        }
        !            71: 
        !            72:        DBG ( "...device found\n" );
        !            73:        return 0;
        !            74: }
        !            75: 
        !            76: /**
        !            77:  * Remove an ISA device
        !            78:  *
        !            79:  * @v isa              ISA device
        !            80:  */
        !            81: static void isa_remove ( struct isa_device *isa ) {
        !            82:        isa->driver->remove ( isa );
        !            83:        DBG ( "Removed ISA%04x\n", isa->ioaddr );
        !            84: }
        !            85: 
        !            86: /**
        !            87:  * Probe ISA root bus
        !            88:  *
        !            89:  * @v rootdev          ISA bus root device
        !            90:  *
        !            91:  * Scans the ISA bus for devices and registers all devices it can
        !            92:  * find.
        !            93:  */
        !            94: static int isabus_probe ( struct root_device *rootdev ) {
        !            95:        struct isa_device *isa = NULL;
        !            96:        struct isa_driver *driver;
        !            97:        int ioidx;
        !            98:        int rc;
        !            99: 
        !           100:        for_each_table_entry ( driver, ISA_DRIVERS ) {
        !           101:                for ( ioidx = ISA_IOIDX_MIN ( driver ) ;
        !           102:                      ioidx <= ISA_IOIDX_MAX ( driver ) ; ioidx++ ) {
        !           103:                        /* Allocate struct isa_device */
        !           104:                        if ( ! isa )
        !           105:                                isa = malloc ( sizeof ( *isa ) );
        !           106:                        if ( ! isa ) {
        !           107:                                rc = -ENOMEM;
        !           108:                                goto err;
        !           109:                        }
        !           110:                        memset ( isa, 0, sizeof ( *isa ) );
        !           111:                        isa->driver = driver;
        !           112:                        isa->ioaddr = ISA_IOADDR ( driver, ioidx );
        !           113: 
        !           114:                        /* Add to device hierarchy */
        !           115:                        snprintf ( isa->dev.name, sizeof ( isa->dev.name ),
        !           116:                                   "ISA%04x", isa->ioaddr );
        !           117:                        isa->dev.driver_name = driver->name;
        !           118:                        isa->dev.desc.bus_type = BUS_TYPE_ISA;
        !           119:                        isa->dev.desc.vendor = driver->vendor_id;
        !           120:                        isa->dev.desc.device = driver->prod_id;
        !           121:                        isa->dev.parent = &rootdev->dev;
        !           122:                        list_add ( &isa->dev.siblings,
        !           123:                                   &rootdev->dev.children );
        !           124:                        INIT_LIST_HEAD ( &isa->dev.children );
        !           125: 
        !           126:                        /* Try probing at this I/O address */
        !           127:                        if ( isa_probe ( isa ) == 0 ) {
        !           128:                                /* isadev registered, we can drop our ref */
        !           129:                                isa = NULL;
        !           130:                        } else {
        !           131:                                /* Not registered; re-use struct */
        !           132:                                list_del ( &isa->dev.siblings );
        !           133:                        }
        !           134:                }
        !           135:        }
        !           136: 
        !           137:        free ( isa );
        !           138:        return 0;
        !           139: 
        !           140:  err:
        !           141:        free ( isa );
        !           142:        isabus_remove ( rootdev );
        !           143:        return rc;
        !           144: }
        !           145: 
        !           146: /**
        !           147:  * Remove ISA root bus
        !           148:  *
        !           149:  * @v rootdev          ISA bus root device
        !           150:  */
        !           151: static void isabus_remove ( struct root_device *rootdev ) {
        !           152:        struct isa_device *isa;
        !           153:        struct isa_device *tmp;
        !           154: 
        !           155:        list_for_each_entry_safe ( isa, tmp, &rootdev->dev.children,
        !           156:                                   dev.siblings ) {
        !           157:                isa_remove ( isa );
        !           158:                list_del ( &isa->dev.siblings );
        !           159:                free ( isa );
        !           160:        }
        !           161: }
        !           162: 
        !           163: /** ISA bus root device driver */
        !           164: static struct root_driver isa_root_driver = {
        !           165:        .probe = isabus_probe,
        !           166:        .remove = isabus_remove,
        !           167: };
        !           168: 
        !           169: /** ISA bus root device */
        !           170: struct root_device isa_root_device __root_device = {
        !           171:        .dev = { .name = "ISA" },
        !           172:        .driver = &isa_root_driver,
        !           173: };

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.