Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 16 Feb 2003 11:43:28 +0100 (CET)
From:      Michal Mertl <mime@traveller.cz>
To:        "M. Warner Losh" <imp@bsdimp.com>
Cc:        pmelo@fe.uc.pt, freebsd-mobile@FreeBSD.ORG
Subject:   Re: Problems with serial port on Xircom RBEM56G
Message-ID:  <20030216113756.J84326@prg.traveller.cz>
In-Reply-To: <20030215.230132.67883547.imp@bsdimp.com>
References:  <00fc01c2d56a$0054c3c0$0a00a8c0@casa> <20030215.230132.67883547.imp@bsdimp.com>

next in thread | previous in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
I've just tried my luck on modem part myself. It's working (I'm currently
connected with it). There's only problem with detach (card removal) - I
guess sio doesn't detach so the resources aren't freed and machine panics
on next insertion.

-- 
Michal Mertl
mime@traveller.cz
[-- Attachment #2 --]
--- cardbus_cis.c.ori	Sun Feb 16 11:38:19 2003
+++ cardbus_cis.c	Sun Feb 16 11:38:43 2003
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/cardbus/cardbus_cis.c,v 1.32 2003/02/16 00:20:24 scottl Exp $
+ * $FreeBSD: src/sys/dev/cardbus/cardbus_cis.c,v 1.31 2003/02/12 06:11:47 imp Exp $
  */
 
 /*
@@ -41,7 +41,6 @@
 #include <machine/bus.h>
 #include <machine/resource.h>
 #include <sys/rman.h>
-#include <sys/endian.h>
 
 #include <sys/pciio.h>
 #include <dev/pci/pcivar.h>
@@ -147,11 +146,13 @@
 	uint32_t devid;	/* Vendor/device of the card */
 	int	type;
 #define	CARDBUS_QUIRK_MAP_REG	1 /* PCI map register in weird place */
+#define	CARDBUS_QUIRK_RID_COUNT	2 /* RID arg1 should have arg2 count */
 	int	arg1;
 	int	arg2;
 };
 
 struct cardbus_quirk cardbus_quirks[] = {
+	{ 0x0103115d, CARDBUS_QUIRK_RID_COUNT, 0x10, 0x8 }, /* Xircom CBEM56G modem */
 	{ 0 }
 };
 
@@ -392,45 +393,47 @@
 {
 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
 	int type;
-	uint8_t reg;
+	int reg;
 	uint32_t bar;
 
+	if (cardbus_cis_debug) {
+		/* XXX print something XXX */
+	}
 	if (len != 6) {
-		device_printf(cbdev, "CIS BAR length not 6 (%d)\n", len);
+		printf("*** ERROR *** BAR length not 6 (%d)\n", len);
 		return (EINVAL);
 	}
-
-	reg = *tupledata;
-	len = le32toh(*(uint32_t*)(tupledata + 2));
+	/* XXX the next two lines are bogus and contain endian errors */
+	reg = *(uint16_t*)tupledata;
+	len = *(uint32_t*)(tupledata + 2);
 	if (reg & TPL_BAR_REG_AS) {
 		type = SYS_RES_IOPORT;
 	} else {
 		type = SYS_RES_MEMORY;
 	}
-
-	bar = reg & TPL_BAR_REG_ASI_MASK;
-	if (bar == 0) {
-		device_printf(cbdev, "Invalid BAR type 0 in CIS\n");
-		return (EINVAL);	/* XXX Return an error? */
-	} else if (bar == 7) {
-		/* XXX Should we try to map in Option ROMs? */
+	bar = (reg & TPL_BAR_REG_ASI_MASK) - 1;
+	if (bar < 0 || bar > 5 ||
+	    (type == SYS_RES_IOPORT && bar == 5)) {
+		device_printf(cbdev, "Invalid BAR number: %02x(%02x)\n",
+		    reg, bar);
 		return (0);
 	}
-		
-	bar = CARDBUS_BASE0_REG + (bar - 1) * 4;
-
+	bar = CARDBUS_BASE0_REG + bar * 4;
 	if (type == SYS_RES_MEMORY) {
 		if (bar & TPL_BAR_REG_PREFETCHABLE)
 			dinfo->mprefetchable |= BARBIT(bar);
 		if (bar & TPL_BAR_REG_BELOW1MB)
 			dinfo->mbelow1mb |= BARBIT(bar);
+	} else if (type == SYS_RES_IOPORT) {
+		if (bar & TPL_BAR_REG_BELOW1MB)
+			dinfo->ibelow1mb |= BARBIT(bar);
 	}
-
 	DEVPRINTF((cbdev, "Opening BAR: type=%s, bar=%02x, len=%04x%s%s\n",
 	    (type == SYS_RES_MEMORY) ? "MEM" : "IO", bar, len,
 	    (type == SYS_RES_MEMORY && dinfo->mprefetchable & BARBIT(bar)) ?
 	    " (Prefetchable)" : "", type == SYS_RES_MEMORY ?
-	    ((dinfo->mbelow1mb & BARBIT(bar)) ? " (Below 1Mb)" : "") : ""));
+	    ((dinfo->mbelow1mb & BARBIT(bar)) ? " (Below 1Mb)" : "") :
+	    (dinfo->ibelow1mb & BARBIT(bar)) ? " (Below 1Mb)" : "" ));
 
 	resource_list_add(&dinfo->pci.resources, type, bar, 0UL, ~0UL, len);
 
@@ -726,7 +729,6 @@
 	res = cardbus_read_tuple_init(cbdev, child, &start, &rid);
 	if (res == NULL)
 		return (ENXIO);
-
 	do {
 		if (0 != cardbus_read_tuple(cbdev, child, res, start, &off,
 		    &tupleid, &len, tupledata)) {
@@ -1041,6 +1043,7 @@
 {
 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
 	struct cardbus_quirk *q;
+	struct resource_list_entry *rle;
 	int reg;
 
 	/*
@@ -1052,11 +1055,30 @@
 	for (reg = 0; reg < dinfo->pci.cfg.nummaps; reg++) {
 		cardbus_add_map(cbdev, child, PCIR_MAPS + reg * 4);
 	}
-
 	for (q = &cardbus_quirks[0]; q->devid; q++) {
-		if (q->devid == ((dinfo->pci.cfg.device << 16) | dinfo->pci.cfg.vendor)
-		    && q->type == CARDBUS_QUIRK_MAP_REG) {
-			cardbus_add_map(cbdev, child, q->arg1);
+		if (q->devid == ((dinfo->pci.cfg.device << 16)
+		    | dinfo->pci.cfg.vendor)) {
+			switch (q->type) {
+			case CARDBUS_QUIRK_MAP_REG:
+				cardbus_add_map(cbdev, child, q->arg1);
+				break;
+			case CARDBUS_QUIRK_RID_COUNT:
+				reg = 0;
+				SLIST_FOREACH(rle, &dinfo->pci.resources,
+				    link) {
+					if (rle->rid == q->arg1) {
+						DEVPRINTF((cbdev, "Applying "
+						    "quirk: type=%d, arg1=0x%x"
+						    ", arg2=0x%x\n", q->type,
+						    q->arg1, q->arg2));
+						rle->count = q->arg2;
+						break;
+					}
+				}
+				break;
+			default:
+				panic("Cardbus quirk bad type");
+			}
 		}
 	}
 }

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030216113756.J84326>