1 /*======================================================================
3 PCMCIA Card Services -- core services
5 cs.c 1.225 1999/09/07 15:19:32
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/
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.
17 The initial developer of the original code is David A. Hinds
18 <dhinds@hyper.stanford.edu>. Portions created by David A. Hinds
19 are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
21 Alternatively, the contents of this file may be used under the
22 terms of the GNU Public License version 2 (the "GPL"), in which
23 case the provisions of the GPL are applicable instead of the
24 above. If you wish to allow the use of your version of this file
25 only under the terms of the GPL and not to allow others to use
26 your version of this file under the MPL, indicate your decision
27 by deleting the provisions above and replace them with the notice
28 and other provisions required by the GPL. If you do not delete
29 the provisions above, a recipient may use your version of this
30 file under either the MPL or the GPL.
32 ======================================================================*/
34 #include <linux/module.h>
35 #include <linux/kernel.h>
36 #include <linux/string.h>
37 #include <linux/major.h>
38 #include <linux/errno.h>
39 #include <linux/malloc.h>
41 #include <linux/sched.h>
42 #include <linux/timer.h>
43 #include <linux/ioport.h>
44 #include <linux/delay.h>
45 #include <linux/proc_fs.h>
46 #include <asm/system.h>
49 #define IN_CARD_SERVICES
50 #include <pcmcia/version.h>
51 #include <pcmcia/cs_types.h>
52 #include <pcmcia/ss.h>
53 #include <pcmcia/cs.h>
54 #include <pcmcia/bulkmem.h>
55 #include <pcmcia/cistpl.h>
56 #include <pcmcia/cisreg.h>
57 #include <pcmcia/bus_ops.h>
58 #include "cs_internal.h"
62 #include <linux/apm_bios.h>
63 static int handle_apm_event(apm_event_t event
);
67 int pc_debug
= PCMCIA_DEBUG
;
68 MODULE_PARM(pc_debug
, "i");
69 static const char *version
=
70 "cs.c 1.225 1999/09/07 15:19:32 (David Hinds)";
73 static const char *release
= "Linux PCMCIA Card Services " CS_RELEASE
;
75 static const char *options
= "options: "
85 #if !defined(CONFIG_CARDBUS) && !defined(CONFIG_PCI) && !defined(CONFIG_APM)
90 /*====================================================================*/
92 /* Parameters that can be set with 'insmod' */
94 static int setup_delay
= HZ
/20; /* ticks */
95 static int resume_delay
= HZ
/5; /* ticks */
96 static int shutdown_delay
= HZ
/40; /* ticks */
97 static int vcc_settle
= HZ
*3/10; /* ticks */
98 static int reset_time
= 10; /* usecs */
99 static int unreset_delay
= HZ
/10; /* ticks */
100 static int unreset_check
= HZ
/10; /* ticks */
101 static int unreset_limit
= 30; /* unreset_check's */
103 /* Access speed for attribute memory windows */
104 static int cis_speed
= 300; /* ns */
106 /* Access speed for IO windows */
107 static int io_speed
= 0; /* ns */
109 /* Optional features */
111 static int do_apm
= 1;
112 MODULE_PARM(do_apm
, "i");
115 MODULE_PARM(setup_delay
, "i");
116 MODULE_PARM(resume_delay
, "i");
117 MODULE_PARM(shutdown_delay
, "i");
118 MODULE_PARM(vcc_settle
, "i");
119 MODULE_PARM(reset_time
, "i");
120 MODULE_PARM(unreset_delay
, "i");
121 MODULE_PARM(unreset_check
, "i");
122 MODULE_PARM(unreset_limit
, "i");
123 MODULE_PARM(cis_speed
, "i");
124 MODULE_PARM(io_speed
, "i");
126 /*====================================================================*/
128 static socket_state_t dead_socket
= {
129 0, SS_DETECT
, 0, 0, 0
132 /* Table of sockets */
133 socket_t sockets
= 0;
134 socket_info_t
*socket_table
[MAX_SOCK
];
136 #ifdef CONFIG_PROC_FS
137 struct proc_dir_entry
*proc_pccard
= NULL
;
140 /*====================================================================*/
142 /* String tables for error messages */
144 typedef struct lookup_t
{
149 static const lookup_t error_table
[] = {
150 { CS_SUCCESS
, "Operation succeeded" },
151 { CS_BAD_ADAPTER
, "Bad adapter" },
152 { CS_BAD_ATTRIBUTE
, "Bad attribute", },
153 { CS_BAD_BASE
, "Bad base address" },
154 { CS_BAD_EDC
, "Bad EDC" },
155 { CS_BAD_IRQ
, "Bad IRQ" },
156 { CS_BAD_OFFSET
, "Bad offset" },
157 { CS_BAD_PAGE
, "Bad page number" },
158 { CS_READ_FAILURE
, "Read failure" },
159 { CS_BAD_SIZE
, "Bad size" },
160 { CS_BAD_SOCKET
, "Bad socket" },
161 { CS_BAD_TYPE
, "Bad type" },
162 { CS_BAD_VCC
, "Bad Vcc" },
163 { CS_BAD_VPP
, "Bad Vpp" },
164 { CS_BAD_WINDOW
, "Bad window" },
165 { CS_WRITE_FAILURE
, "Write failure" },
166 { CS_NO_CARD
, "No card present" },
167 { CS_UNSUPPORTED_FUNCTION
, "Usupported function" },
168 { CS_UNSUPPORTED_MODE
, "Unsupported mode" },
169 { CS_BAD_SPEED
, "Bad speed" },
170 { CS_BUSY
, "Resource busy" },
171 { CS_GENERAL_FAILURE
, "General failure" },
172 { CS_WRITE_PROTECTED
, "Write protected" },
173 { CS_BAD_ARG_LENGTH
, "Bad argument length" },
174 { CS_BAD_ARGS
, "Bad arguments" },
175 { CS_CONFIGURATION_LOCKED
, "Configuration locked" },
176 { CS_IN_USE
, "Resource in use" },
177 { CS_NO_MORE_ITEMS
, "No more items" },
178 { CS_OUT_OF_RESOURCE
, "Out of resource" },
179 { CS_BAD_HANDLE
, "Bad handle" },
180 { CS_BAD_TUPLE
, "Bad CIS tuple" }
182 #define ERROR_COUNT (sizeof(error_table)/sizeof(lookup_t))
184 static const lookup_t service_table
[] = {
185 { AccessConfigurationRegister
, "AccessConfigurationRegister" },
186 { AddSocketServices
, "AddSocketServices" },
187 { AdjustResourceInfo
, "AdjustResourceInfo" },
188 { CheckEraseQueue
, "CheckEraseQueue" },
189 { CloseMemory
, "CloseMemory" },
190 { DeregisterClient
, "DeregisterClient" },
191 { DeregisterEraseQueue
, "DeregisterEraseQueue" },
192 { GetCardServicesInfo
, "GetCardServicesInfo" },
193 { GetClientInfo
, "GetClientInfo" },
194 { GetConfigurationInfo
, "GetConfigurationInfo" },
195 { GetEventMask
, "GetEventMask" },
196 { GetFirstClient
, "GetFirstClient" },
197 { GetFirstRegion
, "GetFirstRegion" },
198 { GetFirstTuple
, "GetFirstTuple" },
199 { GetNextClient
, "GetNextClient" },
200 { GetNextRegion
, "GetNextRegion" },
201 { GetNextTuple
, "GetNextTuple" },
202 { GetStatus
, "GetStatus" },
203 { GetTupleData
, "GetTupleData" },
204 { MapMemPage
, "MapMemPage" },
205 { ModifyConfiguration
, "ModifyConfiguration" },
206 { ModifyWindow
, "ModifyWindow" },
207 { OpenMemory
, "OpenMemory" },
208 { ParseTuple
, "ParseTuple" },
209 { ReadMemory
, "ReadMemory" },
210 { RegisterClient
, "RegisterClient" },
211 { RegisterEraseQueue
, "RegisterEraseQueue" },
212 { RegisterMTD
, "RegisterMTD" },
213 { ReleaseConfiguration
, "ReleaseConfiguration" },
214 { ReleaseIO
, "ReleaseIO" },
215 { ReleaseIRQ
, "ReleaseIRQ" },
216 { ReleaseWindow
, "ReleaseWindow" },
217 { RequestConfiguration
, "RequestConfiguration" },
218 { RequestIO
, "RequestIO" },
219 { RequestIRQ
, "RequestIRQ" },
220 { RequestSocketMask
, "RequestSocketMask" },
221 { RequestWindow
, "RequestWindow" },
222 { ResetCard
, "ResetCard" },
223 { SetEventMask
, "SetEventMask" },
224 { ValidateCIS
, "ValidateCIS" },
225 { WriteMemory
, "WriteMemory" },
226 { BindDevice
, "BindDevice" },
227 { BindMTD
, "BindMTD" },
228 { ReportError
, "ReportError" },
229 { SuspendCard
, "SuspendCard" },
230 { ResumeCard
, "ResumeCard" },
231 { EjectCard
, "EjectCard" },
232 { InsertCard
, "InsertCard" },
233 { ReplaceCIS
, "ReplaceCIS" }
235 #define SERVICE_COUNT (sizeof(service_table)/sizeof(lookup_t))
237 /*======================================================================
239 Reset a socket to the default state
241 ======================================================================*/
243 static void init_socket(socket_info_t
*s
)
246 pccard_io_map io
= { 0, 0, 0, 0, 1 };
247 pccard_mem_map mem
= { 0, 0, 0, 0, 0, 0 };
249 mem
.sys_stop
= s
->cap
.map_size
;
250 s
->socket
= dead_socket
;
251 s
->ss_entry(s
->sock
, SS_SetSocket
, &s
->socket
);
252 for (i
= 0; i
< 2; i
++) {
254 s
->ss_entry(s
->sock
, SS_SetIOMap
, &io
);
256 for (i
= 0; i
< 5; i
++) {
258 s
->ss_entry(s
->sock
, SS_SetMemMap
, &mem
);
262 /*====================================================================*/
264 #if defined(CONFIG_PROC_FS) && defined(PCMCIA_DEBUG)
265 int proc_read_clients(char *buf
, char **start
, off_t pos
,
266 int count
, int *eof
, void *data
)
268 socket_info_t
*s
= data
;
272 for (c
= s
->clients
; c
; c
= c
->next
)
273 p
+= sprintf(p
, "fn %x: '%s' [attr 0x%04x] [state 0x%04x]\n",
274 c
->Function
, c
->dev_info
, c
->Attributes
, c
->state
);
279 /*======================================================================
281 Low-level PC Card interface drivers need to register with Card
282 Services using these calls.
284 ======================================================================*/
286 static void setup_socket(u_long i
);
287 static void shutdown_socket(u_long i
);
288 static void reset_socket(u_long i
);
289 static void unreset_socket(u_long i
);
290 static void parse_events(void *info
, u_int events
);
292 int register_ss_entry(int nsock
, ss_entry_t ss_entry
)
297 DEBUG(0, "cs: register_ss_entry(%d, 0x%p)\n", nsock
, ss_entry
);
299 for (ns
= 0; ns
< nsock
; ns
++) {
300 s
= kmalloc(sizeof(struct socket_info_t
), GFP_KERNEL
);
301 memset(s
, 0, sizeof(socket_info_t
));
303 s
->ss_entry
= ss_entry
;
305 s
->setup
.data
= sockets
;
306 s
->setup
.function
= &setup_socket
;
307 s
->shutdown
.data
= sockets
;
308 s
->shutdown
.function
= &shutdown_socket
;
309 /* base address = 0, map = 0 */
310 s
->cis_mem
.flags
= 0;
311 s
->cis_mem
.speed
= cis_speed
;
312 s
->erase_busy
.next
= s
->erase_busy
.prev
= &s
->erase_busy
;
314 for (i
= 0; i
< sockets
; i
++)
315 if (socket_table
[i
] == NULL
) break;
317 if (i
== sockets
) sockets
++;
320 ss_entry(ns
, SS_InquireSocket
, &s
->cap
);
321 #ifdef CONFIG_PROC_FS
325 struct proc_dir_entry
*ent
;
327 sprintf(name
, "%02d", i
);
328 s
->proc
= create_proc_entry(name
, S_IFDIR
, proc_pccard
);
330 ent
= create_proc_entry("clients", 0, s
->proc
);
331 ent
->read_proc
= proc_read_clients
;
334 ss_entry(ns
, SS_ProcSetup
, s
->proc
);
340 } /* register_ss_entry */
342 /*====================================================================*/
344 void unregister_ss_entry(ss_entry_t ss_entry
)
347 socket_info_t
*s
= NULL
;
351 for (i
= 0; i
< sockets
; i
++) {
353 if (s
->ss_entry
== ss_entry
) break;
358 #ifdef CONFIG_PROC_FS
361 sprintf(name
, "%02d", i
);
363 remove_proc_entry("clients", s
->proc
);
365 remove_proc_entry(name
, proc_pccard
);
370 s
->clients
= s
->clients
->next
;
375 #ifdef CONFIG_CARDBUS
376 cb_release_cis_mem(s
);
380 socket_table
[i
] = NULL
;
381 for (j
= i
; j
< sockets
-1; j
++)
382 socket_table
[j
] = socket_table
[j
+1];
387 } /* unregister_ss_entry */
389 /*======================================================================
391 Shutdown_Socket() and setup_socket() are scheduled using add_timer
392 calls by the main event handler when card insertion and removal
393 events are received. Shutdown_Socket() unconfigures a socket and
394 turns off socket power. Setup_socket() turns on socket power
395 and resets the socket, in two stages.
397 ======================================================================*/
399 static void free_regions(memory_handle_t
*list
)
402 while (*list
!= NULL
) {
404 *list
= tmp
->info
.next
;
405 tmp
->region_magic
= 0;
410 static int send_event(socket_info_t
*s
, event_t event
, int priority
);
412 static void shutdown_socket(u_long i
)
414 socket_info_t
*s
= socket_table
[i
];
417 DEBUG(1, "cs: shutdown_socket(%ld)\n", i
);
419 /* Blank out the socket state */
420 s
->state
&= SOCKET_PRESENT
|SOCKET_SETUP_PENDING
;
422 s
->irq
.AssignedIRQ
= s
->irq
.Config
= 0;
430 #ifdef CONFIG_CARDBUS
431 cb_release_cis_mem(s
);
438 for (c
= &s
->clients
; *c
; ) {
439 if ((*c
)->state
& CLIENT_UNBOUND
) {
447 free_regions(&s
->a_region
);
448 free_regions(&s
->c_region
);
449 } /* shutdown_socket */
451 static void setup_socket(u_long i
)
454 socket_info_t
*s
= socket_table
[i
];
456 s
->ss_entry(s
->sock
, SS_GetStatus
, &val
);
457 if (val
& SS_DETECT
) {
458 DEBUG(1, "cs: setup_socket(%ld): applying power\n", i
);
459 s
->state
|= SOCKET_PRESENT
;
462 s
->socket
.Vcc
= s
->socket
.Vpp
= 33;
463 else if (!(val
& SS_XVCARD
))
464 s
->socket
.Vcc
= s
->socket
.Vpp
= 50;
466 printk(KERN_NOTICE
"cs: socket %ld: unsupported "
470 if (val
& SS_CARDBUS
) {
471 s
->state
|= SOCKET_CARDBUS
;
472 #ifndef CONFIG_CARDBUS
473 printk(KERN_NOTICE
"cs: unsupported card type detected!\n");
476 s
->ss_entry(s
->sock
, SS_SetSocket
, &s
->socket
);
477 s
->setup
.function
= &reset_socket
;
478 s
->setup
.expires
= jiffies
+ vcc_settle
;
479 add_timer(&s
->setup
);
481 DEBUG(0, "cs: setup_socket(%ld): no card!\n", i
);
484 /*======================================================================
486 Reset_socket() and unreset_socket() handle hard resets. Resets
487 have several causes: card insertion, a call to reset_socket, or
488 recovery from a suspend/resume cycle. Unreset_socket() sends
489 a CS event that matches the cause of the reset.
491 ======================================================================*/
493 static void reset_socket(u_long i
)
495 socket_info_t
*s
= socket_table
[i
];
497 DEBUG(1, "cs: resetting socket %ld\n", i
);
498 s
->socket
.flags
|= SS_OUTPUT_ENA
| SS_RESET
;
499 s
->ss_entry(s
->sock
, SS_SetSocket
, &s
->socket
);
500 udelay((long)reset_time
);
501 s
->socket
.flags
&= ~SS_RESET
;
502 s
->ss_entry(s
->sock
, SS_SetSocket
, &s
->socket
);
503 s
->unreset_timeout
= 0;
504 s
->setup
.expires
= jiffies
+ unreset_delay
;
505 s
->setup
.function
= &unreset_socket
;
506 add_timer(&s
->setup
);
510 (SOCKET_SETUP_PENDING|SOCKET_SUSPEND|SOCKET_RESET_PENDING)
512 static void unreset_socket(u_long i
)
514 socket_info_t
*s
= socket_table
[i
];
517 s
->ss_entry(s
->sock
, SS_GetStatus
, &val
);
518 if (val
& SS_READY
) {
519 DEBUG(1, "cs: reset done on socket %ld\n", i
);
520 if (s
->state
& SOCKET_SUSPEND
) {
521 s
->state
&= ~EVENT_MASK
;
522 if (verify_cis_cache(s
) != 0)
523 parse_events(s
, SS_DETECT
);
525 send_event(s
, CS_EVENT_PM_RESUME
, CS_EVENT_PRI_LOW
);
526 } else if (s
->state
& SOCKET_SETUP_PENDING
) {
527 #ifdef CONFIG_CARDBUS
528 if (s
->state
& SOCKET_CARDBUS
)
531 send_event(s
, CS_EVENT_CARD_INSERTION
, CS_EVENT_PRI_LOW
);
532 s
->state
&= ~SOCKET_SETUP_PENDING
;
534 send_event(s
, CS_EVENT_CARD_RESET
, CS_EVENT_PRI_LOW
);
535 s
->reset_handle
->event_callback_args
.info
= NULL
;
536 EVENT(s
->reset_handle
, CS_EVENT_RESET_COMPLETE
,
538 s
->state
&= ~EVENT_MASK
;
541 DEBUG(2, "cs: socket %ld not ready yet\n", i
);
542 if (s
->unreset_timeout
> unreset_limit
) {
543 printk(KERN_NOTICE
"cs: socket %ld timed out during"
545 s
->state
&= ~EVENT_MASK
;
547 s
->unreset_timeout
++;
548 s
->setup
.expires
= jiffies
+ unreset_check
;
549 add_timer(&s
->setup
);
552 } /* unreset_socket */
554 /*======================================================================
556 The central event handler. Send_event() sends an event to all
557 valid clients. Parse_events() interprets the event bits from
558 a card status change report. Do_shotdown() handles the high
559 priority stuff associated with a card removal.
561 ======================================================================*/
563 static int send_event(socket_info_t
*s
, event_t event
, int priority
)
565 client_t
*client
= s
->clients
;
567 DEBUG(1, "cs: send_event(sock %d, event %d, pri %d)\n",
568 s
->sock
, event
, priority
);
570 for (; client
; client
= client
->next
) {
571 if (client
->state
& (CLIENT_UNBOUND
|CLIENT_STALE
))
573 if (client
->EventMask
& event
) {
574 ret
= EVENT(client
, event
, priority
);
582 static void do_shutdown(socket_info_t
*s
)
585 if (s
->state
& SOCKET_SHUTDOWN_PENDING
)
587 s
->state
|= SOCKET_SHUTDOWN_PENDING
;
588 send_event(s
, CS_EVENT_CARD_REMOVAL
, CS_EVENT_PRI_HIGH
);
589 for (client
= s
->clients
; client
; client
= client
->next
)
590 if (!(client
->Attributes
& INFO_MASTER_CLIENT
))
591 client
->state
|= CLIENT_STALE
;
592 if (s
->state
& (SOCKET_SETUP_PENDING
|SOCKET_RESET_PENDING
)) {
593 DEBUG(0, "cs: flushing pending setup\n");
594 del_timer(&s
->setup
);
595 s
->state
&= ~EVENT_MASK
;
597 s
->shutdown
.expires
= jiffies
+ shutdown_delay
;
598 add_timer(&s
->shutdown
);
599 s
->state
&= ~SOCKET_PRESENT
;
602 static void parse_events(void *info
, u_int events
)
604 socket_info_t
*s
= info
;
605 if (events
& SS_DETECT
) {
608 spin_lock_irqsave(&s
->lock
, flags
);
609 s
->ss_entry(s
->sock
, SS_GetStatus
, &status
);
610 if ((s
->state
& SOCKET_PRESENT
) &&
611 (!(s
->state
& SOCKET_SUSPEND
) ||
612 !(status
& SS_DETECT
)))
614 if (status
& SS_DETECT
) {
615 if (s
->state
& SOCKET_SETUP_PENDING
) {
616 del_timer(&s
->setup
);
617 DEBUG(1, "cs: delaying pending setup\n");
619 s
->state
|= SOCKET_SETUP_PENDING
;
620 s
->setup
.function
= &setup_socket
;
621 if (s
->state
& SOCKET_SUSPEND
)
622 s
->setup
.expires
= jiffies
+ resume_delay
;
624 s
->setup
.expires
= jiffies
+ setup_delay
;
625 add_timer(&s
->setup
);
627 spin_unlock_irqrestore(&s
->lock
, flags
);
629 if (events
& SS_BATDEAD
)
630 send_event(s
, CS_EVENT_BATTERY_DEAD
, CS_EVENT_PRI_LOW
);
631 if (events
& SS_BATWARN
)
632 send_event(s
, CS_EVENT_BATTERY_LOW
, CS_EVENT_PRI_LOW
);
633 if (events
& SS_READY
) {
634 if (!(s
->state
& SOCKET_RESET_PENDING
))
635 send_event(s
, CS_EVENT_READY_CHANGE
, CS_EVENT_PRI_LOW
);
636 else DEBUG(1, "cs: ready change during reset\n");
640 /*======================================================================
642 Another event handler, for power management events.
644 This does not comply with the latest PC Card spec for handling
645 power management events.
647 ======================================================================*/
650 static int handle_apm_event(apm_event_t event
)
657 case APM_SYS_SUSPEND
:
658 case APM_USER_SUSPEND
:
659 DEBUG(1, "cs: received suspend notification\n");
661 printk(KERN_DEBUG
"cs: received extra suspend event\n");
665 for (i
= 0; i
< sockets
; i
++) {
667 if ((s
->state
& SOCKET_PRESENT
) &&
668 !(s
->state
& SOCKET_SUSPEND
)){
669 send_event(s
, CS_EVENT_PM_SUSPEND
, CS_EVENT_PRI_LOW
);
670 s
->ss_entry(s
->sock
, SS_SetSocket
, &dead_socket
);
671 s
->state
|= SOCKET_SUSPEND
;
675 case APM_NORMAL_RESUME
:
676 case APM_CRITICAL_RESUME
:
677 DEBUG(1, "cs: received resume notification\n");
679 printk(KERN_DEBUG
"cs: received bogus resume event\n");
683 for (i
= 0; i
< sockets
; i
++) {
685 /* Do this just to reinitialize the socket */
687 s
->ss_entry(s
->sock
, SS_GetStatus
, &stat
);
688 /* If there was or is a card here, we need to do something
689 about it... but parse_events will sort it all out. */
690 if ((s
->state
& SOCKET_PRESENT
) || (stat
& SS_DETECT
))
691 parse_events(s
, SS_DETECT
);
696 } /* handle_apm_event */
699 /*======================================================================
701 Special stuff for managing IO windows, because they are scarce.
703 ======================================================================*/
705 static int alloc_io_space(socket_info_t
*s
, u_int attr
, ioaddr_t
*base
,
706 ioaddr_t num
, char *name
)
711 for (i
= 0; i
< MAX_IO_WIN
; i
++) {
712 if (s
->io
[i
].NumPorts
== 0) {
713 if (find_io_region(base
, num
, name
) == 0) {
714 s
->io
[i
].Attributes
= attr
;
715 s
->io
[i
].BasePort
= *base
;
716 s
->io
[i
].NumPorts
= s
->io
[i
].InUse
= num
;
720 } else if (s
->io
[i
].Attributes
!= attr
)
722 /* Try to extend top of window */
723 try = s
->io
[i
].BasePort
+ s
->io
[i
].NumPorts
;
724 if ((*base
== 0) || (*base
== try))
725 if (find_io_region(&try, num
, name
) == 0) {
727 s
->io
[i
].NumPorts
+= num
;
728 s
->io
[i
].InUse
+= num
;
731 /* Try to extend bottom of window */
732 try = s
->io
[i
].BasePort
- num
;
733 if ((*base
== 0) || (*base
== try))
734 if (find_io_region(&try, num
, name
) == 0) {
735 s
->io
[i
].BasePort
= *base
= try;
736 s
->io
[i
].NumPorts
+= num
;
737 s
->io
[i
].InUse
+= num
;
741 return (i
== MAX_IO_WIN
);
742 } /* alloc_io_space */
744 static void release_io_space(socket_info_t
*s
, ioaddr_t base
,
748 release_region(base
, num
);
749 for (i
= 0; i
< MAX_IO_WIN
; i
++) {
750 if ((s
->io
[i
].BasePort
<= base
) &&
751 (s
->io
[i
].BasePort
+s
->io
[i
].NumPorts
>= base
+num
)) {
752 s
->io
[i
].InUse
-= num
;
753 /* Free the window if no one else is using it */
754 if (s
->io
[i
].InUse
== 0)
755 s
->io
[i
].NumPorts
= 0;
760 /*======================================================================
762 Access_configuration_register() reads and writes configuration
763 registers in attribute memory. Memory window 0 is reserved for
764 this and the tuple reading services.
766 ======================================================================*/
768 static int access_configuration_register(client_handle_t handle
,
776 if (CHECK_HANDLE(handle
))
777 return CS_BAD_HANDLE
;
779 if (handle
->Function
== BIND_FN_ALL
) {
780 if (reg
->Function
>= s
->functions
)
782 c
= &s
->config
[reg
->Function
];
785 if (!(c
->state
& CONFIG_LOCKED
))
786 return CS_CONFIGURATION_LOCKED
;
788 addr
= (c
->ConfigBase
+ reg
->Offset
) >> 1;
790 switch (reg
->Action
) {
792 read_cis_mem(s
, 1, addr
, 1, &val
);
797 write_cis_mem(s
, 1, addr
, 1, &val
);
804 } /* access_configuration_register */
806 /*======================================================================
808 Bind_device() associates a device driver with a particular socket.
809 It is normally called by Driver Services after it has identified
810 a newly inserted card. An instance of that driver will then be
811 eligible to register as a client of this socket.
813 ======================================================================*/
815 static int bind_device(bind_req_t
*req
)
820 if (CHECK_SOCKET(req
->Socket
))
821 return CS_BAD_SOCKET
;
824 client
= (client_t
*)kmalloc(sizeof(client_t
), GFP_KERNEL
);
825 memset(client
, '\0', sizeof(client_t
));
826 client
->client_magic
= CLIENT_MAGIC
;
827 strncpy(client
->dev_info
, (char *)req
->dev_info
, DEV_NAME_LEN
);
828 client
->Socket
= req
->Socket
;
829 client
->Function
= req
->Function
;
830 client
->state
= CLIENT_UNBOUND
;
831 client
->erase_busy
.next
= &client
->erase_busy
;
832 client
->erase_busy
.prev
= &client
->erase_busy
;
833 init_waitqueue_head(&client
->mtd_req
);
834 client
->next
= s
->clients
;
836 DEBUG(1, "cs: bind_device(): client 0x%p, sock %d, dev %s\n",
837 client
, client
->Socket
, client
->dev_info
);
841 /*======================================================================
843 Bind_mtd() associates a device driver with a particular memory
844 region. It is normally called by Driver Services after it has
845 identified a memory device type. An instance of the corresponding
846 driver will then be able to register to control this region.
848 ======================================================================*/
850 static int bind_mtd(mtd_bind_t
*req
)
853 memory_handle_t region
;
855 if (CHECK_SOCKET(req
->Socket
))
856 return CS_BAD_SOCKET
;
859 if (req
->Attributes
& REGION_TYPE_AM
)
860 region
= s
->a_region
;
862 region
= s
->c_region
;
865 if (region
->info
.CardOffset
== req
->CardOffset
) break;
866 region
= region
->info
.next
;
868 if (!region
|| (region
->mtd
!= NULL
))
869 return CS_BAD_OFFSET
;
870 strncpy(region
->dev_info
, (char *)req
->dev_info
, DEV_NAME_LEN
);
872 DEBUG(1, "cs: bind_mtd(): attr 0x%x, offset 0x%x, dev %s\n",
873 req
->Attributes
, req
->CardOffset
, (char *)req
->dev_info
);
877 /*====================================================================*/
879 static int deregister_client(client_handle_t handle
)
883 memory_handle_t region
;
887 DEBUG(1, "cs: deregister_client(%p)\n", handle
);
888 if (CHECK_HANDLE(handle
))
889 return CS_BAD_HANDLE
;
891 (CLIENT_IRQ_REQ
|CLIENT_IO_REQ
|CLIENT_CONFIG_LOCKED
))
893 for (i
= 0; i
< MAX_WIN
; i
++)
894 if (handle
->state
& CLIENT_WIN_REQ(i
))
897 /* Disconnect all MTD links */
899 if (handle
->mtd_count
) {
900 for (region
= s
->a_region
; region
; region
= region
->info
.next
)
901 if (region
->mtd
== handle
) region
->mtd
= NULL
;
902 for (region
= s
->c_region
; region
; region
= region
->info
.next
)
903 if (region
->mtd
== handle
) region
->mtd
= NULL
;
906 sn
= handle
->Socket
; s
= socket_table
[sn
];
908 if ((handle
->state
& CLIENT_STALE
) ||
909 (handle
->Attributes
& INFO_MASTER_CLIENT
)) {
910 spin_lock_irqsave(&s
->lock
, flags
);
911 client
= &s
->clients
;
912 while ((*client
) && ((*client
) != handle
))
913 client
= &(*client
)->next
;
915 return CS_BAD_HANDLE
;
916 *client
= handle
->next
;
917 handle
->client_magic
= 0;
919 spin_unlock_irqrestore(&s
->lock
, flags
);
921 handle
->state
= CLIENT_UNBOUND
;
922 handle
->mtd_count
= 0;
923 handle
->event_handler
= NULL
;
926 if (--s
->real_clients
== 0)
927 s
->ss_entry(sn
, SS_RegisterCallback
, NULL
);
930 } /* deregister_client */
932 /*====================================================================*/
934 static int get_configuration_info(client_handle_t handle
,
935 config_info_t
*config
)
940 if (CHECK_HANDLE(handle
))
941 return CS_BAD_HANDLE
;
943 if (!(s
->state
& SOCKET_PRESENT
))
946 if (handle
->Function
== BIND_FN_ALL
) {
947 if (config
->Function
&& (config
->Function
>= s
->functions
))
950 config
->Function
= handle
->Function
;
952 #ifdef CONFIG_CARDBUS
953 if (s
->state
& SOCKET_CARDBUS
) {
954 u_char fn
= config
->Function
;
955 memset(config
, 0, sizeof(config_info_t
));
956 config
->Function
= fn
;
957 config
->Vcc
= s
->socket
.Vcc
;
958 config
->Vpp1
= config
->Vpp2
= s
->socket
.Vpp
;
959 config
->Option
= s
->cap
.cardbus
;
961 config
->Attributes
= CONF_VALID_CLIENT
;
962 config
->IntType
= INT_CARDBUS
;
963 config
->AssignedIRQ
= s
->irq
.AssignedIRQ
;
964 if (config
->AssignedIRQ
)
965 config
->Attributes
|= CONF_ENABLE_IRQ
;
966 config
->BasePort1
= s
->io
[0].BasePort
;
967 config
->NumPorts1
= s
->io
[0].NumPorts
;
973 c
= (s
->config
!= NULL
) ? &s
->config
[config
->Function
] : NULL
;
975 if ((c
== NULL
) || !(c
->state
& CONFIG_LOCKED
)) {
976 config
->Attributes
= 0;
977 config
->Vcc
= s
->socket
.Vcc
;
978 config
->Vpp1
= config
->Vpp2
= s
->socket
.Vpp
;
982 /* !!! This is a hack !!! */
983 memcpy(&config
->Attributes
, &c
->Attributes
, sizeof(config_t
));
984 config
->Attributes
|= CONF_VALID_CLIENT
;
985 config
->CardValues
= c
->CardValues
;
986 config
->IRQAttributes
= c
->irq
.Attributes
;
987 config
->AssignedIRQ
= s
->irq
.AssignedIRQ
;
988 config
->BasePort1
= c
->io
.BasePort1
;
989 config
->NumPorts1
= c
->io
.NumPorts1
;
990 config
->Attributes1
= c
->io
.Attributes1
;
991 config
->BasePort2
= c
->io
.BasePort2
;
992 config
->NumPorts2
= c
->io
.NumPorts2
;
993 config
->Attributes2
= c
->io
.Attributes2
;
994 config
->IOAddrLines
= c
->io
.IOAddrLines
;
997 } /* get_configuration_info */
999 /*======================================================================
1001 Return information about this version of Card Services.
1003 ======================================================================*/
1005 static int get_card_services_info(servinfo_t
*info
)
1007 info
->Signature
[0] = 'C';
1008 info
->Signature
[1] = 'S';
1009 info
->Count
= sockets
;
1010 info
->Revision
= CS_RELEASE_CODE
;
1011 info
->CSLevel
= 0x0210;
1012 info
->VendorString
= (char *)release
;
1014 } /* get_card_services_info */
1016 /*======================================================================
1018 Note that get_first_client() *does* recognize the Socket field
1019 in the request structure.
1021 ======================================================================*/
1023 static int get_first_client(client_handle_t
*handle
, client_req_t
*req
)
1026 if (req
->Attributes
& CLIENT_THIS_SOCKET
)
1030 if (CHECK_SOCKET(req
->Socket
))
1031 return CS_BAD_SOCKET
;
1032 if (socket_table
[s
]->clients
== NULL
)
1033 return CS_NO_MORE_ITEMS
;
1034 *handle
= socket_table
[s
]->clients
;
1036 } /* get_first_client */
1038 /*====================================================================*/
1040 static int get_next_client(client_handle_t
*handle
, client_req_t
*req
)
1043 if ((handle
== NULL
) || CHECK_HANDLE(*handle
))
1044 return CS_BAD_HANDLE
;
1045 if ((*handle
)->next
== NULL
) {
1046 if (req
->Attributes
& CLIENT_THIS_SOCKET
)
1047 return CS_NO_MORE_ITEMS
;
1048 s
= SOCKET(*handle
);
1049 if (s
->clients
== NULL
)
1050 return CS_NO_MORE_ITEMS
;
1051 *handle
= s
->clients
;
1053 *handle
= (*handle
)->next
;
1055 } /* get_next_client */
1057 /*====================================================================*/
1059 static int get_window(window_handle_t
*handle
, int idx
, win_req_t
*req
)
1066 s
= SOCKET((client_handle_t
)*handle
);
1068 s
= (*handle
)->sock
;
1069 if (!(s
->state
& SOCKET_PRESENT
))
1071 for (w
= idx
; w
< MAX_WIN
; w
++)
1072 if (s
->state
& SOCKET_WIN_REQ(w
)) break;
1074 return CS_NO_MORE_ITEMS
;
1076 req
->Base
= win
->ctl
.sys_start
;
1077 req
->Size
= win
->ctl
.sys_stop
- win
->ctl
.sys_start
+ 1;
1078 req
->AccessSpeed
= win
->ctl
.speed
;
1079 req
->Attributes
= 0;
1080 if (win
->ctl
.flags
& MAP_ATTRIB
)
1081 req
->Attributes
|= WIN_MEMORY_TYPE_AM
;
1082 if (win
->ctl
.flags
& MAP_ACTIVE
)
1083 req
->Attributes
|= WIN_ENABLE
;
1084 if (win
->ctl
.flags
& MAP_16BIT
)
1085 req
->Attributes
|= WIN_DATA_WIDTH
;
1086 if (win
->ctl
.flags
& MAP_USE_WAIT
)
1087 req
->Attributes
|= WIN_USE_WAIT
;
1092 static int get_first_window(client_handle_t
*handle
, win_req_t
*req
)
1094 if ((handle
== NULL
) || CHECK_HANDLE(*handle
))
1095 return CS_BAD_HANDLE
;
1096 return get_window((window_handle_t
*)handle
, 0, req
);
1099 static int get_next_window(window_handle_t
*win
, win_req_t
*req
)
1101 if ((win
== NULL
) || ((*win
)->magic
!= WINDOW_MAGIC
))
1102 return CS_BAD_HANDLE
;
1103 return get_window(win
, (*win
)->index
+1, req
);
1106 /*======================================================================
1108 Get the current socket state bits. We don't support the latched
1109 SocketState yet: I haven't seen any point for it.
1111 ======================================================================*/
1113 static int get_status(client_handle_t handle
, cs_status_t
*status
)
1119 if (CHECK_HANDLE(handle
))
1120 return CS_BAD_HANDLE
;
1122 s
->ss_entry(s
->sock
, SS_GetStatus
, &val
);
1123 status
->CardState
= status
->SocketState
= 0;
1124 status
->CardState
|= (val
& SS_DETECT
) ? CS_EVENT_CARD_DETECT
: 0;
1125 status
->CardState
|= (val
& SS_CARDBUS
) ? CS_EVENT_CB_DETECT
: 0;
1126 status
->CardState
|= (val
& SS_3VCARD
) ? CS_EVENT_3VCARD
: 0;
1127 status
->CardState
|= (val
& SS_XVCARD
) ? CS_EVENT_XVCARD
: 0;
1128 if (s
->state
& SOCKET_SUSPEND
)
1129 status
->CardState
|= CS_EVENT_PM_SUSPEND
;
1130 if (!(s
->state
& SOCKET_PRESENT
))
1132 if (s
->state
& SOCKET_SETUP_PENDING
)
1133 status
->CardState
|= CS_EVENT_CARD_INSERTION
;
1135 /* Get info from the PRR, if necessary */
1136 if (handle
->Function
== BIND_FN_ALL
) {
1137 if (status
->Function
&& (status
->Function
>= s
->functions
))
1139 c
= (s
->config
!= NULL
) ? &s
->config
[status
->Function
] : NULL
;
1142 if ((c
!= NULL
) && (c
->state
& CONFIG_LOCKED
) &&
1143 (c
->IntType
& INT_MEMORY_AND_IO
)) {
1145 if (c
->Present
& PRESENT_PIN_REPLACE
) {
1146 read_cis_mem(s
, 1, (c
->ConfigBase
+CISREG_PRR
)>>1, 1, ®
);
1147 status
->CardState
|=
1148 (reg
& PRR_WP_STATUS
) ? CS_EVENT_WRITE_PROTECT
: 0;
1149 status
->CardState
|=
1150 (reg
& PRR_READY_STATUS
) ? CS_EVENT_READY_CHANGE
: 0;
1151 status
->CardState
|=
1152 (reg
& PRR_BVD2_STATUS
) ? CS_EVENT_BATTERY_LOW
: 0;
1153 status
->CardState
|=
1154 (reg
& PRR_BVD1_STATUS
) ? CS_EVENT_BATTERY_DEAD
: 0;
1156 /* No PRR? Then assume we're always ready */
1157 status
->CardState
|= CS_EVENT_READY_CHANGE
;
1159 if (c
->Present
& PRESENT_EXT_STATUS
) {
1160 read_cis_mem(s
, 1, (c
->ConfigBase
+CISREG_ESR
)>>1, 1, ®
);
1161 status
->CardState
|=
1162 (reg
& ESR_REQ_ATTN
) ? CS_EVENT_REQUEST_ATTENTION
: 0;
1166 status
->CardState
|=
1167 (val
& SS_WRPROT
) ? CS_EVENT_WRITE_PROTECT
: 0;
1168 status
->CardState
|=
1169 (val
& SS_BATDEAD
) ? CS_EVENT_BATTERY_DEAD
: 0;
1170 status
->CardState
|=
1171 (val
& SS_BATWARN
) ? CS_EVENT_BATTERY_LOW
: 0;
1172 status
->CardState
|=
1173 (val
& SS_READY
) ? CS_EVENT_READY_CHANGE
: 0;
1177 /*======================================================================
1179 Change the card address of an already open memory window.
1181 ======================================================================*/
1183 static int get_mem_page(window_handle_t win
, memreq_t
*req
)
1185 if ((win
== NULL
) || (win
->magic
!= WINDOW_MAGIC
))
1186 return CS_BAD_HANDLE
;
1188 req
->CardOffset
= win
->ctl
.card_start
;
1190 } /* get_mem_page */
1192 static int map_mem_page(window_handle_t win
, memreq_t
*req
)
1195 if ((win
== NULL
) || (win
->magic
!= WINDOW_MAGIC
))
1196 return CS_BAD_HANDLE
;
1200 win
->ctl
.card_start
= req
->CardOffset
;
1201 if (s
->ss_entry(s
->sock
, SS_SetMemMap
, &win
->ctl
) != 0)
1202 return CS_BAD_OFFSET
;
1204 } /* map_mem_page */
1206 /*======================================================================
1208 Modify a locked socket configuration
1210 ======================================================================*/
1212 static int modify_configuration(client_handle_t handle
,
1218 if (CHECK_HANDLE(handle
))
1219 return CS_BAD_HANDLE
;
1220 s
= SOCKET(handle
); c
= CONFIG(handle
);
1221 if (!(s
->state
& SOCKET_PRESENT
))
1223 if (!(c
->state
& CONFIG_LOCKED
))
1224 return CS_CONFIGURATION_LOCKED
;
1226 if (mod
->Attributes
& CONF_IRQ_CHANGE_VALID
) {
1227 if (mod
->Attributes
& CONF_ENABLE_IRQ
) {
1228 c
->Attributes
|= CONF_ENABLE_IRQ
;
1229 s
->socket
.io_irq
= s
->irq
.AssignedIRQ
;
1231 c
->Attributes
&= ~CONF_ENABLE_IRQ
;
1232 s
->socket
.io_irq
= 0;
1234 s
->ss_entry(s
->sock
, SS_SetSocket
, &s
->socket
);
1237 if (mod
->Attributes
& CONF_VCC_CHANGE_VALID
)
1240 /* We only allow changing Vpp1 and Vpp2 to the same value */
1241 if ((mod
->Attributes
& CONF_VPP1_CHANGE_VALID
) &&
1242 (mod
->Attributes
& CONF_VPP2_CHANGE_VALID
)) {
1243 if (mod
->Vpp1
!= mod
->Vpp2
)
1245 c
->Vpp1
= c
->Vpp2
= s
->socket
.Vpp
= mod
->Vpp1
;
1246 if (s
->ss_entry(s
->sock
, SS_SetSocket
, &s
->socket
))
1248 } else if ((mod
->Attributes
& CONF_VPP1_CHANGE_VALID
) ||
1249 (mod
->Attributes
& CONF_VPP2_CHANGE_VALID
))
1253 } /* modify_configuration */
1255 /*======================================================================
1257 Modify the attributes of a window returned by RequestWindow.
1259 ======================================================================*/
1261 static int modify_window(window_handle_t win
, modwin_t
*req
)
1263 if ((win
== NULL
) || (win
->magic
!= WINDOW_MAGIC
))
1264 return CS_BAD_HANDLE
;
1266 win
->ctl
.flags
&= ~(MAP_ATTRIB
|MAP_ACTIVE
);
1267 if (req
->Attributes
& WIN_MEMORY_TYPE
)
1268 win
->ctl
.flags
|= MAP_ATTRIB
;
1269 if (req
->Attributes
& WIN_ENABLE
)
1270 win
->ctl
.flags
|= MAP_ACTIVE
;
1271 if (req
->Attributes
& WIN_DATA_WIDTH
)
1272 win
->ctl
.flags
|= MAP_16BIT
;
1273 if (req
->Attributes
& WIN_USE_WAIT
)
1274 win
->ctl
.flags
|= MAP_USE_WAIT
;
1275 win
->ctl
.speed
= req
->AccessSpeed
;
1276 win
->sock
->ss_entry(win
->sock
->sock
, SS_SetMemMap
, &win
->ctl
);
1279 } /* modify_window */
1281 /*======================================================================
1283 Register_client() uses the dev_info_t handle to match the
1284 caller with a socket. The driver must have already been bound
1285 to a socket with bind_device() -- in fact, bind_device()
1286 allocates the client structure that will be used.
1288 ======================================================================*/
1290 static int register_client(client_handle_t
*handle
, client_reg_t
*req
)
1296 /* Look for unbound client with matching dev_info */
1298 for (ns
= 0; ns
< sockets
; ns
++) {
1299 client
= socket_table
[ns
]->clients
;
1300 while (client
!= NULL
) {
1301 if ((strcmp(client
->dev_info
, (char *)req
->dev_info
) == 0)
1302 && (client
->state
& CLIENT_UNBOUND
)) break;
1303 client
= client
->next
;
1305 if (client
!= NULL
) break;
1308 return CS_OUT_OF_RESOURCE
;
1310 s
= socket_table
[ns
];
1311 if (++s
->real_clients
== 1) {
1314 call
.handler
= &parse_events
;
1316 s
->ss_entry(ns
, SS_RegisterCallback
, &call
);
1317 s
->ss_entry(ns
, SS_GetStatus
, &status
);
1318 if ((status
& SS_DETECT
) &&
1319 !(s
->state
& SOCKET_SETUP_PENDING
)) {
1320 s
->state
|= SOCKET_SETUP_PENDING
;
1326 client
->state
&= ~CLIENT_UNBOUND
;
1327 client
->Socket
= ns
;
1328 client
->Attributes
= req
->Attributes
;
1329 client
->EventMask
= req
->EventMask
;
1330 client
->event_handler
= req
->event_handler
;
1331 client
->event_callback_args
= req
->event_callback_args
;
1332 client
->event_callback_args
.client_handle
= client
;
1333 client
->event_callback_args
.bus
= s
->cap
.bus
;
1335 if (s
->state
& SOCKET_CARDBUS
)
1336 client
->state
|= CLIENT_CARDBUS
;
1338 if ((!(s
->state
& SOCKET_CARDBUS
)) && (s
->functions
== 0) &&
1339 (client
->Function
!= BIND_FN_ALL
)) {
1340 cistpl_longlink_mfc_t mfc
;
1341 if (read_tuple(client
, CISTPL_LONGLINK_MFC
, &mfc
)
1343 s
->functions
= mfc
.nfn
;
1346 s
->config
= kmalloc(sizeof(config_t
) * s
->functions
,
1348 memset(s
->config
, 0, sizeof(config_t
) * s
->functions
);
1351 DEBUG(1, "cs: register_client(): client 0x%p, sock %d, dev %s\n",
1352 client
, client
->Socket
, client
->dev_info
);
1353 if (client
->EventMask
& CS_EVENT_REGISTRATION_COMPLETE
)
1354 EVENT(client
, CS_EVENT_REGISTRATION_COMPLETE
, CS_EVENT_PRI_LOW
);
1355 if ((socket_table
[ns
]->state
& SOCKET_PRESENT
) &&
1356 !(socket_table
[ns
]->state
& SOCKET_SETUP_PENDING
)) {
1357 if (client
->EventMask
& CS_EVENT_CARD_INSERTION
)
1358 EVENT(client
, CS_EVENT_CARD_INSERTION
, CS_EVENT_PRI_LOW
);
1360 client
->PendingEvents
|= CS_EVENT_CARD_INSERTION
;
1363 } /* register_client */
1365 /*====================================================================*/
1367 static int release_configuration(client_handle_t handle
,
1374 if (CHECK_HANDLE(handle
) ||
1375 !(handle
->state
& CLIENT_CONFIG_LOCKED
))
1376 return CS_BAD_HANDLE
;
1377 handle
->state
&= ~CLIENT_CONFIG_LOCKED
;
1380 #ifdef CONFIG_CARDBUS
1381 if (handle
->state
& CLIENT_CARDBUS
) {
1388 if (!(handle
->state
& CLIENT_STALE
)) {
1389 config_t
*c
= CONFIG(handle
);
1390 if (--(s
->lock_count
) == 0) {
1391 s
->socket
.flags
= SS_OUTPUT_ENA
;
1393 s
->socket
.io_irq
= 0;
1394 s
->ss_entry(s
->sock
, SS_SetSocket
, &s
->socket
);
1396 if (c
->state
& CONFIG_IO_REQ
)
1397 for (i
= 0; i
< MAX_IO_WIN
; i
++) {
1398 if (s
->io
[i
].NumPorts
== 0)
1401 if (s
->io
[i
].Config
!= 0)
1404 s
->ss_entry(s
->sock
, SS_GetIOMap
, &io
);
1405 io
.flags
&= ~MAP_ACTIVE
;
1406 s
->ss_entry(s
->sock
, SS_SetIOMap
, &io
);
1408 c
->state
&= ~CONFIG_LOCKED
;
1412 } /* release_configuration */
1414 /*======================================================================
1416 Release_io() releases the I/O ranges allocated by a client. This
1417 may be invoked some time after a card ejection has already dumped
1418 the actual socket configuration, so if the client is "stale", we
1419 don't bother checking the port ranges against the current socket
1422 ======================================================================*/
1424 static int release_io(client_handle_t handle
, io_req_t
*req
)
1428 if (CHECK_HANDLE(handle
) || !(handle
->state
& CLIENT_IO_REQ
))
1429 return CS_BAD_HANDLE
;
1430 handle
->state
&= ~CLIENT_IO_REQ
;
1433 #ifdef CONFIG_CARDBUS
1434 if (handle
->state
& CLIENT_CARDBUS
) {
1440 if (!(handle
->state
& CLIENT_STALE
)) {
1441 config_t
*c
= CONFIG(handle
);
1442 if (c
->state
& CONFIG_LOCKED
)
1443 return CS_CONFIGURATION_LOCKED
;
1444 if ((c
->io
.BasePort1
!= req
->BasePort1
) ||
1445 (c
->io
.NumPorts1
!= req
->NumPorts1
) ||
1446 (c
->io
.BasePort2
!= req
->BasePort2
) ||
1447 (c
->io
.NumPorts2
!= req
->NumPorts2
))
1449 c
->state
&= ~CONFIG_IO_REQ
;
1452 release_io_space(s
, req
->BasePort1
, req
->NumPorts1
);
1454 release_io_space(s
, req
->BasePort2
, req
->NumPorts2
);
1459 /*====================================================================*/
1461 static int cs_release_irq(client_handle_t handle
, irq_req_t
*req
)
1464 if (CHECK_HANDLE(handle
) || !(handle
->state
& CLIENT_IRQ_REQ
))
1465 return CS_BAD_HANDLE
;
1466 handle
->state
&= ~CLIENT_IRQ_REQ
;
1469 if (!(handle
->state
& CLIENT_STALE
)) {
1470 config_t
*c
= CONFIG(handle
);
1471 if (c
->state
& CONFIG_LOCKED
)
1472 return CS_CONFIGURATION_LOCKED
;
1473 if (c
->irq
.Attributes
!= req
->Attributes
)
1474 return CS_BAD_ATTRIBUTE
;
1475 if (s
->irq
.AssignedIRQ
!= req
->AssignedIRQ
)
1477 if (--s
->irq
.Config
== 0) {
1478 c
->state
&= ~CONFIG_IRQ_REQ
;
1479 s
->irq
.AssignedIRQ
= 0;
1483 if (req
->Attributes
& IRQ_HANDLE_PRESENT
) {
1484 bus_free_irq(s
->cap
.bus
, req
->AssignedIRQ
, req
->Instance
);
1488 if (req
->AssignedIRQ
!= s
->cap
.pci_irq
)
1489 undo_irq(req
->Attributes
, req
->AssignedIRQ
);
1493 } /* cs_release_irq */
1495 /*====================================================================*/
1497 static int release_window(window_handle_t win
)
1501 if ((win
== NULL
) || (win
->magic
!= WINDOW_MAGIC
))
1502 return CS_BAD_HANDLE
;
1504 if (!(win
->handle
->state
& CLIENT_WIN_REQ(win
->index
)))
1505 return CS_BAD_HANDLE
;
1507 /* Shut down memory window */
1508 win
->ctl
.flags
&= ~MAP_ACTIVE
;
1509 s
->ss_entry(s
->sock
, SS_SetMemMap
, &win
->ctl
);
1510 s
->state
&= ~SOCKET_WIN_REQ(win
->index
);
1512 /* Release system memory */
1513 release_mem_region(win
->base
, win
->size
);
1514 win
->handle
->state
&= ~CLIENT_WIN_REQ(win
->index
);
1519 } /* release_window */
1521 /*====================================================================*/
1523 static int request_configuration(client_handle_t handle
,
1530 pccard_io_map iomap
;
1532 if (CHECK_HANDLE(handle
))
1533 return CS_BAD_HANDLE
;
1534 i
= handle
->Socket
; s
= socket_table
[i
];
1535 if (!(s
->state
& SOCKET_PRESENT
))
1538 #ifdef CONFIG_CARDBUS
1539 if (handle
->state
& CLIENT_CARDBUS
) {
1540 if (!(req
->IntType
& INT_CARDBUS
))
1541 return CS_UNSUPPORTED_MODE
;
1542 if (s
->lock_count
!= 0)
1543 return CS_CONFIGURATION_LOCKED
;
1545 handle
->state
|= CLIENT_CONFIG_LOCKED
;
1551 if (req
->IntType
& INT_CARDBUS
)
1552 return CS_UNSUPPORTED_MODE
;
1554 if (c
->state
& CONFIG_LOCKED
)
1555 return CS_CONFIGURATION_LOCKED
;
1557 /* Do power control. We don't allow changes in Vcc. */
1558 if (s
->socket
.Vcc
!= req
->Vcc
)
1560 if (req
->Vpp1
!= req
->Vpp2
)
1562 s
->socket
.Vpp
= req
->Vpp1
;
1563 if (s
->ss_entry(s
->sock
, SS_SetSocket
, &s
->socket
))
1566 c
->Vcc
= req
->Vcc
; c
->Vpp1
= c
->Vpp2
= req
->Vpp1
;
1568 /* Pick memory or I/O card, DMA mode, interrupt */
1569 c
->IntType
= req
->IntType
;
1570 c
->Attributes
= req
->Attributes
;
1571 if (req
->IntType
& INT_MEMORY_AND_IO
)
1572 s
->socket
.flags
|= SS_IOCARD
;
1573 if (req
->Attributes
& CONF_ENABLE_DMA
)
1574 s
->socket
.flags
|= SS_DMA_MODE
;
1575 if (req
->Attributes
& CONF_ENABLE_SPKR
)
1576 s
->socket
.flags
|= SS_SPKR_ENA
;
1577 if (req
->Attributes
& CONF_ENABLE_IRQ
)
1578 s
->socket
.io_irq
= s
->irq
.AssignedIRQ
;
1580 s
->socket
.io_irq
= 0;
1581 s
->ss_entry(s
->sock
, SS_SetSocket
, &s
->socket
);
1584 /* Set up CIS configuration registers */
1585 base
= c
->ConfigBase
= req
->ConfigBase
;
1586 c
->Present
= c
->CardValues
= req
->Present
;
1587 if (req
->Present
& PRESENT_COPY
) {
1588 c
->Copy
= req
->Copy
;
1589 write_cis_mem(s
, 1, (base
+ CISREG_SCR
)>>1, 1, &c
->Copy
);
1591 if (req
->Present
& PRESENT_OPTION
) {
1592 if (s
->functions
== 1)
1593 c
->Option
= req
->ConfigIndex
& COR_CONFIG_MASK
;
1595 c
->Option
= req
->ConfigIndex
& COR_MFC_CONFIG_MASK
;
1596 c
->Option
|= COR_FUNC_ENA
|COR_ADDR_DECODE
|COR_IREQ_ENA
;
1598 if (c
->state
& CONFIG_IRQ_REQ
)
1599 if (!(c
->irq
.Attributes
& IRQ_FORCED_PULSE
))
1600 c
->Option
|= COR_LEVEL_REQ
;
1601 write_cis_mem(s
, 1, (base
+ CISREG_COR
)>>1, 1, &c
->Option
);
1604 if (req
->Present
& PRESENT_STATUS
) {
1605 c
->Status
= req
->Status
;
1606 write_cis_mem(s
, 1, (base
+ CISREG_CCSR
)>>1, 1, &c
->Status
);
1608 if (req
->Present
& PRESENT_PIN_REPLACE
) {
1610 write_cis_mem(s
, 1, (base
+ CISREG_PRR
)>>1, 1, &c
->Pin
);
1612 if (req
->Present
& PRESENT_EXT_STATUS
) {
1613 c
->ExtStatus
= req
->ExtStatus
;
1614 write_cis_mem(s
, 1, (base
+ CISREG_ESR
)>>1, 1, &c
->ExtStatus
);
1616 if (req
->Present
& PRESENT_IOBASE_0
) {
1617 i
= c
->io
.BasePort1
& 0xff;
1618 write_cis_mem(s
, 1, (base
+ CISREG_IOBASE_0
)>>1, 1, &i
);
1619 i
= (c
->io
.BasePort1
>> 8) & 0xff;
1620 write_cis_mem(s
, 1, (base
+ CISREG_IOBASE_1
)>>1, 1, &i
);
1622 if (req
->Present
& PRESENT_IOSIZE
) {
1623 i
= c
->io
.NumPorts1
+ c
->io
.NumPorts2
- 1;
1624 write_cis_mem(s
, 1, (base
+ CISREG_IOSIZE
)>>1, 1, &i
);
1627 /* Configure I/O windows */
1628 if (c
->state
& CONFIG_IO_REQ
) {
1629 iomap
.speed
= io_speed
;
1630 for (i
= 0; i
< MAX_IO_WIN
; i
++)
1631 if (s
->io
[i
].NumPorts
!= 0) {
1633 iomap
.flags
= MAP_ACTIVE
;
1634 switch (s
->io
[i
].Attributes
& IO_DATA_PATH_WIDTH
) {
1635 case IO_DATA_PATH_WIDTH_16
:
1636 iomap
.flags
|= MAP_16BIT
; break;
1637 case IO_DATA_PATH_WIDTH_AUTO
:
1638 iomap
.flags
|= MAP_AUTOSZ
; break;
1642 iomap
.start
= s
->io
[i
].BasePort
;
1643 iomap
.stop
= iomap
.start
+ s
->io
[i
].NumPorts
- 1;
1644 s
->ss_entry(s
->sock
, SS_SetIOMap
, &iomap
);
1649 c
->state
|= CONFIG_LOCKED
;
1650 handle
->state
|= CLIENT_CONFIG_LOCKED
;
1652 } /* request_configuration */
1654 /*======================================================================
1656 Request_io() reserves ranges of port addresses for a socket.
1657 I have not implemented range sharing or alias addressing.
1659 ======================================================================*/
1661 static int request_io(client_handle_t handle
, io_req_t
*req
)
1666 if (CHECK_HANDLE(handle
))
1667 return CS_BAD_HANDLE
;
1669 if (!(s
->state
& SOCKET_PRESENT
))
1672 if (handle
->state
& CLIENT_CARDBUS
) {
1673 #ifdef CONFIG_CARDBUS
1674 int ret
= cb_config(s
);
1675 if (ret
== CS_SUCCESS
)
1676 handle
->state
|= CLIENT_IO_REQ
;
1679 return CS_UNSUPPORTED_FUNCTION
;
1684 return CS_UNSUPPORTED_MODE
;
1686 if (c
->state
& CONFIG_LOCKED
)
1687 return CS_CONFIGURATION_LOCKED
;
1688 if (c
->state
& CONFIG_IO_REQ
)
1690 if (req
->Attributes1
& (IO_SHARED
| IO_FORCE_ALIAS_ACCESS
))
1691 return CS_BAD_ATTRIBUTE
;
1692 if ((req
->NumPorts2
> 0) &&
1693 (req
->Attributes2
& (IO_SHARED
| IO_FORCE_ALIAS_ACCESS
)))
1694 return CS_BAD_ATTRIBUTE
;
1696 if (alloc_io_space(s
, req
->Attributes1
, &req
->BasePort1
,
1697 req
->NumPorts1
, handle
->dev_info
))
1700 if (req
->NumPorts2
) {
1701 if (alloc_io_space(s
, req
->Attributes2
, &req
->BasePort2
,
1702 req
->NumPorts2
, handle
->dev_info
)) {
1703 release_io_space(s
, req
->BasePort1
, req
->NumPorts1
);
1709 c
->state
|= CONFIG_IO_REQ
;
1710 handle
->state
|= CLIENT_IO_REQ
;
1714 /*======================================================================
1716 Request_irq() reserves an irq for this client.
1718 Also, since Linux only reserves irq's when they are actually
1719 hooked, we don't guarantee that an irq will still be available
1720 when the configuration is locked. Now that I think about it,
1721 there might be a way to fix this using a dummy handler.
1723 ======================================================================*/
1725 static int cs_request_irq(client_handle_t handle
, irq_req_t
*req
)
1729 int try, ret
= 0, irq
= 0;
1732 if (CHECK_HANDLE(handle
))
1733 return CS_BAD_HANDLE
;
1735 if (!(s
->state
& SOCKET_PRESENT
))
1738 if (c
->state
& CONFIG_LOCKED
)
1739 return CS_CONFIGURATION_LOCKED
;
1740 if (c
->state
& CONFIG_IRQ_REQ
)
1743 /* Short cut: if the interrupt is PCI, there are no options */
1744 if (s
->cap
.irq_mask
== (1 << s
->cap
.pci_irq
))
1745 irq
= s
->cap
.pci_irq
;
1747 else if (s
->irq
.AssignedIRQ
!= 0) {
1748 /* If the interrupt is already assigned, it must match */
1749 irq
= s
->irq
.AssignedIRQ
;
1750 if (req
->IRQInfo1
& IRQ_INFO2_VALID
) {
1751 mask
= req
->IRQInfo2
& s
->cap
.irq_mask
;
1752 ret
= ((mask
>> irq
) & 1) ? 0 : CS_BAD_ARGS
;
1754 ret
= ((req
->IRQInfo1
&IRQ_MASK
) == irq
) ? 0 : CS_BAD_ARGS
;
1757 if (req
->IRQInfo1
& IRQ_INFO2_VALID
) {
1758 mask
= req
->IRQInfo2
& s
->cap
.irq_mask
;
1759 mask
&= ~(1 << s
->cap
.pci_irq
);
1760 for (try = 0; try < 2; try++) {
1761 for (irq
= 0; irq
< 32; irq
++)
1762 if ((mask
>> irq
) & 1) {
1763 ret
= try_irq(req
->Attributes
, irq
, try);
1764 if (ret
== 0) break;
1766 if (ret
== 0) break;
1769 irq
= req
->IRQInfo1
& IRQ_MASK
;
1770 ret
= try_irq(req
->Attributes
, irq
, 1);
1774 if (ret
!= 0) return ret
;
1776 if (req
->Attributes
& IRQ_HANDLE_PRESENT
) {
1777 if (bus_request_irq(s
->cap
.bus
, irq
, req
->Handler
,
1778 ((req
->Attributes
& IRQ_TYPE_DYNAMIC_SHARING
) ||
1779 (s
->functions
> 1) ||
1780 (irq
== s
->cap
.pci_irq
)) ? SA_SHIRQ
: 0,
1781 handle
->dev_info
, req
->Instance
))
1785 c
->irq
.Attributes
= req
->Attributes
;
1786 s
->irq
.AssignedIRQ
= req
->AssignedIRQ
= irq
;
1789 c
->state
|= CONFIG_IRQ_REQ
;
1790 handle
->state
|= CLIENT_IRQ_REQ
;
1792 } /* cs_request_irq */
1794 /*======================================================================
1796 Request_window() establishes a mapping between card memory space
1797 and system memory space.
1799 ======================================================================*/
1801 static int request_window(client_handle_t
*handle
, win_req_t
*req
)
1807 if (CHECK_HANDLE(*handle
))
1808 return CS_BAD_HANDLE
;
1809 s
= SOCKET(*handle
);
1810 if (!(s
->state
& SOCKET_PRESENT
))
1812 if (req
->Attributes
& (WIN_PAGED
| WIN_SHARED
))
1813 return CS_BAD_ATTRIBUTE
;
1815 for (w
= 0; w
< MAX_WIN
; w
++)
1816 if (!(s
->state
& SOCKET_WIN_REQ(w
))) break;
1818 return CS_OUT_OF_RESOURCE
;
1820 /* Window size defaults to smallest available */
1822 req
->Size
= s
->cap
.map_size
;
1824 /* Allocate system memory window */
1826 win
->magic
= WINDOW_MAGIC
;
1828 win
->handle
= *handle
;
1830 win
->base
= req
->Base
;
1831 win
->size
= req
->Size
;
1832 if (find_mem_region(&win
->base
, win
->size
, (*handle
)->dev_info
,
1833 ((s
->cap
.features
& SS_CAP_MEM_ALIGN
) ?
1834 req
->Size
: s
->cap
.map_size
),
1835 (req
->Attributes
& WIN_MAP_BELOW_1MB
) ||
1836 !(s
->cap
.features
& SS_CAP_PAGE_REGS
)))
1838 req
->Base
= win
->base
;
1839 (*handle
)->state
|= CLIENT_WIN_REQ(w
);
1841 /* Configure the socket controller */
1844 win
->ctl
.speed
= req
->AccessSpeed
;
1845 if (req
->Attributes
& WIN_MEMORY_TYPE
)
1846 win
->ctl
.flags
|= MAP_ATTRIB
;
1847 if (req
->Attributes
& WIN_ENABLE
)
1848 win
->ctl
.flags
|= MAP_ACTIVE
;
1849 if (req
->Attributes
& WIN_DATA_WIDTH
)
1850 win
->ctl
.flags
|= MAP_16BIT
;
1851 if (req
->Attributes
& WIN_USE_WAIT
)
1852 win
->ctl
.flags
|= MAP_USE_WAIT
;
1853 win
->ctl
.sys_start
= req
->Base
;
1854 win
->ctl
.sys_stop
= req
->Base
+ req
->Size
-1;
1855 win
->ctl
.card_start
= 0;
1856 if (s
->ss_entry(s
->sock
, SS_SetMemMap
, &win
->ctl
) != 0)
1858 s
->state
|= SOCKET_WIN_REQ(w
);
1860 /* Return window handle */
1861 *handle
= (client_handle_t
)win
;
1864 } /* request_window */
1866 /*======================================================================
1868 I'm not sure which "reset" function this is supposed to use,
1869 but for now, it uses the low-level interface's reset, not the
1872 ======================================================================*/
1874 static int reset_card(client_handle_t handle
, client_req_t
*req
)
1879 if (CHECK_HANDLE(handle
))
1880 return CS_BAD_HANDLE
;
1881 i
= handle
->Socket
; s
= socket_table
[i
];
1882 if (!(s
->state
& SOCKET_PRESENT
))
1884 if (s
->state
& SOCKET_RESET_PENDING
)
1886 s
->state
|= SOCKET_RESET_PENDING
;
1888 ret
= send_event(s
, CS_EVENT_RESET_REQUEST
, CS_EVENT_PRI_LOW
);
1890 s
->state
&= ~SOCKET_RESET_PENDING
;
1891 handle
->event_callback_args
.info
= (void *)(u_long
)ret
;
1892 EVENT(handle
, CS_EVENT_RESET_COMPLETE
, CS_EVENT_PRI_LOW
);
1894 DEBUG(1, "cs: resetting socket %d\n", i
);
1895 send_event(s
, CS_EVENT_RESET_PHYSICAL
, CS_EVENT_PRI_LOW
);
1896 s
->reset_handle
= handle
;
1902 /*======================================================================
1904 These shut down or wake up a socket. They are sort of user
1905 initiated versions of the APM suspend and resume actions.
1907 ======================================================================*/
1909 static int suspend_card(client_handle_t handle
, client_req_t
*req
)
1914 if (CHECK_HANDLE(handle
))
1915 return CS_BAD_HANDLE
;
1916 i
= handle
->Socket
; s
= socket_table
[i
];
1917 if (!(s
->state
& SOCKET_PRESENT
))
1919 if (s
->state
& SOCKET_SUSPEND
)
1922 DEBUG(1, "cs: suspending socket %d\n", i
);
1923 send_event(s
, CS_EVENT_PM_SUSPEND
, CS_EVENT_PRI_LOW
);
1924 s
->ss_entry(s
->sock
, SS_SetSocket
, &dead_socket
);
1925 s
->state
|= SOCKET_SUSPEND
;
1928 } /* suspend_card */
1930 static int resume_card(client_handle_t handle
, client_req_t
*req
)
1935 if (CHECK_HANDLE(handle
))
1936 return CS_BAD_HANDLE
;
1937 i
= handle
->Socket
; s
= socket_table
[i
];
1938 if (!(s
->state
& SOCKET_PRESENT
))
1940 if (!(s
->state
& SOCKET_SUSPEND
))
1943 DEBUG(1, "cs: waking up socket %d\n", i
);
1949 /*======================================================================
1951 These handle user requests to eject or insert a card.
1953 ======================================================================*/
1955 static int eject_card(client_handle_t handle
, client_req_t
*req
)
1961 if (CHECK_HANDLE(handle
))
1962 return CS_BAD_HANDLE
;
1963 i
= handle
->Socket
; s
= socket_table
[i
];
1964 if (!(s
->state
& SOCKET_PRESENT
))
1967 DEBUG(1, "cs: user eject request on socket %d\n", i
);
1969 ret
= send_event(s
, CS_EVENT_EJECTION_REQUEST
, CS_EVENT_PRI_LOW
);
1973 spin_lock_irqsave(&s
->lock
, flags
);
1975 spin_unlock_irqrestore(&s
->lock
, flags
);
1981 static int insert_card(client_handle_t handle
, client_req_t
*req
)
1987 if (CHECK_HANDLE(handle
))
1988 return CS_BAD_HANDLE
;
1989 i
= handle
->Socket
; s
= socket_table
[i
];
1990 if (s
->state
& SOCKET_PRESENT
)
1993 DEBUG(1, "cs: user insert request on socket %d\n", i
);
1995 spin_lock_irqsave(&s
->lock
, flags
);
1996 if (!(s
->state
& SOCKET_SETUP_PENDING
)) {
1997 s
->state
|= SOCKET_SETUP_PENDING
;
1998 spin_unlock_irqrestore(&s
->lock
, flags
);
1999 s
->ss_entry(i
, SS_GetStatus
, &status
);
2000 if (status
& SS_DETECT
)
2003 s
->state
&= ~SOCKET_SETUP_PENDING
;
2007 spin_unlock_irqrestore(&s
->lock
, flags
);
2012 /*======================================================================
2014 Maybe this should send a CS_EVENT_CARD_INSERTION event if we
2015 haven't sent one to this client yet?
2017 ======================================================================*/
2019 static int set_event_mask(client_handle_t handle
, eventmask_t
*mask
)
2022 if (CHECK_HANDLE(handle
))
2023 return CS_BAD_HANDLE
;
2024 if (handle
->Attributes
& CONF_EVENT_MASK_VALID
)
2025 return CS_BAD_SOCKET
;
2026 handle
->EventMask
= mask
->EventMask
;
2027 events
= handle
->PendingEvents
& handle
->EventMask
;
2028 handle
->PendingEvents
-= events
;
2029 while (events
!= 0) {
2030 bit
= ((events
^ (events
-1)) + 1) >> 1;
2031 EVENT(handle
, bit
, CS_EVENT_PRI_LOW
);
2035 } /* set_event_mask */
2037 /*====================================================================*/
2039 static int report_error(client_handle_t handle
, error_info_t
*err
)
2044 if (CHECK_HANDLE(handle
))
2045 printk(KERN_NOTICE
);
2047 printk(KERN_NOTICE
"%s: ", handle
->dev_info
);
2049 for (i
= 0; i
< SERVICE_COUNT
; i
++)
2050 if (service_table
[i
].key
== err
->func
) break;
2051 if (i
< SERVICE_COUNT
)
2052 serv
= service_table
[i
].msg
;
2054 serv
= "Unknown service number";
2056 for (i
= 0; i
< ERROR_COUNT
; i
++)
2057 if (error_table
[i
].key
== err
->retcode
) break;
2058 if (i
< ERROR_COUNT
)
2059 printk("%s: %s\n", serv
, error_table
[i
].msg
);
2061 printk("%s: Unknown error code %#x\n", serv
, err
->retcode
);
2064 } /* report_error */
2066 /*====================================================================*/
2068 int CardServices(int func
, void *a1
, void *a2
, void *a3
)
2074 for (i
= 0; i
< SERVICE_COUNT
; i
++)
2075 if (service_table
[i
].key
== func
) break;
2076 if (i
< SERVICE_COUNT
)
2077 printk(KERN_DEBUG
"cs: CardServices(%s, 0x%p, 0x%p)\n",
2078 service_table
[i
].msg
, a1
, a2
);
2080 printk(KERN_DEBUG
"cs: CardServices(Unknown func %d, "
2081 "0x%p, 0x%p)\n", func
, a1
, a2
);
2085 case AccessConfigurationRegister
:
2086 return access_configuration_register(a1
, a2
); break;
2087 case AdjustResourceInfo
:
2088 return adjust_resource_info(a1
, a2
); break;
2089 case CheckEraseQueue
:
2090 return check_erase_queue(a1
); break;
2092 return close_memory(a1
); break;
2094 return copy_memory(a1
, a2
); break;
2095 case DeregisterClient
:
2096 return deregister_client(a1
); break;
2097 case DeregisterEraseQueue
:
2098 return deregister_erase_queue(a1
); break;
2099 case GetFirstClient
:
2100 return get_first_client(a1
, a2
); break;
2101 case GetCardServicesInfo
:
2102 return get_card_services_info(a1
); break;
2103 case GetConfigurationInfo
:
2104 return get_configuration_info(a1
, a2
); break;
2106 return get_next_client(a1
, a2
); break;
2107 case GetFirstRegion
:
2108 return get_first_region(a1
, a2
); break;
2110 return get_first_tuple(a1
, a2
); break;
2112 return get_next_region(a1
, a2
); break;
2114 return get_next_tuple(a1
, a2
); break;
2116 return get_status(a1
, a2
); break;
2118 return get_tuple_data(a1
, a2
); break;
2120 return map_mem_page(a1
, a2
); break;
2121 case ModifyConfiguration
:
2122 return modify_configuration(a1
, a2
); break;
2124 return modify_window(a1
, a2
); break;
2126 return open_memory(a1
, a2
);
2128 return parse_tuple(a1
, a2
, a3
); break;
2130 return read_memory(a1
, a2
, a3
); break;
2131 case RegisterClient
:
2132 return register_client(a1
, a2
); break;
2133 case RegisterEraseQueue
:
2134 return register_erase_queue(a1
, a2
); break;
2136 return register_mtd(a1
, a2
); break;
2137 case ReleaseConfiguration
:
2138 return release_configuration(a1
, a2
); break;
2140 return release_io(a1
, a2
); break;
2142 return cs_release_irq(a1
, a2
); break;
2144 return release_window(a1
); break;
2145 case RequestConfiguration
:
2146 return request_configuration(a1
, a2
); break;
2148 return request_io(a1
, a2
); break;
2150 return cs_request_irq(a1
, a2
); break;
2152 return request_window(a1
, a2
); break;
2154 return reset_card(a1
, a2
); break;
2156 return set_event_mask(a1
, a2
); break;
2158 return validate_cis(a1
, a2
); break;
2160 return write_memory(a1
, a2
, a3
); break;
2162 return bind_device(a1
); break;
2164 return bind_mtd(a1
); break;
2166 return report_error(a1
, a2
); break;
2168 return suspend_card(a1
, a2
); break;
2170 return resume_card(a1
, a2
); break;
2172 return eject_card(a1
, a2
); break;
2174 return insert_card(a1
, a2
); break;
2176 return replace_cis(a1
, a2
); break;
2177 case GetFirstWindow
:
2178 return get_first_window(a1
, a2
); break;
2180 return get_next_window(a1
, a2
); break;
2182 return get_mem_page(a1
, a2
); break;
2184 return CS_UNSUPPORTED_FUNCTION
; break;
2187 } /* CardServices */
2189 /*======================================================================
2191 OS-specific module glue goes here
2193 ======================================================================*/
2195 EXPORT_SYMBOL(register_ss_entry
);
2196 EXPORT_SYMBOL(unregister_ss_entry
);
2197 EXPORT_SYMBOL(CardServices
);
2198 EXPORT_SYMBOL(MTDHelperEntry
);
2200 static int pcmcia_cs_init(void)
2202 printk(KERN_INFO
"%s\n", release
);
2203 printk(KERN_INFO
" %s\n", options
);
2204 DEBUG(0, "%s\n", version
);
2207 apm_register_callback(&handle_apm_event
);
2209 #ifdef CONFIG_PROC_FS
2210 proc_pccard
= create_proc_entry("pccard", S_IFDIR
, proc_bus
);
2217 int init_module(void)
2219 return pcmcia_cs_init();
2222 void cleanup_module(void)
2224 printk(KERN_INFO
"unloading PCMCIA Card Services\n");
2225 #ifdef CONFIG_PROC_FS
2227 remove_proc_entry("pccard", proc_bus
);
2232 apm_unregister_callback(&handle_apm_event
);
2234 release_resource_db();
2239 extern int pcmcia_ds_init(void);
2240 extern int pcmcia_i82365_init(void);
2241 extern int init_pcnet_cs(void);
2242 extern int init_ray_cs(void);
2244 int pcmcia_init(void)
2246 /* Start core services */
2249 /* Load the socket drivers */
2250 pcmcia_i82365_init();
2252 /* Get the ball rolling.. */
2255 #ifdef CONFIG_PCMCIA_PCNET
2258 #ifdef CONFIG_PCMCIA_RAYCS
2266 /*====================================================================*/