eisa.c
Go to the documentation of this file.00001 #include <stdint.h>
00002 #include <string.h>
00003 #include <stdlib.h>
00004 #include <stdio.h>
00005 #include <errno.h>
00006 #include <gpxe/io.h>
00007 #include <unistd.h>
00008 #include <gpxe/eisa.h>
00009
00010 FILE_LICENCE ( GPL2_OR_LATER );
00011
00012 static void eisabus_remove ( struct root_device *rootdev );
00013
00014
00015
00016
00017
00018
00019
00020 void eisa_device_enabled ( struct eisa_device *eisa, int enabled ) {
00021
00022
00023
00024 outb ( EISA_CMD_RESET, eisa->ioaddr + EISA_GLOBAL_CONFIG );
00025 udelay ( 1000 );
00026
00027
00028
00029
00030 outb ( enabled ? EISA_CMD_ENABLE : 0,
00031 eisa->ioaddr + EISA_GLOBAL_CONFIG );
00032 udelay ( 1000 );
00033
00034 DBG ( "EISA %s device %02x\n", ( enabled ? "enabled" : "disabled" ),
00035 eisa->slot );
00036 }
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 static int eisa_probe ( struct eisa_device *eisa ) {
00048 struct eisa_driver *driver;
00049 struct eisa_device_id *id;
00050 unsigned int i;
00051 int rc;
00052
00053 DBG ( "Adding EISA device %02x (%04x:%04x (\"%s\") io %x)\n",
00054 eisa->slot, eisa->vendor_id, eisa->prod_id,
00055 isa_id_string ( eisa->vendor_id, eisa->prod_id ), eisa->ioaddr );
00056
00057 for_each_table_entry ( driver, EISA_DRIVERS ) {
00058 for ( i = 0 ; i < driver->id_count ; i++ ) {
00059 id = &driver->ids[i];
00060 if ( id->vendor_id != eisa->vendor_id )
00061 continue;
00062 if ( ISA_PROD_ID ( id->prod_id ) !=
00063 ISA_PROD_ID ( eisa->prod_id ) )
00064 continue;
00065 eisa->driver = driver;
00066 eisa->driver_name = id->name;
00067 DBG ( "...using driver %s\n", eisa->driver_name );
00068 if ( ( rc = driver->probe ( eisa, id ) ) != 0 ) {
00069 DBG ( "......probe failed\n" );
00070 continue;
00071 }
00072 return 0;
00073 }
00074 }
00075
00076 DBG ( "...no driver found\n" );
00077 return -ENOTTY;
00078 }
00079
00080
00081
00082
00083
00084
00085 static void eisa_remove ( struct eisa_device *eisa ) {
00086 eisa->driver->remove ( eisa );
00087 DBG ( "Removed EISA device %02x\n", eisa->slot );
00088 }
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 static int eisabus_probe ( struct root_device *rootdev ) {
00099 struct eisa_device *eisa = NULL;
00100 unsigned int slot;
00101 int rc;
00102
00103 for ( slot = EISA_MIN_SLOT ; slot <= EISA_MAX_SLOT ; slot++ ) {
00104
00105 if ( ! eisa )
00106 eisa = malloc ( sizeof ( *eisa ) );
00107 if ( ! eisa ) {
00108 rc = -ENOMEM;
00109 goto err;
00110 }
00111 memset ( eisa, 0, sizeof ( *eisa ) );
00112 eisa->slot = slot;
00113 eisa->ioaddr = EISA_SLOT_BASE ( eisa->slot );
00114
00115
00116 outb ( 0xff, eisa->ioaddr + EISA_VENDOR_ID );
00117 eisa->vendor_id =
00118 le16_to_cpu ( inw ( eisa->ioaddr + EISA_VENDOR_ID ) );
00119 eisa->prod_id =
00120 le16_to_cpu ( inw ( eisa->ioaddr + EISA_PROD_ID ) );
00121 if ( eisa->vendor_id & 0x80 ) {
00122
00123 continue;
00124 }
00125
00126
00127 snprintf ( eisa->dev.name, sizeof ( eisa->dev.name ),
00128 "EISA%02x", slot );
00129 eisa->dev.desc.bus_type = BUS_TYPE_EISA;
00130 eisa->dev.desc.vendor = eisa->vendor_id;
00131 eisa->dev.desc.device = eisa->prod_id;
00132 eisa->dev.parent = &rootdev->dev;
00133 list_add ( &eisa->dev.siblings, &rootdev->dev.children );
00134 INIT_LIST_HEAD ( &eisa->dev.children );
00135
00136
00137 if ( eisa_probe ( eisa ) == 0 ) {
00138
00139 eisa = NULL;
00140 } else {
00141
00142 list_del ( &eisa->dev.siblings );
00143 }
00144 }
00145
00146 free ( eisa );
00147 return 0;
00148
00149 err:
00150 free ( eisa );
00151 eisabus_remove ( rootdev );
00152 return rc;
00153 }
00154
00155
00156
00157
00158
00159
00160 static void eisabus_remove ( struct root_device *rootdev ) {
00161 struct eisa_device *eisa;
00162 struct eisa_device *tmp;
00163
00164 list_for_each_entry_safe ( eisa, tmp, &rootdev->dev.children,
00165 dev.siblings ) {
00166 eisa_remove ( eisa );
00167 list_del ( &eisa->dev.siblings );
00168 free ( eisa );
00169 }
00170 }
00171
00172
00173 static struct root_driver eisa_root_driver = {
00174 .probe = eisabus_probe,
00175 .remove = eisabus_remove,
00176 };
00177
00178
00179 struct root_device eisa_root_device __root_device = {
00180 .dev = { .name = "EISA" },
00181 .driver = &eisa_root_driver,
00182 };