1 /*======================================================================
3 PCMCIA Card Services -- core services
5 cs.c 1.271 2000/10/02 20:27:49
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 <dahinds@users.sourceforge.net>. 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/init.h>
36 #include <linux/kernel.h>
37 #include <linux/config.h>
38 #include <linux/string.h>
39 #include <linux/major.h>
40 #include <linux/errno.h>
41 #include <linux/malloc.h>
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>
49 #include <linux/pci.h>
50 #include <asm/system.h>
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"
66 int pc_debug
= PCMCIA_DEBUG
;
67 MODULE_PARM(pc_debug
, "i");
68 static const char *version
=
69 "cs.c 1.271 2000/10/02 20:27:49 (David Hinds)";
73 #define PCI_OPT " [pci]"
78 #define CB_OPT " [cardbus]"
83 #define PM_OPT " [pm]"
87 #if !defined(CONFIG_CARDBUS) && !defined(CONFIG_PCI) && !defined(CONFIG_PM)
88 #define OPTIONS " none"
90 #define OPTIONS PCI_OPT CB_OPT PM_OPT
93 static const char *release
= "Linux PCMCIA Card Services " CS_RELEASE
;
94 static const char *options
= "options: " OPTIONS
;
96 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
97 MODULE_DESCRIPTION("Linux PCMCIA Card Services " CS_RELEASE
98 "\n options:" OPTIONS
);
100 /*====================================================================*/
102 /* Parameters that can be set with 'insmod' */
104 #define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
106 INT_MODULE_PARM(setup_delay
, 10); /* centiseconds */
107 INT_MODULE_PARM(resume_delay
, 20); /* centiseconds */
108 INT_MODULE_PARM(shutdown_delay
, 3); /* centiseconds */
109 INT_MODULE_PARM(vcc_settle
, 40); /* centiseconds */
110 INT_MODULE_PARM(reset_time
, 10); /* usecs */
111 INT_MODULE_PARM(unreset_delay
, 10); /* centiseconds */
112 INT_MODULE_PARM(unreset_check
, 10); /* centiseconds */
113 INT_MODULE_PARM(unreset_limit
, 30); /* unreset_check's */
115 /* Access speed for attribute memory windows */
116 INT_MODULE_PARM(cis_speed
, 300); /* ns */
118 /* Access speed for IO windows */
119 INT_MODULE_PARM(io_speed
, 0); /* ns */
121 /* Optional features */
123 INT_MODULE_PARM(do_apm
, 1);
125 INT_MODULE_PARM(do_apm
, 0);
128 /*====================================================================*/
130 socket_state_t dead_socket
= {
131 0, SS_DETECT
, 0, 0, 0
134 /* Table of sockets */
135 socket_t sockets
= 0;
136 socket_info_t
*socket_table
[MAX_SOCK
];
138 #ifdef CONFIG_PROC_FS
139 struct proc_dir_entry
*proc_pccard
= NULL
;
142 /*====================================================================*/
144 /* String tables for error messages */
146 typedef struct lookup_t
{
151 static const lookup_t error_table
[] = {
152 { CS_SUCCESS
, "Operation succeeded" },
153 { CS_BAD_ADAPTER
, "Bad adapter" },
154 { CS_BAD_ATTRIBUTE
, "Bad attribute", },
155 { CS_BAD_BASE
, "Bad base address" },
156 { CS_BAD_EDC
, "Bad EDC" },
157 { CS_BAD_IRQ
, "Bad IRQ" },
158 { CS_BAD_OFFSET
, "Bad offset" },
159 { CS_BAD_PAGE
, "Bad page number" },
160 { CS_READ_FAILURE
, "Read failure" },
161 { CS_BAD_SIZE
, "Bad size" },
162 { CS_BAD_SOCKET
, "Bad socket" },
163 { CS_BAD_TYPE
, "Bad type" },
164 { CS_BAD_VCC
, "Bad Vcc" },
165 { CS_BAD_VPP
, "Bad Vpp" },
166 { CS_BAD_WINDOW
, "Bad window" },
167 { CS_WRITE_FAILURE
, "Write failure" },
168 { CS_NO_CARD
, "No card present" },
169 { CS_UNSUPPORTED_FUNCTION
, "Usupported function" },
170 { CS_UNSUPPORTED_MODE
, "Unsupported mode" },
171 { CS_BAD_SPEED
, "Bad speed" },
172 { CS_BUSY
, "Resource busy" },
173 { CS_GENERAL_FAILURE
, "General failure" },
174 { CS_WRITE_PROTECTED
, "Write protected" },
175 { CS_BAD_ARG_LENGTH
, "Bad argument length" },
176 { CS_BAD_ARGS
, "Bad arguments" },
177 { CS_CONFIGURATION_LOCKED
, "Configuration locked" },
178 { CS_IN_USE
, "Resource in use" },
179 { CS_NO_MORE_ITEMS
, "No more items" },
180 { CS_OUT_OF_RESOURCE
, "Out of resource" },
181 { CS_BAD_HANDLE
, "Bad handle" },
182 { CS_BAD_TUPLE
, "Bad CIS tuple" }
184 #define ERROR_COUNT (sizeof(error_table)/sizeof(lookup_t))
186 static const lookup_t service_table
[] = {
187 { AccessConfigurationRegister
, "AccessConfigurationRegister" },
188 { AddSocketServices
, "AddSocketServices" },
189 { AdjustResourceInfo
, "AdjustResourceInfo" },
190 { CheckEraseQueue
, "CheckEraseQueue" },
191 { CloseMemory
, "CloseMemory" },
192 { DeregisterClient
, "DeregisterClient" },
193 { DeregisterEraseQueue
, "DeregisterEraseQueue" },
194 { GetCardServicesInfo
, "GetCardServicesInfo" },
195 { GetClientInfo
, "GetClientInfo" },
196 { GetConfigurationInfo
, "GetConfigurationInfo" },
197 { GetEventMask
, "GetEventMask" },
198 { GetFirstClient
, "GetFirstClient" },
199 { GetFirstRegion
, "GetFirstRegion" },
200 { GetFirstTuple
, "GetFirstTuple" },
201 { GetNextClient
, "GetNextClient" },
202 { GetNextRegion
, "GetNextRegion" },
203 { GetNextTuple
, "GetNextTuple" },
204 { GetStatus
, "GetStatus" },
205 { GetTupleData
, "GetTupleData" },
206 { MapMemPage
, "MapMemPage" },
207 { ModifyConfiguration
, "ModifyConfiguration" },
208 { ModifyWindow
, "ModifyWindow" },
209 { OpenMemory
, "OpenMemory" },
210 { ParseTuple
, "ParseTuple" },
211 { ReadMemory
, "ReadMemory" },
212 { RegisterClient
, "RegisterClient" },
213 { RegisterEraseQueue
, "RegisterEraseQueue" },
214 { RegisterMTD
, "RegisterMTD" },
215 { ReleaseConfiguration
, "ReleaseConfiguration" },
216 { ReleaseIO
, "ReleaseIO" },
217 { ReleaseIRQ
, "ReleaseIRQ" },
218 { ReleaseWindow
, "ReleaseWindow" },
219 { RequestConfiguration
, "RequestConfiguration" },
220 { RequestIO
, "RequestIO" },
221 { RequestIRQ
, "RequestIRQ" },
222 { RequestSocketMask
, "RequestSocketMask" },
223 { RequestWindow
, "RequestWindow" },
224 { ResetCard
, "ResetCard" },
225 { SetEventMask
, "SetEventMask" },
226 { ValidateCIS
, "ValidateCIS" },
227 { WriteMemory
, "WriteMemory" },
228 { BindDevice
, "BindDevice" },
229 { BindMTD
, "BindMTD" },
230 { ReportError
, "ReportError" },
231 { SuspendCard
, "SuspendCard" },
232 { ResumeCard
, "ResumeCard" },
233 { EjectCard
, "EjectCard" },
234 { InsertCard
, "InsertCard" },
235 { ReplaceCIS
, "ReplaceCIS" }
237 #define SERVICE_COUNT (sizeof(service_table)/sizeof(lookup_t))
239 /*======================================================================
241 These functions are just shorthand for the actual low-level drivers
243 ======================================================================*/
245 static int register_callback(socket_info_t
*s
, void (*handler
)(void *, unsigned int), void * info
)
247 return s
->ss_entry
->register_callback(s
->sock
, handler
, info
);
250 static int get_socket_status(socket_info_t
*s
, int *val
)
252 return s
->ss_entry
->get_status(s
->sock
, val
);
255 static int set_socket(socket_info_t
*s
, socket_state_t
*state
)
257 return s
->ss_entry
->set_socket(s
->sock
, state
);
260 static int set_io_map(socket_info_t
*s
, struct pccard_io_map
*io
)
262 return s
->ss_entry
->set_io_map(s
->sock
, io
);
265 static int set_mem_map(socket_info_t
*s
, struct pccard_mem_map
*mem
)
267 return s
->ss_entry
->set_mem_map(s
->sock
, mem
);
270 static int suspend_socket(socket_info_t
*s
)
272 s
->socket
= dead_socket
;
273 return s
->ss_entry
->suspend(s
->sock
);
276 static int init_socket(socket_info_t
*s
)
278 s
->socket
= dead_socket
;
279 return s
->ss_entry
->init(s
->sock
);
282 /*====================================================================*/
284 #if defined(CONFIG_PROC_FS) && defined(PCMCIA_DEBUG)
285 static int proc_read_clients(char *buf
, char **start
, off_t pos
,
286 int count
, int *eof
, void *data
)
288 socket_info_t
*s
= data
;
292 for (c
= s
->clients
; c
; c
= c
->next
)
293 p
+= sprintf(p
, "fn %x: '%s' [attr 0x%04x] [state 0x%04x]\n",
294 c
->Function
, c
->dev_info
, c
->Attributes
, c
->state
);
299 /*======================================================================
301 Low-level PC Card interface drivers need to register with Card
302 Services using these calls.
304 ======================================================================*/
306 static int setup_socket(socket_info_t
*);
307 static void shutdown_socket(socket_info_t
*);
308 static void reset_socket(socket_info_t
*);
309 static void unreset_socket(socket_info_t
*);
310 static void parse_events(void *info
, u_int events
);
312 socket_info_t
*pcmcia_register_socket (int slot
,
313 struct pccard_operations
* ss_entry
,
319 DEBUG(0, "cs: pcmcia_register_socket(0x%p)\n", ss_entry
);
321 s
= kmalloc(sizeof(struct socket_info_t
), GFP_KERNEL
);
324 memset(s
, 0, sizeof(socket_info_t
));
326 s
->ss_entry
= ss_entry
;
329 /* base address = 0, map = 0 */
330 s
->cis_mem
.flags
= 0;
331 s
->cis_mem
.speed
= cis_speed
;
332 s
->use_bus_pm
= use_bus_pm
;
333 s
->erase_busy
.next
= s
->erase_busy
.prev
= &s
->erase_busy
;
334 spin_lock_init(&s
->lock
);
336 for (i
= 0; i
< sockets
; i
++)
337 if (socket_table
[i
] == NULL
) break;
339 if (i
== sockets
) sockets
++;
342 ss_entry
->inquire_socket(slot
, &s
->cap
);
343 #ifdef CONFIG_PROC_FS
346 sprintf(name
, "%02d", i
);
347 s
->proc
= proc_mkdir(name
, proc_pccard
);
349 ss_entry
->proc_setup(slot
, s
->proc
);
352 create_proc_read_entry("clients", 0, s
->proc
,
353 proc_read_clients
, s
);
358 } /* pcmcia_register_socket */
360 int register_ss_entry(int nsock
, struct pccard_operations
* ss_entry
)
364 DEBUG(0, "cs: register_ss_entry(%d, 0x%p)\n", nsock
, ss_entry
);
366 for (ns
= 0; ns
< nsock
; ns
++) {
367 pcmcia_register_socket (ns
, ss_entry
, 0);
371 } /* register_ss_entry */
373 /*====================================================================*/
375 void pcmcia_unregister_socket(socket_info_t
*s
)
380 for (j
= 0; j
< MAX_SOCK
; j
++)
381 if (socket_table
[j
] == s
) {
388 #ifdef CONFIG_PROC_FS
391 sprintf(name
, "%02d", socket
);
393 remove_proc_entry("clients", s
->proc
);
395 remove_proc_entry(name
, proc_pccard
);
403 s
->clients
= s
->clients
->next
;
409 socket_table
[socket
] = NULL
;
410 for (j
= socket
; j
< sockets
-1; j
++)
411 socket_table
[j
] = socket_table
[j
+1];
413 } /* pcmcia_unregister_socket */
415 void unregister_ss_entry(struct pccard_operations
* ss_entry
)
419 for (i
= sockets
-1; i
>= 0; i
-- ) {
420 socket_info_t
*socket
= socket_table
[i
];
421 if (socket
->ss_entry
== ss_entry
)
422 pcmcia_unregister_socket (socket
);
424 } /* unregister_ss_entry */
426 /*======================================================================
428 Shutdown_Socket() and setup_socket() are scheduled using add_timer
429 calls by the main event handler when card insertion and removal
430 events are received. Shutdown_Socket() unconfigures a socket and
431 turns off socket power. Setup_socket() turns on socket power
432 and resets the socket, in two stages.
434 ======================================================================*/
436 static void free_regions(memory_handle_t
*list
)
439 while (*list
!= NULL
) {
441 *list
= tmp
->info
.next
;
442 tmp
->region_magic
= 0;
447 static int send_event(socket_info_t
*s
, event_t event
, int priority
);
450 * Sleep for n_cs centiseconds (1 cs = 1/100th of a second)
452 static void cs_sleep(unsigned int n_cs
)
454 current
->state
= TASK_INTERRUPTIBLE
;
455 schedule_timeout( (n_cs
* HZ
+ 99) / 100);
458 static void shutdown_socket(socket_info_t
*s
)
462 DEBUG(1, "cs: shutdown_socket(%p)\n", s
);
464 /* Blank out the socket state */
465 s
->state
&= SOCKET_PRESENT
|SOCKET_SETUP_PENDING
;
467 s
->irq
.AssignedIRQ
= s
->irq
.Config
= 0;
474 #ifdef CONFIG_CARDBUS
475 cb_release_cis_mem(s
);
483 for (c
= &s
->clients
; *c
; ) {
484 if ((*c
)->state
& CLIENT_UNBOUND
) {
492 free_regions(&s
->a_region
);
493 free_regions(&s
->c_region
);
494 } /* shutdown_socket */
497 * Return zero if we think the card isn't actually present
499 static int setup_socket(socket_info_t
*s
)
502 int setup_timeout
= 100;
504 /* Wait for "not pending" */
506 get_socket_status(s
, &val
);
507 if (!(val
& SS_PENDING
))
509 if (--setup_timeout
) {
513 printk(KERN_NOTICE
"cs: socket %p voltage interrogation"
519 if (val
& SS_DETECT
) {
520 DEBUG(1, "cs: setup_socket(%p): applying power\n", s
);
521 s
->state
|= SOCKET_PRESENT
;
522 s
->socket
.flags
&= SS_DEBOUNCED
;
524 s
->socket
.Vcc
= s
->socket
.Vpp
= 33;
525 else if (!(val
& SS_XVCARD
))
526 s
->socket
.Vcc
= s
->socket
.Vpp
= 50;
528 printk(KERN_NOTICE
"cs: socket %p: unsupported "
532 if (val
& SS_CARDBUS
) {
533 s
->state
|= SOCKET_CARDBUS
;
534 #ifndef CONFIG_CARDBUS
535 printk(KERN_NOTICE
"cs: unsupported card type detected!\n");
538 set_socket(s
, &s
->socket
);
539 cs_sleep(vcc_settle
);
543 DEBUG(0, "cs: setup_socket(%p): no card!\n", s
);
550 /*======================================================================
552 Reset_socket() and unreset_socket() handle hard resets. Resets
553 have several causes: card insertion, a call to reset_socket, or
554 recovery from a suspend/resume cycle. Unreset_socket() sends
555 a CS event that matches the cause of the reset.
557 ======================================================================*/
559 static void reset_socket(socket_info_t
*s
)
561 DEBUG(1, "cs: resetting socket %p\n", s
);
562 s
->socket
.flags
|= SS_OUTPUT_ENA
| SS_RESET
;
563 set_socket(s
, &s
->socket
);
564 udelay((long)reset_time
);
565 s
->socket
.flags
&= ~SS_RESET
;
566 set_socket(s
, &s
->socket
);
567 cs_sleep(unreset_delay
);
572 (SOCKET_SETUP_PENDING|SOCKET_SUSPEND|SOCKET_RESET_PENDING)
574 static void unreset_socket(socket_info_t
*s
)
576 int setup_timeout
= unreset_limit
;
579 /* Wait for "ready" */
581 get_socket_status(s
, &val
);
584 DEBUG(2, "cs: socket %d not ready yet\n", s
->sock
);
585 if (--setup_timeout
) {
586 cs_sleep(unreset_check
);
589 printk(KERN_NOTICE
"cs: socket %p timed out during"
590 " reset. Try increasing setup_delay.\n", s
);
591 s
->state
&= ~EVENT_MASK
;
595 DEBUG(1, "cs: reset done on socket %p\n", s
);
596 if (s
->state
& SOCKET_SUSPEND
) {
597 s
->state
&= ~EVENT_MASK
;
598 if (verify_cis_cache(s
) != 0)
599 parse_events(s
, SS_DETECT
);
601 send_event(s
, CS_EVENT_PM_RESUME
, CS_EVENT_PRI_LOW
);
602 } else if (s
->state
& SOCKET_SETUP_PENDING
) {
603 #ifdef CONFIG_CARDBUS
604 if (s
->state
& SOCKET_CARDBUS
)
607 send_event(s
, CS_EVENT_CARD_INSERTION
, CS_EVENT_PRI_LOW
);
608 s
->state
&= ~SOCKET_SETUP_PENDING
;
610 send_event(s
, CS_EVENT_CARD_RESET
, CS_EVENT_PRI_LOW
);
611 if (s
->reset_handle
) {
612 s
->reset_handle
->event_callback_args
.info
= NULL
;
613 EVENT(s
->reset_handle
, CS_EVENT_RESET_COMPLETE
,
616 s
->state
&= ~EVENT_MASK
;
618 } /* unreset_socket */
620 /*======================================================================
622 The central event handler. Send_event() sends an event to all
623 valid clients. Parse_events() interprets the event bits from
624 a card status change report. Do_shotdown() handles the high
625 priority stuff associated with a card removal.
627 ======================================================================*/
629 static int send_event(socket_info_t
*s
, event_t event
, int priority
)
631 client_t
*client
= s
->clients
;
633 DEBUG(1, "cs: send_event(sock %d, event %d, pri %d)\n",
634 s
->sock
, event
, priority
);
636 for (; client
; client
= client
->next
) {
637 if (client
->state
& (CLIENT_UNBOUND
|CLIENT_STALE
))
639 if (client
->EventMask
& event
) {
640 ret
= EVENT(client
, event
, priority
);
648 static void do_shutdown(socket_info_t
*s
)
651 if (s
->state
& SOCKET_SHUTDOWN_PENDING
)
653 s
->state
|= SOCKET_SHUTDOWN_PENDING
;
654 send_event(s
, CS_EVENT_CARD_REMOVAL
, CS_EVENT_PRI_HIGH
);
655 for (client
= s
->clients
; client
; client
= client
->next
)
656 if (!(client
->Attributes
& INFO_MASTER_CLIENT
))
657 client
->state
|= CLIENT_STALE
;
658 if (s
->state
& (SOCKET_SETUP_PENDING
|SOCKET_RESET_PENDING
)) {
659 DEBUG(0, "cs: flushing pending setup\n");
660 s
->state
&= ~EVENT_MASK
;
662 cs_sleep(shutdown_delay
);
663 s
->state
&= ~SOCKET_PRESENT
;
667 static void parse_events(void *info
, u_int events
)
669 socket_info_t
*s
= info
;
670 if (events
& SS_DETECT
) {
673 get_socket_status(s
, &status
);
674 if ((s
->state
& SOCKET_PRESENT
) &&
675 (!(s
->state
& SOCKET_SUSPEND
) ||
676 !(status
& SS_DETECT
)))
678 if (status
& SS_DETECT
) {
679 if (s
->state
& SOCKET_SETUP_PENDING
) {
680 DEBUG(1, "cs: delaying pending setup\n");
683 s
->state
|= SOCKET_SETUP_PENDING
;
684 if (s
->state
& SOCKET_SUSPEND
)
685 cs_sleep(resume_delay
);
687 cs_sleep(setup_delay
);
688 s
->socket
.flags
|= SS_DEBOUNCED
;
689 if (setup_socket(s
) == 0)
690 s
->state
&= ~SOCKET_SETUP_PENDING
;
691 s
->socket
.flags
&= ~SS_DEBOUNCED
;
694 if (events
& SS_BATDEAD
)
695 send_event(s
, CS_EVENT_BATTERY_DEAD
, CS_EVENT_PRI_LOW
);
696 if (events
& SS_BATWARN
)
697 send_event(s
, CS_EVENT_BATTERY_LOW
, CS_EVENT_PRI_LOW
);
698 if (events
& SS_READY
) {
699 if (!(s
->state
& SOCKET_RESET_PENDING
))
700 send_event(s
, CS_EVENT_READY_CHANGE
, CS_EVENT_PRI_LOW
);
701 else DEBUG(1, "cs: ready change during reset\n");
705 /*======================================================================
707 Another event handler, for power management events.
709 This does not comply with the latest PC Card spec for handling
710 power management events.
712 ======================================================================*/
714 void pcmcia_suspend_socket (socket_info_t
*s
)
716 if ((s
->state
& SOCKET_PRESENT
) && !(s
->state
& SOCKET_SUSPEND
)) {
717 send_event(s
, CS_EVENT_PM_SUSPEND
, CS_EVENT_PRI_LOW
);
719 s
->state
|= SOCKET_SUSPEND
;
723 void pcmcia_resume_socket (socket_info_t
*s
)
727 /* Do this just to reinitialize the socket */
729 get_socket_status(s
, &stat
);
731 /* If there was or is a card here, we need to do something
732 about it... but parse_events will sort it all out. */
733 if ((s
->state
& SOCKET_PRESENT
) || (stat
& SS_DETECT
))
734 parse_events(s
, SS_DETECT
);
737 static int handle_pm_event(struct pm_dev
*dev
, pm_request_t rqst
, void *data
)
742 /* only for busses that don't suspend/resume slots directly */
746 DEBUG(1, "cs: received suspend notification\n");
747 for (i
= 0; i
< sockets
; i
++) {
748 s
= socket_table
[i
];
750 pcmcia_suspend_socket (socket_table
[i
]);
754 DEBUG(1, "cs: received resume notification\n");
755 for (i
= 0; i
< sockets
; i
++) {
756 s
= socket_table
[i
];
758 pcmcia_resume_socket (socket_table
[i
]);
763 } /* handle_pm_event */
765 /*======================================================================
767 Special stuff for managing IO windows, because they are scarce.
769 ======================================================================*/
771 static int alloc_io_space(socket_info_t
*s
, u_int attr
, ioaddr_t
*base
,
772 ioaddr_t num
, u_int lines
, char *name
)
777 align
= (*base
) ? (lines
? 1<<lines
: 0) : 1;
778 if (align
&& (align
< num
)) {
780 DEBUG(0, "odd IO request: num %04x align %04x\n",
784 while (align
&& (align
< num
)) align
<<= 1;
786 if (*base
& ~(align
-1)) {
787 DEBUG(0, "odd IO request: base %04x align %04x\n",
791 /* Check for an already-allocated window that must conflict with
792 what was asked for. It is a hack because it does not catch all
793 potential conflicts, just the most obvious ones. */
794 for (i
= 0; i
< MAX_IO_WIN
; i
++)
795 if ((s
->io
[i
].NumPorts
!= 0) &&
796 ((s
->io
[i
].BasePort
& (align
-1)) == *base
))
798 for (i
= 0; i
< MAX_IO_WIN
; i
++) {
799 if (s
->io
[i
].NumPorts
== 0) {
800 if (find_io_region(base
, num
, align
, name
) == 0) {
801 s
->io
[i
].Attributes
= attr
;
802 s
->io
[i
].BasePort
= *base
;
803 s
->io
[i
].NumPorts
= s
->io
[i
].InUse
= num
;
807 } else if (s
->io
[i
].Attributes
!= attr
)
809 /* Try to extend top of window */
810 try = s
->io
[i
].BasePort
+ s
->io
[i
].NumPorts
;
811 if ((*base
== 0) || (*base
== try))
812 if (find_io_region(&try, num
, 0, name
) == 0) {
814 s
->io
[i
].NumPorts
+= num
;
815 s
->io
[i
].InUse
+= num
;
818 /* Try to extend bottom of window */
819 try = s
->io
[i
].BasePort
- num
;
820 if ((*base
== 0) || (*base
== try))
821 if (find_io_region(&try, num
, 0, name
) == 0) {
822 s
->io
[i
].BasePort
= *base
= try;
823 s
->io
[i
].NumPorts
+= num
;
824 s
->io
[i
].InUse
+= num
;
828 return (i
== MAX_IO_WIN
);
829 } /* alloc_io_space */
831 static void release_io_space(socket_info_t
*s
, ioaddr_t base
,
835 release_region(base
, num
);
836 for (i
= 0; i
< MAX_IO_WIN
; i
++) {
837 if ((s
->io
[i
].BasePort
<= base
) &&
838 (s
->io
[i
].BasePort
+s
->io
[i
].NumPorts
>= base
+num
)) {
839 s
->io
[i
].InUse
-= num
;
840 /* Free the window if no one else is using it */
841 if (s
->io
[i
].InUse
== 0)
842 s
->io
[i
].NumPorts
= 0;
847 /*======================================================================
849 Access_configuration_register() reads and writes configuration
850 registers in attribute memory. Memory window 0 is reserved for
851 this and the tuple reading services.
853 ======================================================================*/
855 int pcmcia_access_configuration_register(client_handle_t handle
,
863 if (CHECK_HANDLE(handle
))
864 return CS_BAD_HANDLE
;
866 if (handle
->Function
== BIND_FN_ALL
) {
867 if (reg
->Function
>= s
->functions
)
869 c
= &s
->config
[reg
->Function
];
872 if (!(c
->state
& CONFIG_LOCKED
))
873 return CS_CONFIGURATION_LOCKED
;
875 addr
= (c
->ConfigBase
+ reg
->Offset
) >> 1;
877 switch (reg
->Action
) {
879 read_cis_mem(s
, 1, addr
, 1, &val
);
884 write_cis_mem(s
, 1, addr
, 1, &val
);
891 } /* access_configuration_register */
893 /*======================================================================
895 Bind_device() associates a device driver with a particular socket.
896 It is normally called by Driver Services after it has identified
897 a newly inserted card. An instance of that driver will then be
898 eligible to register as a client of this socket.
900 ======================================================================*/
902 int pcmcia_bind_device(bind_req_t
*req
)
907 if (CHECK_SOCKET(req
->Socket
))
908 return CS_BAD_SOCKET
;
911 client
= (client_t
*)kmalloc(sizeof(client_t
), GFP_KERNEL
);
912 if (!client
) return CS_OUT_OF_RESOURCE
;
913 memset(client
, '\0', sizeof(client_t
));
914 client
->client_magic
= CLIENT_MAGIC
;
915 strncpy(client
->dev_info
, (char *)req
->dev_info
, DEV_NAME_LEN
);
916 client
->Socket
= req
->Socket
;
917 client
->Function
= req
->Function
;
918 client
->state
= CLIENT_UNBOUND
;
919 client
->erase_busy
.next
= &client
->erase_busy
;
920 client
->erase_busy
.prev
= &client
->erase_busy
;
921 init_waitqueue_head(&client
->mtd_req
);
922 client
->next
= s
->clients
;
924 DEBUG(1, "cs: bind_device(): client 0x%p, sock %d, dev %s\n",
925 client
, client
->Socket
, client
->dev_info
);
929 /*======================================================================
931 Bind_mtd() associates a device driver with a particular memory
932 region. It is normally called by Driver Services after it has
933 identified a memory device type. An instance of the corresponding
934 driver will then be able to register to control this region.
936 ======================================================================*/
938 int pcmcia_bind_mtd(mtd_bind_t
*req
)
941 memory_handle_t region
;
943 if (CHECK_SOCKET(req
->Socket
))
944 return CS_BAD_SOCKET
;
947 if (req
->Attributes
& REGION_TYPE_AM
)
948 region
= s
->a_region
;
950 region
= s
->c_region
;
953 if (region
->info
.CardOffset
== req
->CardOffset
) break;
954 region
= region
->info
.next
;
956 if (!region
|| (region
->mtd
!= NULL
))
957 return CS_BAD_OFFSET
;
958 strncpy(region
->dev_info
, (char *)req
->dev_info
, DEV_NAME_LEN
);
960 DEBUG(1, "cs: bind_mtd(): attr 0x%x, offset 0x%x, dev %s\n",
961 req
->Attributes
, req
->CardOffset
, (char *)req
->dev_info
);
965 /*====================================================================*/
967 int pcmcia_deregister_client(client_handle_t handle
)
971 memory_handle_t region
;
975 DEBUG(1, "cs: deregister_client(%p)\n", handle
);
976 if (CHECK_HANDLE(handle
))
977 return CS_BAD_HANDLE
;
979 (CLIENT_IRQ_REQ
|CLIENT_IO_REQ
|CLIENT_CONFIG_LOCKED
))
981 for (i
= 0; i
< MAX_WIN
; i
++)
982 if (handle
->state
& CLIENT_WIN_REQ(i
))
985 /* Disconnect all MTD links */
987 if (handle
->mtd_count
) {
988 for (region
= s
->a_region
; region
; region
= region
->info
.next
)
989 if (region
->mtd
== handle
) region
->mtd
= NULL
;
990 for (region
= s
->c_region
; region
; region
= region
->info
.next
)
991 if (region
->mtd
== handle
) region
->mtd
= NULL
;
994 sn
= handle
->Socket
; s
= socket_table
[sn
];
996 if ((handle
->state
& CLIENT_STALE
) ||
997 (handle
->Attributes
& INFO_MASTER_CLIENT
)) {
998 spin_lock_irqsave(&s
->lock
, flags
);
999 client
= &s
->clients
;
1000 while ((*client
) && ((*client
) != handle
))
1001 client
= &(*client
)->next
;
1002 if (*client
== NULL
) {
1003 spin_unlock_irqrestore(&s
->lock
, flags
);
1004 return CS_BAD_HANDLE
;
1006 *client
= handle
->next
;
1007 handle
->client_magic
= 0;
1009 spin_unlock_irqrestore(&s
->lock
, flags
);
1011 handle
->state
= CLIENT_UNBOUND
;
1012 handle
->mtd_count
= 0;
1013 handle
->event_handler
= NULL
;
1016 if (--s
->real_clients
== 0)
1017 register_callback(s
, NULL
, NULL
);
1020 } /* deregister_client */
1022 /*====================================================================*/
1024 int pcmcia_get_configuration_info(client_handle_t handle
,
1025 config_info_t
*config
)
1030 if (CHECK_HANDLE(handle
))
1031 return CS_BAD_HANDLE
;
1033 if (!(s
->state
& SOCKET_PRESENT
))
1036 if (handle
->Function
== BIND_FN_ALL
) {
1037 if (config
->Function
&& (config
->Function
>= s
->functions
))
1040 config
->Function
= handle
->Function
;
1042 #ifdef CONFIG_CARDBUS
1043 if (s
->state
& SOCKET_CARDBUS
) {
1044 u_char fn
= config
->Function
;
1045 memset(config
, 0, sizeof(config_info_t
));
1046 config
->Function
= fn
;
1047 config
->Vcc
= s
->socket
.Vcc
;
1048 config
->Vpp1
= config
->Vpp2
= s
->socket
.Vpp
;
1049 config
->Option
= s
->cap
.cb_dev
->subordinate
->number
;
1051 config
->Attributes
= CONF_VALID_CLIENT
;
1052 config
->IntType
= INT_CARDBUS
;
1053 config
->AssignedIRQ
= s
->irq
.AssignedIRQ
;
1054 if (config
->AssignedIRQ
)
1055 config
->Attributes
|= CONF_ENABLE_IRQ
;
1056 config
->BasePort1
= s
->io
[0].BasePort
;
1057 config
->NumPorts1
= s
->io
[0].NumPorts
;
1063 c
= (s
->config
!= NULL
) ? &s
->config
[config
->Function
] : NULL
;
1065 if ((c
== NULL
) || !(c
->state
& CONFIG_LOCKED
)) {
1066 config
->Attributes
= 0;
1067 config
->Vcc
= s
->socket
.Vcc
;
1068 config
->Vpp1
= config
->Vpp2
= s
->socket
.Vpp
;
1072 /* !!! This is a hack !!! */
1073 memcpy(&config
->Attributes
, &c
->Attributes
, sizeof(config_t
));
1074 config
->Attributes
|= CONF_VALID_CLIENT
;
1075 config
->CardValues
= c
->CardValues
;
1076 config
->IRQAttributes
= c
->irq
.Attributes
;
1077 config
->AssignedIRQ
= s
->irq
.AssignedIRQ
;
1078 config
->BasePort1
= c
->io
.BasePort1
;
1079 config
->NumPorts1
= c
->io
.NumPorts1
;
1080 config
->Attributes1
= c
->io
.Attributes1
;
1081 config
->BasePort2
= c
->io
.BasePort2
;
1082 config
->NumPorts2
= c
->io
.NumPorts2
;
1083 config
->Attributes2
= c
->io
.Attributes2
;
1084 config
->IOAddrLines
= c
->io
.IOAddrLines
;
1087 } /* get_configuration_info */
1089 /*======================================================================
1091 Return information about this version of Card Services.
1093 ======================================================================*/
1095 int pcmcia_get_card_services_info(servinfo_t
*info
)
1097 info
->Signature
[0] = 'C';
1098 info
->Signature
[1] = 'S';
1099 info
->Count
= sockets
;
1100 info
->Revision
= CS_RELEASE_CODE
;
1101 info
->CSLevel
= 0x0210;
1102 info
->VendorString
= (char *)release
;
1104 } /* get_card_services_info */
1106 /*======================================================================
1108 Note that get_first_client() *does* recognize the Socket field
1109 in the request structure.
1111 ======================================================================*/
1113 int pcmcia_get_first_client(client_handle_t
*handle
, client_req_t
*req
)
1116 if (req
->Attributes
& CLIENT_THIS_SOCKET
)
1120 if (CHECK_SOCKET(req
->Socket
))
1121 return CS_BAD_SOCKET
;
1122 if (socket_table
[s
]->clients
== NULL
)
1123 return CS_NO_MORE_ITEMS
;
1124 *handle
= socket_table
[s
]->clients
;
1126 } /* get_first_client */
1128 /*====================================================================*/
1130 int pcmcia_get_next_client(client_handle_t
*handle
, client_req_t
*req
)
1133 if ((handle
== NULL
) || CHECK_HANDLE(*handle
))
1134 return CS_BAD_HANDLE
;
1135 if ((*handle
)->next
== NULL
) {
1136 if (req
->Attributes
& CLIENT_THIS_SOCKET
)
1137 return CS_NO_MORE_ITEMS
;
1138 s
= SOCKET(*handle
);
1139 if (s
->clients
== NULL
)
1140 return CS_NO_MORE_ITEMS
;
1141 *handle
= s
->clients
;
1143 *handle
= (*handle
)->next
;
1145 } /* get_next_client */
1147 /*====================================================================*/
1149 int pcmcia_get_window(window_handle_t
*handle
, int idx
, win_req_t
*req
)
1156 s
= SOCKET((client_handle_t
)*handle
);
1158 s
= (*handle
)->sock
;
1159 if (!(s
->state
& SOCKET_PRESENT
))
1161 for (w
= idx
; w
< MAX_WIN
; w
++)
1162 if (s
->state
& SOCKET_WIN_REQ(w
)) break;
1164 return CS_NO_MORE_ITEMS
;
1166 req
->Base
= win
->ctl
.sys_start
;
1167 req
->Size
= win
->ctl
.sys_stop
- win
->ctl
.sys_start
+ 1;
1168 req
->AccessSpeed
= win
->ctl
.speed
;
1169 req
->Attributes
= 0;
1170 if (win
->ctl
.flags
& MAP_ATTRIB
)
1171 req
->Attributes
|= WIN_MEMORY_TYPE_AM
;
1172 if (win
->ctl
.flags
& MAP_ACTIVE
)
1173 req
->Attributes
|= WIN_ENABLE
;
1174 if (win
->ctl
.flags
& MAP_16BIT
)
1175 req
->Attributes
|= WIN_DATA_WIDTH_16
;
1176 if (win
->ctl
.flags
& MAP_USE_WAIT
)
1177 req
->Attributes
|= WIN_USE_WAIT
;
1182 int pcmcia_get_first_window(window_handle_t
*win
, win_req_t
*req
)
1184 if ((win
== NULL
) || ((*win
)->magic
!= WINDOW_MAGIC
))
1185 return CS_BAD_HANDLE
;
1186 return pcmcia_get_window(win
, 0, req
);
1189 int pcmcia_get_next_window(window_handle_t
*win
, win_req_t
*req
)
1191 if ((win
== NULL
) || ((*win
)->magic
!= WINDOW_MAGIC
))
1192 return CS_BAD_HANDLE
;
1193 return pcmcia_get_window(win
, (*win
)->index
+1, req
);
1196 /*=====================================================================
1198 Return the PCI device associated with a card..
1200 ======================================================================*/
1202 #ifdef CONFIG_CARDBUS
1204 struct pci_bus
*pcmcia_lookup_bus(client_handle_t handle
)
1208 if (CHECK_HANDLE(handle
))
1211 if (!(s
->state
& SOCKET_CARDBUS
))
1214 return s
->cap
.cb_dev
->subordinate
;
1217 EXPORT_SYMBOL(pcmcia_lookup_bus
);
1221 /*======================================================================
1223 Get the current socket state bits. We don't support the latched
1224 SocketState yet: I haven't seen any point for it.
1226 ======================================================================*/
1228 int pcmcia_get_status(client_handle_t handle
, cs_status_t
*status
)
1234 if (CHECK_HANDLE(handle
))
1235 return CS_BAD_HANDLE
;
1237 get_socket_status(s
, &val
);
1238 status
->CardState
= status
->SocketState
= 0;
1239 status
->CardState
|= (val
& SS_DETECT
) ? CS_EVENT_CARD_DETECT
: 0;
1240 status
->CardState
|= (val
& SS_CARDBUS
) ? CS_EVENT_CB_DETECT
: 0;
1241 status
->CardState
|= (val
& SS_3VCARD
) ? CS_EVENT_3VCARD
: 0;
1242 status
->CardState
|= (val
& SS_XVCARD
) ? CS_EVENT_XVCARD
: 0;
1243 if (s
->state
& SOCKET_SUSPEND
)
1244 status
->CardState
|= CS_EVENT_PM_SUSPEND
;
1245 if (!(s
->state
& SOCKET_PRESENT
))
1247 if (s
->state
& SOCKET_SETUP_PENDING
)
1248 status
->CardState
|= CS_EVENT_CARD_INSERTION
;
1250 /* Get info from the PRR, if necessary */
1251 if (handle
->Function
== BIND_FN_ALL
) {
1252 if (status
->Function
&& (status
->Function
>= s
->functions
))
1254 c
= (s
->config
!= NULL
) ? &s
->config
[status
->Function
] : NULL
;
1257 if ((c
!= NULL
) && (c
->state
& CONFIG_LOCKED
) &&
1258 (c
->IntType
& INT_MEMORY_AND_IO
)) {
1260 if (c
->Present
& PRESENT_PIN_REPLACE
) {
1261 read_cis_mem(s
, 1, (c
->ConfigBase
+CISREG_PRR
)>>1, 1, ®
);
1262 status
->CardState
|=
1263 (reg
& PRR_WP_STATUS
) ? CS_EVENT_WRITE_PROTECT
: 0;
1264 status
->CardState
|=
1265 (reg
& PRR_READY_STATUS
) ? CS_EVENT_READY_CHANGE
: 0;
1266 status
->CardState
|=
1267 (reg
& PRR_BVD2_STATUS
) ? CS_EVENT_BATTERY_LOW
: 0;
1268 status
->CardState
|=
1269 (reg
& PRR_BVD1_STATUS
) ? CS_EVENT_BATTERY_DEAD
: 0;
1271 /* No PRR? Then assume we're always ready */
1272 status
->CardState
|= CS_EVENT_READY_CHANGE
;
1274 if (c
->Present
& PRESENT_EXT_STATUS
) {
1275 read_cis_mem(s
, 1, (c
->ConfigBase
+CISREG_ESR
)>>1, 1, ®
);
1276 status
->CardState
|=
1277 (reg
& ESR_REQ_ATTN
) ? CS_EVENT_REQUEST_ATTENTION
: 0;
1281 status
->CardState
|=
1282 (val
& SS_WRPROT
) ? CS_EVENT_WRITE_PROTECT
: 0;
1283 status
->CardState
|=
1284 (val
& SS_BATDEAD
) ? CS_EVENT_BATTERY_DEAD
: 0;
1285 status
->CardState
|=
1286 (val
& SS_BATWARN
) ? CS_EVENT_BATTERY_LOW
: 0;
1287 status
->CardState
|=
1288 (val
& SS_READY
) ? CS_EVENT_READY_CHANGE
: 0;
1292 /*======================================================================
1294 Change the card address of an already open memory window.
1296 ======================================================================*/
1298 int pcmcia_get_mem_page(window_handle_t win
, memreq_t
*req
)
1300 if ((win
== NULL
) || (win
->magic
!= WINDOW_MAGIC
))
1301 return CS_BAD_HANDLE
;
1303 req
->CardOffset
= win
->ctl
.card_start
;
1305 } /* get_mem_page */
1307 int pcmcia_map_mem_page(window_handle_t win
, memreq_t
*req
)
1310 if ((win
== NULL
) || (win
->magic
!= WINDOW_MAGIC
))
1311 return CS_BAD_HANDLE
;
1315 win
->ctl
.card_start
= req
->CardOffset
;
1316 if (set_mem_map(s
, &win
->ctl
) != 0)
1317 return CS_BAD_OFFSET
;
1319 } /* map_mem_page */
1321 /*======================================================================
1323 Modify a locked socket configuration
1325 ======================================================================*/
1327 int pcmcia_modify_configuration(client_handle_t handle
,
1333 if (CHECK_HANDLE(handle
))
1334 return CS_BAD_HANDLE
;
1335 s
= SOCKET(handle
); c
= CONFIG(handle
);
1336 if (!(s
->state
& SOCKET_PRESENT
))
1338 if (!(c
->state
& CONFIG_LOCKED
))
1339 return CS_CONFIGURATION_LOCKED
;
1341 if (mod
->Attributes
& CONF_IRQ_CHANGE_VALID
) {
1342 if (mod
->Attributes
& CONF_ENABLE_IRQ
) {
1343 c
->Attributes
|= CONF_ENABLE_IRQ
;
1344 s
->socket
.io_irq
= s
->irq
.AssignedIRQ
;
1346 c
->Attributes
&= ~CONF_ENABLE_IRQ
;
1347 s
->socket
.io_irq
= 0;
1349 set_socket(s
, &s
->socket
);
1352 if (mod
->Attributes
& CONF_VCC_CHANGE_VALID
)
1355 /* We only allow changing Vpp1 and Vpp2 to the same value */
1356 if ((mod
->Attributes
& CONF_VPP1_CHANGE_VALID
) &&
1357 (mod
->Attributes
& CONF_VPP2_CHANGE_VALID
)) {
1358 if (mod
->Vpp1
!= mod
->Vpp2
)
1360 c
->Vpp1
= c
->Vpp2
= s
->socket
.Vpp
= mod
->Vpp1
;
1361 if (set_socket(s
, &s
->socket
))
1363 } else if ((mod
->Attributes
& CONF_VPP1_CHANGE_VALID
) ||
1364 (mod
->Attributes
& CONF_VPP2_CHANGE_VALID
))
1368 } /* modify_configuration */
1370 /*======================================================================
1372 Modify the attributes of a window returned by RequestWindow.
1374 ======================================================================*/
1376 int pcmcia_modify_window(window_handle_t win
, modwin_t
*req
)
1378 if ((win
== NULL
) || (win
->magic
!= WINDOW_MAGIC
))
1379 return CS_BAD_HANDLE
;
1381 win
->ctl
.flags
&= ~(MAP_ATTRIB
|MAP_ACTIVE
);
1382 if (req
->Attributes
& WIN_MEMORY_TYPE
)
1383 win
->ctl
.flags
|= MAP_ATTRIB
;
1384 if (req
->Attributes
& WIN_ENABLE
)
1385 win
->ctl
.flags
|= MAP_ACTIVE
;
1386 if (req
->Attributes
& WIN_DATA_WIDTH_16
)
1387 win
->ctl
.flags
|= MAP_16BIT
;
1388 if (req
->Attributes
& WIN_USE_WAIT
)
1389 win
->ctl
.flags
|= MAP_USE_WAIT
;
1390 win
->ctl
.speed
= req
->AccessSpeed
;
1391 set_mem_map(win
->sock
, &win
->ctl
);
1394 } /* modify_window */
1396 /*======================================================================
1398 Register_client() uses the dev_info_t handle to match the
1399 caller with a socket. The driver must have already been bound
1400 to a socket with bind_device() -- in fact, bind_device()
1401 allocates the client structure that will be used.
1403 ======================================================================*/
1405 int pcmcia_register_client(client_handle_t
*handle
, client_reg_t
*req
)
1411 /* Look for unbound client with matching dev_info */
1413 for (ns
= 0; ns
< sockets
; ns
++) {
1414 client
= socket_table
[ns
]->clients
;
1415 while (client
!= NULL
) {
1416 if ((strcmp(client
->dev_info
, (char *)req
->dev_info
) == 0)
1417 && (client
->state
& CLIENT_UNBOUND
)) break;
1418 client
= client
->next
;
1420 if (client
!= NULL
) break;
1423 return CS_OUT_OF_RESOURCE
;
1425 s
= socket_table
[ns
];
1426 if (++s
->real_clients
== 1) {
1428 register_callback(s
, &parse_events
, s
);
1429 get_socket_status(s
, &status
);
1430 if ((status
& SS_DETECT
) &&
1431 !(s
->state
& SOCKET_SETUP_PENDING
)) {
1432 s
->state
|= SOCKET_SETUP_PENDING
;
1433 if (setup_socket(s
) == 0)
1434 s
->state
&= ~SOCKET_SETUP_PENDING
;
1439 client
->state
&= ~CLIENT_UNBOUND
;
1440 client
->Socket
= ns
;
1441 client
->Attributes
= req
->Attributes
;
1442 client
->EventMask
= req
->EventMask
;
1443 client
->event_handler
= req
->event_handler
;
1444 client
->event_callback_args
= req
->event_callback_args
;
1445 client
->event_callback_args
.client_handle
= client
;
1446 client
->event_callback_args
.bus
= s
->cap
.bus
;
1448 if (s
->state
& SOCKET_CARDBUS
)
1449 client
->state
|= CLIENT_CARDBUS
;
1451 if ((!(s
->state
& SOCKET_CARDBUS
)) && (s
->functions
== 0) &&
1452 (client
->Function
!= BIND_FN_ALL
)) {
1453 cistpl_longlink_mfc_t mfc
;
1454 if (read_tuple(client
, CISTPL_LONGLINK_MFC
, &mfc
)
1456 s
->functions
= mfc
.nfn
;
1459 s
->config
= kmalloc(sizeof(config_t
) * s
->functions
,
1461 memset(s
->config
, 0, sizeof(config_t
) * s
->functions
);
1464 DEBUG(1, "cs: register_client(): client 0x%p, sock %d, dev %s\n",
1465 client
, client
->Socket
, client
->dev_info
);
1466 if (client
->EventMask
& CS_EVENT_REGISTRATION_COMPLETE
)
1467 EVENT(client
, CS_EVENT_REGISTRATION_COMPLETE
, CS_EVENT_PRI_LOW
);
1468 if ((socket_table
[ns
]->state
& SOCKET_PRESENT
) &&
1469 !(socket_table
[ns
]->state
& SOCKET_SETUP_PENDING
)) {
1470 if (client
->EventMask
& CS_EVENT_CARD_INSERTION
)
1471 EVENT(client
, CS_EVENT_CARD_INSERTION
, CS_EVENT_PRI_LOW
);
1473 client
->PendingEvents
|= CS_EVENT_CARD_INSERTION
;
1476 } /* register_client */
1478 /*====================================================================*/
1480 int pcmcia_release_configuration(client_handle_t handle
)
1482 pccard_io_map io
= { 0, 0, 0, 0, 1 };
1486 if (CHECK_HANDLE(handle
) ||
1487 !(handle
->state
& CLIENT_CONFIG_LOCKED
))
1488 return CS_BAD_HANDLE
;
1489 handle
->state
&= ~CLIENT_CONFIG_LOCKED
;
1492 #ifdef CONFIG_CARDBUS
1493 if (handle
->state
& CLIENT_CARDBUS
) {
1500 if (!(handle
->state
& CLIENT_STALE
)) {
1501 config_t
*c
= CONFIG(handle
);
1502 if (--(s
->lock_count
) == 0) {
1503 s
->socket
.flags
= SS_OUTPUT_ENA
;
1505 s
->socket
.io_irq
= 0;
1506 set_socket(s
, &s
->socket
);
1508 if (c
->state
& CONFIG_IO_REQ
)
1509 for (i
= 0; i
< MAX_IO_WIN
; i
++) {
1510 if (s
->io
[i
].NumPorts
== 0)
1513 if (s
->io
[i
].Config
!= 0)
1518 c
->state
&= ~CONFIG_LOCKED
;
1522 } /* release_configuration */
1524 /*======================================================================
1526 Release_io() releases the I/O ranges allocated by a client. This
1527 may be invoked some time after a card ejection has already dumped
1528 the actual socket configuration, so if the client is "stale", we
1529 don't bother checking the port ranges against the current socket
1532 ======================================================================*/
1534 int pcmcia_release_io(client_handle_t handle
, io_req_t
*req
)
1538 if (CHECK_HANDLE(handle
) || !(handle
->state
& CLIENT_IO_REQ
))
1539 return CS_BAD_HANDLE
;
1540 handle
->state
&= ~CLIENT_IO_REQ
;
1543 #ifdef CONFIG_CARDBUS
1544 if (handle
->state
& CLIENT_CARDBUS
) {
1550 if (!(handle
->state
& CLIENT_STALE
)) {
1551 config_t
*c
= CONFIG(handle
);
1552 if (c
->state
& CONFIG_LOCKED
)
1553 return CS_CONFIGURATION_LOCKED
;
1554 if ((c
->io
.BasePort1
!= req
->BasePort1
) ||
1555 (c
->io
.NumPorts1
!= req
->NumPorts1
) ||
1556 (c
->io
.BasePort2
!= req
->BasePort2
) ||
1557 (c
->io
.NumPorts2
!= req
->NumPorts2
))
1559 c
->state
&= ~CONFIG_IO_REQ
;
1562 release_io_space(s
, req
->BasePort1
, req
->NumPorts1
);
1564 release_io_space(s
, req
->BasePort2
, req
->NumPorts2
);
1569 /*====================================================================*/
1571 int pcmcia_release_irq(client_handle_t handle
, irq_req_t
*req
)
1574 if (CHECK_HANDLE(handle
) || !(handle
->state
& CLIENT_IRQ_REQ
))
1575 return CS_BAD_HANDLE
;
1576 handle
->state
&= ~CLIENT_IRQ_REQ
;
1579 if (!(handle
->state
& CLIENT_STALE
)) {
1580 config_t
*c
= CONFIG(handle
);
1581 if (c
->state
& CONFIG_LOCKED
)
1582 return CS_CONFIGURATION_LOCKED
;
1583 if (c
->irq
.Attributes
!= req
->Attributes
)
1584 return CS_BAD_ATTRIBUTE
;
1585 if (s
->irq
.AssignedIRQ
!= req
->AssignedIRQ
)
1587 if (--s
->irq
.Config
== 0) {
1588 c
->state
&= ~CONFIG_IRQ_REQ
;
1589 s
->irq
.AssignedIRQ
= 0;
1593 if (req
->Attributes
& IRQ_HANDLE_PRESENT
) {
1594 bus_free_irq(s
->cap
.bus
, req
->AssignedIRQ
, req
->Instance
);
1598 if (req
->AssignedIRQ
!= s
->cap
.pci_irq
)
1599 undo_irq(req
->Attributes
, req
->AssignedIRQ
);
1603 } /* cs_release_irq */
1605 /*====================================================================*/
1607 int pcmcia_release_window(window_handle_t win
)
1611 if ((win
== NULL
) || (win
->magic
!= WINDOW_MAGIC
))
1612 return CS_BAD_HANDLE
;
1614 if (!(win
->handle
->state
& CLIENT_WIN_REQ(win
->index
)))
1615 return CS_BAD_HANDLE
;
1617 /* Shut down memory window */
1618 win
->ctl
.flags
&= ~MAP_ACTIVE
;
1619 set_mem_map(s
, &win
->ctl
);
1620 s
->state
&= ~SOCKET_WIN_REQ(win
->index
);
1622 /* Release system memory */
1623 release_mem_region(win
->base
, win
->size
);
1624 win
->handle
->state
&= ~CLIENT_WIN_REQ(win
->index
);
1629 } /* release_window */
1631 /*====================================================================*/
1633 int pcmcia_request_configuration(client_handle_t handle
,
1640 pccard_io_map iomap
;
1642 if (CHECK_HANDLE(handle
))
1643 return CS_BAD_HANDLE
;
1644 i
= handle
->Socket
; s
= socket_table
[i
];
1645 if (!(s
->state
& SOCKET_PRESENT
))
1648 #ifdef CONFIG_CARDBUS
1649 if (handle
->state
& CLIENT_CARDBUS
) {
1650 if (!(req
->IntType
& INT_CARDBUS
))
1651 return CS_UNSUPPORTED_MODE
;
1652 if (s
->lock_count
!= 0)
1653 return CS_CONFIGURATION_LOCKED
;
1655 handle
->state
|= CLIENT_CONFIG_LOCKED
;
1661 if (req
->IntType
& INT_CARDBUS
)
1662 return CS_UNSUPPORTED_MODE
;
1664 if (c
->state
& CONFIG_LOCKED
)
1665 return CS_CONFIGURATION_LOCKED
;
1667 /* Do power control. We don't allow changes in Vcc. */
1668 if (s
->socket
.Vcc
!= req
->Vcc
)
1670 if (req
->Vpp1
!= req
->Vpp2
)
1672 s
->socket
.Vpp
= req
->Vpp1
;
1673 if (set_socket(s
, &s
->socket
))
1676 c
->Vcc
= req
->Vcc
; c
->Vpp1
= c
->Vpp2
= req
->Vpp1
;
1678 /* Pick memory or I/O card, DMA mode, interrupt */
1679 c
->IntType
= req
->IntType
;
1680 c
->Attributes
= req
->Attributes
;
1681 if (req
->IntType
& INT_MEMORY_AND_IO
)
1682 s
->socket
.flags
|= SS_IOCARD
;
1683 if (req
->Attributes
& CONF_ENABLE_DMA
)
1684 s
->socket
.flags
|= SS_DMA_MODE
;
1685 if (req
->Attributes
& CONF_ENABLE_SPKR
)
1686 s
->socket
.flags
|= SS_SPKR_ENA
;
1687 if (req
->Attributes
& CONF_ENABLE_IRQ
)
1688 s
->socket
.io_irq
= s
->irq
.AssignedIRQ
;
1690 s
->socket
.io_irq
= 0;
1691 set_socket(s
, &s
->socket
);
1694 /* Set up CIS configuration registers */
1695 base
= c
->ConfigBase
= req
->ConfigBase
;
1696 c
->Present
= c
->CardValues
= req
->Present
;
1697 if (req
->Present
& PRESENT_COPY
) {
1698 c
->Copy
= req
->Copy
;
1699 write_cis_mem(s
, 1, (base
+ CISREG_SCR
)>>1, 1, &c
->Copy
);
1701 if (req
->Present
& PRESENT_OPTION
) {
1702 if (s
->functions
== 1) {
1703 c
->Option
= req
->ConfigIndex
& COR_CONFIG_MASK
;
1705 c
->Option
= req
->ConfigIndex
& COR_MFC_CONFIG_MASK
;
1706 c
->Option
|= COR_FUNC_ENA
|COR_IREQ_ENA
;
1707 if (req
->Present
& PRESENT_IOBASE_0
)
1708 c
->Option
|= COR_ADDR_DECODE
;
1710 if (c
->state
& CONFIG_IRQ_REQ
)
1711 if (!(c
->irq
.Attributes
& IRQ_FORCED_PULSE
))
1712 c
->Option
|= COR_LEVEL_REQ
;
1713 write_cis_mem(s
, 1, (base
+ CISREG_COR
)>>1, 1, &c
->Option
);
1716 if (req
->Present
& PRESENT_STATUS
) {
1717 c
->Status
= req
->Status
;
1718 write_cis_mem(s
, 1, (base
+ CISREG_CCSR
)>>1, 1, &c
->Status
);
1720 if (req
->Present
& PRESENT_PIN_REPLACE
) {
1722 write_cis_mem(s
, 1, (base
+ CISREG_PRR
)>>1, 1, &c
->Pin
);
1724 if (req
->Present
& PRESENT_EXT_STATUS
) {
1725 c
->ExtStatus
= req
->ExtStatus
;
1726 write_cis_mem(s
, 1, (base
+ CISREG_ESR
)>>1, 1, &c
->ExtStatus
);
1728 if (req
->Present
& PRESENT_IOBASE_0
) {
1729 u_char b
= c
->io
.BasePort1
& 0xff;
1730 write_cis_mem(s
, 1, (base
+ CISREG_IOBASE_0
)>>1, 1, &b
);
1731 b
= (c
->io
.BasePort1
>> 8) & 0xff;
1732 write_cis_mem(s
, 1, (base
+ CISREG_IOBASE_1
)>>1, 1, &b
);
1734 if (req
->Present
& PRESENT_IOSIZE
) {
1735 u_char b
= c
->io
.NumPorts1
+ c
->io
.NumPorts2
- 1;
1736 write_cis_mem(s
, 1, (base
+ CISREG_IOSIZE
)>>1, 1, &b
);
1739 /* Configure I/O windows */
1740 if (c
->state
& CONFIG_IO_REQ
) {
1741 iomap
.speed
= io_speed
;
1742 for (i
= 0; i
< MAX_IO_WIN
; i
++)
1743 if (s
->io
[i
].NumPorts
!= 0) {
1745 iomap
.flags
= MAP_ACTIVE
;
1746 switch (s
->io
[i
].Attributes
& IO_DATA_PATH_WIDTH
) {
1747 case IO_DATA_PATH_WIDTH_16
:
1748 iomap
.flags
|= MAP_16BIT
; break;
1749 case IO_DATA_PATH_WIDTH_AUTO
:
1750 iomap
.flags
|= MAP_AUTOSZ
; break;
1754 iomap
.start
= s
->io
[i
].BasePort
;
1755 iomap
.stop
= iomap
.start
+ s
->io
[i
].NumPorts
- 1;
1756 set_io_map(s
, &iomap
);
1761 c
->state
|= CONFIG_LOCKED
;
1762 handle
->state
|= CLIENT_CONFIG_LOCKED
;
1764 } /* request_configuration */
1766 /*======================================================================
1768 Request_io() reserves ranges of port addresses for a socket.
1769 I have not implemented range sharing or alias addressing.
1771 ======================================================================*/
1773 int pcmcia_request_io(client_handle_t handle
, io_req_t
*req
)
1778 if (CHECK_HANDLE(handle
))
1779 return CS_BAD_HANDLE
;
1781 if (!(s
->state
& SOCKET_PRESENT
))
1784 if (handle
->state
& CLIENT_CARDBUS
) {
1785 #ifdef CONFIG_CARDBUS
1786 int ret
= cb_config(s
);
1787 if (ret
== CS_SUCCESS
)
1788 handle
->state
|= CLIENT_IO_REQ
;
1791 return CS_UNSUPPORTED_FUNCTION
;
1796 return CS_UNSUPPORTED_MODE
;
1798 if (c
->state
& CONFIG_LOCKED
)
1799 return CS_CONFIGURATION_LOCKED
;
1800 if (c
->state
& CONFIG_IO_REQ
)
1802 if (req
->Attributes1
& (IO_SHARED
| IO_FORCE_ALIAS_ACCESS
))
1803 return CS_BAD_ATTRIBUTE
;
1804 if ((req
->NumPorts2
> 0) &&
1805 (req
->Attributes2
& (IO_SHARED
| IO_FORCE_ALIAS_ACCESS
)))
1806 return CS_BAD_ATTRIBUTE
;
1808 if (alloc_io_space(s
, req
->Attributes1
, &req
->BasePort1
,
1809 req
->NumPorts1
, req
->IOAddrLines
,
1813 if (req
->NumPorts2
) {
1814 if (alloc_io_space(s
, req
->Attributes2
, &req
->BasePort2
,
1815 req
->NumPorts2
, req
->IOAddrLines
,
1816 handle
->dev_info
)) {
1817 release_io_space(s
, req
->BasePort1
, req
->NumPorts1
);
1823 c
->state
|= CONFIG_IO_REQ
;
1824 handle
->state
|= CLIENT_IO_REQ
;
1828 /*======================================================================
1830 Request_irq() reserves an irq for this client.
1832 Also, since Linux only reserves irq's when they are actually
1833 hooked, we don't guarantee that an irq will still be available
1834 when the configuration is locked. Now that I think about it,
1835 there might be a way to fix this using a dummy handler.
1837 ======================================================================*/
1839 int pcmcia_request_irq(client_handle_t handle
, irq_req_t
*req
)
1843 int ret
= 0, irq
= 0;
1845 if (CHECK_HANDLE(handle
))
1846 return CS_BAD_HANDLE
;
1848 if (!(s
->state
& SOCKET_PRESENT
))
1851 if (c
->state
& CONFIG_LOCKED
)
1852 return CS_CONFIGURATION_LOCKED
;
1853 if (c
->state
& CONFIG_IRQ_REQ
)
1856 /* Short cut: if there are no ISA interrupts, then it is PCI */
1857 if (!s
->cap
.irq_mask
) {
1858 irq
= s
->cap
.pci_irq
;
1859 ret
= (irq
) ? 0 : CS_IN_USE
;
1861 } else if (s
->irq
.AssignedIRQ
!= 0) {
1862 /* If the interrupt is already assigned, it must match */
1863 irq
= s
->irq
.AssignedIRQ
;
1864 if (req
->IRQInfo1
& IRQ_INFO2_VALID
) {
1865 u_int mask
= req
->IRQInfo2
& s
->cap
.irq_mask
;
1866 ret
= ((mask
>> irq
) & 1) ? 0 : CS_BAD_ARGS
;
1868 ret
= ((req
->IRQInfo1
&IRQ_MASK
) == irq
) ? 0 : CS_BAD_ARGS
;
1871 if (req
->IRQInfo1
& IRQ_INFO2_VALID
) {
1872 u_int
try, mask
= req
->IRQInfo2
& s
->cap
.irq_mask
;
1873 for (try = 0; try < 2; try++) {
1874 for (irq
= 0; irq
< 32; irq
++)
1875 if ((mask
>> irq
) & 1) {
1876 ret
= try_irq(req
->Attributes
, irq
, try);
1877 if (ret
== 0) break;
1879 if (ret
== 0) break;
1882 irq
= req
->IRQInfo1
& IRQ_MASK
;
1883 ret
= try_irq(req
->Attributes
, irq
, 1);
1887 if (ret
!= 0) return ret
;
1889 if (req
->Attributes
& IRQ_HANDLE_PRESENT
) {
1890 if (bus_request_irq(s
->cap
.bus
, irq
, req
->Handler
,
1891 ((req
->Attributes
& IRQ_TYPE_DYNAMIC_SHARING
) ||
1892 (s
->functions
> 1) ||
1893 (irq
== s
->cap
.pci_irq
)) ? SA_SHIRQ
: 0,
1894 handle
->dev_info
, req
->Instance
))
1898 c
->irq
.Attributes
= req
->Attributes
;
1899 s
->irq
.AssignedIRQ
= req
->AssignedIRQ
= irq
;
1902 c
->state
|= CONFIG_IRQ_REQ
;
1903 handle
->state
|= CLIENT_IRQ_REQ
;
1905 } /* pcmcia_request_irq */
1907 /*======================================================================
1909 Request_window() establishes a mapping between card memory space
1910 and system memory space.
1912 ======================================================================*/
1914 int pcmcia_request_window(client_handle_t
*handle
, win_req_t
*req
, window_handle_t
*wh
)
1921 if (CHECK_HANDLE(*handle
))
1922 return CS_BAD_HANDLE
;
1923 s
= SOCKET(*handle
);
1924 if (!(s
->state
& SOCKET_PRESENT
))
1926 if (req
->Attributes
& (WIN_PAGED
| WIN_SHARED
))
1927 return CS_BAD_ATTRIBUTE
;
1929 /* Window size defaults to smallest available */
1931 req
->Size
= s
->cap
.map_size
;
1932 align
= (((s
->cap
.features
& SS_CAP_MEM_ALIGN
) ||
1933 (req
->Attributes
& WIN_STRICT_ALIGN
)) ?
1934 req
->Size
: s
->cap
.map_size
);
1935 if (req
->Size
& (s
->cap
.map_size
-1))
1937 if ((req
->Base
&& (s
->cap
.features
& SS_CAP_STATIC_MAP
)) ||
1938 (req
->Base
& (align
-1)))
1943 /* Allocate system memory window */
1944 for (w
= 0; w
< MAX_WIN
; w
++)
1945 if (!(s
->state
& SOCKET_WIN_REQ(w
))) break;
1947 return CS_OUT_OF_RESOURCE
;
1950 win
->magic
= WINDOW_MAGIC
;
1952 win
->handle
= *handle
;
1954 win
->base
= req
->Base
;
1955 win
->size
= req
->Size
;
1957 if (!(s
->cap
.features
& SS_CAP_STATIC_MAP
) &&
1958 find_mem_region(&win
->base
, win
->size
, align
,
1959 (req
->Attributes
& WIN_MAP_BELOW_1MB
) ||
1960 !(s
->cap
.features
& SS_CAP_PAGE_REGS
),
1961 (*handle
)->dev_info
))
1963 (*handle
)->state
|= CLIENT_WIN_REQ(w
);
1965 /* Configure the socket controller */
1968 win
->ctl
.speed
= req
->AccessSpeed
;
1969 if (req
->Attributes
& WIN_MEMORY_TYPE
)
1970 win
->ctl
.flags
|= MAP_ATTRIB
;
1971 if (req
->Attributes
& WIN_ENABLE
)
1972 win
->ctl
.flags
|= MAP_ACTIVE
;
1973 if (req
->Attributes
& WIN_DATA_WIDTH_16
)
1974 win
->ctl
.flags
|= MAP_16BIT
;
1975 if (req
->Attributes
& WIN_USE_WAIT
)
1976 win
->ctl
.flags
|= MAP_USE_WAIT
;
1977 win
->ctl
.sys_start
= win
->base
;
1978 win
->ctl
.sys_stop
= win
->base
+ win
->size
-1;
1979 win
->ctl
.card_start
= 0;
1980 if (set_mem_map(s
, &win
->ctl
) != 0)
1982 s
->state
|= SOCKET_WIN_REQ(w
);
1984 /* Return window handle */
1985 req
->Base
= win
->ctl
.sys_start
;
1989 } /* request_window */
1991 /*======================================================================
1993 I'm not sure which "reset" function this is supposed to use,
1994 but for now, it uses the low-level interface's reset, not the
1997 ======================================================================*/
1999 int pcmcia_reset_card(client_handle_t handle
, client_req_t
*req
)
2004 if (CHECK_HANDLE(handle
))
2005 return CS_BAD_HANDLE
;
2006 i
= handle
->Socket
; s
= socket_table
[i
];
2007 if (!(s
->state
& SOCKET_PRESENT
))
2009 if (s
->state
& SOCKET_RESET_PENDING
)
2011 s
->state
|= SOCKET_RESET_PENDING
;
2013 ret
= send_event(s
, CS_EVENT_RESET_REQUEST
, CS_EVENT_PRI_LOW
);
2015 s
->state
&= ~SOCKET_RESET_PENDING
;
2016 handle
->event_callback_args
.info
= (void *)(u_long
)ret
;
2017 EVENT(handle
, CS_EVENT_RESET_COMPLETE
, CS_EVENT_PRI_LOW
);
2019 DEBUG(1, "cs: resetting socket %d\n", i
);
2020 send_event(s
, CS_EVENT_RESET_PHYSICAL
, CS_EVENT_PRI_LOW
);
2021 s
->reset_handle
= handle
;
2027 /*======================================================================
2029 These shut down or wake up a socket. They are sort of user
2030 initiated versions of the APM suspend and resume actions.
2032 ======================================================================*/
2034 int pcmcia_suspend_card(client_handle_t handle
, client_req_t
*req
)
2039 if (CHECK_HANDLE(handle
))
2040 return CS_BAD_HANDLE
;
2041 i
= handle
->Socket
; s
= socket_table
[i
];
2042 if (!(s
->state
& SOCKET_PRESENT
))
2044 if (s
->state
& SOCKET_SUSPEND
)
2047 DEBUG(1, "cs: suspending socket %d\n", i
);
2048 send_event(s
, CS_EVENT_PM_SUSPEND
, CS_EVENT_PRI_LOW
);
2050 s
->state
|= SOCKET_SUSPEND
;
2053 } /* suspend_card */
2055 int pcmcia_resume_card(client_handle_t handle
, client_req_t
*req
)
2060 if (CHECK_HANDLE(handle
))
2061 return CS_BAD_HANDLE
;
2062 i
= handle
->Socket
; s
= socket_table
[i
];
2063 if (!(s
->state
& SOCKET_PRESENT
))
2065 if (!(s
->state
& SOCKET_SUSPEND
))
2068 DEBUG(1, "cs: waking up socket %d\n", i
);
2074 /*======================================================================
2076 These handle user requests to eject or insert a card.
2078 ======================================================================*/
2080 int pcmcia_eject_card(client_handle_t handle
, client_req_t
*req
)
2086 if (CHECK_HANDLE(handle
))
2087 return CS_BAD_HANDLE
;
2088 i
= handle
->Socket
; s
= socket_table
[i
];
2089 if (!(s
->state
& SOCKET_PRESENT
))
2092 DEBUG(1, "cs: user eject request on socket %d\n", i
);
2094 ret
= send_event(s
, CS_EVENT_EJECTION_REQUEST
, CS_EVENT_PRI_LOW
);
2098 spin_lock_irqsave(&s
->lock
, flags
);
2100 spin_unlock_irqrestore(&s
->lock
, flags
);
2106 int pcmcia_insert_card(client_handle_t handle
, client_req_t
*req
)
2112 if (CHECK_HANDLE(handle
))
2113 return CS_BAD_HANDLE
;
2114 i
= handle
->Socket
; s
= socket_table
[i
];
2115 if (s
->state
& SOCKET_PRESENT
)
2118 DEBUG(1, "cs: user insert request on socket %d\n", i
);
2120 spin_lock_irqsave(&s
->lock
, flags
);
2121 if (!(s
->state
& SOCKET_SETUP_PENDING
)) {
2122 s
->state
|= SOCKET_SETUP_PENDING
;
2123 spin_unlock_irqrestore(&s
->lock
, flags
);
2124 get_socket_status(s
, &status
);
2125 if ((status
& SS_DETECT
) == 0 || (setup_socket(s
) == 0)) {
2126 s
->state
&= ~SOCKET_SETUP_PENDING
;
2130 spin_unlock_irqrestore(&s
->lock
, flags
);
2135 /*======================================================================
2137 Maybe this should send a CS_EVENT_CARD_INSERTION event if we
2138 haven't sent one to this client yet?
2140 ======================================================================*/
2142 int pcmcia_set_event_mask(client_handle_t handle
, eventmask_t
*mask
)
2145 if (CHECK_HANDLE(handle
))
2146 return CS_BAD_HANDLE
;
2147 if (handle
->Attributes
& CONF_EVENT_MASK_VALID
)
2148 return CS_BAD_SOCKET
;
2149 handle
->EventMask
= mask
->EventMask
;
2150 events
= handle
->PendingEvents
& handle
->EventMask
;
2151 handle
->PendingEvents
-= events
;
2152 while (events
!= 0) {
2153 bit
= ((events
^ (events
-1)) + 1) >> 1;
2154 EVENT(handle
, bit
, CS_EVENT_PRI_LOW
);
2158 } /* set_event_mask */
2160 /*====================================================================*/
2162 int pcmcia_report_error(client_handle_t handle
, error_info_t
*err
)
2167 if (CHECK_HANDLE(handle
))
2168 printk(KERN_NOTICE
);
2170 printk(KERN_NOTICE
"%s: ", handle
->dev_info
);
2172 for (i
= 0; i
< SERVICE_COUNT
; i
++)
2173 if (service_table
[i
].key
== err
->func
) break;
2174 if (i
< SERVICE_COUNT
)
2175 serv
= service_table
[i
].msg
;
2177 serv
= "Unknown service number";
2179 for (i
= 0; i
< ERROR_COUNT
; i
++)
2180 if (error_table
[i
].key
== err
->retcode
) break;
2181 if (i
< ERROR_COUNT
)
2182 printk("%s: %s\n", serv
, error_table
[i
].msg
);
2184 printk("%s: Unknown error code %#x\n", serv
, err
->retcode
);
2187 } /* report_error */
2189 /*====================================================================*/
2191 int CardServices(int func
, void *a1
, void *a2
, void *a3
)
2197 for (i
= 0; i
< SERVICE_COUNT
; i
++)
2198 if (service_table
[i
].key
== func
) break;
2199 if (i
< SERVICE_COUNT
)
2200 printk(KERN_DEBUG
"cs: CardServices(%s, 0x%p, 0x%p)\n",
2201 service_table
[i
].msg
, a1
, a2
);
2203 printk(KERN_DEBUG
"cs: CardServices(Unknown func %d, "
2204 "0x%p, 0x%p)\n", func
, a1
, a2
);
2208 case AccessConfigurationRegister
:
2209 return pcmcia_access_configuration_register(a1
, a2
); break;
2210 case AdjustResourceInfo
:
2211 return pcmcia_adjust_resource_info(a1
, a2
); break;
2212 case CheckEraseQueue
:
2213 return pcmcia_check_erase_queue(a1
); break;
2215 return pcmcia_close_memory(a1
); break;
2217 return pcmcia_copy_memory(a1
, a2
); break;
2218 case DeregisterClient
:
2219 return pcmcia_deregister_client(a1
); break;
2220 case DeregisterEraseQueue
:
2221 return pcmcia_deregister_erase_queue(a1
); break;
2222 case GetFirstClient
:
2223 return pcmcia_get_first_client(a1
, a2
); break;
2224 case GetCardServicesInfo
:
2225 return pcmcia_get_card_services_info(a1
); break;
2226 case GetConfigurationInfo
:
2227 return pcmcia_get_configuration_info(a1
, a2
); break;
2229 return pcmcia_get_next_client(a1
, a2
); break;
2230 case GetFirstRegion
:
2231 return pcmcia_get_first_region(a1
, a2
); break;
2233 return pcmcia_get_first_tuple(a1
, a2
); break;
2235 return pcmcia_get_next_region(a1
, a2
); break;
2237 return pcmcia_get_next_tuple(a1
, a2
); break;
2239 return pcmcia_get_status(a1
, a2
); break;
2241 return pcmcia_get_tuple_data(a1
, a2
); break;
2243 return pcmcia_map_mem_page(a1
, a2
); break;
2244 case ModifyConfiguration
:
2245 return pcmcia_modify_configuration(a1
, a2
); break;
2247 return pcmcia_modify_window(a1
, a2
); break;
2249 /* return pcmcia_open_memory(a1, a2); */
2252 int ret
= pcmcia_open_memory(a1
, a2
, &m
);
2253 *(memory_handle_t
*)a1
= m
;
2258 return pcmcia_parse_tuple(a1
, a2
, a3
); break;
2260 return pcmcia_read_memory(a1
, a2
, a3
); break;
2261 case RegisterClient
:
2262 return pcmcia_register_client(a1
, a2
); break;
2263 case RegisterEraseQueue
:
2266 int ret
= pcmcia_register_erase_queue(a1
, a2
, &w
);
2267 *(eraseq_handle_t
*)a1
= w
;
2271 /* return pcmcia_register_erase_queue(a1, a2); break; */
2273 return pcmcia_register_mtd(a1
, a2
); break;
2274 case ReleaseConfiguration
:
2275 return pcmcia_release_configuration(a1
); break;
2277 return pcmcia_release_io(a1
, a2
); break;
2279 return pcmcia_release_irq(a1
, a2
); break;
2281 return pcmcia_release_window(a1
); break;
2282 case RequestConfiguration
:
2283 return pcmcia_request_configuration(a1
, a2
); break;
2285 return pcmcia_request_io(a1
, a2
); break;
2287 return pcmcia_request_irq(a1
, a2
); break;
2291 int ret
= pcmcia_request_window(a1
, a2
, &w
);
2292 *(window_handle_t
*)a1
= w
;
2297 return pcmcia_reset_card(a1
, a2
); break;
2299 return pcmcia_set_event_mask(a1
, a2
); break;
2301 return pcmcia_validate_cis(a1
, a2
); break;
2303 return pcmcia_write_memory(a1
, a2
, a3
); break;
2305 return pcmcia_bind_device(a1
); break;
2307 return pcmcia_bind_mtd(a1
); break;
2309 return pcmcia_report_error(a1
, a2
); break;
2311 return pcmcia_suspend_card(a1
, a2
); break;
2313 return pcmcia_resume_card(a1
, a2
); break;
2315 return pcmcia_eject_card(a1
, a2
); break;
2317 return pcmcia_insert_card(a1
, a2
); break;
2319 return pcmcia_replace_cis(a1
, a2
); break;
2320 case GetFirstWindow
:
2321 return pcmcia_get_first_window(a1
, a2
); break;
2323 return pcmcia_get_next_window(a1
, a2
); break;
2325 return pcmcia_get_mem_page(a1
, a2
); break;
2327 return CS_UNSUPPORTED_FUNCTION
; break;
2330 } /* CardServices */
2332 /*======================================================================
2334 OS-specific module glue goes here
2336 ======================================================================*/
2337 /* in alpha order */
2338 EXPORT_SYMBOL(pcmcia_access_configuration_register
);
2339 EXPORT_SYMBOL(pcmcia_adjust_resource_info
);
2340 EXPORT_SYMBOL(pcmcia_bind_device
);
2341 EXPORT_SYMBOL(pcmcia_bind_mtd
);
2342 EXPORT_SYMBOL(pcmcia_check_erase_queue
);
2343 EXPORT_SYMBOL(pcmcia_close_memory
);
2344 EXPORT_SYMBOL(pcmcia_copy_memory
);
2345 EXPORT_SYMBOL(pcmcia_deregister_client
);
2346 EXPORT_SYMBOL(pcmcia_deregister_erase_queue
);
2347 EXPORT_SYMBOL(pcmcia_eject_card
);
2348 EXPORT_SYMBOL(pcmcia_get_first_client
);
2349 EXPORT_SYMBOL(pcmcia_get_card_services_info
);
2350 EXPORT_SYMBOL(pcmcia_get_configuration_info
);
2351 EXPORT_SYMBOL(pcmcia_get_mem_page
);
2352 EXPORT_SYMBOL(pcmcia_get_next_client
);
2353 EXPORT_SYMBOL(pcmcia_get_first_region
);
2354 EXPORT_SYMBOL(pcmcia_get_first_tuple
);
2355 EXPORT_SYMBOL(pcmcia_get_first_window
);
2356 EXPORT_SYMBOL(pcmcia_get_next_region
);
2357 EXPORT_SYMBOL(pcmcia_get_next_tuple
);
2358 EXPORT_SYMBOL(pcmcia_get_next_window
);
2359 EXPORT_SYMBOL(pcmcia_get_status
);
2360 EXPORT_SYMBOL(pcmcia_get_tuple_data
);
2361 EXPORT_SYMBOL(pcmcia_insert_card
);
2362 EXPORT_SYMBOL(pcmcia_map_mem_page
);
2363 EXPORT_SYMBOL(pcmcia_modify_configuration
);
2364 EXPORT_SYMBOL(pcmcia_modify_window
);
2365 EXPORT_SYMBOL(pcmcia_open_memory
);
2366 EXPORT_SYMBOL(pcmcia_parse_tuple
);
2367 EXPORT_SYMBOL(pcmcia_read_memory
);
2368 EXPORT_SYMBOL(pcmcia_register_client
);
2369 EXPORT_SYMBOL(pcmcia_register_erase_queue
);
2370 EXPORT_SYMBOL(pcmcia_register_mtd
);
2371 EXPORT_SYMBOL(pcmcia_release_configuration
);
2372 EXPORT_SYMBOL(pcmcia_release_io
);
2373 EXPORT_SYMBOL(pcmcia_release_irq
);
2374 EXPORT_SYMBOL(pcmcia_release_window
);
2375 EXPORT_SYMBOL(pcmcia_replace_cis
);
2376 EXPORT_SYMBOL(pcmcia_report_error
);
2377 EXPORT_SYMBOL(pcmcia_request_configuration
);
2378 EXPORT_SYMBOL(pcmcia_request_io
);
2379 EXPORT_SYMBOL(pcmcia_request_irq
);
2380 EXPORT_SYMBOL(pcmcia_request_window
);
2381 EXPORT_SYMBOL(pcmcia_reset_card
);
2382 EXPORT_SYMBOL(pcmcia_resume_card
);
2383 EXPORT_SYMBOL(pcmcia_set_event_mask
);
2384 EXPORT_SYMBOL(pcmcia_suspend_card
);
2385 EXPORT_SYMBOL(pcmcia_validate_cis
);
2386 EXPORT_SYMBOL(pcmcia_write_memory
);
2388 EXPORT_SYMBOL(dead_socket
);
2389 EXPORT_SYMBOL(register_ss_entry
);
2390 EXPORT_SYMBOL(unregister_ss_entry
);
2391 EXPORT_SYMBOL(CardServices
);
2392 EXPORT_SYMBOL(MTDHelperEntry
);
2393 #ifdef CONFIG_PROC_FS
2394 EXPORT_SYMBOL(proc_pccard
);
2397 EXPORT_SYMBOL(pcmcia_register_socket
);
2398 EXPORT_SYMBOL(pcmcia_unregister_socket
);
2399 EXPORT_SYMBOL(pcmcia_suspend_socket
);
2400 EXPORT_SYMBOL(pcmcia_resume_socket
);
2402 static int __init
init_pcmcia_cs(void)
2404 printk(KERN_INFO
"%s\n", release
);
2405 printk(KERN_INFO
" %s\n", options
);
2406 DEBUG(0, "%s\n", version
);
2408 pm_register(PM_SYS_DEV
, PM_SYS_PCMCIA
, handle_pm_event
);
2409 #ifdef CONFIG_PROC_FS
2410 proc_pccard
= proc_mkdir("pccard", proc_bus
);
2415 static void __exit
exit_pcmcia_cs(void)
2417 printk(KERN_INFO
"unloading PCMCIA Card Services\n");
2418 #ifdef CONFIG_PROC_FS
2420 remove_proc_entry("pccard", proc_bus
);
2424 pm_unregister_all(handle_pm_event
);
2425 release_resource_db();
2428 module_init(init_pcmcia_cs
);
2429 module_exit(exit_pcmcia_cs
);
2431 /*====================================================================*/