The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/pccard/pcic.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  *  Intel PCIC or compatible Controller driver
    3  *  May be built to make a loadable module.
    4  *-------------------------------------------------------------------------
    5  *
    6  * Copyright (c) 1995 Andrew McRae.  All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. The name of the author may not be used to endorse or promote products
   17  *    derived from this software without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   29  *
   30  * $FreeBSD$
   31  */
   32 
   33 /*
   34  * pcic98 : PC9801 original PCMCIA controller code for NS/A,Ne,NX/C,NR/L.
   35  * by Noriyuki Hosobuchi <yj8n-hsbc@asahi-net.or.jp>
   36  */
   37 
   38 #include <sys/param.h>
   39 #include <sys/systm.h>
   40 #include <sys/kernel.h>
   41 #include <sys/module.h>
   42 #include <sys/select.h>
   43 #include <sys/interrupt.h>
   44 
   45 #include <machine/clock.h>
   46 
   47 #include <i386/isa/icu.h>
   48 #include <i386/isa/isa_device.h>
   49 
   50 #include <pccard/i82365.h>
   51 #ifdef  PC98
   52 #include <pccard/pcic98reg.h>
   53 #endif
   54 
   55 #include <pccard/cardinfo.h>
   56 #include <pccard/driver.h>
   57 #include <pccard/slot.h>
   58 
   59 #ifdef APIC_IO
   60 #include <machine/smp.h>
   61 #endif /* APIC_IO */
   62 /*
   63  *      Prototypes for interrupt handler.
   64  */
   65 static inthand2_t       pcicintr;
   66 static int              pcic_ioctl __P((struct slot *, int, caddr_t));
   67 static int              pcic_power __P((struct slot *));
   68 static timeout_t        pcic_reset;
   69 static void             pcic_resume(struct slot *);
   70 static void             pcic_disable __P((struct slot *));
   71 static void             pcic_mapirq __P((struct slot *, int));
   72 static timeout_t        pcictimeout;
   73 static struct callout_handle pcictimeout_ch
   74     = CALLOUT_HANDLE_INITIALIZER(&pcictimeout_ch);
   75 static int              pcic_modevent __P((module_t, int, void *));
   76 static int              pcic_unload __P((void));
   77 static int              pcic_memory(struct slot *, int);
   78 static int              pcic_io(struct slot *, int);
   79 static u_int            build_freelist(u_int);
   80 
   81 /*
   82  *      Per-slot data table.
   83  */
   84 static struct pcic_slot {
   85         int slotnum;                    /* My slot number */
   86         int index;                      /* Index register */
   87         int data;                       /* Data register */
   88         int offset;                     /* Offset value for index */
   89         char controller;                /* Device type */
   90         char revision;                  /* Device Revision */
   91         struct slot *slt;               /* Back ptr to slot */
   92         u_char (*getb)(struct pcic_slot *, int);
   93         void   (*putb)(struct pcic_slot *, int, u_char);
   94         u_char  *regs;                  /* Pointer to regs in mem */
   95 } pcic_slots[PCIC_MAX_SLOTS];
   96 
   97 static int              pcic_irq;
   98 static unsigned         pcic_imask;
   99 static struct slot_ctrl cinfo;
  100 
  101 
  102 /*
  103  *      Internal inline functions for accessing the PCIC.
  104  */
  105 /*
  106  * Read a register from the PCIC.
  107  */
  108 static __inline unsigned char
  109 getb1(struct pcic_slot *sp, int reg)
  110 {
  111         outb(sp->index, sp->offset + reg);
  112         return inb(sp->data);
  113 }
  114 
  115 static __inline unsigned char
  116 getb2(struct pcic_slot *sp, int reg)
  117 {
  118         return (sp->regs[reg]);
  119 }
  120 
  121 /*
  122  * Write a register on the PCIC
  123  */
  124 static __inline void
  125 putb1(struct pcic_slot *sp, int reg, unsigned char val)
  126 {
  127         outb(sp->index, sp->offset + reg);
  128         outb(sp->data, val);
  129 }
  130 
  131 static __inline void
  132 putb2(struct pcic_slot *sp, int reg, unsigned char val)
  133 {
  134         sp->regs[reg] = val;
  135 }
  136 
  137 /*
  138  * Clear bit(s) of a register.
  139  */
  140 static __inline void
  141 clrb(struct pcic_slot *sp, int reg, unsigned char mask)
  142 {
  143         sp->putb(sp, reg, sp->getb(sp, reg) & ~mask);
  144 }
  145 
  146 /*
  147  * Set bit(s) of a register
  148  */
  149 static __inline void
  150 setb(struct pcic_slot *sp, int reg, unsigned char mask)
  151 {
  152         sp->putb(sp, reg, sp->getb(sp, reg) | mask);
  153 }
  154 
  155 /*
  156  * Write a 16 bit value to 2 adjacent PCIC registers
  157  */
  158 static __inline void
  159 putw(struct pcic_slot *sp, int reg, unsigned short word)
  160 {
  161         sp->putb(sp, reg, word & 0xFF);
  162         sp->putb(sp, reg + 1, (word >> 8) & 0xff);
  163 }
  164 
  165 
  166 /*
  167  *      Loadable kernel module interface.
  168  */
  169 
  170 /*
  171  *      Module handler that processes loads and unloads.
  172  *      Once the module is loaded, the probe routine
  173  *      is called to install the slots (if any).
  174  */
  175 static int
  176 pcic_modevent(module_t mod, int what, void *arg)
  177 {
  178         int err = 0;    /* default = success*/
  179         static int pcic_started = 0;
  180 
  181         switch (what) {
  182         case MOD_LOAD:
  183 
  184                 /*
  185                  *      Call the probe routine to find the slots. If
  186                  *      no slots exist, then don't bother loading the module.
  187                  *      XXX but this is not appropriate as a static module.
  188                  */
  189                 if (pcic_probe())
  190                         pcic_started = 1;
  191                 break;
  192 
  193         case MOD_UNLOAD:
  194                 /*
  195                  *      Attempt to unload the slot driver.
  196                  */
  197                 if (pcic_started) {
  198                         printf("Unloading PCIC driver\n");
  199                         err = pcic_unload();
  200                         pcic_started = 0;
  201                 }
  202                 break;          /* Success*/
  203 
  204         default:        /* we only care about load/unload; ignore shutdown */
  205                 break;
  206         }
  207 
  208         return(err);
  209 }
  210 
  211 static moduledata_t pcic_mod = {
  212         "pcic",
  213         pcic_modevent,
  214         0
  215 };
  216 
  217 /* After configure() has run..  bring on the new bus system! */
  218 DECLARE_MODULE(pcic, pcic_mod, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE);
  219 
  220 /*
  221  *      pcic_unload - Called when unloading a LKM.
  222  *      Disables interrupts and resets PCIC.
  223  */
  224 static int
  225 pcic_unload()
  226 {
  227         int     slot;
  228         struct pcic_slot *sp = pcic_slots;
  229 
  230         untimeout(pcictimeout, 0, pcictimeout_ch);
  231         if (pcic_irq) {
  232                 for (slot = 0; slot < PCIC_MAX_SLOTS; slot++, sp++) {
  233                         if (sp->slt)
  234                                 sp->putb(sp, PCIC_STAT_INT, 0);
  235                 }
  236                 unregister_intr(pcic_irq, pcicintr);
  237         }
  238         pccard_remove_controller(&cinfo);
  239         return(0);
  240 }
  241 
  242 
  243 #if 0
  244 static void
  245 pcic_dump_attributes(unsigned char *scratch, int maxlen)
  246 {
  247         int i,j,k;
  248 
  249         i = 0;
  250         while (scratch[i] != 0xff && i < maxlen) {
  251                 unsigned char link = scratch[i+2];
  252 
  253                 /*
  254                  *      Dump attribute memory
  255                  */
  256                 if (scratch[i]) {
  257                         printf("[%02x] ", i);
  258                         for (j = 0; j < 2 * link + 4 && j < 128; j += 2)
  259                                 printf("%02x ", scratch[j + i]);
  260                         printf("\n");
  261                 }
  262                 i += 4 + 2 * link;
  263         }
  264 }
  265 #endif
  266 
  267 static void
  268 nullfunc(void *unused)
  269 {
  270         /* empty */
  271 }
  272 
  273 static u_int
  274 build_freelist(u_int pcic_mask)
  275 { 
  276         int irq;
  277         u_int mask, freemask; 
  278  
  279         /* No free IRQs (yet). */ 
  280         freemask = 0; 
  281  
  282         /* Walk through all of the IRQ's and find any that aren't allocated. */ 
  283         for (irq = 1; irq < ICU_LEN; irq++) { 
  284                 /* 
  285                  * If the PCIC controller can't generate it, don't
  286                  * bother checking to see if it it's free. 
  287                  */ 
  288                 mask = 1 << irq; 
  289                 if (!(mask & pcic_mask)) continue; 
  290 
  291 #ifdef APIC_IO
  292                 /* When using the APIC, ISA IRQs get mapped onto APIC IRQs
  293                  * (see mptable). Check which APIC IRQ the PCIC controller's
  294                  * IRQ will map to. Only allow interrupts where the APIC IRQ 
  295                  * is the same as the PCIC controller's IRQ.
  296                  * This avoids the problem of tracking both PCIC IRQs and
  297                  * interrupt masks and APIC IRQs and interrupt masks.
  298                  */
  299                 if (isa_apic_irq(irq) != irq) 
  300                          continue;
  301 #endif /* APIC_IO */
  302  
  303                 /* See if the IRQ is free. */
  304                 if (register_intr(irq, 0, 0, nullfunc, NULL, irq) == 0) {
  305                         /* Give it back, but add it to the mask */ 
  306                         INTRMASK(freemask, mask); 
  307                         unregister_intr(irq, nullfunc); 
  308                 }
  309         } 
  310 #ifdef PCIC_DEBUG
  311         printf("Freelist of IRQ's <0x%x>\n", freemask);
  312 #endif
  313         return freemask; 
  314 }
  315 
  316 /*
  317  *      entry point from main code to map/unmap memory context.
  318  */
  319 static int
  320 pcic_memory(struct slot *slt, int win)
  321 {
  322         struct pcic_slot *sp = slt->cdata;
  323         struct mem_desc *mp = &slt->mem[win];
  324         int reg = mp->window * PCIC_MEMSIZE + PCIC_MEMBASE;
  325 
  326 #ifdef  PC98
  327         if (sp->controller == PCIC_PC98) {
  328             if (mp->flags & MDF_ACTIVE) {
  329                 /* slot = 0, window = 0, sys_addr = 0xda000, length = 8KB */
  330                 unsigned char x;
  331                 
  332                 if ((unsigned long)mp->start != 0xda000) {
  333                     printf("sys_addr must be 0xda000. requested address = 0x%x\n",
  334                            mp->start);
  335                     return(EINVAL);
  336                 }
  337                 
  338                 /* omajinai ??? */
  339                 outb(PCIC98_REG0, 0);
  340                 x = inb(PCIC98_REG1);
  341                 x &= 0xfc;
  342                 x |= 0x02;
  343                 outb(PCIC98_REG1, x);
  344                 
  345                 outw(PCIC98_REG_PAGOFS, 0);
  346                 
  347                 if (mp->flags & MDF_ATTR) {
  348                     outb(PCIC98_REG6, inb(PCIC98_REG6) | PCIC98_ATTRMEM);
  349                 }else{
  350                     outb(PCIC98_REG6, inb(PCIC98_REG6) & (~PCIC98_ATTRMEM));
  351                 }
  352                 
  353                 outb(PCIC98_REG_WINSEL, PCIC98_MAPWIN);
  354                 
  355 #if 0
  356                 if ((mp->flags & MDF_16BITS) == 1) {    /* 16bit */
  357                     outb(PCIC98_REG2, inb(PCIC98_REG2) & (~PCIC98_8BIT));
  358                 }else{                                  /* 8bit */
  359                     outb(PCIC98_REG2, inb(PCIC98_REG2) | PCIC98_8BIT);
  360                 }
  361 #endif
  362             }else{
  363                 outb(PCIC98_REG_WINSEL, PCIC98_UNMAPWIN);
  364             }
  365             return 0;
  366         }
  367 #endif  /* PC98 */
  368 
  369         if (mp->flags & MDF_ACTIVE) {
  370                 unsigned long sys_addr = (uintptr_t)(void *)mp->start >> 12;
  371                 /*
  372                  * Write the addresses, card offsets and length.
  373                  * The values are all stored as the upper 12 bits of the
  374                  * 24 bit address i.e everything is allocated as 4 Kb chunks.
  375                  */
  376                 putw(sp, reg, sys_addr & 0xFFF);
  377                 putw(sp, reg+2, (sys_addr + (mp->size >> 12) - 1) & 0xFFF);
  378                 putw(sp, reg+4, ((mp->card >> 12) - sys_addr) & 0x3FFF);
  379 #if 0
  380                 printf("card offs = card_adr = 0x%x 0x%x, sys_addr = 0x%x\n", 
  381                         mp->card, ((mp->card >> 12) - sys_addr) & 0x3FFF,
  382                         sys_addr);
  383 #endif
  384                 /*
  385                  *      Each 16 bit register has some flags in the upper bits.
  386                  */
  387                 if (mp->flags & MDF_16BITS)
  388                         setb(sp, reg+1, PCIC_DATA16);
  389                 if (mp->flags & MDF_ZEROWS)
  390                         setb(sp, reg+1, PCIC_ZEROWS);
  391                 if (mp->flags & MDF_WS0)
  392                         setb(sp, reg+3, PCIC_MW0);
  393                 if (mp->flags & MDF_WS1)
  394                         setb(sp, reg+3, PCIC_MW1);
  395                 if (mp->flags & MDF_ATTR)
  396                         setb(sp, reg+5, PCIC_REG);
  397                 if (mp->flags & MDF_WP)
  398                         setb(sp, reg+5, PCIC_WP);
  399 #if 0
  400         printf("Slot number %d, reg 0x%x, offs 0x%x\n",
  401                 sp->slotnum, reg, sp->offset);
  402         printf("Map window to sys addr 0x%x for %d bytes, card 0x%x\n",
  403                 mp->start, mp->size, mp->card);
  404         printf("regs are: 0x%02x%02x 0x%02x%02x 0x%02x%02x flags 0x%x\n",
  405                 sp->getb(sp, reg), sp->getb(sp, reg+1),
  406                 sp->getb(sp, reg+2), sp->getb(sp, reg+3),
  407                 sp->getb(sp, reg+4), sp->getb(sp, reg+5),
  408                 mp->flags);
  409 #endif
  410                 /*
  411                  * Enable the memory window. By experiment, we need a delay.
  412                  */
  413                 setb(sp, PCIC_ADDRWINE, (1<<win) | PCIC_MEMCS16);
  414                 DELAY(50);
  415         } else {
  416 #if 0
  417                 printf("Unmapping window %d\n", win);
  418 #endif
  419                 clrb(sp, PCIC_ADDRWINE, 1<<win);
  420                 putw(sp, reg, 0);
  421                 putw(sp, reg+2, 0);
  422                 putw(sp, reg+4, 0);
  423         }
  424         return(0);
  425 }
  426 
  427 /*
  428  *      pcic_io - map or unmap I/O context
  429  */
  430 static int
  431 pcic_io(struct slot *slt, int win)
  432 {
  433         int     mask, reg;
  434         struct pcic_slot *sp = slt->cdata;
  435         struct io_desc *ip = &slt->io[win];
  436 #ifdef  PC98
  437         if (sp->controller == PCIC_PC98) {
  438             unsigned char x;
  439 
  440 #if 0
  441             if (win =! 0) {
  442                 printf("pcic98:Illegal PCIC I/O window request(%d)!", win);
  443                 return(EINVAL);
  444             }
  445 #endif
  446 
  447             if (ip->flags & IODF_ACTIVE) {
  448                 unsigned short base;
  449 
  450                 x = inb(PCIC98_REG2) & 0x0f;
  451                 if (! (ip->flags & IODF_16BIT))
  452                     x |= PCIC98_8BIT;
  453 
  454                 if (ip->size > 16)      /* 128bytes mapping */
  455                     x |= PCIC98_MAP128;
  456 
  457                 x |= PCIC98_IOMEMORY;
  458                 outb(PCIC98_REG2, x);
  459     
  460                 base = 0x80d0;
  461                 outw(PCIC98_REG4, base);                /* 98side IO base */
  462                 outw(PCIC98_REG5, ip->start);   /* card side IO base */
  463 
  464 #ifdef  PCIC_DEBUG
  465                 printf("pcic98: IO mapped 0x%04x(98) -> 0x%04x(Card) and width %d bytes\n",
  466                        base, ip->start, ip->size);
  467 #endif
  468                 ip->start = base;
  469 
  470             }else{
  471                 outb(PCIC98_REG2, inb(PCIC98_REG2) & (~PCIC98_IOMEMORY));
  472             }
  473             return 0;
  474         }
  475 #endif
  476         switch (win) {
  477         case 0:
  478                 mask = PCIC_IO0_EN;
  479                 reg = PCIC_IO0;
  480                 break;
  481         case 1:
  482                 mask = PCIC_IO1_EN;
  483                 reg = PCIC_IO1;
  484                 break;
  485         default:
  486                 panic("Illegal PCIC I/O window request!");
  487         }
  488         if (ip->flags & IODF_ACTIVE) {
  489                 unsigned char x, ioctlv;
  490 
  491 #ifdef  PCIC_DEBUG
  492 printf("Map I/O 0x%x (size 0x%x) on Window %d\n", ip->start, ip->size, win);
  493 #endif  /* PCIC_DEBUG */
  494                 putw(sp, reg, ip->start);
  495                 putw(sp, reg+2, ip->start+ip->size-1);
  496                 x = 0;
  497                 if (ip->flags & IODF_ZEROWS)
  498                         x |= PCIC_IO_0WS;
  499                 if (ip->flags & IODF_WS)
  500                         x |= PCIC_IO_WS;
  501                 if (ip->flags & IODF_CS16)
  502                         x |= PCIC_IO_CS16;
  503                 if (ip->flags & IODF_16BIT)
  504                         x |= PCIC_IO_16BIT;
  505                 /*
  506                  * Extract the current flags and merge with new flags.
  507                  * Flags for window 0 in lower nybble, and in upper nybble
  508                  * for window 1.
  509                  */
  510                 ioctlv = sp->getb(sp, PCIC_IOCTL);
  511                 DELAY(100);
  512                 switch (win) {
  513                 case 0:
  514                         sp->putb(sp, PCIC_IOCTL, x | (ioctlv & 0xf0));
  515                         break;
  516                 case 1:
  517                         sp->putb(sp, PCIC_IOCTL, (x << 4) | (ioctlv & 0xf));
  518                         break;
  519                 }
  520                 DELAY(100);
  521                 setb(sp, PCIC_ADDRWINE, mask);
  522                 DELAY(100);
  523         } else {
  524                 clrb(sp, PCIC_ADDRWINE, mask);
  525                 DELAY(100);
  526                 putw(sp, reg, 0);
  527                 putw(sp, reg + 2, 0);
  528         }
  529         return(0);
  530 }
  531 
  532 /*
  533  *      Look for an Intel PCIC (or compatible).
  534  *      For each available slot, allocate a PC-CARD slot.
  535  */
  536 
  537 /*
  538  *      VLSI 82C146 has incompatibilities about the I/O address 
  539  *      of slot 1.  Assume it's the only PCIC whose vendor ID is 0x84,
  540  *      contact Nate Williams <nate@FreeBSD.org> if incorrect.
  541  */
  542 int
  543 pcic_probe(void)
  544 {
  545         int slotnum, validslots = 0;
  546         u_int free_irqs, desired_irq;
  547         struct slot *slt;
  548         struct pcic_slot *sp;
  549         unsigned char c;
  550         static int maybe_vlsi = 0;
  551 
  552         /* Determine the list of free interrupts */
  553         free_irqs = build_freelist(PCIC_INT_MASK_ALLOWED);
  554         
  555         /*
  556          *      Initialise controller information structure.
  557          */
  558         cinfo.mapmem = pcic_memory;
  559         cinfo.mapio = pcic_io;
  560         cinfo.ioctl = pcic_ioctl;
  561         cinfo.power = pcic_power;
  562         cinfo.mapirq = pcic_mapirq;
  563         cinfo.reset = pcic_reset;
  564         cinfo.disable = pcic_disable;
  565         cinfo.resume = pcic_resume;
  566         cinfo.maxmem = PCIC_MEM_WIN;
  567         cinfo.maxio = PCIC_IO_WIN;
  568         cinfo.irqs = free_irqs;
  569         cinfo.imask = &pcic_imask;
  570 
  571         sp = pcic_slots;
  572         for (slotnum = 0; slotnum < PCIC_MAX_SLOTS; slotnum++, sp++) {
  573                 /*
  574                  *      Initialise the PCIC slot table.
  575                  */
  576                 sp->getb = getb1;
  577                 sp->putb = putb1;
  578                 if (slotnum < 4) {
  579                         sp->index = PCIC_INDEX_0;
  580                         sp->data = PCIC_DATA_0;
  581                         sp->offset = slotnum * PCIC_SLOT_SIZE;
  582                 } else {
  583                         sp->index = PCIC_INDEX_1;
  584                         sp->data = PCIC_DATA_1;
  585                         sp->offset = (slotnum - 4) * PCIC_SLOT_SIZE;
  586                 }
  587                 /* 
  588                  * XXX - Screwed up slot 1 on the VLSI chips.  According to
  589                  * the Linux PCMCIA code from David Hinds, working chipsets
  590                  * return 0x84 from their (correct) ID ports, while the broken
  591                  * ones would need to be probed at the new offset we set after
  592                  * we assume it's broken.
  593                  */
  594                 if (slotnum == 1 && maybe_vlsi && sp->getb(sp, PCIC_ID_REV) != 0x84) {
  595                         sp->index += 4;
  596                         sp->data += 4;
  597                         sp->offset = PCIC_SLOT_SIZE << 1;
  598                 }
  599                 /*
  600                  * see if there's a PCMCIA controller here
  601                  * Intel PCMCIA controllers use 0x82 and 0x83
  602                  * IBM clone chips use 0x88 and 0x89, apparently
  603                  */
  604                 c = sp->getb(sp, PCIC_ID_REV);
  605                 sp->revision = -1;
  606                 switch(c) {
  607                 /*
  608                  *      82365 or clones.
  609                  */
  610                 case 0x82:
  611                 case 0x83:
  612                         sp->controller = PCIC_I82365;
  613                         sp->revision = c & 1;
  614                         /*
  615                          *      Now check for VADEM chips.
  616                          */
  617                         outb(sp->index, 0x0E);
  618                         outb(sp->index, 0x37);
  619                         setb(sp, 0x3A, 0x40);
  620                         c = sp->getb(sp, PCIC_ID_REV);
  621                         if (c & 0x08) {
  622                                 switch (sp->revision = c & 7) {
  623                                 case 1:
  624                                         sp->controller = PCIC_VG365;
  625                                         break;
  626                                 case 2:
  627                                         sp->controller = PCIC_VG465;
  628                                         break;
  629                                 case 3:
  630                                         sp->controller = PCIC_VG468;
  631                                         break;
  632                                 default:
  633                                         sp->controller = PCIC_VG469;
  634                                         break;
  635                                 }
  636                                 clrb(sp, 0x3A, 0x40);
  637                         }
  638 
  639                         /*
  640                          * Check for RICOH RF5C396 PCMCIA Controller
  641                          */
  642                         c = sp->getb(sp, 0x3a);
  643                         if (c == 0xb2) {
  644                                 sp->controller = PCIC_RF5C396;
  645                         }
  646 
  647                         break;
  648                 /*
  649                  *      VLSI chips.
  650                  */
  651                 case 0x84:
  652                         sp->controller = PCIC_VLSI;
  653                         maybe_vlsi = 1;
  654                         break;
  655                 case 0x88:
  656                 case 0x89:
  657                         sp->controller = PCIC_IBM;
  658                         sp->revision = c & 1;
  659                         break;
  660                 case 0x8a:
  661                         sp->controller = PCIC_IBM_KING;
  662                         sp->revision = c & 1;
  663                         break;
  664                 default:
  665                         continue;
  666                 }
  667                 /*
  668                  *      Check for Cirrus logic chips.
  669                  */
  670                 sp->putb(sp, 0x1F, 0);
  671                 c = sp->getb(sp, 0x1F);
  672                 if ((c & 0xC0) == 0xC0) {
  673                         c = sp->getb(sp, 0x1F);
  674                         if ((c & 0xC0) == 0) {
  675                                 if (c & 0x20)
  676                                         sp->controller = PCIC_PD672X;
  677                                 else
  678                                         sp->controller = PCIC_PD6710;
  679                                 sp->revision = 8 - ((c & 0x1F) >> 2);
  680                         }
  681                 }
  682                 switch(sp->controller) {
  683                 case PCIC_I82365:
  684                         cinfo.name = "Intel 82365";
  685                         break;
  686                 case PCIC_IBM:
  687                         cinfo.name = "IBM PCIC";
  688                         break;
  689                 case PCIC_IBM_KING:
  690                         cinfo.name = "IBM KING PCMCIA Controller";
  691                         break;
  692                 case PCIC_PD672X:
  693                         cinfo.name = "Cirrus Logic PD672X";
  694                         break;
  695                 case PCIC_PD6710:
  696                         cinfo.name = "Cirrus Logic PD6710";
  697                         break;
  698                 case PCIC_VG365:
  699                         cinfo.name = "Vadem 365";
  700                         break;
  701                 case PCIC_VG465:
  702                         cinfo.name = "Vadem 465";
  703                         break;
  704                 case PCIC_VG468:
  705                         cinfo.name = "Vadem 468";
  706                         break;
  707                 case PCIC_VG469:
  708                         cinfo.name = "Vadem 469";
  709                         break;
  710                 case PCIC_RF5C396:
  711                         cinfo.name = "Ricoh RF5C396";
  712                         break;
  713                 case PCIC_VLSI:
  714                         cinfo.name = "VLSI 82C146";
  715                         break;
  716                 default:
  717                         cinfo.name = "Unknown!";
  718                         break;
  719                 }
  720                 /*
  721                  *      OK it seems we have a PCIC or lookalike.
  722                  *      Allocate a slot and initialise the data structures.
  723                  */
  724                 validslots++;
  725                 sp->slotnum = slotnum;
  726                 slt = pccard_alloc_slot(&cinfo);
  727                 if (slt == 0)
  728                         continue;
  729                 slt->cdata = sp;
  730                 sp->slt = slt;
  731                 /*
  732                  *      If we haven't allocated an interrupt for the controller,
  733                  *      then attempt to get one.
  734                  */
  735                 if (pcic_irq == 0) {
  736 
  737                         pcic_imask = soft_imask;
  738 
  739                         /* See if the user has requested a specific IRQ */
  740                         if (getenv_int("machdep.pccard.pcic_irq", &desired_irq))
  741                                 /* legal IRQ? */
  742                                 if (desired_irq >= 1 &&
  743                                     desired_irq <= ICU_LEN &&
  744                                     (1ul << desired_irq) & free_irqs)
  745                                         free_irqs = 1ul << desired_irq;
  746                                 else
  747                                         /* illeagal, disable use of IRQ */
  748                                         free_irqs = 0;
  749 
  750                         pcic_irq = pccard_alloc_intr(free_irqs,
  751                                 pcicintr, 0, &pcic_imask, NULL);
  752                         if (pcic_irq < 0)
  753                                 printf("pcic: failed to allocate IRQ\n");
  754                         else
  755                                 printf("pcic: controller irq %d\n", pcic_irq);
  756                 }
  757                 /*
  758                  * Modem cards send the speaker audio (dialing noises)
  759                  * to the host's speaker.  Cirrus Logic PCIC chips must
  760                  * enable this.  There is also a Low Power Dynamic Mode bit
  761                  * that claims to reduce power consumption by 30%, so
  762                  * enable it and hope for the best.
  763                  */
  764                 if (sp->controller == PCIC_PD672X) {
  765                         setb(sp, PCIC_MISC1, PCIC_SPKR_EN);
  766                         setb(sp, PCIC_MISC2, PCIC_LPDM_EN);
  767                 }
  768                 /*
  769                  *      Check for a card in this slot.
  770                  */
  771                 setb(sp, PCIC_POWER, PCIC_PCPWRE| PCIC_DISRST);
  772                 if ((sp->getb(sp, PCIC_STATUS) & PCIC_CD) != PCIC_CD) {
  773                         slt->laststate = slt->state = empty;
  774                 } else {
  775                         slt->laststate = slt->state = filled;
  776                         pccard_event(sp->slt, card_inserted);
  777                 }
  778                 /*
  779                  *      Assign IRQ for slot changes
  780                  */
  781                 if (pcic_irq > 0)
  782                         sp->putb(sp, PCIC_STAT_INT, (pcic_irq << 4) | 0xF);
  783         }
  784 #ifdef  PC98
  785         if (validslots == 0) {
  786             sp = pcic_slots;
  787             slotnum = 0;
  788             if (inb(PCIC98_REG0) != 0xff) {
  789                 sp->controller = PCIC_PC98;
  790                 sp->revision = 0;
  791                 cinfo.name = "PC98 Original";
  792                 cinfo.maxmem = 1;
  793                 cinfo.maxio = 1;
  794 /*              cinfo.irqs = PCIC_INT_MASK_ALLOWED;*/
  795                 cinfo.irqs = 0x1468;
  796                 validslots++;
  797                 sp->slotnum = slotnum;
  798 
  799                 slt = pccard_alloc_slot(&cinfo);
  800                 if (slt == 0) {
  801                     printf("pcic98: slt == NULL\n");
  802                     goto pcic98_probe_end;
  803                 }
  804                 slt->cdata = sp;
  805                 sp->slt = slt;
  806 
  807                 /* Check for a card in this slot */
  808                 if (inb(PCIC98_REG1) & PCIC98_CARDEXIST) {
  809                     /* PCMCIA card exist */
  810                     slt->laststate = slt->state = filled;
  811                     pccard_event(sp->slt, card_inserted);
  812                 } else {
  813                     slt->laststate = slt->state = empty;
  814                 }
  815             }
  816         pcic98_probe_end:
  817         }
  818 #endif  /* PC98 */
  819         if (validslots && pcic_irq <= 0)
  820                 pcictimeout_ch = timeout(pcictimeout, 0, hz/2);
  821         return(validslots);
  822 }
  823 
  824 /*
  825  *      ioctl calls - Controller specific ioctls
  826  */
  827 static int
  828 pcic_ioctl(struct slot *slt, int cmd, caddr_t data)
  829 {
  830         struct pcic_slot *sp = slt->cdata;
  831 
  832         switch(cmd) {
  833         default:
  834                 return(EINVAL);
  835         /*
  836          * Get/set PCIC registers
  837          */
  838         case PIOCGREG:
  839                 ((struct pcic_reg *)data)->value =
  840                         sp->getb(sp, ((struct pcic_reg *)data)->reg);
  841                 break;
  842         case PIOCSREG:
  843                 sp->putb(sp, ((struct pcic_reg *)data)->reg,
  844                         ((struct pcic_reg *)data)->value);
  845                 break;
  846         }
  847         return(0);
  848 }
  849 
  850 /*
  851  *      pcic_power - Enable the power of the slot according to
  852  *      the parameters in the power structure(s).
  853  */
  854 static int
  855 pcic_power(struct slot *slt)
  856 {
  857         unsigned char reg = PCIC_DISRST|PCIC_PCPWRE;
  858         struct pcic_slot *sp = slt->cdata;
  859 
  860         switch(sp->controller) {
  861 #ifdef  PC98
  862         case PCIC_PC98:
  863             reg = inb(PCIC98_REG6) & (~PCIC98_VPP12V);
  864             switch(slt->pwr.vpp) {
  865             default:
  866                 return(EINVAL);
  867             case 50:
  868                 break;
  869             case 120:
  870                 reg |= PCIC98_VPP12V;
  871                 break;
  872             }
  873             outb(PCIC98_REG6, reg);
  874             DELAY(100*1000);
  875 
  876             reg = inb(PCIC98_REG2) & (~PCIC98_VCC3P3V);
  877             switch(slt->pwr.vcc) {
  878             default:
  879                 return(EINVAL);
  880             case 33:
  881                 reg |= PCIC98_VCC3P3V;
  882                 break;
  883             case 50:
  884                 break;
  885             }
  886             outb(PCIC98_REG2, reg);
  887             DELAY(100*1000);
  888             return (0);
  889 #endif
  890         case PCIC_PD672X:
  891         case PCIC_PD6710:
  892         case PCIC_VG365:
  893         case PCIC_VG465:
  894         case PCIC_VG468:
  895         case PCIC_VG469:
  896         case PCIC_RF5C396:
  897         case PCIC_VLSI:
  898         case PCIC_IBM_KING:
  899                 switch(slt->pwr.vpp) {
  900                 default:
  901                         return(EINVAL);
  902                 case 0:
  903                         break;
  904                 case 50:
  905                 case 33:
  906                         reg |= PCIC_VPP_5V;
  907                         break;
  908                 case 120:
  909                         reg |= PCIC_VPP_12V;
  910                         break;
  911                 }
  912                 switch(slt->pwr.vcc) {
  913                 default:
  914                         return(EINVAL);
  915                 case 0:
  916                         break;
  917                 case 33:
  918                         if (sp->controller == PCIC_IBM_KING) {
  919                                 reg |= PCIC_VCC_5V_KING;
  920                                 break;
  921                         }
  922                         reg |= PCIC_VCC_3V;
  923                         if ((sp->controller == PCIC_VG468) ||
  924                                 (sp->controller == PCIC_VG469) ||
  925                                 (sp->controller == PCIC_VG465) ||
  926                                 (sp->controller == PCIC_VG365))
  927                                 setb(sp, 0x2f, 0x03) ;
  928                         else
  929                                 setb(sp, 0x16, 0x02);
  930                         break;
  931                 case 50:
  932                         if (sp->controller == PCIC_IBM_KING) {
  933                                 reg |= PCIC_VCC_5V_KING;
  934                                 break;
  935                         }
  936                         reg |= PCIC_VCC_5V;
  937                         if ((sp->controller == PCIC_VG468) ||
  938                                 (sp->controller == PCIC_VG469) ||
  939                                 (sp->controller == PCIC_VG465) ||
  940                                 (sp->controller == PCIC_VG365))
  941                                 clrb(sp, 0x2f, 0x03) ;
  942                         else
  943                                 clrb(sp, 0x16, 0x02);
  944                         break;
  945                 }
  946                 break;
  947         }
  948         sp->putb(sp, PCIC_POWER, reg);
  949         DELAY(300*1000);
  950         if (slt->pwr.vcc) {
  951                 reg |= PCIC_OUTENA;
  952                 sp->putb(sp, PCIC_POWER, reg);
  953                 DELAY(100*1000);
  954         }
  955         /* Some chips are smarter than us it seems, so if we weren't
  956          * allowed to use 5V, try 3.3 instead
  957          */
  958         if (!(sp->getb(sp, PCIC_STATUS) &  0x40) && slt->pwr.vcc == 50) {
  959                 slt->pwr.vcc = 33;
  960                 slt->pwr.vpp = 0;
  961                 return (pcic_power(slt));
  962         }
  963         return(0);
  964 }
  965 
  966 /*
  967  * tell the PCIC which irq we want to use.  only the following are legal:
  968  * 3, 4, 5, 7, 9, 10, 11, 12, 14, 15
  969  */
  970 static void
  971 pcic_mapirq(struct slot *slt, int irq)
  972 {
  973         struct pcic_slot *sp = slt->cdata;
  974 #ifdef  PC98
  975         if (sp->controller == PCIC_PC98) {
  976             unsigned char x;
  977             switch (irq) {
  978             case 3:
  979                 x = PCIC98_INT0; break;
  980             case 5:
  981                 x = PCIC98_INT1; break;
  982             case 6:
  983                 x = PCIC98_INT2; break;
  984             case 10:
  985                 x = PCIC98_INT4; break;
  986             case 12:
  987                 x = PCIC98_INT5; break;
  988             case 0:             /* disable */
  989                 x = PCIC98_INTDISABLE;
  990                 break;
  991             default:
  992                 printf("pcic98: illegal irq %d\n", irq);
  993                 return;
  994             }
  995 #ifdef  PCIC_DEBUG
  996             printf("pcic98: irq=%d mapped.\n", irq);
  997 #endif
  998             outb(PCIC98_REG3, x);
  999 
 1000             return;
 1001         }       
 1002 #endif
 1003         if (irq == 0)
 1004                 clrb(sp, PCIC_INT_GEN, 0xF);
 1005         else
 1006                 sp->putb(sp, PCIC_INT_GEN, 
 1007                     (sp->getb(sp, PCIC_INT_GEN) & 0xF0) | irq);
 1008 }
 1009 
 1010 /*
 1011  *      pcic_reset - Reset the card and enable initial power.
 1012  */
 1013 static void
 1014 pcic_reset(void *chan)
 1015 {
 1016         struct slot *slt = chan;
 1017         struct pcic_slot *sp = slt->cdata;
 1018 
 1019 #ifdef  PC98
 1020         if (sp->controller == PCIC_PC98) {
 1021             outb(PCIC98_REG0, 0);
 1022             outb(PCIC98_REG2, inb(PCIC98_REG2) & (~PCIC98_IOMEMORY));
 1023             outb(PCIC98_REG3, PCIC98_INTDISABLE);
 1024             outb(PCIC98_REG2, inb(PCIC98_REG2) & (~PCIC98_VCC3P3V));
 1025             outb(PCIC98_REG6, inb(PCIC98_REG6) & (~PCIC98_VPP12V));
 1026             outb(PCIC98_REG1, 0);
 1027 
 1028             selwakeup(&slt->selp);
 1029             return;
 1030         }
 1031 #endif
 1032         switch (slt->insert_seq) {
 1033             case 0: /* Something funny happended on the way to the pub... */
 1034                 return;
 1035             case 1: /* Assert reset */
 1036                 clrb(sp, PCIC_INT_GEN, PCIC_CARDRESET);
 1037                 slt->insert_seq = 2;
 1038                 timeout(pcic_reset, (void *)slt, hz/4);
 1039                 return;
 1040             case 2: /* Deassert it again */
 1041                 setb(sp, PCIC_INT_GEN, PCIC_CARDRESET|PCIC_IOCARD);
 1042                 slt->insert_seq = 3;
 1043                 timeout(pcic_reset, (void *)slt, hz/4);
 1044                 return;
 1045             case 3: /* Wait if card needs more time */
 1046                 if (!sp->getb(sp, PCIC_STATUS) & PCIC_READY) {
 1047                         timeout(pcic_reset, (void *)slt, hz/10);
 1048                         return;
 1049                 }
 1050         }
 1051         slt->insert_seq = 0;
 1052         if (sp->controller == PCIC_PD672X || sp->controller == PCIC_PD6710) {
 1053                 sp->putb(sp, PCIC_TIME_SETUP0, 0x1);
 1054                 sp->putb(sp, PCIC_TIME_CMD0, 0x6);
 1055                 sp->putb(sp, PCIC_TIME_RECOV0, 0x0);
 1056                 sp->putb(sp, PCIC_TIME_SETUP1, 1);
 1057                 sp->putb(sp, PCIC_TIME_CMD1, 0xf);
 1058                 sp->putb(sp, PCIC_TIME_RECOV1, 0);
 1059         }
 1060         selwakeup(&slt->selp);
 1061 }
 1062 
 1063 /*
 1064  *      pcic_disable - Disable the slot.
 1065  */
 1066 static void
 1067 pcic_disable(struct slot *slt)
 1068 {
 1069         struct pcic_slot *sp = slt->cdata;
 1070 
 1071 #ifdef  PC98
 1072         if (sp->controller == PCIC_PC98) {
 1073             return;
 1074         }
 1075 #endif
 1076         sp->putb(sp, PCIC_INT_GEN, 0);
 1077         sp->putb(sp, PCIC_POWER, 0);
 1078 }
 1079 
 1080 /*
 1081  *      PCIC timer.  If the controller doesn't have a free IRQ to use
 1082  *      or if interrupt steering doesn't work, poll the controller for
 1083  *      insertion/removal events.
 1084  */
 1085 static void
 1086 pcictimeout(void *chan)
 1087 {
 1088         pcicintr(NULL);
 1089         pcictimeout_ch = timeout(pcictimeout, 0, hz/2);
 1090 }
 1091 
 1092 /*
 1093  *      PCIC Interrupt handler.
 1094  *      Check each slot in turn, and read the card status change
 1095  *      register. If this is non-zero, then a change has occurred
 1096  *      on this card, so send an event to the main code.
 1097  */
 1098 static void
 1099 pcicintr(void *unused)
 1100 {
 1101         int     slot, s;
 1102         unsigned char chg;
 1103         struct pcic_slot *sp = pcic_slots;
 1104 
 1105 #ifdef  PC98
 1106         if (sp->controller == PCIC_PC98) {
 1107             slot = 0;
 1108             s = splhigh();
 1109             /* Check for a card in this slot */
 1110             if (inb(PCIC98_REG1) & PCIC98_CARDEXIST) {
 1111                 if (sp->slt->laststate != filled) {
 1112                     pccard_event(sp->slt, card_inserted);
 1113                 }
 1114             } else {
 1115                 if (sp->slt->laststate != empty) {
 1116                     pccard_event(sp->slt, card_removed);
 1117                 }
 1118             }
 1119             splx(s);
 1120             return;
 1121         }
 1122 #endif  /* PC98 */
 1123         s = splhigh();
 1124         for (slot = 0; slot < PCIC_MAX_SLOTS; slot++, sp++)
 1125                 if (sp->slt && (chg = sp->getb(sp, PCIC_STAT_CHG)) != 0)
 1126                         if (chg & PCIC_CDTCH) {
 1127                                 if ((sp->getb(sp, PCIC_STATUS) & PCIC_CD) ==
 1128                                                 PCIC_CD) {
 1129                                         pccard_event(sp->slt, card_inserted);
 1130                                 } else {
 1131                                         pccard_event(sp->slt, card_removed);
 1132                                 }
 1133                         }
 1134         splx(s);
 1135 }
 1136 
 1137 /*
 1138  *      pcic_resume - Suspend/resume support for PCIC
 1139  */
 1140 static void
 1141 pcic_resume(struct slot *slt)
 1142 {
 1143         struct pcic_slot *sp = slt->cdata;
 1144         if (pcic_irq > 0)
 1145                 sp->putb(sp, PCIC_STAT_INT, (pcic_irq << 4) | 0xF);
 1146         if (sp->controller == PCIC_PD672X) {
 1147                 setb(sp, PCIC_MISC1, PCIC_SPKR_EN);
 1148                 setb(sp, PCIC_MISC2, PCIC_LPDM_EN);
 1149         }
 1150 }

Cache object: 37732df26b9a25043e7a4965635a67aa


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.