Date: Sat, 15 Apr 2006 03:22:51 GMT From: Marcel Moolenaar <marcel@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 95306 for review Message-ID: <200604150322.k3F3Mpcv044521@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=95306 Change 95306 by marcel@marcel_nfs on 2006/04/15 03:22:49 Rewrite of puc(4): o Card configuration information is queried through puc_query(). This function calls the card specific query function when one has been defined. o Manage our bus space with rman. Not functional yet, but compiles again. Affected files ... .. //depot/projects/uart/conf/files#58 edit .. //depot/projects/uart/dev/puc/puc.c#21 edit .. //depot/projects/uart/dev/puc/puc_bus.h#2 edit .. //depot/projects/uart/dev/puc/puc_cfg.c#1 add .. //depot/projects/uart/dev/puc/puc_cfg.h#1 add .. //depot/projects/uart/dev/puc/puc_pci.c#11 edit .. //depot/projects/uart/dev/puc/pucdata.c#22 edit .. //depot/projects/uart/dev/puc/pucvar.h#18 edit Differences ... ==== //depot/projects/uart/conf/files#58 (text+ko) ==== @@ -806,6 +806,7 @@ dev/pst/pst-pci.c optional pst pci dev/pst/pst-raid.c optional pst dev/puc/puc.c optional puc +dev/puc/puc_cfg.c optional puc dev/puc/puc_pccard.c optional puc pccard dev/puc/puc_pci.c optional puc pci dev/puc/pucdata.c optional puc pci ==== //depot/projects/uart/dev/puc/puc.c#21 (text+ko) ==== @@ -1,49 +1,16 @@ -/* $NetBSD: puc.c,v 1.7 2000/07/29 17:43:38 jlam Exp $ */ - /*- - * Copyright (c) 2002 JF Hay. All rights reserved. - * Copyright (c) 2000 M. Warner Losh. All rights reserved. + * Copyright (c) 2006 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. - */ - -/*- - * Copyright (c) 1996, 1998, 1999 - * Christopher G. Demetriou. 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Christopher G. Demetriou - * for the NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -60,29 +27,6 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD: src/sys/dev/puc/puc.c,v 1.46 2006/02/22 17:19:10 jhb Exp $"); -/* - * PCI "universal" communication card device driver, glues com, lpt, - * and similar ports to PCI via bridge chip often much larger than - * the devices being glued. - * - * Author: Christopher G. Demetriou, May 14, 1998 (derived from NetBSD - * sys/dev/pci/pciide.c, revision 1.6). - * - * These devices could be (and some times are) described as - * communications/{serial,parallel}, etc. devices with known - * programming interfaces, but those programming interfaces (in - * particular the BAR assignments for devices, etc.) in fact are not - * particularly well defined. - * - * After I/we have seen more of these devices, it may be possible - * to generalize some of these bits. In particular, devices which - * describe themselves as communications/serial/16[45]50, and - * communications/parallel/??? might be attached via direct - * 'com' and 'lpt' attachments to pci. - */ - -#include "opt_puc.h" - #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> @@ -97,390 +41,234 @@ #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> -#define PUC_ENTRAILS 1 +#include <dev/puc/puc_bus.h> +#include <dev/puc/puc_cfg.h> #include <dev/puc/pucvar.h> -struct puc_device { - struct resource_list resources; - u_int serialfreq; -}; +devclass_t puc_devclass; +char puc_driver_name[] = "puc"; -static void puc_intr(void *arg); +MALLOC_DEFINE(M_PUC, "PUC", "PUC driver"); -static int puc_find_free_unit(char *); -#ifdef PUC_DEBUG -static void puc_print_resource_list(struct resource_list *); -#endif +static struct puc_bar * +puc_get_bar(struct puc_softc *sc, int rid) +{ + struct puc_bar *bar; + struct rman *rm; + u_long end, start; + int error, i; -devclass_t puc_devclass; + /* Find the BAR entry with the given RID. */ + i = 0; + while (i < PUC_PCI_BARS && sc->sc_bar[i].b_rid != rid) + i++; + if (i < PUC_PCI_BARS) + return (&sc->sc_bar[i]); -static int -puc_port_bar_index(struct puc_softc *sc, int bar) -{ - int i; + /* Not found. If we're looking for an unused entry, return NULL. */ + if (rid == -1) + return (NULL); - for (i = 0; i < PUC_MAX_BAR; i += 1) { - if (!sc->sc_bar_mappings[i].used) - break; - if (sc->sc_bar_mappings[i].bar == bar) - return (i); + /* Get an unused entry for us to fill. */ + bar = puc_get_bar(sc, -1); + if (bar == NULL) + return (NULL); + bar->b_rid = rid; + bar->b_type = SYS_RES_IOPORT; + bar->b_res = bus_alloc_resource_any(sc->sc_dev, bar->b_type, + &bar->b_rid, RF_ACTIVE); + if (bar->b_res == NULL) { + bar->b_rid = rid; + bar->b_type = SYS_RES_MEMORY; + bar->b_res = bus_alloc_resource_any(sc->sc_dev, bar->b_type, + &bar->b_rid, RF_ACTIVE); + if (bar->b_res == NULL) { + bar->b_rid = -1; + return (NULL); + } } - if (i == PUC_MAX_BAR) { - printf("%s: out of bars!\n", __func__); - return (-1); + + /* Update our managed space. */ + rm = (bar->b_type == SYS_RES_IOPORT) ? &sc->sc_ioport : &sc->sc_iomem; + start = rman_get_start(bar->b_res); + end = rman_get_end(bar->b_res); + error = rman_manage_region(rm, start, end); + if (error) { + bus_release_resource(sc->sc_dev, bar->b_type, bar->b_rid, + bar->b_res); + bar->b_res = NULL; + bar->b_rid = -1; + bar = NULL; } - sc->sc_bar_mappings[i].bar = bar; - sc->sc_bar_mappings[i].used = 1; - return (i); + + return (bar); } -static int -puc_probe_ilr(struct puc_softc *sc, struct resource *res) +static void +puc_intr(void *arg) { - 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 && 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]); - 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) +puc_attach(device_t dev) { - char *typestr; - int bidx, childunit, i, error, ressz, rid, type; + struct puc_bar *bar; struct puc_softc *sc; - struct puc_device *pdev; - struct resource *res; - struct resource_list_entry *rle; - bus_space_handle_t bh; + struct rman *rm; + intptr_t res; + u_long start; + int error, i, port; - if (desc == NULL) - return (ENXIO); + sc = device_get_softc(dev); - sc = (struct puc_softc *)device_get_softc(dev); - bzero(sc, sizeof(*sc)); - sc->sc_desc = *desc; + for (i = 0; i < PUC_PCI_BARS; i++) + sc->sc_bar[i].b_rid = -1; -#ifdef PUC_DEBUG - bootverbose = 1; + sc->sc_ioport.rm_type = RMAN_ARRAY; + sc->sc_ioport.rm_descr = "I/O port space"; + error = rman_init(&sc->sc_ioport); + if (error) + return (error); + sc->sc_iomem.rm_type = RMAN_ARRAY; + sc->sc_iomem.rm_descr = "Memory mapped I/O space"; + error = rman_init(&sc->sc_iomem); + if (error) { + rman_fini(&sc->sc_ioport); + return (error); + } - printf("puc: name: %s\n", sc->sc_desc.name); -#endif + error = puc_query(sc->sc_cfg, PUC_QUERY_NPORTS, 0, &res); + KASSERT(error == 0, ("%s %d", __func__, __LINE__)); + sc->sc_nports = (int)res; + sc->sc_port = malloc(sc->sc_nports * sizeof(struct puc_port), + M_PUC, M_WAITOK|M_ZERO); - rid = 0; - res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_ACTIVE | RF_SHAREABLE); - if (!res) - return (ENXIO); - - sc->irqres = res; - sc->irqrid = rid; - error = bus_setup_intr(dev, res, INTR_TYPE_TTY | INTR_FAST, - puc_intr, sc, &sc->intr_cookie); - if (error) { - error = bus_setup_intr(dev, res, INTR_TYPE_TTY | INTR_MPSAFE, - puc_intr, sc, &sc->intr_cookie); + for (port = 0; port < sc->sc_nports; port++) { + sc->sc_port[port].p_nr = port + 1; + error = puc_query(sc->sc_cfg, PUC_QUERY_TYPE, port, &res); + if (error) + goto fail; + sc->sc_port[port].p_type = res; + error = puc_query(sc->sc_cfg, PUC_QUERY_RID, port, &res); if (error) - return (error); - } else - sc->fastintr = INTR_FAST; - - rid = 0; - for (i = 0; PUC_PORT_VALID(sc->sc_desc, i); i++) { - if (i > 0 && rid == sc->sc_desc.ports[i].bar) - sc->barmuxed = 1; - rid = sc->sc_desc.ports[i].bar; - bidx = puc_port_bar_index(sc, rid); - - if (bidx < 0 || sc->sc_bar_mappings[bidx].res != NULL) - continue; - - type = SYS_RES_IOPORT; - res = bus_alloc_resource_any(dev, type, &rid, RF_ACTIVE); - if (res == NULL) { - type = SYS_RES_MEMORY; - res = bus_alloc_resource_any(dev, type, &rid, - RF_ACTIVE); + goto fail; + bar = puc_get_bar(sc, res); + if (bar == NULL) { + error = ENXIO; + goto fail; } - if (res == NULL) { - device_printf(dev, "could not get resource\n"); - continue; - } - sc->sc_bar_mappings[bidx].type = type; - sc->sc_bar_mappings[bidx].res = res; + sc->sc_port[port].p_bar = bar; + error = puc_query(sc->sc_cfg, PUC_QUERY_OFS, port, &res); + if (error) + goto fail; + start = rman_get_start(bar->b_res) + res; + error = puc_query(sc->sc_cfg, PUC_QUERY_LEN, port, &res); + if (error) + goto fail; - 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 %lx, start %lx, end %lx\n", - (type == SYS_RES_MEMORY) ? "memory" : "port", rid, - (u_long)rman_get_bustag(res), (u_long)rman_get_start(res), - (u_long)rman_get_end(res)); -#endif + rm = (bar->b_type == SYS_RES_IOPORT) + ? &sc->sc_ioport: &sc->sc_iomem; + sc->sc_port[port].p_res = rman_reserve_resource(rm, start, + start + res - 1, res, 0, sc->sc_dev); } - if (desc->init != NULL) { - i = desc->init(sc); - if (i != 0) - return (i); - } + sc->sc_irid = 0; + sc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_irid, + RF_ACTIVE|RF_SHAREABLE); + if (sc->sc_ires != NULL) { + error = bus_setup_intr(dev, sc->sc_ires, + INTR_TYPE_TTY | INTR_FAST, puc_intr, sc, &sc->sc_icookie); + if (error) + error = bus_setup_intr(dev, sc->sc_ires, + INTR_TYPE_TTY | INTR_MPSAFE, puc_intr, sc, + &sc->sc_icookie); + else + sc->sc_fastintr = 1; - for (i = 0; PUC_PORT_VALID(sc->sc_desc, i); i++) { - rid = sc->sc_desc.ports[i].bar; - bidx = puc_port_bar_index(sc, rid); - if (bidx < 0 || sc->sc_bar_mappings[bidx].res == NULL) - continue; - - switch (sc->sc_desc.ports[i].type) { - case PUC_PORT_TYPE_COM: - typestr = "uart"; - ressz = 8; - break; - case PUC_PORT_TYPE_LPT: - typestr = "ppc"; - ressz = 8; - break; - default: - continue; + 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; } - - pdev = malloc(sizeof(struct puc_device), M_DEVBUF, - M_NOWAIT | M_ZERO); - if (!pdev) - continue; - resource_list_init(&pdev->resources); - - /* First fake up an IRQ resource. */ - resource_list_add(&pdev->resources, SYS_RES_IRQ, 0, - rman_get_start(sc->irqres), rman_get_end(sc->irqres), - rman_get_end(sc->irqres) - rman_get_start(sc->irqres) + 1); - rle = resource_list_find(&pdev->resources, SYS_RES_IRQ, 0); - rle->res = sc->irqres; - - /* Now fake an IOPORT or MEMORY resource */ - 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 - + ressz - 1, ressz); - rle = resource_list_find(&pdev->resources, type, 0); - - if (sc->barmuxed == 0) { - rle->res = sc->sc_bar_mappings[bidx].res; - } else { - rle->res = rman_secret_puc_alloc_resource(M_WAITOK); - if (rle->res == NULL) { - free(pdev, M_DEVBUF); - return (ENOMEM); - } - - rman_set_start(rle->res, rman_get_start(res) + - sc->sc_desc.ports[i].offset); - rman_set_end(rle->res, rman_get_start(rle->res) + - ressz - 1); - rman_set_bustag(rle->res, rman_get_bustag(res)); - bus_space_subregion(rman_get_bustag(rle->res), - rman_get_bushandle(res), - sc->sc_desc.ports[i].offset, ressz, - &bh); - rman_set_bushandle(rle->res, bh); - } - - pdev->serialfreq = sc->sc_desc.serialfreq; - - 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), ressz); - rman_secret_puc_free_resource(rle->res); - 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); -#ifdef PUC_DEBUG - printf("puc: type %s(%d), bar %x, offset %x\n", typestr, - 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); - 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), ressz); - rman_secret_puc_free_resource(rle->res); - free(pdev, M_DEVBUF); - } - } + } + if (sc->sc_ires == NULL) { + /* XXX no interrupt resource. Force polled mode. */ + sc->sc_polled = 1; } -#ifdef PUC_DEBUG - bootverbose = 0; -#endif 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 && 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); - } - break; - - default: - mask = 0xffffffff; - break; +fail: + for (port = 0; port < sc->sc_nports; port++) { + if (sc->sc_port[port].p_res != NULL) + rman_release_resource(sc->sc_port[port].p_res); + } + for (i = 0; i < PUC_PCI_BARS; i++) { + if (sc->sc_bar[i].b_res != NULL) + bus_release_resource(sc->sc_dev, sc->sc_bar[i].b_type, + sc->sc_bar[i].b_rid, sc->sc_bar[i].b_res); } - return (mask); + rman_fini(&sc->sc_iomem); + rman_fini(&sc->sc_ioport); + free(sc->sc_port, M_PUC); + return (error); } -/* - * 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 +puc_probe(device_t dev, const struct puc_cfg *cfg) { - int i; - u_int32_t ilr_mask; struct puc_softc *sc; + intptr_t res; + int error; - 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 && - ((ilr_mask >> i) & 0x00000001)) - (sc->sc_ports[i].ihand)(sc->sc_ports[i].ihandarg); -} + sc = device_get_softc(dev); + sc->sc_dev = dev; + sc->sc_cfg = cfg; -static int -puc_find_free_unit(char *name) -{ - devclass_t dc; - int start; - int unit; + /* We don't attach to single-port serial cards. */ + if (cfg->ports == PUC_PORT_1S) + return (EDOOFUS); + error = puc_query(cfg, PUC_QUERY_NPORTS, 0, &res); + if (error) + return (error); - unit = 0; - start = 0; - while (resource_int_value(name, unit, "port", &start) == 0 && - start > 0) - unit++; - dc = devclass_find(name); - if (dc == NULL) - return (-1); - while (devclass_get_device(dc, unit)) - unit++; -#ifdef PUC_DEBUG - printf("puc: Using %s%d\n", name, unit); -#endif - return (unit); + if (cfg->name != NULL) + device_set_desc(dev, cfg->name); + return (BUS_PROBE_DEFAULT); } -#ifdef PUC_DEBUG -static void -puc_print_resource_list(struct resource_list *rl) -{ -#if 0 - struct resource_list_entry *rle; - - printf("print_resource_list: rl %p\n", rl); - SLIST_FOREACH(rle, rl, link) - 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 -} -#endif - struct resource * puc_alloc_resource(device_t dev, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { - struct puc_device *pdev; - struct resource *retval; - struct resource_list *rl; - struct resource_list_entry *rle; - device_t my_child; + struct puc_port *p; - /* - * in the case of a child of child we need to find our immediate child - */ - for (my_child = child; device_get_parent(my_child) != dev; - my_child = device_get_parent(my_child)); + while (child != NULL && device_get_parent(child) != dev) + child = device_get_parent(child); + if (child == NULL) + return (NULL); - pdev = device_get_ivars(my_child); - rl = &pdev->resources; + /* We only support default allocations. */ + if (*rid != 0 || start != 0UL || end != ~0UL) + return (NULL); -#ifdef PUC_DEBUG - printf("puc_alloc_resource: pdev %p, looking for t %x, r %x\n", - pdev, type, *rid); - puc_print_resource_list(rl); -#endif - retval = NULL; - rle = resource_list_find(rl, type, *rid); - if (rle) { -#ifdef PUC_DEBUG - printf("found rle, %lx, %lx, %lx\n", rle->start, rle->end, - rle->count); -#endif - retval = rle->res; - } -#ifdef PUC_DEBUG - else - printf("oops rle is gone\n"); -#endif - - return (retval); + p = device_get_ivars(child); + return (NULL); } int puc_release_resource(device_t dev, device_t child, int type, int rid, struct resource *res) { + struct puc_port *p; + + while (child != NULL && device_get_parent(child) != dev) + child = device_get_parent(child); + if (child == NULL) + return (EINVAL); + + p = device_get_ivars(child); return (0); } @@ -488,89 +276,65 @@ puc_get_resource(device_t dev, device_t child, int type, int rid, u_long *startp, u_long *countp) { - struct puc_device *pdev; - struct resource_list *rl; - struct resource_list_entry *rle; + struct puc_port *p; - pdev = device_get_ivars(child); - rl = &pdev->resources; + while (child != NULL && device_get_parent(child) != dev) + child = device_get_parent(child); + if (child == NULL) + return (EINVAL); -#ifdef PUC_DEBUG - printf("puc_get_resource: pdev %p, looking for t %x, r %x\n", pdev, - type, rid); - puc_print_resource_list(rl); -#endif - rle = resource_list_find(rl, type, rid); - if (rle) { -#ifdef PUC_DEBUG - printf("found rle %p,", rle); -#endif - if (startp != NULL) - *startp = rle->start; - if (countp != NULL) - *countp = rle->count; -#ifdef PUC_DEBUG - printf(" %lx, %lx\n", rle->start, rle->count); -#endif - return (0); - } else - printf("oops rle is gone\n"); + p = device_get_ivars(child); return (ENXIO); } int puc_setup_intr(device_t dev, device_t child, struct resource *r, int flags, - void (*ihand)(void *), void *arg, void **cookiep) + void (*ihand)(void *), void *arg, void **cookiep) { - int i; - struct puc_softc *sc; + struct puc_port *p; + + while (child != NULL && device_get_parent(child) != dev) + child = device_get_parent(child); + if (child == NULL) + return (EINVAL); - sc = (struct puc_softc *)device_get_softc(dev); - if ((flags & INTR_FAST) != sc->fastintr) - return (ENXIO); - for (i = 0; PUC_PORT_VALID(sc->sc_desc, i); i++) { - if (sc->sc_ports[i].dev == child) { - if (sc->sc_ports[i].ihand != 0) - return (ENXIO); - sc->sc_ports[i].ihand = ihand; - sc->sc_ports[i].ihandarg = arg; - *cookiep = arg; - return (0); - } - } + p = device_get_ivars(child); return (ENXIO); } int puc_teardown_intr(device_t dev, device_t child, struct resource *r, - void *cookie) + void *cookie) { - int i; - struct puc_softc *sc; + struct puc_port *p; + + while (child != NULL && device_get_parent(child) != dev) + child = device_get_parent(child); + if (child == NULL) + return (EINVAL); - sc = (struct puc_softc *)device_get_softc(dev); - for (i = 0; PUC_PORT_VALID(sc->sc_desc, i); i++) { - if (sc->sc_ports[i].dev == child) { - sc->sc_ports[i].ihand = NULL; - sc->sc_ports[i].ihandarg = NULL; - return (0); - } - } + p = device_get_ivars(child); return (ENXIO); } int puc_read_ivar(device_t dev, device_t child, int index, uintptr_t *result) { - struct puc_device *pdev; + struct puc_port *p; + + while (child != NULL && device_get_parent(child) != dev) + child = device_get_parent(child); + if (child == NULL) + return (EINVAL); - pdev = device_get_ivars(child); - if (pdev == NULL) - return (ENOENT); + p = device_get_ivars(child); switch(index) { - case PUC_IVAR_FREQ: - *result = pdev->serialfreq; + case PUC_IVAR_CLOCK: + *result = p->p_rclk; + break; + case PUC_IVAR_TYPE: + *result = p->p_type; break; default: return (ENOENT); ==== //depot/projects/uart/dev/puc/puc_bus.h#2 (text+ko) ==== @@ -36,7 +36,7 @@ #define PUC_IVAR_TYPE 1 /* Port types. */ -#define PUC_TYPE_SERIAL 0 -#define PUC_TYPE_PARALLEL 1 +#define PUC_TYPE_SERIAL 1 +#define PUC_TYPE_PARALLEL 2 #endif /* _DEV_PUC_BUS_H_ */ ==== //depot/projects/uart/dev/puc/puc_pci.c#11 (text+ko) ==== @@ -60,8 +60,6 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD: src/sys/dev/puc/puc_pci.c,v 1.14 2005/03/05 18:10:49 imp Exp $"); -#include "opt_puc.h" - #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> @@ -77,15 +75,13 @@ #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> -#define PUC_ENTRAILS 1 +#include <dev/puc/puc_cfg.h> #include <dev/puc/pucvar.h> -extern const struct puc_device_description puc_devices[]; +extern const struct puc_cfg puc_devices[]; -int puc_config_win877(struct puc_softc *); - -static const struct puc_device_description * -puc_pci_match(device_t dev, const struct puc_device_description *desc) +static const struct puc_cfg * +puc_pci_match(device_t dev, const struct puc_cfg *desc) { uint16_t device, subdev, subven, vendor; @@ -110,7 +106,7 @@ static int puc_pci_probe(device_t dev) { - const struct puc_device_description *desc; + const struct puc_cfg *desc; if ((pci_read_config(dev, PCIR_HDRTYPE, 1) & PCIM_HDRTYPE) != 0) return (ENXIO); @@ -118,21 +114,13 @@ desc = puc_pci_match(dev, puc_devices); if (desc == NULL) return (ENXIO); - device_set_desc(dev, desc->name); - return (BUS_PROBE_DEFAULT); + return (puc_probe(dev, desc)); } -static int -puc_pci_attach(device_t dev) -{ - - return (puc_attach(dev, puc_pci_match(dev, puc_devices))); -} - static device_method_t puc_pci_methods[] = { /* Device interface */ DEVMETHOD(device_probe, puc_pci_probe), - DEVMETHOD(device_attach, puc_pci_attach), + DEVMETHOD(device_attach, puc_attach), DEVMETHOD(bus_alloc_resource, puc_alloc_resource), DEVMETHOD(bus_release_resource, puc_release_resource), @@ -146,136 +134,10 @@ }; static driver_t puc_pci_driver = { - "puc", + puc_driver_name, puc_pci_methods, sizeof(struct puc_softc), }; DRIVER_MODULE(puc, pci, puc_pci_driver, puc_devclass, 0, 0); DRIVER_MODULE(puc, cardbus, puc_pci_driver, puc_devclass, 0, 0); - - -#define rdspio(indx) (bus_space_write_1(bst, bsh, efir, indx), \ - bus_space_read_1(bst, bsh, efdr)) -#define wrspio(indx,data) (bus_space_write_1(bst, bsh, efir, indx), \ - bus_space_write_1(bst, bsh, efdr, data)) - -#ifdef PUC_DEBUG -static void -puc_print_win877(bus_space_tag_t bst, bus_space_handle_t bsh, u_int efir, - u_int efdr) -{ - u_char cr00, cr01, cr04, cr09, cr0d, cr14, cr15, cr16, cr17; - u_char cr18, cr19, cr24, cr25, cr28, cr2c, cr31, cr32; - - cr00 = rdspio(0x00); - cr01 = rdspio(0x01); - cr04 = rdspio(0x04); - cr09 = rdspio(0x09); - cr0d = rdspio(0x0d); - cr14 = rdspio(0x14); - cr15 = rdspio(0x15); - cr16 = rdspio(0x16); - cr17 = rdspio(0x17); - cr18 = rdspio(0x18); - cr19 = rdspio(0x19); - cr24 = rdspio(0x24); - cr25 = rdspio(0x25); - cr28 = rdspio(0x28); - cr2c = rdspio(0x2c); - cr31 = rdspio(0x31); - cr32 = rdspio(0x32); - printf("877T: cr00 %x, cr01 %x, cr04 %x, cr09 %x, cr0d %x, cr14 %x, " - "cr15 %x, cr16 %x, cr17 %x, cr18 %x, cr19 %x, cr24 %x, cr25 %x, " - "cr28 %x, cr2c %x, cr31 %x, cr32 %x\n", cr00, cr01, cr04, cr09, - cr0d, cr14, cr15, cr16, cr17, - cr18, cr19, cr24, cr25, cr28, cr2c, cr31, cr32); -} -#endif - -int -puc_config_win877(struct puc_softc *sc) -{ - u_char val; - u_int efir, efdr; - bus_space_tag_t bst; - bus_space_handle_t bsh; - struct resource *res; - - res = sc->sc_bar_mappings[0].res; - - bst = rman_get_bustag(res); - bsh = rman_get_bushandle(res); - - /* configure the first W83877TF */ - bus_space_write_1(bst, bsh, 0x250, 0x89); - efir = 0x251; - efdr = 0x252; - val = rdspio(0x09) & 0x0f; - if (val != 0x0c) { - printf("conf_win877: Oops not a W83877TF\n"); - return (ENXIO); - } - -#ifdef PUC_DEBUG - printf("before: "); - puc_print_win877(bst, bsh, efir, efdr); -#endif - - val = rdspio(0x16); - val |= 0x04; - wrspio(0x16, val); - val &= ~0x04; - wrspio(0x16, val); - - wrspio(0x24, 0x2e8 >> 2); - wrspio(0x25, 0x2f8 >> 2); - wrspio(0x17, 0x03); - wrspio(0x28, 0x43); - -#ifdef PUC_DEBUG - printf("after: "); - puc_print_win877(bst, bsh, efir, efdr); -#endif - - bus_space_write_1(bst, bsh, 0x250, 0xaa); - - /* configure the second W83877TF */ - bus_space_write_1(bst, bsh, 0x3f0, 0x87); - bus_space_write_1(bst, bsh, 0x3f0, 0x87); - efir = 0x3f0; - efdr = 0x3f1; - val = rdspio(0x09) & 0x0f; - if (val != 0x0c) { - printf("conf_win877: Oops not a W83877TF\n"); - return(ENXIO); - } - -#ifdef PUC_DEBUG - printf("before: "); - puc_print_win877(bst, bsh, efir, efdr); -#endif - - val = rdspio(0x16); - val |= 0x04; >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200604150322.k3F3Mpcv044521>