summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/sio/sio.c156
-rw-r--r--sys/dev/sio/sio_isa.c3
-rw-r--r--sys/dev/sio/sio_pccard.c3
-rw-r--r--sys/dev/sio/sio_pci.c4
-rw-r--r--sys/dev/sio/siovar.h112
5 files changed, 152 insertions, 126 deletions
diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c
index 29f594b..59bcdad 100644
--- a/sys/dev/sio/sio.c
+++ b/sys/dev/sio/sio.c
@@ -72,14 +72,13 @@
#include <sys/timetc.h>
#include <sys/timepps.h>
-#include <machine/clock.h>
+#include <isa/isavar.h>
+
#include <machine/resource.h>
#include <dev/sio/sioreg.h>
#include <dev/sio/siovar.h>
-#include <isa/isavar.h>
-
#ifdef COM_ESP
#include <dev/ic/esp.h>
#endif
@@ -111,6 +110,8 @@
#define COM_LOSESOUTINTS(flags) ((flags) & 0x08)
#define COM_NOFIFO(flags) ((flags) & 0x02)
#define COM_ST16650A(flags) ((flags) & 0x20000)
+#define COM_C_NOPROBE (0x40000)
+#define COM_NOPROBE(flags) ((flags) & COM_C_NOPROBE)
#define COM_C_IIR_TXRDYBUG (0x80000)
#define COM_IIR_TXRDYBUG(flags) ((flags) & COM_C_IIR_TXRDYBUG)
#define COM_FIFOSIZE(flags) (((flags) & 0xff000000) >> 24)
@@ -157,8 +158,116 @@ static char const * const error_desc[] = {
"tty-level buffer overflow",
};
+#define CE_NTYPES 3
#define CE_RECORD(com, errnum) (++(com)->delta_error_counts[errnum])
+/* types. XXX - should be elsewhere */
+typedef u_int Port_t; /* hardware port */
+typedef u_char bool_t; /* boolean */
+
+/* queue of linear buffers */
+struct lbq {
+ u_char *l_head; /* next char to process */
+ u_char *l_tail; /* one past the last char to process */
+ struct lbq *l_next; /* next in queue */
+ bool_t l_queued; /* nonzero if queued */
+};
+
+/* com device structure */
+struct com_s {
+ u_int flags; /* Copy isa device flags */
+ u_char state; /* miscellaneous flag bits */
+ bool_t active_out; /* nonzero if the callout device is open */
+ u_char cfcr_image; /* copy of value written to CFCR */
+#ifdef COM_ESP
+ bool_t esp; /* is this unit a hayes esp board? */
+#endif
+ u_char extra_state; /* more flag bits, separate for order trick */
+ u_char fifo_image; /* copy of value written to FIFO */
+ bool_t hasfifo; /* nonzero for 16550 UARTs */
+ bool_t st16650a; /* Is a Startech 16650A or RTS/CTS compat */
+ bool_t loses_outints; /* nonzero if device loses output interrupts */
+ u_char mcr_image; /* copy of value written to MCR */
+#ifdef COM_MULTIPORT
+ bool_t multiport; /* is this unit part of a multiport device? */
+#endif /* COM_MULTIPORT */
+ bool_t no_irq; /* nonzero if irq is not attached */
+ bool_t gone; /* hardware disappeared */
+ bool_t poll; /* nonzero if polling is required */
+ bool_t poll_output; /* nonzero if polling for output is required */
+ int unit; /* unit number */
+ int dtr_wait; /* time to hold DTR down on close (* 1/hz) */
+ u_int tx_fifo_size;
+ u_int wopeners; /* # processes waiting for DCD in open() */
+
+ /*
+ * The high level of the driver never reads status registers directly
+ * because there would be too many side effects to handle conveniently.
+ * Instead, it reads copies of the registers stored here by the
+ * interrupt handler.
+ */
+ u_char last_modem_status; /* last MSR read by intr handler */
+ u_char prev_modem_status; /* last MSR handled by high level */
+
+ u_char hotchar; /* ldisc-specific char to be handled ASAP */
+ u_char *ibuf; /* start of input buffer */
+ u_char *ibufend; /* end of input buffer */
+ u_char *ibufold; /* old input buffer, to be freed */
+ u_char *ihighwater; /* threshold in input buffer */
+ u_char *iptr; /* next free spot in input buffer */
+ int ibufsize; /* size of ibuf (not include error bytes) */
+ int ierroff; /* offset of error bytes in ibuf */
+
+ struct lbq obufq; /* head of queue of output buffers */
+ struct lbq obufs[2]; /* output buffers */
+
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+
+ Port_t data_port; /* i/o ports */
+#ifdef COM_ESP
+ Port_t esp_port;
+#endif
+ Port_t int_id_port;
+ Port_t modem_ctl_port;
+ Port_t line_status_port;
+ Port_t modem_status_port;
+ Port_t intr_ctl_port; /* Ports of IIR register */
+
+ struct tty *tp; /* cross reference */
+
+ /* Initial state. */
+ struct termios it_in; /* should be in struct tty */
+ struct termios it_out;
+
+ /* Lock state. */
+ struct termios lt_in; /* should be in struct tty */
+ struct termios lt_out;
+
+ bool_t do_timestamp;
+ bool_t do_dcd_timestamp;
+ struct timeval timestamp;
+ struct timeval dcd_timestamp;
+ struct pps_state pps;
+
+ u_long bytes_in; /* statistics */
+ u_long bytes_out;
+ u_int delta_error_counts[CE_NTYPES];
+ u_long error_counts[CE_NTYPES];
+
+ struct resource *irqres;
+ struct resource *ioportres;
+ void *cookie;
+ dev_t devs[6];
+
+ /*
+ * Data area for output buffers. Someday we should build the output
+ * buffer queue without copying data.
+ */
+ u_char obuf1[256];
+ u_char obuf2[256];
+};
+
#ifdef COM_ESP
static int espattach __P((struct com_s *com, Port_t esp_port));
#endif
@@ -187,7 +296,7 @@ static int sio_inited;
/* table and macro for fast conversion from a unit number to its com struct */
devclass_t sio_devclass;
#define com_addr(unit) ((struct com_s *) \
- devclass_get_softc(sio_devclass, unit))
+ devclass_get_softc(sio_devclass, unit)) /* XXX */
static d_open_t sioopen;
static d_close_t sioclose;
@@ -258,6 +367,7 @@ static struct speedtab comspeedtab[] = {
#ifdef COM_ESP
/* XXX configure this properly. */
+/* XXX quite broken for new-bus. */
static Port_t likely_com_ports[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, };
static Port_t likely_esp_ports[] = { 0x140, 0x180, 0x280, 0 };
#endif
@@ -322,6 +432,19 @@ sysctl_machdep_comdefaultrate(SYSCTL_HANDLER_ARGS)
SYSCTL_PROC(_machdep, OID_AUTO, conspeed, CTLTYPE_INT | CTLFLAG_RW,
0, 0, sysctl_machdep_comdefaultrate, "I", "");
+#define SET_FLAG(dev, bit) device_set_flags(dev, device_get_flags(dev) | (bit))
+#define CLR_FLAG(dev, bit) device_set_flags(dev, device_get_flags(dev) & ~(bit))
+
+/*
+ * Unload the driver and clear the table.
+ * XXX this is mostly wrong.
+ * XXX TODO:
+ * This is usually called when the card is ejected, but
+ * can be caused by a modunload of a controller driver.
+ * The idea is to reset the driver's view of the device
+ * and ensure that any driver entry points such as
+ * read and write do not hang.
+ */
int
siodetach(dev)
device_t dev;
@@ -353,6 +476,8 @@ siodetach(dev)
} else {
if (com->ibuf != NULL)
free(com->ibuf, M_DEVBUF);
+ device_set_softc(dev, NULL);
+ free(com, M_DEVBUF);
}
return (0);
}
@@ -387,7 +512,10 @@ sioprobe(dev, xrid, noprobe)
if (!port)
return (ENXIO);
- com = device_get_softc(dev);
+ com = malloc(sizeof(*com), M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (com == NULL)
+ return (ENOMEM);
+ device_set_softc(dev, com);
com->bst = rman_get_bustag(port);
com->bsh = rman_get_bushandle(port);
@@ -433,6 +561,8 @@ sioprobe(dev, xrid, noprobe)
printf("sio%d: reserved for low-level i/o\n",
device_get_unit(dev));
bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
+ device_set_softc(dev, NULL);
+ free(com, M_DEVBUF);
return (ENXIO);
}
@@ -584,7 +714,13 @@ sioprobe(dev, xrid, noprobe)
sio_setreg(com, com_cfcr, CFCR_8BITS);
mtx_unlock_spin(&sio_lock);
bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
- return (iobase == siocniobase ? 0 : result);
+ if (iobase == siocniobase)
+ result = 0;
+ if (result != 0) {
+ device_set_softc(dev, NULL);
+ free(com, M_DEVBUF);
+ }
+ return (result);
}
/*
@@ -651,7 +787,13 @@ sioprobe(dev, xrid, noprobe)
break;
}
bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
- return (iobase == siocniobase ? 0 : result);
+ if (iobase == siocniobase)
+ result = 0;
+ if (result != 0) {
+ device_set_softc(dev, NULL);
+ free(com, M_DEVBUF);
+ }
+ return (result);
}
#ifdef COM_ESP
diff --git a/sys/dev/sio/sio_isa.c b/sys/dev/sio/sio_isa.c
index 0cb066b..3d13e47 100644
--- a/sys/dev/sio/sio_isa.c
+++ b/sys/dev/sio/sio_isa.c
@@ -34,7 +34,6 @@
#include <sys/mutex.h>
#include <sys/module.h>
#include <sys/tty.h>
-#include <machine/clock.h>
#include <machine/bus_pio.h>
#include <machine/bus.h>
#include <sys/timepps.h>
@@ -58,7 +57,7 @@ static device_method_t sio_isa_methods[] = {
static driver_t sio_isa_driver = {
sio_driver_name,
sio_isa_methods,
- sizeof(struct com_s),
+ 0,
};
static struct isa_pnp_id sio_ids[] = {
diff --git a/sys/dev/sio/sio_pccard.c b/sys/dev/sio/sio_pccard.c
index c25709d..0a40927 100644
--- a/sys/dev/sio/sio_pccard.c
+++ b/sys/dev/sio/sio_pccard.c
@@ -34,7 +34,6 @@
#include <sys/mutex.h>
#include <sys/module.h>
#include <sys/tty.h>
-#include <machine/clock.h>
#include <machine/bus_pio.h>
#include <machine/bus.h>
#include <machine/resource.h>
@@ -68,7 +67,7 @@ static device_method_t sio_pccard_methods[] = {
static driver_t sio_pccard_driver = {
sio_driver_name,
sio_pccard_methods,
- sizeof(struct com_s),
+ 0,
};
static int
diff --git a/sys/dev/sio/sio_pci.c b/sys/dev/sio/sio_pci.c
index 8d1af7a..a369146 100644
--- a/sys/dev/sio/sio_pci.c
+++ b/sys/dev/sio/sio_pci.c
@@ -34,14 +34,12 @@
#include <sys/mutex.h>
#include <sys/module.h>
#include <sys/tty.h>
-#include <machine/clock.h>
#include <machine/bus_pio.h>
#include <machine/bus.h>
#include <sys/timepps.h>
#include <dev/sio/siovar.h>
-#include <pci/pcireg.h>
#include <pci/pcivar.h>
static int sio_pci_attach __P((device_t dev));
@@ -59,7 +57,7 @@ static device_method_t sio_pci_methods[] = {
static driver_t sio_pci_driver = {
sio_driver_name,
sio_pci_methods,
- sizeof(struct com_s),
+ 0,
};
struct pci_ids {
diff --git a/sys/dev/sio/siovar.h b/sys/dev/sio/siovar.h
index 7d95fe9..ebc2968 100644
--- a/sys/dev/sio/siovar.h
+++ b/sys/dev/sio/siovar.h
@@ -33,118 +33,6 @@
* $FreeBSD$
*/
-#define SET_FLAG(dev, bit) device_set_flags(dev, device_get_flags(dev) | (bit))
-#define CLR_FLAG(dev, bit) device_set_flags(dev, device_get_flags(dev) & ~(bit))
-
-#define CE_NTYPES 3
-
-/* types. XXX - should be elsewhere */
-typedef u_int Port_t; /* hardware port */
-typedef u_char bool_t; /* boolean */
-
-/* queue of linear buffers */
-struct lbq {
- u_char *l_head; /* next char to process */
- u_char *l_tail; /* one past the last char to process */
- struct lbq *l_next; /* next in queue */
- bool_t l_queued; /* nonzero if queued */
-};
-
-/* com device structure */
-struct com_s {
- u_int flags; /* Copy isa device flags */
- u_char state; /* miscellaneous flag bits */
- bool_t active_out; /* nonzero if the callout device is open */
- u_char cfcr_image; /* copy of value written to CFCR */
-#ifdef COM_ESP
- bool_t esp; /* is this unit a hayes esp board? */
-#endif
- u_char extra_state; /* more flag bits, separate for order trick */
- u_char fifo_image; /* copy of value written to FIFO */
- bool_t hasfifo; /* nonzero for 16550 UARTs */
- bool_t st16650a; /* Is a Startech 16650A or RTS/CTS compat */
- bool_t loses_outints; /* nonzero if device loses output interrupts */
- u_char mcr_image; /* copy of value written to MCR */
-#ifdef COM_MULTIPORT
- bool_t multiport; /* is this unit part of a multiport device? */
-#endif /* COM_MULTIPORT */
- bool_t no_irq; /* nonzero if irq is not attached */
- bool_t gone; /* hardware disappeared */
- bool_t poll; /* nonzero if polling is required */
- bool_t poll_output; /* nonzero if polling for output is required */
- int unit; /* unit number */
- int dtr_wait; /* time to hold DTR down on close (* 1/hz) */
- u_int tx_fifo_size;
- u_int wopeners; /* # processes waiting for DCD in open() */
-
- /*
- * The high level of the driver never reads status registers directly
- * because there would be too many side effects to handle conveniently.
- * Instead, it reads copies of the registers stored here by the
- * interrupt handler.
- */
- u_char last_modem_status; /* last MSR read by intr handler */
- u_char prev_modem_status; /* last MSR handled by high level */
-
- u_char hotchar; /* ldisc-specific char to be handled ASAP */
- u_char *ibuf; /* start of input buffer */
- u_char *ibufend; /* end of input buffer */
- u_char *ibufold; /* old input buffer, to be freed */
- u_char *ihighwater; /* threshold in input buffer */
- u_char *iptr; /* next free spot in input buffer */
- int ibufsize; /* size of ibuf (not include error bytes) */
- int ierroff; /* offset of error bytes in ibuf */
-
- struct lbq obufq; /* head of queue of output buffers */
- struct lbq obufs[2]; /* output buffers */
-
- bus_space_tag_t bst;
- bus_space_handle_t bsh;
-
- Port_t data_port; /* i/o ports */
-#ifdef COM_ESP
- Port_t esp_port;
-#endif
- Port_t int_id_port;
- Port_t modem_ctl_port;
- Port_t line_status_port;
- Port_t modem_status_port;
- Port_t intr_ctl_port; /* Ports of IIR register */
-
- struct tty *tp; /* cross reference */
-
- /* Initial state. */
- struct termios it_in; /* should be in struct tty */
- struct termios it_out;
-
- /* Lock state. */
- struct termios lt_in; /* should be in struct tty */
- struct termios lt_out;
-
- bool_t do_timestamp;
- bool_t do_dcd_timestamp;
- struct timeval timestamp;
- struct timeval dcd_timestamp;
- struct pps_state pps;
-
- u_long bytes_in; /* statistics */
- u_long bytes_out;
- u_int delta_error_counts[CE_NTYPES];
- u_long error_counts[CE_NTYPES];
-
- struct resource *irqres;
- struct resource *ioportres;
- void *cookie;
- dev_t devs[6];
-
- /*
- * Data area for output buffers. Someday we should build the output
- * buffer queue without copying data.
- */
- u_char obuf1[256];
- u_char obuf2[256];
-};
-
int sioattach __P((device_t dev, int xrid));
int siodetach __P((device_t dev));
int sioprobe __P((device_t dev, int xrid, int noprobe));
OpenPOWER on IntegriCloud