PERFORCE change 64479 for review
Marcel Moolenaar
marcel at FreeBSD.org
Sat Nov 6 18:42:24 PST 2004
http://perforce.freebsd.org/chv.cgi?CH=64479
Change 64479 by marcel at marcel_nfs on 2004/11/07 02:42:00
o define structures to represent the SCC channels and modes.
o have scc_bfe_attach() create the channels and modes and
associate an unnamed device_t to each node.
o s/sc/cl/g for the prefix of fields of struct scc_class.
o add cl_class and cl_modes to struct scc_class.
o implement scc_bus_read_ivar().
Affected files ...
.. //depot/projects/uart/dev/scc/scc_bfe.h#5 edit
.. //depot/projects/uart/dev/scc/scc_core.c#3 edit
.. //depot/projects/uart/dev/scc/scc_dev_sab82532.c#2 edit
.. //depot/projects/uart/dev/scc/scc_dev_z8530.c#2 edit
Differences ...
==== //depot/projects/uart/dev/scc/scc_bfe.h#5 (text+ko) ====
@@ -45,14 +45,46 @@
#define SCC_IPEND_SIGMASK 0x00ffff
/*
+ * SCC mode (child) and channel control structures.
+ */
+struct scc_chan;
+
+struct scc_mode {
+ STAILQ_ENTRY(scc_mode) m_link;
+ struct scc_chan *m_chan;
+ device_t m_dev;
+
+ int m_mode;
+ int m_alloc_rres:1;
+
+ driver_intr_t *ih;
+ driver_intr_t *ih_ovrrun;
+ driver_intr_t *ih_break;
+ driver_intr_t *ih_rxready;
+ driver_intr_t *ih_sigchg;
+ driver_intr_t *ih_txidle;
+};
+
+struct scc_chan {
+ STAILQ_ENTRY(scc_chan) ch_link;
+ struct resource_list ch_rlist;
+
+ STAILQ_HEAD(, scc_mode) ch_mode;
+
+ u_int ch_nr;
+};
+
+/*
* SCC class & instance (=softc)
*/
struct scc_class {
KOBJ_CLASS_FIELDS;
- u_int sc_channels;
- u_int sc_range;
- u_int sc_rclk;
- u_int sc_regshft;
+ int cl_channels; /* Number of independent channels. */
+ int cl_class; /* SCC bus class ID. */
+ int cl_modes; /* Supported modes (bitset). */
+ int cl_range;
+ int cl_rclk;
+ int cl_regshft;
};
extern struct scc_class scc_sab82532_class;
@@ -71,6 +103,11 @@
struct resource *sc_ires; /* Interrupt resource. */
void *sc_icookie;
int sc_irid;
+
+ STAILQ_HEAD(, scc_chan) sc_chan;
+
+ int sc_fastintr:1;
+ int sc_polled:1;
};
extern devclass_t scc_devclass;
==== //depot/projects/uart/dev/scc/scc_core.c#3 (text+ko) ====
@@ -33,6 +33,7 @@
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
+#include <sys/queue.h>
#include <machine/bus.h>
#include <machine/resource.h>
@@ -44,18 +45,90 @@
devclass_t scc_devclass;
char scc_driver_name[] = "scc";
+MALLOC_DEFINE(M_SCC, "SCC", "SCC driver");
+
+static void
+scc_bfe_intr(void *arg)
+{
+}
+
int
scc_bfe_attach(device_t dev)
{
+ struct scc_chan *ch;
+ struct scc_class *cl;
+ struct scc_mode *m;
struct scc_softc *sc;
+ u_long size, start;
+ int c, error, i, mode;
sc = device_get_softc(dev);
+ cl = sc->sc_class;
+
sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype, &sc->sc_rrid,
- 0, ~0, sc->sc_class->sc_range, RF_ACTIVE);
+ 0, ~0, cl->cl_range, RF_ACTIVE);
if (sc->sc_rres == NULL)
return (ENXIO);
- return (ENXIO);
+ sc->sc_irid = 0;
+ sc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_irid,
+ RF_ACTIVE);
+ if (sc->sc_ires != NULL) {
+ error = BUS_SETUP_INTR(device_get_parent(dev), dev,
+ sc->sc_ires, INTR_TYPE_TTY | INTR_FAST, scc_bfe_intr,
+ sc, &sc->sc_icookie);
+ if (error)
+ error = BUS_SETUP_INTR(device_get_parent(dev), dev,
+ sc->sc_ires, INTR_TYPE_TTY | INTR_MPSAFE,
+ scc_bfe_intr, sc, &sc->sc_icookie);
+ else
+ sc->sc_fastintr = 1;
+
+ if (error) {
+ device_printf(dev, "could not activate interrupt\n");
+ bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid,
+ sc->sc_ires);
+ sc->sc_ires = NULL;
+ }
+ }
+ if (sc->sc_ires == NULL) {
+ /* XXX no interrupt resource. Force polled mode. */
+ sc->sc_polled = 1;
+ }
+
+ STAILQ_INIT(&sc->sc_chan);
+ size = cl->cl_range / cl->cl_channels;
+ start = rman_get_start(sc->sc_rres);
+ for (c = 1; c <= cl->cl_channels; c++) {
+ ch = malloc(sizeof(struct scc_chan), M_SCC, M_WAITOK | M_ZERO);
+ STAILQ_INSERT_TAIL(&sc->sc_chan, ch, ch_link);
+ ch->ch_nr = c;
+
+ resource_list_init(&ch->ch_rlist);
+ resource_list_add(&ch->ch_rlist, sc->sc_rtype, sc->sc_rrid,
+ start, start + size - 1, size);
+ resource_list_add(&ch->ch_rlist, SYS_RES_IRQ, sc->sc_irid,
+ rman_get_start(sc->sc_ires), rman_get_end(sc->sc_ires), 1);
+
+ STAILQ_INIT(&ch->ch_mode);
+ mode = cl->cl_modes;
+ while (mode != 0) {
+ m = malloc(sizeof(struct scc_mode), M_SCC,
+ M_WAITOK | M_ZERO);
+ STAILQ_INSERT_TAIL(&ch->ch_mode, m, m_link);
+ m->m_chan = ch;
+ m->m_dev = device_add_child(dev, NULL, -1);
+ device_set_ivars(m->m_dev, (void *)m);
+ i = ffs(mode) - 1;
+ m->m_mode = 1 << i;
+ mode &= ~m->m_mode;
+ device_probe_and_attach(m->m_dev);
+ }
+
+ start += size >> cl->cl_regshft;
+ }
+
+ return (0);
}
int
@@ -93,12 +166,12 @@
sc->sc_rrid = 0;
sc->sc_rtype = SYS_RES_IOPORT;
sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype, &sc->sc_rrid,
- 0, ~0, sc->sc_class->sc_range, RF_ACTIVE);
+ 0, ~0, sc->sc_class->cl_range, RF_ACTIVE);
if (sc->sc_rres == NULL) {
sc->sc_rrid = 0;
sc->sc_rtype = SYS_RES_MEMORY;
sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype,
- &sc->sc_rrid, 0, ~0, sc->sc_class->sc_range, RF_ACTIVE);
+ &sc->sc_rrid, 0, ~0, sc->sc_class->cl_range, RF_ACTIVE);
if (sc->sc_rres == NULL)
return (ENXIO);
}
@@ -111,7 +184,7 @@
scc_bus_alloc_resource(device_t dev, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
-
+ device_printf(dev, "%s\n", __func__);
return (NULL);
}
@@ -126,20 +199,36 @@
int
scc_bus_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
{
+ struct scc_chan *ch;
+ struct scc_class *cl;
+ struct scc_mode *m;
+ struct scc_softc *sc;
+ sc = device_get_softc(dev);
+ cl = sc->sc_class;
+ m = device_get_ivars(child);
+ ch = m->m_chan;
+
switch (index) {
case SCC_IVAR_CHANNEL:
+ *result = ch->ch_nr;
break;
case SCC_IVAR_CLASS:
+ *result = cl->cl_class;
break;
case SCC_IVAR_CLOCK:
+ *result = cl->cl_rclk;
break;
+ case SCC_IVAR_MODE:
+ *result = m->m_mode;
+ break;
case SCC_IVAR_REGSHFT:
+ *result = cl->cl_regshft;
break;
default:
return (EINVAL);
}
- return (ENXIO);
+ return (0);
}
int
==== //depot/projects/uart/dev/scc/scc_dev_sab82532.c#2 (text+ko) ====
@@ -34,6 +34,7 @@
#include <machine/bus.h>
#include <dev/scc/scc_bfe.h>
+#include <dev/scc/scc_bus.h>
#define DEFAULT_RCLK 29491200
@@ -45,8 +46,10 @@
"sab82532 class",
sab82532_methods,
sizeof(struct scc_softc),
- .sc_channels = 2,
- .sc_range = 64,
- .sc_rclk = DEFAULT_RCLK,
- .sc_regshft = 0
+ .cl_channels = 2,
+ .cl_class = SCC_CLASS_SAB82532,
+ .cl_modes = SCC_MODE_ASYNC | SCC_MODE_BISYNC | SCC_MODE_HDLC,
+ .cl_range = 64,
+ .cl_rclk = DEFAULT_RCLK,
+ .cl_regshft = 0
};
==== //depot/projects/uart/dev/scc/scc_dev_z8530.c#2 (text+ko) ====
@@ -34,6 +34,7 @@
#include <machine/bus.h>
#include <dev/scc/scc_bfe.h>
+#include <dev/scc/scc_bus.h>
#define DEFAULT_RCLK 307200
@@ -45,8 +46,10 @@
"z8530 class",
z8530_methods,
sizeof(struct scc_softc),
- .sc_channels = 2,
- .sc_range = 2,
- .sc_rclk = DEFAULT_RCLK,
- .sc_regshft = 1,
+ .cl_channels = 2,
+ .cl_class = SCC_CLASS_Z8530,
+ .cl_modes = SCC_MODE_ASYNC | SCC_MODE_BISYNC | SCC_MODE_HDLC,
+ .cl_range = 2,
+ .cl_rclk = DEFAULT_RCLK,
+ .cl_regshft = 1,
};
More information about the p4-projects
mailing list