diff options
author | jmg <jmg@FreeBSD.org> | 1997-09-19 15:25:49 +0000 |
---|---|---|
committer | jmg <jmg@FreeBSD.org> | 1997-09-19 15:25:49 +0000 |
commit | 13be81370a2693efa154eacd260966b414e3a525 (patch) | |
tree | 1e88cc251dc37ddb5a3693f14ee334bd0e9290d9 /sys/dev | |
parent | 6d02356368490b36d701bc5fb7890e9067455af6 (diff) | |
download | FreeBSD-src-13be81370a2693efa154eacd260966b414e3a525.zip FreeBSD-src-13be81370a2693efa154eacd260966b414e3a525.tar.gz |
teach sio how to attach to isa PnP cards. This is mainly for use with
internal modems. Currently detects a USR modem, and a couple Supra
modems... vendor id's for sio capabile cards welcomed...
document new option EXTRA_SIO that will increase sio's internal data
structures to support X more serial ports... these are used by the
PnP part of sio for attaching... If you don't have it specified, it
will default to 2... This is defaulted to 0 if you don't have PnP
compiled into your kernel...
also document that if you set the PnP flags (pnp x flags y) to 0x1 that
the modem will be refused to be recognized by the sio driver... this
is for people that want the traditional isa driver to probe and attach
the modem... (for keeping legacy sio numbering)
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/sio/sio.c | 135 |
1 files changed, 122 insertions, 13 deletions
diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c index d7bebbb..37d8ecd 100644 --- a/sys/dev/sio/sio.c +++ b/sys/dev/sio/sio.c @@ -31,13 +31,24 @@ * SUCH DAMAGE. * * from: @(#)com.c 7.5 (Berkeley) 5/16/91 - * $Id: sio.c,v 1.180 1997/09/01 07:45:28 fsmp Exp $ + * $Id: sio.c,v 1.181 1997/09/14 03:19:23 peter Exp $ */ #include "opt_comconsole.h" #include "opt_ddb.h" #include "opt_sio.h" #include "sio.h" +#include "pnp.h" + +#ifndef EXTRA_SIO +#if NPNP > 0 +#define EXTRA_SIO 2 +#else +#define EXTRA_SIO 0 +#endif +#endif + +#define NSIOTOT (NSIO + EXTRA_SIO) /* * Serial driver, based on 386BSD-0.1 com driver. @@ -83,6 +94,10 @@ #include <pccard/slot.h> #endif +#if NPNP > 0 +#include <i386/isa/pnp.h> +#endif + #ifdef SMP #define disable_intr() COM_DISABLE_INTR() #define enable_intr() COM_ENABLE_INTR() @@ -329,7 +344,7 @@ static int LoadSoftModem __P((int unit,int base_io, u_long size, u_char *ptr static char driver_name[] = "sio"; /* table and macro for fast conversion from a unit number to its com struct */ -static struct com_s *p_com_addr[NSIO]; +static struct com_s *p_com_addr[NSIOTOT]; #define com_addr(unit) (p_com_addr[unit]) struct isa_driver siodriver = { @@ -359,11 +374,11 @@ static Port_t siocniobase; static int sio_timeout; static int sio_timeouts_until_log; #if 0 /* XXX */ -static struct tty *sio_tty[NSIO]; +static struct tty *sio_tty[NSIOTOT]; #else -static struct tty sio_tty[NSIO]; +static struct tty sio_tty[NSIOTOT]; #endif -static const int nsio_tty = NSIO; +static const int nsio_tty = NSIOTOT; static struct speedtab comspeedtab[] = { { 0, 0 }, @@ -498,7 +513,7 @@ sioinit(struct pccard_dev *dp, int first) /* validate unit number. */ if (first) { - if (dp->isahd.id_unit >= NSIO) + if (dp->isahd.id_unit >= (NSIOTOT)) return(ENODEV); /* Make sure it isn't already probed. */ if (com_addr(dp->isahd.id_unit)) @@ -1075,7 +1090,7 @@ sioopen(dev, flag, mode, p) mynor = minor(dev); unit = MINOR_TO_UNIT(mynor); - if ((u_int) unit >= NSIO || (com = com_addr(unit)) == NULL) + if ((u_int) unit >= NSIOTOT || (com = com_addr(unit)) == NULL) return (ENXIO); if (com->gone) return (ENXIO); @@ -1441,7 +1456,7 @@ siointr(unit) COM_LOCK(); do { possibly_more_intrs = FALSE; - for (unit = 0; unit < NSIO; ++unit) { + for (unit = 0; unit < NSIOTOT; ++unit) { com = com_addr(unit); /* * XXX COM_LOCK(); @@ -1817,7 +1832,7 @@ siopoll() if (com_events == 0) return; repeat: - for (unit = 0; unit < NSIO; ++unit) { + for (unit = 0; unit < NSIOTOT; ++unit) { u_char *buf; struct com_s *com; u_char *ibuf; @@ -2322,7 +2337,7 @@ siodevtotty(dev) if (mynor & CONTROL_MASK) return (NULL); unit = MINOR_TO_UNIT(mynor); - if ((u_int) unit >= NSIO) + if ((u_int) unit >= NSIOTOT) return (NULL); return (&sio_tty[unit]); } @@ -2398,7 +2413,7 @@ siosettimeout() untimeout(comwakeup, (void *)NULL); sio_timeout = hz; someopen = FALSE; - for (unit = 0; unit < NSIO; ++unit) { + for (unit = 0; unit < NSIOTOT; ++unit) { com = com_addr(unit); if (com != NULL && com->tp != NULL && com->tp->t_state & TS_ISOPEN && !com->gone) { @@ -2433,7 +2448,7 @@ comwakeup(chan) * Recover from lost output interrupts. * Poll any lines that don't use interrupts. */ - for (unit = 0; unit < NSIO; ++unit) { + for (unit = 0; unit < NSIOTOT; ++unit) { com = com_addr(unit); if (com != NULL && !com->gone && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) { @@ -2449,7 +2464,7 @@ comwakeup(chan) if (--sio_timeouts_until_log > 0) return; sio_timeouts_until_log = hz / sio_timeout; - for (unit = 0; unit < NSIO; ++unit) { + for (unit = 0; unit < NSIOTOT; ++unit) { int errnum; com = com_addr(unit); @@ -2873,3 +2888,97 @@ error: return EIO; } #endif /* DSI_SOFT_MODEM */ + +/* + * support PnP cards if we are using 'em + */ + +#if NPNP > 0 + +static struct siopnp_ids { + u_long vend_id; + char *id_str; +} siopnp_ids[] = { + { 0x8113b04e, "Supra1381"}, + { 0x9012b04e, "Supra1290"}, + { 0x11007256, "USR0011"}, + { 0 } +}; + +static char *siopnp_probe(u_long csn, u_long vend_id); +static void siopnp_attach(u_long csn, u_long vend_id, char *name, + struct isa_device *dev); +static u_long nsiopnp = NSIO; + +static struct pnp_device siopnp = { + "siopnp", + siopnp_probe, + siopnp_attach, + &nsiopnp, + &tty_imask +}; +DATA_SET (pnpdevice_set, siopnp); + +static char * +siopnp_probe(u_long csn, u_long vend_id) +{ + struct siopnp_ids *ids; + char *s = NULL; + + for(ids = siopnp_ids; ids->vend_id != 0; ids++) { + if (vend_id == ids->vend_id) { + s = ids->id_str; + break; + } + } + + if (s) { + struct pnp_cinfo d; + read_pnp_parms(&d, 0); + if (d.enable == 0 || d.flags & 1) { + printf("CSN %d is disabled.\n", csn); + return (NULL); + } + + } + + return (s); +} + +static void +siopnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev) +{ + struct pnp_cinfo d; + struct isa_device *dvp; + + if (dev->id_unit >= NSIOTOT) + return; + + if (read_pnp_parms(&d, 0) == 0) { + printf("failed to read pnp parms\n"); + return; + } + + write_pnp_parms(&d, 0); + + enable_pnp_card(); + + dev->id_iobase = d.port[0]; + dev->id_irq = (1 << d.irq[0]); + dev->id_intr = siointr; + dev->id_ri_flags = RI_FAST; + dev->id_drq = -1; + + if (dev->id_driver == NULL) { + dev->id_driver = &siodriver; + dvp = find_isadev(isa_devtab_tty, &siodriver, 0); + if (dvp != NULL) + dev->id_id = dvp->id_id; + } + + if ((dev->id_alive = sioprobe(dev)) != 0) + sioattach(dev); + else + printf("sio%d: probe failed\n", dev->id_unit); +} +#endif |