Subject: PCMCIA diffs for xircom
To: None <tech-kern@netbsd.org>
From: Manuel Bouyer <bouyer@antioche.eu.org>
List: tech-kern
Date: 10/14/2001 15:19:51
--PEIAKu/WMn1b1Hv9
Content-Type: text/plain; charset=us-ascii

Hi,
attached is a patch that makes a xircom Xircom RealPort Ethernet 10/100 + Modem
work (ethernet part only). I don't know exactly what the change to
pcmcia_cis.c does (I've stolen this from OpenBSD), but this is required to get
the adapter to work. Without this accesses to the card registers fails
(the PHY isn't found).

I also checked that my 3com 3C562D (ethernet+modem) still works :)

I noone object I'll commit this in a few days.

--
Manuel Bouyer <bouyer@antioche.eu.org>
--

--PEIAKu/WMn1b1Hv9
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="pcmcia.diff"

Index: if_xi.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/pcmcia/if_xi.c,v
retrieving revision 1.15
diff -u -r1.15 if_xi.c
--- if_xi.c	2001/09/26 09:01:30	1.15
+++ if_xi.c	2001/10/14 13:14:46
@@ -246,6 +246,9 @@
 	{ PCMCIA_VENDOR_INTEL,		0x0143,
 	  0,				XIFLAGS_MOHAWK | XIFLAGS_MODEM,
 	  PCMCIA_STR_INTEL_EEPRO100 },
+	{ PCMCIA_VENDOR_XIRCOM,		0x110a,
+	  0,				XIFLAGS_MOHAWK | XIFLAGS_DINGO | XIFLAGS_MODEM,
+	  PCMCIA_STR_XIRCOM_REM56 },
 #ifdef NOT_SUPPORTED
 	{ PCMCIA_VENDOR_XIRCOM,		0x1141,
 	  0,				XIFLAGS_MODEM,
@@ -349,6 +352,9 @@
 {
 	struct pcmcia_attach_args *pa = aux;
 	
+	if (pa->manufacturer == PCMCIA_VENDOR_XIRCOM &&
+	    pa->product == 0x110a)
+		return (2); /* prevent attach to com_pcmcia */
 	if (pa->pf->function != PCMCIA_FUNCTION_NETWORK)
 		return (0);
 
@@ -629,20 +635,20 @@
 
 	DPRINTF(XID_CONFIG,("xi_pcmcia_enable()\n"));
 
+	if (pcmcia_function_enable(psc->sc_pf))
+		return (1);
+	psc->sc_resource |= XI_RES_PCIC;
+
 	/* establish the interrupt. */
 	psc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET, xi_intr, sc);
 	if (psc->sc_ih == NULL) {
 		printf("%s: couldn't establish interrupt\n",
 		    sc->sc_dev.dv_xname);
+		pcmcia_function_disable(psc->sc_pf);
+		psc->sc_resource &= ~XI_RES_PCIC;
 		return (1);
 	}
 
-	if (pcmcia_function_enable(psc->sc_pf)) {
-		pcmcia_intr_disestablish(psc->sc_pf, psc->sc_ih);
-		return (1);
-	}
-	psc->sc_resource |= XI_RES_PCIC;
-
 	xi_full_reset(sc);
 
         return (0);
@@ -656,8 +662,8 @@
 	DPRINTF(XID_CONFIG,("xi_pcmcia_disable()\n"));
 
 	if (psc->sc_resource & XI_RES_PCIC) {
-		pcmcia_function_disable(psc->sc_pf);
 		pcmcia_intr_disestablish(psc->sc_pf, psc->sc_ih);
+		pcmcia_function_disable(psc->sc_pf);
 		psc->sc_resource &= ~XI_RES_PCIC;
 	}
 }
Index: pcmcia_cis.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/pcmcia/pcmcia_cis.c,v
retrieving revision 1.25
diff -u -r1.25 pcmcia_cis.c
--- pcmcia_cis.c	2001/09/24 14:19:10	1.25
+++ pcmcia_cis.c	2001/10/14 13:14:46
@@ -838,7 +838,20 @@
 			    tuple->length));
 			break;
 		}
-		if ((state->pf == NULL) || (state->gotmfc == 2)) {
+		if (state->pf) {
+			if (state->pf->function == PCMCIA_FUNCTION_UNSPEC) {
+				/*
+				 * This looks like a opportunistic function
+				 * created by a CONFIG tuple.  Just keep it.
+				 */
+			} else {
+				/*
+				 * A function is being defined, end it.
+				 */
+				state->pf = NULL;
+			}
+		}
+		if (state->pf == NULL) {
 			state->pf = malloc(sizeof(*state->pf), M_DEVBUF,
 			    M_NOWAIT);
 			memset(state->pf, 0, sizeof(*state->pf));

--PEIAKu/WMn1b1Hv9--