~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/pcmcia/cs.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*======================================================================
  2 
  3     PCMCIA Card Services -- core services
  4 
  5     cs.c 1.271 2000/10/02 20:27:49
  6     
  7     The contents of this file are subject to the Mozilla Public
  8     License Version 1.1 (the "License"); you may not use this file
  9     except in compliance with the License. You may obtain a copy of
 10     the License at http://www.mozilla.org/MPL/
 11 
 12     Software distributed under the License is distributed on an "AS
 13     IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 14     implied. See the License for the specific language governing
 15     rights and limitations under the License.
 16 
 17     The initial developer of the original code is David A. Hinds
 18     <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
 19     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
 20 
 21     Alternatively, the contents of this file may be used under the
 22     terms of the GNU Public License version 2 (the "GPL"), in which
 23     case the provisions of the GPL are applicable instead of the
 24     above.  If you wish to allow the use of your version of this file
 25     only under the terms of the GPL and not to allow others to use
 26     your version of this file under the MPL, indicate your decision
 27     by deleting the provisions above and replace them with the notice
 28     and other provisions required by the GPL.  If you do not delete
 29     the provisions above, a recipient may use your version of this
 30     file under either the MPL or the GPL.
 31     
 32 ======================================================================*/
 33 
 34 #include <linux/module.h>
 35 #include <linux/init.h>
 36 #include <linux/kernel.h>
 37 #include <linux/config.h>
 38 #include <linux/string.h>
 39 #include <linux/major.h>
 40 #include <linux/errno.h>
 41 #include <linux/malloc.h>
 42 #include <linux/mm.h>
 43 #include <linux/sched.h>
 44 #include <linux/timer.h>
 45 #include <linux/ioport.h>
 46 #include <linux/delay.h>
 47 #include <linux/proc_fs.h>
 48 #include <linux/pm.h>
 49 #include <linux/pci.h>
 50 #include <asm/system.h>
 51 #include <asm/irq.h>
 52 
 53 #define IN_CARD_SERVICES
 54 #include <pcmcia/version.h>
 55 #include <pcmcia/cs_types.h>
 56 #include <pcmcia/ss.h>
 57 #include <pcmcia/cs.h>
 58 #include <pcmcia/bulkmem.h>
 59 #include <pcmcia/cistpl.h>
 60 #include <pcmcia/cisreg.h>
 61 #include <pcmcia/bus_ops.h>
 62 #include "cs_internal.h"
 63 #include "rsrc_mgr.h"
 64 
 65 #ifdef PCMCIA_DEBUG
 66 int pc_debug = PCMCIA_DEBUG;
 67 MODULE_PARM(pc_debug, "i");
 68 static const char *version =
 69 "cs.c 1.271 2000/10/02 20:27:49 (David Hinds)";
 70 #endif
 71 
 72 #ifdef CONFIG_PCI
 73 #define PCI_OPT " [pci]"
 74 #else
 75 #define PCI_OPT ""
 76 #endif
 77 #ifdef CONFIG_CARDBUS
 78 #define CB_OPT " [cardbus]"
 79 #else
 80 #define CB_OPT ""
 81 #endif
 82 #ifdef CONFIG_PM
 83 #define PM_OPT " [pm]"
 84 #else
 85 #define PM_OPT ""
 86 #endif
 87 #if !defined(CONFIG_CARDBUS) && !defined(CONFIG_PCI) && !defined(CONFIG_PM)
 88 #define OPTIONS " none"
 89 #else
 90 #define OPTIONS PCI_OPT CB_OPT PM_OPT
 91 #endif
 92 
 93 static const char *release = "Linux PCMCIA Card Services " CS_RELEASE;
 94 static const char *options = "options: " OPTIONS;
 95 
 96 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
 97 MODULE_DESCRIPTION("Linux PCMCIA Card Services " CS_RELEASE
 98                    "\n  options:" OPTIONS);
 99 
