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/i386/isa/pcicx.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  * TODO:
    3  * [1] integrate into current if_ed.c
    4  * [2] parse tuples to find out where to map the shared memory buffer,
    5  *     and what to write into the configuration register
    6  * [3] move pcic-specific code into a separate module.
    7  *
    8  * Device driver for IBM PCMCIA Credit Card Adapter for Ethernet,
    9  * if_ze.c
   10  *
   11  * Based on the Device driver for National Semiconductor DS8390 ethernet
   12  * adapters by David Greenman.  Modifications for PCMCIA by Keith Moore.
   13  * Adapted for FreeBSD 1.1.5 by Jordan Hubbard.
   14  *
   15  * Currently supports only the IBM Credit Card Adapter for Ethernet, but
   16  * could probably work with other PCMCIA cards also, if it were modified
   17  * to get the locations of the PCMCIA configuration option register (COR)
   18  * by parsing the configuration tuples, rather than by hard-coding in
   19  * the value expected by IBM's card.
   20  *
   21  * Sources for data on the PCMCIA/IBM CCAE specific portions of the driver:
   22  *
   23  * [1] _Local Area Network Credit Card Adapters Technical Reference_,
   24  *     IBM Corp., SC30-3585-00, part # 33G9243.
   25  * [2] "pre-alpha" PCMCIA support code for Linux by Barry Jaspan.
   26  * [3] Intel 82536SL PC Card Interface Controller Data Sheet, Intel
   27  *     Order Number 290423-002
   28  * [4] National Semiconductor DP83902A ST-NIC (tm) Serial Network
   29  *     Interface Controller for Twisted Pair data sheet.
   30  *
   31  *
   32  * Copyright (C) 1993, David Greenman. This software may be used, modified,
   33  *   copied, distributed, and sold, in both source and binary form provided
   34  *   that the above copyright and these terms are retained. Under no
   35  *   circumstances is the author responsible for the proper functioning
   36  *   of this software, nor does the author assume any responsibility
   37  *   for damages incurred with its use.
   38  */
   39 #include <sys/param.h>
   40 #if defined(__FreeBSD__)
   41 #include <sys/systm.h>
   42 #include <machine/clock.h>
   43 #endif
   44 #include <i386/isa/isa_device.h>
   45 #include <i386/isa/pcic.h>
   46 
   47 /*
   48  * map a portion of the card's memory space into system memory
   49  * space.
   50  *
   51  * slot = # of the slot the card is plugged into
   52  * window = which pcic memory map registers to use (0..4)
   53  * sys_addr = base system PHYSICAL memory address where we want it.  must
   54  *            be on an appropriate boundary (lower 12 bits are zero).
   55  * card_addr = the base address of the card's memory to correspond
   56  *             to sys_addr
   57  * length = length of the segment to map (may be rounded up as necessary)
   58  * type = which card memory space to map (attribute or shared)
   59  * width = 1 for byte-wide mapping; 2 for word (16-bit) mapping.
   60  */
   61 
   62 void
   63 pcic_map_memory (int slot, int window, unsigned long sys_addr,
   64                  unsigned long card_addr, unsigned long length,
   65                  enum memtype type, int width)
   66 {
   67     unsigned short offset;
   68     unsigned short mem_start_addr;
   69     unsigned short mem_stop_addr;
   70 
   71     sys_addr >>= 12;
   72     card_addr >>= 12;
   73     length >>= 12;
   74     /*
   75      * compute an offset for the chip such that
   76      * (sys_addr + offset) = card_addr
   77      * but the arithmetic is done modulo 2^14
   78      */
   79     offset = (card_addr - sys_addr) & 0x3FFF;
   80     /*
   81      * now OR in the bit for "attribute memory" if necessary
   82      */
   83     if (type == ATTRIBUTE) {
   84         offset |= (PCIC_REG << 8);
   85         /* REG == "region active" pin on card */
   86     }
   87     /*
   88      * okay, set up the chip memory mapping registers, and turn
   89      * on the enable bit for this window.
   90      * if we are doing 16-bit wide accesses (width == 2),
   91      * turn on the appropriate bit.
   92      *
   93      * XXX for now, we set all of the wait state bits to zero.
   94      * Not really sure how they should be set.
   95      */
   96     mem_start_addr = sys_addr & 0xFFF;
   97     if (width == 2)
   98         mem_start_addr |= (PCIC_DATA16 << 8);
   99     mem_stop_addr = (sys_addr + length) & 0xFFF;
  100 
  101     pcic_putw (slot, MEM_START_ADDR(window), mem_start_addr);
  102     pcic_putw (slot, MEM_STOP_ADDR(window), mem_stop_addr);
  103     pcic_putw (slot, MEM_OFFSET(window), offset);
  104     /*
  105      * Assert the bit (PCIC_MEMCS16) that says to decode all of
  106      * the address lines.
  107      */
  108     pcic_putb (slot, PCIC_ADDRWINE,
  109                pcic_getb (slot, PCIC_ADDRWINE) |
  110                MEM_ENABLE_BIT(window) | PCIC_MEMCS16);
  111 }
  112 
  113 void
  114 pcic_unmap_memory (int slot, int window)
  115 {
  116     /*
  117      * seems like we need to turn off the enable bit first, after which
  118      * we can clear the registers out just to be sure.
  119      */
  120     pcic_putb (slot, PCIC_ADDRWINE,
  121                pcic_getb (slot, PCIC_ADDRWINE) & ~MEM_ENABLE_BIT(window));
  122     pcic_putw (slot, MEM_START_ADDR(window), 0);
  123     pcic_putw (slot, MEM_STOP_ADDR(window), 0);
  124     pcic_putw (slot, MEM_OFFSET(window), 0);
  125 }
  126 
  127 /*
  128  * map a range of addresses into system i/o space
  129  * (no translation of i/o addresses is possible)
  130  *
  131  * 'width' is:
  132  * + 0 to tell the PCIC to generate the ISA IOCS16* signal from
  133  *   the PCMCIA IOIS16* signal.
  134  * + 1 to select 8-bit width
  135  * + 2 to select 16-bit width
  136  */
  137 
  138 void
  139 pcic_map_io (int slot, int window, unsigned short base, unsigned short length,
  140              unsigned short width)
  141 {
  142     unsigned char x;
  143 
  144     pcic_putw (slot, IO_START_ADDR(window), base);
  145     pcic_putw (slot, IO_STOP_ADDR(window), base+length-1);
  146     /*
  147      * select the bits that determine whether
  148      * an i/o operation is 8 or 16 bits wide
  149      */
  150     x = pcic_getb (slot, PCIC_IOCTL);
  151     switch (width) {
  152     case 0:                     /* PCMCIA card decides */
  153         if (window)
  154             x = (x & 0xf0) | PCIC_IO1_CS16;
  155         else
  156             x = (x & 0x0f) | PCIC_IO0_CS16;
  157         break;
  158     case 1:                     /* 8 bits wide */
  159         break;
  160     case 2:                     /* 16 bits wide */
  161         if (window)
  162             x = (x & 0xf0) | PCIC_IO1_16BIT;
  163         else
  164             x = (x & 0x0f) | PCIC_IO0_16BIT;
  165         break;
  166     }
  167     pcic_putb (slot, PCIC_IOCTL, x);
  168     pcic_putb (slot, PCIC_ADDRWINE,
  169                pcic_getb (slot, PCIC_ADDRWINE) | IO_ENABLE_BIT(window));
  170 }
  171 
  172 #ifdef TEST
  173 void
  174 pcic_unmap_io (int slot, int window)
  175 {
  176     pcic_putb (slot, PCIC_ADDRWINE,
  177                pcic_getb (slot, PCIC_ADDRWINE) & ~IO_ENABLE_BIT(window));
  178     pcic_putw (slot, IO_START_ADDR(window), 0);
  179     pcic_putw (slot, IO_STOP_ADDR(window), 0);
  180 }
  181 #endif /* TEST */
  182 
  183 /*
  184  * tell the PCIC which irq we want to use.  only the following are legal:
  185  * 3, 4, 5, 7, 9, 10, 11, 12, 14, 15
  186  *
  187  * NB: 'irq' is an interrupt NUMBER, not a MASK as in struct isa_device.
  188  */
  189 
  190 void
  191 pcic_map_irq (int slot, int irq)
  192 {
  193     if (irq < 3 || irq == 6 || irq == 8 || irq == 13 || irq > 15) {
  194         printf ("zp: pcic_map_irq (slot %d): illegal irq %d\n", slot, irq);
  195         return;
  196     }
  197     pcic_putb (slot, PCIC_INT_GEN,
  198                pcic_getb (slot, PCIC_INT_GEN) | (irq & 0x0F));
  199 }
  200 
  201 void
  202 pcic_power_on (int slot)
  203 {
  204     pcic_putb (slot, PCIC_STATUS,
  205                pcic_getb (slot, PCIC_STATUS) | PCIC_POW);
  206     DELAY (100000);
  207     pcic_putb (slot, PCIC_POWER,
  208                pcic_getb (slot, PCIC_POWER) | PCIC_DISRST | PCIC_PCPWRE);
  209     DELAY (100000);
  210     pcic_putb (slot, PCIC_POWER,
  211                pcic_getb (slot, PCIC_POWER) | PCIC_OUTENA);
  212 }
  213 
  214 void
  215 pcic_power_off (int slot)
  216 {
  217     pcic_putb (slot, PCIC_POWER,
  218                pcic_getb (slot, PCIC_POWER) & ~(PCIC_OUTENA|PCIC_PCPWRE));
  219 }
  220 
  221 void
  222 pcic_reset (int slot)
  223 {
  224     /* assert RESET (by clearing a bit!), wait a bit, and de-assert it */
  225     pcic_putb (slot, PCIC_INT_GEN,
  226                pcic_getb (slot, PCIC_INT_GEN) & ~PCIC_CARDRESET);
  227     DELAY (100000);
  228     pcic_putb (slot, PCIC_INT_GEN,
  229                pcic_getb (slot, PCIC_INT_GEN) | PCIC_CARDRESET);
  230 }
  231 

Cache object: b229820cfe61cf52127dfa5ad47a2da2


[ 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.