From owner-freebsd-current Wed Mar 15 9: 0:26 2000 Delivered-To: freebsd-current@freebsd.org Received: from piranha.amis.net (piranha.amis.net [212.18.32.3]) by hub.freebsd.org (Postfix) with ESMTP id 4BAAD37B9CC for ; Wed, 15 Mar 2000 09:00:09 -0800 (PST) (envelope-from blaz@amis.net) Received: from gold.amis.net (gold.amis.net [212.18.32.254]) by piranha.amis.net (Postfix) with ESMTP id 223F15D2D for ; Wed, 15 Mar 2000 18:00:05 +0100 (CET) Date: Wed, 15 Mar 2000 18:00:04 +0100 (CET) From: Blaz Zupan To: freebsd-current@freebsd.org Subject: pccard not working on 4.0-RELEASE Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG In accordance with Murphy's law, 4.0-RELEASE seems to have broken pccard support for me. I have a WaveLAN wireless LAN card and use the optional ISA-to-pccard bridge. On a two week old -current, it was working just fine, displaying the following: pcic: polling mode pcic: polling mode pcic0: at port 0x3e0 iomem 0xd0000 on isa0 pccard0: on pcic0 pccard1: on pcic0 My kernel config file says: device pcic0 at isa? port 0x3e0 iomem 0xd0000 device wi Notice that I don't specify an irq for pcic0, because I am really short of them. So pcic is run in polling mode. I also tried specifying an irq with exactly the same result. With a 4.0-RELEASE kernel it does not work, pcic0 is simply not found and absolutely no message is being displayed. Applying the below patch which effectively backs out revision 1.89 of sys/pccard/pcic.c makes the card work again. It is very unfortunate that it is too late to fix this :( Blaz Zupan, blaz@amis.net, http://home.amis.net/blaz/ Medinet d.o.o., Linhartova 21, 2000 Maribor, Slovenia Index: pcic.c =================================================================== RCS file: /ftp/pub/FreeBSD/development/FreeBSD-CVS/src/sys/pccard/pcic.c,v retrieving revision 1.89 retrieving revision 1.88 diff -u -r1.89 -r1.88 --- pcic.c 2000/03/10 05:43:28 1.89 +++ pcic.c 2000/02/21 06:56:29 1.88 @@ -27,7 +27,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/pccard/pcic.c,v 1.89 2000/03/10 05:43:28 imp Exp $ + * $FreeBSD: src/sys/pccard/pcic.c,v 1.88 2000/02/21 06:56:29 imp Exp $ */ #include @@ -44,10 +44,6 @@ #include #include -/* Get pnp IDs */ -#include -#include - /* * Prototypes for interrupt handler. */ @@ -80,20 +76,9 @@ u_char *regs; /* Pointer to regs in mem */ } pcic_slots[PCIC_MAX_SLOTS]; +static int pcic_irq; static struct slot_ctrl cinfo; -static struct isa_pnp_id pcic_ids[] = { - {PCIC_PNP_82365, NULL}, /* PNP0E00 */ - {PCIC_PNP_CL_PD6720, NULL}, /* PNP0E01 */ - {PCIC_PNP_VLSI_82C146, NULL}, /* PNP0E02 */ - {PCIC_PNP_82365_CARDBUS, NULL}, /* PNP0E03 */ - {0} -}; - -static int validunits = 0; - -#define GET_UNIT(d) *(int *)device_get_softc(d) -#define SET_UNIT(d,u) *(int *)device_get_softc(d) = (u) /* * Internal inline functions for accessing the PCIC. @@ -279,16 +264,16 @@ struct slot *slt; struct pcic_slot *sp; unsigned char c; + void *ih; char *name; + int i; int error; - struct resource *r; + struct resource *res = 0; int rid; static int maybe_vlsi = 0; - /* Check isapnp ids */ - error = ISA_PNP_PROBE(device_get_parent(dev), dev, pcic_ids); - if (error == ENXIO) - return (ENXIO); + if (device_get_unit(dev) != 0) + return ENXIO; /* * Initialise controller information structure. @@ -304,26 +289,22 @@ cinfo.maxmem = PCIC_MEM_WIN; cinfo.maxio = PCIC_IO_WIN; - if (bus_get_resource_start(dev, SYS_RES_IOPORT, 0) == 0) - bus_set_resource(dev, SYS_RES_IOPORT, 0, PCIC_INDEX0, 2); - rid = 0; - r = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE); - if (!r) { - if (bootverbose) - device_printf(dev, "Cannot get I/O range\n"); - return ENOMEM; - } - - sp = &pcic_slots[validunits * PCIC_CARD_SLOTS]; - for (slotnum = 0; slotnum < PCIC_CARD_SLOTS; slotnum++, sp++) { + sp = pcic_slots; + for (slotnum = 0; slotnum < PCIC_MAX_SLOTS; slotnum++, sp++) { /* * Initialise the PCIC slot table. */ sp->getb = getb1; sp->putb = putb1; - sp->index = rman_get_start(r); - sp->data = sp->index + 1; - sp->offset = slotnum * PCIC_SLOT_SIZE; + if (slotnum < 4) { + sp->index = PCIC_INDEX_0; + sp->data = PCIC_DATA_0; + sp->offset = slotnum * PCIC_SLOT_SIZE; + } else { + sp->index = PCIC_INDEX_1; + sp->data = PCIC_DATA_1; + sp->offset = (slotnum - 4) * PCIC_SLOT_SIZE; + } /* * XXX - Screwed up slot 1 on the VLSI chips. According to * the Linux PCMCIA code from David Hinds, working chipsets @@ -463,13 +444,47 @@ * Allocate a slot and initialise the data structures. */ validslots++; - sp->slotnum = slotnum + validunits * PCIC_CARD_SLOTS; + sp->slotnum = slotnum; slt = pccard_alloc_slot(&cinfo); if (slt == 0) continue; slt->cdata = sp; sp->slt = slt; /* + * If we haven't allocated an interrupt for the controller, + * then attempt to get one. + */ + if (pcic_irq == 0) { + /* See if the user has requested a specific IRQ */ + if (!getenv_int("machdep.pccard.pcic_irq", &pcic_irq)) + pcic_irq = -1; + rid = 0; + if (pcic_irq) { + if (pcic_irq < 0) + pcic_irq = 0; + res = bus_alloc_resource(dev, SYS_RES_IRQ, + &rid, pcic_irq, ~0, 1, RF_ACTIVE); + } + if (res) { + error = bus_setup_intr(dev, res, + INTR_TYPE_MISC, pcicintr, NULL, &ih); + if (error) { + bus_release_resource(dev, SYS_RES_IRQ, + rid, res); + return error; + } + pcic_irq = rman_get_start(res); + printf("pcic: management irq %d\n", pcic_irq); + } else { + if (pcic_irq) + printf("pcic: polling mode, can't alloc %d\n", + pcic_irq); + else + printf("pcic: polling mode\n"); + pcic_irq = 0; + } + } + /* * Modem cards send the speaker audio (dialing noises) * to the host's speaker. Cirrus Logic PCIC chips must * enable this. There is also a Low Power Dynamic Mode bit @@ -479,86 +494,33 @@ if (sp->controller == PCIC_PD672X) { setb(sp, PCIC_MISC1, PCIC_SPKR_EN); setb(sp, PCIC_MISC2, PCIC_LPDM_EN); - } - } - bus_release_resource(dev, SYS_RES_IOPORT, rid, r); - return(validslots ? 0 : ENXIO); -} - -static int -pcic_attach(device_t dev) -{ - void *ih; - int rid; - struct resource *r; - int irq; - int error; - struct pcic_slot *sp; - int i; - - sp = &pcic_slots[GET_UNIT(dev) * PCIC_CARD_SLOTS]; - for (i = 0; i < PCIC_CARD_SLOTS; i++, sp++) { - if (sp->slt) - device_add_child(dev, NULL, -1); - } - SET_UNIT(dev, validunits); - validunits++; - - rid = 0; - r = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE); - if (!r) { - return ENXIO; - } - - irq = bus_get_resource_start(dev, SYS_RES_IRQ, 0); - if (irq == 0) { - /* See if the user has requested a specific IRQ */ - if (!getenv_int("machdep.pccard.pcic_irq", &irq)) - irq = 0; - } - rid = 0; - r = 0; - if (irq >= 0) { - r = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, irq, - ~0, 1, RF_ACTIVE); - } - if (r) { - error = bus_setup_intr(dev, r, INTR_TYPE_MISC, - pcicintr, (void *) GET_UNIT(dev), &ih); - if (error) { - bus_release_resource(dev, SYS_RES_IRQ, rid, r); - return error; } - irq = rman_get_start(r); - device_printf(dev, "management irq %d\n", irq); - } else { - irq = 0; - } - if (irq == 0) { - pcictimeout_ch = timeout(pcictimeout, (void *) GET_UNIT(dev), - hz/2); - device_printf(dev, "Polling mode\n"); - } - - sp = &pcic_slots[GET_UNIT(dev) * PCIC_CARD_SLOTS]; - for (i = 0; i < PCIC_CARD_SLOTS; i++, sp++) { - /* Assign IRQ */ - sp->putb(sp, PCIC_STAT_INT, (irq << 4) | 0xF); - - /* Check for changes */ + /* + * Check for a card in this slot. + */ setb(sp, PCIC_POWER, PCIC_PCPWRE| PCIC_DISRST); - if (sp->slt == NULL) - continue; if ((sp->getb(sp, PCIC_STATUS) & PCIC_CD) != PCIC_CD) { - sp->slt->laststate = sp->slt->state = empty; + slt->laststate = slt->state = empty; } else { - sp->slt->laststate = sp->slt->state = filled; + slt->laststate = slt->state = filled; pccard_event(sp->slt, card_inserted); } - sp->slt->irq = irq; + /* + * Assign IRQ for slot changes + */ + if (pcic_irq > 0) + sp->putb(sp, PCIC_STAT_INT, (pcic_irq << 4) | 0xF); + else if (pcic_irq == 0) + sp->putb(sp, PCIC_STAT_INT, 0xF); + } + if (validslots && pcic_irq <= 0) + pcictimeout_ch = timeout(pcictimeout, 0, hz/2); + if (validslots) { + for (i = 0; i < validslots; i++) { + device_add_child(dev, NULL, -1); + } } - - return (bus_generic_attach(dev)); + return(validslots ? 0 : ENXIO); } /* @@ -749,8 +711,8 @@ static void pcictimeout(void *chan) { - pcicintr(chan); - pcictimeout_ch = timeout(pcictimeout, chan, hz/2); + pcicintr(0); + pcictimeout_ch = timeout(pcictimeout, 0, hz/2); } /* @@ -764,11 +726,10 @@ { int slot, s; unsigned char chg; - int unit = (int) arg; - struct pcic_slot *sp = &pcic_slots[unit * PCIC_CARD_SLOTS]; + struct pcic_slot *sp = pcic_slots; s = splhigh(); - for (slot = 0; slot < PCIC_CARD_SLOTS; slot++, sp++) { + for (slot = 0; slot < PCIC_MAX_SLOTS; slot++, sp++) { if (sp->slt && (chg = sp->getb(sp, PCIC_STAT_CHG)) != 0) { if (chg & PCIC_CDTCH) { if ((sp->getb(sp, PCIC_STATUS) & PCIC_CD) == @@ -791,7 +752,8 @@ { struct pcic_slot *sp = slt->cdata; - sp->putb(sp, PCIC_STAT_INT, (slt->irq << 4) | 0xF); + if (pcic_irq > 0) + sp->putb(sp, PCIC_STAT_INT, (pcic_irq << 4) | 0xF); if (sp->controller == PCIC_PD672X) { setb(sp, PCIC_MISC1, PCIC_SPKR_EN); setb(sp, PCIC_MISC2, PCIC_LPDM_EN); @@ -919,7 +881,7 @@ static device_method_t pcic_methods[] = { /* Device interface */ DEVMETHOD(device_probe, pcic_probe), - DEVMETHOD(device_attach, pcic_attach), + DEVMETHOD(device_attach, bus_generic_attach), DEVMETHOD(device_detach, bus_generic_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, bus_generic_suspend), @@ -942,7 +904,7 @@ static driver_t pcic_driver = { "pcic", pcic_methods, - sizeof(int) + 1, /* no softc */ }; DRIVER_MODULE(pcic, isa, pcic_driver, pcic_devclass, 0, 0); Index: i82365.h =================================================================== RCS file: /ftp/pub/FreeBSD/development/FreeBSD-CVS/src/sys/pccard/i82365.h,v retrieving revision 1.10 retrieving revision 1.9 diff -u -r1.10 -r1.9 --- i82365.h 2000/03/10 05:43:28 1.10 +++ i82365.h 1998/08/25 22:46:44 1.9 @@ -31,8 +31,6 @@ * 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. - * - * $FreeBSD: src/sys/pccard/i82365.h,v 1.10 2000/03/10 05:43:28 imp Exp $ */ #define PCIC_I82365 0 /* Intel chip */ @@ -61,11 +59,10 @@ * identify the port number, and the lower 6 bits * select one of the 64 possible data registers. */ -#define PCIC_INDEX_0 0x3e0 /* index reg, chips 0 and 1 */ +#define PCIC_INDEX_0 0x3E0 /* index reg, chips 0 and 1 */ #define PCIC_DATA_0 (PCIC_INDEX_0 + 1) /* data reg, chips 0 and 1 */ #define PCIC_INDEX_1 (PCIC_INDEX_0 + 2) /* index reg, chips 2 and 3 */ #define PCIC_DATA_1 (PCIC_INDEX_1 + 1) /* data reg, chips 2 and 3 */ - /* * Register index addresses. */ @@ -226,6 +223,4 @@ #define PCIC_IO_WIN 2 #define PCIC_MEM_WIN 5 -#define PCIC_CARD_SLOTS 4 -#define PCIC_MAX_CARDS 2 -#define PCIC_MAX_SLOTS (PCIC_MAX_CARDS * PCIC_CARD_SLOTS) +#define PCIC_MAX_SLOTS 8 To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message