Re[2]: Modem + Network in Xircom cards, and maybe others

"Carlos Velasco" <[email protected]>
Newsgroups gmane.os.freebsd.current,gmane.os.freebsd.devel.mobile
Message-ID <[email protected]>
On 05/05/2004 at 15:59 M. Warner Losh wrote:

>In message: <[email protected]>
>            "Carlos Velasco" <[email protected]> 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

_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "[email protected]"
xircom_2.patch (application/octet-stream, 5.7 KB)
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);
 }
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.