Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 26 Nov 2001 08:19:12 +0900 (JST)
From:      YAMAMOTO Shigeru <shigeru@iij.ad.jp>
To:        freebsd-mobile@freebsd.org
Cc:        freebsd-current@freebsd.org
Subject:   patch to support sio with NEWCARD
Message-ID:  <20011126.081912.33968257.shigeru@iij.ad.jp>

next in thread | raw e-mail | index | archive | help
----Next_Part(Mon_Nov_26_08:19:12_2001_701)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit


Hi all,

I make a patch to support sio with NEWCARD.
This patch is to avoid ghost interrupt when a PC-Card was removed.

This patch has one assamption,
     - all Serial PC-Card have a 16450/16550 compatible interface.

I tested it on my NotePC and there is no problems.
Please try it if you have an interest.

Thanks,
-------
YAMAMOTO Shigeru	<shigeru@iij.ad.jp>

----Next_Part(Mon_Nov_26_08:19:12_2001_701)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="sio.diff"

Index: sys/dev/sio/sio.c
===================================================================
RCS file: /share/cvsup/FreeBSD/current/usr/src/sys/dev/sio/sio.c,v
retrieving revision 1.352
diff -u -r1.352 sio.c
--- sys/dev/sio/sio.c	24 Oct 2001 18:30:04 -0000	1.352
+++ sys/dev/sio/sio.c	23 Nov 2001 10:41:30 -0000
@@ -1466,7 +1466,24 @@
 	com = (struct com_s *)arg;
 
 	mtx_lock_spin(&sio_lock);
-	siointr1(com);
+	while (!com->gone) {
+		u_int8_t	iir = 0;
+
+		iir = inb(com->int_id_port);
+/*
+printf(__FUNCTION__ ":%d: iir = 0x%x\n", __LINE__, iir);
+*/
+		if (iir != 0xFF) {
+			siointr1(com);
+			if ((iir & IIR_IMASK) == IIR_NOPEND) {
+				break;
+			}
+		}
+		else {
+printf(__FUNCTION__ ":%d: maybe, card was remoted\n", __LINE__);
+			break;
+		}
+	}
 	mtx_unlock_spin(&sio_lock);
 #else /* COM_MULTIPORT */
 	bool_t		possibly_more_intrs;
@@ -1483,6 +1500,8 @@
 	do {
 		possibly_more_intrs = FALSE;
 		for (unit = 0; unit < sio_numunits; ++unit) {
+			u_int8_t	iir = 0;
+
 			com = com_addr(unit);
 			/*
 			 * XXX COM_LOCK();
@@ -1490,8 +1509,9 @@
 			 */
 			if (com != NULL 
 			    && !com->gone
-			    && (inb(com->int_id_port) & IIR_IMASK)
-			       != IIR_NOPEND) {
+			    && ((iir = inb(com->int_id_port)) & IIR_IMASK)
+			       != IIR_NOPEND
+			    && iir != 0xFF) {
 				siointr1(com);
 				possibly_more_intrs = TRUE;
 			}
@@ -1530,9 +1550,8 @@
 			}
 		}
 		line_status = inb(com->line_status_port);
-
 		/* input event? (check first to help avoid overruns) */
-		while (line_status & LSR_RCV_MASK) {
+		while ((line_status & LSR_RCV_MASK)) {
 			/* break/unnattached error bits or real input? */
 			if (!(line_status & LSR_RXRDY))
 				recv_data = 0;
@@ -1718,10 +1737,12 @@
 			}
 		}
 
+#if	0
 		/* finished? */
 #ifndef COM_MULTIPORT
 		if ((inb(com->int_id_port) & IIR_IMASK) == IIR_NOPEND)
 #endif /* COM_MULTIPORT */
+#endif
 			return;
 	}
 }
Index: sys/dev/sio/sio_pccard.c
===================================================================
RCS file: /share/cvsup/FreeBSD/current/usr/src/sys/dev/sio/sio_pccard.c,v
retrieving revision 1.1
diff -u -r1.1 sio_pccard.c
--- sys/dev/sio/sio_pccard.c	23 Oct 2001 15:17:33 -0000	1.1
+++ sys/dev/sio/sio_pccard.c	24 Nov 2001 05:29:25 -0000
@@ -40,18 +40,28 @@
 #include <machine/resource.h>
 #include <sys/timepps.h>
 
+#include <dev/pccard/pccardreg.h>
+#include <dev/pccard/pccardvar.h>
+#include <dev/pccard/pccarddevs.h>
+
 #include <dev/sio/siovar.h>
 
-static	int	sio_pccard_attach __P((device_t dev));
-static	int	sio_pccard_detach __P((device_t dev));
-static	int	sio_pccard_probe __P((device_t dev));
+static	int	sio_pccard_match	__P((device_t self));
+static	int	sio_pccard_probe	__P((device_t self));
+static	int	sio_pccard_attach	__P((device_t self));
+static	int	sio_pccard_detach	__P((device_t self));
 
 static device_method_t sio_pccard_methods[] = {
 	/* Device interface */
-	DEVMETHOD(device_probe,		sio_pccard_probe),
-	DEVMETHOD(device_attach,	sio_pccard_attach),
+	DEVMETHOD(device_probe,		pccard_compat_probe),
+	DEVMETHOD(device_attach,	pccard_compat_attach),
 	DEVMETHOD(device_detach,	sio_pccard_detach),
 
+	/* Card interface */
+	DEVMETHOD(card_compat_match,	sio_pccard_match),
+	DEVMETHOD(card_compat_probe,	sio_pccard_probe),
+	DEVMETHOD(card_compat_attach,	sio_pccard_attach),
+
 	{ 0, 0 }
 };
 
@@ -61,27 +71,53 @@
 	sizeof(struct com_s),
 };
 
-static int
-sio_pccard_probe(dev)
-	device_t	dev;
-{
+static
+int
+sio_pccard_match(device_t self) {
+	int		error = 0;
+	u_int32_t	fcn = PCCARD_FUNCTION_UNSPEC;
+
+	error = pccard_get_function(self, &fcn);
+	if (!error) {
+		switch (fcn) {
+		case PCCARD_FUNCTION_SERIAL:
+		/* match? */
+			error = 0;
+			break;
+
+		default:
+			error = EINVAL;
+			break;
+		}
+	}
+
+	return(error);
+}
+
+static
+int
+sio_pccard_probe(device_t self) {
+	int	error = 0;
+
 	/* Do not probe IRQ - pccard doesn't turn on the interrupt line */
 	/* until bus_setup_intr */
-	return (sioprobe(dev, 0, 1));
+	error = sioprobe(self, 0, 1);
+	return(error);
 }
 
-static int
-sio_pccard_attach(dev)
-	device_t	dev;
-{
-	return (sioattach(dev, 0));
+static
+int
+sio_pccard_attach(device_t self) {
+	int	error = 0;
+
+	error = sioattach(self, 0);
+	return(error);
 }
 
-static int
-sio_pccard_detach(dev)
-	device_t	dev;
-{
-	return (siodetach(dev));
+static
+int
+sio_pccard_detach(device_t self) {
+	return(siodetach(self));
 }
 
 DRIVER_MODULE(sio, pccard, sio_pccard_driver, sio_devclass, 0, 0);

----Next_Part(Mon_Nov_26_08:19:12_2001_701)----

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




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