diff options
| author | Maxim Sobolev <sobomax@FreeBSD.org> | 2003-03-15 16:25:40 +0000 |
|---|---|---|
| committer | Maxim Sobolev <sobomax@FreeBSD.org> | 2003-03-15 16:25:40 +0000 |
| commit | 084254f80770c2c3fd71da3a2fe223b8d4b8b102 (patch) | |
| tree | 55efefc19da767f399830aeb6d78166bc554ea4f /sys/dev/puc | |
| parent | 40811c1473f27350ba0ac7325dbe627943f471a1 (diff) | |
Notes
Diffstat (limited to 'sys/dev/puc')
| -rw-r--r-- | sys/dev/puc/puc.c | 74 | ||||
| -rw-r--r-- | sys/dev/puc/pucdata.c | 66 | ||||
| -rw-r--r-- | sys/dev/puc/pucvar.h | 9 |
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; |
