From a0742ff39fe05e0f8194c9ddb7f7d61de1ee655a Mon Sep 17 00:00:00 2001 From: "Federico G. Schwindt" Date: Fri, 5 Aug 2005 18:21:05 +0000 Subject: correct io base/limit registers handling. from mycroft. only affects multi function cards for now. this fixes the Novatel Wireless Merlin UMTS Modem reported by Bolke de Bruin tested by several ppl, commit deraadt@. --- sys/dev/pcmcia/pcmcia.c | 60 +++++++++++++++++++--------------------------- sys/dev/pcmcia/pcmciavar.h | 6 ++--- 2 files changed, 28 insertions(+), 38 deletions(-) diff --git a/sys/dev/pcmcia/pcmcia.c b/sys/dev/pcmcia/pcmcia.c index faa63d647cf..38f9924723e 100644 --- a/sys/dev/pcmcia/pcmcia.c +++ b/sys/dev/pcmcia/pcmcia.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pcmcia.c,v 1.34 2005/01/27 17:03:23 millert Exp $ */ +/* $OpenBSD: pcmcia.c,v 1.35 2005/08/05 18:21:04 fgsch Exp $ */ /* $NetBSD: pcmcia.c,v 1.9 1998/08/13 02:10:55 eeh Exp $ */ /* @@ -512,22 +512,16 @@ pcmcia_function_enable(pf) pcmcia_ccr_write(pf, PCMCIA_CCR_SOCKETCOPY, 0); if (pcmcia_mfc(pf->sc)) { - long tmp, iosize; - - tmp = pf->pf_mfc_iomax - pf->pf_mfc_iobase; - /* round up to nearest (2^n)-1 */ - for (iosize = 1; iosize < tmp; iosize <<= 1) - ; - iosize--; - pcmcia_ccr_write(pf, PCMCIA_CCR_IOBASE0, - pf->pf_mfc_iobase & 0xff); + (pf->pf_mfc_iobase >> 0) & 0xff); pcmcia_ccr_write(pf, PCMCIA_CCR_IOBASE1, - (pf->pf_mfc_iobase >> 8) & 0xff); - pcmcia_ccr_write(pf, PCMCIA_CCR_IOBASE2, 0); - pcmcia_ccr_write(pf, PCMCIA_CCR_IOBASE3, 0); - - pcmcia_ccr_write(pf, PCMCIA_CCR_IOSIZE, iosize); + (pf->pf_mfc_iobase >> 8) & 0xff); + pcmcia_ccr_write(pf, PCMCIA_CCR_IOBASE2, + (pf->pf_mfc_iobase >> 16) & 0xff); + pcmcia_ccr_write(pf, PCMCIA_CCR_IOBASE3, + (pf->pf_mfc_iobase >> 24) & 0xff); + pcmcia_ccr_write(pf, PCMCIA_CCR_IOSIZE, + pf->pf_mfc_iomax - pf->pf_mfc_iobase); } #ifdef PCMCIADEBUG @@ -644,33 +638,29 @@ pcmcia_io_map(pf, width, offset, size, pcihp, windowp) */ if (pcmcia_mfc(pf->sc)) { - long tmp, iosize; + bus_addr_t iobase = pcihp->addr; + bus_addr_t iomax = pcihp->addr + pcihp->size - 1; if (pf->pf_mfc_iomax == 0) { - pf->pf_mfc_iobase = pcihp->addr + offset; - pf->pf_mfc_iomax = pf->pf_mfc_iobase + size; + pf->pf_mfc_iobase = iobase; + pf->pf_mfc_iomax = iomax; } else { - /* This makes the assumption that nothing overlaps. */ - if (pf->pf_mfc_iobase > pcihp->addr + offset) - pf->pf_mfc_iobase = pcihp->addr + offset; - if (pf->pf_mfc_iomax < pcihp->addr + offset + size) - pf->pf_mfc_iomax = pcihp->addr + offset + size; + if (iobase < pf->pf_mfc_iobase) + pf->pf_mfc_iobase = iobase; + if (iomax > pf->pf_mfc_iomax) + pf->pf_mfc_iomax = iomax; } - tmp = pf->pf_mfc_iomax - pf->pf_mfc_iobase; - /* round up to nearest (2^n)-1 */ - for (iosize = 1; iosize >= tmp; iosize <<= 1) - ; - iosize--; - pcmcia_ccr_write(pf, PCMCIA_CCR_IOBASE0, - pf->pf_mfc_iobase & 0xff); + (pf->pf_mfc_iobase >> 0) & 0xff); pcmcia_ccr_write(pf, PCMCIA_CCR_IOBASE1, - (pf->pf_mfc_iobase >> 8) & 0xff); - pcmcia_ccr_write(pf, PCMCIA_CCR_IOBASE2, 0); - pcmcia_ccr_write(pf, PCMCIA_CCR_IOBASE3, 0); - - pcmcia_ccr_write(pf, PCMCIA_CCR_IOSIZE, iosize); + (pf->pf_mfc_iobase >> 8) & 0xff); + pcmcia_ccr_write(pf, PCMCIA_CCR_IOBASE2, + (pf->pf_mfc_iobase >> 16) & 0xff); + pcmcia_ccr_write(pf, PCMCIA_CCR_IOBASE3, + (pf->pf_mfc_iobase >> 24) & 0xff); + pcmcia_ccr_write(pf, PCMCIA_CCR_IOSIZE, + pf->pf_mfc_iomax - pf->pf_mfc_iobase); reg = pcmcia_ccr_read(pf, PCMCIA_CCR_OPTION); reg |= PCMCIA_CCR_OPTION_ADDR_DECODE; diff --git a/sys/dev/pcmcia/pcmciavar.h b/sys/dev/pcmcia/pcmciavar.h index 4bd4c7b0158..752d58ad7a4 100644 --- a/sys/dev/pcmcia/pcmciavar.h +++ b/sys/dev/pcmcia/pcmciavar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pcmciavar.h,v 1.18 2005/01/27 17:03:23 millert Exp $ */ +/* $OpenBSD: pcmciavar.h,v 1.19 2005/08/05 18:21:04 fgsch Exp $ */ /* $NetBSD: pcmciavar.h,v 1.5 1998/07/19 17:28:17 christos Exp $ */ /* @@ -126,8 +126,8 @@ struct pcmcia_function { #define pf_ccr_realsize pf_pcmh.realsize bus_addr_t pf_ccr_offset; int pf_ccr_window; - long pf_mfc_iobase; - long pf_mfc_iomax; + bus_addr_t pf_mfc_iobase; + bus_addr_t pf_mfc_iomax; int (*ih_fct)(void *); void *ih_arg; int ih_ipl; -- cgit v1.2.3