summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2001-11-26 07:39:51 +0000
committerimp <imp@FreeBSD.org>2001-11-26 07:39:51 +0000
commitb81d338044f3ac68d3c7a8a919932f5291954137 (patch)
tree22a359138de748f0c30c96f678a41c6ac8f3c1ca /sys
parent31e236c67382da93a93ae78dbeb8c445088b17bc (diff)
downloadFreeBSD-src-b81d338044f3ac68d3c7a8a919932f5291954137.zip
FreeBSD-src-b81d338044f3ac68d3c7a8a919932f5291954137.tar.gz
bde suggests that sio really wants to manage its own softc. This
allows us to move the sio softc data structure back into sio.c and reduce the complexity of the non sio.c sio files. Submitted by: bde # I didn't fix the locking issues that bruce also submitted.
Diffstat (limited to 'sys')
-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