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