summaryrefslogtreecommitdiff
path: root/sys/dev/pcmcia/pcmcia_conf.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pcmcia/pcmcia_conf.c')
-rw-r--r--sys/dev/pcmcia/pcmcia_conf.c657
1 files changed, 0 insertions, 657 deletions
diff --git a/sys/dev/pcmcia/pcmcia_conf.c b/sys/dev/pcmcia/pcmcia_conf.c
deleted file mode 100644
index 8a4e15ca9f6..00000000000
--- a/sys/dev/pcmcia/pcmcia_conf.c
+++ /dev/null
@@ -1,657 +0,0 @@
-/* $OpenBSD: pcmcia_conf.c,v 1.7 1998/08/13 06:39:22 deraadt Exp $ */
-/*
- * Copyright (c) 1996 John T. Kohl. All rights reserved.
- * Copyright (c) 1994 Stefan Grefen. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Charles Hannum.
- * This product includes software developed by Stefan Grefen.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-/*
- * This file is shared between user and kernel space, so be careful with the
- * coding conventions.
- */
-#ifdef _KERNEL
-#include <sys/errno.h>
-#else
-#include <errno.h>
-#endif
-#include <sys/types.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/device.h>
-#include <sys/time.h>
-#include <sys/systm.h>
-
-#include <dev/pcmcia/pcmciavar.h>
-#include <dev/pcmcia/pcmciareg.h>
-#include <dev/pcmcia/pcmcia_ioctl.h>
-
-#ifdef CFG_DEBUG
-static void dump __P((u_char *, int));
-
-static
-void dump(addr, len)
- u_char *addr;
- int len;
-{
- int i;
-
- for (i = 0; i < len; i++) {
- printf("%02x ", addr[i]);
- if (i != 0 && (i & 0xf) == 0)
- printf("\n");
- }
- if (i != 0 && (i & 0xf) == 0)
- printf("\n");
-}
-#endif
-
-int
-pcmcia_get_cf(pc_link, data, dlen, idx, pc_cf)
- struct pcmcia_link *pc_link;
- u_char *data;
- int dlen, idx;
- struct pcmcia_conf *pc_cf;
-{
- u_char code, len, *tbuf, *endp;
- int done;
-
- endp = data + dlen;
-
- done = 0;
- while (!done && data < endp) {
- code = *data++;
- if (code == CIS_NULL) {
- continue;
- }
- len = *data++;
-
- tbuf = data;
- data += len;
- switch (code) {
- case CIS_END:
- done = 1;
- break;
- case CIS_CFG_INFO:
- read_cfg_info(tbuf, len, pc_cf);
- break;
- case CIS_CFG_ENT:
- if ((idx & CFGENTRYMASK) != CFGENTRYID ||
- pc_cf->cfgid == 0)
- parse_cfent(tbuf, len, idx, pc_cf);
- break;
- default:
- break;
- }
- }
- return 0;
-}
-
-
-void
-read_cfg_info(tbuf, len, pc_cf)
- u_char *tbuf;
- int len;
- struct pcmcia_conf *pc_cf;
-{
- int rasz, rmsz;
-
- rasz = (tbuf[0] & TPCC_RASZ) >> TPCC_RASZ_SHIFT;
- rmsz = (tbuf[0] & TPCC_RMSZ) >> TPCC_RMSZ_SHIFT;
-
-#ifdef CFG_DEBUG
- printf("read_cfg_info\n");
- dump(tbuf, len);
-#endif
-
- pc_cf->cfg_off = 0;
- switch (rasz) {
- case 3:
- pc_cf->cfg_off |= (tbuf[5] << 24);
- case 2:
- pc_cf->cfg_off |= (tbuf[4] << 16);
- case 1:
- pc_cf->cfg_off |= (tbuf[3] << 8);
- case 0:
- pc_cf->cfg_off |= tbuf[2];
- }
-
- tbuf += rasz + 3;
- pc_cf->cfg_regmask = 0;
- switch (rmsz & 3) {
- case 3:
- pc_cf->cfg_regmask |= (tbuf[3] << 24);
- case 2:
- pc_cf->cfg_regmask |= (tbuf[2] << 16);
- case 1:
- pc_cf->cfg_regmask |= (tbuf[1] << 8);
- case 0:
- pc_cf->cfg_regmask |= tbuf[0];
- }
-}
-
-void
-parse_cfent(tbuf, len, slotid, pc_cf)
- u_char *tbuf;
- int len;
- int slotid;
- struct pcmcia_conf *pc_cf;
-{
- volatile int i, idx, defp, intface, k;
- int ios, ftrs;
- int host_addr_p, addr_size, len_size;
-
-#ifdef CFG_DEBUG
- printf("parse_cfent\n");
- dump(tbuf, len);
-#endif
-
- i = 0;
- intface = (tbuf[i] & TPCE_INDX_INT);
- idx = (tbuf[i] & TPCE_INDX_ENTRY);
- defp = (tbuf[i] & TPCE_INDX_DEF);
-
- if ((idx == slotid) || (defp && slotid!=-2 &&
- (slotid & CFGENTRYMASK) == CFGENTRYMASK)) {
- int j;
- if (intface) {
- i++;
- pc_cf->iocard = (tbuf[i] & TPCE_IF_TYPE) == 1;
- }
- i++;
- ftrs = tbuf[i++];
- for (j = 0; j < (ftrs & TPCE_FS_PWR); j++) {
- int pwr_desc = tbuf[i++];
- /* for each struct, skip all parameter defns */
- for (k = 0; k < 8; pwr_desc >>= 1, k++) {
- if (pwr_desc & 0x01) {
- /* skip bytes until non-ext found */
- while (tbuf[i++] & 0x80)
- continue;
- }
- }
- }
- /* TODO read timing info */
- if (ftrs & TPCE_FS_TD) {
-#define BONE(a,b) (j & a) != 7 << b ? 1 : 0
- int j = tbuf[i++];
- i += ((j & TPCE_FS_TD_WAIT) != 3 ? 1 : 0);
- i += BONE(TPCE_FS_TD_RDY,TPCE_FS_TD_RDY_SHIFT);
- i += BONE(TPCE_FS_TD_RSV,TPCE_FS_TD_RSV_SHIFT);
-#undef BONE
- }
- if (ftrs & TPCE_FS_IO) {
- int io_addrs[16], io_lens[16];
- int io_16, io_block_len, io_block_size, io_lines;
- int io_range;
-
- io_lines = tbuf[i] & TPCE_FS_IO_LINES;
- io_16 = tbuf[i] & TPCE_FS_IO_BUS16;
- io_range = tbuf[i] &TPCE_FS_IO_RANGE;
- i++;
- if (io_range) {
- int iptr, ilen, elen;
-
- io_block_len = (tbuf[i] & TPCE_FS_IO_LEN) >>
- TPCE_FS_IO_LEN_SHIFT;
- io_block_size = (tbuf[i] & TPCE_FS_IO_SIZE) >>
- TPCE_FS_IO_SIZE_SHIFT;
- ios = (tbuf[i] & TPCE_FS_IO_NUM) + 1;
- i++;
- elen=io_block_len+(io_block_len==3?1:0)+
- io_block_size+(io_block_size==3?1:0);
- if ((ftrs & TPCE_FS_IRQ) != 0) {
- iptr=(ios * elen) + i;
-#define IRQTYPE (TPCE_FS_IRQ_PULSE|TPCE_FS_IRQ_LEVEL)
-#define IRQMASK TPCE_FS_IRQ_MASK
- if ((tbuf[iptr] & IRQTYPE) == 0)
- if ((tbuf[iptr-elen] &
- IRQTYPE) != 0)
- iptr -= elen;
- if ((tbuf[iptr] & IRQMASK) != 0)
- ilen = 2;
- else
- ilen=1;
- }
- else
- ilen=0;
-
- if ((i + (ios * elen) + ilen) > len) {
- printf(
-"Warning: CIS range info doesn't fit in entry! Reducing # of ranges by 1\n");
- ios--;
- }
-
- for (j = 0; j < ios; j++) {
- io_addrs[j] = io_lens[j] = 0;
- switch (io_block_size) {
- case 3:
- io_addrs[j] |= tbuf[i+3] << 24;
- io_addrs[j] |= tbuf[i+2] << 16;
- case 2:
- io_addrs[j] |= tbuf[i+1] << 8;
- case 1:
- io_addrs[j] |= tbuf[i];
- break;
- }
- pc_cf->io[j].start = io_addrs[j];
- i += io_block_size +
- (io_block_size == 3 ? 1 : 0);
- switch (io_block_len) {
- case 3:
- io_lens[j] |= tbuf[i+3] << 24;
- io_lens[j] |= tbuf[i+2] << 16;
- case 2:
- io_lens[j] |= tbuf[i+1] << 8;
- case 1:
- io_lens[j] |= tbuf[i];
- break;
- }
- io_lens[j]++;
- if(io_lens[j] & 1) {
- printf(
-"Odd IO window length!! (Assuming incorrect CIS entry %d)\n", io_lens[j]);
- io_lens[j]--;
- }
-
- pc_cf->io[j].len = io_lens[j];
- pc_cf->io[j].flags = io_16 ?
- PCMCIA_MAP_16 : PCMCIA_MAP_8;
- i += io_block_len +
- (io_block_len == 3 ? 1 : 0);
- }
- pc_cf->iowin = ios;
- }
- else {
- pc_cf->iowin = 1;
- pc_cf->io[0].len = 1 << io_lines;
- pc_cf->io[0].start= 0 ;
- pc_cf->io[0].flags = io_16 ?
- PCMCIA_MAP_16 : PCMCIA_MAP_8;
- }
- }
- if (ftrs & TPCE_FS_IRQ) {
- pc_cf->irq_level = (tbuf[i] & TPCE_FS_IRQ_LEVEL) != 0;
- pc_cf->irq_pulse = (tbuf[i] & TPCE_FS_IRQ_PULSE) != 0;
- pc_cf->irq_share = (tbuf[i] & TPCE_FS_IRQ_SHARE) != 0;
- if (tbuf[i] & TPCE_FS_IRQ_MASK) {
- pc_cf->irq_mask = (tbuf[i+2] << 8) + tbuf[i+1];
- if (pc_cf->irq_mask & (1 << 2))
- pc_cf->irq_mask |= 1 << 9;
- i += 2;
- } else {
- pc_cf->irq_num = tbuf[i] & TPCE_FS_IRQ_IRQN;
- pc_cf->irq_mask = -1;
- }
-
- i++;
- }
- if (ftrs & TPCE_FS_MEM) {
- int memp, mems, mem_lens[16], mem_caddrs[16],
- mem_haddrs[16];
- memp = 1;
- switch ((ftrs & TPCE_FS_MEM) >> TPCE_FS_MEM_SHIFT) {
- case 1:
- mems = 1;
- mem_lens[0] = (tbuf[i+1] << 8) + tbuf[i];
- mem_lens[0] <<= 8;
-
- break;
- case 2:
- mems = 1;
- mem_lens[0] = (tbuf[i+1] << 8) + tbuf[i];
- mem_caddrs[0] = mem_haddrs[0] =
- (tbuf[i+3] << 8) + tbuf[i+2];
-
- mem_lens[0] <<= 8;
- mem_caddrs[0] <<= 8;
-
- break;
- case 3:
- host_addr_p = tbuf[i] & TPCE_FS_MEM_HOST;
- addr_size = (tbuf[i] & TPCE_FS_MEM_ADDR) >>
- TPCE_FS_MEM_ADDR_SHIFT;
- len_size = (tbuf[i] & TPCE_FS_MEM_LEN) >>
- TPCE_FS_MEM_LEN_SHIFT;
- mems = (tbuf[i] & TPCE_FS_MEM_WINS) + 1;
- i++;
- for (j = 0; j < mems; j++) {
- mem_lens[j] = 0;
- mem_caddrs[j] = 0;
- mem_haddrs[j] = 0;
- switch (len_size) {
- case 3:
- mem_lens[j] |=
- (tbuf[i+2] << 16);
- case 2:
- mem_lens[j] |=
- (tbuf[i+1] << 8);
- case 1:
- mem_lens[j] |= tbuf[i];
- }
- i += len_size;
- switch (addr_size) {
- case 3:
- mem_caddrs[j] |=
- (tbuf[i+2] << 16);
- case 2:
- mem_caddrs[j] |=
- (tbuf[i+1] << 8);
- case 1:
- mem_caddrs[j] |= tbuf[i];
- }
- i += addr_size;
- if (host_addr_p) {
- switch (addr_size) {
- case 3:
- mem_haddrs[j] |=
- (tbuf[i+2] << 16);
- case 2:
- mem_haddrs[j] |=
- (tbuf[i+1] << 8);
- case 1:
- mem_haddrs[j] |=
- tbuf[i];
- }
- i += addr_size;
- }
- mem_lens[j] <<= 8;
- mem_caddrs[j] <<= 8;
- mem_haddrs[j] <<= 8;
-
- }
- break;
- default:
- mems = 0;
- break;
- }
- for (j = 0; j < mems; j++) {
- pc_cf->mem[j].len = mem_lens[j];
- pc_cf->mem[j].caddr = mem_caddrs[j];
- pc_cf->mem[j].start = mem_haddrs[j];
- pc_cf->mem[j].flags = 0;
- }
- pc_cf->memwin = mems;
- } else
- pc_cf->memwin = 0;
- return;
- }
-
-
- if (slotid == -2 ) {
- /* find matching slotid */
- struct pcmcia_conf tmp_cf;
- /* get defaults */
- parse_cfent(tbuf, len, -1, &tmp_cf);
- /* change to selected */
- parse_cfent(tbuf, len, idx, &tmp_cf);
-#ifdef CFG_DEBUG
- printf("slotid %d %d iowin %d %d memwin %d %d wins %x %x %d %d\n",
- pc_cf->iocard , tmp_cf.iocard,
- pc_cf->iowin , tmp_cf.iowin,
- pc_cf->memwin , tmp_cf.memwin,
- pc_cf->io[0].start , tmp_cf.io[0].start,
- pc_cf->io[0].len , tmp_cf.io[0].len
- );
-#endif
-
- if((pc_cf->iocard == tmp_cf.iocard) && /* same type */
- (pc_cf->iowin == tmp_cf.iowin) &&
- (pc_cf->memwin == tmp_cf.memwin)) {
- int i;
- for (i = 0; i < tmp_cf.iowin; i++)
- if (pc_cf->io[i].len != tmp_cf.io[i].len ||
- pc_cf->io[i].start != tmp_cf.io[i].start)
- return;
-
- for (i = 0; i < tmp_cf.memwin; i++)
- if (pc_cf->mem[i].len!=tmp_cf.mem[i].len ||
- pc_cf->mem[i].start!=tmp_cf.mem[i].start)
- return;
-
- /* *pc_cf = tmp_cf; */
- pc_cf->cfgid = idx;
- }
- return;
- }
-}
-
-void
-pcmcia_getstr(buf, pptr, end)
- char *buf;
- u_char **pptr;
- u_char *end;
-{
- u_char *ptr = *pptr;
- char *eb = buf + MAX_CIS_NAMELEN - 1;
-
- while (buf < eb && ptr < end)
- switch (*ptr) {
- case 0x00:
- ptr++;
- /*FALLTHROUGH*/
- case 0xff:
- *pptr = ptr;
- *buf = '\0';
- return;
-
- default:
- *buf++ = *ptr++;
- break;
- }
- printf("Warning: Maximum CIS string length exceeded\n");
- *buf = '\0';
-
- /* Keep going until we find the end */
- while (ptr < end)
- switch (*ptr) {
- case 0x00:
- ptr++;
- /*FALLTHROUGH*/
- case 0xff:
- *pptr = ptr;
- return;
-
- default:
- ptr++;
- break;
- }
-
- *pptr = ptr;
-}
-
-
-int
-pcmcia_get_cisver1(pc_link, data, len, manu, model, add_inf1, add_inf2)
- struct pcmcia_link *pc_link;
- u_char *data;
- int len;
- char *manu, *model, *add_inf1, *add_inf2;
-{
- u_char *p, *end;
-
- p = data;
- end = data + len;
- while ((*p != (u_char) 0xff) && (p < end)) {
- int clen = *(p + 1);
- int maj, min;
- if (*p == CIS_VER1) {
- u_char *pp = p + 2;
- maj = *pp++;
- min = *pp++;
- if ((maj != 4 || min != 1) &&
- (maj != 5 || min != 0)) {
- printf("wrong version id %d.%d for card in slot %d\n",
- maj, min, pc_link->slot);
- return ENODEV;
- }
- pcmcia_getstr(manu, &pp, end);
- pcmcia_getstr(model, &pp, end);
- pcmcia_getstr(add_inf1, &pp, end);
- pcmcia_getstr(add_inf2, &pp, end);
- if (*pp != (u_char) 0xff) {
- printf("WARNING: broken id for card in slot %d\n", pc_link->slot);
- printf("manu %s model %s add_inf1 %s add_inf2 %s\n", manu, model, add_inf1, add_inf2);
- return 0;
- }
- return 0;
- }
- p += clen + 2;
- }
-#ifdef CFG_DEBUG
- printf("get_cisver1 failed, buffer [%p,%p)\n", p, end);
-#endif
- return ENODEV;
-}
-
-#define NULLCP (void *)0
-
-/* pcmcia template string match. A '*' matches any number of characters.
- A NULL template matches all strings.
- return-value
- 0 nomatch
- 1 wildcard match
- 2 excact match
- */
-int
-pcmcia_strcmp(templ, val, flags, msg)
- const char *templ;
- const char *val;
- int flags;
- const char *msg;
-{
- const char *ltempl = NULLCP;
- const char *lval = NULLCP;
-
- if (flags & PC_SHOWME)
- printf("%s = `%s'-`%s'\n", msg, templ ? templ : "X", val);
-
- if (templ == NULLCP) {
- return 1;
- }
- while (*val) {
- while (*templ == '*') {
- ltempl = ++templ;
- lval = val;
- }
- if (*templ == *val) {
- templ++;
- val++;
- } else {
- if (ltempl == NULLCP)
- return 0;
- val = ++lval;
- templ = ltempl;
- }
- }
- if (*templ != 0 && *templ != '*')
- return 0;
- return (ltempl ? 1 : 2);
-}
-
-/*
- * Return a match value to estimate how good a match the specified driver
- * is for this particular card.
- */
-
-int
-pcmcia_matchvalue(card, dentry)
- const struct pcmcia_cardinfo *card;
- struct pcmciadevs *dentry;
-{
- int match;
-
-#ifdef PCMCIA_DEBUG
- dentry->flags |= PC_SHOWME;
-#endif
- match = pcmcia_strcmp(dentry->manufacturer,
- card->manufacturer,
- dentry->flags, "manufacturer")<<6;
- match |= pcmcia_strcmp(dentry->model,
- card->model, dentry->flags, "model")<<4;
- match |= pcmcia_strcmp(dentry->add_inf1,
- card->add_info1, dentry->flags, "info1")<<2;
- match |= pcmcia_strcmp(dentry->add_inf2,
- card->add_info2, dentry->flags, "info2");
-#ifdef PCMCIA_DEBUG
- printf("match == %d\n", match);
-#endif
- return match;
-}
-
-int
-pcmcia_bestvalue(card, dentries, nentries, rmatch)
- struct pcmcia_cardinfo *card;
- struct pcmciadevs *dentries;
- int nentries;
- struct pcmciadevs **rmatch;
-{
- int bestmatch, thismatch;
- register int i;
-
- for (i = 0, bestmatch = 0; i < nentries; i++) {
- if ((thismatch = pcmcia_matchvalue(card, &dentries[i])) >
- bestmatch) {
- bestmatch = thismatch;
- *rmatch = &dentries[i];
- }
- }
- return bestmatch;
-}
-
-int
-pcmcia_slave_match(parent, match, aux, devs, ndevs)
- struct device *parent;
- void *match, *aux;
- struct pcmciadevs *devs;
- int ndevs;
-{
- struct pcmcia_attach_args *paa = aux;
- struct device *self = match;
- struct pcmciadevs *devmatch;
- int value;
-
- if (paa->paa_link->fordriver &&
- strcmp(paa->paa_link->fordriver,
- self->dv_cfdata->cf_driver->cd_name))
- return 0; /* wrong driver */
- value = pcmcia_bestvalue(paa->paa_cardinfo, devs, ndevs, &devmatch);
- if (value > paa->paa_bestmatch) {
- paa->paa_bestmatch = value;
- paa->paa_link->device = devmatch;
-#ifdef PCMCIA_DEBUG
- printf("pcmcia_slave_match: best so far, %p->%p\n",
- paa->paa_link, devmatch);
- printf("pcmcia_slave_match returns %d\n", value);
- delay(2000000);
-#endif
- if (!paa->paa_matchonly)
- return value;
- }
- return 0;
-}