source: bootcd/isolinux/syslinux-6.03/gpxe/src/core/pcmcia.c

Last change on this file was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 8.7 KB
Line 
1#if 0
2
3/*
4 *      pcmcia.c
5 *
6 *      PCMCIA support routines for etherboot - generic stuff
7 *
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
13 *
14 *      Distributed under GPL2
15 */
16
17/*
18 *
19 *
20 *                      ******************************
21 *                      PLEASE DO NOT YET WORK ON THIS
22 *                      ******************************
23 *
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*
27 */
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>
36
37int     sockets; /* AHTODO: Phase this out! */
38u_int   pccsocks;
39struct  pccsock_t pccsock[MAXPCCSOCKS];
40int     inited = -1;
41struct  pcc_config_t pccconfig[MAXPCCCONFIGS];
42
43struct  driver_interact_t driver[] = {
44#ifdef  SUPPORT_I82365
45        { I82365, i82365_interfacer, "Intel_82365" },
46#endif
47};
48
49#define NUM_DRIVERS (sizeof(driver)/(sizeof(struct driver_interact_t)))
50
51void    sleepticks(int numticks ) {
52        u_int   tmo;
53        for (tmo = currticks()+numticks; currticks() < tmo; ) {
54        }
55        return;
56}
57
58static 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 );
67                }
68                printf ( "\n" );
69        }
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.
76        }
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;
82                }
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();
87                        }
88                        continue;
89                }
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;
99                        }
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
104                }
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)] );
120                                }
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);
126                                }
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);
130                                }
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)] );
141                                }
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;
150                                }
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;
156                                }
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;
164                                        }
165                                        k+=2;
166                                        if ( 0 != ( uc[k] & 0x0f ) ) {
167                                        //      printf ( "Don't support more than 1 iowin right now\n" );
168                                                continue;
169                                        }
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);
179                                        }
180                                        for ( n = 0; n < m; ++n, k+=2 ) {
181                                                pccconfig[configs].iolen += uc[k] << (n*8);
182                                        }
183                                        // printf ( "io %x len %d (%d)\n", pccconfig[configs].iowin, pccconfig[configs].iolen,configs );
184                                }
185                                for ( j = 0; j < (uc[k] & 3); ++j ) {
186                                //      pccconfig[configs].iowin += (uc[k+(2*j)+2]) << (8*j);
187                                }
188                                ++configs;
189                        }
190                }
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:' ' ) );
196                        }
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" );
221                        }
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);
233                                }
234                                printf ( "done!\n" );
235                                continue;
236                        }
237                } else {
238                        printf ( "unsupported - no identifier string found in CIS\n" );
239                }
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();
246                        }
247                        continue;
248                    }
249                }
250        }
251        if ( PDEBUG > 2 ) {
252                printf ( "<press key to exit the pcmcia_init_all routine>\n" );
253                getchar();
254        }
255
256}
257
258static 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);
263        }
264        printf("Shutdown of PCMCIA subsystem completed");
265}
266
267#endif
Note: See TracBrowser for help on using the repository browser.