Added netdev_nullify to natsemi_remove()
[gpxe.git] / src / core / pcmcia.c
blob631971ef5c0ef364e4c36b6c6582baf23b55d293
1 #if 0
3 /*
4 * pcmcia.c
6 * PCMCIA support routines for etherboot - generic stuff
8 * This code has partly be taken from the linux kernel sources, .../drivers/pcmcia/
9 * Started & put together by
10 * Anselm Martin Hoffmeister
11 * Stockholm Projekt Computer-Service
12 * Sankt Augustin / Bonn, Germany
14 * Distributed under GPL2
20 * ******************************
21 * PLEASE DO NOT YET WORK ON THIS
22 * ******************************
24 * I'm still fixing it up on every end, so we most probably would interfere
25 * at some point. If there's anything obvious or better, not-so-obvious,
26 * please contact me by e-mail: anselm (AT) hoffmeister (DOT) be *THANKS*
28 #include <stdio.h>
29 #include <pcmcia.h>
30 #include <i82365.h>
31 #define CODE_STATUS "alpha"
32 #define CODE_VERSION "0.1.3"
33 #include <pcmcia-opts.h>
34 #include <console.h>
35 #include <gpxe/init.h>
37 int sockets; /* AHTODO: Phase this out! */
38 u_int pccsocks;
39 struct pccsock_t pccsock[MAXPCCSOCKS];
40 int inited = -1;
41 struct pcc_config_t pccconfig[MAXPCCCONFIGS];
43 struct driver_interact_t driver[] = {
44 #ifdef SUPPORT_I82365
45 { I82365, i82365_interfacer, "Intel_82365" },
46 #endif
49 #define NUM_DRIVERS (sizeof(driver)/(sizeof(struct driver_interact_t)))
51 void sleepticks(int numticks ) {
52 u_int tmo;
53 for (tmo = currticks()+numticks; currticks() < tmo; ) {
55 return;
58 static void pcmcia_init_all(void) {
59 u_int i, j, k, l, m, n, ui, configs = 0;
60 u_int multicard[8];
61 u_char *uc, upc;
62 if ( PDEBUG > 0 ) printf("Initializing PCMCIA subsystem (code-status: " CODE_STATUS ", Version " CODE_VERSION ")\n");
63 if ( PDEBUG > 2 ) {
64 printf ( "Supporting %d driver(s): ", NUM_DRIVERS );
65 for ( i = 0; i < NUM_DRIVERS; ++i ) {
66 printf ( "[%s] ", driver[i].name );
68 printf ( "\n" );
70 pccsocks = 0;
71 sockets = 0;
72 // Init all drivers in the driver[] array:
73 for ( i = 0; i < NUM_DRIVERS; ++i ) {
74 driver[i].f(INIT,0,i,0,0); // init needs no params. It uses pccsocks and pccsock[].
75 // Only i tells it which driver_id itself is.
77 for ( i = 0; i < pccsocks; ++i ) {
78 printf ( "Socket %d: ", i );
79 if ( pccsock[i].status != HASCARD ) {
80 printf ( "is %s: skipping\n", pccsock[i].status == EMPTY? "empty":"[status unknown]" );
81 continue;
83 if ( 0 != driver[pccsock[i].drivernum].f(MAPATTRMEM,pccsock[i].internalid,MAP_ATTRMEM_TO, MAP_ATTRMEM_LEN,0 ) ) {
84 printf ("PCMCIA controller failed to map attribute memory.\n**** SEVERE ERROR CONDITION. Skipping controller.\n" );
85 if ( PDEBUG > 2 ) {
86 printf ( "<press key. THIS CONDITION SHOULD BE REPORTED!>\n" ); getchar();
88 continue;
90 // parse configuration information
91 uc = ioremap ( MAP_ATTRMEM_TO, MAP_ATTRMEM_LEN );
92 pccsock[i].stringoffset = pccsock[i].configoffset = pccsock[i].stringlength = 0;
93 pccsock[i].type = 0xff;
94 for ( l = 0; l < 8; ++l ) multicard[l] = 0;
95 sleepticks(2);
96 for ( l = ui = 0; ui < 0x800; ui += uc[(2*ui)+2] + 2 ) {
97 if ( uc[(2*ui)] == 0xff ) {
98 break;
100 // This loop is complete rubbish AFAICS.
101 // But without it, my test system won't come up.
102 // It's too bad to develop on broken hardware
103 // - Anselm
105 sleepticks(2);
106 configs = 0;
107 inited = -1;
108 for ( l = ui = 0; ui < 0x800; ui += uc[(2*ui)+2] + 2 ) {
109 if ( uc[(2*ui)] == 0xff ) break;
110 else if ( uc[2*ui] == 0x15 ) {
111 for ( k = 2 * ( ui + 2 ); ( uc[k] <= ' ' ) && ( k < ( 2 * ( uc[2*(ui+1)] + ui + 2 ) ) ) ; k += 2 ) { ; }
112 pccsock[i].stringoffset = k;
113 pccsock[i].stringlength = ( 2 * ( ui + 2 + uc[(2*ui)+2] ) - k ) / 2;
114 } else if ( uc[2*ui] == 0x21 ) {
115 pccsock[i].type = uc[(2*ui)+4];
116 } else if ( uc[2*ui] == 0x1a ) { // Configuration map
117 printf ( "\nConfig map 0x1a found [" );
118 for ( k = 0; k < uc[2*(ui+1)]; ++k ) {
119 printf ( "%02x ", uc[2*(ui+k+2)] );
121 printf ( "]\nHighest config available is %d\n", uc[2*(ui+3)] );
122 m = uc[2*(ui+2)];
123 pccsock[i].configoffset = 0;
124 for ( j = 0; j <= (m & 3); ++j ) {
125 pccsock[i].configoffset += uc[2*(ui+4+j)] << (8*j);
127 pccsock[i].rmask0 = 0;
128 for ( j = 0; j <= ( ( ( m & 0x3c ) >> 2 ) & 3 ); ++j ) {
129 pccsock[i].rmask0 += uc[2*(ui+5+(m&3)+j)] << (8*j);
131 j = pccsock[i].rmask0;
132 printf ( "Config offset is %x, card has regs: < %s%s%s%s%s>\n", pccsock[i].configoffset,
133 j & 1 ? "COR ":"", j & 2 ? "CCSR ":"", j & 4 ? "PRR ":"", j & 8 ? "SCR ":"", j & 16? "ESR ":"" );
134 printf ( "COR + CCSR contents (si/du) %x %x/%x %x\n", uc[pccsock[i].configoffset+0],
135 uc[pccsock[i].configoffset+2],uc[pccsock[i].configoffset*2],uc[(pccsock[i].configoffset*2)+2] );
136 printf ( " " );
137 } else if ( uc[2*ui] == 0x1b ) { // Configuration data entry
138 //printf ( "Config data 0x1b found [\n" );getchar();
139 for ( k = 0; k < uc[2*(ui+1)]; ++k ) {
140 // printf ( "%02x ", uc[2*(ui+k+2)] );
142 // Parse this tuple into pccconfig[configs]
143 // printf ( "]\n" );
144 if ( configs == MAXPCCCONFIGS ) continue;
145 k = 2*ui+4;
146 pccconfig[configs].index = uc[k] & 0x3f;
147 if ( uc[k] & 0x80 ) {
148 // printf ( "Special config, unsupp. for now\n" );
149 continue;
151 k+=2;
152 // printf ( "Features: %2x\n", uc[k] );
153 if ( uc[k] & 0x7 ) {
154 // printf ( "Cannot work with Vcc/Timing configs right now\n" );
155 continue;
157 pccconfig[configs].iowin = pccconfig[configs].iolen = 0;
158 if ( 0 != ( uc[k] & 0x8 ) ) {
159 k+=2;
160 // printf ( "Reading IO config: " );
161 if ( 0 == ( uc[k] & 0x80 ) ) {
162 // printf ( "Cannot work with auto/io config\n" );
163 continue;
165 k+=2;
166 if ( 0 != ( uc[k] & 0x0f ) ) {
167 // printf ( "Don't support more than 1 iowin right now\n" );
168 continue;
170 j = (uc[k] & 0x30) >> 4;
171 m = (uc[k] & 0xc0) >> 6;
172 if ( 3 == j ) ++j;
173 if ( 3 == m ) ++m;
174 k += 2;
175 pccconfig[configs].iowin = 0;
176 pccconfig[configs].iolen = 1;
177 for ( n = 0; n < j; ++n, k+=2 ) {
178 pccconfig[configs].iowin += uc[k] << (n*8);
180 for ( n = 0; n < m; ++n, k+=2 ) {
181 pccconfig[configs].iolen += uc[k] << (n*8);
183 // printf ( "io %x len %d (%d)\n", pccconfig[configs].iowin, pccconfig[configs].iolen,configs );
185 for ( j = 0; j < (uc[k] & 3); ++j ) {
186 // pccconfig[configs].iowin += (uc[k+(2*j)+2]) << (8*j);
188 ++configs;
191 if ( pccsock[i].stringoffset > 0 ) { // If no identifier, it's not a valid CIS (as of documentation...)
192 printf ( "[" );
193 for ( k = 0; ( k < pccsock[i].stringlength ) && ( k < 64 ); ++k ) {
194 j = uc[pccsock[i].stringoffset + 2 * k];
195 printf ( "%c", (j>=' '? j:' ' ) );
197 printf ("]\n is type %d (", pccsock[i].type );
198 switch ( pccsock[i].type ) {
199 case 0x00:
200 printf ( "MULTI" ); break;
201 case 0x01:
202 printf ( "Memory" ); break;
203 case 0x02:
204 printf ( "Serial" ); break;
205 case 0x03:
206 printf ( "Parallel" ); break;
207 case 0x04:
208 printf ( "Fixed" ); break;
209 case 0x05:
210 printf ( "Video" ); break;
211 case 0x06:
212 printf ( "Network" ); break;
213 case 0x07:
214 printf ( "AIMS" ); break;
215 case 0x08:
216 printf ( "SCSI" ); break;
217 case 0x106: // Special / homebrew to say "Multi/network"
218 printf ( "MULTI, with Network" ); break; // AHTODO find a card for this
219 default:
220 printf ( "UNSUPPORTED/UNKNOWN" );
222 printf ( ") with %d possible configuration(s)\n", configs );
223 // Now set dependency: If it's Network or multi->network, accept
224 if ( (inited <= 0 ) && (6 == (0xff & pccsock[i].type) ) && (0 < configs ) ) {
225 printf ( "activating this device with ioport %x-%x (config #%d)\n",
226 pccconfig[0].iowin, pccconfig[0].iowin+pccconfig[0].iolen-1, pccconfig[0].index );
227 inited = i;
228 // And unmap attrmem ourselves!
229 printf ( "Activating config..." );
230 if ( m=driver[pccsock[i].drivernum].f(SELECTCONFIG,pccsock[i].internalid,pccconfig[0].index,0,&pccconfig[0]) ) {
231 printf ("Failure(%d)!",m); inited = -1;
232 driver[pccsock[i].drivernum].f(UNMAPATTRMEM,pccsock[i].internalid,0,0,0);
234 printf ( "done!\n" );
235 continue;
237 } else {
238 printf ( "unsupported - no identifier string found in CIS\n" );
240 // unmap the PCMCIA device
241 if ( i != inited ) {
242 if ( 0 != driver[pccsock[i].drivernum].f(UNMAPATTRMEM,pccsock[i].internalid,0,0,0) ) {
243 printf ("PCMCIA controller failed to unmap attribute memory.\n**** SEVERE ERROR CONDITION ****\n" );
244 if ( PDEBUG > 2 ) {
245 printf ( "<press key. THIS CONDITION SHOULD BE REPORTED!>\n" ); getchar();
247 continue;
251 if ( PDEBUG > 2 ) {
252 printf ( "<press key to exit the pcmcia_init_all routine>\n" );
253 getchar();
258 static void pcmcia_shutdown_all(void) {
259 int i;
260 //if ( PDEBUG > 2 ) {printf("<press key to continue>\n" ); getchar(); }
261 for ( i = 0; i < pccsocks; ++i ) {
262 driver[pccsock[i].drivernum].f(SHUTDOWN,pccsock[i].internalid,0,0,0);
264 printf("Shutdown of PCMCIA subsystem completed");
267 #endif