From dc9deb292c258d2da350f88ba1be36a40dfdbd96 Mon Sep 17 00:00:00 2001 From: Poul-Henning Kamp Date: Tue, 31 Oct 1995 18:28:55 +0000 Subject: [PATCH] Get pccard stuff into LINT. rename i386/isa/pcic.c to .../pcicx.c this file will go away when the if_ze and if_zp dies. --- sys/conf/NOTES | 9 +- sys/conf/files.i386 | 6 +- sys/i386/conf/LINT | 9 +- sys/i386/conf/NOTES | 9 +- sys/i386/conf/files.i386 | 6 +- sys/i386/isa/pcicx.c | 246 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 276 insertions(+), 9 deletions(-) create mode 100644 sys/i386/isa/pcicx.c diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 168b9f891bac..a66fc6a07e2e 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -2,7 +2,7 @@ # LINT -- config file for checking all the sources, tries to pull in # as much of the source tree as it can. # -# $Id: LINT,v 1.208 1995/10/31 07:42:49 julian Exp $ +# $Id: LINT,v 1.209 1995/10/31 17:00:03 joerg Exp $ # # NB: You probably don't want to try running a kernel built from this # file. Instead, you should start from GENERIC, and add options from @@ -788,6 +788,13 @@ device fpa0 device meteor0 options PROBE_VERBOSE + +# +# PCCARD/PCMCIA +# +controller crd0 +controller pcic0 at crd? + # # Laptop/Notebook options: # diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 8f50bc2bfb7d..6eb3e16e29b5 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -1,7 +1,7 @@ # This file tells config what files go into building a kernel, # files marked standard are always included. # -# $Id: files.i386,v 1.110 1995/10/10 08:04:10 swallace Exp $ +# $Id: files.i386,v 1.111 1995/10/28 16:57:35 markm Exp $ # aic7xxx_asm optional ahc device-driver \ dependency "$S/dev/aic7xxx/aic7xxx_asm.c" \ @@ -105,8 +105,8 @@ i386/isa/npx.c optional npx device-driver i386/isa/pcaudio.c optional pca device-driver i386/isa/matcd/matcd.c optional matcd device-driver i386/isa/pcibus.c optional pci device-driver -i386/isa/pcic.c optional ze device-driver -i386/isa/pcic.c optional zp device-driver +i386/isa/pcicx.c optional ze device-driver +i386/isa/pcicx.c optional zp device-driver i386/isa/random.c standard i386/eisa/eisaconf.c optional eisa i386/eisa/eisadevs.c optional eisa diff --git a/sys/i386/conf/LINT b/sys/i386/conf/LINT index 168b9f891bac..a66fc6a07e2e 100644 --- a/sys/i386/conf/LINT +++ b/sys/i386/conf/LINT @@ -2,7 +2,7 @@ # LINT -- config file for checking all the sources, tries to pull in # as much of the source tree as it can. # -# $Id: LINT,v 1.208 1995/10/31 07:42:49 julian Exp $ +# $Id: LINT,v 1.209 1995/10/31 17:00:03 joerg Exp $ # # NB: You probably don't want to try running a kernel built from this # file. Instead, you should start from GENERIC, and add options from @@ -788,6 +788,13 @@ device fpa0 device meteor0 options PROBE_VERBOSE + +# +# PCCARD/PCMCIA +# +controller crd0 +controller pcic0 at crd? + # # Laptop/Notebook options: # diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES index 168b9f891bac..a66fc6a07e2e 100644 --- a/sys/i386/conf/NOTES +++ b/sys/i386/conf/NOTES @@ -2,7 +2,7 @@ # LINT -- config file for checking all the sources, tries to pull in # as much of the source tree as it can. # -# $Id: LINT,v 1.208 1995/10/31 07:42:49 julian Exp $ +# $Id: LINT,v 1.209 1995/10/31 17:00:03 joerg Exp $ # # NB: You probably don't want to try running a kernel built from this # file. Instead, you should start from GENERIC, and add options from @@ -788,6 +788,13 @@ device fpa0 device meteor0 options PROBE_VERBOSE + +# +# PCCARD/PCMCIA +# +controller crd0 +controller pcic0 at crd? + # # Laptop/Notebook options: # diff --git a/sys/i386/conf/files.i386 b/sys/i386/conf/files.i386 index 8f50bc2bfb7d..6eb3e16e29b5 100644 --- a/sys/i386/conf/files.i386 +++ b/sys/i386/conf/files.i386 @@ -1,7 +1,7 @@ # This file tells config what files go into building a kernel, # files marked standard are always included. # -# $Id: files.i386,v 1.110 1995/10/10 08:04:10 swallace Exp $ +# $Id: files.i386,v 1.111 1995/10/28 16:57:35 markm Exp $ # aic7xxx_asm optional ahc device-driver \ dependency "$S/dev/aic7xxx/aic7xxx_asm.c" \ @@ -105,8 +105,8 @@ i386/isa/npx.c optional npx device-driver i386/isa/pcaudio.c optional pca device-driver i386/isa/matcd/matcd.c optional matcd device-driver i386/isa/pcibus.c optional pci device-driver -i386/isa/pcic.c optional ze device-driver -i386/isa/pcic.c optional zp device-driver +i386/isa/pcicx.c optional ze device-driver +i386/isa/pcicx.c optional zp device-driver i386/isa/random.c standard i386/eisa/eisaconf.c optional eisa i386/eisa/eisadevs.c optional eisa diff --git a/sys/i386/isa/pcicx.c b/sys/i386/isa/pcicx.c new file mode 100644 index 000000000000..f5b31c9fe071 --- /dev/null +++ b/sys/i386/isa/pcicx.c @@ -0,0 +1,246 @@ +/*- + * TODO: + * [1] integrate into current if_ed.c + * [2] parse tuples to find out where to map the shared memory buffer, + * and what to write into the configuration register + * [3] move pcic-specific code into a separate module. + * + * Device driver for IBM PCMCIA Credit Card Adapter for Ethernet, + * if_ze.c + * + * Based on the Device driver for National Semiconductor DS8390 ethernet + * adapters by David Greenman. Modifications for PCMCIA by Keith Moore. + * Adapted for FreeBSD 1.1.5 by Jordan Hubbard. + * + * Currently supports only the IBM Credit Card Adapter for Ethernet, but + * could probably work with other PCMCIA cards also, if it were modified + * to get the locations of the PCMCIA configuration option register (COR) + * by parsing the configuration tuples, rather than by hard-coding in + * the value expected by IBM's card. + * + * Sources for data on the PCMCIA/IBM CCAE specific portions of the driver: + * + * [1] _Local Area Network Credit Card Adapters Technical Reference_, + * IBM Corp., SC30-3585-00, part # 33G9243. + * [2] "pre-alpha" PCMCIA support code for Linux by Barry Jaspan. + * [3] Intel 82536SL PC Card Interface Controller Data Sheet, Intel + * Order Number 290423-002 + * [4] National Semiconductor DP83902A ST-NIC (tm) Serial Network + * Interface Controller for Twisted Pair data sheet. + * + * + * Copyright (C) 1993, David Greenman. This software may be used, modified, + * copied, distributed, and sold, in both source and binary form provided + * that the above copyright and these terms are retained. Under no + * circumstances is the author responsible for the proper functioning + * of this software, nor does the author assume any responsibility + * for damages incurred with its use. + */ +#include +#if defined(__FreeBSD__) +#include +#include +#include +#endif +#include +#include +#include +#include + +void +pcic_print_regs (int slot) +{ + int i, j; + + for (i = 0; i < 0x40; i += 16) { + for (j = 0; j < 16; ++j) + printf ("%02x ", pcic_getb (slot, i + j)); + printf ("\n"); + } +} + +/* + * map a portion of the card's memory space into system memory + * space. + * + * slot = # of the slot the card is plugged into + * window = which pcic memory map registers to use (0..4) + * sys_addr = base system PHYSICAL memory address where we want it. must + * be on an appropriate boundary (lower 12 bits are zero). + * card_addr = the base address of the card's memory to correspond + * to sys_addr + * length = length of the segment to map (may be rounded up as necessary) + * type = which card memory space to map (attribute or shared) + * width = 1 for byte-wide mapping; 2 for word (16-bit) mapping. + */ + +void +pcic_map_memory (int slot, int window, unsigned long sys_addr, + unsigned long card_addr, unsigned long length, + enum memtype type, int width) +{ + unsigned short offset; + unsigned short mem_start_addr; + unsigned short mem_stop_addr; + + sys_addr >>= 12; + card_addr >>= 12; + length >>= 12; + /* + * compute an offset for the chip such that + * (sys_addr + offset) = card_addr + * but the arithmetic is done modulo 2^14 + */ + offset = (card_addr - sys_addr) & 0x3FFF; + /* + * now OR in the bit for "attribute memory" if necessary + */ + if (type == ATTRIBUTE) { + offset |= (PCIC_REG << 8); + /* REG == "region active" pin on card */ + } + /* + * okay, set up the chip memory mapping registers, and turn + * on the enable bit for this window. + * if we are doing 16-bit wide accesses (width == 2), + * turn on the appropriate bit. + * + * XXX for now, we set all of the wait state bits to zero. + * Not really sure how they should be set. + */ + mem_start_addr = sys_addr & 0xFFF; + if (width == 2) + mem_start_addr |= (PCIC_DATA16 << 8); + mem_stop_addr = (sys_addr + length) & 0xFFF; + + pcic_putw (slot, MEM_START_ADDR(window), mem_start_addr); + pcic_putw (slot, MEM_STOP_ADDR(window), mem_stop_addr); + pcic_putw (slot, MEM_OFFSET(window), offset); + /* + * Assert the bit (PCIC_MEMCS16) that says to decode all of + * the address lines. + */ + pcic_putb (slot, PCIC_ADDRWINE, + pcic_getb (slot, PCIC_ADDRWINE) | + MEM_ENABLE_BIT(window) | PCIC_MEMCS16); +} + +void +pcic_unmap_memory (int slot, int window) +{ + /* + * seems like we need to turn off the enable bit first, after which + * we can clear the registers out just to be sure. + */ + pcic_putb (slot, PCIC_ADDRWINE, + pcic_getb (slot, PCIC_ADDRWINE) & ~MEM_ENABLE_BIT(window)); + pcic_putw (slot, MEM_START_ADDR(window), 0); + pcic_putw (slot, MEM_STOP_ADDR(window), 0); + pcic_putw (slot, MEM_OFFSET(window), 0); +} + +/* + * map a range of addresses into system i/o space + * (no translation of i/o addresses is possible) + * + * 'width' is: + * + 0 to tell the PCIC to generate the ISA IOCS16* signal from + * the PCMCIA IOIS16* signal. + * + 1 to select 8-bit width + * + 2 to select 16-bit width + */ + +void +pcic_map_io (int slot, int window, unsigned short base, unsigned short length, + unsigned short width) +{ + unsigned char x; + + pcic_putw (slot, IO_START_ADDR(window), base); + pcic_putw (slot, IO_STOP_ADDR(window), base+length-1); + /* + * select the bits that determine whether + * an i/o operation is 8 or 16 bits wide + */ + x = pcic_getb (slot, PCIC_IOCTL); + switch (width) { + case 0: /* PCMCIA card decides */ + if (window) + x = (x & 0xf0) | PCIC_IO1_CS16; + else + x = (x & 0x0f) | PCIC_IO0_CS16; + break; + case 1: /* 8 bits wide */ + break; + case 2: /* 16 bits wide */ + if (window) + x = (x & 0xf0) | PCIC_IO1_16BIT; + else + x = (x & 0x0f) | PCIC_IO0_16BIT; + break; + } + pcic_putb (slot, PCIC_IOCTL, x); + pcic_putb (slot, PCIC_ADDRWINE, + pcic_getb (slot, PCIC_ADDRWINE) | IO_ENABLE_BIT(window)); +} + +#ifdef TEST +void +pcic_unmap_io (int slot, int window) +{ + pcic_putb (slot, PCIC_ADDRWINE, + pcic_getb (slot, PCIC_ADDRWINE) & ~IO_ENABLE_BIT(window)); + pcic_putw (slot, IO_START_ADDR(window), 0); + pcic_putw (slot, IO_STOP_ADDR(window), 0); +} +#endif /* TEST */ + +/* + * tell the PCIC which irq we want to use. only the following are legal: + * 3, 4, 5, 7, 9, 10, 11, 12, 14, 15 + * + * NB: 'irq' is an interrupt NUMBER, not a MASK as in struct isa_device. + */ + +void +pcic_map_irq (int slot, int irq) +{ + if (irq < 3 || irq == 6 || irq == 8 || irq == 13 || irq > 15) { + printf ("zp: pcic_map_irq (slot %d): illegal irq %d\n", slot, irq); + return; + } + pcic_putb (slot, PCIC_INT_GEN, + pcic_getb (slot, PCIC_INT_GEN) | (irq & 0x0F)); +} + +void +pcic_power_on (int slot) +{ + pcic_putb (slot, PCIC_STATUS, + pcic_getb (slot, PCIC_STATUS) | PCIC_POW); + DELAY (100000); + pcic_putb (slot, PCIC_POWER, + pcic_getb (slot, PCIC_POWER) | PCIC_DISRST | PCIC_PCPWRE); + DELAY (100000); + pcic_putb (slot, PCIC_POWER, + pcic_getb (slot, PCIC_POWER) | PCIC_OUTENA); +} + +void +pcic_power_off (int slot) +{ + pcic_putb (slot, PCIC_POWER, + pcic_getb (slot, PCIC_POWER) & ~(PCIC_OUTENA|PCIC_PCPWRE)); +} + +void +pcic_reset (int slot) +{ + /* assert RESET (by clearing a bit!), wait a bit, and de-assert it */ + pcic_putb (slot, PCIC_INT_GEN, + pcic_getb (slot, PCIC_INT_GEN) & ~PCIC_CARDRESET); + DELAY (100000); + pcic_putb (slot, PCIC_INT_GEN, + pcic_getb (slot, PCIC_INT_GEN) | PCIC_CARDRESET); +} +