aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/puc
diff options
context:
space:
mode:
authorMaxim Sobolev <sobomax@FreeBSD.org>2003-03-15 16:25:40 +0000
committerMaxim Sobolev <sobomax@FreeBSD.org>2003-03-15 16:25:40 +0000
commit084254f80770c2c3fd71da3a2fe223b8d4b8b102 (patch)
tree55efefc19da767f399830aeb6d78166bc554ea4f /sys/dev/puc
parent40811c1473f27350ba0ac7325dbe627943f471a1 (diff)
Notes
Diffstat (limited to 'sys/dev/puc')
-rw-r--r--sys/dev/puc/puc.c74
-rw-r--r--sys/dev/puc/pucdata.c66
-rw-r--r--sys/dev/puc/pucvar.h9
3 files changed, 111 insertions, 38 deletions
diff --git a/sys/dev/puc/puc.c b/sys/dev/puc/puc.c
index 18d2fbabc0f5..fedf9bb073cf 100644
--- a/sys/dev/puc/puc.c
+++ b/sys/dev/puc/puc.c
@@ -130,6 +130,35 @@ puc_port_bar_index(struct puc_softc *sc, int bar)
return (i);
}
+static int
+puc_probe_ilr(struct puc_softc *sc, struct resource *res)
+{
+ u_char t1, t2;
+ int i;
+
+ switch (sc->sc_desc->ilr_type) {
+ case PUC_ILR_TYPE_DIGI:
+ sc->ilr_st = rman_get_bustag(res);
+ sc->ilr_sh = rman_get_bushandle(res);
+ for (i = 0; i < 2; i++) {
+ t1 = bus_space_read_1(sc->ilr_st, sc->ilr_sh,
+ sc->sc_desc->ilr_offset[i]);
+ t1 = ~t1;
+ bus_space_write_1(sc->ilr_st, sc->ilr_sh,
+ sc->sc_desc->ilr_offset[i], t1);
+ t2 = bus_space_read_1(sc->ilr_st, sc->ilr_sh,
+ sc->sc_desc->ilr_offset[i]);
+ if (t2 == t1)
+ return (0);
+ }
+ return (1);
+
+ default:
+ break;
+ }
+ return (0);
+}
+
int
puc_attach(device_t dev, const struct puc_device_description *desc)
{
@@ -195,6 +224,14 @@ puc_attach(device_t dev, const struct puc_device_description *desc)
}
sc->sc_bar_mappings[bidx].type = type;
sc->sc_bar_mappings[bidx].res = res;
+
+ if (sc->sc_desc->ilr_type != PUC_ILR_TYPE_NONE) {
+ sc->ilr_enabled = puc_probe_ilr(sc, res);
+ if (sc->ilr_enabled)
+ device_printf(dev, "ILR enabled\n");
+ else
+ device_printf(dev, "ILR disabled\n");
+ }
#ifdef PUC_DEBUG
printf("%s rid %d bst %x, start %x, end %x\n",
(type == SYS_RES_MEMORY) ? "memory" : "port", rid,
@@ -307,22 +344,47 @@ puc_attach(device_t dev, const struct puc_device_description *desc)
return (0);
}
+static u_int32_t
+puc_ilr_read(struct puc_softc *sc)
+{
+ u_int32_t mask;
+ int i;
+
+ mask = 0;
+ switch (sc->sc_desc->ilr_type) {
+ case PUC_ILR_TYPE_DIGI:
+ for (i = 1; i >= 0; i--) {
+ mask = (mask << 8) | (bus_space_read_1(sc->ilr_st,
+ sc->ilr_sh, sc->sc_desc->ilr_offset[i]) & 0xff);
+ }
+ break;
+
+ default:
+ mask = 0xffffffff;
+ break;
+ }
+ return (mask);
+}
+
/*
- * This is just a brute force interrupt handler. It just calls all the
- * registered handlers sequencially.
- *
- * Later on we should maybe have a different handler for boards that can
- * tell us which device generated the interrupt.
+ * This is an interrupt handler. For boards that can't tell us which
+ * device generated the interrupt it just calls all the registered
+ * handlers sequencially, but for boards that can tell us which
+ * device(s) generated the interrupt it calls only handlers for devices
+ * that actually generated the interrupt.
*/
static void
puc_intr(void *arg)
{
int i;
+ u_int32_t ilr_mask;
struct puc_softc *sc;
sc = (struct puc_softc *)arg;
+ ilr_mask = sc->ilr_enabled ? puc_ilr_read(sc) : 0xffffffff;
for (i = 0; i < PUC_MAX_PORTS; i++)
- if (sc->sc_ports[i].ihand != NULL)
+ if (sc->sc_ports[i].ihand != NULL &&
+ ((ilr_mask >> i) & 0x00000001))
(sc->sc_ports[i].ihand)(sc->sc_ports[i].ihandarg);
}
diff --git a/sys/dev/puc/pucdata.c b/sys/dev/puc/pucdata.c
index e55621502b6e..7e65aa775a15 100644
--- a/sys/dev/puc/pucdata.c
+++ b/sys/dev/puc/pucdata.c
@@ -1000,23 +1000,24 @@ const struct puc_device_description puc_devices[] = {
{ 0xb00c, 0x091c, 0, 0 },
{ 0xffff, 0xffff, 0, 0 },
{
- { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x20, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x28, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x30, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x38, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x40, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x48, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x50, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x58, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x60, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x68, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x70, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x78, COM_FREQ * 4 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x20, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x28, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x30, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x38, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x40, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x48, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x50, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x58, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x60, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x68, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x70, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x78, COM_FREQ },
},
+ PUC_ILR_TYPE_DIGI, { 0x07, 0x47 },
},
{ "IC Book Labs Dreadnought x16 Pro",
@@ -1024,23 +1025,24 @@ const struct puc_device_description puc_devices[] = {
{ 0xb00c, 0x081c, 0, 0 },
{ 0xffff, 0xffff, 0, 0 },
{
- { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x20, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x28, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x30, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x38, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x40, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x48, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x50, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x58, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x60, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x68, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x70, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x78, COM_FREQ * 8 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x20, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x28, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x30, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x38, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x40, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x48, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x50, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x58, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x60, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x68, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x70, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x78, COM_FREQ * 8, 0x200000 },
},
+ PUC_ILR_TYPE_DIGI, { 0x07, 0x47 },
},
{ 0 }
diff --git a/sys/dev/puc/pucvar.h b/sys/dev/puc/pucvar.h
index fcbb0eb86b66..9bb3928340de 100644
--- a/sys/dev/puc/pucvar.h
+++ b/sys/dev/puc/pucvar.h
@@ -80,6 +80,8 @@ struct puc_device_description {
u_int serialfreq;
u_int flags;
} ports[PUC_MAX_PORTS];
+ uint32_t ilr_type;
+ uint32_t ilr_offset[2];
};
#define PUC_REG_VEND 0
@@ -91,6 +93,10 @@ struct puc_device_description {
#define PUC_PORT_TYPE_COM 1
#define PUC_PORT_TYPE_LPT 2
+/* Interrupt Latch Register (ILR) types */
+#define PUC_ILR_TYPE_NONE 0
+#define PUC_ILR_TYPE_DIGI 1
+
#define PUC_FLAGS_MEMORY 0x0001 /* Use memory mapped I/O. */
#define PUC_PORT_VALID(desc, port) \
@@ -126,6 +132,9 @@ struct puc_softc {
int irqrid;
struct resource *irqres;
void *intr_cookie;
+ int ilr_enabled;
+ bus_space_tag_t ilr_st;
+ bus_space_handle_t ilr_sh;
struct {
int used;