summaryrefslogtreecommitdiffstats
path: root/sys/isa
diff options
context:
space:
mode:
authorjmg <jmg@FreeBSD.org>1997-09-19 15:25:49 +0000
committerjmg <jmg@FreeBSD.org>1997-09-19 15:25:49 +0000
commit13be81370a2693efa154eacd260966b414e3a525 (patch)
tree1e88cc251dc37ddb5a3693f14ee334bd0e9290d9 /sys/isa
parent6d02356368490b36d701bc5fb7890e9067455af6 (diff)
downloadFreeBSD-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/isa')
-rw-r--r--sys/isa/sio.c135
1 files changed, 122 insertions, 13 deletions
diff --git a/sys/isa/sio.c b/sys/isa/sio.c
index d7bebbb..37d8ecd 100644
--- a/sys/isa/sio.c
+++ b/sys/isa/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
OpenPOWER on IntegriCloud