OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [pcmcia/] [cs.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.