Modem + Network in Xircom cards, and maybe others

Carlos Velasco freebsd at newipnet.com
Wed May 5 04:37:46 PDT 2004


On 02/05/2004 at 22:24 Carlos Velasco wrote:

>On 02/05/2004 at 9:14 M. Warner Losh wrote:
>
>>: sio4: 118 more interrupt-level buffer overflows (total 118)
>>: sio4: 162 more interrupt-level buffer overflows (total 280)
>>
>>That may be due to the MFC interrupt issue that I talked about.  But
>>it could be something else...
>
>I have tried playing with pccard_intr but it doesn't work.
>I'm reading about a patch for sio.c in the list, i don't know if it can
>helps into this I will try it in near future and see the results.

Well... this didn't work.

However I googled and found this:
http://lists.freebsd.org/pipermail/freebsd-bugs/2003-May/000687.html

Applying it solves problem for me.
Could we commit this in sio.c until GIANT solve work is done?

This is my complete patch (it works for me), including sio change and also
pccard 64k alignment:


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);
 }
 


Regards,
Carlos Velasco



More information about the freebsd-mobile mailing list