Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 17 May 2004 13:36:32 +0200
From:      "Carlos Velasco" <freebsd@newipnet.com>
To:        "M. Warner Losh" <imp@bsdimp.com>
Cc:        freebsd-mobile@freebsd.org
Subject:   Re[2]: Modem + Network in Xircom cards, and maybe others
Message-ID:  <200405171336320804.080CD05E@192.168.128.16>
In-Reply-To: <20040505.155926.128442915.imp@bsdimp.com>
References:  <200405051311330554.1F584985@192.168.128.16> <20040505233435.B15444@gamplex.bde.org> <200405051746300245.2039F9A4@192.168.128.16> <20040505.155926.128442915.imp@bsdimp.com>

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

[-- Attachment #1 --]
On 05/05/2004 at 15:59 M. Warner Losh wrote:

>In message: <200405051746300245.2039F9A4@192.168.128.16>
>            "Carlos Velasco" <freebsd@newipnet.com> writes:
>: I'm patching it to activate both functions (usually modem/serial and
>: network).
>: Network is in xe driver, however I'm passing modem to sio.
>: It works, however sio reports interrupt-level buffer overflows when I'm
>: above 2400bps, losing characters, and here is where I'm lost.
>
>I don't think you are getting interrupts like you should.

Warner,

I think my patch is ok, problem is related to sio in normal mode (i think).
Aplying a last patch into sio.c makes my xircom modem work perfectly.

Have you tested other 16 bits cards?

I'm attaching my last complete patch.

Regards,
Carlos Velasco


