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        <[EMAIL PROTECTED]>
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);

Reply via email to