From de27193cae74efc68618f3709bde0e09ae6db4df Mon Sep 17 00:00:00 2001 From: marcel Date: Sat, 6 Sep 2003 21:48:50 +0000 Subject: Enhance puc(4) to support uart(4). This includes: o Introduce PUC_PORT_TYPE_UART so that we can attach to uart(4), o Introduce port sub-types (eg PUC_PORT_UART_NS8250, PUC_PORT_UART_Z8530) to handle different hardware and determine resource sizes. o Introduce two new IVARs: PUC_IVAR_SUBTYPE and PUC_IVAR_REGSHFT. Both are used by uart(4) to get sufficient information to talk to the HW. o Introduce PUC_FLAGS_ALTRES to tell puc(4) to try memory mapped I/O if I/O port space cannot be allocated, or vice versa. o Have ports of type PUC_PORT_TYPE_COM attach to uart(1) if attaching to sio(4) fails (due to not having the sio driver). o Put struct puc_device_description in struct puc_softc instead of having a pointer to a device description in the softc. This allows us to create device descriptions on the fly without having to use malloc() or otherwise have them staticly defined. o Move puc_find_description() from puc.c to puc_pci.c as it's specific to PCI. o Add EBUS and SBUS frontends for use on sparc64. Note that the P in puc stands for PCI, so we kinda mess things up here. It's too soon to worry about it though. We'll know what to do about it in time. NOTE: This commit changes the behaviour of puc(4) to not quieten the device probe and attach for child devices. The uart(4) driver provides additional device description that is valuable to have. --- sys/dev/puc/puc.c | 149 ++++++++++++++++++++++++++----------------------- sys/dev/puc/puc_ebus.c | 100 +++++++++++++++++++++++++++++++++ sys/dev/puc/puc_pci.c | 26 +++++++++ sys/dev/puc/puc_sbus.c | 101 +++++++++++++++++++++++++++++++++ sys/dev/puc/pucdata.c | 13 +++++ sys/dev/puc/pucvar.h | 22 +++++--- 6 files changed, 334 insertions(+), 77 deletions(-) create mode 100644 sys/dev/puc/puc_ebus.c create mode 100644 sys/dev/puc/puc_sbus.c (limited to 'sys/dev') diff --git a/sys/dev/puc/puc.c b/sys/dev/puc/puc.c index 694e348..8ba17b1 100644 --- a/sys/dev/puc/puc.c +++ b/sys/dev/puc/puc.c @@ -105,7 +105,9 @@ __FBSDID("$FreeBSD$"); struct puc_device { struct resource_list resources; - u_int serialfreq; + u_int serialfreq; + u_int subtype; + int regshft; }; static void puc_intr(void *arg); @@ -139,18 +141,18 @@ puc_probe_ilr(struct puc_softc *sc, struct resource *res) u_char t1, t2; int i; - switch (sc->sc_desc->ilr_type) { + 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 && sc->sc_desc->ilr_offset[i] != 0; i++) { + for (i = 0; i < 2 && sc->sc_desc.ilr_offset[i] != 0; i++) { t1 = bus_space_read_1(sc->ilr_st, sc->ilr_sh, - sc->sc_desc->ilr_offset[i]); + 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); + sc->sc_desc.ilr_offset[i], t1); t2 = bus_space_read_1(sc->ilr_st, sc->ilr_sh, - sc->sc_desc->ilr_offset[i]); + sc->sc_desc.ilr_offset[i]); if (t2 == t1) return (0); } @@ -166,22 +168,23 @@ int puc_attach(device_t dev, const struct puc_device_description *desc) { char *typestr; - int bidx, childunit, i, irq_setup, rid, type; + int bidx, childunit, i, irq_setup, ressz, rid, type; struct puc_softc *sc; struct puc_device *pdev; struct resource *res; struct resource_list_entry *rle; + if (desc == NULL) + return (ENXIO); + sc = (struct puc_softc *)device_get_softc(dev); bzero(sc, sizeof(*sc)); - sc->sc_desc = desc; - if (sc->sc_desc == NULL) - return (ENXIO); + sc->sc_desc = *desc; #ifdef PUC_DEBUG bootverbose = 1; - printf("puc: name: %s\n", sc->sc_desc->name); + printf("puc: name: %s\n", sc->sc_desc.name); #endif rid = 0; res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, @@ -208,27 +211,34 @@ puc_attach(device_t dev, const struct puc_device_description *desc) rid = 0; for (i = 0; PUC_PORT_VALID(sc->sc_desc, i); i++) { - if (i > 0 && rid == sc->sc_desc->ports[i].bar) + if (i > 0 && rid == sc->sc_desc.ports[i].bar) sc->barmuxed = 1; - rid = sc->sc_desc->ports[i].bar; + rid = sc->sc_desc.ports[i].bar; bidx = puc_port_bar_index(sc, rid); if (sc->sc_bar_mappings[bidx].res != NULL) continue; - type = (sc->sc_desc->ports[i].flags & PUC_FLAGS_MEMORY) + type = (sc->sc_desc.ports[i].flags & PUC_FLAGS_MEMORY) ? SYS_RES_MEMORY : SYS_RES_IOPORT; res = bus_alloc_resource(dev, type, &rid, 0ul, ~0ul, 1, RF_ACTIVE); + if (res == NULL && + sc->sc_desc.ports[i].flags & PUC_FLAGS_ALTRES) { + type = (type == SYS_RES_IOPORT) + ? SYS_RES_MEMORY : SYS_RES_IOPORT; + res = bus_alloc_resource(dev, type, &rid, 0ul, ~0ul, 1, + RF_ACTIVE); + } if (res == NULL) { - printf("could not get resource\n"); + device_printf(dev, "could not get resource\n"); continue; } sc->sc_bar_mappings[bidx].type = type; sc->sc_bar_mappings[bidx].res = res; - if (sc->sc_desc->ilr_type != PUC_ILR_TYPE_NONE) { + 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"); @@ -236,10 +246,10 @@ puc_attach(device_t dev, const struct puc_device_description *desc) device_printf(dev, "ILR disabled\n"); } #ifdef PUC_DEBUG - printf("%s rid %d bst %x, start %x, end %x\n", + printf("%s rid %d bst %lx, start %lx, end %lx\n", (type == SYS_RES_MEMORY) ? "memory" : "port", rid, - (u_int)rman_get_bustag(res), (u_int)rman_get_start(res), - (u_int)rman_get_end(res)); + (u_long)rman_get_bustag(res), (u_long)rman_get_start(res), + (u_long)rman_get_end(res)); #endif } @@ -250,21 +260,35 @@ puc_attach(device_t dev, const struct puc_device_description *desc) } for (i = 0; PUC_PORT_VALID(sc->sc_desc, i); i++) { - rid = sc->sc_desc->ports[i].bar; + rid = sc->sc_desc.ports[i].bar; bidx = puc_port_bar_index(sc, rid); if (sc->sc_bar_mappings[bidx].res == NULL) continue; - switch (sc->sc_desc->ports[i].type) { + switch (sc->sc_desc.ports[i].type & ~PUC_PORT_SUBTYPE_MASK) { case PUC_PORT_TYPE_COM: typestr = "sio"; break; case PUC_PORT_TYPE_LPT: typestr = "ppc"; break; + case PUC_PORT_TYPE_UART: + typestr = "uart"; + break; default: continue; } + switch (sc->sc_desc.ports[i].type & PUC_PORT_SUBTYPE_MASK) { + case PUC_PORT_UART_SAB82532: + ressz = 64; + break; + case PUC_PORT_UART_Z8530: + ressz = 2; + break; + default: + ressz = 8; + break; + } pdev = malloc(sizeof(struct puc_device), M_DEVBUF, M_NOWAIT | M_ZERO); if (!pdev) @@ -282,9 +306,9 @@ puc_attach(device_t dev, const struct puc_device_description *desc) res = sc->sc_bar_mappings[bidx].res; type = sc->sc_bar_mappings[bidx].type; resource_list_add(&pdev->resources, type, 0, - rman_get_start(res) + sc->sc_desc->ports[i].offset, - rman_get_start(res) + sc->sc_desc->ports[i].offset + 8 - 1, - 8); + rman_get_start(res) + sc->sc_desc.ports[i].offset, + rman_get_start(res) + sc->sc_desc.ports[i].offset + + ressz - 1, ressz); rle = resource_list_find(&pdev->resources, type, 0); if (sc->barmuxed == 0) { @@ -298,46 +322,51 @@ puc_attach(device_t dev, const struct puc_device_description *desc) } rle->res->r_start = rman_get_start(res) + - sc->sc_desc->ports[i].offset; - rle->res->r_end = rle->res->r_start + 8 - 1; + sc->sc_desc.ports[i].offset; + rle->res->r_end = rle->res->r_start + ressz - 1; rle->res->r_bustag = rman_get_bustag(res); bus_space_subregion(rle->res->r_bustag, rman_get_bushandle(res), - sc->sc_desc->ports[i].offset, 8, + sc->sc_desc.ports[i].offset, ressz, &rle->res->r_bushandle); } - pdev->serialfreq = sc->sc_desc->ports[i].serialfreq; + pdev->serialfreq = sc->sc_desc.ports[i].serialfreq; + pdev->subtype = sc->sc_desc.ports[i].type & + PUC_PORT_SUBTYPE_MASK; + pdev->regshft = sc->sc_desc.ports[i].regshft; childunit = puc_find_free_unit(typestr); - sc->sc_ports[i].dev = device_add_child(dev, typestr, childunit); + if (childunit < 0 && strcmp(typestr, "uart") != 0) { + typestr = "uart"; + childunit = puc_find_free_unit(typestr); + } + sc->sc_ports[i].dev = device_add_child(dev, typestr, + childunit); if (sc->sc_ports[i].dev == NULL) { if (sc->barmuxed) { bus_space_unmap(rman_get_bustag(rle->res), - rman_get_bushandle(rle->res), 8); + rman_get_bushandle(rle->res), ressz); free(rle->res, M_DEVBUF); free(pdev, M_DEVBUF); } continue; } device_set_ivars(sc->sc_ports[i].dev, pdev); - device_set_desc(sc->sc_ports[i].dev, sc->sc_desc->name); - if (!bootverbose) - device_quiet(sc->sc_ports[i].dev); + device_set_desc(sc->sc_ports[i].dev, sc->sc_desc.name); #ifdef PUC_DEBUG printf("puc: type %d, bar %x, offset %x\n", - sc->sc_desc->ports[i].type, - sc->sc_desc->ports[i].bar, - sc->sc_desc->ports[i].offset); + sc->sc_desc.ports[i].type, + sc->sc_desc.ports[i].bar, + sc->sc_desc.ports[i].offset); puc_print_resource_list(&pdev->resources); #endif device_set_flags(sc->sc_ports[i].dev, - sc->sc_desc->ports[i].flags); + sc->sc_desc.ports[i].flags); if (device_probe_and_attach(sc->sc_ports[i].dev) != 0) { if (sc->barmuxed) { bus_space_unmap(rman_get_bustag(rle->res), - rman_get_bushandle(rle->res), - 8); + rman_get_bushandle(rle->res), ressz); free(rle->res, M_DEVBUF); free(pdev, M_DEVBUF); } @@ -357,11 +386,11 @@ puc_ilr_read(struct puc_softc *sc) int i; mask = 0; - switch (sc->sc_desc->ilr_type) { + switch (sc->sc_desc.ilr_type) { case PUC_ILR_TYPE_DIGI: - for (i = 1; i >= 0 && sc->sc_desc->ilr_offset[i] != 0; i--) { + for (i = 1; i >= 0 && sc->sc_desc.ilr_offset[i] != 0; i--) { mask = (mask << 8) | (bus_space_read_1(sc->ilr_st, - sc->ilr_sh, sc->sc_desc->ilr_offset[i]) & 0xff); + sc->ilr_sh, sc->sc_desc.ilr_offset[i]) & 0xff); } break; @@ -394,28 +423,6 @@ puc_intr(void *arg) (sc->sc_ports[i].ihand)(sc->sc_ports[i].ihandarg); } -const struct puc_device_description * -puc_find_description(uint32_t vend, uint32_t prod, uint32_t svend, - uint32_t sprod) -{ - int i; - -#define checkreg(val, index) \ - (((val) & puc_devices[i].rmask[(index)]) == puc_devices[i].rval[(index)]) - - for (i = 0; puc_devices[i].name != NULL; i++) { - if (checkreg(vend, PUC_REG_VEND) && - checkreg(prod, PUC_REG_PROD) && - checkreg(svend, PUC_REG_SVEND) && - checkreg(sprod, PUC_REG_SPROD)) - return (&puc_devices[i]); - } - -#undef checkreg - - return (NULL); -} - static int puc_find_free_unit(char *name) { @@ -448,7 +455,7 @@ puc_print_resource_list(struct resource_list *rl) printf("print_resource_list: rl %p\n", rl); SLIST_FOREACH(rle, rl, link) - printf(" type %x, rid %x start %x end %x count %x\n", + printf(" type %x, rid %x start %lx end %lx count %lx\n", rle->type, rle->rid, rle->start, rle->end, rle->count); printf("print_resource_list: end.\n"); #endif @@ -482,11 +489,9 @@ puc_alloc_resource(device_t dev, device_t child, int type, int *rid, retval = NULL; rle = resource_list_find(rl, type, *rid); if (rle) { - start = rle->start; - end = rle->end; - count = rle->count; #ifdef PUC_DEBUG - printf("found rle, %lx, %lx, %lx\n", start, end, count); + printf("found rle, %lx, %lx, %lx\n", rle->start, rle->end, + rle->count); #endif retval = rle->res; } @@ -593,6 +598,12 @@ puc_read_ivar(device_t dev, device_t child, int index, uintptr_t *result) case PUC_IVAR_FREQ: *result = pdev->serialfreq; break; + case PUC_IVAR_SUBTYPE: + *result = pdev->subtype; + break; + case PUC_IVAR_REGSHFT: + *result = pdev->regshft; + break; default: return (ENOENT); } diff --git a/sys/dev/puc/puc_ebus.c b/sys/dev/puc/puc_ebus.c new file mode 100644 index 0000000..78fc6d4 --- /dev/null +++ b/sys/dev/puc/puc_ebus.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2003 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "opt_puc.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define PUC_ENTRAILS 1 +#include + +static int +puc_ebus_probe(device_t dev) +{ + const char *nm; + + nm = ebus_get_name(dev); + if (!strcmp(nm, "se")) { + device_set_desc(dev, "Siemens SAB 82532 dual channel SCC"); + return (0); + } + return (ENXIO); +} + +static int +puc_ebus_attach(device_t dev) +{ + struct puc_device_description dd; + int i; + + bzero(&dd, sizeof(dd)); + dd.name = device_get_desc(dev); + for (i = 0; i < 2; i++) { + dd.ports[i].type = PUC_PORT_TYPE_UART | PUC_PORT_UART_SAB82532; + dd.ports[i].bar = 0; + dd.ports[i].offset = 0x40 * i; + dd.ports[i].serialfreq = 0; + dd.ports[i].flags = 0; + } + return (puc_attach(dev, &dd)); +} + +static device_method_t puc_ebus_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, puc_ebus_probe), + DEVMETHOD(device_attach, puc_ebus_attach), + + DEVMETHOD(bus_alloc_resource, puc_alloc_resource), + DEVMETHOD(bus_release_resource, puc_release_resource), + DEVMETHOD(bus_get_resource, puc_get_resource), + DEVMETHOD(bus_read_ivar, puc_read_ivar), + DEVMETHOD(bus_setup_intr, puc_setup_intr), + DEVMETHOD(bus_teardown_intr, puc_teardown_intr), + DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_driver_added, bus_generic_driver_added), + { 0, 0 } +}; + +static driver_t puc_ebus_driver = { + "puc", + puc_ebus_methods, + sizeof(struct puc_softc), +}; + +DRIVER_MODULE(puc, ebus, puc_ebus_driver, puc_devclass, 0, 0); diff --git a/sys/dev/puc/puc_pci.c b/sys/dev/puc/puc_pci.c index 1e6de33..74d7a2e 100644 --- a/sys/dev/puc/puc_pci.c +++ b/sys/dev/puc/puc_pci.c @@ -82,6 +82,32 @@ __FBSDID("$FreeBSD$"); #define PUC_ENTRAILS 1 #include +extern const struct puc_device_description puc_devices[]; + +int puc_config_win877(struct puc_softc *); + +static const struct puc_device_description * +puc_find_description(uint32_t vend, uint32_t prod, uint32_t svend, + uint32_t sprod) +{ + int i; + +#define checkreg(val, index) \ + (((val) & puc_devices[i].rmask[(index)]) == puc_devices[i].rval[(index)]) + + for (i = 0; puc_devices[i].name != NULL; i++) { + if (checkreg(vend, PUC_REG_VEND) && + checkreg(prod, PUC_REG_PROD) && + checkreg(svend, PUC_REG_SVEND) && + checkreg(sprod, PUC_REG_SPROD)) + return (&puc_devices[i]); + } + +#undef checkreg + + return (NULL); +} + static int puc_pci_probe(device_t dev) { diff --git a/sys/dev/puc/puc_sbus.c b/sys/dev/puc/puc_sbus.c new file mode 100644 index 0000000..313d52e --- /dev/null +++ b/sys/dev/puc/puc_sbus.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2003 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "opt_puc.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define PUC_ENTRAILS 1 +#include + +static int +puc_sbus_probe(device_t dev) +{ + const char *nm; + + nm = sbus_get_name(dev); + if (!strcmp(nm, "zs")) { + device_set_desc(dev, "Zilog Z8530 dual channel SCC"); + return (0); + } + return (ENXIO); +} + +static int +puc_sbus_attach(device_t dev) +{ + struct puc_device_description dd; + int i; + + bzero(&dd, sizeof(dd)); + dd.name = device_get_desc(dev); + for (i = 0; i < 2; i++) { + dd.ports[i].type = PUC_PORT_TYPE_UART | PUC_PORT_UART_Z8530; + dd.ports[i].bar = 0; + dd.ports[i].offset = 4 * i; + dd.ports[i].serialfreq = 0; + dd.ports[i].flags = PUC_FLAGS_MEMORY; + dd.ports[i].regshft = 1; + } + return (puc_attach(dev, &dd)); +} + +static device_method_t puc_sbus_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, puc_sbus_probe), + DEVMETHOD(device_attach, puc_sbus_attach), + + DEVMETHOD(bus_alloc_resource, puc_alloc_resource), + DEVMETHOD(bus_release_resource, puc_release_resource), + DEVMETHOD(bus_get_resource, puc_get_resource), + DEVMETHOD(bus_read_ivar, puc_read_ivar), + DEVMETHOD(bus_setup_intr, puc_setup_intr), + DEVMETHOD(bus_teardown_intr, puc_teardown_intr), + DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_driver_added, bus_generic_driver_added), + { 0, 0 } +}; + +static driver_t puc_sbus_driver = { + "puc", + puc_sbus_methods, + sizeof(struct puc_softc), +}; + +DRIVER_MODULE(puc, sbus, puc_sbus_driver, puc_devclass, 0, 0); diff --git a/sys/dev/puc/pucdata.c b/sys/dev/puc/pucdata.c index 3eea5e3..be8b848 100644 --- a/sys/dev/puc/pucdata.c +++ b/sys/dev/puc/pucdata.c @@ -47,8 +47,21 @@ __FBSDID("$FreeBSD$"); #define COM_FREQ DEFAULT_RCLK +int puc_config_win877(struct puc_softc *); + const struct puc_device_description puc_devices[] = { + { "Diva Serial [GSP] Multiport UART", + NULL, + { 0x103c, 0x1048, 0x103c, 0x1282 }, + { 0xffff, 0xffff, 0xffff, 0xffff }, + { + { PUC_PORT_TYPE_UART, 0x10, 0x00, 0, PUC_FLAGS_MEMORY }, + { PUC_PORT_TYPE_UART, 0x10, 0x10, 0, PUC_FLAGS_MEMORY }, + { PUC_PORT_TYPE_UART, 0x10, 0x38, 0, PUC_FLAGS_MEMORY }, + }, + }, + { "Comtrol RocketPort 550/4 RJ45", NULL, { 0x11fe, 0x8014, 0, 0 }, diff --git a/sys/dev/puc/pucvar.h b/sys/dev/puc/pucvar.h index 9bb3928..3415c89 100644 --- a/sys/dev/puc/pucvar.h +++ b/sys/dev/puc/pucvar.h @@ -79,6 +79,7 @@ struct puc_device_description { int offset; u_int serialfreq; u_int flags; + int regshft; } ports[PUC_MAX_PORTS]; uint32_t ilr_type; uint32_t ilr_offset[2]; @@ -92,20 +93,30 @@ struct puc_device_description { #define PUC_PORT_TYPE_NONE 0 #define PUC_PORT_TYPE_COM 1 #define PUC_PORT_TYPE_LPT 2 +#define PUC_PORT_TYPE_UART 3 + +/* UART subtypes. */ +#define PUC_PORT_SUBTYPE_MASK (~0xff) +#define PUC_PORT_UART_NS8250 (0<<8) +#define PUC_PORT_UART_SAB82532 (1<<8) +#define PUC_PORT_UART_Z8530 (2<<8) /* 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_FLAGS_ALTRES 0x0002 /* Use alternate I/O type. */ #define PUC_PORT_VALID(desc, port) \ - ((port) < PUC_MAX_PORTS && (desc)->ports[(port)].type != PUC_PORT_TYPE_NONE) + ((port) < PUC_MAX_PORTS && (desc).ports[(port)].type != PUC_PORT_TYPE_NONE) #define PUC_MAX_BAR 6 enum puc_device_ivars { - PUC_IVAR_FREQ + PUC_IVAR_FREQ, + PUC_IVAR_SUBTYPE, + PUC_IVAR_REGSHFT }; #ifdef PUC_ENTRAILS @@ -120,11 +131,9 @@ int puc_setup_intr(device_t, device_t, struct resource *, int, void (*)(void *), void *, void **); int puc_teardown_intr(device_t, device_t, struct resource *, void *); -const struct puc_device_description *puc_find_description(uint32_t, - uint32_t, uint32_t, uint32_t); struct puc_softc { - const struct puc_device_description *sc_desc; + struct puc_device_description sc_desc; /* card-global dynamic data */ int fastintr; @@ -153,6 +162,3 @@ struct puc_softc { }; #endif /* PUC_ENTRAILS */ - -int puc_config_win877(struct puc_softc *); -extern const struct puc_device_description puc_devices[]; -- cgit v1.1