linux-old/drivers/pcmcia/cs.c
<<
>>
Prefs
   1/*======================================================================
   2
   3    Kernel Card Services -- core services
   4
   5    cs.c 1.271 2000/10/02 20:27:49
   6    
   7    The contents of this file are subject to the Mozilla Public
   8    License Version 1.1 (the "License"); you may not use this file
   9    except in compliance with the License. You may obtain a copy of
  10    the License at http://www.mozilla.org/MPL/
  11
  12    Software distributed under the License is distributed on an "AS
  13    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  14    implied. See the License for the specific language governing
  15    rights and limitations under the License.
  16
  17    The initial developer of the original code is David A. Hinds
  18    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  19    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  20
  21    Alternatively, the contents of this file may be used under the
  22    terms of the GNU General Public License version 2 (the "GPL"), in which
  23    case the provisions of the GPL are applicable instead of the
  24    above.  If you wish to allow the use of your version of this file
  25    only under the terms of the GPL and not to allow others to use
  26    your version of this file under the MPL, indicate your decision
  27    by deleting the provisions above and replace them with the notice
  28    and other provisions required by the GPL.  If you do not delete
  29    the provisions above, a recipient may use your version of this
  30    file under either the MPL or the GPL.
  31    
  32======================================================================*/
  33
  34#include <linux/module.h>
  35#include <linux/init.h>
  36#include <linux/kernel.h>
  37#include <linux/config.h>
  38#include <linux/string.h>
  39#include <linux/major.h>
  40#include <linux/errno.h>
  41#include <linux/slab.h>
  42#include <linux/mm.h>
  43#include <linux/sched.h>
  44#include <linux/timer.h>
  45#include <linux/ioport.h>
  46#include <linux/delay.h>
  47#include <linux/proc_fs.h>
  48#include <linux/pm.h>
  49#include <linux/pci.h>
  50#include <asm/system.h>
  51#include <asm/irq.h>
  52
  53#define IN_CARD_SERVICES
  54#include <pcmcia/version.h>
  55#include <pcmcia/cs_types.h>
  56#include <pcmcia/ss.h>
  57#include <pcmcia/cs.h>
  58#include <pcmcia/bulkmem.h>
  59#include <pcmcia/cistpl.h>
  60#include <pcmcia/cisreg.h>
  61#include <pcmcia/bus_ops.h>
  62#include "cs_internal.h"
  63
  64#ifdef CONFIG_PCI
  65#define PCI_OPT " [pci]"
  66#else
  67#define PCI_OPT ""
  68#endif
  69#ifdef CONFIG_CARDBUS
  70#define CB_OPT " [cardbus]"
  71#else
  72#define CB_OPT ""
  73#endif
  74#ifdef CONFIG_PM
  75#define PM_OPT " [pm]"
  76#else
  77#define PM_OPT ""
  78#endif
  79#if !defined(CONFIG_CARDBUS) && !defined(CONFIG_PCI) && !defined(CONFIG_PM)
  80#define OPTIONS " none"
  81#else
  82#define OPTIONS PCI_OPT CB_OPT PM_OPT
  83#endif
  84
  85static const char *release = "Linux Kernel Card Services " CS_RELEASE;
  86static const char *options = "options: " OPTIONS;
  87
  88/*====================================================================*/
  89
  90/* Module parameters */
  91
  92MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
  93MODULE_DESCRIPTION("Linux Kernel Card Services " CS_RELEASE
  94                   "\n  options:" OPTIONS);
  95MODULE_LICENSE("Dual MPL/GPL");   
  96
  97#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
  98
  99INT_MODULE_PARM(setup_delay,    10);            /* centiseconds */
 100INT_MODULE_PARM(resume_delay,   20);            /* centiseconds */
 101INT_MODULE_PARM(shutdown_delay, 3);             /* centiseconds */
 102INT_MODULE_PARM(vcc_settle,     40);            /* centiseconds */
 103INT_MODULE_PARM(reset_time,     10);            /* usecs */
 104INT_MODULE_PARM(unreset_delay,  10);            /* centiseconds */
 105INT_MODULE_PARM(unreset_check,  10);            /* centiseconds */
 106INT_MODULE_PARM(unreset_limit,  30);            /* unreset_check's */
 107
 108/* Access speed for attribute memory windows */
 109INT_MODULE_PARM(cis_speed,      300);           /* ns */
 110
 111/* Access speed for IO windows */
 112INT_MODULE_PARM(io_speed,       0);             /* ns */
 113
 114/* Optional features */
 115#ifdef CONFIG_PM
 116INT_MODULE_PARM(do_apm,         1);
 117#else
 118INT_MODULE_PARM(do_apm,         0);
 119#endif
 120
 121#ifdef PCMCIA_DEBUG
 122INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
 123static const char *version =
 124"cs.c 1.279 2001/10/13 00:08:28 (David Hinds)";
 125#endif
 126 
 127/*====================================================================*/
 128
 129socket_state_t dead_socket = {
 130    0, SS_DETECT, 0, 0, 0
 131};
 132
 133/* Table of sockets */
 134socket_t sockets = 0;
 135socket_info_t *socket_table[MAX_SOCK];
 136
 137#ifdef CONFIG_PROC_FS
 138struct proc_dir_entry *proc_pccard = NULL;
 139#endif
 140
 141/*====================================================================*/
 142
 143/* String tables for error messages */
 144
 145typedef struct lookup_t {
 146    int key;
 147    char *msg;
 148} lookup_t;
 149
 150static const lookup_t error_table[] = {
 151    { CS_SUCCESS,               "Operation succeeded" },
 152    { CS_BAD_ADAPTER,           "Bad adapter" },
 153    { CS_BAD_ATTRIBUTE,         "Bad attribute", },
 154    { CS_BAD_BASE,              "Bad base address" },
 155    { CS_BAD_EDC,               "Bad EDC" },
 156    { CS_BAD_IRQ,               "Bad IRQ" },
 157    { CS_BAD_OFFSET,            "Bad offset" },
 158    { CS_BAD_PAGE,              "Bad page number" },
 159    { CS_READ_FAILURE,          "Read failure" },
 160    { CS_BAD_SIZE,              "Bad size" },
 161    { CS_BAD_SOCKET,            "Bad socket" },
 162    { CS_BAD_TYPE,              "Bad type" },
 163    { CS_BAD_VCC,               "Bad Vcc" },
 164    { CS_BAD_VPP,               "Bad Vpp" },
 165    { CS_BAD_WINDOW,            "Bad window" },
 166    { CS_WRITE_FAILURE,         "Write failure" },
 167    { CS_NO_CARD,               "No card present" },
 168    { CS_UNSUPPORTED_FUNCTION,  "Usupported function" },
 169    { CS_UNSUPPORTED_MODE,      "Unsupported mode" },
 170    { CS_BAD_SPEED,             "Bad speed" },
 171    { CS_BUSY,                  "Resource busy" },
 172    { CS_GENERAL_FAILURE,       "General failure" },
 173    { CS_WRITE_PROTECTED,       "Write protected" },
 174    { CS_BAD_ARG_LENGTH,        "Bad argument length" },
 175    { CS_BAD_ARGS,              "Bad arguments" },
 176    { CS_CONFIGURATION_LOCKED,  "Configuration locked" },
 177    { CS_IN_USE,                "Resource in use" },
 178    { CS_NO_MORE_ITEMS,         "No more items" },
 179    { CS_OUT_OF_RESOURCE,       "Out of resource" },
 180    { CS_BAD_HANDLE,            "Bad handle" },
 181    { CS_BAD_TUPLE,             "Bad CIS tuple" }
 182};
 183#define ERROR_COUNT (sizeof(error_table)/sizeof(lookup_t))
 184
 185static const lookup_t service_table[] = {
 186    { AccessConfigurationRegister,      "AccessConfigurationRegister" },
 187    { AddSocketServices,                "AddSocketServices" },
 188    { AdjustResourceInfo,               "AdjustResourceInfo" },
 189    { CheckEraseQueue,                  "CheckEraseQueue" },
 190    { CloseMemory,                      "CloseMemory" },
 191    { DeregisterClient,                 "DeregisterClient" },
 192    { DeregisterEraseQueue,             "DeregisterEraseQueue" },
 193    { GetCardServicesInfo,              "GetCardServicesInfo" },
 194    { GetClientInfo,                    "GetClientInfo" },
 195    { GetConfigurationInfo,             "GetConfigurationInfo" },
 196    { GetEventMask,                     "GetEventMask" },
 197    { GetFirstClient,                   "GetFirstClient" },
 198    { GetFirstRegion,                   "GetFirstRegion" },
 199    { GetFirstTuple,                    "GetFirstTuple" },
 200    { GetNextClient,                    "GetNextClient" },
 201    { GetNextRegion,                    "GetNextRegion" },
 202    { GetNextTuple,                     "GetNextTuple" },
 203    { GetStatus,                        "GetStatus" },
 204    { GetTupleData,                     "GetTupleData" },
 205    { MapMemPage,                       "MapMemPage" },
 206    { ModifyConfiguration,              "ModifyConfiguration" },
 207    { ModifyWindow,                     "ModifyWindow" },
 208    { OpenMemory,                       "OpenMemory" },
 209    { ParseTuple,                       "ParseTuple" },
 210    { ReadMemory,                       "ReadMemory" },
 211    { RegisterClient,                   "RegisterClient" },
 212    { RegisterEraseQueue,               "RegisterEraseQueue" },
 213    { RegisterMTD,                      "RegisterMTD" },
 214    { ReleaseConfiguration,             "ReleaseConfiguration" },
 215    { ReleaseIO,                        "ReleaseIO" },
 216    { ReleaseIRQ,                       "ReleaseIRQ" },
 217    { ReleaseWindow,                    "ReleaseWindow" },
 218    { RequestConfiguration,             "RequestConfiguration" },
 219    { RequestIO,                        "RequestIO" },
 220    { RequestIRQ,                       "RequestIRQ" },
 221    { RequestSocketMask,                "RequestSocketMask" },
 222    { RequestWindow,                    "RequestWindow" },
 223    { ResetCard,                        "ResetCard" },
 224    { SetEventMask,                     "SetEventMask" },
 225    { ValidateCIS,                      "ValidateCIS" },
 226    { WriteMemory,                      "WriteMemory" },
 227    { BindDevice,                       "BindDevice" },
 228    { BindMTD,                          "BindMTD" },
 229    { ReportError,                      "ReportError" },
 230    { SuspendCard,                      "SuspendCard" },
 231    { ResumeCard,                       "ResumeCard" },
 232    { EjectCard,                        "EjectCard" },
 233    { InsertCard,                       "InsertCard" },
 234    { ReplaceCIS,                       "ReplaceCIS" }
 235};
 236#define SERVICE_COUNT (sizeof(service_table)/sizeof(lookup_t))
 237
 238/*======================================================================
 239
 240 These functions are just shorthand for the actual low-level drivers
 241
 242======================================================================*/
 243
 244static int register_callback(socket_info_t *s, void (*handler)(void *, unsigned int), void * info)
 245{
 246        return s->ss_entry->register_callback(s->sock, handler, info);
 247}
 248
 249static int get_socket_status(socket_info_t *s, int *val)
 250{
 251        return s->ss_entry->get_status(s->sock, val);
 252}
 253
 254static int set_socket(socket_info_t *s, socket_state_t *state)
 255{
 256        return s->ss_entry->set_socket(s->sock, state);
 257}
 258
 259static int set_io_map(socket_info_t *s, struct pccard_io_map *io)
 260{
 261        return s->ss_entry->set_io_map(s->sock, io);
 262}
 263
 264static int set_mem_map(socket_info_t *s, struct pccard_mem_map *mem)
 265{
 266        return s->ss_entry->set_mem_map(s->sock, mem);
 267}
 268
 269static int suspend_socket(socket_info_t *s)
 270{
 271        s->socket = dead_socket;
 272        return s->ss_entry->suspend(s->sock);
 273}
 274
 275static int init_socket(socket_info_t *s)
 276{
 277        s->socket = dead_socket;
 278        return s->ss_entry->init(s->sock);
 279}
 280
 281/*====================================================================*/
 282
 283#if defined(CONFIG_PROC_FS) && defined(PCMCIA_DEBUG)
 284static int proc_read_clients(char *buf, char **start, off_t pos,
 285                             int count, int *eof, void *data)
 286{
 287    socket_info_t *s = data;
 288    client_handle_t c;
 289    char *p = buf;
 290
 291    for (c = s->clients; c; c = c->next)
 292        p += sprintf(p, "fn %x: '%s' [attr 0x%04x] [state 0x%04x]\n",
 293                     c->Function, c->dev_info, c->Attributes, c->state);
 294    return (p - buf);
 295}
 296#endif
 297
 298/*======================================================================
 299
 300    Low-level PC Card interface drivers need to register with Card
 301    Services using these calls.
 302    
 303======================================================================*/
 304
 305static int setup_socket(socket_info_t *);
 306static void shutdown_socket(socket_info_t *);
 307static void reset_socket(socket_info_t *);
 308static void unreset_socket(socket_info_t *);
 309static void parse_events(void *info, u_int events);
 310
 311socket_info_t *pcmcia_register_socket (int slot,
 312        struct pccard_operations * ss_entry,
 313        int use_bus_pm)
 314{
 315    socket_info_t *s;
 316    int i;
 317
 318    DEBUG(0, "cs: pcmcia_register_socket(0x%p)\n", ss_entry);
 319
 320    s = kmalloc(sizeof(struct socket_info_t), GFP_KERNEL);
 321    if (!s)
 322        return NULL;
 323    memset(s, 0, sizeof(socket_info_t));
 324
 325    s->ss_entry = ss_entry;
 326    s->sock = slot;
 327
 328    /* 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
 359int register_ss_entry(int nsock, struct pccard_operations * ss_entry)
 360{
 361    int ns;
 362
 363    DEBUG(0, "cs: register_ss_entry(%d, 0x%p)\n", nsock, ss_entry);
 364
 365    for (ns = 0; ns < nsock; ns++) {
 366        pcmcia_register_socket (ns, ss_entry, 0);
 367    }
 368    
 369    return 0;
 370} /* register_ss_entry */
 371
 372/*====================================================================*/
 373
 374void pcmcia_unregister_socket(socket_info_t *s)
 375{
 376    int j, socket = -1;
 377    client_t *client;
 378
 379    for (j = 0; j < MAX_SOCK; j++)
 380        if (socket_table [j] == s) {
 381            socket = j;
 382            break;
 383        }
 384    if (socket < 0)
 385        return;
 386
 387#ifdef CONFIG_PROC_FS
 388    if (proc_pccard) {
 389        char name[3];
 390        sprintf(name, "%02d", socket);
 391#ifdef PCMCIA_DEBUG
 392        remove_proc_entry("clients", s->proc);
 393#endif
 394        remove_proc_entry(name, proc_pccard);
 395    }
 396#endif
 397
 398    shutdown_socket(s);
 399    release_cis_mem(s);
 400    while (s->clients) {
 401        client = s->clients;
 402        s->clients = s->clients->next;
 403        kfree(client);
 404    }
 405    s->ss_entry = NULL;
 406    kfree(s);
 407
 408    socket_table[socket] = NULL;
 409    for (j = socket; j < sockets-1; j++)
 410        socket_table[j] = socket_table[j+1];
 411    sockets--;
 412} /* pcmcia_unregister_socket */
 413
 414void unregister_ss_entry(struct pccard_operations * ss_entry)
 415{
 416    int i;
 417
 418    for (i = sockets-1; i >= 0; i-- ) {
 419        socket_info_t *socket = socket_table[i];
 420        if (socket->ss_entry == ss_entry)
 421                pcmcia_unregister_socket (socket);
 422    }
 423} /* 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
 435static void free_regions(memory_handle_t *list)
 436{
 437    memory_handle_t tmp;
 438    while (*list != NULL) {
 439        tmp = *list;
 440        *list = tmp->info.next;
 441        tmp->region_magic = 0;
 442        kfree(tmp);
 443    }
 444}
 445
 446static int send_event(socket_info_t *s, event_t event, int priority);
 447
 448/*
 449 * Sleep for n_cs centiseconds (1 cs = 1/100th of a second)
 450 */
 451static void cs_sleep(unsigned int n_cs)
 452{
 453        current->state = TASK_INTERRUPTIBLE;
 454        schedule_timeout( (n_cs * HZ + 99) / 100);
 455}
 456
 457static void shutdown_socket(socket_info_t *s)
 458{
 459    client_t **c;
 460    
 461    DEBUG(1, "cs: shutdown_socket(%p)\n", s);
 462
 463    /* 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 */
 507static 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        }
 554out:
 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
 567static void reset_socket(socket_info_t *s)
 568{
 569    DEBUG(1, "cs: resetting socket %p\n", s);
 570    s->socket.flags |= SS_OUTPUT_ENA | SS_RESET;
 571    set_socket(s, &s->socket);
 572    udelay((long)reset_time);
 573    s->socket.flags &= ~SS_RESET;
 574    set_socket(s, &s->socket);
 575    cs_sleep(unreset_delay);
 576    unreset_socket(s);
 577} /* reset_socket */
 578
 579#define EVENT_MASK \
 580(SOCKET_SETUP_PENDING|SOCKET_SUSPEND|SOCKET_RESET_PENDING)
 581
 582static void unreset_socket(socket_info_t *s)
 583{
 584        int setup_timeout = unreset_limit;
 585        int val;
 586
 587        /* 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
 637static int send_event(socket_info_t *s, event_t event, int priority)
 638{
 639    client_t *client = s->clients;
 640    int ret;
 641    DEBUG(1, "cs: send_event(sock %d, event %d, pri %d)\n",
 642          s->sock, event, priority);
 643    ret = 0;
 644    for (; client; client = client->next) { 
 645        if (client->state & (CLIENT_UNBOUND|CLIENT_STALE))
 646            continue;
 647        if (client->EventMask & event) {
 648            ret = EVENT(client, event, priority);
 649            if (ret != 0)
 650                return ret;
 651        }
 652    }
 653    return ret;
 654} /* send_event */
 655
 656static void do_shutdown(socket_info_t *s)
 657{
 658    client_t *client;
 659    if (s->state & SOCKET_SHUTDOWN_PENDING)
 660        return;
 661    s->state |= SOCKET_SHUTDOWN_PENDING;
 662    send_event(s, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
 663    for (client = s->clients; client; client = client->next)
 664        if (!(client->Attributes & INFO_MASTER_CLIENT))
 665            client->state |= CLIENT_STALE;
 666    if (s->state & (SOCKET_SETUP_PENDING|SOCKET_RESET_PENDING)) {
 667        DEBUG(0, "cs: flushing pending setup\n");
 668        s->state &= ~EVENT_MASK;
 669    }
 670    cs_sleep(shutdown_delay);
 671    s->state &= ~SOCKET_PRESENT;
 672    shutdown_socket(s);
 673}
 674
 675static void parse_events(void *info, u_int events)
 676{
 677    socket_info_t *s = info;
 678    if (events & SS_DETECT) {
 679        int status;
 680
 681        get_socket_status(s, &status);
 682        if ((s->state & SOCKET_PRESENT) &&
 683            (!(s->state & SOCKET_SUSPEND) ||
 684             !(status & SS_DETECT)))
 685            do_shutdown(s);
 686        if (status & SS_DETECT) {
 687            if (s->state & SOCKET_SETUP_PENDING) {
 688                DEBUG(1, "cs: delaying pending setup\n");
 689                return;
 690            }
 691            s->state |= SOCKET_SETUP_PENDING;
 692            if (s->state & SOCKET_SUSPEND)
 693                cs_sleep(resume_delay);
 694            else
 695                cs_sleep(setup_delay);
 696            s->socket.flags |= SS_DEBOUNCED;
 697            if (setup_socket(s) == 0)
 698                s->state &= ~SOCKET_SETUP_PENDING;
 699            s->socket.flags &= ~SS_DEBOUNCED;
 700        }
 701    }
 702    if (events & SS_BATDEAD)
 703        send_event(s, CS_EVENT_BATTERY_DEAD, CS_EVENT_PRI_LOW);
 704    if (events & SS_BATWARN)
 705        send_event(s, CS_EVENT_BATTERY_LOW, CS_EVENT_PRI_LOW);
 706    if (events & SS_READY) {
 707        if (!(s->state & SOCKET_RESET_PENDING))
 708            send_event(s, CS_EVENT_READY_CHANGE, CS_EVENT_PRI_LOW);
 709        else DEBUG(1, "cs: ready change during reset\n");
 710    }
 711} /* 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
 722void pcmcia_suspend_socket (socket_info_t *s)
 723{
 724    if ((s->state & SOCKET_PRESENT) && !(s->state & SOCKET_SUSPEND)) {
 725        send_event(s, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW);
 726        suspend_socket(s);
 727        s->state |= SOCKET_SUSPEND;
 728    }
 729}
 730
 731void pcmcia_resume_socket (socket_info_t *s)
 732{
 733    int stat;
 734
 735    /* 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
 745static int handle_pm_event(struct pm_dev *dev, pm_request_t rqst, void *data)
 746{
 747    int i;
 748    socket_info_t *s;
 749
 750    /* 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
 779static int alloc_io_space(socket_info_t *s, u_int attr, ioaddr_t *base,
 780                          ioaddr_t num, u_int lines, char *name)
 781{
 782    int i;
 783    ioaddr_t try, align;
 784
 785    align = (*base) ? (lines ? 1<<lines : 0) : 1;
 786    if (align && (align < num)) {
 787        if (*base) {
 788            DEBUG(0, "odd IO request: num %04x align %04x\n",
 789                  num, align);
 790            align = 0;
 791        } else
 792            while (align && (align < num)) align <<= 1;
 793    }
 794    if (*base & ~(align-1)) {
 795        DEBUG(0, "odd IO request: base %04x align %04x\n",
 796              *base, align);
 797        align = 0;
 798    }
 799    if ((s->cap.features & SS_CAP_STATIC_MAP) && s->cap.io_offset) {
 800        *base = s->cap.io_offset | (*base & 0x0fff);
 801        return 0;
 802    }
 803    /* 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
 843static void release_io_space(socket_info_t *s, ioaddr_t base,
 844                             ioaddr_t num)
 845{
 846    int i;
 847    if(!(s->cap.features & SS_CAP_STATIC_MAP))
 848        release_region(base, num);
 849    for (i = 0; i < MAX_IO_WIN; i++) {
 850        if ((s->io[i].BasePort <= base) &&
 851            (s->io[i].BasePort+s->io[i].NumPorts >= base+num)) {
 852            s->io[i].InUse -= num;
 853            /* 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
 868int pcmcia_access_configuration_register(client_handle_t handle,
 869                                         conf_reg_t *reg)
 870{
 871    socket_info_t *s;
 872    config_t *c;
 873    int addr;
 874    u_char val;
 875    
 876    if (CHECK_HANDLE(handle))
 877        return CS_BAD_HANDLE;
 878    s = SOCKET(handle);
 879    if (handle->Function == BIND_FN_ALL) {
 880        if (reg->Function >= s->functions)
 881            return CS_BAD_ARGS;
 882        c = &s->config[reg->Function];
 883    } else
 884        c = CONFIG(handle);
 885
 886    if (c == NULL)
 887        return CS_NO_CARD;
 888
 889    if (!(c->state & CONFIG_LOCKED))
 890        return CS_CONFIGURATION_LOCKED;
 891
 892    addr = (c->ConfigBase + reg->Offset) >> 1;
 893    
 894    switch (reg->Action) {
 895    case CS_READ:
 896        read_cis_mem(s, 1, addr, 1, &val);
 897        reg->Value = val;
 898        break;
 899    case CS_WRITE:
 900        val = reg->Value;
 901        write_cis_mem(s, 1, addr, 1, &val);
 902        break;
 903    default:
 904        return CS_BAD_ARGS;
 905        break;
 906    }
 907    return CS_SUCCESS;
 908} /* 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
 919int pcmcia_bind_device(bind_req_t *req)
 920{
 921    client_t *client;
 922    socket_info_t *s;
 923
 924    if (CHECK_SOCKET(req->Socket))
 925        return CS_BAD_SOCKET;
 926    s = SOCKET(req);
 927
 928    client = (client_t *)kmalloc(sizeof(client_t), GFP_KERNEL);
 929    if (!client) return CS_OUT_OF_RESOURCE;
 930    memset(client, '\0', sizeof(client_t));
 931    client->client_magic = CLIENT_MAGIC;
 932    strncpy(client->dev_info, (char *)req->dev_info, DEV_NAME_LEN);
 933    client->Socket = req->Socket;
 934    client->Function = req->Function;
 935    client->state = CLIENT_UNBOUND;
 936    client->erase_busy.next = &client->erase_busy;
 937    client->erase_busy.prev = &client->erase_busy;
 938    init_waitqueue_head(&client->mtd_req);
 939    client->next = s->clients;
 940    s->clients = client;
 941    DEBUG(1, "cs: bind_device(): client 0x%p, sock %d, dev %s\n",
 942          client, client->Socket, client->dev_info);
 943    return CS_SUCCESS;
 944} /* 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
 955int pcmcia_bind_mtd(mtd_bind_t *req)
 956{
 957    socket_info_t *s;
 958    memory_handle_t region;
 959    
 960    if (CHECK_SOCKET(req->Socket))
 961        return CS_BAD_SOCKET;
 962    s = SOCKET(req);
 963    
 964    if (req->Attributes & REGION_TYPE_AM)
 965        region = s->a_region;
 966    else
 967        region = s->c_region;
 968    
 969    while (region) {
 970        if (region->info.CardOffset == req->CardOffset) break;
 971        region = region->info.next;
 972    }
 973    if (!region || (region->mtd != NULL))
 974        return CS_BAD_OFFSET;
 975    strncpy(region->dev_info, (char *)req->dev_info, DEV_NAME_LEN);
 976    
 977    DEBUG(1, "cs: bind_mtd(): attr 0x%x, offset 0x%x, dev %s\n",
 978          req->Attributes, req->CardOffset, (char *)req->dev_info);
 979    return CS_SUCCESS;
 980} /* bind_mtd */
 981
 982/*====================================================================*/
 983
 984int pcmcia_deregister_client(client_handle_t handle)
 985{
 986    client_t **client;
 987    socket_info_t *s;
 988    memory_handle_t region;
 989    u_long flags;
 990    int i, sn;
 991    
 992    DEBUG(1, "cs: deregister_client(%p)\n", handle);
 993    if (CHECK_HANDLE(handle))
 994        return CS_BAD_HANDLE;
 995    if (handle->state &
 996        (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
 997        return CS_IN_USE;
 998    for (i = 0; i < MAX_WIN; i++)
 999        if (handle->state & CLIENT_WIN_REQ(i))
1000            return CS_IN_USE;
1001
1002    /* 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
1041int pcmcia_get_configuration_info(client_handle_t handle,
1042                                  config_info_t *config)
1043{
1044    socket_info_t *s;
1045    config_t *c;
1046    
1047    if (CHECK_HANDLE(handle))
1048        return CS_BAD_HANDLE;
1049    s = SOCKET(handle);
1050    if (!(s->state & SOCKET_PRESENT))
1051        return CS_NO_CARD;
1052
1053    if (handle->Function == BIND_FN_ALL) {
1054        if (config->Function && (config->Function >= s->functions))
1055            return CS_BAD_ARGS;
1056    } else
1057        config->Function = handle->Function;
1058    
1059#ifdef CONFIG_CARDBUS
1060    if (s->state & SOCKET_CARDBUS) {
1061        u_char fn = config->Function;
1062        memset(config, 0, sizeof(config_info_t));
1063        config->Function = fn;
1064        config->Vcc = s->socket.Vcc;
1065        config->Vpp1 = config->Vpp2 = s->socket.Vpp;
1066        config->Option = s->cap.cb_dev->subordinate->number;
1067        if (s->cb_config) {
1068            config->Attributes = CONF_VALID_CLIENT;
1069            config->IntType = INT_CARDBUS;
1070            config->AssignedIRQ = s->irq.AssignedIRQ;
1071            if (config->AssignedIRQ)
1072                config->Attributes |= CONF_ENABLE_IRQ;
1073            config->BasePort1 = s->io[0].BasePort;
1074            config->NumPorts1 = s->io[0].NumPorts;
1075        }
1076        return CS_SUCCESS;
1077    }
1078#endif
1079    
1080    c = (s->config != NULL) ? &s->config[config->Function] : NULL;
1081    
1082    if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {
1083        config->Attributes = 0;
1084        config->Vcc = s->socket.Vcc;
1085        config->Vpp1 = config->Vpp2 = s->socket.Vpp;
1086        return CS_SUCCESS;
1087    }
1088    
1089    /* !!! 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
1112int pcmcia_get_card_services_info(servinfo_t *info)
1113{
1114    info->Signature[0] = 'C';
1115    info->Signature[1] = 'S';
1116    info->Count = sockets;
1117    info->Revision = CS_RELEASE_CODE;
1118    info->CSLevel = 0x0210;
1119    info->VendorString = (char *)release;
1120    return CS_SUCCESS;
1121} /* 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
1130int pcmcia_get_first_client(client_handle_t *handle, client_req_t *req)
1131{
1132    socket_t s;
1133    if (req->Attributes & CLIENT_THIS_SOCKET)
1134        s = req->Socket;
1135    else
1136        s = 0;
1137    if (CHECK_SOCKET(req->Socket))
1138        return CS_BAD_SOCKET;
1139    if (socket_table[s]->clients == NULL)
1140        return CS_NO_MORE_ITEMS;
1141    *handle = socket_table[s]->clients;
1142    return CS_SUCCESS;
1143} /* get_first_client */
1144
1145/*====================================================================*/
1146
1147int pcmcia_get_next_client(client_handle_t *handle, client_req_t *req)
1148{
1149    socket_info_t *s;
1150    if ((handle == NULL) || CHECK_HANDLE(*handle))
1151        return CS_BAD_HANDLE;
1152    if ((*handle)->next == NULL) {
1153        if (req->Attributes & CLIENT_THIS_SOCKET)
1154            return CS_NO_MORE_ITEMS;
1155        s = SOCKET(*handle);
1156        if (s->clients == NULL)
1157            return CS_NO_MORE_ITEMS;
1158        *handle = s->clients;
1159    } else
1160        *handle = (*handle)->next;
1161    return CS_SUCCESS;
1162} /* get_next_client */
1163
1164/*====================================================================*/
1165
1166int pcmcia_get_window(window_handle_t *handle, int idx, win_req_t *req)
1167{
1168    socket_info_t *s;
1169    window_t *win;
1170    int w;
1171
1172    if (idx == 0)
1173        s = SOCKET((client_handle_t)*handle);
1174    else
1175        s = (*handle)->sock;
1176    if (!(s->state & SOCKET_PRESENT))
1177        return CS_NO_CARD;
1178    for (w = idx; w < MAX_WIN; w++)
1179        if (s->state & SOCKET_WIN_REQ(w)) break;
1180    if (w == MAX_WIN)
1181        return CS_NO_MORE_ITEMS;
1182    win = &s->win[w];
1183    req->Base = win->ctl.sys_start;
1184    req->Size = win->ctl.sys_stop - win->ctl.sys_start + 1;
1185    req->AccessSpeed = win->ctl.speed;
1186    req->Attributes = 0;
1187    if (win->ctl.flags & MAP_ATTRIB)
1188        req->Attributes |= WIN_MEMORY_TYPE_AM;
1189    if (win->ctl.flags & MAP_ACTIVE)
1190        req->Attributes |= WIN_ENABLE;
1191    if (win->ctl.flags & MAP_16BIT)
1192        req->Attributes |= WIN_DATA_WIDTH_16;
1193    if (win->ctl.flags & MAP_USE_WAIT)
1194        req->Attributes |= WIN_USE_WAIT;
1195    *handle = win;
1196    return CS_SUCCESS;
1197} /* get_window */
1198
1199int pcmcia_get_first_window(window_handle_t *win, win_req_t *req)
1200{
1201    if ((win == NULL) || ((*win)->magic != WINDOW_MAGIC))
1202        return CS_BAD_HANDLE;
1203    return pcmcia_get_window(win, 0, req);
1204}
1205
1206int pcmcia_get_next_window(window_handle_t *win, win_req_t *req)
1207{
1208    if ((win == NULL) || ((*win)->magic != WINDOW_MAGIC))
1209        return CS_BAD_HANDLE;
1210    return pcmcia_get_window(win, (*win)->index+1, req);
1211}
1212
1213/*=====================================================================
1214
1215    Return the PCI device associated with a card..
1216
1217======================================================================*/
1218
1219#ifdef CONFIG_CARDBUS
1220
1221struct pci_bus *pcmcia_lookup_bus(client_handle_t handle)
1222{
1223        socket_info_t *s;
1224
1225        if (CHECK_HANDLE(handle))
1226                return NULL;
1227        s = SOCKET(handle);
1228        if (!(s->state & SOCKET_CARDBUS))
1229                return NULL;
1230
1231        return s->cap.cb_dev->subordinate;
1232}
1233
1234EXPORT_SYMBOL(pcmcia_lookup_bus);
1235
1236#endif
1237
1238/*======================================================================
1239
1240    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
1245int pcmcia_get_status(client_handle_t handle, cs_status_t *status)
1246{
1247    socket_info_t *s;
1248    config_t *c;
1249    int val;
1250    
1251    if (CHECK_HANDLE(handle))
1252        return CS_BAD_HANDLE;
1253    s = SOCKET(handle);
1254    get_socket_status(s, &val);
1255    status->CardState = status->SocketState = 0;
1256    status->CardState |= (val & SS_DETECT) ? CS_EVENT_CARD_DETECT : 0;
1257    status->CardState |= (val & SS_CARDBUS) ? CS_EVENT_CB_DETECT : 0;
1258    status->CardState |= (val & SS_3VCARD) ? CS_EVENT_3VCARD : 0;
1259    status->CardState |= (val & SS_XVCARD) ? CS_EVENT_XVCARD : 0;
1260    if (s->state & SOCKET_SUSPEND)
1261        status->CardState |= CS_EVENT_PM_SUSPEND;
1262    if (!(s->state & SOCKET_PRESENT))
1263        return CS_NO_CARD;
1264    if (s->state & SOCKET_SETUP_PENDING)
1265        status->CardState |= CS_EVENT_CARD_INSERTION;
1266    
1267    /* 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
1315int pcmcia_get_mem_page(window_handle_t win, memreq_t *req)
1316{
1317    if ((win == NULL) || (win->magic != WINDOW_MAGIC))
1318        return CS_BAD_HANDLE;
1319    req->Page = 0;
1320    req->CardOffset = win->ctl.card_start;
1321    return CS_SUCCESS;
1322} /* get_mem_page */
1323
1324int pcmcia_map_mem_page(window_handle_t win, memreq_t *req)
1325{
1326    socket_info_t *s;
1327    if ((win == NULL) || (win->magic != WINDOW_MAGIC))
1328        return CS_BAD_HANDLE;
1329    if (req->Page != 0)
1330        return CS_BAD_PAGE;
1331    s = win->sock;
1332    win->ctl.card_start = req->CardOffset;
1333    if (set_mem_map(s, &win->ctl) != 0)
1334        return CS_BAD_OFFSET;
1335    return CS_SUCCESS;
1336} /* map_mem_page */
1337
1338/*======================================================================
1339
1340    Modify a locked socket configuration
1341    
1342======================================================================*/
1343
1344int pcmcia_modify_configuration(client_handle_t handle,
1345                                modconf_t *mod)
1346{
1347    socket_info_t *s;
1348    config_t *c;
1349    
1350    if (CHECK_HANDLE(handle))
1351        return CS_BAD_HANDLE;
1352    s = SOCKET(handle); c = CONFIG(handle);
1353    if (!(s->state & SOCKET_PRESENT))
1354        return CS_NO_CARD;
1355    if (!(c->state & CONFIG_LOCKED))
1356        return CS_CONFIGURATION_LOCKED;
1357    
1358    if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {
1359        if (mod->Attributes & CONF_ENABLE_IRQ) {
1360            c->Attributes |= CONF_ENABLE_IRQ;
1361            s->socket.io_irq = s->irq.AssignedIRQ;
1362        } else {
1363            c->Attributes &= ~CONF_ENABLE_IRQ;
1364            s->socket.io_irq = 0;
1365        }
1366        set_socket(s, &s->socket);
1367    }
1368
1369    if (mod->Attributes & CONF_VCC_CHANGE_VALID)
1370        return CS_BAD_VCC;
1371
1372    /* 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
1393int pcmcia_modify_window(window_handle_t win, modwin_t *req)
1394{
1395    if ((win == NULL) || (win->magic != WINDOW_MAGIC))
1396        return CS_BAD_HANDLE;
1397
1398    win->ctl.flags &= ~(MAP_ATTRIB|MAP_ACTIVE);
1399    if (req->Attributes & WIN_MEMORY_TYPE)
1400        win->ctl.flags |= MAP_ATTRIB;
1401    if (req->Attributes & WIN_ENABLE)
1402        win->ctl.flags |= MAP_ACTIVE;
1403    if (req->Attributes & WIN_DATA_WIDTH_16)
1404        win->ctl.flags |= MAP_16BIT;
1405    if (req->Attributes & WIN_USE_WAIT)
1406        win->ctl.flags |= MAP_USE_WAIT;
1407    win->ctl.speed = req->AccessSpeed;
1408    set_mem_map(win->sock, &win->ctl);
1409    
1410    return CS_SUCCESS;
1411} /* 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
1422int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
1423{
1424    client_t *client;
1425    socket_info_t *s;
1426    socket_t ns;
1427    
1428    /* 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
1499int pcmcia_release_configuration(client_handle_t handle)
1500{
1501    pccard_io_map io = { 0, 0, 0, 0, 1 };
1502    socket_info_t *s;
1503    int i;
1504    
1505    if (CHECK_HANDLE(handle) ||
1506        !(handle->state & CLIENT_CONFIG_LOCKED))
1507        return CS_BAD_HANDLE;
1508    handle->state &= ~CLIENT_CONFIG_LOCKED;
1509    s = SOCKET(handle);
1510    
1511#ifdef CONFIG_CARDBUS
1512    if (handle->state & CLIENT_CARDBUS) {
1513        cb_disable(s);
1514        s->lock_count = 0;
1515        return CS_SUCCESS;
1516    }
1517#endif
1518    
1519    if (!(handle->state & CLIENT_STALE)) {
1520        config_t *c = CONFIG(handle);
1521        if (--(s->lock_count) == 0) {
1522            s->socket.flags = SS_OUTPUT_ENA;   /* 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
1553int pcmcia_release_io(client_handle_t handle, io_req_t *req)
1554{
1555    socket_info_t *s;
1556    
1557    if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IO_REQ))
1558        return CS_BAD_HANDLE;
1559    handle->state &= ~CLIENT_IO_REQ;
1560    s = SOCKET(handle);
1561    
1562#ifdef CONFIG_CARDBUS
1563    if (handle->state & CLIENT_CARDBUS) {
1564        cb_release(s);
1565        return CS_SUCCESS;
1566    }
1567#endif
1568    
1569    if (!(handle->state & CLIENT_STALE)) {
1570        config_t *c = CONFIG(handle);
1571        if (c->state & CONFIG_LOCKED)
1572            return CS_CONFIGURATION_LOCKED;
1573        if ((c->io.BasePort1 != req->BasePort1) ||
1574            (c->io.NumPorts1 != req->NumPorts1) ||
1575            (c->io.BasePort2 != req->BasePort2) ||
1576            (c->io.NumPorts2 != req->NumPorts2))
1577            return CS_BAD_ARGS;
1578        c->state &= ~CONFIG_IO_REQ;
1579    }
1580
1581    release_io_space(s, req->BasePort1, req->NumPorts1);
1582    if (req->NumPorts2)
1583        release_io_space(s, req->BasePort2, req->NumPorts2);
1584    
1585    return CS_SUCCESS;
1586} /* release_io */
1587
1588/*====================================================================*/
1589
1590int pcmcia_release_irq(client_handle_t handle, irq_req_t *req)
1591{
1592    socket_info_t *s;
1593    if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IRQ_REQ))
1594        return CS_BAD_HANDLE;
1595    handle->state &= ~CLIENT_IRQ_REQ;
1596    s = SOCKET(handle);
1597    
1598    if (!(handle->state & CLIENT_STALE)) {
1599        config_t *c = CONFIG(handle);
1600        if (c->state & CONFIG_LOCKED)
1601            return CS_CONFIGURATION_LOCKED;
1602        if (c->irq.Attributes != req->Attributes)
1603            return CS_BAD_ATTRIBUTE;
1604        if (s->irq.AssignedIRQ != req->AssignedIRQ)
1605            return CS_BAD_IRQ;
1606        if (--s->irq.Config == 0) {
1607            c->state &= ~CONFIG_IRQ_REQ;
1608            s->irq.AssignedIRQ = 0;
1609        }
1610    }
1611    
1612    if (req->Attributes & IRQ_HANDLE_PRESENT) {
1613        bus_free_irq(s->cap.bus, req->AssignedIRQ, req->Instance);
1614    }
1615
1616#ifdef CONFIG_ISA
1617    if (req->AssignedIRQ != s->cap.pci_irq)
1618        undo_irq(req->Attributes, req->AssignedIRQ);
1619#endif
1620    
1621    return CS_SUCCESS;
1622} /* cs_release_irq */
1623
1624/*====================================================================*/
1625
1626int pcmcia_release_window(window_handle_t win)
1627{
1628    socket_info_t *s;
1629    
1630    if ((win == NULL) || (win->magic != WINDOW_MAGIC))
1631        return CS_BAD_HANDLE;
1632    s = win->sock;
1633    if (!(win->handle->state & CLIENT_WIN_REQ(win->index)))
1634        return CS_BAD_HANDLE;
1635
1636    /* 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
1653int pcmcia_request_configuration(client_handle_t handle,
1654                                 config_req_t *req)
1655{
1656    int i;
1657    u_int base;
1658    socket_info_t *s;
1659    config_t *c;
1660    pccard_io_map iomap;
1661    
1662    if (CHECK_HANDLE(handle))
1663        return CS_BAD_HANDLE;
1664    i = handle->Socket; s = socket_table[i];
1665    if (!(s->state & SOCKET_PRESENT))
1666        return CS_NO_CARD;
1667    
1668#ifdef CONFIG_CARDBUS
1669    if (handle->state & CLIENT_CARDBUS) {
1670        if (!(req->IntType & INT_CARDBUS))
1671            return CS_UNSUPPORTED_MODE;
1672        if (s->lock_count != 0)
1673            return CS_CONFIGURATION_LOCKED;
1674        cb_enable(s);
1675        handle->state |= CLIENT_CONFIG_LOCKED;
1676        s->lock_count++;
1677        return CS_SUCCESS;
1678    }
1679#endif
1680    
1681    if (req->IntType & INT_CARDBUS)
1682        return CS_UNSUPPORTED_MODE;
1683    c = CONFIG(handle);
1684    if (c->state & CONFIG_LOCKED)
1685        return CS_CONFIGURATION_LOCKED;
1686
1687    /* 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
1795int pcmcia_request_io(client_handle_t handle, io_req_t *req)
1796{
1797    socket_info_t *s;
1798    config_t *c;
1799    
1800    if (CHECK_HANDLE(handle))
1801        return CS_BAD_HANDLE;
1802    s = SOCKET(handle);
1803    if (!(s->state & SOCKET_PRESENT))
1804        return CS_NO_CARD;
1805
1806    if (handle->state & CLIENT_CARDBUS) {
1807#ifdef CONFIG_CARDBUS
1808        int ret = cb_config(s);
1809        if (ret == CS_SUCCESS)
1810            handle->state |= CLIENT_IO_REQ;
1811        return ret;
1812#else
1813        return CS_UNSUPPORTED_FUNCTION;
1814#endif
1815    }
1816
1817    if (!req)
1818        return CS_UNSUPPORTED_MODE;
1819    c = CONFIG(handle);
1820    if (c->state & CONFIG_LOCKED)
1821        return CS_CONFIGURATION_LOCKED;
1822    if (c->state & CONFIG_IO_REQ)
1823        return CS_IN_USE;
1824    if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))
1825        return CS_BAD_ATTRIBUTE;
1826    if ((req->NumPorts2 > 0) &&
1827        (req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)))
1828        return CS_BAD_ATTRIBUTE;
1829
1830    if (alloc_io_space(s, req->Attributes1, &req->BasePort1,
1831                       req->NumPorts1, req->IOAddrLines,
1832                       handle->dev_info))
1833        return CS_IN_USE;
1834
1835    if (req->NumPorts2) {
1836        if (alloc_io_space(s, req->Attributes2, &req->BasePort2,
1837                           req->NumPorts2, req->IOAddrLines,
1838                           handle->dev_info)) {
1839            release_io_space(s, req->BasePort1, req->NumPorts1);
1840            return CS_IN_USE;
1841        }
1842    }
1843
1844    c->io = *req;
1845    c->state |= CONFIG_IO_REQ;
1846    handle->state |= CLIENT_IO_REQ;
1847    return CS_SUCCESS;
1848} /* 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
1861int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)
1862{
1863    socket_info_t *s;
1864    config_t *c;
1865    int ret = CS_IN_USE, irq = 0;
1866    
1867    if (CHECK_HANDLE(handle))
1868        return CS_BAD_HANDLE;
1869    s = SOCKET(handle);
1870    if (!(s->state & SOCKET_PRESENT))
1871        return CS_NO_CARD;
1872    c = CONFIG(handle);
1873    if (c->state & CONFIG_LOCKED)
1874        return CS_CONFIGURATION_LOCKED;
1875    if (c->state & CONFIG_IRQ_REQ)
1876        return CS_IN_USE;
1877
1878#ifdef CONFIG_ISA
1879    if (s->irq.AssignedIRQ != 0) {
1880        /* 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
1935int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle_t *wh)
1936{
1937    socket_info_t *s;
1938    window_t *win;
1939    u_long align;
1940    int w;
1941    
1942    if (CHECK_HANDLE(*handle))
1943        return CS_BAD_HANDLE;
1944    s = SOCKET(*handle);
1945    if (!(s->state & SOCKET_PRESENT))
1946        return CS_NO_CARD;
1947    if (req->Attributes & (WIN_PAGED | WIN_SHARED))
1948        return CS_BAD_ATTRIBUTE;
1949
1950    /* 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
2020int pcmcia_reset_card(client_handle_t handle, client_req_t *req)
2021{
2022    int i, ret;
2023    socket_info_t *s;
2024    
2025    if (CHECK_HANDLE(handle))
2026        return CS_BAD_HANDLE;
2027    i = handle->Socket; s = socket_table[i];
2028    if (!(s->state & SOCKET_PRESENT))
2029        return CS_NO_CARD;
2030    if (s->state & SOCKET_RESET_PENDING)
2031        return CS_IN_USE;
2032    s->state |= SOCKET_RESET_PENDING;
2033
2034    ret = send_event(s, CS_EVENT_RESET_REQUEST, CS_EVENT_PRI_LOW);
2035    if (ret != 0) {
2036        s->state &= ~SOCKET_RESET_PENDING;
2037        handle->event_callback_args.info = (void *)(u_long)ret;
2038        EVENT(handle, CS_EVENT_RESET_COMPLETE, CS_EVENT_PRI_LOW);
2039    } else {
2040        DEBUG(1, "cs: resetting socket %d\n", i);
2041        send_event(s, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW);
2042        s->reset_handle = handle;
2043        reset_socket(s);
2044    }
2045    return CS_SUCCESS;
2046} /* 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
2055int pcmcia_suspend_card(client_handle_t handle, client_req_t *req)
2056{
2057    int i;
2058    socket_info_t *s;
2059    
2060    if (CHECK_HANDLE(handle))
2061        return CS_BAD_HANDLE;
2062    i = handle->Socket; s = socket_table[i];
2063    if (!(s->state & SOCKET_PRESENT))
2064        return CS_NO_CARD;
2065    if (s->state & SOCKET_SUSPEND)
2066        return CS_IN_USE;
2067
2068    DEBUG(1, "cs: suspending socket %d\n", i);
2069    send_event(s, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW);
2070    suspend_socket(s);
2071    s->state |= SOCKET_SUSPEND;
2072
2073    return CS_SUCCESS;
2074} /* suspend_card */
2075
2076int pcmcia_resume_card(client_handle_t handle, client_req_t *req)
2077{
2078    int i;
2079    socket_info_t *s;
2080    
2081    if (CHECK_HANDLE(handle))
2082        return CS_BAD_HANDLE;
2083    i = handle->Socket; s = socket_table[i];
2084    if (!(s->state & SOCKET_PRESENT))
2085        return CS_NO_CARD;
2086    if (!(s->state & SOCKET_SUSPEND))
2087        return CS_IN_USE;
2088
2089    DEBUG(1, "cs: waking up socket %d\n", i);
2090    setup_socket(s);
2091
2092    return CS_SUCCESS;
2093} /* resume_card */
2094
2095/*======================================================================
2096
2097    These handle user requests to eject or insert a card.
2098    
2099======================================================================*/
2100
2101int pcmcia_eject_card(client_handle_t handle, client_req_t *req)
2102{
2103    int i, ret;
2104    socket_info_t *s;
2105    u_long flags;
2106    
2107    if (CHECK_HANDLE(handle))
2108        return CS_BAD_HANDLE;
2109    i = handle->Socket; s = socket_table[i];
2110    if (!(s->state & SOCKET_PRESENT))
2111        return CS_NO_CARD;
2112
2113    DEBUG(1, "cs: user eject request on socket %d\n", i);
2114
2115    ret = send_event(s, CS_EVENT_EJECTION_REQUEST, CS_EVENT_PRI_LOW);
2116    if (ret != 0)
2117        return ret;
2118
2119    spin_lock_irqsave(&s->lock, flags);
2120    do_shutdown(s);
2121    spin_unlock_irqrestore(&s->lock, flags);
2122    
2123    return CS_SUCCESS;
2124    
2125} /* eject_card */
2126
2127int pcmcia_insert_card(client_handle_t handle, client_req_t *req)
2128{
2129    int i, status;
2130    socket_info_t *s;
2131    u_long flags;
2132    
2133    if (CHECK_HANDLE(handle))
2134        return CS_BAD_HANDLE;
2135    i = handle->Socket; s = socket_table[i];
2136    if (s->state & SOCKET_PRESENT)
2137        return CS_IN_USE;
2138
2139    DEBUG(1, "cs: user insert request on socket %d\n", i);
2140
2141    spin_lock_irqsave(&s->lock, flags);
2142    if (!(s->state & SOCKET_SETUP_PENDING)) {
2143        s->state |= SOCKET_SETUP_PENDING;
2144        spin_unlock_irqrestore(&s->lock, flags);
2145        get_socket_status(s, &status);
2146        if ((status & SS_DETECT) == 0 || (setup_socket(s) == 0)) {
2147            s->state &= ~SOCKET_SETUP_PENDING;
2148            return CS_NO_CARD;
2149        }
2150    } else
2151        spin_unlock_irqrestore(&s->lock, flags);
2152
2153    return CS_SUCCESS;
2154} /* 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
2163int pcmcia_set_event_mask(client_handle_t handle, eventmask_t *mask)
2164{
2165    u_int events, bit;
2166    if (CHECK_HANDLE(handle))
2167        return CS_BAD_HANDLE;
2168    if (handle->Attributes & CONF_EVENT_MASK_VALID)
2169        return CS_BAD_SOCKET;
2170    handle->EventMask = mask->EventMask;
2171    events = handle->PendingEvents & handle->EventMask;
2172    handle->PendingEvents -= events;
2173    while (events != 0) {
2174        bit = ((events ^ (events-1)) + 1) >> 1;
2175        EVENT(handle, bit, CS_EVENT_PRI_LOW);
2176        events -= bit;
2177    }
2178    return CS_SUCCESS;
2179} /* set_event_mask */
2180
2181/*====================================================================*/
2182
2183int pcmcia_report_error(client_handle_t handle, error_info_t *err)
2184{
2185    int i;
2186    char *serv;
2187
2188    if (CHECK_HANDLE(handle))
2189        printk(KERN_NOTICE);
2190    else
2191        printk(KERN_NOTICE "%s: ", handle->dev_info);
2192    
2193    for (i = 0; i < SERVICE_COUNT; i++)
2194        if (service_table[i].key == err->func) break;
2195    if (i < SERVICE_COUNT)
2196        serv = service_table[i].msg;
2197    else
2198        serv = "Unknown service number";
2199
2200    for (i = 0; i < ERROR_COUNT; i++)
2201        if (error_table[i].key == err->retcode) break;
2202    if (i < ERROR_COUNT)
2203        printk("%s: %s\n", serv, error_table[i].msg);
2204    else
2205        printk("%s: Unknown error code %#x\n", serv, err->retcode);
2206
2207    return CS_SUCCESS;
2208} /* report_error */
2209
2210/*====================================================================*/
2211
2212int CardServices(int func, void *a1, void *a2, void *a3)
2213{
2214
2215#ifdef PCMCIA_DEBUG
2216    if (pc_debug > 2) {
2217        int i;
2218        for (i = 0; i < SERVICE_COUNT; i++)
2219            if (service_table[i].key == func) break;
2220        if (i < SERVICE_COUNT)
2221            printk(KERN_DEBUG "cs: CardServices(%s, 0x%p, 0x%p)\n",
2222                   service_table[i].msg, a1, a2);
2223        else
2224            printk(KERN_DEBUG "cs: CardServices(Unknown func %d, "
2225                   "0x%p, 0x%p)\n", func, a1, a2);
2226    }
2227#endif
2228    switch (func) {
2229    case AccessConfigurationRegister:
2230        return pcmcia_access_configuration_register(a1, a2); break;
2231    case AdjustResourceInfo:
2232        return pcmcia_adjust_resource_info(a1, a2); break;
2233    case CheckEraseQueue:
2234        return pcmcia_check_erase_queue(a1); break;
2235    case CloseMemory:
2236        return pcmcia_close_memory(a1); break;
2237    case CopyMemory:
2238        return pcmcia_copy_memory(a1, a2); break;
2239    case DeregisterClient:
2240        return pcmcia_deregister_client(a1); break;
2241    case DeregisterEraseQueue:
2242        return pcmcia_deregister_erase_queue(a1); break;
2243    case GetFirstClient:
2244        return pcmcia_get_first_client(a1, a2); break;
2245    case GetCardServicesInfo:
2246        return pcmcia_get_card_services_info(a1); break;
2247    case GetConfigurationInfo:
2248        return pcmcia_get_configuration_info(a1, a2); break;
2249    case GetNextClient:
2250        return pcmcia_get_next_client(a1, a2); break;
2251    case GetFirstRegion:
2252        return pcmcia_get_first_region(a1, a2); break;
2253    case GetFirstTuple:
2254        return pcmcia_get_first_tuple(a1, a2); break;
2255    case GetNextRegion:
2256        return pcmcia_get_next_region(a1, a2); break;
2257    case GetNextTuple:
2258        return pcmcia_get_next_tuple(a1, a2); break;
2259    case GetStatus:
2260        return pcmcia_get_status(a1, a2); break;
2261    case GetTupleData:
2262        return pcmcia_get_tuple_data(a1, a2); break;
2263    case MapMemPage:
2264        return pcmcia_map_mem_page(a1, a2); break;
2265    case ModifyConfiguration:
2266        return pcmcia_modify_configuration(a1, a2); break;
2267    case ModifyWindow:
2268        return pcmcia_modify_window(a1, a2); break;
2269    case OpenMemory:
2270/*      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 */
2359EXPORT_SYMBOL(pcmcia_access_configuration_register);
2360EXPORT_SYMBOL(pcmcia_adjust_resource_info);
2361EXPORT_SYMBOL(pcmcia_bind_device);
2362EXPORT_SYMBOL(pcmcia_bind_mtd);
2363EXPORT_SYMBOL(pcmcia_check_erase_queue);
2364EXPORT_SYMBOL(pcmcia_close_memory);
2365EXPORT_SYMBOL(pcmcia_copy_memory);
2366EXPORT_SYMBOL(pcmcia_deregister_client);
2367EXPORT_SYMBOL(pcmcia_deregister_erase_queue);
2368EXPORT_SYMBOL(pcmcia_eject_card);
2369EXPORT_SYMBOL(pcmcia_get_first_client);
2370EXPORT_SYMBOL(pcmcia_get_card_services_info);
2371EXPORT_SYMBOL(pcmcia_get_configuration_info);
2372EXPORT_SYMBOL(pcmcia_get_mem_page);
2373EXPORT_SYMBOL(pcmcia_get_next_client);
2374EXPORT_SYMBOL(pcmcia_get_first_region);
2375EXPORT_SYMBOL(pcmcia_get_first_tuple);
2376EXPORT_SYMBOL(pcmcia_get_first_window);
2377EXPORT_SYMBOL(pcmcia_get_next_region);
2378EXPORT_SYMBOL(pcmcia_get_next_tuple);
2379EXPORT_SYMBOL(pcmcia_get_next_window);
2380EXPORT_SYMBOL(pcmcia_get_status);
2381EXPORT_SYMBOL(pcmcia_get_tuple_data);
2382EXPORT_SYMBOL(pcmcia_insert_card);
2383EXPORT_SYMBOL(pcmcia_map_mem_page);
2384EXPORT_SYMBOL(pcmcia_modify_configuration);
2385EXPORT_SYMBOL(pcmcia_modify_window);
2386EXPORT_SYMBOL(pcmcia_open_memory);
2387EXPORT_SYMBOL(pcmcia_parse_tuple);
2388EXPORT_SYMBOL(pcmcia_read_memory);
2389EXPORT_SYMBOL(pcmcia_register_client);
2390EXPORT_SYMBOL(pcmcia_register_erase_queue);
2391EXPORT_SYMBOL(pcmcia_register_mtd);
2392EXPORT_SYMBOL(pcmcia_release_configuration);
2393EXPORT_SYMBOL(pcmcia_release_io);
2394EXPORT_SYMBOL(pcmcia_release_irq);
2395EXPORT_SYMBOL(pcmcia_release_window);
2396EXPORT_SYMBOL(pcmcia_replace_cis);
2397EXPORT_SYMBOL(pcmcia_report_error);
2398EXPORT_SYMBOL(pcmcia_request_configuration);
2399EXPORT_SYMBOL(pcmcia_request_io);
2400EXPORT_SYMBOL(pcmcia_request_irq);
2401EXPORT_SYMBOL(pcmcia_request_window);
2402EXPORT_SYMBOL(pcmcia_reset_card);
2403EXPORT_SYMBOL(pcmcia_resume_card);
2404EXPORT_SYMBOL(pcmcia_set_event_mask);
2405EXPORT_SYMBOL(pcmcia_suspend_card);
2406EXPORT_SYMBOL(pcmcia_validate_cis);
2407EXPORT_SYMBOL(pcmcia_write_memory);
2408
2409EXPORT_SYMBOL(dead_socket);
2410EXPORT_SYMBOL(register_ss_entry);
2411EXPORT_SYMBOL(unregister_ss_entry);
2412EXPORT_SYMBOL(CardServices);
2413EXPORT_SYMBOL(MTDHelperEntry);
2414#ifdef CONFIG_PROC_FS
2415EXPORT_SYMBOL(proc_pccard);
2416#endif
2417
2418EXPORT_SYMBOL(pcmcia_register_socket);
2419EXPORT_SYMBOL(pcmcia_unregister_socket);
2420EXPORT_SYMBOL(pcmcia_suspend_socket);
2421EXPORT_SYMBOL(pcmcia_resume_socket);
2422
2423static int __init init_pcmcia_cs(void)
2424{
2425    printk(KERN_INFO "%s\n", release);
2426    printk(KERN_INFO "  %s\n", options);
2427    DEBUG(0, "%s\n", version);
2428    if (do_apm)
2429        pm_register(PM_SYS_DEV, PM_SYS_PCMCIA, handle_pm_event);
2430#ifdef CONFIG_PROC_FS
2431    proc_pccard = proc_mkdir("pccard", proc_bus);
2432#endif
2433    return 0;
2434}
2435
2436static void __exit exit_pcmcia_cs(void)
2437{
2438    printk(KERN_INFO "unloading Kernel Card Services\n");
2439#ifdef CONFIG_PROC_FS
2440    if (proc_pccard) {
2441        remove_proc_entry("pccard", proc_bus);
2442    }
2443#endif
2444    if (do_apm)
2445        pm_unregister_all(handle_pm_event);
2446    release_resource_db();
2447}
2448
2449module_init(init_pcmcia_cs);
2450module_exit(exit_pcmcia_cs);
2451
2452/*====================================================================*/
2453
2454
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.