Re: Problems with serial port on Xircom RBEM56G

Michal Mertl <[email protected]>
Newsgroups gmane.os.freebsd.devel.mobile
Message-ID <[email protected]>
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
[email protected]
cardbus_cis.c.patch (text/plain, 4.4 KB)
--- 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");
+			}
 		}
 	}
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.