1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
85static const char *release = "Linux Kernel Card Services " CS_RELEASE;
86static const char *options = "options: " OPTIONS;
87
88
89
90
91
92MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
93MODULE_DESCRIPTION("Linux Kernel Card Services " CS_RELEASE
94 "\n options:" OPTIONS);
95MODULE_LICENSE("Dual MPL/GPL");
96
97#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
98
99INT_MODULE_PARM(setup_delay, 10);
100INT_MODULE_PARM(resume_delay, 20);
101INT_MODULE_PARM(shutdown_delay, 3);
102INT_MODULE_PARM(vcc_settle, 40);
103INT_MODULE_PARM(reset_time, 10);
104INT_MODULE_PARM(unreset_delay, 10);
105INT_MODULE_PARM(unreset_check, 10);
106INT_MODULE_PARM(unreset_limit, 30);
107
108
109INT_MODULE_PARM(cis_speed, 300);
110
111
112INT_MODULE_PARM(io_speed, 0);
113
114
115#ifdef CONFIG_PM
116INT_MODULE_PARM(do_apm, 1);
117#else
118INT_MODULE_PARM(do_apm, 0);
119#endif
120
121#ifdef PCMCIA_DEBUG
122INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
123static const char *version =
124"cs.c 1.279 2001/10/13 00:08:28 (David Hinds)";
125#endif
126
127
128
129socket_state_t dead_socket = {
130 0, SS_DETECT, 0, 0, 0
131};
132
133
134socket_t sockets = 0;
135socket_info_t *socket_table[MAX_SOCK];
136
137#ifdef CONFIG_PROC_FS
138struct proc_dir_entry *proc_pccard = NULL;
139#endif
140
141
142
143
144
145typedef struct lookup_t {
146 int key;
147 char *msg;
148} lookup_t;
149
150static 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
185static 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
241
242
243
244static 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
249static int get_socket_status(socket_info_t *s, int *val)
250{
251 return s->ss_entry->get_status(s->sock, val);
252}
253
254static int set_socket(socket_info_t *s, socket_state_t *state)
255{
256 return s->ss_entry->set_socket(s->sock, state);
257}
258
259static 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
264static 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
269static int suspend_socket(socket_info_t *s)
270{
271 s->socket = dead_socket;
272 return s->ss_entry->suspend(s->sock);
273}
274
275static 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)
284static 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
301
302
303
304
305static int setup_socket(socket_info_t *);
306static void shutdown_socket(socket_info_t *);
307static void reset_socket(socket_info_t *);
308static void unreset_socket(socket_info_t *);
309static void parse_events(void *info, u_int events);
310
311socket_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
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}
358
359int 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}
371
372
373
374void 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}
413
414void 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}
424
425
426
427
428
429
430
431
432
433
434
435static 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
446static int send_event(socket_info_t *s, event_t event, int priority);
447
448
449
450
451static void cs_sleep(unsigned int n_cs)
452{
453 current->state = TASK_INTERRUPTIBLE;
454 schedule_timeout( (n_cs * HZ + 99) / 100);
455}
456
457static void shutdown_socket(socket_info_t *s)
458{
459 client_t **c;
460
461 DEBUG(1, "cs: shutdown_socket(%p)\n", s);
462
463
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
474
475
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}
503
504
505
506
507static int setup_socket(socket_info_t *s)
508{
509 int val, ret;
510 int setup_timeout = 100;
511
512
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 }
554out:
555 return ret;
556}
557
558
559
560
561
562
563
564
565
566
567static 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}
578
579#define EVENT_MASK \
580(SOCKET_SETUP_PENDING|SOCKET_SUSPEND|SOCKET_RESET_PENDING)
581
582static void unreset_socket(socket_info_t *s)
583{
584 int setup_timeout = unreset_limit;
585 int val;
586
587
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}
627
628
629
630
631
632
633
634
635
636
637static 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}
655
656static 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
675static 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}
712
713
714
715
716
717
718
719
720
721
722void 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
731void pcmcia_resume_socket (socket_info_t *s)
732{
733 int stat;
734
735
736 init_socket(s);
737 get_socket_status(s, &stat);
738
739
740
741 if ((s->state & SOCKET_PRESENT) || (stat & SS_DETECT))
742 parse_events(s, SS_DETECT);
743}
744
745static 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
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}
772
773
774
775
776
777
778
779static 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
804
805
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
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
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}
842
843static 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
854 if (s->io[i].InUse == 0)
855 s->io[i].NumPorts = 0;
856 }
857 }
858}
859
860
861
862
863
864
865
866
867
868int 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}
909
910
911
912
913
914
915
916
917
918
919int 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}
945
946
947
948
949
950
951
952
953
954
955int 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}
981
982
983
984int 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
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}
1038
1039
1040
1041int 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
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}
1105
1106
1107
1108
1109
1110
1111
1112int 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}
1122
1123
1124
1125
1126
1127
1128
1129
1130int 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}
1144
1145
1146
1147int 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}
1163
1164
1165
1166int 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}
1198
1199int 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
1206int 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
1216
1217
1218
1219#ifdef CONFIG_CARDBUS
1220
1221struct 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
1234EXPORT_SYMBOL(pcmcia_lookup_bus);
1235
1236#endif
1237
1238
1239
1240
1241
1242
1243
1244
1245int 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
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
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}
1308
1309
1310
1311
1312
1313
1314
1315int 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}
1323
1324int 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}
1337
1338
1339
1340
1341
1342
1343
1344int 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
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}
1386
1387
1388
1389
1390
1391
1392
1393int 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}
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422int 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
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}
1496
1497
1498
1499int 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;
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}
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553int 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}
1587
1588
1589
1590int 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}
1623
1624
1625
1626int 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
1637 win->ctl.flags &= ~MAP_ACTIVE;
1638 set_mem_map(s, &win->ctl);
1639 s->state &= ~SOCKET_WIN_REQ(win->index);
1640
1641
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}
1650
1651
1652
1653int 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
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
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
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
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}
1787
1788
1789
1790
1791
1792
1793
1794
1795int 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}
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861int 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
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}
1927
1928
1929
1930
1931
1932
1933
1934
1935int 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
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
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
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
2006 req->Base = win->ctl.sys_start;
2007 *wh = win;
2008
2009 return CS_SUCCESS;
2010}
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020int 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}
2047
2048
2049
2050
2051
2052
2053
2054
2055int 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}
2075
2076int 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}
2094
2095
2096
2097
2098
2099
2100
2101int 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}
2126
2127int 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}
2155
2156
2157
2158
2159
2160
2161
2162
2163int 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}
2180
2181
2182
2183int 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}
2209
2210
2211
2212int 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
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
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}
2352
2353
2354
2355
2356
2357
2358
2359EXPORT_SYMBOL(pcmcia_access_configuration_register);
2360EXPORT_SYMBOL(pcmcia_adjust_resource_info);
2361EXPORT_SYMBOL(pcmcia_bind_device);
2362EXPORT_SYMBOL(pcmcia_bind_mtd);
2363EXPORT_SYMBOL(pcmcia_check_erase_queue);
2364EXPORT_SYMBOL(pcmcia_close_memory);
2365EXPORT_SYMBOL(pcmcia_copy_memory);
2366EXPORT_SYMBOL(pcmcia_deregister_client);
2367EXPORT_SYMBOL(pcmcia_deregister_erase_queue);
2368EXPORT_SYMBOL(pcmcia_eject_card);
2369EXPORT_SYMBOL(pcmcia_get_first_client);
2370EXPORT_SYMBOL(pcmcia_get_card_services_info);
2371EXPORT_SYMBOL(pcmcia_get_configuration_info);
2372EXPORT_SYMBOL(pcmcia_get_mem_page);
2373EXPORT_SYMBOL(pcmcia_get_next_client);
2374EXPORT_SYMBOL(pcmcia_get_first_region);
2375EXPORT_SYMBOL(pcmcia_get_first_tuple);
2376EXPORT_SYMBOL(pcmcia_get_first_window);
2377EXPORT_SYMBOL(pcmcia_get_next_region);
2378EXPORT_SYMBOL(pcmcia_get_next_tuple);
2379EXPORT_SYMBOL(pcmcia_get_next_window);
2380EXPORT_SYMBOL(pcmcia_get_status);
2381EXPORT_SYMBOL(pcmcia_get_tuple_data);
2382EXPORT_SYMBOL(pcmcia_insert_card);
2383EXPORT_SYMBOL(pcmcia_map_mem_page);
2384EXPORT_SYMBOL(pcmcia_modify_configuration);
2385EXPORT_SYMBOL(pcmcia_modify_window);
2386EXPORT_SYMBOL(pcmcia_open_memory);
2387EXPORT_SYMBOL(pcmcia_parse_tuple);
2388EXPORT_SYMBOL(pcmcia_read_memory);
2389EXPORT_SYMBOL(pcmcia_register_client);
2390EXPORT_SYMBOL(pcmcia_register_erase_queue);
2391EXPORT_SYMBOL(pcmcia_register_mtd);
2392EXPORT_SYMBOL(pcmcia_release_configuration);
2393EXPORT_SYMBOL(pcmcia_release_io);
2394EXPORT_SYMBOL(pcmcia_release_irq);
2395EXPORT_SYMBOL(pcmcia_release_window);
2396EXPORT_SYMBOL(pcmcia_replace_cis);
2397EXPORT_SYMBOL(pcmcia_report_error);
2398EXPORT_SYMBOL(pcmcia_request_configuration);
2399EXPORT_SYMBOL(pcmcia_request_io);
2400EXPORT_SYMBOL(pcmcia_request_irq);
2401EXPORT_SYMBOL(pcmcia_request_window);
2402EXPORT_SYMBOL(pcmcia_reset_card);
2403EXPORT_SYMBOL(pcmcia_resume_card);
2404EXPORT_SYMBOL(pcmcia_set_event_mask);
2405EXPORT_SYMBOL(pcmcia_suspend_card);
2406EXPORT_SYMBOL(pcmcia_validate_cis);
2407EXPORT_SYMBOL(pcmcia_write_memory);
2408
2409EXPORT_SYMBOL(dead_socket);
2410EXPORT_SYMBOL(register_ss_entry);
2411EXPORT_SYMBOL(unregister_ss_entry);
2412EXPORT_SYMBOL(CardServices);
2413EXPORT_SYMBOL(MTDHelperEntry);
2414#ifdef CONFIG_PROC_FS
2415EXPORT_SYMBOL(proc_pccard);
2416#endif
2417
2418EXPORT_SYMBOL(pcmcia_register_socket);
2419EXPORT_SYMBOL(pcmcia_unregister_socket);
2420EXPORT_SYMBOL(pcmcia_suspend_socket);
2421EXPORT_SYMBOL(pcmcia_resume_socket);
2422
2423static 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
2436static 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
2449module_init(init_pcmcia_cs);
2450module_exit(exit_pcmcia_cs);
2451
2452
2453
2454