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

From: Carlos Velasco <freebsd_at_newipnet.com>
Date: Wed, 05 May 2004 13:11:33 +0200
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
_at__at_ -955,8 +955,8 _at__at_
 	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;
_at__at_ -1075,6 +1075,7 _at__at_
 	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) {
_at__at_ -1090,8 +1091,15 _at__at_
 	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
_at__at_ -96,6 +96,8 _at__at_
 
 	state.pf = NULL;
 
+	state.card->mfc = 0;
+
 	tsleep(&state, 0, "pccard", hz);
 	if (pccard_scan_cis(sc->dev, pccard_parse_cis_tuple,
 	    &state) == -1)
_at__at_ -663,6 +665,7 _at__at_
 		 * up.
 		 */
 		state->gotmfc = 1;
+		state->card->mfc = 1;
 		break;
 #ifdef PCCARDCISDEBUG
 	case CISTPL_DEVICE:
_at__at_ -803,6 +806,42 _at__at_
 
 			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
_at__at_ -179,6 +179,7 _at__at_
 	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;
_at__at_ -284,8 +285,9 _at__at_
 #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
_at__at_ -2374,7 +2374,7 _at__at_
 	 * (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
_at__at_ -402,6 +402,7 _at__at_
 	const struct xe_pccard_product* xpp;
 	u_int16_t prodext;
 
+
 	DEVPRINTF(2, (dev, "pccard_product_match\n"));
 
 	xpp = (const struct xe_pccard_product*)ent;
_at__at_ -409,6 +410,8 _at__at_
 
 	if (xpp->prodext != prodext)
 		vpfmatch = 0;
+	else
+		vpfmatch++;
 
 	return (vpfmatch);
 }
_at__at_ -416,8 +419,19 _at__at_
 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;
_at__at_ -425,7 +439,6 _at__at_
 	if ((pp = pccard_product_lookup(dev, pp,
 	     sizeof(xe_pccard_products[0]), xe_pccard_product_match)) != NULL)
 		return (0);
-
 	return (EIO);
 }
 


Regards,
Carlos Velasco
Received on Wed May 05 2004 - 02:37:46 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:37:53 UTC