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 <sys/kernel.h>
   43 #include <machine/clock.h>
   44 #endif
   45 #include <i386/isa/isa_device.h>
   46 #include <i386/isa/pcic.h>
   47 
   48 /*
   49  * map a portion of the card's memory space into system memory
   50  * space.
   51  *
   52  * slot = # of the slot the card is plugged into
   53  * window = which pcic memory map registers to use (0..4)
   54  * sys_addr = base system PHYSICAL memory address where we want it.  must
   55  *            be on an appropriate boundary (lower 12 bits are zero).
   56  * card_addr = the base address of the card's memory to correspond
   57  *             to sys_addr
   58  * length = length of the segment to map (may be rounded up as necessary)
   59  * type = which card memory space to map (attribute or shared)
   60  * width = 1 for byte-wide mapping; 2 for word (16-bit) mapping.
   61  */
   62 
   63 void
   64 pcic_map_memory (int slot, int window, unsigned long sys_addr,
   65                  unsigned long card_addr, unsigned long length,
   66                  enum memtype type, int width)
   67 {
   68     unsigned short offset;
   69     unsigned short mem_start_addr;
   70     unsigned short mem_stop_addr;
   71 
   72     sys_addr >>= 12;
   73     card_addr >>= 12;
   74     length >>= 12;
   75     /*
   76      * compute an offset for the chip such that
   77      * (sys_addr + offset) = card_addr
   78      * but the arithmetic is done modulo 2^14
   79      */
   80     offset = (card_addr - sys_addr) & 0x3FFF;
   81     /*
   82      * now OR in the bit for "attribute memory" if necessary
   83      */
   84     if (type == ATTRIBUTE) {
   85         offset |= (PCIC_REG << 8);
   86         /* REG == "region active" pin on card */
   87     }
   88     /*
   89      * okay, set up the chip memory mapping registers, and turn
   90      * on the enable bit for this window.
   91      * if we are doing 16-bit wide accesses (width == 2),
   92      * turn on the appropriate bit.
   93      *
   94      * XXX for now, we set all of the wait state bits to zero.
   95      * Not really sure how they should be set.
   96      */
   97     mem_start_addr = sys_addr & 0xFFF;
   98     if (width == 2)
   99         mem_start_addr |= (PCIC_DATA16 << 8);
  100     mem_stop_addr = (sys_addr + length) & 0xFFF;
  101 
  102     pcic_putw (slot, MEM_START_ADDR(window), mem_start_addr);
  103     pcic_putw (slot, MEM_STOP_ADDR(window), mem_stop_addr);
  104     pcic_putw (slot, MEM_OFFSET(window), offset);
  105     /*
  106      * Assert the bit (PCIC_MEMCS16) that says to decode all of
  107      * the address lines.
  108      */
  109     pcic_putb (slot, PCIC_ADDRWINE,
  110                pcic_getb (slot, PCIC_ADDRWINE) |
  111                MEM_ENABLE_BIT(window) | PCIC_MEMCS16);
  112 }
  113 
  114 void
  115 pcic_unmap_memory (int slot, int window)
  116 {
  117     /*
  118      * seems like we need to turn off the enable bit first, after which
  119      * we can clear the registers out just to be sure.
  120      */
  121     pcic_putb (slot, PCIC_ADDRWINE,
  122                pcic_getb (slot, PCIC_ADDRWINE) & ~MEM_ENABLE_BIT(window));
  123     pcic_putw (slot, MEM_START_ADDR(window), 0);
  124     pcic_putw (slot, MEM_STOP_ADDR(window), 0);
  125     pcic_putw (slot, MEM_OFFSET(window), 0);
  126 }
  127 
  128 /*
  129  * map a range of addresses into system i/o space
  130  * (no translation of i/o addresses is possible)
  131  *
  132  * 'width' is:
  133  * + 0 to tell the PCIC to generate the ISA IOCS16* signal from
  134  *   the PCMCIA IOIS16* signal.
  135  * + 1 to select 8-bit width
  136  * + 2 to select 16-bit width
  137  */
  138 
  139 void
  140 pcic_map_io (int slot, int window, unsigned short base, unsigned short length,
  141              unsigned short width)
  142 {
  143     unsigned char x;
  144 
  145     pcic_putw (slot, IO_START_ADDR(window), base);
  146     pcic_putw (slot, IO_STOP_ADDR(window), base+length-1);
  147     /*
  148      * select the bits that determine whether
  149      * an i/o operation is 8 or 16 bits wide
  150      */
  151     x = pcic_getb (slot, PCIC_IOCTL);
  152     switch (width) {
  153     case 0:                     /* PCMCIA card decides */
  154         if (window)
  155             x = (x & 0xf0) | PCIC_IO1_CS16;
  156         else
  157             x = (x & 0x0f) | PCIC_IO0_CS16;
  158         break;
  159     case 1:                     /* 8 bits wide */
  160         break;
  161     case 2:                     /* 16 bits wide */
  162         if (window)
  163             x = (x & 0xf0) | PCIC_IO1_16BIT;
  164         else
  165             x = (x & 0x0f) | PCIC_IO0_16BIT;
  166         break;
  167     }
  168     pcic_putb (slot, PCIC_IOCTL, x);
  169     pcic_putb (slot, PCIC_ADDRWINE,
  170                pcic_getb (slot, PCIC_ADDRWINE) | IO_ENABLE_BIT(window));
  171 }
  172 
  173 #ifdef TEST
  174 void
  175 pcic_unmap_io (int slot, int window)
  176 {
  177     pcic_putb (slot, PCIC_ADDRWINE,
  178                pcic_getb (slot, PCIC_ADDRWINE) & ~IO_ENABLE_BIT(window));
  179     pcic_putw (slot, IO_START_ADDR(window), 0);
  180     pcic_putw (slot, IO_STOP_ADDR(window), 0);
  181 }
  182 #endif /* TEST */
  183 
  184 /*
  185  * tell the PCIC which irq we want to use.  only the following are legal:
  186  * 3, 4, 5, 7, 9, 10, 11, 12, 14, 15
  187  *
  188  * NB: 'irq' is an interrupt NUMBER, not a MASK as in struct isa_device.
  189  */
  190 
  191 void
  192 pcic_map_irq (int slot, int irq)
  193 {
  194     if (irq < 3 || irq == 6 || irq == 8 || irq == 13 || irq > 15) {
  195         printf ("zp: pcic_map_irq (slot %d): illegal irq %d\n", slot, irq);
  196         return;
  197     }
  198     pcic_putb (slot, PCIC_INT_GEN,
  199                pcic_getb (slot, PCIC_INT_GEN) | (irq & 0x0F));
  200 }
  201 
  202 void
  203 pcic_power_on (int slot)
  204 {
  205     pcic_putb (slot, PCIC_STATUS,
  206                pcic_getb (slot, PCIC_STATUS) | PCIC_POW);
  207     DELAY (100000);
  208     pcic_putb (slot, PCIC_POWER,
  209                pcic_getb (slot, PCIC_POWER) | PCIC_DISRST | PCIC_PCPWRE);
  210     DELAY (100000);
  211     pcic_putb (slot, PCIC_POWER,
  212                pcic_getb (slot, PCIC_POWER) | PCIC_OUTENA);
  213 }
  214 
  215 void
  216 pcic_power_off (int slot)
  217 {
  218     pcic_putb (slot, PCIC_POWER,
  219                pcic_getb (slot, PCIC_POWER) & ~(PCIC_OUTENA|PCIC_PCPWRE));
  220 }
  221 
  222 void
  223 pcic_reset (int slot)
  224 {
  225     /* assert RESET (by clearing a bit!), wait a bit, and de-assert it */
  226     pcic_putb (slot, PCIC_INT_GEN,
  227                pcic_getb (slot, PCIC_INT_GEN) & ~PCIC_CARDRESET);
  228     DELAY (100000);
  229     pcic_putb (slot, PCIC_INT_GEN,
  230                pcic_getb (slot, PCIC_INT_GEN) | PCIC_CARDRESET);
  231 }
  232 

Cache object: b3c05f6b876e5b7c8f178d4557fc98b2


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