Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 Mar 2000 18:00:04 +0100 (CET)
From:      Blaz Zupan <blaz@amis.net>
To:        freebsd-current@freebsd.org
Subject:   pccard not working on 4.0-RELEASE
Message-ID:  <Pine.BSF.4.21.0003151754580.205-100000@gold.amis.net>

next in thread | raw e-mail | index | archive | help
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: <Vadem 469> at port 0x3e0 iomem 0xd0000 on isa0
pccard0: <PC Card bus -- kludge version> on pcic0
pccard1: <PC Card bus -- kludge version> 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 <sys/param.h>
@@ -44,10 +44,6 @@
 #include <pccard/slot.h>
 #include <pccard/pcic.h>
 
-/* Get pnp IDs */
-#include <isa/isavar.h>
-#include <dev/pcic/i82365reg.h>
-
 /*
  *	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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.21.0003151754580.205-100000>