[-- Attachment #2 --]
diff -ru sys/dev/pccard/pccard.c sysnew/dev/pccard/pccard.c
--- sys/dev/pccard/pccard.c	Wed Mar 17 17:50:38 2004
+++ sysnew/dev/pccard/pccard.c	Sat May  1 09:47:57 2004
@@ -955,8 +955,8 @@
 	struct pccard_softc *sc = PCCARD_SOFTC(bus);
 
 	device_printf(bus, "<unknown card>");
-	printf(" (manufacturer=0x%04x, product=0x%04x) at function %d\n",
-	  sc->card.manufacturer, sc->card.product, func->number);
+	printf(" (manufacturer=0x%04x, product=0x%04x, prodext=0x%02x) at function %d\n",
+	  sc->card.manufacturer, sc->card.product, sc->card.prodext, func->number);
 	device_printf(bus, "   CIS info: %s, %s, %s\n", sc->card.cis1_info[0],
 	  sc->card.cis1_info[1], sc->card.cis1_info[2]);
 	return;
@@ -1075,6 +1075,7 @@
 	int passthrough = (device_get_parent(child) != dev);
 	int isdefault = (start == 0 && end == ~0UL && count == 1);
 	struct resource *r = NULL;
+       u_int align;
 
 	/* XXX I'm no longer sure this is right */
 	if (passthrough) {
@@ -1090,8 +1091,15 @@
 	if (rle == NULL || rle->res == NULL) {
 		/* Do we want this device to own it? */
 		/* XXX I think so, but that might be lame XXX */
+
+               /* force 64k page align */
+               if (type == SYS_RES_MEMORY)
+                   align = (flags & ~RF_ALIGNMENT_MASK) |
+                       rman_make_alignment_flags(64*1024);
+               else
+                   align = flags;
 		r = bus_alloc_resource(dev, type, rid, start, end,
-		  count, flags /* XXX aligment? */);
+                 count, align);
 		if (r == NULL)
 		    goto bad;
 		resource_list_add(&dinfo->resources, type, *rid,
diff -ru sys/dev/pccard/pccard_cis.c sysnew/dev/pccard/pccard_cis.c
--- sys/dev/pccard/pccard_cis.c	Mon Apr 12 20:56:34 2004
+++ sysnew/dev/pccard/pccard_cis.c	Sat May  1 09:47:57 2004
@@ -96,6 +96,8 @@
 
 	state.pf = NULL;
 
+	state.card->mfc = 0;
+
 	tsleep(&state, 0, "pccard", hz);
 	if (pccard_scan_cis(sc->dev, pccard_parse_cis_tuple,
 	    &state) == -1)
@@ -663,6 +665,7 @@
 		 * up.
 		 */
 		state->gotmfc = 1;
+		state->card->mfc = 1;
 		break;
 #ifdef PCCARDCISDEBUG
 	case CISTPL_DEVICE:
@@ -803,6 +806,42 @@
 
 			STAILQ_INSERT_TAIL(&state->card->pf_head, state->pf,
 			    pf_list);
+		} else if (state->pf->function != PCCARD_FUNCTION_UNSPEC) {
+			/* We have a non-MFC compliant card, it puts more
+			 * than 1 FUNCID in the CIS without LONGLINK.
+			 * a) We put the functions in the list ala MFC.
+			 * b) Copy last CFG entry for previous function,
+			 *    not sure if this is right, but usually works.
+			 */
+			struct pccard_config_entry *cfe, *qcfe;
+			uint32_t	ccr_base = state->pf->ccr_base;
+			uint32_t	ccr_mask = state->pf->ccr_mask;
+
+			cfe = NULL;
+			STAILQ_FOREACH(qcfe, &state->pf->cfe_head, cfe_list) {
+				if (qcfe->number == state->pf->last_config_index) {
+				cfe = (struct pccard_config_entry *)
+				    malloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT);
+				*cfe = *qcfe;
+				break;
+				}
+			}
+
+			state->pf = malloc(sizeof(*state->pf), M_DEVBUF,
+			    M_NOWAIT | M_ZERO);
+			state->pf->number = state->count++;
+			state->pf->last_config_index = cfe->number;
+			state->pf->ccr_base = ccr_base;
+			state->pf->ccr_mask = ccr_mask;
+
+			STAILQ_INIT(&state->pf->cfe_head);
+			if (cfe) 
+				STAILQ_INSERT_TAIL(&state->pf->cfe_head,
+				    cfe, cfe_list);
+
+			STAILQ_INSERT_TAIL(&state->card->pf_head, state->pf,
+			    pf_list);
+		
 		}
 		state->pf->function = pccard_tuple_read_1(tuple, 0);
 
diff -ru sys/dev/pccard/pccardvar.h sysnew/dev/pccard/pccardvar.h
--- sys/dev/pccard/pccardvar.h	Sun Nov  2 20:18:19 2003
+++ sysnew/dev/pccard/pccardvar.h	Sat May  1 09:47:57 2004
@@ -179,6 +179,7 @@
 	int32_t		product;
 #define	PCMCIA_PRODUCT_INVALID		-1
 	int16_t		prodext;
+	int		mfc;
 	uint16_t	error;
 #define	PCMCIA_CIS_INVALID		{ NULL, NULL, NULL, NULL }
 	STAILQ_HEAD(, pccard_function) pf_head;
@@ -284,8 +285,9 @@
 #define	PCCARD_SPACE_IO		2
 
 #define	pccard_mfc(sc)							\
-		(STAILQ_FIRST(&(sc)->card.pf_head) &&			\
-		 STAILQ_NEXT(STAILQ_FIRST(&(sc)->card.pf_head),pf_list))
+		(sc->card.mfc)
+/*		(STAILQ_FIRST(&(sc)->card.pf_head) &&			\
+		 STAILQ_NEXT(STAILQ_FIRST(&(sc)->card.pf_head),pf_list)) */
 
 #define	pccard_io_alloc(pf, start, size, align, pciop)			\
 	(pccard_chip_io_alloc((pf)->sc->pct, pf->sc->pch, (start),	\
diff -ru sys/dev/sio/sio.c sysnew/dev/sio/sio.c
--- sys/dev/sio/sio.c	Mon May  3 22:35:28 2004
+++ sysnew/dev/sio/sio.c	Wed May  5 13:04:14 2004
@@ -2374,7 +2374,7 @@
 	 * (about 3 ticks if input flow control is not used or not honoured,
 	 * but a bit less for CS5-CS7 modes).
 	 */
-	cp4ticks = speed / 10 / hz * 4;
+	cp4ticks = speed / 10 / hz * 40;
 	for (ibufsize = 128; ibufsize < cp4ticks;)
 		ibufsize <<= 1;
 	if (ibufsize == com->ibufsize) {
diff -ru sys/dev/xe/if_xe_pccard.c sysnew/dev/xe/if_xe_pccard.c
--- sys/dev/xe/if_xe_pccard.c	Sun Apr 11 16:34:29 2004
+++ sysnew/dev/xe/if_xe_pccard.c	Sat May  1 09:48:24 2004
@@ -402,6 +402,7 @@
 	const struct xe_pccard_product* xpp;
 	u_int16_t prodext;
 
+
 	DEVPRINTF(2, (dev, "pccard_product_match\n"));
 
 	xpp = (const struct xe_pccard_product*)ent;
@@ -409,6 +410,8 @@
 
 	if (xpp->prodext != prodext)
 		vpfmatch = 0;
+	else
+		vpfmatch++;
 
 	return (vpfmatch);
 }
@@ -416,8 +419,19 @@
 static int
 xe_pccard_match(device_t dev)
 {
+	int		error = 0;
+	u_int32_t	fcn = PCCARD_FUNCTION_UNSPEC;
 	const struct pccard_product *pp;
 
+	error = pccard_get_function(dev, &fcn);
+	if (error != 0)
+		return (error);
+	/*
+	 * If not a network card, we are not the right driver.
+	 */
+	if (fcn != PCCARD_FUNCTION_NETWORK)
+		return (ENXIO);
+
 	DEVPRINTF(2, (dev, "pccard_match\n"));
 
 	pp = (const struct pccard_product*)xe_pccard_products;
@@ -425,7 +439,6 @@
 	if ((pp = pccard_product_lookup(dev, pp,
 	     sizeof(xe_pccard_products[0]), xe_pccard_product_match)) != NULL)
 		return (0);
-
 	return (EIO);
 }
 

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