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-mobile" 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>