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>