100 /*====================================================================*/
101 
102 /* Parameters that can be set with 'insmod' */
103 
104 #define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
105 
106 INT_MODULE_PARM(setup_delay,    10);            /* centiseconds */
107 INT_MODULE_PARM(resume_delay,   20);            /* centiseconds */
108 INT_MODULE_PARM(shutdown_delay, 3);             /* centiseconds */
109 INT_MODULE_PARM(vcc_settle,     40);            /* centiseconds */
110 INT_MODULE_PARM(reset_time,     10);            /* usecs */
111 INT_MODULE_PARM(unreset_delay,  10);            /* centiseconds */
112 INT_MODULE_PARM(unreset_check,  10);            /* centiseconds */
113 INT_MODULE_PARM(unreset_limit,  30);            /* unreset_check's */
114 
115 /* Access speed for attribute memory windows */
116 INT_MODULE_PARM(cis_speed,      300);           /* ns */
117 
118 /* Access speed for IO windows */
119 INT_MODULE_PARM(io_speed,       0);             /* ns */
120 
121 /* Optional features */
122 #ifdef CONFIG_PM
123 INT_MODULE_PARM(do_apm,         1);
124 #else
125 INT_MODULE_PARM(do_apm,         0);
126 #endif
127 
128 /*====================================================================*/
129 
130 socket_state_t dead_socket = {
131     0, SS_DETECT, 0, 0, 0
132 };
133 
134 /* Table of sockets */
135 socket_t sockets = 0;
136 socket_info_t *socket_table[MAX_SOCK];
137 
138 #ifdef CONFIG_PROC_FS
139 struct proc_dir_entry *proc_pccard = NULL;
140 #endif
141 
142 /*====================================================================*/
143 
144 /* String tables for error messages */
145 
146 typedef struct lookup_t {
147     int key;
148     char *msg;
149 } lookup_t;
150 
151 static const lookup_t error_table[] = {
152     { CS_SUCCESS,               "Operation succeeded" },
153     { CS_BAD_ADAPTER,           "Bad adapter" },
154     { CS_BAD_ATTRIBUTE,         "Bad attribute", },
155     { CS_BAD_BASE,              "Bad base address" },
156     { CS_BAD_EDC,               "Bad EDC" },
157     { CS_BAD_IRQ,               "Bad IRQ" },
158     { CS_BAD_OFFSET,            "Bad offset" },
159     { CS_BAD_PAGE,              "Bad page number" },
160     { CS_READ_FAILURE,          "Read failure" },
161     { CS_BAD_SIZE,              "Bad size" },
162     { CS_BAD_SOCKET,            "Bad socket" },
163     { CS_BAD_TYPE,              "Bad type" },
164     { CS_BAD_VCC,               "Bad Vcc" },
165     { CS_BAD_VPP,               "Bad Vpp" },
166     { CS_BAD_WINDOW,            "Bad window" },
167     { CS_WRITE_FAILURE,         "Write failure" },
168     { CS_NO_CARD,               "No card present" },
169     { CS_UNSUPPORTED_FUNCTION,  "Usupported function" },
170     { CS_UNSUPPORTED_MODE,      "Unsupported mode" },
171     { CS_BAD_SPEED,             "Bad speed" },
172     { CS_BUSY,                  "Resource busy" },
173     { CS_GENERAL_FAILURE,       "General failure" },
174     { CS_WRITE_PROTECTED,       "Write protected" },
175     { CS_BAD_ARG_LENGTH,        "Bad argument length" },
176     { CS_BAD_ARGS,              "Bad arguments" },
177     { CS_CONFIGURATION_LOCKED,  "Configuration locked" },
178     { CS_IN_USE,                "Resource in use" },
179     { CS_NO_MORE_ITEMS,         "No more items" },
180     { CS_OUT_OF_RESOURCE,       "Out of resource" },
181     { CS_BAD_HANDLE,            "Bad handle" },
182     { CS_BAD_TUPLE,             "Bad CIS tuple" }
183 };
184 #define ERROR_COUNT (sizeof(error_table)/sizeof(lookup_t))
185 
186 static const lookup_t service_table[] = {
187     { AccessConfigurationRegister,      "AccessConfigurationRegister" },
188     { AddSocketServices,                "AddSocketServices" },
189     { AdjustResourceInfo,               "AdjustResourceInfo" },
190     { CheckEraseQueue,                  "CheckEraseQueue" },
191     { CloseMemory,                      "CloseMemory" },
192     { DeregisterClient,                 "DeregisterClient" },
193     { DeregisterEraseQueue,             "DeregisterEraseQueue" },
194     { GetCardServicesInfo,              "GetCardServicesInfo" },
195     { GetClientInfo,                    "GetClientInfo" },
196     { GetConfigurationInfo,             "GetConfigurationInfo" },
197     { GetEventMask,                     "GetEventMask" },
198     { GetFirstClient,                   "GetFirstClient" },
199     { GetFirstRegion,                   "GetFirstRegion" },
200     { GetFirstTuple,                    "GetFirstTuple" },
201     { GetNextClient,                    "GetNextClient" },
202     { GetNextRegion,                    "GetNextRegion" },
203     { GetNextTuple,                     "GetNextTuple" },
204     { GetStatus,                        "GetStatus" },
205     { GetTupleData,                     "GetTupleData" },
206     { MapMemPage,                       "MapMemPage" },
207     { ModifyConfiguration,              "ModifyConfiguration" },
208     { ModifyWindow,                     "ModifyWindow" },
209     { OpenMemory,                       "OpenMemory" },
210     { ParseTuple,                       "ParseTuple" },
211     { ReadMemory,                       "ReadMemory" },
212     { RegisterClient,                   "RegisterClient" },
213     { RegisterEraseQueue,               "RegisterEraseQueue" },
214     { RegisterMTD,                      "RegisterMTD" },
215     { ReleaseConfiguration,             "ReleaseConfiguration" },
216     { ReleaseIO,                        "ReleaseIO" },
217     { ReleaseIRQ,                       "ReleaseIRQ" },
218     { ReleaseWindow,                    "ReleaseWindow" },
219     { RequestConfiguration,             "RequestConfiguration" },
220     { RequestIO,                        "RequestIO" },
221     { RequestIRQ,                       "RequestIRQ" },
222     { RequestSocketMask,                "RequestSocketMask" },
223     { RequestWindow,                    "RequestWindow" },
224     { ResetCard,                        "ResetCard" },
225     { SetEventMask,                     "SetEventMask" },
226     { ValidateCIS,                      "ValidateCIS" },
227     { WriteMemory,                      "WriteMemory" },
228     { BindDevice,                       "BindDevice" },
229     { BindMTD,                          "BindMTD" },
230     { ReportError,                      "ReportError" },
231     { SuspendCard,                      "SuspendCard" },
232     { ResumeCard,                       "ResumeCard" },
233     { EjectCard,                        "EjectCard" },
234     { InsertCard,                       "InsertCard" },
235     { ReplaceCIS,                       "ReplaceCIS" }
236 };
237 #define SERVICE_COUNT (sizeof(service_table)/sizeof(lookup_t))
238 
239 /*======================================================================
240 
241  These functions are just shorthand for the actual low-level drivers
242 
243 ======================================================================*/
244 
245 static int register_callback(socket_info_t *s, void (*handler)(void *, unsigned int), void * info)
246 {
247         return s->ss_entry->register_callback(s->sock, handler, info);
248 }
249 
250 static int get_socket_status(socket_info_t *s, int *val)
251 {
252         return s->ss_entry->get_status(s->sock, val);
253 }
254 
255 static int set_socket(socket_info_t *s, socket_state_t *state)
256 {
257         return s->ss_entry->set_socket(s->sock, state);
258 }
259 
260 static int set_io_map(socket_info_t *s, struct pccard_io_map *io)
261 {
262         return s->ss_entry->set_io_map(s->sock, io);
263 }
264 
265 static int set_mem_map(socket_info_t *s, struct pccard_mem_map *mem)
266 {
267         return s->ss_entry->set_mem_map(s->sock, mem);
268 }
269 
270 static int suspend_socket(socket_info_t *s)
271 {
272         s->socket = dead_socket;
273         return s->ss_entry->suspend(s->sock);
274 }
275 
276 static int init_socket(socket_info_t *s)
277 {
278         s->socket = dead_socket;
279         return s->ss_entry->init(s->sock);
280 }
281 
282 /*====================================================================*/
283 
284 #if defined(CONFIG_PROC_FS) && defined(PCMCIA_DEBUG)
285 static int proc_read_clients(char *buf, char **start, off_t pos,
286                              int count, int *eof, void *data)
287 {
288     socket_info_t *s = data;
289     client_handle_t c;
290     char *p = buf;
291 
292     for (c = s->clients; c; c = c->next)
293         p += sprintf(p, "fn %x: '%s' [attr 0x%04x] [state 0x%04x]\n",
294                      c->Function, c->dev_info, c->Attributes, c->state);
295     return (p - buf);
296 }
297 #endif
298 
299 /*======================================================================
300 
301     Low-level PC Card interface drivers need to register with Card
302     Services using these calls.
303     
304 ======================================================================*/
305 
306 static int setup_socket(socket_info_t *);
307 static void shutdown_socket(socket_info_t *);
308 static void reset_socket(socket_info_t *);
309 static void unreset_socket(socket_info_t *);
310 static void parse_events(void *info, u_int events);
311 
312 socket_info_t *pcmcia_register_socket (int slot,
313         struct pccard_operations * ss_entry,
314         int use_bus_pm)
315 {
316     socket_info_t *s;
317     int i;
318 
319     DEBUG(0, "cs: pcmcia_register_socket(0x%p)\n", ss_entry);
320 
321     s = kmalloc(sizeof(struct socket_info_t), GFP_KERNEL);
322     if (!s)
323         return NULL;
324     memset(s, 0, sizeof(socket_info_t));
325 
326     s->ss_entry = ss_entry;
327     s->sock = slot;
328 
329     /* base address = 0, map = 0 */
330     s->cis_mem.flags = 0;
331     s->cis_mem.speed = cis_speed;
332     s->use_bus_pm = use_bus_pm;
333     s->erase_busy.next = s->erase_busy.prev = &s->erase_busy;
334     spin_lock_init(&s->lock);
335     
336     for (i = 0; i < sockets; i++)
337         if (socket_table[i] == NULL) break;
338     socket_table[i] = s;
339     if (i == sockets) sockets++;
340 
341     init_socket(s);
342     ss_entry->inquire_socket(slot, &s->cap);
343 #ifdef CONFIG_PROC_FS
344     if (proc_pccard) {
345         char name[3];
346         sprintf(name, "%02d", i);
347         s->proc = proc_mkdir(name, proc_pccard);
348         if (s->proc)
349             ss_entry->proc_setup(slot, s->proc);
350 #ifdef PCMCIA_DEBUG
351         if (s->proc)
352             create_proc_read_entry("clients", 0, s->proc,
353                                    proc_read_clients, s);
354 #endif
355     }
356 #endif
357     return s;
358 } /* pcmcia_register_socket */
359 
360 int register_ss_entry(int nsock, struct pccard_operations * ss_entry)
361 {
362     int ns;
363 
364     DEBUG(0, "cs: register_ss_entry(%d, 0x%p)\n", nsock, ss_entry);
365 
366     for (ns = 0; ns < nsock; ns++) {
367         pcmcia_register_socket (ns, ss_entry, 0);
368     }
369     
370     return 0;
371 } /* register_ss_entry */
372 
373 /*====================================================================*/
374 
375 void pcmcia_unregister_socket(socket_info_t *s)
376 {
377     int j, socket = -1;
378     client_t *client;
379 
380     for (j = 0; j < MAX_SOCK; j++)
381         if (socket_table [j] == s) {
382             socket = j;
383             break;
384         }
385     if (socket < 0)
386         return;
387 
388 #ifdef CONFIG_PROC_FS
389     if (proc_pccard) {
390         char name[3];
391         sprintf(name, "%02d", socket);
392 #ifdef PCMCIA_DEBUG
393         remove_proc_entry("clients", s->proc);
394 #endif
395         remove_proc_entry(name, proc_pccard);
396     }
397 #endif
398 
399     shutdown_socket(s);
400     release_cis_mem(s);
401     while (s->clients) {
402         client = s->clients;
403         s->clients = s->clients->next;
404         kfree(client);
405     }
406     s->ss_entry = NULL;
407     kfree(s);
408 
409     socket_table[socket] = NULL;
410     for (j = socket; j < sockets-1; j++)
411         socket_table[j] = socket_table[j+1];
412     sockets--;
413 } /* pcmcia_unregister_socket */
414 
415 void unregister_ss_entry(struct pccard_operations * ss_entry)
416 {
417     int i;
418 
419     for (i = sockets-1; i >= 0; i-- ) {
420         socket_info_t *socket = socket_table[i];
421         if (socket->ss_entry == ss_entry)
422                 pcmcia_unregister_socket (socket);
423     }
424 } /* unregister_ss_entry */
425 
426 /*======================================================================
427 
428     Shutdown_Socket() and setup_socket() are scheduled using add_timer
429     calls by the main event handler when card insertion and removal
430     events are received.  Shutdown_Socket() unconfigures a socket and
431     turns off socket power.  Setup_socket() turns on socket power
432     and resets the socket, in two stages.
433 
434 ======================================================================*/
435 
436 static void free_regions(memory_handle_t *list)
437 {
438     memory_handle_t tmp;
439     while (*list != NULL) {
440         tmp = *list;
441         *list = tmp->info.next;
442         tmp->region_magic = 0;
443         kfree(tmp);
444     }
445 }
446 
447 static int send_event(socket_info_t *s, event_t event, int priority);
448 
449 /*
450  * Sleep for n_cs centiseconds (1 cs = 1/100th of a second)
451  */
452 static void cs_sleep(unsigned int n_cs)
453 {
454         current->state = TASK_INTERRUPTIBLE;
455         schedule_timeout( (n_cs * HZ + 99) / 100);
456 }
457 
458 static void shutdown_socket(socket_info_t *s)
459 {
460     client_t **c;
461     
462     DEBUG(1, "cs: shutdown_socket(%p)\n", s);
463 
464     /* Blank out the socket state */
465     s->state &= SOCKET_PRESENT|SOCKET_SETUP_PENDING;
466     init_socket(s);
467     s->irq.AssignedIRQ = s->irq.Config = 0;
468     s->lock_count = 0;
469     s->cis_used = 0;
470     if (s->fake_cis) {
471         kfree(s->fake_cis);
472         s->fake_cis = NULL;
473     }
474 #ifdef CONFIG_CARDBUS
475     cb_release_cis_mem(s);
476     cb_free(s);
477 #endif
478     s->functions = 0;
479     if (s->config) {
480         kfree(s->config);
481         s->config = NULL;
482     }
483     for (c = &s->clients; *c; ) {
484         if ((*c)->state & CLIENT_UNBOUND) {
485             client_t *d = *c;
486             *c = (*c)->next;
487             kfree(d);
488         } else {
489             c = &((*c)->next);
490         }
491     }
492     free_regions(&s->a_region);
493     free_regions(&s->c_region);
494 } /* shutdown_socket */
495 
496 /*
497  * Return zero if we think the card isn't actually present
498  */
499 static int setup_socket(socket_info_t *s)
500 {
501         int val, ret;
502         int setup_timeout = 100;
503 
504         /* Wait for "not pending" */
505         for (;;) {
506                 get_socket_status(s, &val);
507                 if (!(val & SS_PENDING))
508                         break;
509                 if (--setup_timeout) {
510                         cs_sleep(10);
511                         continue;
512                 }
513                 printk(KERN_NOTICE "cs: socket %p voltage interrogation"
514                         " timed out\n", s);
515                 ret = 0;
516                 goto out;
517         }
518 
519         if (val & SS_DETECT) {
520                 DEBUG(1, "cs: setup_socket(%p): applying power\n", s);
521                 s->state |= SOCKET_PRESENT;
522                 s->socket.flags &= SS_DEBOUNCED;
523                 if (val & SS_3VCARD)
524                     s->socket.Vcc = s->socket.Vpp = 33;
525                 else if (!(val & SS_XVCARD))
526                     s->socket.Vcc = s->socket.Vpp = 50;
527                 else {
528                     printk(KERN_NOTICE "cs: socket %p: unsupported "
529                            "voltage key\n", s);
530                     s->socket.Vcc = 0;
531                 }
532                 if (val & SS_CARDBUS) {
533                     s->state |= SOCKET_CARDBUS;
534 #ifndef CONFIG_CARDBUS
535                     printk(KERN_NOTICE "cs: unsupported card type detected!\n");
536 #endif
537                 }
538                 set_socket(s, &s->socket);
539                 cs_sleep(vcc_settle);
540                 reset_socket(s);
541                 ret = 1;
542         } else {
543                 DEBUG(0, "cs: setup_socket(%p): no card!\n", s);
544                 ret = 0;
545         }
546 out:
547         return ret;
548 } /* setup_socket */
549 
550 /*======================================================================
551 
552     Reset_socket() and unreset_socket() handle hard resets.  Resets
553     have several causes: card insertion, a call to reset_socket, or
554     recovery from a suspend/resume cycle.  Unreset_socket() sends
555     a CS event that matches the cause of the reset.
556     
557 ======================================================================*/
558 
559 static void reset_socket(socket_info_t *s)
560 {
561     DEBUG(1, "cs: resetting socket %p\n", s);
562     s->socket.flags |= SS_OUTPUT_ENA | SS_RESET;
563     set_socket(s, &s->socket);
564     udelay((long)reset_time);
565     s->socket.flags &= ~SS_RESET;
566     set_socket(s, &s->socket);
567     cs_sleep(unreset_delay);
568     unreset_socket(s);
569 } /* reset_socket */
570 
571 #define EVENT_MASK \
572 (SOCKET_SETUP_PENDING|SOCKET_SUSPEND|SOCKET_RESET_PENDING)
573 
574 static void unreset_socket(socket_info_t *s)
575 {
576         int setup_timeout = unreset_limit;
577         int val;
578 
579         /* Wait for "ready" */
580         for (;;) {
581                 get_socket_status(s, &val);
582                 if (val & SS_READY)
583                         break;
584                 DEBUG(2, "cs: socket %d not ready yet\n", s->sock);
585                 if (--setup_timeout) {
586                         cs_sleep(unreset_check);
587                         continue;
588                 }
589                 printk(KERN_NOTICE "cs: socket %p timed out during"
590                         " reset.  Try increasing setup_delay.\n", s);
591                 s->state &= ~EVENT_MASK;
592                 return;
593         }
594 
595         DEBUG(1, "cs: reset done on socket %p\n", s);
596         if (s->state & SOCKET_SUSPEND) {
597             s->state &= ~EVENT_MASK;
598             if (verify_cis_cache(s) != 0)
599                 parse_events(s, SS_DETECT);
600             else
601                 send_event(s, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW);
602         } else if (s->state & SOCKET_SETUP_PENDING) {
603 #ifdef CONFIG_CARDBUS
604             if (s->state & SOCKET_CARDBUS)
605                 cb_alloc(s);
606 #endif
607             send_event(s, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
608             s->state &= ~SOCKET_SETUP_PENDING;
609         } else {
610             send_event(s, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW);
611             if (s->reset_handle) { 
612                     s->reset_handle->event_callback_args.info = NULL;
613                     EVENT(s->reset_handle, CS_EVENT_RESET_COMPLETE,
614                           CS_EVENT_PRI_LOW);
615             }
616             s->state &= ~EVENT_MASK;
617         }
618 } /* unreset_socket */
619 
620 /*======================================================================
621 
622     The central event handler.  Send_event() sends an event to all
623     valid clients.  Parse_events() interprets the event bits from
624     a card status change report.  Do_shotdown() handles the high
625     priority stuff associated with a card removal.
626     
627 ======================================================================*/
628 
629 static int send_event(socket_info_t *s, event_t event, int priority)
630 {
631     client_t *client = s->clients;
632     int ret;
633     DEBUG(1, "cs: send_event(sock %d, event %d, pri %d)\n",
634           s->sock, event, priority);
635     ret = 0;
636     for (; client; client = client->next) { 
637         if (client->state & (CLIENT_UNBOUND|CLIENT_STALE))
638             continue;
639         if (client->EventMask & event) {
640             ret = EVENT(client, event, priority);
641             if (ret != 0)
642                 return ret;
643         }
644     }
645     return ret;
646 } /* send_event */
647 
648 static void do_shutdown(socket_info_t *s)
649 {
650     client_t *client;
651     if (s->state & SOCKET_SHUTDOWN_PENDING)
652         return;
653     s->state |= SOCKET_SHUTDOWN_PENDING;
654     send_event(s, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
655     for (client = s->clients; client; client = client->next)
656         if (!(client->Attributes & INFO_MASTER_CLIENT))
657             client->state |= CLIENT_STALE;
658     if (s->state & (SOCKET_SETUP_PENDING|SOCKET_RESET_PENDING)) {
659         DEBUG(0, "cs: flushing pending setup\n");
660         s->state &= ~EVENT_MASK;
661     }
662     cs_sleep(shutdown_delay);
663     s->state &= ~SOCKET_PRESENT;
664     shutdown_socket(s);
665 }
666 
667 static void parse_events(void *info, u_int events)
668 {
669     socket_info_t *s = info;
670     if (events & SS_DETECT) {
671         int status;
672 
673         get_socket_status(s, &status);
674         if ((s->state & SOCKET_PRESENT) &&
675             (!(s->state & SOCKET_SUSPEND) ||
676              !(status & SS_DETECT)))
677             do_shutdown(s);
678         if (status & SS_DETECT) {
679             if (s->state & SOCKET_SETUP_PENDING) {
680                 DEBUG(1, "cs: delaying pending setup\n");
681                 return;
682             }
683             s->state |= SOCKET_SETUP_PENDING;
684             if (s->state & SOCKET_SUSPEND)
685                 cs_sleep(resume_delay);
686             else
687                 cs_sleep(setup_delay);
688             s->socket.flags |= SS_DEBOUNCED;
689             if (setup_socket(s) == 0)
690                 s->state &= ~SOCKET_SETUP_PENDING;
691             s->socket.flags &= ~SS_DEBOUNCED;
692         }
693     }
694     if (events & SS_BATDEAD)
695         send_event(s, CS_EVENT_BATTERY_DEAD, CS_EVENT_PRI_LOW);
696     if (events & SS_BATWARN)
697         send_event(s, CS_EVENT_BATTERY_LOW, CS_EVENT_PRI_LOW);
698     if (events & SS_READY) {
699         if (!(s->state & SOCKET_RESET_PENDING))
700             send_event(s, CS_EVENT_READY_CHANGE, CS_EVENT_PRI_LOW);
701         else DEBUG(1, "cs: ready change during reset\n");
702     }
703 } /* parse_events */
704 
705 /*======================================================================
706 
707     Another event handler, for power management events.
708 
709     This does not comply with the latest PC Card spec for handling
710     power management events.
711     
712 ======================================================================*/
713 
714 void pcmcia_suspend_socket (socket_info_t *s)
715 {
716     if ((s->state & SOCKET_PRESENT) && !(s->state & SOCKET_SUSPEND)) {
717         send_event(s, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW);
718         suspend_socket(s);
719         s->state |= SOCKET_SUSPEND;
720     }
721 }
722 
723 void pcmcia_resume_socket (socket_info_t *s)
724 {
725     int stat;
726 
727     /* Do this just to reinitialize the socket */
728     init_socket(s);
729     get_socket_status(s, &stat);
730 
731     /* If there was or is a card here, we need to do something
732     about it... but parse_events will sort it all out. */
733     if ((s->state & SOCKET_PRESENT) || (stat & SS_DETECT))
734         parse_events(s, SS_DETECT);
735 }
736 
737 static int handle_pm_event(struct pm_dev *dev, pm_request_t rqst, void *data)
738 {
739     int i;
740     socket_info_t *s;
741 
742     /* only for busses that don't suspend/resume slots directly */
743 
744     switch (rqst) {
745     case PM_SUSPEND:
746         DEBUG(1, "cs: received suspend notification\n");
747         for (i = 0; i < sockets; i++) {
748             s = socket_table [i];
749             if (!s->use_bus_pm)
750                 pcmcia_suspend_socket (socket_table [i]);
751         }
752         break;
753     case PM_RESUME:
754         DEBUG(1, "cs: received resume notification\n");
755         for (i = 0; i < sockets; i++) {
756             s = socket_table [i];
757             if (!s->use_bus_pm)
758                 pcmcia_resume_socket (socket_table [i]);
759         }
760         break;
761     }
762     return 0;
763 } /* handle_pm_event */
764 
765 /*======================================================================
766 
767     Special stuff for managing IO windows, because they are scarce.
768     
769 ======================================================================*/
770 
771 static int alloc_io_space(socket_info_t *s, u_int attr, ioaddr_t *base,
772                           ioaddr_t num, u_int lines, char *name)
773 {
774     int i;
775     ioaddr_t try, align;
776 
777     align = (*base) ? (lines ? 1<<lines : 0) : 1;
778     if (align && (align < num)) {
779         if (*base) {
780             DEBUG(0, "odd IO request: num %04x align %04x\n",
781                   num, align);
782             align = 0;
783         } else
784             while (align && (align < num)) align <<= 1;
785     }
786     if (*base & ~(align-1)) {
787         DEBUG(0, "odd IO request: base %04x align %04x\n",
788               *base, align);
789         align = 0;
790     }
791     /* Check for an already-allocated window that must conflict with
792        what was asked for.  It is a hack because it does not catch all
793        potential conflicts, just the most obvious ones. */
794     for (i = 0; i < MAX_IO_WIN; i++)
795         if ((s->io[i].NumPorts != 0) &&
796             ((s->io[i].BasePort & (align-1)) == *base))
797             return 1;
798     for (i = 0; i < MAX_IO_WIN; i++) {
799         if (s->io[i].NumPorts == 0) {
800             if (find_io_region(base, num, align, name) == 0) {
801                 s->io[i].Attributes = attr;
802                 s->io[i].BasePort = *base;
803                 s->io[i].NumPorts = s->io[i].InUse = num;
804                 break;
805             } else
806                 return 1;
807         } else if (s->io[i].Attributes != attr)
808             continue;
809         /* Try to extend top of window */
810         try = s->io[i].BasePort + s->io[i].NumPorts;
811         if ((*base == 0) || (*base == try))
812             if (find_io_region(&try, num, 0, name) == 0) {
813                 *base = try;
814                 s->io[i].NumPorts += num;
815                 s->io[i].InUse += num;
816                 break;
817             }
818         /* Try to extend bottom of window */
819         try = s->io[i].BasePort - num;
820         if ((*base == 0) || (*base == try))
821             if (find_io_region(&try, num, 0, name) == 0) {
822                 s->io[i].BasePort = *base = try;
823                 s->io[i].NumPorts += num;
824                 s->io[i].InUse += num;
825                 break;
826             }
827     }
828     return (i == MAX_IO_WIN);
829 } /* alloc_io_space */
830 
831 static void release_io_space(socket_info_t *s, ioaddr_t base,
832                              ioaddr_t num)
833 {
834     int i;
835     release_region(base, num);
836     for (i = 0; i < MAX_IO_WIN; i++) {
837         if ((s->io[i].BasePort <= base) &&
838             (s->io[i].BasePort+s->io[i].NumPorts >= base+num)) {
839             s->io[i].InUse -= num;
840             /* Free the window if no one else is using it */
841             if (s->io[i].InUse == 0)
842                 s->io[i].NumPorts = 0;
843         }
844     }
845 }
846 
847 /*======================================================================
848 
849     Access_configuration_register() reads and writes configuration
850     registers in attribute memory.  Memory window 0 is reserved for
851     this and the tuple reading services.
852     
853 ======================================================================*/
854 
855 int pcmcia_access_configuration_register(client_handle_t handle,
856                                          conf_reg_t *reg)
857 {
858     socket_info_t *s;
859     config_t *c;
860     int addr;
861     u_char val;
862     
863     if (CHECK_HANDLE(handle))
864         return CS_BAD_HANDLE;
865     s = SOCKET(handle);
866     if (handle->Function == BIND_FN_ALL) {
867         if (reg->Function >= s->functions)
868             return CS_BAD_ARGS;
869         c = &s->config[reg->Function];
870     } else
871         c = CONFIG(handle);
872     if (!(c->state & CONFIG_LOCKED))
873         return CS_CONFIGURATION_LOCKED;
874 
875     addr = (c->ConfigBase + reg->Offset) >> 1;
876     
877     switch (reg->Action) {
878     case CS_READ:
879         read_cis_mem(s, 1, addr, 1, &val);
880         reg->Value = val;
881         break;
882     case CS_WRITE:
883         val = reg->Value;
884         write_cis_mem(s, 1, addr, 1, &val);
885         break;
886     default:
887         return CS_BAD_ARGS;
888         break;
889     }
890     return CS_SUCCESS;
891 } /* access_configuration_register */
892 
893 /*======================================================================
894 
895     Bind_device() associates a device driver with a particular socket.
896     It is normally called by Driver Services after it has identified
897     a newly inserted card.  An instance of that driver will then be
898     eligible to register as a client of this socket.
899     
900 ======================================================================*/
901 
902 int pcmcia_bind_device(bind_req_t *req)
903 {
904     client_t *client;
905     socket_info_t *s;
906 
907     if (CHECK_SOCKET(req->Socket))
908         return CS_BAD_SOCKET;
909     s = SOCKET(req);
910 
911     client = (client_t *)kmalloc(sizeof(client_t), GFP_KERNEL);
912     if (!client) return CS_OUT_OF_RESOURCE;
913     memset(client, '\0', sizeof(client_t));
914     client->client_magic = CLIENT_MAGIC;
915     strncpy(client->dev_info, (char *)req->dev_info, DEV_NAME_LEN);
916     client->Socket = req->Socket;
917     client->Function = req->Function;
918     client->state = CLIENT_UNBOUND;
919     client->erase_busy.next = &client->erase_busy;
920     client->erase_busy.prev = &client->erase_busy;
921     init_waitqueue_head(&client->mtd_req);
922     client->next = s->clients;
923     s->clients = client;
924     DEBUG(1, "cs: bind_device(): client 0x%p, sock %d, dev %s\n",
925           client, client->Socket, client->dev_info);
926     return CS_SUCCESS;
927 } /* bind_device */
928 
929 /*======================================================================
930 
931     Bind_mtd() associates a device driver with a particular memory
932     region.  It is normally called by Driver Services after it has
933     identified a memory device type.  An instance of the corresponding
934     driver will then be able to register to control this region.
935     
936 ======================================================================*/
937 
938 int pcmcia_bind_mtd(mtd_bind_t *req)
939 {
940     socket_info_t *s;
941     memory_handle_t region;
942     
943     if (CHECK_SOCKET(req->Socket))
944         return CS_BAD_SOCKET;
945     s = SOCKET(req);
946     
947     if (req->Attributes & REGION_TYPE_AM)
948         region = s->a_region;
949     else
950         region = s->c_region;
951     
952     while (region) {
953         if (region->info.CardOffset == req->CardOffset) break;
954         region = region->info.next;
955     }
956     if (!region || (region->mtd != NULL))
957         return CS_BAD_OFFSET;
958     strncpy(region->dev_info, (char *)req->dev_info, DEV_NAME_LEN);
959     
960     DEBUG(1, "cs: bind_mtd(): attr 0x%x, offset 0x%x, dev %s\n",
961           req->Attributes, req->CardOffset, (char *)req->dev_info);
962     return CS_SUCCESS;
963 } /* bind_mtd */
964 
965 /*====================================================================*/
966 
967 int pcmcia_deregister_client(client_handle_t handle)
968 {
969     client_t **client;
970     socket_info_t *s;
971     memory_handle_t region;
972     u_long flags;
973     int i, sn;
974     
975     DEBUG(1, "cs: deregister_client(%p)\n", handle);
976     if (CHECK_HANDLE(handle))
977         return CS_BAD_HANDLE;
978     if (handle->state &
979         (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
980         return CS_IN_USE;
981     for (i = 0; i < MAX_WIN; i++)
982         if (handle->state & CLIENT_WIN_REQ(i))
983             return CS_IN_USE;
984 
985     /* Disconnect all MTD links */
986     s = SOCKET(handle);
987     if (handle->mtd_count) {
988         for (region = s->a_region; region; region = region->info.next)
989             if (region->mtd == handle) region->mtd = NULL;
990         for (region = s->c_region; region; region = region->info.next)
991             if (region->mtd == handle) region->mtd = NULL;
992     }
993     
994     sn = handle->Socket; s = socket_table[sn];
995 
996     if ((handle->state & CLIENT_STALE) ||
997         (handle->Attributes & INFO_MASTER_CLIENT)) {
998         spin_lock_irqsave(&s->lock, flags);
999         client = &s->clients;
1000         while ((*client) && ((*client) != handle))
1001             client = &(*client)->next;
1002         if (*client == NULL) {
1003             spin_unlock_irqrestore(&s->lock, flags);
1004             return CS_BAD_HANDLE;
1005         }
1006         *client = handle->next;
1007         handle->client_magic = 0;
1008         kfree(handle);
1009         spin_unlock_irqrestore(&s->lock, flags);
1010     } else {
1011         handle->state = CLIENT_UNBOUND;
1012         handle->mtd_count = 0;
1013         handle->event_handler = NULL;
1014     }
1015 
1016     if (--s->real_clients == 0)
1017         register_callback(s, NULL, NULL);
1018     
1019     return CS_SUCCESS;
1020 } /* deregister_client */
1021 
1022 /*====================================================================*/
1023 
1024 int pcmcia_get_configuration_info(client_handle_t handle,
1025                                   config_info_t *config)
1026 {
1027     socket_info_t *s;
1028     config_t *c;
1029     
1030     if (CHECK_HANDLE(handle))
1031         return CS_BAD_HANDLE;
1032     s = SOCKET(handle);
1033     if (!(s->state & SOCKET_PRESENT))
1034         return CS_NO_CARD;
1035 
1036     if (handle->Function == BIND_FN_ALL) {
1037         if (config->Function && (config->Function >= s->functions))
1038             return CS_BAD_ARGS;
1039     } else
1040         config->Function = handle->Function;
1041     
1042 #ifdef CONFIG_CARDBUS
1043     if (s->state & SOCKET_CARDBUS) {
1044         u_char fn = config->Function;
1045         memset(config, 0, sizeof(config_info_t));
1046         config->Function = fn;
1047         config->Vcc = s->socket.Vcc;
1048         config->Vpp1 = config->Vpp2 = s->socket.Vpp;
1049         config->Option = s->cap.cb_dev->subordinate->number;
1050         if (s->cb_config) {
1051             config->Attributes = CONF_VALID_CLIENT;
1052             config->IntType = INT_CARDBUS;
1053             config->AssignedIRQ = s->irq.AssignedIRQ;
1054             if (config->AssignedIRQ)
1055                 config->Attributes |= CONF_ENABLE_IRQ;
1056             config->BasePort1 = s->io[0].BasePort;
1057             config->NumPorts1 = s->io[0].NumPorts;
1058         }
1059         return CS_SUCCESS;
1060     }
1061 #endif
1062     
1063     c = (s->config != NULL) ? &s->config[config->Function] : NULL;
1064     
1065     if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {
1066         config->Attributes = 0;
1067         config->Vcc = s->socket.Vcc;
1068         config->Vpp1 = config->Vpp2 = s->socket.Vpp;
1069         return CS_SUCCESS;
1070     }
1071     
1072     /* !!! This is a hack !!! */
1073     memcpy(&config->Attributes, &c->Attributes, sizeof(config_t));
1074     config->Attributes |= CONF_VALID_CLIENT;
1075     config->CardValues = c->CardValues;
1076     config->IRQAttributes = c->irq.Attributes;
1077     config->AssignedIRQ = s->irq.AssignedIRQ;
1078     config->BasePort1 = c->io.BasePort1;
1079     config->NumPorts1 = c->io.NumPorts1;
1080     config->Attributes1 = c->io.Attributes1;
1081     config->BasePort2 = c->io.BasePort2;
1082     config->NumPorts2 = c->io.NumPorts2;
1083     config->Attributes2 = c->io.Attributes2;
1084     config->IOAddrLines = c->io.IOAddrLines;
1085     
1086     return CS_SUCCESS;
1087 } /* get_configuration_info */
1088 
1089 /*======================================================================
1090 
1091     Return information about this version of Card Services.
1092     
1093 ======================================================================*/
1094 
1095 int pcmcia_get_card_services_info(servinfo_t *info)
1096 {
1097     info->Signature[0] = 'C';
1098     info->Signature[1] = 'S';
1099     info->Count = sockets;
1100     info->Revision = CS_RELEASE_CODE;
1101     info->CSLevel = 0x0210;
1102     info->VendorString = (char *)release;
1103     return CS_SUCCESS;
1104 } /* get_card_services_info */
1105 
1106 /*======================================================================
1107 
1108     Note that get_first_client() *does* recognize the Socket field
1109     in the request structure.
1110     
1111 ======================================================================*/
1112 
1113 int pcmcia_get_first_client(client_handle_t *handle, client_req_t *req)
1114 {
1115     socket_t s;
1116     if (req->Attributes & CLIENT_THIS_SOCKET)
1117         s = req->Socket;
1118     else
1119         s = 0;
1120     if (CHECK_SOCKET(req->Socket))
1121         return CS_BAD_SOCKET;
1122     if (socket_table[s]->clients == NULL)
1123         return CS_NO_MORE_ITEMS;
1124     *handle = socket_table[s]->clients;
1125     return CS_SUCCESS;
1126 } /* get_first_client */
1127 
1128 /*====================================================================*/
1129 
1130 int pcmcia_get_next_client(client_handle_t *handle, client_req_t *req)
1131 {
1132     socket_info_t *s;
1133     if ((handle == NULL) || CHECK_HANDLE(*handle))
1134         return CS_BAD_HANDLE;
1135     if ((*handle)->next == NULL) {
1136         if (req->Attributes & CLIENT_THIS_SOCKET)
1137             return CS_NO_MORE_ITEMS;
1138         s = SOCKET(*handle);
1139         if (s->clients == NULL)
1140             return CS_NO_MORE_ITEMS;
1141         *handle = s->clients;
1142     } else
1143         *handle = (*handle)->next;
1144     return CS_SUCCESS;
1145 } /* get_next_client */
1146 
1147 /*====================================================================*/
1148 
1149 int pcmcia_get_window(window_handle_t *handle, int idx, win_req_t *req)
1150 {
1151     socket_info_t *s;
1152     window_t *win;
1153     int w;
1154 
1155     if (idx == 0)
1156         s = SOCKET((client_handle_t)*handle);
1157     else
1158         s = (*handle)->sock;
1159     if (!(s->state & SOCKET_PRESENT))
1160         return CS_NO_CARD;
1161     for (w = idx; w < MAX_WIN; w++)
1162         if (s->state & SOCKET_WIN_REQ(w)) break;
1163     if (w == MAX_WIN)
1164         return CS_NO_MORE_ITEMS;
1165     win = &s->win[w];
1166     req->Base = win->ctl.sys_start;
1167     req->Size = win->ctl.sys_stop - win->ctl.sys_start + 1;
1168     req->AccessSpeed = win->ctl.speed;
1169     req->Attributes = 0;
1170     if (win->ctl.flags & MAP_ATTRIB)
1171         req->Attributes |= WIN_MEMORY_TYPE_AM;
1172     if (win->ctl.flags & MAP_ACTIVE)
1173         req->Attributes |= WIN_ENABLE;
1174     if (win->ctl.flags & MAP_16BIT)
1175         req->Attributes |= WIN_DATA_WIDTH_16;
1176     if (win->ctl.flags & MAP_USE_WAIT)
1177         req->Attributes |= WIN_USE_WAIT;
1178     *handle = win;
1179     return CS_SUCCESS;
1180 } /* get_window */
1181 
1182 int pcmcia_get_first_window(window_handle_t *win, win_req_t *req)
1183 {
1184     if ((win == NULL) || ((*win)->magic != WINDOW_MAGIC))
1185         return CS_BAD_HANDLE;
1186     return pcmcia_get_window(win, 0, req);
1187 }
1188 
1189 int pcmcia_get_next_window(window_handle_t *win, win_req_t *req)
1190 {
1191     if ((win == NULL) || ((*win)->magic != WINDOW_MAGIC))
1192         return CS_BAD_HANDLE;
1193     return pcmcia_get_window(win, (*win)->index+1, req);
1194 }
1195 
1196 /*=====================================================================
1197 
1198     Return the PCI device associated with a card..
1199 
1200 ======================================================================*/
1201 
1202 #ifdef CONFIG_CARDBUS
1203 
1204 struct pci_bus *pcmcia_lookup_bus(client_handle_t handle)
1205 {
1206         socket_info_t *s;
1207 
1208         if (CHECK_HANDLE(handle))
1209                 return NULL;
1210         s = SOCKET(handle);
1211         if (!(s->state & SOCKET_CARDBUS))
1212                 return NULL;
1213 
1214         return s->cap.cb_dev->subordinate;
1215 }
1216 
1217 EXPORT_SYMBOL(pcmcia_lookup_bus);
1218 
1219 #endif
1220 
1221 /*======================================================================
1222 
1223     Get the current socket state bits.  We don't support the latched
1224     SocketState yet: I haven't seen any point for it.
1225     
1226 ======================================================================*/
1227 
1228 int pcmcia_get_status(client_handle_t handle, cs_status_t *status)
1229 {
1230     socket_info_t *s;
1231     config_t *c;
1232     int val;
1233     
1234     if (CHECK_HANDLE(handle))
1235         return CS_BAD_HANDLE;
1236     s = SOCKET(handle);
1237     get_socket_status(s, &val);
1238     status->CardState = status->SocketState = 0;
1239     status->CardState |= (val & SS_DETECT) ? CS_EVENT_CARD_DETECT : 0;
1240     status->CardState |= (val & SS_CARDBUS) ? CS_EVENT_CB_DETECT : 0;
1241     status->CardState |= (val & SS_3VCARD) ? CS_EVENT_3VCARD : 0;
1242     status->CardState |= (val & SS_XVCARD) ? CS_EVENT_XVCARD : 0;
1243     if (s->state & SOCKET_SUSPEND)
1244         status->CardState |= CS_EVENT_PM_SUSPEND;
1245     if (!(s->state & SOCKET_PRESENT))
1246         return CS_NO_CARD;
1247     if (s->state & SOCKET_SETUP_PENDING)
1248         status->CardState |= CS_EVENT_CARD_INSERTION;
1249     
1250     /* Get info from the PRR, if necessary */
1251     if (handle->Function == BIND_FN_ALL) {
1252         if (status->Function && (status->Function >= s->functions))
1253             return CS_BAD_ARGS;
1254         c = (s->config != NULL) ? &s->config[status->Function] : NULL;
1255     } else
1256         c = CONFIG(handle);
1257     if ((c != NULL) && (c->state & CONFIG_LOCKED) &&
1258         (c->IntType & INT_MEMORY_AND_IO)) {
1259         u_char reg;
1260         if (c->Present & PRESENT_PIN_REPLACE) {
1261             read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, &reg);
1262             status->CardState |=
1263                 (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0;
1264             status->CardState |=
1265                 (reg & PRR_READY_STATUS) ? CS_EVENT_READY_CHANGE : 0;
1266             status->CardState |=
1267                 (reg & PRR_BVD2_STATUS) ? CS_EVENT_BATTERY_LOW : 0;
1268             status->CardState |=
1269                 (reg & PRR_BVD1_STATUS) ? CS_EVENT_BATTERY_DEAD : 0;
1270         } else {
1271             /* No PRR?  Then assume we're always ready */
1272             status->CardState |= CS_EVENT_READY_CHANGE;
1273         }
1274         if (c->Present & PRESENT_EXT_STATUS) {
1275             read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, &reg);
1276             status->CardState |=
1277                 (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;
1278         }
1279         return CS_SUCCESS;
1280     }
1281     status->CardState |=
1282         (val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0;
1283     status->CardState |=
1284         (val & SS_BATDEAD) ? CS_EVENT_BATTERY_DEAD : 0;
1285     status->CardState |=
1286         (val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0;
1287     status->CardState |=
1288         (val & SS_READY) ? CS_EVENT_READY_CHANGE : 0;
1289     return CS_SUCCESS;
1290 } /* get_status */
1291 
1292 /*======================================================================
1293 
1294     Change the card address of an already open memory window.
1295     
1296 ======================================================================*/
1297 
1298 int pcmcia_get_mem_page(window_handle_t win, memreq_t *req)
1299 {
1300     if ((win == NULL) || (win->magic != WINDOW_MAGIC))
1301         return CS_BAD_HANDLE;
1302     req->Page = 0;
1303     req->CardOffset = win->ctl.card_start;
1304     return CS_SUCCESS;
1305 } /* get_mem_page */
1306 
1307 int pcmcia_map_mem_page(window_handle_t win, memreq_t *req)
1308 {
1309     socket_info_t *s;
1310     if ((win == NULL) || (win->magic != WINDOW_MAGIC))
1311         return CS_BAD_HANDLE;
1312     if (req->Page != 0)
1313         return CS_BAD_PAGE;
1314     s = win->sock;
1315     win->ctl.card_start = req->CardOffset;
1316     if (set_mem_map(s, &win->ctl) != 0)
1317         return CS_BAD_OFFSET;
1318     return CS_SUCCESS;
1319 } /* map_mem_page */
1320 
1321 /*======================================================================
1322 
1323     Modify a locked socket configuration
1324     
1325 ======================================================================*/
1326 
1327 int pcmcia_modify_configuration(client_handle_t handle,
1328                                 modconf_t *mod)
1329 {
1330     socket_info_t *s;
1331     config_t *c;
1332     
1333     if (CHECK_HANDLE(handle))
1334         return CS_BAD_HANDLE;
1335     s = SOCKET(handle); c = CONFIG(handle);
1336     if (!(s->state & SOCKET_PRESENT))
1337         return CS_NO_CARD;
1338     if (!(c->state & CONFIG_LOCKED))
1339         return CS_CONFIGURATION_LOCKED;
1340     
1341     if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {
1342         if (mod->Attributes & CONF_ENABLE_IRQ) {
1343             c->Attributes |= CONF_ENABLE_IRQ;
1344             s->socket.io_irq = s->irq.AssignedIRQ;
1345         } else {
1346             c->Attributes &= ~CONF_ENABLE_IRQ;
1347             s->socket.io_irq = 0;
1348         }
1349         set_socket(s, &s->socket);
1350     }
1351 
1352     if (mod->Attributes & CONF_VCC_CHANGE_VALID)
1353         return CS_BAD_VCC;
1354 
1355     /* We only allow changing Vpp1 and Vpp2 to the same value */
1356     if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) &&
1357         (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
1358         if (mod->Vpp1 != mod->Vpp2)
1359             return CS_BAD_VPP;
1360         c->Vpp1 = c->Vpp2 = s->socket.Vpp = mod->Vpp1;
1361         if (set_socket(s, &s->socket))
1362             return CS_BAD_VPP;
1363     } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
1364                (mod->Attributes & CONF_VPP2_CHANGE_VALID))
1365         return CS_BAD_VPP;
1366 
1367     return CS_SUCCESS;
1368 } /* modify_configuration */
1369 
1370 /*======================================================================
1371 
1372     Modify the attributes of a window returned by RequestWindow.
1373 
1374 ======================================================================*/
1375 
1376 int pcmcia_modify_window(window_handle_t win, modwin_t *req)
1377 {
1378     if ((win == NULL) || (win->magic != WINDOW_MAGIC))
1379         return CS_BAD_HANDLE;
1380 
1381     win->ctl.flags &= ~(MAP_ATTRIB|MAP_ACTIVE);
1382     if (req->Attributes & WIN_MEMORY_TYPE)
1383         win->ctl.flags |= MAP_ATTRIB;
1384     if (req->Attributes & WIN_ENABLE)
1385         win->ctl.flags |= MAP_ACTIVE;
1386     if (req->Attributes & WIN_DATA_WIDTH_16)
1387         win->ctl.flags |= MAP_16BIT;
1388     if (req->Attributes & WIN_USE_WAIT)
1389         win->ctl.flags |= MAP_USE_WAIT;
1390     win->ctl.speed = req->AccessSpeed;
1391     set_mem_map(win->sock, &win->ctl);
1392     
1393     return CS_SUCCESS;
1394 } /* modify_window */
1395 
1396 /*======================================================================
1397 
1398     Register_client() uses the dev_info_t handle to match the
1399     caller with a socket.  The driver must have already been bound
1400     to a socket with bind_device() -- in fact, bind_device()
1401     allocates the client structure that will be used.
1402     
1403 ======================================================================*/
1404 
1405 int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
1406 {
1407     client_t *client;
1408     socket_info_t *s;
1409     socket_t ns;
1410     
1411     /* Look for unbound client with matching dev_info */
1412     client = NULL;
1413     for (ns = 0; ns < sockets; ns++) {
1414         client = socket_table[ns]->clients;
1415         while (client != NULL) {
1416             if ((strcmp(client->dev_info, (char *)req->dev_info) == 0)
1417                 && (client->state & CLIENT_UNBOUND)) break;
1418             client = client->next;
1419         }
1420         if (client != NULL) break;
1421     }
1422     if (client == NULL)
1423         return CS_OUT_OF_RESOURCE;
1424 
1425     s = socket_table[ns];
1426     if (++s->real_clients == 1) {
1427         int status;
1428         register_callback(s, &parse_events, s);
1429         get_socket_status(s, &status);
1430         if ((status & SS_DETECT) &&
1431             !(s->state & SOCKET_SETUP_PENDING)) {
1432             s->state |= SOCKET_SETUP_PENDING;
1433             if (setup_socket(s) == 0)
1434                     s->state &= ~SOCKET_SETUP_PENDING;
1435         }
1436     }
1437 
1438     *handle = client;
1439     client->state &= ~CLIENT_UNBOUND;
1440     client->Socket = ns;
1441     client->Attributes = req->Attributes;
1442     client->EventMask = req->EventMask;
1443     client->event_handler = req->event_handler;
1444     client->event_callback_args = req->event_callback_args;
1445     client->event_callback_args.client_handle = client;
1446     client->event_callback_args.bus = s->cap.bus;
1447 
1448     if (s->state & SOCKET_CARDBUS)
1449         client->state |= CLIENT_CARDBUS;
1450     
1451     if ((!(s->state & SOCKET_CARDBUS)) && (s->functions == 0) &&
1452         (client->Function != BIND_FN_ALL)) {
1453         cistpl_longlink_mfc_t mfc;
1454         if (read_tuple(client, CISTPL_LONGLINK_MFC, &mfc)
1455             == CS_SUCCESS)
1456             s->functions = mfc.nfn;
1457         else
1458             s->functions = 1;
1459         s->config = kmalloc(sizeof(config_t) * s->functions,
1460                             GFP_KERNEL);
1461         memset(s->config, 0, sizeof(config_t) * s->functions);
1462     }
1463     
1464     DEBUG(1, "cs: register_client(): client 0x%p, sock %d, dev %s\n",
1465           client, client->Socket, client->dev_info);
1466     if (client->EventMask & CS_EVENT_REGISTRATION_COMPLETE)
1467         EVENT(client, CS_EVENT_REGISTRATION_COMPLETE, CS_EVENT_PRI_LOW);
1468     if ((socket_table[ns]->state & SOCKET_PRESENT) &&
1469         !(socket_table[ns]->state & SOCKET_SETUP_PENDING)) {
1470         if (client->EventMask & CS_EVENT_CARD_INSERTION)
1471             EVENT(client, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
1472         else
1473             client->PendingEvents |= CS_EVENT_CARD_INSERTION;
1474     }
1475     return CS_SUCCESS;
1476 } /* register_client */
1477 
1478 /*====================================================================*/
1479 
1480 int pcmcia_release_configuration(client_handle_t handle)
1481 {
1482     pccard_io_map io = { 0, 0, 0, 0, 1 };
1483     socket_info_t *s;
1484     int i;
1485     
1486     if (CHECK_HANDLE(handle) ||
1487         !(handle->state & CLIENT_CONFIG_LOCKED))
1488         return CS_BAD_HANDLE;
1489     handle->state &= ~CLIENT_CONFIG_LOCKED;
1490     s = SOCKET(handle);
1491     
1492 #ifdef CONFIG_CARDBUS
1493     if (handle->state & CLIENT_CARDBUS) {
1494         cb_disable(s);
1495         s->lock_count = 0;
1496         return CS_SUCCESS;
1497     }
1498 #endif
1499     
1500     if (!(handle->state & CLIENT_STALE)) {
1501         config_t *c = CONFIG(handle);
1502         if (--(s->lock_count) == 0) {
1503             s->socket.flags = SS_OUTPUT_ENA;
1504             s->socket.Vpp = 0;
1505             s->socket.io_irq = 0;
1506             set_socket(s, &s->socket);
1507         }
1508         if (c->state & CONFIG_IO_REQ)
1509             for (i = 0; i < MAX_IO_WIN; i++) {
1510                 if (s->io[i].NumPorts == 0)
1511                     continue;
1512                 s->io[i].Config--;
1513                 if (s->io[i].Config != 0)
1514                     continue;
1515                 io.map = i;
1516                 set_io_map(s, &io);
1517             }
1518         c->state &= ~CONFIG_LOCKED;
1519     }
1520     
1521     return CS_SUCCESS;
1522 } /* release_configuration */
1523 
1524 /*======================================================================
1525 
1526     Release_io() releases the I/O ranges allocated by a client.  This
1527     may be invoked some time after a card ejection has already dumped
1528     the actual socket configuration, so if the client is "stale", we
1529     don't bother checking the port ranges against the current socket
1530     values.
1531     
1532 ======================================================================*/
1533 
1534 int pcmcia_release_io(client_handle_t handle, io_req_t *req)
1535 {
1536     socket_info_t *s;
1537     
1538     if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IO_REQ))
1539         return CS_BAD_HANDLE;
1540     handle->state &= ~CLIENT_IO_REQ;
1541     s = SOCKET(handle);
1542     
1543 #ifdef CONFIG_CARDBUS
1544     if (handle->state & CLIENT_CARDBUS) {
1545         cb_release(s);
1546         return CS_SUCCESS;
1547     }
1548 #endif
1549     
1550     if (!(handle->state & CLIENT_STALE)) {
1551         config_t *c = CONFIG(handle);
1552         if (c->state & CONFIG_LOCKED)
1553             return CS_CONFIGURATION_LOCKED;
1554         if ((c->io.BasePort1 != req->BasePort1) ||
1555             (c->io.NumPorts1 != req->NumPorts1) ||
1556             (c->io.BasePort2 != req->BasePort2) ||
1557             (c->io.NumPorts2 != req->NumPorts2))
1558             return CS_BAD_ARGS;
1559         c->state &= ~CONFIG_IO_REQ;
1560     }
1561 
1562     release_io_space(s, req->BasePort1, req->NumPorts1);
1563     if (req->NumPorts2)
1564         release_io_space(s, req->BasePort2, req->NumPorts2);
1565     
1566     return CS_SUCCESS;
1567 } /* release_io */
1568 
1569 /*====================================================================*/
1570 
1571 int pcmcia_release_irq(client_handle_t handle, irq_req_t *req)
1572 {
1573     socket_info_t *s;
1574     if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IRQ_REQ))
1575         return CS_BAD_HANDLE;
1576     handle->state &= ~CLIENT_IRQ_REQ;
1577     s = SOCKET(handle);
1578     
1579     if (!(handle->state & CLIENT_STALE)) {
1580         config_t *c = CONFIG(handle);
1581         if (c->state & CONFIG_LOCKED)
1582             return CS_CONFIGURATION_LOCKED;
1583         if (c->irq.Attributes != req->Attributes)
1584             return CS_BAD_ATTRIBUTE;
1585         if (s->irq.AssignedIRQ != req->AssignedIRQ)
1586             return CS_BAD_IRQ;
1587         if (--s->irq.Config == 0) {
1588             c->state &= ~CONFIG_IRQ_REQ;
1589             s->irq.AssignedIRQ = 0;
1590         }
1591     }
1592     
1593     if (req->Attributes & IRQ_HANDLE_PRESENT) {
1594         bus_free_irq(s->cap.bus, req->AssignedIRQ, req->Instance);
1595     }
1596 
1597 #ifdef CONFIG_ISA
1598     if (req->AssignedIRQ != s->cap.pci_irq)
1599         undo_irq(req->Attributes, req->AssignedIRQ);
1600 #endif
1601     
1602     return CS_SUCCESS;
1603 } /* cs_release_irq */
1604 
1605 /*====================================================================*/
1606 
1607 int pcmcia_release_window(window_handle_t win)
1608 {
1609     socket_info_t *s;
1610     
1611     if ((win == NULL) || (win->magic != WINDOW_MAGIC))
1612         return CS_BAD_HANDLE;
1613     s = win->sock;
1614     if (!(win->handle->state & CLIENT_WIN_REQ(win->index)))
1615         return CS_BAD_HANDLE;
1616 
1617     /* Shut down memory window */
1618     win->ctl.flags &= ~MAP_ACTIVE;
1619     set_mem_map(s, &win->ctl);
1620     s->state &= ~SOCKET_WIN_REQ(win->index);
1621 
1622     /* Release system memory */
1623     release_mem_region(win->base, win->size);
1624     win->handle->state &= ~CLIENT_WIN_REQ(win->index);
1625 
1626     win->magic = 0;
1627     
1628     return CS_SUCCESS;
1629 } /* release_window */
1630 
1631 /*====================================================================*/
1632 
1633 int pcmcia_request_configuration(client_handle_t handle,
1634                                  config_req_t *req)
1635 {
1636     int i;
1637     u_int base;
1638     socket_info_t *s;
1639     config_t *c;
1640     pccard_io_map iomap;
1641     
1642     if (CHECK_HANDLE(handle))
1643         return CS_BAD_HANDLE;
1644     i = handle->Socket; s = socket_table[i];
1645     if (!(s->state & SOCKET_PRESENT))
1646         return CS_NO_CARD;
1647     
1648 #ifdef CONFIG_CARDBUS
1649     if (handle->state & CLIENT_CARDBUS) {
1650         if (!(req->IntType & INT_CARDBUS))
1651             return CS_UNSUPPORTED_MODE;
1652         if (s->lock_count != 0)
1653             return CS_CONFIGURATION_LOCKED;
1654         cb_enable(s);
1655         handle->state |= CLIENT_CONFIG_LOCKED;
1656         s->lock_count++;
1657         return CS_SUCCESS;
1658     }
1659 #endif
1660     
1661     if (req->IntType & INT_CARDBUS)
1662         return CS_UNSUPPORTED_MODE;
1663     c = CONFIG(handle);
1664     if (c->state & CONFIG_LOCKED)
1665         return CS_CONFIGURATION_LOCKED;
1666 
1667     /* Do power control.  We don't allow changes in Vcc. */
1668     if (s->socket.Vcc != req->Vcc)
1669         return CS_BAD_VCC;
1670     if (req->Vpp1 != req->Vpp2)
1671         return CS_BAD_VPP;
1672     s->socket.Vpp = req->Vpp1;
1673     if (set_socket(s, &s->socket))
1674         return CS_BAD_VPP;
1675     
1676     c->Vcc = req->Vcc; c->Vpp1 = c->Vpp2 = req->Vpp1;
1677     
1678     /* Pick memory or I/O card, DMA mode, interrupt */
1679     c->IntType = req->IntType;
1680     c->Attributes = req->Attributes;
1681     if (req->IntType & INT_MEMORY_AND_IO)
1682         s->socket.flags |= SS_IOCARD;
1683     if (req->Attributes & CONF_ENABLE_DMA)
1684         s->socket.flags |= SS_DMA_MODE;
1685     if (req->Attributes & CONF_ENABLE_SPKR)
1686         s->socket.flags |= SS_SPKR_ENA;
1687     if (req->Attributes & CONF_ENABLE_IRQ)
1688         s->socket.io_irq = s->irq.AssignedIRQ;
1689     else
1690         s->socket.io_irq = 0;
1691     set_socket(s, &s->socket);
1692     s->lock_count++;
1693     
1694     /* Set up CIS configuration registers */
1695     base = c->ConfigBase = req->ConfigBase;
1696     c->Present = c->CardValues = req->Present;
1697     if (req->Present & PRESENT_COPY) {
1698         c->Copy = req->Copy;
1699         write_cis_mem(s, 1, (base + CISREG_SCR)>>1, 1, &c->Copy);
1700     }
1701     if (req->Present & PRESENT_OPTION) {
1702         if (s->functions == 1) {
1703             c->Option = req->ConfigIndex & COR_CONFIG_MASK;
1704         } else {
1705             c->Option = req->ConfigIndex & COR_MFC_CONFIG_MASK;
1706             c->Option |= COR_FUNC_ENA|COR_IREQ_ENA;
1707             if (req->Present & PRESENT_IOBASE_0)
1708                 c->Option |= COR_ADDR_DECODE;
1709         }
1710         if (c->state & CONFIG_IRQ_REQ)
1711             if (!(c->irq.Attributes & IRQ_FORCED_PULSE))
1712                 c->Option |= COR_LEVEL_REQ;
1713         write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &c->Option);
1714         mdelay(40);
1715     }
1716     if (req->Present & PRESENT_STATUS) {
1717         c->Status = req->Status;
1718         write_cis_mem(s, 1, (base + CISREG_CCSR)>>1, 1, &c->Status);
1719     }
1720     if (req->Present & PRESENT_PIN_REPLACE) {
1721         c->Pin = req->Pin;
1722         write_cis_mem(s, 1, (base + CISREG_PRR)>>1, 1, &c->Pin);
1723     }
1724     if (req->Present & PRESENT_EXT_STATUS) {
1725         c->ExtStatus = req->ExtStatus;
1726         write_cis_mem(s, 1, (base + CISREG_ESR)>>1, 1, &c->ExtStatus);
1727     }
1728     if (req->Present & PRESENT_IOBASE_0) {
1729         u_char b = c->io.BasePort1 & 0xff;
1730         write_cis_mem(s, 1, (base + CISREG_IOBASE_0)>>1, 1, &b);
1731         b = (c->io.BasePort1 >> 8) & 0xff;
1732         write_cis_mem(s, 1, (base + CISREG_IOBASE_1)>>1, 1, &b);
1733     }
1734     if (req->Present & PRESENT_IOSIZE) {
1735         u_char b = c->io.NumPorts1 + c->io.NumPorts2 - 1;
1736         write_cis_mem(s, 1, (base + CISREG_IOSIZE)>>1, 1, &b);
1737     }
1738     
1739     /* Configure I/O windows */
1740     if (c->state & CONFIG_IO_REQ) {
1741         iomap.speed = io_speed;
1742         for (i = 0; i < MAX_IO_WIN; i++)
1743             if (s->io[i].NumPorts != 0) {
1744                 iomap.map = i;
1745                 iomap.flags = MAP_ACTIVE;
1746                 switch (s->io[i].Attributes & IO_DATA_PATH_WIDTH) {
1747                 case IO_DATA_PATH_WIDTH_16:
1748                     iomap.flags |= MAP_16BIT; break;
1749                 case IO_DATA_PATH_WIDTH_AUTO:
1750                     iomap.flags |= MAP_AUTOSZ; break;
1751                 default:
1752                     break;
1753                 }
1754                 iomap.start = s->io[i].BasePort;
1755                 iomap.stop = iomap.start + s->io[i].NumPorts - 1;
1756                 set_io_map(s, &iomap);
1757                 s->io[i].Config++;
1758             }
1759     }
1760     
1761     c->state |= CONFIG_LOCKED;
1762     handle->state |= CLIENT_CONFIG_LOCKED;
1763     return CS_SUCCESS;
1764 } /* request_configuration */
1765 
1766 /*======================================================================
1767   
1768     Request_io() reserves ranges of port addresses for a socket.
1769     I have not implemented range sharing or alias addressing.
1770     
1771 ======================================================================*/
1772 
1773 int pcmcia_request_io(client_handle_t handle, io_req_t *req)
1774 {
1775     socket_info_t *s;
1776     config_t *c;
1777     
1778     if (CHECK_HANDLE(handle))
1779         return CS_BAD_HANDLE;
1780     s = SOCKET(handle);
1781     if (!(s->state & SOCKET_PRESENT))
1782         return CS_NO_CARD;
1783 
1784     if (handle->state & CLIENT_CARDBUS) {
1785 #ifdef CONFIG_CARDBUS
1786         int ret = cb_config(s);
1787         if (ret == CS_SUCCESS)
1788             handle->state |= CLIENT_IO_REQ;
1789         return ret;
1790 #else
1791         return CS_UNSUPPORTED_FUNCTION;
1792 #endif
1793     }
1794 
1795     if (!req)
1796         return CS_UNSUPPORTED_MODE;
1797     c = CONFIG(handle);
1798     if (c->state & CONFIG_LOCKED)
1799         return CS_CONFIGURATION_LOCKED;
1800     if (c->state & CONFIG_IO_REQ)
1801         return CS_IN_USE;
1802     if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))
1803         return CS_BAD_ATTRIBUTE;
1804     if ((req->NumPorts2 > 0) &&
1805         (req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)))
1806         return CS_BAD_ATTRIBUTE;
1807 
1808     if (alloc_io_space(s, req->Attributes1, &req->BasePort1,
1809                        req->NumPorts1, req->IOAddrLines,
1810                        handle->dev_info))
1811         return CS_IN_USE;
1812 
1813     if (req->NumPorts2) {
1814         if (alloc_io_space(s, req->Attributes2, &req->BasePort2,
1815                            req->NumPorts2, req->IOAddrLines,
1816                            handle->dev_info)) {
1817             release_io_space(s, req->BasePort1, req->NumPorts1);
1818             return CS_IN_USE;
1819         }
1820     }
1821 
1822     c->io = *req;
1823     c->state |= CONFIG_IO_REQ;
1824     handle->state |= CLIENT_IO_REQ;
1825     return CS_SUCCESS;
1826 } /* request_io */
1827 
1828 /*======================================================================
1829 
1830     Request_irq() reserves an irq for this client.
1831 
1832     Also, since Linux only reserves irq's when they are actually
1833     hooked, we don't guarantee that an irq will still be available
1834     when the configuration is locked.  Now that I think about it,
1835     there might be a way to fix this using a dummy handler.
1836     
1837 ======================================================================*/
1838 
1839 int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)
1840 {
1841     socket_info_t *s;
1842     config_t *c;
1843     int ret = 0, irq = 0;
1844     
1845     if (CHECK_HANDLE(handle))
1846         return CS_BAD_HANDLE;
1847     s = SOCKET(handle);
1848     if (!(s->state & SOCKET_PRESENT))
1849         return CS_NO_CARD;
1850     c = CONFIG(handle);
1851     if (c->state & CONFIG_LOCKED)
1852         return CS_CONFIGURATION_LOCKED;
1853     if (c->state & CONFIG_IRQ_REQ)
1854         return CS_IN_USE;
1855     
1856     /* Short cut: if there are no ISA interrupts, then it is PCI */
1857     if (!s->cap.irq_mask) {
1858         irq = s->cap.pci_irq;
1859         ret = (irq) ? 0 : CS_IN_USE;
1860 #ifdef CONFIG_ISA
1861     } else if (s->irq.AssignedIRQ != 0) {
1862         /* If the interrupt is already assigned, it must match */
1863         irq = s->irq.AssignedIRQ;
1864         if (req->IRQInfo1 & IRQ_INFO2_VALID) {
1865             u_int mask = req->IRQInfo2 & s->cap.irq_mask;
1866             ret = ((mask >> irq) & 1) ? 0 : CS_BAD_ARGS;
1867         } else
1868             ret = ((req->IRQInfo1&IRQ_MASK) == irq) ? 0 : CS_BAD_ARGS;
1869     } else {
1870         ret = CS_IN_USE;
1871         if (req->IRQInfo1 & IRQ_INFO2_VALID) {
1872             u_int try, mask = req->IRQInfo2 & s->cap.irq_mask;
1873             for (try = 0; try < 2; try++) {
1874                 for (irq = 0; irq < 32; irq++)
1875                     if ((mask >> irq) & 1) {
1876                         ret = try_irq(req->Attributes, irq, try);
1877                         if (ret == 0) break;
1878                     }
1879                 if (ret == 0) break;
1880             }
1881         } else {
1882             irq = req->IRQInfo1 & IRQ_MASK;
1883             ret = try_irq(req->Attributes, irq, 1);
1884         }
1885 #endif
1886     }
1887     if (ret != 0) return ret;
1888 
1889     if (req->Attributes & IRQ_HANDLE_PRESENT) {
1890         if (bus_request_irq(s->cap.bus, irq, req->Handler,
1891                             ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) || 
1892                              (s->functions > 1) ||
1893                              (irq == s->cap.pci_irq)) ? SA_SHIRQ : 0,
1894                             handle->dev_info, req->Instance))
1895             return CS_IN_USE;
1896     }
1897 
1898     c->irq.Attributes = req->Attributes;
1899     s->irq.AssignedIRQ = req->AssignedIRQ = irq;
1900     s->irq.Config++;
1901     
1902     c->state |= CONFIG_IRQ_REQ;
1903     handle->state |= CLIENT_IRQ_REQ;
1904     return CS_SUCCESS;
1905 } /* pcmcia_request_irq */
1906 
1907 /*======================================================================
1908 
1909     Request_window() establishes a mapping between card memory space
1910     and system memory space.
1911 
1912 ======================================================================*/
1913 
1914 int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle_t *wh)
1915 {
1916     socket_info_t *s;
1917     window_t *win;
1918     u_long align;
1919     int w;
1920     
1921     if (CHECK_HANDLE(*handle))
1922         return CS_BAD_HANDLE;
1923     s = SOCKET(*handle);
1924     if (!(s->state & SOCKET_PRESENT))
1925         return CS_NO_CARD;
1926     if (req->Attributes & (WIN_PAGED | WIN_SHARED))
1927         return CS_BAD_ATTRIBUTE;
1928 
1929     /* Window size defaults to smallest available */
1930     if (req->Size == 0)
1931         req->Size = s->cap.map_size;
1932     align = (((s->cap.features & SS_CAP_MEM_ALIGN) ||
1933               (req->Attributes & WIN_STRICT_ALIGN)) ?
1934              req->Size : s->cap.map_size);
1935     if (req->Size & (s->cap.map_size-1))
1936         return CS_BAD_SIZE;
1937     if ((req->Base && (s->cap.features & SS_CAP_STATIC_MAP)) ||
1938         (req->Base & (align-1)))
1939         return CS_BAD_BASE;
1940     if (req->Base)
1941         align = 0;
1942 
1943     /* Allocate system memory window */
1944     for (w = 0; w < MAX_WIN; w++)
1945         if (!(s->state & SOCKET_WIN_REQ(w))) break;
1946     if (w == MAX_WIN)
1947         return CS_OUT_OF_RESOURCE;
1948 
1949     win = &s->win[w];
1950     win->magic = WINDOW_MAGIC;
1951     win->index = w;
1952     win->handle = *handle;
1953     win->sock = s;
1954     win->base = req->Base;
1955     win->size = req->Size;
1956 
1957     if (!(s->cap.features & SS_CAP_STATIC_MAP) &&
1958         find_mem_region(&win->base, win->size, align,
1959                         (req->Attributes & WIN_MAP_BELOW_1MB) ||
1960                         !(s->cap.features & SS_CAP_PAGE_REGS),
1961                         (*handle)->dev_info))
1962         return CS_IN_USE;
1963     (*handle)->state |= CLIENT_WIN_REQ(w);
1964 
1965     /* Configure the socket controller */
1966     win->ctl.map = w+1;
1967     win->ctl.flags = 0;
1968     win->ctl.speed = req->AccessSpeed;
1969     if (req->Attributes & WIN_MEMORY_TYPE)
1970         win->ctl.flags |= MAP_ATTRIB;
1971     if (req->Attributes & WIN_ENABLE)
1972         win->ctl.flags |= MAP_ACTIVE;
1973     if (req->Attributes & WIN_DATA_WIDTH_16)
1974         win->ctl.flags |= MAP_16BIT;
1975     if (req->Attributes & WIN_USE_WAIT)
1976         win->ctl.flags |= MAP_USE_WAIT;
1977     win->ctl.sys_start = win->base;
1978     win->ctl.sys_stop = win->base + win->size-1;
1979     win->ctl.card_start = 0;
1980     if (set_mem_map(s, &win->ctl) != 0)
1981         return CS_BAD_ARGS;
1982     s->state |= SOCKET_WIN_REQ(w);
1983 
1984     /* Return window handle */
1985     req->Base = win->ctl.sys_start;
1986     *wh = win;
1987     
1988     return CS_SUCCESS;
1989 } /* request_window */
1990 
1991 /*======================================================================
1992 
1993     I'm not sure which "reset" function this is supposed to use,
1994     but for now, it uses the low-level interface's reset, not the
1995     CIS register.
1996     
1997 ======================================================================*/
1998 
1999 int pcmcia_reset_card(client_handle_t handle, client_req_t *req)
2000 {
2001     int i, ret;
2002     socket_info_t *s;
2003     
2004     if (CHECK_HANDLE(handle))
2005         return CS_BAD_HANDLE;
2006     i = handle->Socket; s = socket_table[i];
2007     if (!(s->state & SOCKET_PRESENT))
2008         return CS_NO_CARD;
2009     if (s->state & SOCKET_RESET_PENDING)
2010         return CS_IN_USE;
2011     s->state |= SOCKET_RESET_PENDING;
2012 
2013     ret = send_event(s, CS_EVENT_RESET_REQUEST, CS_EVENT_PRI_LOW);
2014     if (ret != 0) {
2015         s->state &= ~SOCKET_RESET_PENDING;
2016         handle->event_callback_args.info = (void *)(u_long)ret;
2017         EVENT(handle, CS_EVENT_RESET_COMPLETE, CS_EVENT_PRI_LOW);
2018     } else {
2019         DEBUG(1, "cs: resetting socket %d\n", i);
2020         send_event(s, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW);
2021         s->reset_handle = handle;
2022         reset_socket(s);
2023     }
2024     return CS_SUCCESS;
2025 } /* reset_card */
2026 
2027 /*======================================================================
2028 
2029     These shut down or wake up a socket.  They are sort of user
2030     initiated versions of the APM suspend and resume actions.
2031     
2032 ======================================================================*/
2033 
2034 int pcmcia_suspend_card(client_handle_t handle, client_req_t *req)
2035 {
2036     int i;
2037     socket_info_t *s;
2038     
2039     if (CHECK_HANDLE(handle))
2040         return CS_BAD_HANDLE;
2041     i = handle->Socket; s = socket_table[i];
2042     if (!(s->state & SOCKET_PRESENT))
2043         return CS_NO_CARD;
2044     if (s->state & SOCKET_SUSPEND)
2045         return CS_IN_USE;
2046 
2047     DEBUG(1, "cs: suspending socket %d\n", i);
2048     send_event(s, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW);
2049     suspend_socket(s);
2050     s->state |= SOCKET_SUSPEND;
2051 
2052     return CS_SUCCESS;
2053 } /* suspend_card */
2054 
2055 int pcmcia_resume_card(client_handle_t handle, client_req_t *req)
2056 {
2057     int i;
2058     socket_info_t *s;
2059     
2060     if (CHECK_HANDLE(handle))
2061         return CS_BAD_HANDLE;
2062     i = handle->Socket; s = socket_table[i];
2063     if (!(s->state & SOCKET_PRESENT))
2064         return CS_NO_CARD;
2065     if (!(s->state & SOCKET_SUSPEND))
2066         return CS_IN_USE;
2067 
2068     DEBUG(1, "cs: waking up socket %d\n", i);
2069     setup_socket(s);
2070 
2071     return CS_SUCCESS;
2072 } /* resume_card */
2073 
2074 /*======================================================================
2075 
2076     These handle user requests to eject or insert a card.
2077     
2078 ======================================================================*/
2079 
2080 int pcmcia_eject_card(client_handle_t handle, client_req_t *req)
2081 {
2082     int i, ret;
2083     socket_info_t *s;
2084     u_long flags;
2085     
2086     if (CHECK_HANDLE(handle))
2087         return CS_BAD_HANDLE;
2088     i = handle->Socket; s = socket_table[i];
2089     if (!(s->state & SOCKET_PRESENT))
2090         return CS_NO_CARD;
2091 
2092     DEBUG(1, "cs: user eject request on socket %d\n", i);
2093 
2094     ret = send_event(s, CS_EVENT_EJECTION_REQUEST, CS_EVENT_PRI_LOW);
2095     if (ret != 0)
2096         return ret;
2097 
2098     spin_lock_irqsave(&s->lock, flags);
2099     do_shutdown(s);
2100     spin_unlock_irqrestore(&s->lock, flags);
2101     
2102     return CS_SUCCESS;
2103     
2104 } /* eject_card */
2105 
2106 int pcmcia_insert_card(client_handle_t handle, client_req_t *req)
2107 {
2108     int i, status;
2109     socket_info_t *s;
2110     u_long flags;
2111     
2112     if (CHECK_HANDLE(handle))
2113         return CS_BAD_HANDLE;
2114     i = handle->Socket; s = socket_table[i];
2115     if (s->state & SOCKET_PRESENT)
2116         return CS_IN_USE;
2117 
2118     DEBUG(1, "cs: user insert request on socket %d\n", i);
2119 
2120     spin_lock_irqsave(&s->lock, flags);
2121     if (!(s->state & SOCKET_SETUP_PENDING)) {
2122         s->state |= SOCKET_SETUP_PENDING;
2123         spin_unlock_irqrestore(&s->lock, flags);
2124         get_socket_status(s, &status);
2125         if ((status & SS_DETECT) == 0 || (setup_socket(s) == 0)) {
2126             s->state &= ~SOCKET_SETUP_PENDING;
2127             return CS_NO_CARD;
2128         }
2129     } else
2130         spin_unlock_irqrestore(&s->lock, flags);
2131 
2132     return CS_SUCCESS;
2133 } /* insert_card */
2134 
2135 /*======================================================================
2136 
2137     Maybe this should send a CS_EVENT_CARD_INSERTION event if we
2138     haven't sent one to this client yet?
2139     
2140 ======================================================================*/
2141 
2142 int pcmcia_set_event_mask(client_handle_t handle, eventmask_t *mask)
2143 {
2144     u_int events, bit;
2145     if (CHECK_HANDLE(handle))
2146         return CS_BAD_HANDLE;
2147     if (handle->Attributes & CONF_EVENT_MASK_VALID)
2148         return CS_BAD_SOCKET;
2149     handle->EventMask = mask->EventMask;
2150     events = handle->PendingEvents & handle->EventMask;
2151     handle->PendingEvents -= events;
2152     while (events != 0) {
2153         bit = ((events ^ (events-1)) + 1) >> 1;
2154         EVENT(handle, bit, CS_EVENT_PRI_LOW);
2155         events -= bit;
2156     }
2157     return CS_SUCCESS;
2158 } /* set_event_mask */
2159 
2160 /*====================================================================*/
2161 
2162 int pcmcia_report_error(client_handle_t handle, error_info_t *err)
2163 {
2164     int i;
2165     char *serv;
2166 
2167     if (CHECK_HANDLE(handle))
2168         printk(KERN_NOTICE);
2169     else
2170         printk(KERN_NOTICE "%s: ", handle->dev_info);
2171     
2172     for (i = 0; i < SERVICE_COUNT; i++)
2173         if (service_table[i].key == err->func) break;
2174     if (i < SERVICE_COUNT)
2175         serv = service_table[i].msg;
2176     else
2177         serv = "Unknown service number";
2178 
2179     for (i = 0; i < ERROR_COUNT; i++)
2180         if (error_table[i].key == err->retcode) break;
2181     if (i < ERROR_COUNT)
2182         printk("%s: %s\n", serv, error_table[i].msg);
2183     else
2184         printk("%s: Unknown error code %#x\n", serv, err->retcode);
2185 
2186     return CS_SUCCESS;
2187 } /* report_error */
2188 
2189 /*====================================================================*/
2190 
2191 int CardServices(int func, void *a1, void *a2, void *a3)
2192 {
2193 
2194 #ifdef PCMCIA_DEBUG
2195     if (pc_debug > 2) {
2196         int i;
2197         for (i = 0; i < SERVICE_COUNT; i++)
2198             if (service_table[i].key == func) break;
2199         if (i < SERVICE_COUNT)
2200             printk(KERN_DEBUG "cs: CardServices(%s, 0x%p, 0x%p)\n",
2201                    service_table[i].msg, a1, a2);
2202         else
2203             printk(KERN_DEBUG "cs: CardServices(Unknown func %d, "
2204                    "0x%p, 0x%p)\n", func, a1, a2);
2205     }
2206 #endif
2207     switch (func) {
2208     case AccessConfigurationRegister:
2209         return pcmcia_access_configuration_register(a1, a2); break;
2210     case AdjustResourceInfo:
2211         return pcmcia_adjust_resource_info(a1, a2); break;
2212     case CheckEraseQueue:
2213         return pcmcia_check_erase_queue(a1); break;
2214     case CloseMemory:
2215         return pcmcia_close_memory(a1); break;
2216     case CopyMemory:
2217         return pcmcia_copy_memory(a1, a2); break;
2218     case DeregisterClient:
2219         return pcmcia_deregister_client(a1); break;
2220     case DeregisterEraseQueue:
2221         return pcmcia_deregister_erase_queue(a1); break;
2222     case GetFirstClient:
2223         return pcmcia_get_first_client(a1, a2); break;
2224     case GetCardServicesInfo:
2225         return pcmcia_get_card_services_info(a1); break;
2226     case GetConfigurationInfo:
2227         return pcmcia_get_configuration_info(a1, a2); break;
2228     case GetNextClient:
2229         return pcmcia_get_next_client(a1, a2); break;
2230     case GetFirstRegion:
2231         return pcmcia_get_first_region(a1, a2); break;
2232     case GetFirstTuple:
2233         return pcmcia_get_first_tuple(a1, a2); break;
2234     case GetNextRegion:
2235         return pcmcia_get_next_region(a1, a2); break;
2236     case GetNextTuple:
2237         return pcmcia_get_next_tuple(a1, a2); break;
2238     case GetStatus:
2239         return pcmcia_get_status(a1, a2); break;
2240     case GetTupleData:
2241         return pcmcia_get_tuple_data(a1, a2); break;
2242     case MapMemPage:
2243         return pcmcia_map_mem_page(a1, a2); break;
2244     case ModifyConfiguration:
2245         return pcmcia_modify_configuration(a1, a2); break;
2246     case ModifyWindow:
2247         return pcmcia_modify_window(a1, a2); break;
2248     case OpenMemory:
2249 /*      return pcmcia_open_memory(a1, a2); */
2250     {
2251         memory_handle_t m;
2252         int ret = pcmcia_open_memory(a1, a2, &m);
2253         *(memory_handle_t *)a1 = m;
2254         return  ret;
2255     }
2256         break;
2257     case ParseTuple:
2258         return pcmcia_parse_tuple(a1, a2, a3); break;
2259     case ReadMemory:
2260         return pcmcia_read_memory(a1, a2, a3); break;
2261     case RegisterClient:
2262         return pcmcia_register_client(a1, a2); break;
2263     case RegisterEraseQueue:
2264     {
2265         eraseq_handle_t w;
2266         int ret = pcmcia_register_erase_queue(a1, a2, &w);
2267         *(eraseq_handle_t *)a1 = w;
2268         return  ret;
2269     }
2270         break;
2271 /*      return pcmcia_register_erase_queue(a1, a2); break; */
2272 
2273         return pcmcia_register_mtd(a1, a2); break;
2274     case ReleaseConfiguration:
2275         return pcmcia_release_configuration(a1); break;
2276     case ReleaseIO:
2277         return pcmcia_release_io(a1, a2); break;
2278     case ReleaseIRQ:
2279         return pcmcia_release_irq(a1, a2); break;
2280     case ReleaseWindow:
2281         return pcmcia_release_window(a1); break;
2282     case RequestConfiguration:
2283         return pcmcia_request_configuration(a1, a2); break;
2284     case RequestIO:
2285         return pcmcia_request_io(a1, a2); break;
2286     case RequestIRQ:
2287         return pcmcia_request_irq(a1, a2); break;
2288     case RequestWindow:
2289     {
2290         window_handle_t w;
2291         int ret = pcmcia_request_window(a1, a2, &w);
2292         *(window_handle_t *)a1 = w;
2293         return  ret;
2294     }
2295         break;
2296     case ResetCard:
2297         return pcmcia_reset_card(a1, a2); break;
2298     case SetEventMask:
2299         return pcmcia_set_event_mask(a1, a2); break;
2300     case ValidateCIS:
2301         return pcmcia_validate_cis(a1, a2); break;
2302     case WriteMemory:
2303         return pcmcia_write_memory(a1, a2, a3); break;
2304     case BindDevice:
2305         return pcmcia_bind_device(a1); break;
2306     case BindMTD:
2307         return pcmcia_bind_mtd(a1); break;
2308     case ReportError:
2309         return pcmcia_report_error(a1, a2); break;
2310     case SuspendCard:
2311         return pcmcia_suspend_card(a1, a2); break;
2312     case ResumeCard:
2313         return pcmcia_resume_card(a1, a2); break;
2314     case EjectCard:
2315         return pcmcia_eject_card(a1, a2); break;
2316     case InsertCard:
2317         return pcmcia_insert_card(a1, a2); break;
2318     case ReplaceCIS:
2319         return pcmcia_replace_cis(a1, a2); break;
2320     case GetFirstWindow:
2321         return pcmcia_get_first_window(a1, a2); break;
2322     case GetNextWindow:
2323         return pcmcia_get_next_window(a1, a2); break;
2324     case GetMemPage:
2325         return pcmcia_get_mem_page(a1, a2); break;
2326     default:
2327         return CS_UNSUPPORTED_FUNCTION; break;
2328     }
2329     
2330 } /* CardServices */
2331 
2332 /*======================================================================
2333 
2334     OS-specific module glue goes here
2335     
2336 ======================================================================*/
2337 /* in alpha order */
2338 EXPORT_SYMBOL(pcmcia_access_configuration_register);
2339 EXPORT_SYMBOL(pcmcia_adjust_resource_info);
2340 EXPORT_SYMBOL(pcmcia_bind_device);
2341 EXPORT_SYMBOL(pcmcia_bind_mtd);
2342 EXPORT_SYMBOL(pcmcia_check_erase_queue);
2343 EXPORT_SYMBOL(pcmcia_close_memory);
2344 EXPORT_SYMBOL(pcmcia_copy_memory);
2345 EXPORT_SYMBOL(pcmcia_deregister_client);
2346 EXPORT_SYMBOL(pcmcia_deregister_erase_queue);
2347 EXPORT_SYMBOL(pcmcia_eject_card);
2348 EXPORT_SYMBOL(pcmcia_get_first_client);
2349 EXPORT_SYMBOL(pcmcia_get_card_services_info);
2350 EXPORT_SYMBOL(pcmcia_get_configuration_info);
2351 EXPORT_SYMBOL(pcmcia_get_mem_page);
2352 EXPORT_SYMBOL(pcmcia_get_next_client);
2353 EXPORT_SYMBOL(pcmcia_get_first_region);
2354 EXPORT_SYMBOL(pcmcia_get_first_tuple);
2355 EXPORT_SYMBOL(pcmcia_get_first_window);
2356 EXPORT_SYMBOL(pcmcia_get_next_region);
2357 EXPORT_SYMBOL(pcmcia_get_next_tuple);
2358 EXPORT_SYMBOL(pcmcia_get_next_window);
2359 EXPORT_SYMBOL(pcmcia_get_status);
2360 EXPORT_SYMBOL(pcmcia_get_tuple_data);
2361 EXPORT_SYMBOL(pcmcia_insert_card);
2362 EXPORT_SYMBOL(pcmcia_map_mem_page);
2363 EXPORT_SYMBOL(pcmcia_modify_configuration);
2364 EXPORT_SYMBOL(pcmcia_modify_window);
2365 EXPORT_SYMBOL(pcmcia_open_memory);
2366 EXPORT_SYMBOL(pcmcia_parse_tuple);
2367 EXPORT_SYMBOL(pcmcia_read_memory);
2368 EXPORT_SYMBOL(pcmcia_register_client);
2369 EXPORT_SYMBOL(pcmcia_register_erase_queue);
2370 EXPORT_SYMBOL(pcmcia_register_mtd);
2371 EXPORT_SYMBOL(pcmcia_release_configuration);
2372 EXPORT_SYMBOL(pcmcia_release_io);
2373 EXPORT_SYMBOL(pcmcia_release_irq);
2374 EXPORT_SYMBOL(pcmcia_release_window);
2375 EXPORT_SYMBOL(pcmcia_replace_cis);
2376 EXPORT_SYMBOL(pcmcia_report_error);
2377 EXPORT_SYMBOL(pcmcia_request_configuration);
2378 EXPORT_SYMBOL(pcmcia_request_io);
2379 EXPORT_SYMBOL(pcmcia_request_irq);
2380 EXPORT_SYMBOL(pcmcia_request_window);
2381 EXPORT_SYMBOL(pcmcia_reset_card);
2382 EXPORT_SYMBOL(pcmcia_resume_card);
2383 EXPORT_SYMBOL(pcmcia_set_event_mask);
2384 EXPORT_SYMBOL(pcmcia_suspend_card);
2385 EXPORT_SYMBOL(pcmcia_validate_cis);
2386 EXPORT_SYMBOL(pcmcia_write_memory);
2387 
2388 EXPORT_SYMBOL(dead_socket);
2389 EXPORT_SYMBOL(register_ss_entry);
2390 EXPORT_SYMBOL(unregister_ss_entry);
2391 EXPORT_SYMBOL(CardServices);
2392 EXPORT_SYMBOL(MTDHelperEntry);
2393 #ifdef CONFIG_PROC_FS
2394 EXPORT_SYMBOL(proc_pccard);
2395 #endif
2396 
2397 EXPORT_SYMBOL(pcmcia_register_socket);
2398 EXPORT_SYMBOL(pcmcia_unregister_socket);
2399 EXPORT_SYMBOL(pcmcia_suspend_socket);
2400 EXPORT_SYMBOL(pcmcia_resume_socket);
2401 
2402 static int __init init_pcmcia_cs(void)
2403 {
2404     printk(KERN_INFO "%s\n", release);
2405     printk(KERN_INFO "  %s\n", options);
2406     DEBUG(0, "%s\n", version);
2407     if (do_apm)
2408         pm_register(PM_SYS_DEV, PM_SYS_PCMCIA, handle_pm_event);
2409 #ifdef CONFIG_PROC_FS
2410     proc_pccard = proc_mkdir("pccard", proc_bus);
2411 #endif
2412     return 0;
2413 }
2414 
2415 static void __exit exit_pcmcia_cs(void)
2416 {
2417     printk(KERN_INFO "unloading PCMCIA Card Services\n");
2418 #ifdef CONFIG_PROC_FS
2419     if (proc_pccard) {
2420         remove_proc_entry("pccard", proc_bus);
2421     }
2422 #endif
2423     if (do_apm)
2424         pm_unregister_all(handle_pm_event);
2425     release_resource_db();
2426 }
2427 
2428 module_init(init_pcmcia_cs);
2429 module_exit(exit_pcmcia_cs);
2430 
2431 /*====================================================================*/
2432 
2433 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.