linux-old/drivers/pcmcia/i82365.c
<<
>>
Prefs
   1/*======================================================================
   2
   3    Device driver for Intel 82365 and compatible PC Card controllers.
   4
   5    i82365.c 1.265 1999/11/10 18:36:21
   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/config.h>
  37#include <linux/types.h>
  38#include <linux/fcntl.h>
  39#include <linux/string.h>
  40#include <linux/kernel.h>
  41#include <linux/errno.h>
  42#include <linux/timer.h>
  43#include <linux/sched.h>
  44#include <linux/slab.h>
  45#include <linux/ioport.h>
  46#include <linux/delay.h>
  47#include <linux/proc_fs.h>
  48#include <asm/irq.h>
  49#include <asm/io.h>
  50#include <asm/bitops.h>
  51#include <asm/segment.h>
  52#include <asm/system.h>
  53
  54#include <pcmcia/version.h>
  55#include <pcmcia/cs_types.h>
  56#include <pcmcia/ss.h>
  57#include <pcmcia/cs.h>
  58
  59#include <linux/isapnp.h>
  60
  61/* ISA-bus controllers */
  62#include "i82365.h"
  63#include "cirrus.h"
  64#include "vg468.h"
  65#include "ricoh.h"
  66
  67#ifdef PCMCIA_DEBUG
  68static int pc_debug = PCMCIA_DEBUG;
  69MODULE_PARM(pc_debug, "i");
  70#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
  71static const char *version =
  72"i82365.c 1.265 1999/11/10 18:36:21 (David Hinds)";
  73#else
  74#define DEBUG(n, args...) do { } while (0)
  75#endif
  76
  77static void irq_count(int, void *, struct pt_regs *);
  78static inline int _check_irq(int irq, int flags)
  79{
  80    if (request_irq(irq, irq_count, flags, "x", irq_count) != 0)
  81        return -1;
  82    free_irq(irq, irq_count);
  83    return 0;
  84}
  85
  86/*====================================================================*/
  87
  88/* Parameters that can be set with 'insmod' */
  89
  90/* Default base address for i82365sl and other ISA chips */
  91static int i365_base = 0x3e0;
  92/* Should we probe at 0x3e2 for an extra ISA controller? */
  93static int extra_sockets = 0;
  94/* Specify a socket number to ignore */
  95static int ignore = -1;
  96/* Bit map or list of interrupts to choose from */
  97static u_int irq_mask = 0xffff;
  98static int irq_list[16] = { -1 };
  99/* The card status change interrupt -- 0 means autoselect */
 100static int cs_irq = 0;
 101
 102/* Probe for safe interrupts? */
 103static int do_scan = 1;
 104/* Poll status interval -- 0 means default to interrupt */
 105static int poll_interval = 0;
 106/* External clock time, in nanoseconds.  120 ns = 8.33 MHz */
 107static int cycle_time = 120;
 108
 109/* Cirrus options */
 110static int has_dma = -1;
 111static int has_led = -1;
 112static int has_ring = -1;
 113static int dynamic_mode = 0;
 114static int freq_bypass = -1;
 115static int setup_time = -1;
 116static int cmd_time = -1;
 117static int recov_time = -1;
 118
 119/* Vadem options */
 120static int async_clock = -1;
 121static int cable_mode = -1;
 122static int wakeup = 0;
 123
 124MODULE_PARM(i365_base, "i");
 125MODULE_PARM(ignore, "i");
 126MODULE_PARM(extra_sockets, "i");
 127MODULE_PARM(irq_mask, "i");
 128MODULE_PARM(irq_list, "1-16i");
 129MODULE_PARM(cs_irq, "i");
 130MODULE_PARM(async_clock, "i");
 131MODULE_PARM(cable_mode, "i");
 132MODULE_PARM(wakeup, "i");
 133
 134MODULE_PARM(do_scan, "i");
 135MODULE_PARM(poll_interval, "i");
 136MODULE_PARM(cycle_time, "i");
 137MODULE_PARM(has_dma, "i");
 138MODULE_PARM(has_led, "i");
 139MODULE_PARM(has_ring, "i");
 140MODULE_PARM(dynamic_mode, "i");
 141MODULE_PARM(freq_bypass, "i");
 142MODULE_PARM(setup_time, "i");
 143MODULE_PARM(cmd_time, "i");
 144MODULE_PARM(recov_time, "i");
 145
 146/*====================================================================*/
 147
 148typedef struct cirrus_state_t {
 149    u_char              misc1, misc2;
 150    u_char              timer[6];
 151} cirrus_state_t;
 152
 153typedef struct vg46x_state_t {
 154    u_char              ctl, ema;
 155} vg46x_state_t;
 156
 157typedef struct socket_info_t {
 158    u_short             type, flags;
 159    socket_cap_t        cap;
 160    ioaddr_t            ioaddr;
 161    u_short             psock;
 162    u_char              cs_irq, intr;
 163    void                (*handler)(void *info, u_int events);
 164    void                *info;
 165#ifdef CONFIG_PROC_FS
 166    struct proc_dir_entry *proc;
 167#endif
 168    union {
 169        cirrus_state_t          cirrus;
 170        vg46x_state_t           vg46x;
 171    } state;
 172} socket_info_t;
 173
 174/* Where we keep track of our sockets... */
 175static int sockets = 0;
 176static socket_info_t socket[8] = {
 177    { 0, }, /* ... */
 178};
 179
 180/* Default ISA interrupt mask */
 181#define I365_MASK       0xdeb8  /* irq 15,14,12,11,10,9,7,5,4,3 */
 182
 183static int grab_irq;
 184static spinlock_t isa_lock = SPIN_LOCK_UNLOCKED;
 185#define ISA_LOCK(n, f) spin_lock_irqsave(&isa_lock, f)
 186#define ISA_UNLOCK(n, f) spin_unlock_irqrestore(&isa_lock, f)
 187
 188static struct timer_list poll_timer;
 189
 190/*====================================================================*/
 191
 192/* These definitions must match the pcic table! */
 193typedef enum pcic_id {
 194    IS_I82365A, IS_I82365B, IS_I82365DF,
 195    IS_IBM, IS_RF5Cx96, IS_VLSI, IS_VG468, IS_VG469,
 196    IS_PD6710, IS_PD672X, IS_VT83C469,
 197} pcic_id;
 198
 199/* Flags for classifying groups of controllers */
 200#define IS_VADEM        0x0001
 201#define IS_CIRRUS       0x0002
 202#define IS_VIA          0x0010
 203#define IS_UNKNOWN      0x0400
 204#define IS_VG_PWR       0x0800
 205#define IS_DF_PWR       0x1000
 206#define IS_ALIVE        0x8000
 207
 208typedef struct pcic_t {
 209    char                *name;
 210    u_short             flags;
 211} pcic_t;
 212
 213static pcic_t pcic[] = {
 214    { "Intel i82365sl A step", 0 },
 215    { "Intel i82365sl B step", 0 },
 216    { "Intel i82365sl DF", IS_DF_PWR },
 217    { "IBM Clone", 0 },
 218    { "Ricoh RF5C296/396", 0 },
 219    { "VLSI 82C146", 0 },
 220    { "Vadem VG-468", IS_VADEM },
 221    { "Vadem VG-469", IS_VADEM|IS_VG_PWR },
 222    { "Cirrus PD6710", IS_CIRRUS },
 223    { "Cirrus PD672x", IS_CIRRUS },
 224    { "VIA VT83C469", IS_CIRRUS|IS_VIA },
 225};
 226
 227#define PCIC_COUNT      (sizeof(pcic)/sizeof(pcic_t))
 228
 229/*====================================================================*/
 230
 231static spinlock_t bus_lock = SPIN_LOCK_UNLOCKED;
 232
 233static u_char i365_get(u_short sock, u_short reg)
 234{
 235    unsigned long flags;
 236    spin_lock_irqsave(&bus_lock,flags);
 237    {
 238        ioaddr_t port = socket[sock].ioaddr;
 239        u_char val;
 240        reg = I365_REG(socket[sock].psock, reg);
 241        outb(reg, port); val = inb(port+1);
 242        spin_unlock_irqrestore(&bus_lock,flags);
 243        return val;
 244    }
 245}
 246
 247static void i365_set(u_short sock, u_short reg, u_char data)
 248{
 249    unsigned long flags;
 250    spin_lock_irqsave(&bus_lock,flags);
 251    {
 252        ioaddr_t port = socket[sock].ioaddr;
 253        u_char val = I365_REG(socket[sock].psock, reg);
 254        outb(val, port); outb(data, port+1);
 255        spin_unlock_irqrestore(&bus_lock,flags);
 256    }
 257}
 258
 259static void i365_bset(u_short sock, u_short reg, u_char mask)
 260{
 261    u_char d = i365_get(sock, reg);
 262    d |= mask;
 263    i365_set(sock, reg, d);
 264}
 265
 266static void i365_bclr(u_short sock, u_short reg, u_char mask)
 267{
 268    u_char d = i365_get(sock, reg);
 269    d &= ~mask;
 270    i365_set(sock, reg, d);
 271}
 272
 273static void i365_bflip(u_short sock, u_short reg, u_char mask, int b)
 274{
 275    u_char d = i365_get(sock, reg);
 276    if (b)
 277        d |= mask;
 278    else
 279        d &= ~mask;
 280    i365_set(sock, reg, d);
 281}
 282
 283static u_short i365_get_pair(u_short sock, u_short reg)
 284{
 285    u_short a, b;
 286    a = i365_get(sock, reg);
 287    b = i365_get(sock, reg+1);
 288    return (a + (b<<8));
 289}
 290
 291static void i365_set_pair(u_short sock, u_short reg, u_short data)
 292{
 293    i365_set(sock, reg, data & 0xff);
 294    i365_set(sock, reg+1, data >> 8);
 295}
 296
 297/*======================================================================
 298
 299    Code to save and restore global state information for Cirrus
 300    PD67xx controllers, and to set and report global configuration
 301    options.
 302
 303    The VIA controllers also use these routines, as they are mostly
 304    Cirrus lookalikes, without the timing registers.
 305    
 306======================================================================*/
 307
 308#define flip(v,b,f) (v = ((f)<0) ? v : ((f) ? ((v)|(b)) : ((v)&(~b))))
 309
 310static void cirrus_get_state(u_short s)
 311{
 312    int i;
 313    cirrus_state_t *p = &socket[s].state.cirrus;
 314    p->misc1 = i365_get(s, PD67_MISC_CTL_1);
 315    p->misc1 &= (PD67_MC1_MEDIA_ENA | PD67_MC1_INPACK_ENA);
 316    p->misc2 = i365_get(s, PD67_MISC_CTL_2);
 317    for (i = 0; i < 6; i++)
 318        p->timer[i] = i365_get(s, PD67_TIME_SETUP(0)+i);
 319}
 320
 321static void cirrus_set_state(u_short s)
 322{
 323    int i;
 324    u_char misc;
 325    cirrus_state_t *p = &socket[s].state.cirrus;
 326
 327    misc = i365_get(s, PD67_MISC_CTL_2);
 328    i365_set(s, PD67_MISC_CTL_2, p->misc2);
 329    if (misc & PD67_MC2_SUSPEND) mdelay(50);
 330    misc = i365_get(s, PD67_MISC_CTL_1);
 331    misc &= ~(PD67_MC1_MEDIA_ENA | PD67_MC1_INPACK_ENA);
 332    i365_set(s, PD67_MISC_CTL_1, misc | p->misc1);
 333    for (i = 0; i < 6; i++)
 334        i365_set(s, PD67_TIME_SETUP(0)+i, p->timer[i]);
 335}
 336
 337static u_int __init cirrus_set_opts(u_short s, char *buf)
 338{
 339    socket_info_t *t = &socket[s];
 340    cirrus_state_t *p = &socket[s].state.cirrus;
 341    u_int mask = 0xffff;
 342
 343    if (has_ring == -1) has_ring = 1;
 344    flip(p->misc2, PD67_MC2_IRQ15_RI, has_ring);
 345    flip(p->misc2, PD67_MC2_DYNAMIC_MODE, dynamic_mode);
 346    flip(p->misc2, PD67_MC2_FREQ_BYPASS, freq_bypass);
 347    if (p->misc2 & PD67_MC2_IRQ15_RI)
 348        strcat(buf, " [ring]");
 349    if (p->misc2 & PD67_MC2_DYNAMIC_MODE)
 350        strcat(buf, " [dyn mode]");
 351    if (p->misc2 & PD67_MC2_FREQ_BYPASS)
 352        strcat(buf, " [freq bypass]");
 353    if (p->misc1 & PD67_MC1_INPACK_ENA)
 354        strcat(buf, " [inpack]");
 355    if (p->misc2 & PD67_MC2_IRQ15_RI)
 356        mask &= ~0x8000;
 357    if (has_led > 0) {
 358        strcat(buf, " [led]");
 359        mask &= ~0x1000;
 360    }
 361    if (has_dma > 0) {
 362        strcat(buf, " [dma]");
 363        mask &= ~0x0600;
 364    }
 365    if (!(t->flags & IS_VIA)) {
 366        if (setup_time >= 0)
 367            p->timer[0] = p->timer[3] = setup_time;
 368        if (cmd_time > 0) {
 369            p->timer[1] = cmd_time;
 370            p->timer[4] = cmd_time*2+4;
 371        }
 372        if (p->timer[1] == 0) {
 373            p->timer[1] = 6; p->timer[4] = 16;
 374            if (p->timer[0] == 0)
 375                p->timer[0] = p->timer[3] = 1;
 376        }
 377        if (recov_time >= 0)
 378            p->timer[2] = p->timer[5] = recov_time;
 379        buf += strlen(buf);
 380        sprintf(buf, " [%d/%d/%d] [%d/%d/%d]", p->timer[0], p->timer[1],
 381                p->timer[2], p->timer[3], p->timer[4], p->timer[5]);
 382    }
 383    return mask;
 384}
 385
 386/*======================================================================
 387
 388    Code to save and restore global state information for Vadem VG468
 389    and VG469 controllers, and to set and report global configuration
 390    options.
 391    
 392======================================================================*/
 393
 394static void vg46x_get_state(u_short s)
 395{
 396    vg46x_state_t *p = &socket[s].state.vg46x;
 397    p->ctl = i365_get(s, VG468_CTL);
 398    if (socket[s].type == IS_VG469)
 399        p->ema = i365_get(s, VG469_EXT_MODE);
 400}
 401
 402static void vg46x_set_state(u_short s)
 403{
 404    vg46x_state_t *p = &socket[s].state.vg46x;
 405    i365_set(s, VG468_CTL, p->ctl);
 406    if (socket[s].type == IS_VG469)
 407        i365_set(s, VG469_EXT_MODE, p->ema);
 408}
 409
 410static u_int __init vg46x_set_opts(u_short s, char *buf)
 411{
 412    vg46x_state_t *p = &socket[s].state.vg46x;
 413    
 414    flip(p->ctl, VG468_CTL_ASYNC, async_clock);
 415    flip(p->ema, VG469_MODE_CABLE, cable_mode);
 416    if (p->ctl & VG468_CTL_ASYNC)
 417        strcat(buf, " [async]");
 418    if (p->ctl & VG468_CTL_INPACK)
 419        strcat(buf, " [inpack]");
 420    if (socket[s].type == IS_VG469) {
 421        u_char vsel = i365_get(s, VG469_VSELECT);
 422        if (vsel & VG469_VSEL_EXT_STAT) {
 423            strcat(buf, " [ext mode]");
 424            if (vsel & VG469_VSEL_EXT_BUS)
 425                strcat(buf, " [isa buf]");
 426        }
 427        if (p->ema & VG469_MODE_CABLE)
 428            strcat(buf, " [cable]");
 429        if (p->ema & VG469_MODE_COMPAT)
 430            strcat(buf, " [c step]");
 431    }
 432    return 0xffff;
 433}
 434
 435/*======================================================================
 436
 437    Generic routines to get and set controller options
 438    
 439======================================================================*/
 440
 441static void get_bridge_state(u_short s)
 442{
 443    socket_info_t *t = &socket[s];
 444    if (t->flags & IS_CIRRUS)
 445        cirrus_get_state(s);
 446    else if (t->flags & IS_VADEM)
 447        vg46x_get_state(s);
 448}
 449
 450static void set_bridge_state(u_short s)
 451{
 452    socket_info_t *t = &socket[s];
 453    if (t->flags & IS_CIRRUS)
 454        cirrus_set_state(s);
 455    else {
 456        i365_set(s, I365_GBLCTL, 0x00);
 457        i365_set(s, I365_GENCTL, 0x00);
 458    }
 459    i365_bflip(s, I365_INTCTL, I365_INTR_ENA, t->intr);
 460    if (t->flags & IS_VADEM)
 461        vg46x_set_state(s);
 462}
 463
 464static u_int __init set_bridge_opts(u_short s, u_short ns)
 465{
 466    u_short i;
 467    u_int m = 0xffff;
 468    char buf[128];
 469
 470    for (i = s; i < s+ns; i++) {
 471        if (socket[i].flags & IS_ALIVE) {
 472            printk(KERN_INFO "    host opts [%d]: already alive!\n", i);
 473            continue;
 474        }
 475        buf[0] = '\0';
 476        get_bridge_state(i);
 477        if (socket[i].flags & IS_CIRRUS)
 478            m = cirrus_set_opts(i, buf);
 479        else if (socket[i].flags & IS_VADEM)
 480            m = vg46x_set_opts(i, buf);
 481        set_bridge_state(i);
 482        printk(KERN_INFO "    host opts [%d]:%s\n", i,
 483               (*buf) ? buf : " none");
 484    }
 485    return m;
 486}
 487
 488/*======================================================================
 489
 490    Interrupt testing code, for ISA and PCI interrupts
 491    
 492======================================================================*/
 493
 494static volatile u_int irq_hits;
 495static u_short irq_sock;
 496
 497static void irq_count(int irq, void *dev, struct pt_regs *regs)
 498{
 499    i365_get(irq_sock, I365_CSC);
 500    irq_hits++;
 501    DEBUG(2, "-> hit on irq %d\n", irq);
 502}
 503
 504static u_int __init test_irq(u_short sock, int irq)
 505{
 506    DEBUG(2, "  testing ISA irq %d\n", irq);
 507    if (request_irq(irq, irq_count, 0, "scan", irq_count) != 0)
 508        return 1;
 509    irq_hits = 0; irq_sock = sock;
 510    __set_current_state(TASK_UNINTERRUPTIBLE);
 511    schedule_timeout(HZ/100);
 512    if (irq_hits) {
 513        free_irq(irq, irq_count);
 514        DEBUG(2, "    spurious hit!\n");
 515        return 1;
 516    }
 517
 518    /* Generate one interrupt */
 519    i365_set(sock, I365_CSCINT, I365_CSC_DETECT | (irq << 4));
 520    i365_bset(sock, I365_GENCTL, I365_CTL_SW_IRQ);
 521    udelay(1000);
 522
 523    free_irq(irq, irq_count);
 524
 525    /* mask all interrupts */
 526    i365_set(sock, I365_CSCINT, 0);
 527    DEBUG(2, "    hits = %d\n", irq_hits);
 528    
 529    return (irq_hits != 1);
 530}
 531
 532static u_int __init isa_scan(u_short sock, u_int mask0)
 533{
 534    u_int mask1 = 0;
 535    int i;
 536
 537#ifdef __alpha__
 538#define PIC 0x4d0
 539    /* Don't probe level-triggered interrupts -- reserved for PCI */
 540    mask0 &= ~(inb(PIC) | (inb(PIC+1) << 8));
 541#endif
 542    
 543    if (do_scan) {
 544        set_bridge_state(sock);
 545        i365_set(sock, I365_CSCINT, 0);
 546        for (i = 0; i < 16; i++)
 547            if ((mask0 & (1 << i)) && (test_irq(sock, i) == 0))
 548                mask1 |= (1 << i);
 549        for (i = 0; i < 16; i++)
 550            if ((mask1 & (1 << i)) && (test_irq(sock, i) != 0))
 551                mask1 ^= (1 << i);
 552    }
 553    
 554    printk(KERN_INFO "    ISA irqs (");
 555    if (mask1) {
 556        printk("scanned");
 557    } else {
 558        /* Fallback: just find interrupts that aren't in use */
 559        for (i = 0; i < 16; i++)
 560            if ((mask0 & (1 << i)) && (_check_irq(i, 0) == 0))
 561                mask1 |= (1 << i);
 562        printk("default");
 563        /* If scan failed, default to polled status */
 564        if (!cs_irq && (poll_interval == 0)) poll_interval = HZ;
 565    }
 566    printk(") = ");
 567    
 568    for (i = 0; i < 16; i++)
 569        if (mask1 & (1<<i))
 570            printk("%s%d", ((mask1 & ((1<<i)-1)) ? "," : ""), i);
 571    if (mask1 == 0) printk("none!");
 572    
 573    return mask1;
 574}
 575
 576/*====================================================================*/
 577
 578/* Time conversion functions */
 579
 580static int to_cycles(int ns)
 581{
 582    return ns/cycle_time;
 583}
 584
 585static int to_ns(int cycles)
 586{
 587    return cycle_time*cycles;
 588}
 589
 590/*====================================================================*/
 591
 592static int __init identify(u_short port, u_short sock)
 593{
 594    u_char val;
 595    int type = -1;
 596
 597    /* Use the next free entry in the socket table */
 598    socket[sockets].ioaddr = port;
 599    socket[sockets].psock = sock;
 600    
 601    /* Wake up a sleepy Cirrus controller */
 602    if (wakeup) {
 603        i365_bclr(sockets, PD67_MISC_CTL_2, PD67_MC2_SUSPEND);
 604        /* Pause at least 50 ms */
 605        mdelay(50);
 606    }
 607    
 608    if ((val = i365_get(sockets, I365_IDENT)) & 0x70)
 609        return -1;
 610    switch (val) {
 611    case 0x82:
 612        type = IS_I82365A; break;
 613    case 0x83:
 614        type = IS_I82365B; break;
 615    case 0x84:
 616        type = IS_I82365DF; break;
 617    case 0x88: case 0x89: case 0x8a:
 618        type = IS_IBM; break;
 619    }
 620    
 621    /* Check for Vadem VG-468 chips */
 622    outb(0x0e, port);
 623    outb(0x37, port);
 624    i365_bset(sockets, VG468_MISC, VG468_MISC_VADEMREV);
 625    val = i365_get(sockets, I365_IDENT);
 626    if (val & I365_IDENT_VADEM) {
 627        i365_bclr(sockets, VG468_MISC, VG468_MISC_VADEMREV);
 628        type = ((val & 7) >= 4) ? IS_VG469 : IS_VG468;
 629    }
 630
 631    /* Check for Ricoh chips */
 632    val = i365_get(sockets, RF5C_CHIP_ID);
 633    if ((val == RF5C_CHIP_RF5C296) || (val == RF5C_CHIP_RF5C396))
 634        type = IS_RF5Cx96;
 635    
 636    /* Check for Cirrus CL-PD67xx chips */
 637    i365_set(sockets, PD67_CHIP_INFO, 0);
 638    val = i365_get(sockets, PD67_CHIP_INFO);
 639    if ((val & PD67_INFO_CHIP_ID) == PD67_INFO_CHIP_ID) {
 640        val = i365_get(sockets, PD67_CHIP_INFO);
 641        if ((val & PD67_INFO_CHIP_ID) == 0) {
 642            type = (val & PD67_INFO_SLOTS) ? IS_PD672X : IS_PD6710;
 643            i365_set(sockets, PD67_EXT_INDEX, 0xe5);
 644            if (i365_get(sockets, PD67_EXT_INDEX) != 0xe5)
 645                type = IS_VT83C469;
 646        }
 647    }
 648    return type;
 649} /* identify */
 650
 651/*======================================================================
 652
 653    See if a card is present, powered up, in IO mode, and already
 654    bound to a (non PC Card) Linux driver.  We leave these alone.
 655
 656    We make an exception for cards that seem to be serial devices.
 657    
 658======================================================================*/
 659
 660static int __init is_alive(u_short sock)
 661{
 662    u_char stat;
 663    u_short start, stop;
 664    
 665    stat = i365_get(sock, I365_STATUS);
 666    start = i365_get_pair(sock, I365_IO(0)+I365_W_START);
 667    stop = i365_get_pair(sock, I365_IO(0)+I365_W_STOP);
 668    if ((stat & I365_CS_DETECT) && (stat & I365_CS_POWERON) &&
 669        (i365_get(sock, I365_INTCTL) & I365_PC_IOCARD) &&
 670        (i365_get(sock, I365_ADDRWIN) & I365_ENA_IO(0)) &&
 671        (check_region(start, stop-start+1) != 0) &&
 672        ((start & 0xfeef) != 0x02e8))
 673        return 1;
 674    else
 675        return 0;
 676}
 677
 678/*====================================================================*/
 679
 680static void __init add_socket(u_short port, int psock, int type)
 681{
 682    socket[sockets].ioaddr = port;
 683    socket[sockets].psock = psock;
 684    socket[sockets].type = type;
 685    socket[sockets].flags = pcic[type].flags;
 686    if (is_alive(sockets))
 687        socket[sockets].flags |= IS_ALIVE;
 688    sockets++;
 689}
 690
 691static void __init add_pcic(int ns, int type)
 692{
 693    u_int mask = 0, i, base;
 694    int isa_irq = 0;
 695    socket_info_t *t = &socket[sockets-ns];
 696
 697    base = sockets-ns;
 698    if (t->ioaddr > 0) request_region(t->ioaddr, 2, "i82365");
 699    
 700    if (base == 0) printk("\n");
 701    printk(KERN_INFO "  %s", pcic[type].name);
 702    printk(" ISA-to-PCMCIA at port %#x ofs 0x%02x",
 703               t->ioaddr, t->psock*0x40);
 704    printk(", %d socket%s\n", ns, ((ns > 1) ? "s" : ""));
 705
 706    /* Set host options, build basic interrupt mask */
 707    if (irq_list[0] == -1)
 708        mask = irq_mask;
 709    else
 710        for (i = mask = 0; i < 16; i++)
 711            mask |= (1<<irq_list[i]);
 712    mask &= I365_MASK & set_bridge_opts(base, ns);
 713    /* Scan for ISA interrupts */
 714    mask = isa_scan(base, mask);
 715        
 716    /* Poll if only two interrupts available */
 717    if (!poll_interval) {
 718        u_int tmp = (mask & 0xff20);
 719        tmp = tmp & (tmp-1);
 720        if ((tmp & (tmp-1)) == 0)
 721            poll_interval = HZ;
 722    }
 723    /* Only try an ISA cs_irq if this is the first controller */
 724    if (!grab_irq && (cs_irq || !poll_interval)) {
 725        /* Avoid irq 12 unless it is explicitly requested */
 726        u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12));
 727        for (cs_irq = 15; cs_irq > 0; cs_irq--)
 728            if ((cs_mask & (1 << cs_irq)) &&
 729                (_check_irq(cs_irq, 0) == 0))
 730                break;
 731        if (cs_irq) {
 732            grab_irq = 1;
 733            isa_irq = cs_irq;
 734            printk(" status change on irq %d\n", cs_irq);
 735        }
 736    }
 737    
 738    if (!isa_irq) {
 739        if (poll_interval == 0)
 740            poll_interval = HZ;
 741        printk(" polling interval = %d ms\n",
 742               poll_interval * 1000 / HZ);
 743        
 744    }
 745    
 746    /* Update socket interrupt information, capabilities */
 747    for (i = 0; i < ns; i++) {
 748        t[i].cap.features |= SS_CAP_PCCARD;
 749        t[i].cap.map_size = 0x1000;
 750        t[i].cap.irq_mask = mask;
 751        t[i].cs_irq = isa_irq;
 752    }
 753
 754} /* add_pcic */
 755
 756/*====================================================================*/
 757
 758#if defined(CONFIG_ISAPNP) || (defined(CONFIG_ISAPNP_MODULE) && defined(MODULE))
 759#define I82365_ISAPNP
 760#endif
 761
 762#ifdef I82365_ISAPNP
 763static struct isapnp_device_id id_table[] __initdata = {
 764        {       ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('P', 'N', 'P'),
 765                ISAPNP_FUNCTION(0x0e00), (unsigned long) "Intel 82365-Compatible" },
 766        {       ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('P', 'N', 'P'),
 767                ISAPNP_FUNCTION(0x0e01), (unsigned long) "Cirrus Logic CL-PD6720" },
 768        {       ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('P', 'N', 'P'),
 769                ISAPNP_FUNCTION(0x0e02), (unsigned long) "VLSI VL82C146" },
 770        {       0 }
 771};
 772MODULE_DEVICE_TABLE(isapnp, id_table);
 773
 774static struct pci_dev *i82365_pnpdev;
 775#endif
 776
 777static void __init isa_probe(void)
 778{
 779    int i, j, sock, k, ns, id;
 780    ioaddr_t port;
 781#ifdef I82365_ISAPNP
 782    struct isapnp_device_id *devid;
 783    struct pci_dev *dev;
 784
 785    for (devid = id_table; devid->vendor; devid++) {
 786        if ((dev = isapnp_find_dev(NULL, devid->vendor, devid->function, NULL))) {
 787            printk("ISAPNP ");
 788
 789            if (dev->prepare && dev->prepare(dev) < 0) {
 790                printk("prepare failed\n");
 791                break;
 792            }
 793
 794            if (dev->activate && dev->activate(dev) < 0) {
 795                printk("activate failed\n");
 796                break;
 797            }
 798
 799            if ((i365_base = pci_resource_start(dev, 0))) {
 800                printk("no resources ?\n");
 801                break;
 802            }
 803            i82365_pnpdev = dev;
 804            break;
 805        }
 806    }
 807#endif
 808
 809    if (check_region(i365_base, 2) != 0) {
 810        if (sockets == 0)
 811            printk("port conflict at %#x\n", i365_base);
 812        return;
 813    }
 814
 815    id = identify(i365_base, 0);
 816    if ((id == IS_I82365DF) && (identify(i365_base, 1) != id)) {
 817        for (i = 0; i < 4; i++) {
 818            if (i == ignore) continue;
 819            port = i365_base + ((i & 1) << 2) + ((i & 2) << 1);
 820            sock = (i & 1) << 1;
 821            if (identify(port, sock) == IS_I82365DF) {
 822                add_socket(port, sock, IS_VLSI);
 823                add_pcic(1, IS_VLSI);
 824            }
 825        }
 826    } else {
 827        for (i = 0; i < 8; i += 2) {
 828            if (sockets && !extra_sockets && (i == 4))
 829                break;
 830            port = i365_base + 2*(i>>2);
 831            sock = (i & 3);
 832            id = identify(port, sock);
 833            if (id < 0) continue;
 834
 835            for (j = ns = 0; j < 2; j++) {
 836                /* Does the socket exist? */
 837                if ((ignore == i+j) || (identify(port, sock+j) < 0))
 838                    continue;
 839                /* Check for bad socket decode */
 840                for (k = 0; k <= sockets; k++)
 841                    i365_set(k, I365_MEM(0)+I365_W_OFF, k);
 842                for (k = 0; k <= sockets; k++)
 843                    if (i365_get(k, I365_MEM(0)+I365_W_OFF) != k)
 844                        break;
 845                if (k <= sockets) break;
 846                add_socket(port, sock+j, id); ns++;
 847            }
 848            if (ns != 0) add_pcic(ns, id);
 849        }
 850    }
 851}
 852
 853/*====================================================================*/
 854
 855static u_int pending_events[8];
 856static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED;
 857
 858static void pcic_bh(void *dummy)
 859{
 860        u_int events;
 861        int i;
 862
 863        for (i=0; i < sockets; i++) {
 864                spin_lock_irq(&pending_event_lock);
 865                events = pending_events[i];
 866                pending_events[i] = 0;
 867                spin_unlock_irq(&pending_event_lock);
 868                /* 
 869                SS_DETECT events need a small delay here. The reason for this is that 
 870                the "is there a card" electronics need time to see the card after the
 871                "we have a card coming in" electronics have seen it. 
 872                */
 873                if (events & SS_DETECT) 
 874                        mdelay(4);
 875                if (socket[i].handler)
 876                        socket[i].handler(socket[i].info, events);
 877        }
 878}
 879
 880static struct tq_struct pcic_task = {
 881        routine:        pcic_bh
 882};
 883
 884static unsigned long last_detect_jiffies;
 885
 886static void pcic_interrupt(int irq, void *dev,
 887                                    struct pt_regs *regs)
 888{
 889    int i, j, csc;
 890    u_int events, active;
 891    u_long flags = 0;
 892    
 893    DEBUG(4, "i82365: pcic_interrupt(%d)\n", irq);
 894
 895    for (j = 0; j < 20; j++) {
 896        active = 0;
 897        for (i = 0; i < sockets; i++) {
 898            if (socket[i].cs_irq != irq)
 899                continue;
 900            ISA_LOCK(i, flags);
 901            csc = i365_get(i, I365_CSC);
 902            if ((csc == 0) || (!socket[i].handler) ||
 903                (i365_get(i, I365_IDENT) & 0x70)) {
 904                ISA_UNLOCK(i, flags);
 905                continue;
 906            }
 907            events = (csc & I365_CSC_DETECT) ? SS_DETECT : 0;
 908            
 909            
 910            /* Several sockets will send multiple "new card detected"
 911               events in rapid succession. However, the rest of the pcmcia expects 
 912               only one such event. We just ignore these events by having a
 913               timeout */
 914
 915            if (events) {
 916                if ((jiffies - last_detect_jiffies)<(HZ/20)) 
 917                        events = 0;
 918                last_detect_jiffies = jiffies;
 919                
 920            }
 921        
 922            if (i365_get(i, I365_INTCTL) & I365_PC_IOCARD)
 923                events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0;
 924            else {
 925                events |= (csc & I365_CSC_BVD1) ? SS_BATDEAD : 0;
 926                events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0;
 927                events |= (csc & I365_CSC_READY) ? SS_READY : 0;
 928            }
 929            ISA_UNLOCK(i, flags);
 930            DEBUG(2, "i82365: socket %d event 0x%02x\n", i, events);
 931
 932            if (events) {
 933                    spin_lock(&pending_event_lock);
 934                    pending_events[i] |= events;
 935                    spin_unlock(&pending_event_lock);
 936                    schedule_task(&pcic_task);
 937            }
 938            active |= events;
 939        }
 940        if (!active) break;
 941    }
 942    if (j == 20)
 943        printk(KERN_NOTICE "i82365: infinite loop in interrupt handler\n");
 944
 945    DEBUG(4, "i82365: interrupt done\n");
 946} /* pcic_interrupt */
 947
 948static void pcic_interrupt_wrapper(u_long data)
 949{
 950    pcic_interrupt(0, NULL, NULL);
 951    poll_timer.expires = jiffies + poll_interval;
 952    add_timer(&poll_timer);
 953}
 954
 955/*====================================================================*/
 956
 957static int pcic_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void * info)
 958{
 959    socket[sock].handler = handler;
 960    socket[sock].info = info;
 961    if (handler == NULL) {
 962        MOD_DEC_USE_COUNT;
 963    } else {
 964        MOD_INC_USE_COUNT;
 965    }
 966    return 0;
 967} /* pcic_register_callback */
 968
 969/*====================================================================*/
 970
 971static int pcic_inquire_socket(unsigned int sock, socket_cap_t *cap)
 972{
 973    *cap = socket[sock].cap;
 974    return 0;
 975} /* pcic_inquire_socket */
 976
 977/*====================================================================*/
 978
 979static int i365_get_status(u_short sock, u_int *value)
 980{
 981    u_int status;
 982    
 983    status = i365_get(sock, I365_STATUS);
 984    *value = ((status & I365_CS_DETECT) == I365_CS_DETECT)
 985        ? SS_DETECT : 0;
 986        
 987    if (i365_get(sock, I365_INTCTL) & I365_PC_IOCARD)
 988        *value |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG;
 989    else {
 990        *value |= (status & I365_CS_BVD1) ? 0 : SS_BATDEAD;
 991        *value |= (status & I365_CS_BVD2) ? 0 : SS_BATWARN;
 992    }
 993    *value |= (status & I365_CS_WRPROT) ? SS_WRPROT : 0;
 994    *value |= (status & I365_CS_READY) ? SS_READY : 0;
 995    *value |= (status & I365_CS_POWERON) ? SS_POWERON : 0;
 996
 997    if (socket[sock].type == IS_VG469) {
 998        status = i365_get(sock, VG469_VSENSE);
 999        if (socket[sock].psock & 1) {
1000            *value |= (status & VG469_VSENSE_B_VS1) ? 0 : SS_3VCARD;
1001            *value |= (status & VG469_VSENSE_B_VS2) ? 0 : SS_XVCARD;
1002        } else {
1003            *value |= (status & VG469_VSENSE_A_VS1) ? 0 : SS_3VCARD;
1004            *value |= (status & VG469_VSENSE_A_VS2) ? 0 : SS_XVCARD;
1005        }
1006    }
1007    
1008    DEBUG(1, "i82365: GetStatus(%d) = %#4.4x\n", sock, *value);
1009    return 0;
1010} /* i365_get_status */
1011
1012/*====================================================================*/
1013
1014static int i365_get_socket(u_short sock, socket_state_t *state)
1015{
1016    socket_info_t *t = &socket[sock];
1017    u_char reg, vcc, vpp;
1018    
1019    reg = i365_get(sock, I365_POWER);
1020    state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0;
1021    state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0;
1022    vcc = reg & I365_VCC_MASK; vpp = reg & I365_VPP1_MASK;
1023    state->Vcc = state->Vpp = 0;
1024    if (t->flags & IS_CIRRUS) {
1025        if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_VCC_3V) {
1026            if (reg & I365_VCC_5V) state->Vcc = 33;
1027            if (vpp == I365_VPP1_5V) state->Vpp = 33;
1028        } else {
1029            if (reg & I365_VCC_5V) state->Vcc = 50;
1030            if (vpp == I365_VPP1_5V) state->Vpp = 50;
1031        }
1032        if (vpp == I365_VPP1_12V) state->Vpp = 120;
1033    } else if (t->flags & IS_VG_PWR) {
1034        if (i365_get(sock, VG469_VSELECT) & VG469_VSEL_VCC) {
1035            if (reg & I365_VCC_5V) state->Vcc = 33;
1036            if (vpp == I365_VPP1_5V) state->Vpp = 33;
1037        } else {
1038            if (reg & I365_VCC_5V) state->Vcc = 50;
1039            if (vpp == I365_VPP1_5V) state->Vpp = 50;
1040        }
1041        if (vpp == I365_VPP1_12V) state->Vpp = 120;
1042    } else if (t->flags & IS_DF_PWR) {
1043        if (vcc == I365_VCC_3V) state->Vcc = 33;
1044        if (vcc == I365_VCC_5V) state->Vcc = 50;
1045        if (vpp == I365_VPP1_5V) state->Vpp = 50;
1046        if (vpp == I365_VPP1_12V) state->Vpp = 120;
1047    } else {
1048        if (reg & I365_VCC_5V) {
1049            state->Vcc = 50;
1050            if (vpp == I365_VPP1_5V) state->Vpp = 50;
1051            if (vpp == I365_VPP1_12V) state->Vpp = 120;
1052        }
1053    }
1054
1055    /* IO card, RESET flags, IO interrupt */
1056    reg = i365_get(sock, I365_INTCTL);
1057    state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET;
1058    if (reg & I365_PC_IOCARD) state->flags |= SS_IOCARD;
1059    state->io_irq = reg & I365_IRQ_MASK;
1060    
1061    /* speaker control */
1062    if (t->flags & IS_CIRRUS) {
1063        if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_SPKR_ENA)
1064            state->flags |= SS_SPKR_ENA;
1065    }
1066    
1067    /* Card status change mask */
1068    reg = i365_get(sock, I365_CSCINT);
1069    state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0;
1070    if (state->flags & SS_IOCARD)
1071        state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0;
1072    else {
1073        state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0;
1074        state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0;
1075        state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0;
1076    }
1077    
1078    DEBUG(1, "i82365: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
1079          "io_irq %d, csc_mask %#2.2x\n", sock, state->flags,
1080          state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
1081    return 0;
1082} /* i365_get_socket */
1083
1084/*====================================================================*/
1085
1086static int i365_set_socket(u_short sock, socket_state_t *state)
1087{
1088    socket_info_t *t = &socket[sock];
1089    u_char reg;
1090    
1091    DEBUG(1, "i82365: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
1092          "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
1093          state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
1094    
1095    /* First set global controller options */
1096    set_bridge_state(sock);
1097    
1098    /* IO card, RESET flag, IO interrupt */
1099    reg = t->intr;
1100    reg |= state->io_irq;
1101    reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
1102    reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
1103    i365_set(sock, I365_INTCTL, reg);
1104    
1105    reg = I365_PWR_NORESET;
1106    if (state->flags & SS_PWR_AUTO) reg |= I365_PWR_AUTO;
1107    if (state->flags & SS_OUTPUT_ENA) reg |= I365_PWR_OUT;
1108
1109    if (t->flags & IS_CIRRUS) {
1110        if (state->Vpp != 0) {
1111            if (state->Vpp == 120)
1112                reg |= I365_VPP1_12V;
1113            else if (state->Vpp == state->Vcc)
1114                reg |= I365_VPP1_5V;
1115            else return -EINVAL;
1116        }
1117        if (state->Vcc != 0) {
1118            reg |= I365_VCC_5V;
1119            if (state->Vcc == 33)
1120                i365_bset(sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
1121            else if (state->Vcc == 50)
1122                i365_bclr(sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
1123            else return -EINVAL;
1124        }
1125    } else if (t->flags & IS_VG_PWR) {
1126        if (state->Vpp != 0) {
1127            if (state->Vpp == 120)
1128                reg |= I365_VPP1_12V;
1129            else if (state->Vpp == state->Vcc)
1130                reg |= I365_VPP1_5V;
1131            else return -EINVAL;
1132        }
1133        if (state->Vcc != 0) {
1134            reg |= I365_VCC_5V;
1135            if (state->Vcc == 33)
1136                i365_bset(sock, VG469_VSELECT, VG469_VSEL_VCC);
1137            else if (state->Vcc == 50)
1138                i365_bclr(sock, VG469_VSELECT, VG469_VSEL_VCC);
1139            else return -EINVAL;
1140        }
1141    } else if (t->flags & IS_DF_PWR) {
1142        switch (state->Vcc) {
1143        case 0:         break;
1144        case 33:        reg |= I365_VCC_3V; break;
1145        case 50:        reg |= I365_VCC_5V; break;
1146        default:        return -EINVAL;
1147        }
1148        switch (state->Vpp) {
1149        case 0:         break;
1150        case 50:        reg |= I365_VPP1_5V; break;
1151        case 120:       reg |= I365_VPP1_12V; break;
1152        default:        return -EINVAL;
1153        }
1154    } else {
1155        switch (state->Vcc) {
1156        case 0:         break;
1157        case 50:        reg |= I365_VCC_5V; break;
1158        default:        return -EINVAL;
1159        }
1160        switch (state->Vpp) {
1161        case 0:         break;
1162        case 50:        reg |= I365_VPP1_5V | I365_VPP2_5V; break;
1163        case 120:       reg |= I365_VPP1_12V | I365_VPP2_12V; break;
1164        default:        return -EINVAL;
1165        }
1166    }
1167    
1168    if (reg != i365_get(sock, I365_POWER))
1169        i365_set(sock, I365_POWER, reg);
1170
1171    /* Chipset-specific functions */
1172    if (t->flags & IS_CIRRUS) {
1173        /* Speaker control */
1174        i365_bflip(sock, PD67_MISC_CTL_1, PD67_MC1_SPKR_ENA,
1175                   state->flags & SS_SPKR_ENA);
1176    }
1177    
1178    /* Card status change interrupt mask */
1179    reg = t->cs_irq << 4;
1180    if (state->csc_mask & SS_DETECT) reg |= I365_CSC_DETECT;
1181    if (state->flags & SS_IOCARD) {
1182        if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG;
1183    } else {
1184        if (state->csc_mask & SS_BATDEAD) reg |= I365_CSC_BVD1;
1185        if (state->csc_mask & SS_BATWARN) reg |= I365_CSC_BVD2;
1186        if (state->csc_mask & SS_READY) reg |= I365_CSC_READY;
1187    }
1188    i365_set(sock, I365_CSCINT, reg);
1189    i365_get(sock, I365_CSC);
1190    
1191    return 0;
1192} /* i365_set_socket */
1193
1194/*====================================================================*/
1195
1196static int i365_get_io_map(u_short sock, struct pccard_io_map *io)
1197{
1198    u_char map, ioctl, addr;
1199    
1200    map = io->map;
1201    if (map > 1) return -EINVAL;
1202    io->start = i365_get_pair(sock, I365_IO(map)+I365_W_START);
1203    io->stop = i365_get_pair(sock, I365_IO(map)+I365_W_STOP);
1204    ioctl = i365_get(sock, I365_IOCTL);
1205    addr = i365_get(sock, I365_ADDRWIN);
1206    io->speed = to_ns(ioctl & I365_IOCTL_WAIT(map)) ? 1 : 0;
1207    io->flags  = (addr & I365_ENA_IO(map)) ? MAP_ACTIVE : 0;
1208    io->flags |= (ioctl & I365_IOCTL_0WS(map)) ? MAP_0WS : 0;
1209    io->flags |= (ioctl & I365_IOCTL_16BIT(map)) ? MAP_16BIT : 0;
1210    io->flags |= (ioctl & I365_IOCTL_IOCS16(map)) ? MAP_AUTOSZ : 0;
1211    DEBUG(1, "i82365: GetIOMap(%d, %d) = %#2.2x, %d ns, "
1212          "%#4.4x-%#4.4x\n", sock, map, io->flags, io->speed,
1213          io->start, io->stop);
1214    return 0;
1215} /* i365_get_io_map */
1216
1217/*====================================================================*/
1218
1219static int i365_set_io_map(u_short sock, struct pccard_io_map *io)
1220{
1221    u_char map, ioctl;
1222    
1223    DEBUG(1, "i82365: SetIOMap(%d, %d, %#2.2x, %d ns, "
1224          "%#4.4x-%#4.4x)\n", sock, io->map, io->flags,
1225          io->speed, io->start, io->stop);
1226    map = io->map;
1227    if ((map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
1228        (io->stop < io->start)) return -EINVAL;
1229    /* Turn off the window before changing anything */
1230    if (i365_get(sock, I365_ADDRWIN) & I365_ENA_IO(map))
1231        i365_bclr(sock, I365_ADDRWIN, I365_ENA_IO(map));
1232    i365_set_pair(sock, I365_IO(map)+I365_W_START, io->start);
1233    i365_set_pair(sock, I365_IO(map)+I365_W_STOP, io->stop);
1234    ioctl = i365_get(sock, I365_IOCTL) & ~I365_IOCTL_MASK(map);
1235    if (io->speed) ioctl |= I365_IOCTL_WAIT(map);
1236    if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map);
1237    if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map);
1238    if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map);
1239    i365_set(sock, I365_IOCTL, ioctl);
1240    /* Turn on the window if necessary */
1241    if (io->flags & MAP_ACTIVE)
1242        i365_bset(sock, I365_ADDRWIN, I365_ENA_IO(map));
1243    return 0;
1244} /* i365_set_io_map */
1245
1246/*====================================================================*/
1247
1248static int i365_get_mem_map(u_short sock, struct pccard_mem_map *mem)
1249{
1250    u_short base, i;
1251    u_char map, addr;
1252    
1253    map = mem->map;
1254    if (map > 4) return -EINVAL;
1255    addr = i365_get(sock, I365_ADDRWIN);
1256    mem->flags = (addr & I365_ENA_MEM(map)) ? MAP_ACTIVE : 0;
1257    base = I365_MEM(map);
1258    
1259    i = i365_get_pair(sock, base+I365_W_START);
1260    mem->flags |= (i & I365_MEM_16BIT) ? MAP_16BIT : 0;
1261    mem->flags |= (i & I365_MEM_0WS) ? MAP_0WS : 0;
1262    mem->sys_start = ((u_long)(i & 0x0fff) << 12);
1263    
1264    i = i365_get_pair(sock, base+I365_W_STOP);
1265    mem->speed  = (i & I365_MEM_WS0) ? 1 : 0;
1266    mem->speed += (i & I365_MEM_WS1) ? 2 : 0;
1267    mem->speed = to_ns(mem->speed);
1268    mem->sys_stop = ((u_long)(i & 0x0fff) << 12) + 0x0fff;
1269    
1270    i = i365_get_pair(sock, base+I365_W_OFF);
1271    mem->flags |= (i & I365_MEM_WRPROT) ? MAP_WRPROT : 0;
1272    mem->flags |= (i & I365_MEM_REG) ? MAP_ATTRIB : 0;
1273    mem->card_start = ((u_int)(i & 0x3fff) << 12) + mem->sys_start;
1274    mem->card_start &= 0x3ffffff;
1275    
1276    DEBUG(1, "i82365: GetMemMap(%d, %d) = %#2.2x, %d ns, %#5.5lx-%#5."
1277          "5lx, %#5.5x\n", sock, mem->map, mem->flags, mem->speed,
1278          mem->sys_start, mem->sys_stop, mem->card_start);
1279    return 0;
1280} /* i365_get_mem_map */
1281
1282/*====================================================================*/
1283  
1284static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem)
1285{
1286    u_short base, i;
1287    u_char map;
1288    
1289    DEBUG(1, "i82365: SetMemMap(%d, %d, %#2.2x, %d ns, %#5.5lx-%#5.5"
1290          "lx, %#5.5x)\n", sock, mem->map, mem->flags, mem->speed,
1291          mem->sys_start, mem->sys_stop, mem->card_start);
1292
1293    map = mem->map;
1294    if ((map > 4) || (mem->card_start > 0x3ffffff) ||
1295        (mem->sys_start > mem->sys_stop) || (mem->speed > 1000))
1296        return -EINVAL;
1297    if ((mem->sys_start > 0xffffff) || (mem->sys_stop > 0xffffff))
1298        return -EINVAL;
1299        
1300    /* Turn off the window before changing anything */
1301    if (i365_get(sock, I365_ADDRWIN) & I365_ENA_MEM(map))
1302        i365_bclr(sock, I365_ADDRWIN, I365_ENA_MEM(map));
1303    
1304    base = I365_MEM(map);
1305    i = (mem->sys_start >> 12) & 0x0fff;
1306    if (mem->flags & MAP_16BIT) i |= I365_MEM_16BIT;
1307    if (mem->flags & MAP_0WS) i |= I365_MEM_0WS;
1308    i365_set_pair(sock, base+I365_W_START, i);
1309    
1310    i = (mem->sys_stop >> 12) & 0x0fff;
1311    switch (to_cycles(mem->speed)) {
1312    case 0:     break;
1313    case 1:     i |= I365_MEM_WS0; break;
1314    case 2:     i |= I365_MEM_WS1; break;
1315    default:    i |= I365_MEM_WS1 | I365_MEM_WS0; break;
1316    }
1317    i365_set_pair(sock, base+I365_W_STOP, i);
1318    
1319    i = ((mem->card_start - mem->sys_start) >> 12) & 0x3fff;
1320    if (mem->flags & MAP_WRPROT) i |= I365_MEM_WRPROT;
1321    if (mem->flags & MAP_ATTRIB) i |= I365_MEM_REG;
1322    i365_set_pair(sock, base+I365_W_OFF, i);
1323    
1324    /* Turn on the window if necessary */
1325    if (mem->flags & MAP_ACTIVE)
1326        i365_bset(sock, I365_ADDRWIN, I365_ENA_MEM(map));
1327    return 0;
1328} /* i365_set_mem_map */
1329
1330/*======================================================================
1331
1332    Routines for accessing socket information and register dumps via
1333    /proc/bus/pccard/...
1334    
1335======================================================================*/
1336
1337#ifdef CONFIG_PROC_FS
1338
1339static int proc_read_info(char *buf, char **start, off_t pos,
1340                          int count, int *eof, void *data)
1341{
1342    socket_info_t *s = data;
1343    char *p = buf;
1344    p += sprintf(p, "type:     %s\npsock:    %d\n",
1345                 pcic[s->type].name, s->psock);
1346    return (p - buf);
1347}
1348
1349static int proc_read_exca(char *buf, char **start, off_t pos,
1350                          int count, int *eof, void *data)
1351{
1352    u_short sock = (socket_info_t *)data - socket;
1353    char *p = buf;
1354    int i, top;
1355    
1356    u_long flags = 0;
1357    ISA_LOCK(sock, flags);
1358    top = 0x40;
1359    for (i = 0; i < top; i += 4) {
1360        if (i == 0x50) {
1361            p += sprintf(p, "\n");
1362            i = 0x100;
1363        }
1364        p += sprintf(p, "%02x %02x %02x %02x%s",
1365                     i365_get(sock,i), i365_get(sock,i+1),
1366                     i365_get(sock,i+2), i365_get(sock,i+3),
1367                     ((i % 16) == 12) ? "\n" : " ");
1368    }
1369    ISA_UNLOCK(sock, flags);
1370    return (p - buf);
1371}
1372
1373static void pcic_proc_setup(unsigned int sock, struct proc_dir_entry *base)
1374{
1375    socket_info_t *s = &socket[sock];
1376
1377    if (s->flags & IS_ALIVE)
1378        return;
1379
1380    create_proc_read_entry("info", 0, base, proc_read_info, s);
1381    create_proc_read_entry("exca", 0, base, proc_read_exca, s);
1382    s->proc = base;
1383}
1384
1385static void pcic_proc_remove(u_short sock)
1386{
1387    struct proc_dir_entry *base = socket[sock].proc;
1388    if (base == NULL) return;
1389    remove_proc_entry("info", base);
1390    remove_proc_entry("exca", base);
1391}
1392
1393#else
1394
1395#define pcic_proc_setup NULL
1396
1397#endif /* CONFIG_PROC_FS */
1398
1399/*====================================================================*/
1400
1401/* this is horribly ugly... proper locking needs to be done here at 
1402 * some time... */
1403#define LOCKED(x) do { \
1404        int retval; \
1405        unsigned long flags; \
1406        spin_lock_irqsave(&isa_lock, flags); \
1407        retval = x; \
1408        spin_unlock_irqrestore(&isa_lock, flags); \
1409        return retval; \
1410} while (0)
1411
1412static int pcic_get_status(unsigned int sock, u_int *value)
1413{
1414        if (socket[sock].flags & IS_ALIVE) {
1415                *value = 0;
1416                return -EINVAL;
1417        }
1418
1419        LOCKED(i365_get_status(sock, value));
1420}
1421
1422static int pcic_get_socket(unsigned int sock, socket_state_t *state)
1423{
1424        if (socket[sock].flags & IS_ALIVE)
1425                return -EINVAL;
1426
1427        LOCKED(i365_get_socket(sock, state));
1428}
1429
1430static int pcic_set_socket(unsigned int sock, socket_state_t *state)
1431{
1432        if (socket[sock].flags & IS_ALIVE)
1433                return -EINVAL;
1434
1435        LOCKED(i365_set_socket(sock, state));
1436}
1437
1438static int pcic_get_io_map(unsigned int sock, struct pccard_io_map *io)
1439{
1440        if (socket[sock].flags & IS_ALIVE)
1441                return -EINVAL;
1442
1443        LOCKED(i365_get_io_map(sock, io));
1444}
1445
1446static int pcic_set_io_map(unsigned int sock, struct pccard_io_map *io)
1447{
1448        if (socket[sock].flags & IS_ALIVE)
1449                return -EINVAL;
1450
1451        LOCKED(i365_set_io_map(sock, io));
1452}
1453
1454static int pcic_get_mem_map(unsigned int sock, struct pccard_mem_map *mem)
1455{
1456        if (socket[sock].flags & IS_ALIVE)
1457                return -EINVAL;
1458
1459        LOCKED(i365_get_mem_map(sock, mem));
1460}
1461
1462static int pcic_set_mem_map(unsigned int sock, struct pccard_mem_map *mem)
1463{
1464        if (socket[sock].flags & IS_ALIVE)
1465                return -EINVAL;
1466
1467        LOCKED(i365_set_mem_map(sock, mem));
1468}
1469
1470static int pcic_init(unsigned int s)
1471{
1472        int i;
1473        pccard_io_map io = { 0, 0, 0, 0, 1 };
1474        pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
1475
1476        mem.sys_stop = 0x1000;
1477        pcic_set_socket(s, &dead_socket);
1478        for (i = 0; i < 2; i++) {
1479                io.map = i;
1480                pcic_set_io_map(s, &io);
1481        }
1482        for (i = 0; i < 5; i++) {
1483                mem.map = i;
1484                pcic_set_mem_map(s, &mem);
1485        }
1486        return 0;
1487}
1488
1489static int pcic_suspend(unsigned int sock)
1490{
1491        return pcic_set_socket(sock, &dead_socket);
1492}
1493
1494static struct pccard_operations pcic_operations = {
1495        pcic_init,
1496        pcic_suspend,
1497        pcic_register_callback,
1498        pcic_inquire_socket,
1499        pcic_get_status,
1500        pcic_get_socket,
1501        pcic_set_socket,
1502        pcic_get_io_map,
1503        pcic_set_io_map,
1504        pcic_get_mem_map,
1505        pcic_set_mem_map,
1506        pcic_proc_setup
1507};
1508
1509/*====================================================================*/
1510
1511static int __init init_i82365(void)
1512{
1513    servinfo_t serv;
1514    pcmcia_get_card_services_info(&serv);
1515    if (serv.Revision != CS_RELEASE_CODE) {
1516        printk(KERN_NOTICE "i82365: Card Services release "
1517               "does not match!\n");
1518        return -1;
1519    }
1520    DEBUG(0, "%s\n", version);
1521    printk(KERN_INFO "Intel ISA PCIC probe: ");
1522    sockets = 0;
1523
1524    isa_probe();
1525
1526    if (sockets == 0) {
1527        printk("not found.\n");
1528        return -ENODEV;
1529    }
1530
1531    /* Set up interrupt handler(s) */
1532    if (grab_irq != 0)
1533        request_irq(cs_irq, pcic_interrupt, 0, "i82365", pcic_interrupt);
1534    
1535    if (register_ss_entry(sockets, &pcic_operations) != 0)
1536        printk(KERN_NOTICE "i82365: register_ss_entry() failed\n");
1537
1538    /* Finally, schedule a polling interrupt */
1539    if (poll_interval != 0) {
1540        poll_timer.function = pcic_interrupt_wrapper;
1541        poll_timer.data = 0;
1542        init_timer(&poll_timer);
1543        poll_timer.expires = jiffies + poll_interval;
1544        add_timer(&poll_timer);
1545    }
1546    
1547    return 0;
1548    
1549} /* init_i82365 */
1550
1551static void __exit exit_i82365(void)
1552{
1553    int i;
1554#ifdef CONFIG_PROC_FS
1555    for (i = 0; i < sockets; i++) pcic_proc_remove(i);
1556#endif
1557    unregister_ss_entry(&pcic_operations);
1558    if (poll_interval != 0)
1559        del_timer(&poll_timer);
1560    if (grab_irq != 0)
1561        free_irq(cs_irq, pcic_interrupt);
1562    for (i = 0; i < sockets; i++) {
1563        /* Turn off all interrupt sources! */
1564        i365_set(i, I365_CSCINT, 0);
1565        release_region(socket[i].ioaddr, 2);
1566    }
1567#if defined(I82365_ISAPNP)
1568    if (i82365_pnpdev && i82365_pnpdev->deactivate)
1569                i82365_pnpdev->deactivate(i82365_pnpdev);
1570#endif
1571} /* exit_i82365 */
1572
1573module_init(init_i82365);
1574module_exit(exit_i82365);
1575MODULE_LICENSE("Dual MPL/GPL");
1576/*====================================================================*/
1577
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.