Index: head/sys/dev/aha/aha_isa.c =================================================================== --- head/sys/dev/aha/aha_isa.c (revision 327101) +++ head/sys/dev/aha/aha_isa.c (revision 327102) @@ -1,364 +1,365 @@ /* * Product specific probe and attach routines for: * Adaptec 154x. */ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 1999-2003 M. Warner Losh * 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, * without modification, immediately at the beginning of the file. * 2. 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 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. * * Derived from bt isa from end, written by: * * Copyright (c) 1998 Justin T. Gibbs * 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, * without modification, immediately at the beginning of the file. * 2. 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 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include static struct isa_pnp_id aha_ids[] = { {ADP0100_PNP, "Adaptec 1540/1542 ISA SCSI"}, /* ADP0100 */ {AHA1540_PNP, "Adaptec 1540/aha-1640/aha-1535"},/* ADP1540 */ {AHA1542_PNP, "Adaptec 1542/aha-1535"}, /* ADP1542 */ {AHA1542_PNPCOMPAT, "Adaptec 1542 compatible"}, /* PNP00A0 */ {ICU0091_PNP, "Adaptec AHA-1540/1542 SCSI"}, /* ICU0091 */ {0} }; /* * I/O ports listed in the order enumerated by the card for certain op codes. */ static bus_addr_t aha_board_ports[] = { 0x330, 0x334, 0x230, 0x234, 0x130, 0x134 }; /* * Check if the device can be found at the port given */ static int aha_isa_probe(device_t dev) { /* * find unit and check we have that many defined */ struct aha_softc *aha = device_get_softc(dev); int error; u_long port_start; int port_rid; int drq; int irq; config_data_t config_data; aha->dev = dev; /* Check isapnp ids */ if (ISA_PNP_PROBE(device_get_parent(dev), dev, aha_ids) == ENXIO) return (ENXIO); port_rid = 0; aha->port = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &port_rid, AHA_NREGS, RF_ACTIVE); if (aha->port == NULL) return (ENXIO); port_start = rman_get_start(aha->port); aha_alloc(aha); /* See if there is really a card present */ if (aha_probe(aha) || aha_fetch_adapter_info(aha)) { aha_free(aha); bus_release_resource(dev, SYS_RES_IOPORT, port_rid, aha->port); return (ENXIO); } /* * Determine our IRQ, and DMA settings and * export them to the configuration system. */ error = aha_cmd(aha, AOP_INQUIRE_CONFIG, NULL, /*parmlen*/0, (uint8_t*)&config_data, sizeof(config_data), DEFAULT_CMD_TIMEOUT); if (error != 0) { device_printf(dev, "Could not determine IRQ or DMA " "settings for adapter at %#jx. Failing probe\n", (uintmax_t)port_start); aha_free(aha); bus_release_resource(dev, SYS_RES_IOPORT, port_rid, aha->port); return (ENXIO); } bus_release_resource(dev, SYS_RES_IOPORT, port_rid, aha->port); aha->port = NULL; switch (config_data.dma_chan) { case DMA_CHAN_5: drq = 5; break; case DMA_CHAN_6: drq = 6; break; case DMA_CHAN_7: drq = 7; break; default: device_printf(dev, "Invalid DMA setting for adapter at %#jx.", (uintmax_t)port_start); return (ENXIO); } error = bus_set_resource(dev, SYS_RES_DRQ, 0, drq, 1); if (error) return error; irq = ffs(config_data.irq) + 8; error = bus_set_resource(dev, SYS_RES_IRQ, 0, irq, 1); return (error); } /* * Attach all the sub-devices we can find */ static int aha_isa_attach(device_t dev) { struct aha_softc *aha = device_get_softc(dev); int error = ENOMEM; aha->dev = dev; aha->portrid = 0; aha->port = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &aha->portrid, AHA_NREGS, RF_ACTIVE); if (!aha->port) { device_printf(dev, "Unable to allocate I/O ports\n"); goto fail; } aha->irqrid = 0; aha->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &aha->irqrid, RF_ACTIVE); if (!aha->irq) { device_printf(dev, "Unable to allocate excluse use of irq\n"); goto fail; } aha->drqrid = 0; aha->drq = bus_alloc_resource_any(dev, SYS_RES_DRQ, &aha->drqrid, RF_ACTIVE); if (!aha->drq) { device_printf(dev, "Unable to allocate drq\n"); goto fail; } #if 0 /* is the drq ever unset? */ if (dev->id_drq != -1) isa_dmacascade(dev->id_drq); #endif isa_dmacascade(rman_get_start(aha->drq)); /* Allocate our parent dmatag */ if (bus_dma_tag_create( /* parent */ bus_get_dma_tag(dev), /* alignemnt */ 1, /* boundary */ 0, /* lowaddr */ BUS_SPACE_MAXADDR_24BIT, /* highaddr */ BUS_SPACE_MAXADDR, /* filter */ NULL, /* filterarg */ NULL, /* maxsize */ BUS_SPACE_MAXSIZE_24BIT, /* nsegments */ ~0, /* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT, /* flags */ 0, /* lockfunc */ NULL, /* lockarg */ NULL, &aha->parent_dmat) != 0) { device_printf(dev, "dma tag create failed.\n"); goto fail; } if (aha_init(aha)) { device_printf(dev, "init failed\n"); goto fail; } /* * The 1542A and B look the same. So we guess based on * the firmware revision. It appears that only rev 0 is on * the A cards. */ if (aha->boardid <= BOARD_1542 && aha->fw_major == 0) { device_printf(dev, "154xA may not work\n"); aha->ccb_sg_opcode = INITIATOR_SG_CCB; aha->ccb_ccb_opcode = INITIATOR_CCB; } error = aha_attach(aha); if (error) { device_printf(dev, "attach failed\n"); goto fail; } error = bus_setup_intr(dev, aha->irq, INTR_TYPE_CAM|INTR_ENTROPY| INTR_MPSAFE, NULL, aha_intr, aha, &aha->ih); if (error) { device_printf(dev, "Unable to register interrupt handler\n"); aha_detach(aha); goto fail; } return (0); fail: ; aha_free(aha); bus_free_resource(dev, SYS_RES_IOPORT, aha->port); bus_free_resource(dev, SYS_RES_IRQ, aha->irq); bus_free_resource(dev, SYS_RES_DRQ, aha->drq); return (error); } static int aha_isa_detach(device_t dev) { struct aha_softc *aha = (struct aha_softc *)device_get_softc(dev); int error; error = bus_teardown_intr(dev, aha->irq, aha->ih); if (error) device_printf(dev, "failed to unregister interrupt handler\n"); error = aha_detach(aha); if (error) { device_printf(dev, "detach failed\n"); return (error); } aha_free(aha); bus_free_resource(dev, SYS_RES_IOPORT, aha->port); bus_free_resource(dev, SYS_RES_IRQ, aha->irq); bus_free_resource(dev, SYS_RES_DRQ, aha->drq); return (0); } static void aha_isa_identify(driver_t *driver, device_t parent) { int i; bus_addr_t ioport; struct aha_softc aha; int rid; device_t child; /* Attempt to find an adapter */ for (i = 0; i < nitems(aha_board_ports); i++) { bzero(&aha, sizeof(aha)); ioport = aha_board_ports[i]; /* * XXX Check to see if we have a hard-wired aha device at * XXX this port, if so, skip. This should also cover the * XXX case where we are run multiple times due to, eg, * XXX kldload/kldunload. */ rid = 0; aha.port = bus_alloc_resource(parent, SYS_RES_IOPORT, &rid, ioport, ioport, AHA_NREGS, RF_ACTIVE); if (aha.port == NULL) continue; aha_alloc(&aha); /* See if there is really a card present */ if (aha_probe(&aha) || aha_fetch_adapter_info(&aha)) goto not_this_one; child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "aha", -1); bus_set_resource(child, SYS_RES_IOPORT, 0, ioport, AHA_NREGS); /* * Could query the board and set IRQ/DRQ, but probe does * that. */ not_this_one: bus_release_resource(parent, SYS_RES_IOPORT, rid, aha.port); aha_free(&aha); } } static device_method_t aha_isa_methods[] = { /* Device interface */ DEVMETHOD(device_probe, aha_isa_probe), DEVMETHOD(device_attach, aha_isa_attach), DEVMETHOD(device_detach, aha_isa_detach), DEVMETHOD(device_identify, aha_isa_identify), { 0, 0 } }; static driver_t aha_isa_driver = { "aha", aha_isa_methods, sizeof(struct aha_softc), }; static devclass_t aha_devclass; DRIVER_MODULE(aha, isa, aha_isa_driver, aha_devclass, 0, 0); MODULE_DEPEND(aha, isa, 1, 1, 1); +ISA_PNP_INFO(aha_ids); Index: head/sys/dev/aic/aic_isa.c =================================================================== --- head/sys/dev/aic/aic_isa.c (revision 327101) +++ head/sys/dev/aic/aic_isa.c (revision 327102) @@ -1,244 +1,245 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 1999 Luoqi Chen. * 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include struct aic_isa_softc { struct aic_softc sc_aic; struct resource *sc_port; struct resource *sc_irq; struct resource *sc_drq; void *sc_ih; }; static int aic_isa_alloc_resources(device_t); static void aic_isa_release_resources(device_t); static int aic_isa_probe(device_t); static int aic_isa_attach(device_t); static u_int aic_isa_ports[] = { 0x340, 0x140 }; #define AIC_ISA_NUMPORTS nitems(aic_isa_ports) #define AIC_ISA_PORTSIZE 0x20 static struct isa_pnp_id aic_ids[] = { { 0x15309004, "Adaptec AHA-1530P" }, { 0x15209004, "Adaptec AHA-1520P" }, { 0 } }; static int aic_isa_alloc_resources(device_t dev) { struct aic_isa_softc *sc = device_get_softc(dev); int rid; sc->sc_port = sc->sc_irq = sc->sc_drq = NULL; rid = 0; sc->sc_port = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &rid, AIC_ISA_PORTSIZE, RF_ACTIVE); if (!sc->sc_port) { device_printf(dev, "I/O port allocation failed\n"); return (ENOMEM); } if (isa_get_irq(dev) != -1) { rid = 0; sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); if (!sc->sc_irq) { device_printf(dev, "IRQ allocation failed\n"); aic_isa_release_resources(dev); return (ENOMEM); } } if (isa_get_drq(dev) != -1) { rid = 0; sc->sc_drq = bus_alloc_resource_any(dev, SYS_RES_DRQ, &rid, RF_ACTIVE); if (!sc->sc_drq) { device_printf(dev, "DRQ allocation failed\n"); aic_isa_release_resources(dev); return (ENOMEM); } } sc->sc_aic.dev = dev; sc->sc_aic.res = sc->sc_port; mtx_init(&sc->sc_aic.lock, "aic", NULL, MTX_DEF); return (0); } static void aic_isa_release_resources(device_t dev) { struct aic_isa_softc *sc = device_get_softc(dev); if (sc->sc_port) bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->sc_port); if (sc->sc_irq) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq); if (sc->sc_drq) bus_release_resource(dev, SYS_RES_DRQ, 0, sc->sc_drq); sc->sc_port = sc->sc_irq = sc->sc_drq = NULL; mtx_destroy(&sc->sc_aic.lock); } static int aic_isa_probe(device_t dev) { struct aic_isa_softc *sc = device_get_softc(dev); struct aic_softc *aic = &sc->sc_aic; int numports, i; u_int port, *ports; u_int8_t porta; if (ISA_PNP_PROBE(device_get_parent(dev), dev, aic_ids) == ENXIO) return (ENXIO); port = isa_get_port(dev); if (port != -1) { ports = &port; numports = 1; } else { ports = aic_isa_ports; numports = AIC_ISA_NUMPORTS; } for (i = 0; i < numports; i++) { if (bus_set_resource(dev, SYS_RES_IOPORT, 0, ports[i], AIC_ISA_PORTSIZE)) continue; if (aic_isa_alloc_resources(dev)) continue; if (aic_probe(aic) == 0) break; aic_isa_release_resources(dev); } if (i == numports) return (ENXIO); porta = aic_inb(aic, PORTA); aic_isa_release_resources(dev); if (isa_get_irq(dev) == -1) bus_set_resource(dev, SYS_RES_IRQ, 0, PORTA_IRQ(porta), 1); if ((aic->flags & AIC_DMA_ENABLE) && isa_get_drq(dev) == -1) bus_set_resource(dev, SYS_RES_DRQ, 0, PORTA_DRQ(porta), 1); device_set_desc(dev, "Adaptec 6260/6360 SCSI controller"); return (0); } static int aic_isa_attach(device_t dev) { struct aic_isa_softc *sc = device_get_softc(dev); struct aic_softc *aic = &sc->sc_aic; int error; error = aic_isa_alloc_resources(dev); if (error) { device_printf(dev, "resource allocation failed\n"); return (error); } error = aic_attach(aic); if (error) { device_printf(dev, "attach failed\n"); aic_isa_release_resources(dev); return (error); } error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_CAM | INTR_ENTROPY | INTR_MPSAFE, NULL, aic_intr, aic, &sc->sc_ih); if (error) { device_printf(dev, "failed to register interrupt handler\n"); aic_isa_release_resources(dev); return (error); } return (0); } static int aic_isa_detach(device_t dev) { struct aic_isa_softc *sc = device_get_softc(dev); struct aic_softc *aic = &sc->sc_aic; int error; error = aic_detach(aic); if (error) { device_printf(dev, "detach failed\n"); return (error); } error = bus_teardown_intr(dev, sc->sc_irq, sc->sc_ih); if (error) { device_printf(dev, "failed to unregister interrupt handler\n"); } aic_isa_release_resources(dev); return (0); } static device_method_t aic_isa_methods[] = { /* Device interface */ DEVMETHOD(device_probe, aic_isa_probe), DEVMETHOD(device_attach, aic_isa_attach), DEVMETHOD(device_detach, aic_isa_detach), { 0, 0 } }; static driver_t aic_isa_driver = { "aic", aic_isa_methods, sizeof(struct aic_isa_softc), }; extern devclass_t aic_devclass; MODULE_DEPEND(aic, cam, 1,1,1); DRIVER_MODULE(aic, isa, aic_isa_driver, aic_devclass, 0, 0); +ISA_PNP_INFO(aic_ids); Index: head/sys/dev/an/if_an_isa.c =================================================================== --- head/sys/dev/an/if_an_isa.c (revision 327101) +++ head/sys/dev/an/if_an_isa.c (revision 327102) @@ -1,152 +1,153 @@ /*- * SPDX-License-Identifier: BSD-4-Clause * * Copyright (c) 1997, 1998, 1999 * Bill Paul . 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 Bill Paul. * 4. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul OR THE VOICES IN HIS HEAD * 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. */ /* * Aironet 4500/4800 802.11 PCMCIA/ISA/PCI driver for FreeBSD. * * Written by Bill Paul * Electrical Engineering Department * Columbia University, New York City */ #include __FBSDID("$FreeBSD$"); #include "opt_inet.h" #ifdef INET #define ANCACHE #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static struct isa_pnp_id an_ids[] = { { 0x0100ec06, "Aironet ISA4500/ISA4800" }, { 0, NULL } }; static int an_probe_isa(device_t); static int an_attach_isa(device_t); static int an_probe_isa(device_t dev) { int error = 0; error = ISA_PNP_PROBE(device_get_parent(dev), dev, an_ids); if (error == ENXIO) return(error); error = an_probe(dev); an_release_resources(dev); if (error == 0) return (ENXIO); error = an_alloc_irq(dev, 0, 0); an_release_resources(dev); if (!error) device_set_desc(dev, "Aironet ISA4500/ISA4800"); return (error); } static int an_attach_isa(device_t dev) { struct an_softc *sc = device_get_softc(dev); int flags = device_get_flags(dev); int error; an_alloc_port(dev, sc->port_rid, 1); an_alloc_irq(dev, sc->irq_rid, 0); sc->an_dev = dev; error = an_attach(sc, flags); if (error) { an_release_resources(dev); return (error); } error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET, NULL, an_intr, sc, &sc->irq_handle); if (error) { an_release_resources(dev); return (error); } return (0); } static device_method_t an_isa_methods[] = { /* Device interface */ DEVMETHOD(device_probe, an_probe_isa), DEVMETHOD(device_attach, an_attach_isa), DEVMETHOD(device_detach, an_detach), DEVMETHOD(device_shutdown, an_shutdown), { 0, 0 } }; static driver_t an_isa_driver = { "an", an_isa_methods, sizeof(struct an_softc) }; static devclass_t an_isa_devclass; DRIVER_MODULE(an, isa, an_isa_driver, an_isa_devclass, 0, 0); MODULE_DEPEND(an, isa, 1, 1, 1); MODULE_DEPEND(an, wlan, 1, 1, 1); +ISA_PNP_INFO(an_ids); Index: head/sys/dev/atkbdc/atkbdc_isa.c =================================================================== --- head/sys/dev/atkbdc/atkbdc_isa.c (revision 327101) +++ head/sys/dev/atkbdc/atkbdc_isa.c (revision 327102) @@ -1,324 +1,325 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 1999 Kazutaka YOKOTA * 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 as * the first lines of this file unmodified. * 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 AUTHORS ``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 AUTHORS 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_kbd.h" #include #include #include #include #include #include #include #include #include #include #include #include #include static int atkbdc_isa_probe(device_t dev); static int atkbdc_isa_attach(device_t dev); static device_t atkbdc_isa_add_child(device_t bus, u_int order, const char *name, int unit); static struct resource *atkbdc_isa_alloc_resource(device_t dev, device_t child, int type, int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags); static int atkbdc_isa_release_resource(device_t dev, device_t child, int type, int rid, struct resource *r); static device_method_t atkbdc_isa_methods[] = { DEVMETHOD(device_probe, atkbdc_isa_probe), DEVMETHOD(device_attach, atkbdc_isa_attach), DEVMETHOD(device_suspend, bus_generic_suspend), DEVMETHOD(device_resume, bus_generic_resume), DEVMETHOD(bus_add_child, atkbdc_isa_add_child), DEVMETHOD(bus_print_child, atkbdc_print_child), DEVMETHOD(bus_read_ivar, atkbdc_read_ivar), DEVMETHOD(bus_write_ivar, atkbdc_write_ivar), DEVMETHOD(bus_get_resource_list,atkbdc_get_resource_list), DEVMETHOD(bus_alloc_resource, atkbdc_isa_alloc_resource), DEVMETHOD(bus_release_resource, atkbdc_isa_release_resource), DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource), DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), { 0, 0 } }; static driver_t atkbdc_isa_driver = { ATKBDC_DRIVER_NAME, atkbdc_isa_methods, sizeof(atkbdc_softc_t *), }; static struct isa_pnp_id atkbdc_ids[] = { { 0x0303d041, "Keyboard controller (i8042)" }, /* PNP0303 */ { 0x0b03d041, "Keyboard controller (i8042)" }, /* PNP030B */ { 0x2003d041, "Keyboard controller (i8042)" }, /* PNP0320 */ { 0 } }; static int atkbdc_isa_probe(device_t dev) { struct resource *port0; struct resource *port1; rman_res_t start; rman_res_t count; int error; int rid; #if defined(__i386__) || defined(__amd64__) bus_space_tag_t tag; bus_space_handle_t ioh1; volatile int i; register_t flags; #endif /* check PnP IDs */ if (ISA_PNP_PROBE(device_get_parent(dev), dev, atkbdc_ids) == ENXIO) return ENXIO; device_set_desc(dev, "Keyboard controller (i8042)"); /* * Adjust I/O port resources. * The AT keyboard controller uses two ports (a command/data port * 0x60 and a status port 0x64), which may be given to us in * one resource (0x60 through 0x64) or as two separate resources * (0x60 and 0x64). Some brain-damaged ACPI BIOS has reversed * command/data port and status port. Furthermore, /boot/device.hints * may contain just one port, 0x60. We shall adjust resource settings * so that these two ports are available as two separate resources * in correct order. */ device_quiet(dev); rid = 0; if (bus_get_resource(dev, SYS_RES_IOPORT, rid, &start, &count) != 0) return ENXIO; if (start == IO_KBD + KBD_STATUS_PORT) { start = IO_KBD; count++; } if (count > 1) /* adjust the count and/or start port */ bus_set_resource(dev, SYS_RES_IOPORT, rid, start, 1); port0 = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); if (port0 == NULL) return ENXIO; rid = 1; if (bus_get_resource(dev, SYS_RES_IOPORT, rid, NULL, NULL) != 0) bus_set_resource(dev, SYS_RES_IOPORT, 1, start + KBD_STATUS_PORT, 1); port1 = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); if (port1 == NULL) { bus_release_resource(dev, SYS_RES_IOPORT, 0, port0); return ENXIO; } #if defined(__i386__) || defined(__amd64__) /* * Check if we really have AT keyboard controller. Poll status * register until we get "all clear" indication. If no such * indication comes, it probably means that there is no AT * keyboard controller present. Give up in such case. Check relies * on the fact that reading from non-existing in/out port returns * 0xff on i386. May or may not be true on other platforms. */ tag = rman_get_bustag(port0); ioh1 = rman_get_bushandle(port1); flags = intr_disable(); for (i = 0; i != 65535; i++) { if ((bus_space_read_1(tag, ioh1, 0) & 0x2) == 0) break; } intr_restore(flags); if (i == 65535) { bus_release_resource(dev, SYS_RES_IOPORT, 0, port0); bus_release_resource(dev, SYS_RES_IOPORT, 1, port1); if (bootverbose) device_printf(dev, "AT keyboard controller not found\n"); return ENXIO; } #endif device_verbose(dev); error = atkbdc_probe_unit(device_get_unit(dev), port0, port1); bus_release_resource(dev, SYS_RES_IOPORT, 0, port0); bus_release_resource(dev, SYS_RES_IOPORT, 1, port1); return error; } static int atkbdc_isa_attach(device_t dev) { atkbdc_softc_t *sc; int unit; int error; int rid; unit = device_get_unit(dev); sc = *(atkbdc_softc_t **)device_get_softc(dev); if (sc == NULL) { /* * We have to maintain two copies of the kbdc_softc struct, * as the low-level console needs to have access to the * keyboard controller before kbdc is probed and attached. * kbdc_soft[] contains the default entry for that purpose. * See atkbdc.c. XXX */ sc = atkbdc_get_softc(unit); if (sc == NULL) return ENOMEM; } rid = 0; sc->retry = 5000; sc->port0 = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); if (sc->port0 == NULL) return ENXIO; rid = 1; sc->port1 = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); if (sc->port1 == NULL) { bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port0); return ENXIO; } /* * If the device is not created by the PnP BIOS or ACPI, then * the hint for the IRQ is on the child atkbd device, not the * keyboard controller, so this can fail. */ rid = 0; sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); error = atkbdc_attach_unit(unit, sc, sc->port0, sc->port1); if (error) { bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port0); bus_release_resource(dev, SYS_RES_IOPORT, 1, sc->port1); if (sc->irq != NULL) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq); return error; } *(atkbdc_softc_t **)device_get_softc(dev) = sc; bus_generic_probe(dev); bus_generic_attach(dev); return 0; } static device_t atkbdc_isa_add_child(device_t bus, u_int order, const char *name, int unit) { atkbdc_device_t *ivar; atkbdc_softc_t *sc; device_t child; int t; sc = *(atkbdc_softc_t **)device_get_softc(bus); ivar = malloc(sizeof(struct atkbdc_device), M_ATKBDDEV, M_NOWAIT | M_ZERO); if (!ivar) return NULL; child = device_add_child_ordered(bus, order, name, unit); if (child == NULL) { free(ivar, M_ATKBDDEV); return child; } resource_list_init(&ivar->resources); ivar->rid = order; /* * If the device is not created by the PnP BIOS or ACPI, refer * to device hints for IRQ. We always populate the resource * list entry so we can use a standard bus_get_resource() * method. */ if (order == KBDC_RID_KBD) { if (sc->irq == NULL) { if (resource_int_value(name, unit, "irq", &t) != 0) t = -1; } else t = rman_get_start(sc->irq); if (t > 0) resource_list_add(&ivar->resources, SYS_RES_IRQ, ivar->rid, t, t, 1); } if (resource_disabled(name, unit)) device_disable(child); device_set_ivars(child, ivar); return child; } struct resource * atkbdc_isa_alloc_resource(device_t dev, device_t child, int type, int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) { atkbdc_softc_t *sc; sc = *(atkbdc_softc_t **)device_get_softc(dev); if (type == SYS_RES_IRQ && *rid == KBDC_RID_KBD && sc->irq != NULL) return (sc->irq); return (bus_generic_rl_alloc_resource(dev, child, type, rid, start, end, count, flags)); } static int atkbdc_isa_release_resource(device_t dev, device_t child, int type, int rid, struct resource *r) { atkbdc_softc_t *sc; sc = *(atkbdc_softc_t **)device_get_softc(dev); if (type == SYS_RES_IRQ && rid == KBDC_RID_KBD && r == sc->irq) return (0); return (bus_generic_rl_release_resource(dev, child, type, rid, r)); } DRIVER_MODULE(atkbdc, isa, atkbdc_isa_driver, atkbdc_devclass, 0, 0); DRIVER_MODULE(atkbdc, acpi, atkbdc_isa_driver, atkbdc_devclass, 0, 0); +ISA_PNP_INFO(atkbdc_ids); Index: head/sys/dev/cs/if_cs_isa.c =================================================================== --- head/sys/dev/cs/if_cs_isa.c (revision 327101) +++ head/sys/dev/cs/if_cs_isa.c (revision 327102) @@ -1,122 +1,123 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 1997,1998 Maxim Bolotin and Oleg Sharoiko. * 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 unmodified, 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. * */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int cs_isa_probe(device_t); static int cs_isa_attach(device_t); static struct isa_pnp_id cs_ids[] = { { 0x4060630e, NULL }, /* CSC6040 */ { 0x10104d24, NULL }, /* IBM EtherJet */ { 0, NULL } }; /* * Determine if the device is present */ static int cs_isa_probe(device_t dev) { int error; /* Check isapnp ids */ error = ISA_PNP_PROBE(device_get_parent(dev), dev, cs_ids); /* If the card had a PnP ID that didn't match any we know about */ if (error == ENXIO) goto end; /* If we've matched, or there's no PNP ID, probe chip */ if (error == 0 || error == ENOENT) error = cs_cs89x0_probe(dev); end: /* Make sure IRQ is assigned for probe message and available */ if (error == 0) error = cs_alloc_irq(dev, 0); cs_release_resources(dev); return (error); } static int cs_isa_attach(device_t dev) { struct cs_softc *sc = device_get_softc(dev); cs_alloc_port(dev, 0, CS_89x0_IO_PORTS); cs_alloc_irq(dev, sc->irq_rid); return (cs_attach(dev)); } static device_method_t cs_isa_methods[] = { /* Device interface */ DEVMETHOD(device_probe, cs_isa_probe), DEVMETHOD(device_attach, cs_isa_attach), DEVMETHOD(device_detach, cs_detach), { 0, 0 } }; static driver_t cs_isa_driver = { "cs", cs_isa_methods, sizeof(struct cs_softc), }; extern devclass_t cs_devclass; DRIVER_MODULE(cs, isa, cs_isa_driver, cs_devclass, 0, 0); MODULE_DEPEND(cs, isa, 1, 1, 1); MODULE_DEPEND(cs, ether, 1, 1, 1); +ISA_PNP_INFO(cs_ids); Index: head/sys/dev/ed/if_ed_isa.c =================================================================== --- head/sys/dev/ed/if_ed_isa.c (revision 327101) +++ head/sys/dev/ed/if_ed_isa.c (revision 327102) @@ -1,208 +1,206 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 1995, David Greenman * 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 unmodified, 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. * */ #include __FBSDID("$FreeBSD$"); #include "opt_ed.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int ed_isa_probe(device_t); static int ed_isa_attach(device_t); static struct isa_pnp_id ed_ids[] = { { 0x0131d805, NULL }, /* ANX3101 */ { 0x4cf48906, NULL }, /* ATIf44c */ { 0x01200507, NULL }, /* AXE2001 */ { 0x0115180e, NULL }, /* CPX1501 */ { 0x0090252a, NULL }, /* JQE9000 */ { 0x0020832e, NULL }, /* KTC2000 */ { 0xd680d041, NULL }, /* PNP80d6 */ { 0x6081d041, NULL }, /* PNP8160 */ { 0x19808c4a, NULL }, /* RTL8019 */ { 0x1684a34d, NULL }, /* SMC8416 */ { 0x1980635e, NULL }, /* WSC8019 */ { 0, NULL } }; static int ed_isa_probe_Novell(device_t dev) { struct ed_softc *sc = device_get_softc(dev); int flags = device_get_flags(dev); int err; err = ed_probe_Novell(dev, 0, flags); if (err) return err; ed_Novell_read_mac(sc); /* * Final sanity check for Gateway Ethernet cards before * believing that they really are Gateway AT. * XXX I think this is stale. */ if ((ED_FLAGS_GETTYPE(flags) == ED_FLAGS_GWETHER) && (sc->enaddr[2] == 0x86)) { sc->type_str = "Gateway AT"; } return (0); } static int ed_isa_probe(device_t dev) { struct ed_softc *sc = device_get_softc(dev); int flags = device_get_flags(dev); int error = 0; /* Check isapnp ids */ error = ISA_PNP_PROBE(device_get_parent(dev), dev, ed_ids); /* If the card had a PnP ID that didn't match any we know about */ if (error == ENXIO) goto end; /* If we had some other problem. */ if (!(error == 0 || error == ENOENT)) goto end; /* Heuristic probes */ error = ed_probe_WD80x3(dev, 0, flags); if (error == 0) goto end; ed_release_resources(dev); error = ed_probe_RTL80x9(dev, 0, flags); if (error == 0) { ed_Novell_read_mac(sc); goto end; } ed_release_resources(dev); #ifdef ED_3C503 error = ed_probe_3Com(dev, 0, flags); if (error == 0) goto end; ed_release_resources(dev); #endif #ifdef ED_SIC error = ed_probe_SIC(dev, 0, flags); if (error == 0) goto end; ed_release_resources(dev); #endif error = ed_isa_probe_Novell(dev); if (error == 0) goto end; ed_release_resources(dev); #ifdef ED_HPP error = ed_probe_HP_pclanp(dev, 0, flags); if (error == 0) goto end; ed_release_resources(dev); #endif end: if (error == 0) error = ed_alloc_irq(dev, 0, 0); ed_release_resources(dev); return (error); } static int ed_isa_attach(device_t dev) { struct ed_softc *sc = device_get_softc(dev); int error; if (sc->port_used > 0) ed_alloc_port(dev, 0, sc->port_used); if (sc->mem_used) ed_alloc_memory(dev, 0, sc->mem_used); ed_alloc_irq(dev, 0, 0); if (sc->sc_media_ioctl == NULL) ed_gen_ifmedia_init(sc); error = ed_attach(dev); if (error) { ed_release_resources(dev); return (error); } error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE, NULL, edintr, sc, &sc->irq_handle); if (error) ed_release_resources(dev); return (error); } static device_method_t ed_isa_methods[] = { /* Device interface */ DEVMETHOD(device_probe, ed_isa_probe), DEVMETHOD(device_attach, ed_isa_attach), DEVMETHOD(device_detach, ed_detach), { 0, 0 } }; static driver_t ed_isa_driver = { "ed", ed_isa_methods, sizeof(struct ed_softc) }; DRIVER_MODULE(ed, isa, ed_isa_driver, ed_devclass, 0, 0); MODULE_DEPEND(ed, isa, 1, 1, 1); MODULE_DEPEND(ed, ether, 1, 1, 1); -MODULE_PNP_INFO("E:pnpid;", isa, ed, ed_ids, sizeof(ed_ids[0]), - nitems(ed_ids) - 1); - +ISA_PNP_INFO(ed_ids); Index: head/sys/dev/ep/if_ep_isa.c =================================================================== --- head/sys/dev/ep/if_ep_isa.c (revision 327101) +++ head/sys/dev/ep/if_ep_isa.c (revision 327102) @@ -1,397 +1,398 @@ /*- * SPDX-License-Identifier: BSD-4-Clause * * Copyright (c) 1994 Herb Peyerl * 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 Herb Peyerl. * 4. The name of Herb Peyerl 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 * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __i386__ #include #endif #ifdef __i386__ static uint16_t get_eeprom_data(int, int); static void ep_isa_identify(driver_t *, device_t); #endif static int ep_isa_probe(device_t); static int ep_isa_attach(device_t); static int ep_eeprom_cksum(struct ep_softc *); struct isa_ident { uint32_t id; char *name; }; const char *ep_isa_match_id(uint32_t, struct isa_ident *); #define ISA_ID_3C509_XXX 0x0506d509 #define ISA_ID_3C509_TP 0x506d5090 #define ISA_ID_3C509_BNC 0x506d5091 #define ISA_ID_3C509_COMBO 0x506d5094 #define ISA_ID_3C509_TPO 0x506d5095 #define ISA_ID_3C509_TPC 0x506d5098 #ifdef __i386__ static struct isa_ident ep_isa_devs[] = { {ISA_ID_3C509_TP, "3Com 3C509-TP EtherLink III"}, {ISA_ID_3C509_BNC, "3Com 3C509-BNC EtherLink III"}, {ISA_ID_3C509_COMBO, "3Com 3C509-Combo EtherLink III"}, {ISA_ID_3C509_TPO, "3Com 3C509-TPO EtherLink III"}, {ISA_ID_3C509_TPC, "3Com 3C509-TPC EtherLink III"}, {0, NULL}, }; #endif static struct isa_pnp_id ep_ids[] = { {0x90506d50, "3Com 3C509B-TP EtherLink III (PnP)"}, /* TCM5090 */ {0x91506d50, "3Com 3C509B-BNC EtherLink III (PnP)"}, /* TCM5091 */ {0x94506d50, "3Com 3C509B-Combo EtherLink III (PnP)"}, /* TCM5094 */ {0x95506d50, "3Com 3C509B-TPO EtherLink III (PnP)"}, /* TCM5095 */ {0x98506d50, "3Com 3C509B-TPC EtherLink III (PnP)"}, /* TCM5098 */ {0xf780d041, NULL}, /* PNP80f7 */ {0, NULL}, }; /* * We get eeprom data from the id_port given an offset into the eeprom. * Basically; after the ID_sequence is sent to all of the cards; they enter * the ID_CMD state where they will accept command requests. 0x80-0xbf loads * the eeprom data. We then read the port 16 times and with every read; the * cards check for contention (ie: if one card writes a 0 bit and another * writes a 1 bit then the host sees a 0. At the end of the cycle; each card * compares the data on the bus; if there is a difference then that card goes * into ID_WAIT state again). In the meantime; one bit of data is returned in * the AX register which is conveniently returned to us by inb(). Hence; we * read 16 times getting one bit of data with each read. */ #ifdef __i386__ static uint16_t get_eeprom_data(int id_port, int offset) { int i; uint16_t data = 0; outb(id_port, EEPROM_CMD_RD | offset); DELAY(BIT_DELAY_MULTIPLE * 1000); for (i = 0; i < 16; i++) { DELAY(50); data = (data << 1) | (inw(id_port) & 1); } return (data); } #endif const char * ep_isa_match_id(uint32_t id, struct isa_ident *isa_devs) { struct isa_ident *i = isa_devs; while (i->name != NULL) { if (id == i->id) return (i->name); i++; } /* * If we see a card that is likely to be a 3c509 * return something so that it will work; be annoying * so that the user will tell us about it though. */ if ((id >> 4) == ISA_ID_3C509_XXX) return ("Unknown 3c509; notify maintainer!"); return (NULL); } #ifdef __i386__ static void ep_isa_identify(driver_t * driver, device_t parent) { int tag = EP_LAST_TAG; int found = 0; int i; int j; const char *desc; uint16_t data; uint32_t irq; uint32_t ioport; uint32_t isa_id; device_t child; outb(ELINK_ID_PORT, 0); outb(ELINK_ID_PORT, 0); elink_idseq(ELINK_509_POLY); elink_reset(); DELAY(DELAY_MULTIPLE * 10000); for (i = 0; i < EP_MAX_BOARDS; i++) { outb(ELINK_ID_PORT, 0); outb(ELINK_ID_PORT, 0); elink_idseq(ELINK_509_POLY); DELAY(400); /* * For the first probe, clear all board's tag registers. * Otherwise kill off already-found boards. -- linux 3c509.c */ if (i == 0) outb(ELINK_ID_PORT, 0xd0); else outb(ELINK_ID_PORT, 0xd8); /* Get out of loop if we're out of cards. */ data = get_eeprom_data(ELINK_ID_PORT, EEPROM_MFG_ID); if (data != MFG_ID) break; /* resolve contention using the Ethernet address */ for (j = 0; j < 3; j++) (void)get_eeprom_data(ELINK_ID_PORT, j); /* * Construct an 'isa_id' in 'EISA' format. */ data = get_eeprom_data(ELINK_ID_PORT, EEPROM_MFG_ID); isa_id = (htons(data) << 16); data = get_eeprom_data(ELINK_ID_PORT, EEPROM_PROD_ID); isa_id |= htons(data); /* Find known ISA boards */ desc = ep_isa_match_id(isa_id, ep_isa_devs); if (!desc) { if (bootverbose) device_printf(parent, "unknown ID 0x%08x\n", isa_id); continue; } /* Retreive IRQ */ data = get_eeprom_data(ELINK_ID_PORT, EEPROM_RESOURCE_CFG); irq = (data >> 12); /* Retreive IOPORT */ data = get_eeprom_data(ELINK_ID_PORT, EEPROM_ADDR_CFG); ioport = (((data & ADDR_CFG_MASK) << 4) + 0x200); if ((data & ADDR_CFG_MASK) == ADDR_CFG_EISA) { device_printf(parent, "<%s> at port 0x%03x in EISA mode, ignoring!\n", desc, ioport); /* * Set the adaptor tag so that the next card can be * found. */ outb(ELINK_ID_PORT, tag--); continue; } /* Test for an adapter with PnP support. */ data = get_eeprom_data(ELINK_ID_PORT, EEPROM_CAP); if (data == CAP_ISA) { data = get_eeprom_data(ELINK_ID_PORT, EEPROM_INT_CONFIG_1); if (data & ICW1_IAS_PNP) { if (bootverbose) device_printf(parent, "<%s> at 0x%03x " "in PnP mode!\n", desc, ioport); /* * Set the adaptor tag so that the next card * can be found. */ outb(ELINK_ID_PORT, tag--); continue; } } /* Set the adaptor tag so that the next card can be found. */ outb(ELINK_ID_PORT, tag--); /* Activate the adaptor at the EEPROM location. */ outb(ELINK_ID_PORT, ACTIVATE_ADAPTER_TO_CONFIG); /* Test for an adapter in TEST mode. */ outw(ioport + EP_COMMAND, WINDOW_SELECT | 0); data = inw(ioport + EP_W0_EEPROM_COMMAND); if (data & EEPROM_TST_MODE) { device_printf(parent, "<%s> at port 0x%03x in TEST mode!" " Erase pencil mark.\n", desc, ioport); continue; } child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "ep", -1); device_set_desc_copy(child, desc); device_set_driver(child, driver); bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1); bus_set_resource(child, SYS_RES_IOPORT, 0, ioport, EP_IOSIZE); if (bootverbose) device_printf(parent, "<%s>" " at port 0x%03x-0x%03x irq %d\n", desc, ioport, ioport + EP_IOSIZE, irq); found++; } } #endif static int ep_isa_probe(device_t dev) { int error = 0; /* Check isapnp ids */ error = ISA_PNP_PROBE(device_get_parent(dev), dev, ep_ids); /* If the card had a PnP ID that didn't match any we know about */ if (error == ENXIO) return (error); /* If we had some other problem. */ if (!(error == 0 || error == ENOENT)) return (error); /* If we have the resources we need then we're good to go. */ if ((bus_get_resource_start(dev, SYS_RES_IOPORT, 0) != 0) && (bus_get_resource_start(dev, SYS_RES_IRQ, 0) != 0)) return (0); return (ENXIO); } static int ep_isa_attach(device_t dev) { struct ep_softc *sc = device_get_softc(dev); int error = 0; if ((error = ep_alloc(dev))) goto bad; ep_get_media(sc); GO_WINDOW(sc, 0); SET_IRQ(sc, rman_get_start(sc->irq)); if ((error = ep_attach(sc))) goto bad; error = ep_eeprom_cksum(sc); if (error) { device_printf(sc->dev, "Invalid EEPROM checksum!\n"); goto bad; } if ((error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, NULL, ep_intr, sc, &sc->ep_intrhand))) { device_printf(dev, "bus_setup_intr() failed! (%d)\n", error); goto bad; } return (0); bad: ep_free(dev); return (error); } static int ep_eeprom_cksum(struct ep_softc *sc) { int i; int error; uint16_t val; uint16_t cksum; uint8_t cksum_high = 0; uint8_t cksum_low = 0; error = ep_get_e(sc, 0x0f, &val); if (error) return (ENXIO); cksum = val; for (i = 0; i < 0x0f; i++) { error = ep_get_e(sc, i, &val); if (error) return (ENXIO); switch (i) { case 0x08: case 0x09: case 0x0d: cksum_low ^= (uint8_t) (val & 0x00ff) ^ (uint8_t)((val & 0xff00) >> 8); break; default: cksum_high ^= (uint8_t) (val & 0x00ff) ^ (uint8_t)((val & 0xff00) >> 8); break; } } return (cksum != ((uint16_t)cksum_low | (uint16_t)(cksum_high << 8))); } static device_method_t ep_isa_methods[] = { /* Device interface */ #ifdef __i386__ DEVMETHOD(device_identify, ep_isa_identify), #endif DEVMETHOD(device_probe, ep_isa_probe), DEVMETHOD(device_attach, ep_isa_attach), DEVMETHOD(device_detach, ep_detach), DEVMETHOD_END }; static driver_t ep_isa_driver = { "ep", ep_isa_methods, sizeof(struct ep_softc), }; extern devclass_t ep_devclass; DRIVER_MODULE(ep, isa, ep_isa_driver, ep_devclass, 0, 0); #ifdef __i386__ MODULE_DEPEND(ep, elink, 1, 1, 1); #endif +ISA_PNP_INFO(ep_ids); Index: head/sys/dev/ex/if_ex_isa.c =================================================================== --- head/sys/dev/ex/if_ex_isa.c (revision 327101) +++ head/sys/dev/ex/if_ex_isa.c (revision 327102) @@ -1,339 +1,340 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2000 Matthew N. Dodd * 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. * */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Bus Front End Functions */ static void ex_isa_identify(driver_t *, device_t); static int ex_isa_probe(device_t); static int ex_isa_attach(device_t); static int ex_look_for_card(struct ex_softc *); #if 0 static void ex_pnp_wakeup(void *); SYSINIT(ex_pnpwakeup, SI_SUB_CPU, SI_ORDER_ANY, ex_pnp_wakeup, NULL); #endif static device_method_t ex_isa_methods[] = { /* Device interface */ DEVMETHOD(device_identify, ex_isa_identify), DEVMETHOD(device_probe, ex_isa_probe), DEVMETHOD(device_attach, ex_isa_attach), DEVMETHOD(device_detach, ex_detach), { 0, 0 } }; static driver_t ex_isa_driver = { "ex", ex_isa_methods, sizeof(struct ex_softc), }; -DRIVER_MODULE(ex, isa, ex_isa_driver, ex_devclass, 0, 0); - static struct isa_pnp_id ex_ids[] = { { 0x3110d425, NULL }, /* INT1031 */ { 0x3010d425, NULL }, /* INT1030 */ { 0, NULL }, }; #if 0 #define EX_PNP_WAKE 0x279 static uint8_t ex_pnp_wake_seq[] = { 0x6A, 0xB5, 0xDA, 0xED, 0xF6, 0xFB, 0x7D, 0xBE, 0xDF, 0x6F, 0x37, 0x1B, 0x0D, 0x86, 0xC3, 0x61, 0xB0, 0x58, 0x2C, 0x16, 0x8B, 0x45, 0xA2, 0xD1, 0xE8, 0x74, 0x3A, 0x9D, 0xCE, 0xE7, 0x73, 0x43 }; static void ex_pnp_wakeup (void * dummy) { int tmp; if (bootverbose) printf("ex_pnp_wakeup()\n"); outb(EX_PNP_WAKE, 0); outb(EX_PNP_WAKE, 0); for (tmp = 0; tmp < 32; tmp++) { outb(EX_PNP_WAKE, ex_pnp_wake_seq[tmp]); } } #endif /* * Non-destructive identify. */ static void ex_isa_identify(driver_t *driver, device_t parent) { device_t child; bus_addr_t ioport; u_char enaddr[6]; u_int irq; int tmp; const char * desc; struct ex_softc sc; int rid; if (bootverbose) printf("ex_isa_identify()\n"); for (ioport = 0x200; ioport < 0x3a0; ioport += 0x10) { rid = 0; sc.ioport = bus_alloc_resource(parent, SYS_RES_IOPORT, &rid, ioport, ioport, 0x10, RF_ACTIVE); if (sc.ioport == NULL) continue; /* No board found at address */ if (!ex_look_for_card(&sc)) { bus_release_resource(parent, SYS_RES_IOPORT, rid, sc.ioport); continue; } if (bootverbose) printf("ex: Found card at 0x%03lx!\n", (unsigned long)ioport); /* Board in PnP mode */ if (ex_eeprom_read(&sc, EE_W0) & EE_W0_PNP) { /* Reset the card. */ CSR_WRITE_1(&sc, CMD_REG, Reset_CMD); DELAY(500); if (bootverbose) printf("ex: card at 0x%03lx in PnP mode!\n", (unsigned long)ioport); bus_release_resource(parent, SYS_RES_IOPORT, rid, sc.ioport); continue; } bzero(enaddr, sizeof(enaddr)); /* Reset the card. */ CSR_WRITE_1(&sc, CMD_REG, Reset_CMD); DELAY(400); ex_get_address(&sc, enaddr); tmp = ex_eeprom_read(&sc, EE_W1) & EE_W1_INT_SEL; /* work out which set of irq <-> internal tables to use */ if (ex_card_type(enaddr) == CARD_TYPE_EX_10_PLUS) { irq = plus_ee2irqmap[tmp]; desc = "Intel Pro/10+"; } else { irq = ee2irqmap[tmp]; desc = "Intel Pro/10"; } bus_release_resource(parent, SYS_RES_IOPORT, rid, sc.ioport); child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "ex", -1); device_set_desc_copy(child, desc); device_set_driver(child, driver); bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1); bus_set_resource(child, SYS_RES_IOPORT, 0, ioport, EX_IOSIZE); if (bootverbose) printf("ex: Adding board at 0x%03lx, irq %d\n", (unsigned long)ioport, irq); } return; } static int ex_isa_probe(device_t dev) { bus_addr_t iobase; u_int irq; char * irq2ee; u_char * ee2irq; u_char enaddr[6]; int tmp; int error; struct ex_softc *sc = device_get_softc(dev); /* Check isapnp ids */ error = ISA_PNP_PROBE(device_get_parent(dev), dev, ex_ids); /* If the card had a PnP ID that didn't match any we know about */ if (error == ENXIO) return(error); /* If we had some other problem. */ if (!(error == 0 || error == ENOENT)) return(error); error = ex_alloc_resources(dev); if (error != 0) goto bad; iobase = bus_get_resource_start(dev, SYS_RES_IOPORT, 0); if (!ex_look_for_card(sc)) { if (bootverbose) printf("ex: no card found at 0x%03lx.\n", (unsigned long)iobase); error = ENXIO; goto bad; } if (bootverbose) printf("ex: ex_isa_probe() found card at 0x%03lx\n", (unsigned long)iobase); /* * Reset the card. */ CSR_WRITE_1(sc, CMD_REG, Reset_CMD); DELAY(800); ex_get_address(sc, enaddr); /* work out which set of irq <-> internal tables to use */ if (ex_card_type(enaddr) == CARD_TYPE_EX_10_PLUS) { irq2ee = plus_irq2eemap; ee2irq = plus_ee2irqmap; } else { irq2ee = irq2eemap; ee2irq = ee2irqmap; } tmp = ex_eeprom_read(sc, EE_W1) & EE_W1_INT_SEL; irq = bus_get_resource_start(dev, SYS_RES_IRQ, 0); if (irq > 0) { /* This will happen if board is in PnP mode. */ if (ee2irq[tmp] != irq) { device_printf(dev, "WARNING: IRQ mismatch: EEPROM %d, using %d\n", ee2irq[tmp], irq); } } else { irq = ee2irq[tmp]; bus_set_resource(dev, SYS_RES_IRQ, 0, irq, 1); } if (irq == 0) { printf("ex: invalid IRQ.\n"); error = ENXIO; } bad:; ex_release_resources(dev); return (error); } static int ex_isa_attach(device_t dev) { struct ex_softc * sc = device_get_softc(dev); int error = 0; uint16_t temp; sc->dev = dev; sc->ioport_rid = 0; sc->irq_rid = 0; sc->flags |= HAS_INT_NO_REG; if ((error = ex_alloc_resources(dev)) != 0) { device_printf(dev, "ex_alloc_resources() failed!\n"); goto bad; } /* * Fill in several fields of the softc structure: * - I/O base address. * - Hardware Ethernet address. * - IRQ number (if not supplied in config file, read it from EEPROM). * - Connector type. */ sc->irq_no = rman_get_start(sc->irq); ex_get_address(sc, sc->enaddr); temp = ex_eeprom_read(sc, EE_W0); device_printf(sc->dev, "%s config, %s bus, ", (temp & EE_W0_PNP) ? "PnP" : "Manual", (temp & EE_W0_BUS16) ? "16-bit" : "8-bit"); temp = ex_eeprom_read(sc, EE_W6); printf("board id 0x%03x, stepping 0x%01x\n", (temp & EE_W6_BOARD_MASK) >> EE_W6_BOARD_SHIFT, temp & EE_W6_STEP_MASK); if ((error = ex_attach(dev)) != 0) { device_printf(dev, "ex_attach() failed!\n"); goto bad; } return(0); bad: ex_release_resources(dev); return (error); } static int ex_look_for_card(struct ex_softc *sc) { int count1, count2; /* * Check for the i82595 signature, and check that the round robin * counter actually advances. */ if (((count1 = CSR_READ_1(sc, ID_REG)) & Id_Mask) != Id_Sig) return(0); count2 = CSR_READ_1(sc, ID_REG); count2 = CSR_READ_1(sc, ID_REG); count2 = CSR_READ_1(sc, ID_REG); return((count2 & Counter_bits) == ((count1 + 0xc0) & Counter_bits)); } + +DRIVER_MODULE(ex, isa, ex_isa_driver, ex_devclass, 0, 0); +ISA_PNP_INFO(ex_ids); Index: head/sys/dev/fdc/fdc_isa.c =================================================================== --- head/sys/dev/fdc/fdc_isa.c (revision 327101) +++ head/sys/dev/fdc/fdc_isa.c (revision 327102) @@ -1,226 +1,227 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2004-2005 M. Warner Losh. * 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include static int fdc_isa_probe(device_t); static struct isa_pnp_id fdc_ids[] = { {0x0007d041, "PC standard floppy controller"}, /* PNP0700 */ {0x0107d041, "Standard floppy controller supporting MS Device Bay Spec"}, /* PNP0701 */ {0} }; /* * On standard ISA, we don't just use an 8 port range * (e.g. 0x3f0-0x3f7) since that covers an IDE control register at * 0x3f6. So, on older hardware, we use 0x3f0-0x3f5 and 0x3f7. * However, some BIOSs omit the control port, while others start at * 0x3f2. Of the latter, sometimes we have two resources, other times * we have one. We have to deal with the following cases: * * 1: 0x3f0-0x3f5 # very rare * 2: 0x3f0 # hints -> 0x3f0-0x3f5,0x3f7 * 3: 0x3f0-0x3f5,0x3f7 # Most common * 4: 0x3f2-0x3f5,0x3f7 # Second most common * 5: 0x3f2-0x3f5 # implies 0x3f7 too. * 6: 0x3f2-0x3f3,0x3f4-0x3f5,0x3f7 # becoming common * 7: 0x3f2-0x3f3,0x3f4-0x3f5 # rare * 8: 0x3f0-0x3f1,0x3f2-0x3f3,0x3f4-0x3f5,0x3f7 * 9: 0x3f0-0x3f3,0x3f4-0x3f5,0x3f7 * * The following code is generic for any value of 0x3fx. It is also * generic for all the above cases, as well as cases where things are * even weirder. */ int fdc_isa_alloc_resources(device_t dev, struct fdc_data *fdc) { struct resource *res; int i, j, rid, newrid, nport; u_long port; fdc->fdc_dev = dev; rid = 0; for (i = 0; i < FDC_MAXREG; i++) fdc->resio[i] = NULL; nport = isa_get_logicalid(dev) ? 1 : 6; for (rid = 0; ; rid++) { newrid = rid; res = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &newrid, rid == 0 ? nport : 1, RF_ACTIVE); if (res == NULL) break; /* * Mask off the upper bits of the register, and sanity * check resource ranges. */ i = rman_get_start(res) & 0x7; if (i + rman_get_size(res) - 1 > FDC_MAXREG) { bus_release_resource(dev, SYS_RES_IOPORT, newrid, res); return (ENXIO); } for (j = 0; j < rman_get_size(res); j++) { fdc->resio[i + j] = res; fdc->ridio[i + j] = newrid; fdc->ioff[i + j] = j; fdc->ioh[i + j] = rman_get_bushandle(res); } } if (fdc->resio[2] == NULL) { device_printf(dev, "No FDOUT register!\n"); return (ENXIO); } fdc->iot = rman_get_bustag(fdc->resio[2]); if (fdc->resio[7] == NULL) { port = (rman_get_start(fdc->resio[2]) & ~0x7) + 7; newrid = rid; res = bus_alloc_resource(dev, SYS_RES_IOPORT, &newrid, port, port, 1, RF_ACTIVE); if (res == NULL) { device_printf(dev, "Faking up FDCTL\n"); fdc->resio[7] = fdc->resio[2]; fdc->ridio[7] = fdc->ridio[2]; fdc->ioff[7] = fdc->ioff[2] + 5; fdc->ioh[7] = fdc->ioh[2]; } else { fdc->resio[7] = res; fdc->ridio[7] = newrid; fdc->ioff[7] = rman_get_start(res) & 7; fdc->ioh[7] = rman_get_bushandle(res); } } fdc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &fdc->rid_irq, RF_ACTIVE | RF_SHAREABLE); if (fdc->res_irq == NULL) { device_printf(dev, "cannot reserve interrupt line\n"); return (ENXIO); } if ((fdc->flags & FDC_NODMA) == 0) { fdc->res_drq = bus_alloc_resource_any(dev, SYS_RES_DRQ, &fdc->rid_drq, RF_ACTIVE | RF_SHAREABLE); if (fdc->res_drq == NULL) { device_printf(dev, "cannot reserve DMA request line\n"); /* This is broken and doesn't work for ISA case */ fdc->flags |= FDC_NODMA; } else fdc->dmachan = rman_get_start(fdc->res_drq); } return (0); } static int fdc_isa_probe(device_t dev) { int error; struct fdc_data *fdc; fdc = device_get_softc(dev); fdc->fdc_dev = dev; /* Check pnp ids */ error = ISA_PNP_PROBE(device_get_parent(dev), dev, fdc_ids); if (error == ENXIO) return (ENXIO); /* Attempt to allocate our resources for the duration of the probe */ error = fdc_isa_alloc_resources(dev, fdc); if (error == 0) error = fdc_initial_reset(dev, fdc); fdc_release_resources(fdc); return (error); } static int fdc_isa_attach(device_t dev) { struct fdc_data *fdc; int error; fdc = device_get_softc(dev); fdc->fdc_dev = dev; error = fdc_isa_alloc_resources(dev, fdc); if (error == 0) error = fdc_attach(dev); if (error == 0) error = fdc_hints_probe(dev); if (error == 0) fdc_start_worker(dev); else fdc_release_resources(fdc); return (error); } static device_method_t fdc_methods[] = { /* Device interface */ DEVMETHOD(device_probe, fdc_isa_probe), DEVMETHOD(device_attach, fdc_isa_attach), DEVMETHOD(device_detach, fdc_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, bus_generic_suspend), DEVMETHOD(device_resume, bus_generic_resume), /* Bus interface */ DEVMETHOD(bus_print_child, fdc_print_child), DEVMETHOD(bus_read_ivar, fdc_read_ivar), DEVMETHOD(bus_write_ivar, fdc_write_ivar), /* Our children never use any other bus interface methods. */ { 0, 0 } }; static driver_t fdc_driver = { "fdc", fdc_methods, sizeof(struct fdc_data) }; DRIVER_MODULE(fdc, isa, fdc_driver, fdc_devclass, 0, 0); +ISA_PNP_INFO(fdc_ids); Index: head/sys/dev/fe/if_fe_isa.c =================================================================== --- head/sys/dev/fe/if_fe_isa.c (revision 327101) +++ head/sys/dev/fe/if_fe_isa.c (revision 327102) @@ -1,1064 +1,1063 @@ /*- * All Rights Reserved, Copyright (C) Fujitsu Limited 1995 * * This software may be used, modified, copied, distributed, and sold, in * both source and binary form provided that the above copyright, these * terms and the following disclaimer are retained. The name of the author * and/or the contributor 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 AND THE CONTRIBUTOR ``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 THE CONTRIBUTOR 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* * ISA specific code. */ static int fe_isa_probe(device_t); static int fe_isa_attach(device_t); static device_method_t fe_isa_methods[] = { /* Device interface */ DEVMETHOD(device_probe, fe_isa_probe), DEVMETHOD(device_attach, fe_isa_attach), { 0, 0 } }; static driver_t fe_isa_driver = { "fe", fe_isa_methods, sizeof (struct fe_softc) }; -DRIVER_MODULE(fe, isa, fe_isa_driver, fe_devclass, 0, 0); - - static int fe_probe_ssi(device_t); static int fe_probe_jli(device_t); static int fe_probe_fmv(device_t); static int fe_probe_lnx(device_t); static int fe_probe_gwy(device_t); static int fe_probe_ubn(device_t); /* * Determine if the device is present at a specified I/O address. The * main entry to the driver. */ static int fe_isa_probe(device_t dev) { struct fe_softc *sc; int error; /* Check isapnp ids */ if (isa_get_vendorid(dev)) return (ENXIO); /* Prepare for the softc struct. */ sc = device_get_softc(dev); sc->sc_unit = device_get_unit(dev); /* Probe for supported boards. */ if ((error = fe_probe_ssi(dev)) == 0) goto end; fe_release_resource(dev); if ((error = fe_probe_jli(dev)) == 0) goto end; fe_release_resource(dev); if ((error = fe_probe_fmv(dev)) == 0) goto end; fe_release_resource(dev); if ((error = fe_probe_lnx(dev)) == 0) goto end; fe_release_resource(dev); if ((error = fe_probe_ubn(dev)) == 0) goto end; fe_release_resource(dev); if ((error = fe_probe_gwy(dev)) == 0) goto end; fe_release_resource(dev); end: if (error == 0) error = fe_alloc_irq(dev, 0); fe_release_resource(dev); return (error); } static int fe_isa_attach(device_t dev) { struct fe_softc *sc = device_get_softc(dev); int error = 0; /* * Note: these routines aren't expected to fail since we also call * them in the probe routine. But coverity complains, so we'll honor * that complaint since the intention here was never to ignore them.. */ if (sc->port_used) { error = fe_alloc_port(dev, sc->port_used); if (error != 0) return (error); } error = fe_alloc_irq(dev, 0); if (error != 0) return (error); return fe_attach(dev); } /* * Probe and initialization for Fujitsu FMV-180 series boards */ static void fe_init_fmv(struct fe_softc *sc) { /* Initialize ASIC. */ fe_outb(sc, FE_FMV3, 0); fe_outb(sc, FE_FMV10, 0); #if 0 /* "Refresh" hardware configuration. FIXME. */ fe_outb(sc, FE_FMV2, fe_inb(sc, FE_FMV2)); #endif /* Turn the "master interrupt control" flag of ASIC on. */ fe_outb(sc, FE_FMV3, FE_FMV3_IRQENB); } static void fe_msel_fmv184(struct fe_softc *sc) { u_char port; /* FMV-184 has a special "register" to switch between AUI/BNC. Determine the value to write into the register, based on the user-specified media selection. */ port = (IFM_SUBTYPE(sc->media.ifm_media) == IFM_10_2) ? 0x00 : 0x01; /* The register is #5 on exntesion register bank... (Details of the register layout is not yet discovered.) */ fe_outb(sc, 0x1B, 0x46); /* ??? */ fe_outb(sc, 0x1E, 0x04); /* select ex-reg #4. */ fe_outb(sc, 0x1F, 0xC8); /* ??? */ fe_outb(sc, 0x1E, 0x05); /* select ex-reg #5. */ fe_outb(sc, 0x1F, port); /* Switch the media. */ fe_outb(sc, 0x1E, 0x04); /* select ex-reg #4. */ fe_outb(sc, 0x1F, 0x00); /* ??? */ fe_outb(sc, 0x1B, 0x00); /* ??? */ /* Make sure to select "external tranceiver" on MB86964. */ fe_outb(sc, FE_BMPR13, sc->proto_bmpr13 | FE_B13_PORT_AUI); } static int fe_probe_fmv(device_t dev) { struct fe_softc *sc = device_get_softc(dev); int n; rman_res_t iobase, irq; static u_short const irqmap [ 4 ] = { 3, 7, 10, 15 }; static struct fe_simple_probe_struct const probe_table [] = { { FE_DLCR2, 0x71, 0x00 }, { FE_DLCR4, 0x08, 0x00 }, { FE_FMV0, 0x78, 0x50 }, /* ERRDY+PRRDY */ { FE_FMV1, 0xB0, 0x00 }, /* FMV-183/4 has 0x48 bits. */ { FE_FMV3, 0x7F, 0x00 }, { 0 } }; /* Board subtypes; it lists known FMV-180 variants. */ struct subtype { u_short mcode; u_short mbitmap; u_short defmedia; char const * str; }; static struct subtype const typelist [] = { { 0x0005, MB_HA|MB_HT|MB_H5, MB_HA, "FMV-181" }, { 0x0105, MB_HA|MB_HT|MB_H5, MB_HA, "FMV-181A" }, { 0x0003, MB_HM, MB_HM, "FMV-182" }, { 0x0103, MB_HM, MB_HM, "FMV-182A" }, { 0x0804, MB_HT, MB_HT, "FMV-183" }, { 0x0C04, MB_HT, MB_HT, "FMV-183 (on-board)" }, { 0x0803, MB_H2|MB_H5, MB_H2, "FMV-184" }, { 0, MB_HA, MB_HA, "unknown FMV-180 (?)" }, }; struct subtype const * type; /* Media indicator and "Hardware revision ID" */ u_short mcode; /* See if the specified address is possible for FMV-180 series. 220, 240, 260, 280, 2A0, 2C0, 300, and 340 are allowed for all boards, and 200, 2E0, 320, 360, 380, 3A0, 3C0, and 3E0 for PnP boards. */ if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) return ENXIO; if ((iobase & ~0x1E0) != 0x200) return ENXIO; /* FMV-180 occupies 32 I/O addresses. */ if (fe_alloc_port(dev, 32)) return ENXIO; /* Setup an I/O address mapping table and some others. */ fe_softc_defaults(sc); /* Simple probe. */ if (!fe_simple_probe(sc, probe_table)) return ENXIO; /* Get our station address from EEPROM, and make sure it is Fujitsu's. */ fe_inblk(sc, FE_FMV4, sc->enaddr, ETHER_ADDR_LEN); if (!fe_valid_Ether_p(sc->enaddr, 0x00000E)) return ENXIO; /* Find the supported media and "hardware revision" to know the model identification. */ mcode = (fe_inb(sc, FE_FMV0) & FE_FMV0_MEDIA) | ((fe_inb(sc, FE_FMV1) & FE_FMV1_REV) << 8); /* Determine the card type. */ for (type = typelist; type->mcode != 0; type++) { if (type->mcode == mcode) break; } if (type->mcode == 0) { /* Unknown card type... Hope the driver works. */ sc->stability |= UNSTABLE_TYPE; if (bootverbose) { device_printf(dev, "unknown config: %x-%x-%x-%x\n", fe_inb(sc, FE_FMV0), fe_inb(sc, FE_FMV1), fe_inb(sc, FE_FMV2), fe_inb(sc, FE_FMV3)); } } /* Setup the board type and media information. */ sc->type = FE_TYPE_FMV; sc->typestr = type->str; sc->mbitmap = type->mbitmap; sc->defmedia = type->defmedia; sc->msel = fe_msel_965; if (type->mbitmap == (MB_H2 | MB_H5)) { /* FMV184 requires a special media selection procedure. */ sc->msel = fe_msel_fmv184; } /* * An FMV-180 has been probed. * Determine which IRQ to be used. * * In this version, we give a priority to the kernel config file. * If the EEPROM and config don't match, say it to the user for * an attention. */ n = (fe_inb(sc, FE_FMV2) & FE_FMV2_IRS) >> FE_FMV2_IRS_SHIFT; irq = 0; bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL); if (irq == NO_IRQ) { /* Just use the probed value. */ bus_set_resource(dev, SYS_RES_IRQ, 0, irqmap[n], 1); } else if (irq != irqmap[n]) { /* Don't match. */ sc->stability |= UNSTABLE_IRQ; } /* We need an init hook to initialize ASIC before we start. */ sc->init = fe_init_fmv; return 0; } /* * Fujitsu MB86965 JLI mode probe routines. * * 86965 has a special operating mode called JLI (mode 0), under which * the chip interfaces with ISA bus with a software-programmable * configuration. (The Fujitsu document calls the feature "Plug and * play," but it is not compatible with the ISA-PnP spec. designed by * Intel and Microsoft.) Ethernet cards designed to use JLI are * almost same, but there are two things which require board-specific * probe routines: EEPROM layout and IRQ pin connection. * * JLI provides a handy way to access EEPROM which should contains the * chip configuration information (such as I/O port address) as well * as Ethernet station (MAC) address. The chip configuration info. is * stored on a fixed location. However, the station address can be * located anywhere in the EEPROM; it is up to the board designer to * determine the location. (The manual just says "somewhere in the * EEPROM.") The fe driver must somehow find out the correct * location. * * Another problem resides in the IRQ pin connection. JLI provides a * user to choose an IRQ from up to four predefined IRQs. The 86965 * chip has a register to select one out of the four possibilities. * However, the selection is against the four IRQ pins on the chip. * (So-called IRQ-A, -B, -C and -D.) It is (again) up to the board * designer to determine which pin to connect which IRQ line on the * ISA bus. We need a vendor (or model, for some vendor) specific IRQ * mapping table. * * The routine fe_probe_jli() provides all probe and initialization * processes which are common to all JLI implementation, and sub-probe * routines supply board-specific actions. * * JLI sub-probe routine has the following template: * * u_short const * func (struct fe_softc * sc, u_char const * eeprom); * * where eeprom is a pointer to an array of 32 byte data read from the * config EEPROM on the board. It returns an IRQ mapping table for the * board, when the corresponding implementation is detected. It * returns a NULL otherwise. * * Primary purpose of the functin is to analize the config EEPROM, * determine if it matches with the pattern of that of supported card, * and extract necessary information from it. One of the information * expected to be extracted from EEPROM is the Ethernet station (MAC) * address, which must be set to the softc table of the interface by * the board-specific routine. */ /* JLI sub-probe for Allied-Telesyn/Allied-Telesis AT1700/RE2000 series. */ static u_short const * fe_probe_jli_ati(struct fe_softc * sc, u_char const * eeprom) { int i; static u_short const irqmaps_ati [4][4] = { { 3, 4, 5, 9 }, { 10, 11, 12, 15 }, { 3, 11, 5, 15 }, { 10, 11, 14, 15 }, }; /* Make sure the EEPROM contains Allied-Telesis/Allied-Telesyn bit pattern. */ if (eeprom[1] != 0x00) return NULL; for (i = 2; i < 8; i++) if (eeprom[i] != 0xFF) return NULL; for (i = 14; i < 24; i++) if (eeprom[i] != 0xFF) return NULL; /* Get our station address from EEPROM, and make sure the EEPROM contains ATI's address. */ bcopy(eeprom + 8, sc->enaddr, ETHER_ADDR_LEN); if (!fe_valid_Ether_p(sc->enaddr, 0x0000F4)) return NULL; /* * The following model identification codes are stolen * from the NetBSD port of the fe driver. My reviewers * suggested minor revision. */ /* Determine the card type. */ switch (eeprom[FE_ATI_EEP_MODEL]) { case FE_ATI_MODEL_AT1700T: sc->typestr = "AT-1700T/RE2001"; sc->mbitmap = MB_HT; sc->defmedia = MB_HT; break; case FE_ATI_MODEL_AT1700BT: sc->typestr = "AT-1700BT/RE2003"; sc->mbitmap = MB_HA | MB_HT | MB_H2; break; case FE_ATI_MODEL_AT1700FT: sc->typestr = "AT-1700FT/RE2009"; sc->mbitmap = MB_HA | MB_HT | MB_HF; break; case FE_ATI_MODEL_AT1700AT: sc->typestr = "AT-1700AT/RE2005"; sc->mbitmap = MB_HA | MB_HT | MB_H5; break; default: sc->typestr = "unknown AT-1700/RE2000"; sc->stability |= UNSTABLE_TYPE | UNSTABLE_IRQ; break; } sc->type = FE_TYPE_JLI; #if 0 /* Should we extract default media from eeprom? Linux driver for AT1700 does it, although previous releases of FreeBSD don't. FIXME. */ /* Determine the default media selection from the config EEPROM. The byte at offset EEP_MEDIA is believed to contain BMPR13 value to be set. We just ignore STP bit or squelch bit, since we don't support those. (It is intentional.) */ switch (eeprom[FE_ATI_EEP_MEDIA] & FE_B13_PORT) { case FE_B13_AUTO: sc->defmedia = MB_HA; break; case FE_B13_TP: sc->defmedia = MB_HT; break; case FE_B13_AUI: sc->defmedia = sc->mbitmap & (MB_H2|MB_H5|MB_H5); /*XXX*/ break; default: sc->defmedia = MB_HA; break; } /* Make sure the default media is compatible with the supported ones. */ if ((sc->defmedia & sc->mbitmap) == 0) { if (sc->defmedia == MB_HA) { sc->defmedia = MB_HT; } else { sc->defmedia = MB_HA; } } #endif /* * Try to determine IRQ settings. * Different models use different ranges of IRQs. */ switch ((eeprom[FE_ATI_EEP_REVISION] & 0xf0) |(eeprom[FE_ATI_EEP_MAGIC] & 0x04)) { case 0x30: case 0x34: return irqmaps_ati[3]; case 0x10: case 0x14: case 0x50: case 0x54: return irqmaps_ati[2]; case 0x44: case 0x64: return irqmaps_ati[1]; default: return irqmaps_ati[0]; } } /* JLI sub-probe and msel hook for ICL Ethernet. */ static void fe_msel_icl(struct fe_softc *sc) { u_char d4; /* Switch between UTP and "external tranceiver" as always. */ fe_msel_965(sc); /* The board needs one more bit (on DLCR4) be set appropriately. */ if (IFM_SUBTYPE(sc->media.ifm_media) == IFM_10_5) { d4 = sc->proto_dlcr4 | FE_D4_CNTRL; } else { d4 = sc->proto_dlcr4 & ~FE_D4_CNTRL; } fe_outb(sc, FE_DLCR4, d4); } static u_short const * fe_probe_jli_icl(struct fe_softc * sc, u_char const * eeprom) { int i; u_short defmedia; u_char d6; static u_short const irqmap_icl [4] = { 9, 10, 5, 15 }; /* Make sure the EEPROM contains ICL bit pattern. */ for (i = 24; i < 39; i++) { if (eeprom[i] != 0x20 && (eeprom[i] & 0xF0) != 0x30) return NULL; } for (i = 112; i < 122; i++) { if (eeprom[i] != 0x20 && (eeprom[i] & 0xF0) != 0x30) return NULL; } /* Make sure the EEPROM contains ICL's permanent station address. If it isn't, probably this board is not an ICL's. */ if (!fe_valid_Ether_p(eeprom+122, 0x00004B)) return NULL; /* Check if the "configured" Ethernet address in the EEPROM is valid. Use it if it is, or use the "permanent" address instead. */ if (fe_valid_Ether_p(eeprom+4, 0x020000)) { /* The configured address is valid. Use it. */ bcopy(eeprom+4, sc->enaddr, ETHER_ADDR_LEN); } else { /* The configured address is invalid. Use permanent. */ bcopy(eeprom+122, sc->enaddr, ETHER_ADDR_LEN); } /* Determine model and supported media. */ switch (eeprom[0x5E]) { case 0: sc->typestr = "EtherTeam16i/COMBO"; sc->mbitmap = MB_HA | MB_HT | MB_H5 | MB_H2; break; case 1: sc->typestr = "EtherTeam16i/TP"; sc->mbitmap = MB_HT; break; case 2: sc->typestr = "EtherTeam16i/ErgoPro"; sc->mbitmap = MB_HA | MB_HT | MB_H5; break; case 4: sc->typestr = "EtherTeam16i/DUO"; sc->mbitmap = MB_HA | MB_HT | MB_H2; break; default: sc->typestr = "EtherTeam16i"; sc->stability |= UNSTABLE_TYPE; if (bootverbose) { printf("fe%d: unknown model code %02x for EtherTeam16i\n", sc->sc_unit, eeprom[0x5E]); } break; } sc->type = FE_TYPE_JLI; /* I'm not sure the following msel hook is required by all models or COMBO only... FIXME. */ sc->msel = fe_msel_icl; /* Make the configured media selection the default media. */ switch (eeprom[0x28]) { case 0: defmedia = MB_HA; break; case 1: defmedia = MB_H5; break; case 2: defmedia = MB_HT; break; case 3: defmedia = MB_H2; break; default: if (bootverbose) { printf("fe%d: unknown default media: %02x\n", sc->sc_unit, eeprom[0x28]); } defmedia = MB_HA; break; } /* Make sure the default media is compatible with the supported media. */ if ((defmedia & sc->mbitmap) == 0) { if (bootverbose) { printf("fe%d: default media adjusted\n", sc->sc_unit); } defmedia = sc->mbitmap; } /* Keep the determined default media. */ sc->defmedia = defmedia; /* ICL has "fat" models. We have to program 86965 to properly reflect the hardware. */ d6 = sc->proto_dlcr6 & ~(FE_D6_BUFSIZ | FE_D6_BBW); switch ((eeprom[0x61] << 8) | eeprom[0x60]) { case 0x2008: d6 |= FE_D6_BUFSIZ_32KB | FE_D6_BBW_BYTE; break; case 0x4010: d6 |= FE_D6_BUFSIZ_64KB | FE_D6_BBW_WORD; break; default: /* We can't support it, since we don't know which bits to set in DLCR6. */ printf("fe%d: unknown SRAM config for ICL\n", sc->sc_unit); return NULL; } sc->proto_dlcr6 = d6; /* Returns the IRQ table for the ICL board. */ return irqmap_icl; } /* JLI sub-probe for RATOC REX-5586/5587. */ static u_short const * fe_probe_jli_rex(struct fe_softc * sc, u_char const * eeprom) { int i; static u_short const irqmap_rex [4] = { 3, 4, 5, NO_IRQ }; /* Make sure the EEPROM contains RATOC's config pattern. */ if (eeprom[1] != eeprom[0]) return NULL; for (i = 8; i < 32; i++) if (eeprom[i] != 0xFF) return NULL; /* Get our station address from EEPROM. Note that RATOC stores it "byte-swapped" in each word. (I don't know why.) So, we just can't use bcopy().*/ sc->enaddr[0] = eeprom[3]; sc->enaddr[1] = eeprom[2]; sc->enaddr[2] = eeprom[5]; sc->enaddr[3] = eeprom[4]; sc->enaddr[4] = eeprom[7]; sc->enaddr[5] = eeprom[6]; /* Make sure the EEPROM contains RATOC's station address. */ if (!fe_valid_Ether_p(sc->enaddr, 0x00C0D0)) return NULL; /* I don't know any sub-model identification. */ sc->type = FE_TYPE_JLI; sc->typestr = "REX-5586/5587"; /* Returns the IRQ for the RATOC board. */ return irqmap_rex; } /* JLI sub-probe for Unknown board. */ static u_short const * fe_probe_jli_unk(struct fe_softc * sc, u_char const * eeprom) { int i, n, romsize; static u_short const irqmap [4] = { NO_IRQ, NO_IRQ, NO_IRQ, NO_IRQ }; /* The generic JLI probe considered this board has an 86965 in JLI mode, but any other board-specific routines could not find the matching implementation. So, we "guess" the location by looking for a bit pattern which looks like a MAC address. */ /* Determine how large the EEPROM is. */ for (romsize = JLI_EEPROM_SIZE/2; romsize > 16; romsize >>= 1) { for (i = 0; i < romsize; i++) { if (eeprom[i] != eeprom[i+romsize]) break; } if (i < romsize) break; } romsize <<= 1; /* Look for a bit pattern which looks like a MAC address. */ for (n = 2; n <= romsize - ETHER_ADDR_LEN; n += 2) { if (!fe_valid_Ether_p(eeprom + n, 0x000000)) continue; } /* If no reasonable address was found, we can't go further. */ if (n > romsize - ETHER_ADDR_LEN) return NULL; /* Extract our (guessed) station address. */ bcopy(eeprom+n, sc->enaddr, ETHER_ADDR_LEN); /* We are not sure what type of board it is... */ sc->type = FE_TYPE_JLI; sc->typestr = "(unknown JLI)"; sc->stability |= UNSTABLE_TYPE | UNSTABLE_MAC; /* Returns the totally unknown IRQ mapping table. */ return irqmap; } /* * Probe and initialization for all JLI implementations. */ static int fe_probe_jli(device_t dev) { struct fe_softc *sc = device_get_softc(dev); int i, n, error, xirq; rman_res_t iobase, irq; u_char eeprom [JLI_EEPROM_SIZE]; u_short const * irqmap; static u_short const baseaddr [8] = { 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300 }; static struct fe_simple_probe_struct const probe_table [] = { { FE_DLCR1, 0x20, 0x00 }, { FE_DLCR2, 0x50, 0x00 }, { FE_DLCR4, 0x08, 0x00 }, { FE_DLCR5, 0x80, 0x00 }, #if 0 { FE_BMPR16, 0x1B, 0x00 }, { FE_BMPR17, 0x7F, 0x00 }, #endif { 0 } }; /* * See if the specified address is possible for MB86965A JLI mode. */ if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) return ENXIO; for (i = 0; i < 8; i++) { if (baseaddr[i] == iobase) break; } if (i == 8) return ENXIO; /* 86965 JLI occupies 32 I/O addresses. */ if (fe_alloc_port(dev, 32)) return ENXIO; /* Fill the softc struct with reasonable default. */ fe_softc_defaults(sc); /* * We should test if MB86965A is on the base address now. * Unfortunately, it is very hard to probe it reliably, since * we have no way to reset the chip under software control. * On cold boot, we could check the "signature" bit patterns * described in the Fujitsu document. On warm boot, however, * we can predict almost nothing about register values. */ if (!fe_simple_probe(sc, probe_table)) return ENXIO; /* Check if our I/O address matches config info on 86965. */ n = (fe_inb(sc, FE_BMPR19) & FE_B19_ADDR) >> FE_B19_ADDR_SHIFT; if (baseaddr[n] != iobase) return ENXIO; /* * We are now almost sure we have an MB86965 at the given * address. So, read EEPROM through it. We have to write * into LSI registers to read from EEPROM. I want to avoid it * at this stage, but I cannot test the presence of the chip * any further without reading EEPROM. FIXME. */ fe_read_eeprom_jli(sc, eeprom); /* Make sure that config info in EEPROM and 86965 agree. */ if (eeprom[FE_EEPROM_CONF] != fe_inb(sc, FE_BMPR19)) return ENXIO; /* Use 86965 media selection scheme, unless othewise specified. It is "AUTO always" and "select with BMPR13." This behaviour covers most of the 86965 based board (as minimum requirements.) It is backward compatible with previous versions, also. */ sc->mbitmap = MB_HA; sc->defmedia = MB_HA; sc->msel = fe_msel_965; /* Perform board-specific probe, one by one. Note that the order of probe is important and should not be changed arbitrarily. */ if ((irqmap = fe_probe_jli_ati(sc, eeprom)) == NULL && (irqmap = fe_probe_jli_rex(sc, eeprom)) == NULL && (irqmap = fe_probe_jli_icl(sc, eeprom)) == NULL && (irqmap = fe_probe_jli_unk(sc, eeprom)) == NULL) return ENXIO; /* Find the IRQ read from EEPROM. */ n = (fe_inb(sc, FE_BMPR19) & FE_B19_IRQ) >> FE_B19_IRQ_SHIFT; xirq = irqmap[n]; /* Try to determine IRQ setting. */ error = bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL); if (error && xirq == NO_IRQ) { /* The device must be configured with an explicit IRQ. */ device_printf(dev, "IRQ auto-detection does not work\n"); return ENXIO; } else if (error && xirq != NO_IRQ) { /* Just use the probed IRQ value. */ bus_set_resource(dev, SYS_RES_IRQ, 0, xirq, 1); } else if (!error && xirq == NO_IRQ) { /* No problem. Go ahead. */ } else if (irq == xirq) { /* Good. Go ahead. */ } else { /* User must be warned in this case. */ sc->stability |= UNSTABLE_IRQ; } /* Setup a hook, which resets te 86965 when the driver is being initialized. This may solve a nasty bug. FIXME. */ sc->init = fe_init_jli; return 0; } /* Probe for TDK LAK-AX031, which is an SSi 78Q8377A based board. */ static int fe_probe_ssi(device_t dev) { struct fe_softc *sc = device_get_softc(dev); rman_res_t iobase, irq; u_char eeprom [SSI_EEPROM_SIZE]; static struct fe_simple_probe_struct probe_table [] = { { FE_DLCR2, 0x08, 0x00 }, { FE_DLCR4, 0x08, 0x00 }, { 0 } }; /* See if the specified I/O address is possible for 78Q8377A. */ if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) return ENXIO; if ((iobase & ~0x3F0) != 0x000) return ENXIO; /* We have 16 registers. */ if (fe_alloc_port(dev, 16)) return ENXIO; /* Fill the softc struct with default values. */ fe_softc_defaults(sc); /* See if the card is on its address. */ if (!fe_simple_probe(sc, probe_table)) return ENXIO; /* We now have to read the config EEPROM. We should be very careful, since doing so destroys a register. (Remember, we are not yet sure we have a LAK-AX031 board here.) Don't remember to select BMPRs bofore reading EEPROM, since other register bank may be selected before the probe() is called. */ fe_read_eeprom_ssi(sc, eeprom); /* Make sure the Ethernet (MAC) station address is of TDK's. */ if (!fe_valid_Ether_p(eeprom+FE_SSI_EEP_ADDR, 0x008098)) return ENXIO; bcopy(eeprom + FE_SSI_EEP_ADDR, sc->enaddr, ETHER_ADDR_LEN); /* This looks like a TDK-AX031 board. It requires an explicit IRQ setting in config, since we currently don't know how we can find the IRQ value assigned by ISA PnP manager. */ if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL) != 0) { fe_irq_failure("LAK-AX031", sc->sc_unit, NO_IRQ, NULL); return ENXIO; } /* Fill softc struct accordingly. */ sc->type = FE_TYPE_SSI; sc->typestr = "LAK-AX031"; sc->mbitmap = MB_HT; sc->defmedia = MB_HT; return 0; } /* * Probe and initialization for TDK/LANX LAC-AX012/013 boards. */ static int fe_probe_lnx(device_t dev) { struct fe_softc *sc = device_get_softc(dev); rman_res_t iobase, irq; u_char eeprom [LNX_EEPROM_SIZE]; static struct fe_simple_probe_struct probe_table [] = { { FE_DLCR2, 0x58, 0x00 }, { FE_DLCR4, 0x08, 0x00 }, { 0 } }; /* See if the specified I/O address is possible for TDK/LANX boards. */ /* 300, 320, 340, and 360 are allowed. */ if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) return ENXIO; if ((iobase & ~0x060) != 0x300) return ENXIO; /* We have 32 registers. */ if (fe_alloc_port(dev, 32)) return ENXIO; /* Fill the softc struct with default values. */ fe_softc_defaults(sc); /* See if the card is on its address. */ if (!fe_simple_probe(sc, probe_table)) return ENXIO; /* We now have to read the config EEPROM. We should be very careful, since doing so destroys a register. (Remember, we are not yet sure we have a LAC-AX012/AX013 board here.) */ fe_read_eeprom_lnx(sc, eeprom); /* Make sure the Ethernet (MAC) station address is of TDK/LANX's. */ if (!fe_valid_Ether_p(eeprom, 0x008098)) return ENXIO; bcopy(eeprom, sc->enaddr, ETHER_ADDR_LEN); /* This looks like a TDK/LANX board. It requires an explicit IRQ setting in config. Make sure we have one, determining an appropriate value for the IRQ control register. */ irq = 0; bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL); switch (irq) { case 3: sc->priv_info = 0x40 | LNX_CLK_LO | LNX_SDA_HI; break; case 4: sc->priv_info = 0x20 | LNX_CLK_LO | LNX_SDA_HI; break; case 5: sc->priv_info = 0x10 | LNX_CLK_LO | LNX_SDA_HI; break; case 9: sc->priv_info = 0x80 | LNX_CLK_LO | LNX_SDA_HI; break; default: fe_irq_failure("LAC-AX012/AX013", sc->sc_unit, irq, "3/4/5/9"); return ENXIO; } /* Fill softc struct accordingly. */ sc->type = FE_TYPE_LNX; sc->typestr = "LAC-AX012/AX013"; sc->init = fe_init_lnx; return 0; } /* * Probe and initialization for Gateway Communications' old cards. */ static int fe_probe_gwy(device_t dev) { struct fe_softc *sc = device_get_softc(dev); rman_res_t iobase, irq; static struct fe_simple_probe_struct probe_table [] = { /* { FE_DLCR2, 0x70, 0x00 }, */ { FE_DLCR2, 0x58, 0x00 }, { FE_DLCR4, 0x08, 0x00 }, { 0 } }; /* See if the specified I/O address is possible for Gateway boards. */ if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) return ENXIO; if ((iobase & ~0x1E0) != 0x200) return ENXIO; /* That's all. The card occupies 32 I/O addresses, as always. */ if (fe_alloc_port(dev, 32)) return ENXIO; /* Setup an I/O address mapping table and some others. */ fe_softc_defaults(sc); /* See if the card is on its address. */ if (!fe_simple_probe(sc, probe_table)) return ENXIO; /* Get our station address from EEPROM. */ fe_inblk(sc, 0x18, sc->enaddr, ETHER_ADDR_LEN); /* Make sure it is Gateway Communication's. */ if (!fe_valid_Ether_p(sc->enaddr, 0x000061)) return ENXIO; /* Gateway's board requires an explicit IRQ to work, since it is not possible to probe the setting of jumpers. */ if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL) != 0) { fe_irq_failure("Gateway Ethernet", sc->sc_unit, NO_IRQ, NULL); return ENXIO; } /* Fill softc struct accordingly. */ sc->type = FE_TYPE_GWY; sc->typestr = "Gateway Ethernet (Fujitsu chipset)"; return 0; } /* Probe and initialization for Ungermann-Bass Network K.K. "Access/PC" boards. */ static int fe_probe_ubn(device_t dev) { struct fe_softc *sc = device_get_softc(dev); rman_res_t iobase, irq; #if 0 u_char sum; #endif static struct fe_simple_probe_struct const probe_table [] = { { FE_DLCR2, 0x58, 0x00 }, { FE_DLCR4, 0x08, 0x00 }, { 0 } }; /* See if the specified I/O address is possible for AccessPC/ISA. */ if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) return ENXIO; if ((iobase & ~0x0E0) != 0x300) return ENXIO; /* We have 32 registers. */ if (fe_alloc_port(dev, 32)) return ENXIO; /* Setup an I/O address mapping table and some others. */ fe_softc_defaults(sc); /* Simple probe. */ if (!fe_simple_probe(sc, probe_table)) return ENXIO; /* Get our station address form ID ROM and make sure it is UBN's. */ fe_inblk(sc, 0x18, sc->enaddr, ETHER_ADDR_LEN); if (!fe_valid_Ether_p(sc->enaddr, 0x00DD01)) return ENXIO; #if 0 /* Calculate checksum. */ sum = fe_inb(sc, 0x1e); for (i = 0; i < ETHER_ADDR_LEN; i++) { sum ^= sc->enaddr[i]; } if (sum != 0) return ENXIO; #endif /* This looks like an AccessPC/ISA board. It requires an explicit IRQ setting in config. Make sure we have one, determining an appropriate value for the IRQ control register. */ irq = 0; bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL); switch (irq) { case 3: sc->priv_info = 0x02; break; case 4: sc->priv_info = 0x04; break; case 5: sc->priv_info = 0x08; break; case 10: sc->priv_info = 0x10; break; default: fe_irq_failure("Access/PC", sc->sc_unit, irq, "3/4/5/10"); return ENXIO; } /* Fill softc struct accordingly. */ sc->type = FE_TYPE_UBN; sc->typestr = "Access/PC"; sc->init = fe_init_ubn; return 0; } + +DRIVER_MODULE(fe, isa, fe_isa_driver, fe_devclass, 0, 0); Index: head/sys/dev/joy/joy_isa.c =================================================================== --- head/sys/dev/joy/joy_isa.c (revision 327101) +++ head/sys/dev/joy/joy_isa.c (revision 327102) @@ -1,87 +1,88 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1995 Jean-Marc Zucconi * 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 * in this position and unchanged. * 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. 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 * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include "isa_if.h" static int joy_isa_probe (device_t); static struct isa_pnp_id joy_ids[] = { {0x0100630e, "CSC0001 PnP Joystick"}, /* CSC0001 */ {0x0101630e, "CSC0101 PnP Joystick"}, /* CSC0101 */ {0x01100002, "ALS0110 PnP Joystick"}, /* @P@1001 */ {0x01200002, "ALS0120 PnP Joystick"}, /* @P@2001 */ {0x01007316, "ESS0001 PnP Joystick"}, /* ESS0001 */ {0x2fb0d041, "Generic PnP Joystick"}, /* PNPb02f */ {0x2200a865, "YMH0022 PnP Joystick"}, /* YMH0022 */ {0x82719304, NULL}, /* ADS7182 */ {0} }; static int joy_isa_probe(device_t dev) { if (ISA_PNP_PROBE(device_get_parent(dev), dev, joy_ids) == ENXIO) return ENXIO; return (joy_probe(dev)); } static device_method_t joy_methods[] = { DEVMETHOD(device_probe, joy_isa_probe), DEVMETHOD(device_attach, joy_attach), DEVMETHOD(device_detach, joy_detach), { 0, 0 } }; static driver_t joy_isa_driver = { "joy", joy_methods, sizeof (struct joy_softc) }; DRIVER_MODULE(joy, isa, joy_isa_driver, joy_devclass, 0, 0); DRIVER_MODULE(joy, acpi, joy_isa_driver, joy_devclass, 0, 0); +ISA_PNP_INFO(joy_ids); Index: head/sys/dev/le/if_le_isa.c =================================================================== --- head/sys/dev/le/if_le_isa.c (revision 327101) +++ head/sys/dev/le/if_le_isa.c (revision 327102) @@ -1,498 +1,499 @@ /* $NetBSD: if_le_isa.c,v 1.41 2005/12/24 20:27:41 perry Exp $ */ /*- * SPDX-License-Identifier: BSD-2-Clause-NetBSD AND BSD-3-Clause * * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace * Simulation Facility, NASA Ames Research Center. * * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Ralph Campbell and Rick Macklem. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)if_le.c 8.2 (Berkeley) 11/16/93 */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define LE_ISA_MEMSIZE (16*1024) #define PCNET_RDP 0x10 #define PCNET_RAP 0x12 struct le_isa_softc { struct am7990_softc sc_am7990; /* glue to MI code */ bus_size_t sc_rap; /* offsets to LANCE... */ bus_size_t sc_rdp; /* ...registers */ struct resource *sc_rres; struct resource *sc_dres; struct resource *sc_ires; void *sc_ih; bus_dma_tag_t sc_pdmat; bus_dma_tag_t sc_dmat; bus_dmamap_t sc_dmam; }; static device_probe_t le_isa_probe; static device_attach_t le_isa_attach; static device_detach_t le_isa_detach; static device_resume_t le_isa_resume; static device_suspend_t le_isa_suspend; static device_method_t le_isa_methods[] = { /* Device interface */ DEVMETHOD(device_probe, le_isa_probe), DEVMETHOD(device_attach, le_isa_attach), DEVMETHOD(device_detach, le_isa_detach), /* We can just use the suspend method here. */ DEVMETHOD(device_shutdown, le_isa_suspend), DEVMETHOD(device_suspend, le_isa_suspend), DEVMETHOD(device_resume, le_isa_resume), { 0, 0 } }; -DEFINE_CLASS_0(le, le_isa_driver, le_isa_methods, sizeof(struct le_isa_softc)); -DRIVER_MODULE(le, isa, le_isa_driver, le_devclass, 0, 0); -MODULE_DEPEND(le, ether, 1, 1, 1); - struct le_isa_param { const char *name; u_long iosize; bus_size_t rap; bus_size_t rdp; bus_size_t macstart; int macstride; } static const le_isa_params[] = { { "BICC Isolan", 24, 0xe, 0xc, 0, 2 }, { "Novell NE2100", 16, 0x12, 0x10, 0, 1 } }; static struct isa_pnp_id le_isa_ids[] = { { 0x0322690e, "Cabletron E2200 Single Chip" }, /* CSI2203 */ { 0x0110490a, "Boca LANCard Combo" }, /* BRI1001 */ { 0x0100a60a, "Melco Inc. LGY-IV" }, /* BUF0001 */ { 0xd880d041, "Novell NE2100" }, /* PNP80D8 */ { 0x0082d041, "Cabletron E2100 Series DNI" }, /* PNP8200 */ { 0x3182d041, "AMD AM1500T/AM2100" }, /* PNP8231 */ { 0x8c82d041, "AMD PCnet-ISA" }, /* PNP828C */ { 0x8d82d041, "AMD PCnet-32" }, /* PNP828D */ { 0xcefaedfe, "Racal InterLan EtherBlaster" }, /* _WMFACE */ { 0, NULL } }; static void le_isa_wrcsr(struct lance_softc *, uint16_t, uint16_t); static uint16_t le_isa_rdcsr(struct lance_softc *, uint16_t); static bus_dmamap_callback_t le_isa_dma_callback; static int le_isa_probe_legacy(device_t, const struct le_isa_param *); static void le_isa_wrcsr(struct lance_softc *sc, uint16_t port, uint16_t val) { struct le_isa_softc *lesc = (struct le_isa_softc *)sc; bus_write_2(lesc->sc_rres, lesc->sc_rap, port); bus_barrier(lesc->sc_rres, lesc->sc_rap, 2, BUS_SPACE_BARRIER_WRITE); bus_write_2(lesc->sc_rres, lesc->sc_rdp, val); } static uint16_t le_isa_rdcsr(struct lance_softc *sc, uint16_t port) { struct le_isa_softc *lesc = (struct le_isa_softc *)sc; bus_write_2(lesc->sc_rres, lesc->sc_rap, port); bus_barrier(lesc->sc_rres, lesc->sc_rap, 2, BUS_SPACE_BARRIER_WRITE); return (bus_read_2(lesc->sc_rres, lesc->sc_rdp)); } static void le_isa_dma_callback(void *xsc, bus_dma_segment_t *segs, int nsegs, int error) { struct lance_softc *sc = (struct lance_softc *)xsc; if (error != 0) return; KASSERT(nsegs == 1, ("%s: bad DMA segment count", __func__)); sc->sc_addr = segs[0].ds_addr; } static int le_isa_probe_legacy(device_t dev, const struct le_isa_param *leip) { struct le_isa_softc *lesc; struct lance_softc *sc; int error, i; lesc = device_get_softc(dev); sc = &lesc->sc_am7990.lsc; i = 0; lesc->sc_rres = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &i, leip->iosize, RF_ACTIVE); if (lesc->sc_rres == NULL) return (ENXIO); lesc->sc_rap = leip->rap; lesc->sc_rdp = leip->rdp; /* Stop the chip and put it in a known state. */ le_isa_wrcsr(sc, LE_CSR0, LE_C0_STOP); DELAY(100); if (le_isa_rdcsr(sc, LE_CSR0) != LE_C0_STOP) { error = ENXIO; goto fail; } le_isa_wrcsr(sc, LE_CSR3, 0); error = 0; fail: bus_release_resource(dev, SYS_RES_IOPORT, rman_get_rid(lesc->sc_rres), lesc->sc_rres); return (error); } static int le_isa_probe(device_t dev) { int i; switch (ISA_PNP_PROBE(device_get_parent(dev), dev, le_isa_ids)) { case 0: return (BUS_PROBE_DEFAULT); case ENOENT: for (i = 0; i < nitems(le_isa_params); i++) { if (le_isa_probe_legacy(dev, &le_isa_params[i]) == 0) { device_set_desc(dev, le_isa_params[i].name); return (BUS_PROBE_DEFAULT); } } /* FALLTHROUGH */ case ENXIO: default: return (ENXIO); } } static int le_isa_attach(device_t dev) { struct le_isa_softc *lesc; struct lance_softc *sc; bus_size_t macstart, rap, rdp; int error, i, j, macstride; lesc = device_get_softc(dev); sc = &lesc->sc_am7990.lsc; LE_LOCK_INIT(sc, device_get_nameunit(dev)); j = 0; switch (ISA_PNP_PROBE(device_get_parent(dev), dev, le_isa_ids)) { case 0: lesc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &j, RF_ACTIVE); rap = PCNET_RAP; rdp = PCNET_RDP; macstart = 0; macstride = 1; break; case ENOENT: for (i = 0; i < nitems(le_isa_params); i++) { if (le_isa_probe_legacy(dev, &le_isa_params[i]) == 0) { lesc->sc_rres = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &j, le_isa_params[i].iosize, RF_ACTIVE); rap = le_isa_params[i].rap; rdp = le_isa_params[i].rdp; macstart = le_isa_params[i].macstart; macstride = le_isa_params[i].macstride; goto found; } } /* FALLTHROUGH */ case ENXIO: default: device_printf(dev, "cannot determine chip\n"); error = ENXIO; goto fail_mtx; } found: if (lesc->sc_rres == NULL) { device_printf(dev, "cannot allocate registers\n"); error = ENXIO; goto fail_mtx; } lesc->sc_rap = rap; lesc->sc_rdp = rdp; i = 0; if ((lesc->sc_dres = bus_alloc_resource_any(dev, SYS_RES_DRQ, &i, RF_ACTIVE)) == NULL) { device_printf(dev, "cannot allocate DMA channel\n"); error = ENXIO; goto fail_rres; } i = 0; if ((lesc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &i, RF_SHAREABLE | RF_ACTIVE)) == NULL) { device_printf(dev, "cannot allocate interrupt\n"); error = ENXIO; goto fail_dres; } error = bus_dma_tag_create( bus_get_dma_tag(dev), /* parent */ 1, 0, /* alignment, boundary */ BUS_SPACE_MAXADDR_24BIT, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ BUS_SPACE_MAXSIZE_32BIT, /* maxsize */ 0, /* nsegments */ BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ 0, /* flags */ NULL, NULL, /* lockfunc, lockarg */ &lesc->sc_pdmat); if (error != 0) { device_printf(dev, "cannot allocate parent DMA tag\n"); goto fail_ires; } sc->sc_memsize = LE_ISA_MEMSIZE; /* * For Am79C90, Am79C961 and Am79C961A the init block must be 2-byte * aligned and the ring descriptors must be 8-byte aligned. */ error = bus_dma_tag_create( lesc->sc_pdmat, /* parent */ 8, 0, /* alignment, boundary */ BUS_SPACE_MAXADDR_24BIT, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ sc->sc_memsize, /* maxsize */ 1, /* nsegments */ sc->sc_memsize, /* maxsegsize */ 0, /* flags */ NULL, NULL, /* lockfunc, lockarg */ &lesc->sc_dmat); if (error != 0) { device_printf(dev, "cannot allocate buffer DMA tag\n"); goto fail_pdtag; } error = bus_dmamem_alloc(lesc->sc_dmat, (void **)&sc->sc_mem, BUS_DMA_WAITOK | BUS_DMA_COHERENT, &lesc->sc_dmam); if (error != 0) { device_printf(dev, "cannot allocate DMA buffer memory\n"); goto fail_dtag; } sc->sc_addr = 0; error = bus_dmamap_load(lesc->sc_dmat, lesc->sc_dmam, sc->sc_mem, sc->sc_memsize, le_isa_dma_callback, sc, 0); if (error != 0 || sc->sc_addr == 0) { device_printf(dev, "cannot load DMA buffer map\n"); goto fail_dmem; } isa_dmacascade(rman_get_start(lesc->sc_dres)); sc->sc_flags = 0; sc->sc_conf3 = 0; /* * Extract the physical MAC address from the ROM. */ for (i = 0; i < sizeof(sc->sc_enaddr); i++) sc->sc_enaddr[i] = bus_read_1(lesc->sc_rres, macstart + i * macstride); sc->sc_copytodesc = lance_copytobuf_contig; sc->sc_copyfromdesc = lance_copyfrombuf_contig; sc->sc_copytobuf = lance_copytobuf_contig; sc->sc_copyfrombuf = lance_copyfrombuf_contig; sc->sc_zerobuf = lance_zerobuf_contig; sc->sc_rdcsr = le_isa_rdcsr; sc->sc_wrcsr = le_isa_wrcsr; sc->sc_hwreset = NULL; sc->sc_hwinit = NULL; sc->sc_hwintr = NULL; sc->sc_nocarrier = NULL; sc->sc_mediachange = NULL; sc->sc_mediastatus = NULL; sc->sc_supmedia = NULL; error = am7990_config(&lesc->sc_am7990, device_get_name(dev), device_get_unit(dev)); if (error != 0) { device_printf(dev, "cannot attach Am7990\n"); goto fail_dmap; } error = bus_setup_intr(dev, lesc->sc_ires, INTR_TYPE_NET | INTR_MPSAFE, NULL, am7990_intr, sc, &lesc->sc_ih); if (error != 0) { device_printf(dev, "cannot set up interrupt\n"); goto fail_am7990; } return (0); fail_am7990: am7990_detach(&lesc->sc_am7990); fail_dmap: bus_dmamap_unload(lesc->sc_dmat, lesc->sc_dmam); fail_dmem: bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam); fail_dtag: bus_dma_tag_destroy(lesc->sc_dmat); fail_pdtag: bus_dma_tag_destroy(lesc->sc_pdmat); fail_ires: bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(lesc->sc_ires), lesc->sc_ires); fail_dres: bus_release_resource(dev, SYS_RES_DRQ, rman_get_rid(lesc->sc_dres), lesc->sc_dres); fail_rres: bus_release_resource(dev, SYS_RES_IOPORT, rman_get_rid(lesc->sc_rres), lesc->sc_rres); fail_mtx: LE_LOCK_DESTROY(sc); return (error); } static int le_isa_detach(device_t dev) { struct le_isa_softc *lesc; struct lance_softc *sc; lesc = device_get_softc(dev); sc = &lesc->sc_am7990.lsc; bus_teardown_intr(dev, lesc->sc_ires, lesc->sc_ih); am7990_detach(&lesc->sc_am7990); bus_dmamap_unload(lesc->sc_dmat, lesc->sc_dmam); bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam); bus_dma_tag_destroy(lesc->sc_dmat); bus_dma_tag_destroy(lesc->sc_pdmat); bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(lesc->sc_ires), lesc->sc_ires); bus_release_resource(dev, SYS_RES_DRQ, rman_get_rid(lesc->sc_dres), lesc->sc_dres); bus_release_resource(dev, SYS_RES_IOPORT, rman_get_rid(lesc->sc_rres), lesc->sc_rres); LE_LOCK_DESTROY(sc); return (0); } static int le_isa_suspend(device_t dev) { struct le_isa_softc *lesc; lesc = device_get_softc(dev); lance_suspend(&lesc->sc_am7990.lsc); return (0); } static int le_isa_resume(device_t dev) { struct le_isa_softc *lesc; lesc = device_get_softc(dev); lance_resume(&lesc->sc_am7990.lsc); return (0); } + +DEFINE_CLASS_0(le, le_isa_driver, le_isa_methods, sizeof(struct le_isa_softc)); +DRIVER_MODULE(le, isa, le_isa_driver, le_devclass, 0, 0); +MODULE_DEPEND(le, ether, 1, 1, 1); +ISA_PNP_INFO(le_isa_ids); Index: head/sys/dev/mse/mse_isa.c =================================================================== --- head/sys/dev/mse/mse_isa.c (revision 327101) +++ head/sys/dev/mse/mse_isa.c (revision 327102) @@ -1,392 +1,393 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2004 M. Warner Losh * 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. * * $FreeBSD$ */ /*- * Copyright 1992 by the University of Guelph * * Permission to use, copy and modify this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation. * University of Guelph makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ /* * Driver for the Logitech and ATI Inport Bus mice for use with 386bsd and * the X386 port, courtesy of * Rick Macklem, rick@snowhite.cis.uoguelph.ca * Caveats: The driver currently uses spltty(), but doesn't use any * generic tty code. It could use splmse() (that only masks off the * bus mouse interrupt, but that would require hacking in i386/isa/icu.s. * (This may be worth the effort, since the Logitech generates 30/60 * interrupts/sec continuously while it is open.) * NB: The ATI has NOT been tested yet! */ /* * Modification history: * Sep 6, 1994 -- Lars Fredriksen(fredriks@mcs.com) * improved probe based on input from Logitech. * * Oct 19, 1992 -- E. Stark (stark@cs.sunysb.edu) * fixes to make it work with Microsoft InPort busmouse * * Jan, 1993 -- E. Stark (stark@cs.sunysb.edu) * added patches for new "select" interface * * May 4, 1993 -- E. Stark (stark@cs.sunysb.edu) * changed position of some spl()'s in mseread * * October 8, 1993 -- E. Stark (stark@cs.sunysb.edu) * limit maximum negative x/y value to -127 to work around XFree problem * that causes spurious button pushes. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int mse_isa_probe(device_t dev); static int mse_isa_attach(device_t dev); static device_method_t mse_methods[] = { DEVMETHOD(device_probe, mse_isa_probe), DEVMETHOD(device_attach, mse_isa_attach), DEVMETHOD(device_detach, mse_detach), { 0, 0 } }; static driver_t mse_driver = { "mse", mse_methods, sizeof(mse_softc_t), }; -DRIVER_MODULE(mse, isa, mse_driver, mse_devclass, 0, 0); - static struct isa_pnp_id mse_ids[] = { { 0x000fd041, "Bus mouse" }, /* PNP0F00 */ { 0x020fd041, "InPort mouse" }, /* PNP0F02 */ { 0x0d0fd041, "InPort mouse compatible" }, /* PNP0F0D */ { 0x110fd041, "Bus mouse compatible" }, /* PNP0F11 */ { 0x150fd041, "Logitech bus mouse" }, /* PNP0F15 */ { 0x180fd041, "Logitech bus mouse compatible" },/* PNP0F18 */ { 0 } }; /* * Logitech bus mouse definitions */ #define MSE_SETUP 0x91 /* What does this mean? */ /* The definition for the control port */ /* is as follows: */ /* D7 = Mode set flag (1 = active) */ /* D6,D5 = Mode selection (port A) */ /* 00 = Mode 0 = Basic I/O */ /* 01 = Mode 1 = Strobed I/O */ /* 10 = Mode 2 = Bi-dir bus */ /* D4 = Port A direction (1 = input)*/ /* D3 = Port C (upper 4 bits) */ /* direction. (1 = input) */ /* D2 = Mode selection (port B & C) */ /* 0 = Mode 0 = Basic I/O */ /* 1 = Mode 1 = Strobed I/O */ /* D1 = Port B direction (1 = input)*/ /* D0 = Port C (lower 4 bits) */ /* direction. (1 = input) */ /* So 91 means Basic I/O on all 3 ports,*/ /* Port A is an input port, B is an */ /* output port, C is split with upper */ /* 4 bits being an output port and lower*/ /* 4 bits an input port, and enable the */ /* sucker. */ /* Courtesy Intel 8255 databook. Lars */ #define MSE_HOLD 0x80 #define MSE_RXLOW 0x00 #define MSE_RXHIGH 0x20 #define MSE_RYLOW 0x40 #define MSE_RYHIGH 0x60 #define MSE_DISINTR 0x10 #define MSE_INTREN 0x00 static int mse_probelogi(device_t dev, mse_softc_t *sc); static void mse_disablelogi(struct resource *port); static void mse_getlogi(struct resource *port, int *dx, int *dy, int *but); static void mse_enablelogi(struct resource *port); /* * ATI Inport mouse definitions */ #define MSE_INPORT_RESET 0x80 #define MSE_INPORT_STATUS 0x00 #define MSE_INPORT_DX 0x01 #define MSE_INPORT_DY 0x02 #define MSE_INPORT_MODE 0x07 #define MSE_INPORT_HOLD 0x20 #define MSE_INPORT_INTREN 0x09 static int mse_probeati(device_t dev, mse_softc_t *sc); static void mse_enableati(struct resource *port); static void mse_disableati(struct resource *port); static void mse_getati(struct resource *port, int *dx, int *dy, int *but); static struct mse_types mse_types[] = { { MSE_ATIINPORT, mse_probeati, mse_enableati, mse_disableati, mse_getati, { 2, MOUSE_IF_INPORT, MOUSE_MOUSE, MOUSE_MODEL_GENERIC, 0, }, { MOUSE_PROTO_INPORT, -1, -1, 0, 0, MOUSE_MSC_PACKETSIZE, { MOUSE_MSC_SYNCMASK, MOUSE_MSC_SYNC, }, }, }, { MSE_LOGITECH, mse_probelogi, mse_enablelogi, mse_disablelogi, mse_getlogi, { 2, MOUSE_IF_BUS, MOUSE_MOUSE, MOUSE_MODEL_GENERIC, 0, }, { MOUSE_PROTO_BUS, -1, -1, 0, 0, MOUSE_MSC_PACKETSIZE, { MOUSE_MSC_SYNCMASK, MOUSE_MSC_SYNC, }, }, }, { 0, }, }; static int mse_isa_probe(device_t dev) { mse_softc_t *sc; int error; int rid; int i; /* check PnP IDs */ error = ISA_PNP_PROBE(device_get_parent(dev), dev, mse_ids); if (error == ENXIO) return error; sc = device_get_softc(dev); rid = 0; sc->sc_port = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &rid, MSE_IOSIZE, RF_ACTIVE); if (sc->sc_port == NULL) return ENXIO; /* * Check for each mouse type in the table. */ i = 0; while (mse_types[i].m_type) { if ((*mse_types[i].m_probe)(dev, sc)) { sc->sc_mousetype = mse_types[i].m_type; sc->sc_enablemouse = mse_types[i].m_enable; sc->sc_disablemouse = mse_types[i].m_disable; sc->sc_getmouse = mse_types[i].m_get; sc->hw = mse_types[i].m_hw; sc->mode = mse_types[i].m_mode; bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->sc_port); device_set_desc(dev, "Bus/InPort Mouse"); return 0; } i++; } bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->sc_port); return ENXIO; } static int mse_isa_attach(device_t dev) { mse_softc_t *sc; int rid; sc = device_get_softc(dev); rid = 0; sc->sc_port = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &rid, MSE_IOSIZE, RF_ACTIVE); if (sc->sc_port == NULL) return ENXIO; return (mse_common_attach(dev)); } /* * Routines for the Logitech mouse. */ /* * Test for a Logitech bus mouse and return 1 if it is. * (until I know how to use the signature port properly, just disable * interrupts and return 1) */ static int mse_probelogi(device_t dev, mse_softc_t *sc) { int sig; bus_write_1(sc->sc_port, MSE_PORTD, MSE_SETUP); /* set the signature port */ bus_write_1(sc->sc_port, MSE_PORTB, MSE_LOGI_SIG); DELAY(30000); /* 30 ms delay */ sig = bus_read_1(sc->sc_port, MSE_PORTB) & 0xFF; if (sig == MSE_LOGI_SIG) { bus_write_1(sc->sc_port, MSE_PORTC, MSE_DISINTR); return(1); } else { if (bootverbose) device_printf(dev, "wrong signature %x\n", sig); return(0); } } /* * Initialize Logitech mouse and enable interrupts. */ static void mse_enablelogi(struct resource *port) { int dx, dy, but; bus_write_1(port, MSE_PORTD, MSE_SETUP); mse_getlogi(port, &dx, &dy, &but); } /* * Disable interrupts for Logitech mouse. */ static void mse_disablelogi(struct resource *port) { bus_write_1(port, MSE_PORTC, MSE_DISINTR); } /* * Get the current dx, dy and button up/down state. */ static void mse_getlogi(struct resource *port, int *dx, int *dy, int *but) { char x, y; bus_write_1(port, MSE_PORTC, MSE_HOLD | MSE_RXLOW); x = bus_read_1(port, MSE_PORTA); *but = (x >> 5) & MOUSE_MSC_BUTTONS; x &= 0xf; bus_write_1(port, MSE_PORTC, MSE_HOLD | MSE_RXHIGH); x |= (bus_read_1(port, MSE_PORTA) << 4); bus_write_1(port, MSE_PORTC, MSE_HOLD | MSE_RYLOW); y = (bus_read_1(port, MSE_PORTA) & 0xf); bus_write_1(port, MSE_PORTC, MSE_HOLD | MSE_RYHIGH); y |= (bus_read_1(port, MSE_PORTA) << 4); *dx = x; *dy = y; bus_write_1(port, MSE_PORTC, MSE_INTREN); } /* * Routines for the ATI Inport bus mouse. */ /* * Test for an ATI Inport bus mouse and return 1 if it is. * (do not enable interrupts) */ static int mse_probeati(device_t dev, mse_softc_t *sc) { int i; for (i = 0; i < 2; i++) if (bus_read_1(sc->sc_port, MSE_PORTC) == 0xde) return (1); return (0); } /* * Initialize ATI Inport mouse and enable interrupts. */ static void mse_enableati(struct resource *port) { bus_write_1(port, MSE_PORTA, MSE_INPORT_RESET); bus_write_1(port, MSE_PORTA, MSE_INPORT_MODE); bus_write_1(port, MSE_PORTB, MSE_INPORT_INTREN); } /* * Disable interrupts for ATI Inport mouse. */ static void mse_disableati(struct resource *port) { bus_write_1(port, MSE_PORTA, MSE_INPORT_MODE); bus_write_1(port, MSE_PORTB, 0); } /* * Get current dx, dy and up/down button state. */ static void mse_getati(struct resource *port, int *dx, int *dy, int *but) { char byte; bus_write_1(port, MSE_PORTA, MSE_INPORT_MODE); bus_write_1(port, MSE_PORTB, MSE_INPORT_HOLD); bus_write_1(port, MSE_PORTA, MSE_INPORT_STATUS); *but = ~bus_read_1(port, MSE_PORTB) & MOUSE_MSC_BUTTONS; bus_write_1(port, MSE_PORTA, MSE_INPORT_DX); byte = bus_read_1(port, MSE_PORTB); *dx = byte; bus_write_1(port, MSE_PORTA, MSE_INPORT_DY); byte = bus_read_1(port, MSE_PORTB); *dy = byte; bus_write_1(port, MSE_PORTA, MSE_INPORT_MODE); bus_write_1(port, MSE_PORTB, MSE_INPORT_INTREN); } + +DRIVER_MODULE(mse, isa, mse_driver, mse_devclass, 0, 0); +ISA_PNP_INFO(mse_ids); Index: head/sys/dev/pccard/pccardvar.h =================================================================== --- head/sys/dev/pccard/pccardvar.h (revision 327101) +++ head/sys/dev/pccard/pccardvar.h (revision 327102) @@ -1,263 +1,263 @@ /* $NetBSD: pcmciavar.h,v 1.12 2000/02/08 12:51:31 enami Exp $ */ /* $FreeBSD$ */ /*- * SPDX-License-Identifier: BSD-4-Clause * * Copyright (c) 1997 Marc Horowitz. 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 Marc Horowitz. * 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 * 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. */ /* * Contains information about mapped/allocated i/o spaces. */ struct pccard_io_handle { bus_space_tag_t iot; /* bus space tag (from chipset) */ bus_space_handle_t ioh; /* mapped space handle */ bus_addr_t addr; /* resulting address in bus space */ bus_size_t size; /* size of i/o space */ int flags; /* misc. information */ int width; }; #define PCCARD_IO_ALLOCATED 0x01 /* i/o space was allocated */ /* * Contains information about allocated memory space. */ struct pccard_mem_handle { bus_space_tag_t memt; /* bus space tag (from chipset) */ bus_space_handle_t memh; /* mapped space handle */ bus_addr_t addr; /* resulting address in bus space */ bus_size_t size; /* size of mem space */ bus_size_t realsize; /* how much we really allocated */ bus_addr_t cardaddr; /* Absolute address on card */ int kind; }; /* Bits for kind */ #define PCCARD_MEM_16BIT 1 /* 1 -> 16bit 0 -> 8bit */ #define PCCARD_MEM_ATTR 2 /* 1 -> attribute mem 0 -> common */ #define PCCARD_WIDTH_AUTO 0 #define PCCARD_WIDTH_IO8 1 #define PCCARD_WIDTH_IO16 2 struct pccard_tuple { unsigned int code; unsigned int length; u_long mult; /* dist btn successive bytes */ bus_addr_t ptr; bus_space_tag_t memt; bus_space_handle_t memh; }; typedef int (*pccard_scan_t)(const struct pccard_tuple *, void *); struct pccard_product { const char *pp_name; #define PCCARD_VENDOR_ANY (0xffffffff) uint32_t pp_vendor; /* 0 == end of table */ #define PCCARD_PRODUCT_ANY (0xffffffff) uint32_t pp_product; const char *pp_cis[4]; }; /** * Note: There's no cis3 or cis4 reported for NOMATCH / pnpinfo events for * pccard It's unclear if we actually need that for automatic loading or * not. These stirngs are informative, according to the standard. Some Linux * drivers match on them, for example. However, FreeBSD's hardware probing is a * little different than Linux so it turns out we don't need them. Some cards * use CIS3 or CIS4 for a textual representation of the MAC address. In short, * they aren't needed even though our friends in Linux have them. It is my * belief that all the entries in Linux don't actually need to be separate there * either, but it's hard to eliminate them and retest on old, possibly rare, * hardware so they persist. Despite years of collecting ~300 different PC Cards * off E-Bay, I've not been able to find any that need CIS3/CIS4 to select which * device attaches. */ #define PCCARD_PNP_DESCR "D:#;V32:manufacturer;V32:product;Z:cisvendor;Z:cisproduct;" #define PCCARD_PNP_INFO(t) \ - MODULE_PNP_INFO(PCCARD_PNP_DESCR, pccard, t, t, sizeof(t[0]), sizeof(t) / sizeof(t[0]) - 1); \ + MODULE_PNP_INFO(PCCARD_PNP_DESCR, pccard, t, t, sizeof(t[0]), nitems(t) - 1); \ typedef int (*pccard_product_match_fn) (device_t dev, const struct pccard_product *ent, int vpfmatch); #include "card_if.h" /* * make this inline so that we don't have to worry about dangling references * to it in the modules or the code. */ static inline const struct pccard_product * pccard_product_lookup(device_t dev, const struct pccard_product *tab, size_t ent_size, pccard_product_match_fn matchfn) { return CARD_DO_PRODUCT_LOOKUP(device_get_parent(dev), dev, tab, ent_size, matchfn); } #define pccard_cis_read_1(tuple, idx0) \ (bus_space_read_1((tuple)->memt, (tuple)->memh, (tuple)->mult*(idx0))) #define pccard_tuple_read_1(tuple, idx1) \ (pccard_cis_read_1((tuple), ((tuple)->ptr+(2+(idx1))))) #define pccard_tuple_read_2(tuple, idx2) \ (pccard_tuple_read_1((tuple), (idx2)) | \ (pccard_tuple_read_1((tuple), (idx2)+1)<<8)) #define pccard_tuple_read_3(tuple, idx3) \ (pccard_tuple_read_1((tuple), (idx3)) | \ (pccard_tuple_read_1((tuple), (idx3)+1)<<8) | \ (pccard_tuple_read_1((tuple), (idx3)+2)<<16)) #define pccard_tuple_read_4(tuple, idx4) \ (pccard_tuple_read_1((tuple), (idx4)) | \ (pccard_tuple_read_1((tuple), (idx4)+1)<<8) | \ (pccard_tuple_read_1((tuple), (idx4)+2)<<16) | \ (pccard_tuple_read_1((tuple), (idx4)+3)<<24)) #define pccard_tuple_read_n(tuple, n, idxn) \ (((n)==1)?pccard_tuple_read_1((tuple), (idxn)) : \ (((n)==2)?pccard_tuple_read_2((tuple), (idxn)) : \ (((n)==3)?pccard_tuple_read_3((tuple), (idxn)) : \ /* n == 4 */ pccard_tuple_read_4((tuple), (idxn))))) #define PCCARD_SPACE_MEMORY 1 #define PCCARD_SPACE_IO 2 #define pccard_mfc(sc) \ (STAILQ_FIRST(&(sc)->card.pf_head) && \ STAILQ_NEXT(STAILQ_FIRST(&(sc)->card.pf_head),pf_list)) /* Convenience functions */ static inline int pccard_cis_scan(device_t dev, pccard_scan_t fct, void *arg) { return (CARD_CIS_SCAN(device_get_parent(dev), dev, fct, arg)); } static inline int pccard_attr_read_1(device_t dev, uint32_t offset, uint8_t *val) { return (CARD_ATTR_READ(device_get_parent(dev), dev, offset, val)); } static inline int pccard_attr_write_1(device_t dev, uint32_t offset, uint8_t val) { return (CARD_ATTR_WRITE(device_get_parent(dev), dev, offset, val)); } static inline int pccard_ccr_read_1(device_t dev, uint32_t offset, uint8_t *val) { return (CARD_CCR_READ(device_get_parent(dev), dev, offset, val)); } static inline int pccard_ccr_write_1(device_t dev, uint32_t offset, uint8_t val) { return (CARD_CCR_WRITE(device_get_parent(dev), dev, offset, val)); } /* Hack */ int pccard_select_cfe(device_t dev, int entry); /* ivar interface */ enum { PCCARD_IVAR_ETHADDR, /* read ethernet address from CIS tupple */ PCCARD_IVAR_VENDOR, PCCARD_IVAR_PRODUCT, PCCARD_IVAR_PRODEXT, PCCARD_IVAR_FUNCTION_NUMBER, PCCARD_IVAR_VENDOR_STR, /* CIS string for "Manufacturer" */ PCCARD_IVAR_PRODUCT_STR,/* CIS string for "Product" */ PCCARD_IVAR_CIS3_STR, PCCARD_IVAR_CIS4_STR, PCCARD_IVAR_FUNCTION, PCCARD_IVAR_FUNCE_DISK }; #define PCCARD_ACCESSOR(A, B, T) \ static inline int \ pccard_get_ ## A(device_t dev, T *t) \ { \ return BUS_READ_IVAR(device_get_parent(dev), dev, \ PCCARD_IVAR_ ## B, (uintptr_t *) t); \ } PCCARD_ACCESSOR(ether, ETHADDR, uint8_t) PCCARD_ACCESSOR(vendor, VENDOR, uint32_t) PCCARD_ACCESSOR(product, PRODUCT, uint32_t) PCCARD_ACCESSOR(prodext, PRODEXT, uint16_t) PCCARD_ACCESSOR(function_number,FUNCTION_NUMBER, uint32_t) PCCARD_ACCESSOR(function, FUNCTION, uint32_t) PCCARD_ACCESSOR(funce_disk, FUNCE_DISK, uint16_t) PCCARD_ACCESSOR(vendor_str, VENDOR_STR, const char *) PCCARD_ACCESSOR(product_str, PRODUCT_STR, const char *) PCCARD_ACCESSOR(cis3_str, CIS3_STR, const char *) PCCARD_ACCESSOR(cis4_str, CIS4_STR, const char *) /* shared memory flags */ enum { PCCARD_A_MEM_COM, /* common */ PCCARD_A_MEM_ATTR, /* attribute */ PCCARD_A_MEM_8BIT, /* 8 bit */ PCCARD_A_MEM_16BIT /* 16 bit */ }; #define PCCARD_S(a, b) PCMCIA_STR_ ## a ## _ ## b #define PCCARD_P(a, b) PCMCIA_PRODUCT_ ## a ## _ ## b #define PCCARD_C(a, b) PCMCIA_CIS_ ## a ## _ ## b #define PCMCIA_CARD_D(v, p) { PCCARD_S(v, p), PCMCIA_VENDOR_ ## v, \ PCCARD_P(v, p), PCCARD_C(v, p) } #define PCMCIA_CARD(v, p) { PCCARD_S(v, p), PCMCIA_VENDOR_ ## v, \ PCCARD_P(v, p), PCCARD_C(v, p) } /* * Defines to decode the get_funce_disk return value. See the PCMCIA standard * for all the details of what these bits mean. */ #define PFD_I_V_MASK 0x3 #define PFD_I_V_NONE_REQUIRED 0x0 #define PFD_I_V_REQ_MOD_ACC 0x1 #define PFD_I_V_REQ_ACC 0x2 #define PFD_I_V_REQ_ALWYS 0x1 #define PFD_I_S 0x4 /* 0 rotating, 1 silicon */ #define PFD_I_U 0x8 /* SN Uniq? */ #define PFD_I_D 0x10 /* 0 - 1 drive, 1 - 2 drives */ #define PFD_P_P0 0x100 #define PFD_P_P1 0x200 #define PFD_P_P2 0x400 #define PFD_P_P3 0x800 #define PFD_P_N 0x1000 /* 3f7/377 excluded? */ #define PFD_P_E 0x2000 /* Index bit supported? */ #define PFD_P_I 0x4000 /* twincard */ Index: head/sys/dev/pccbb/pccbb_isa.c =================================================================== --- head/sys/dev/pccbb/pccbb_isa.c (revision 327101) +++ head/sys/dev/pccbb/pccbb_isa.c (revision 327102) @@ -1,257 +1,257 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2002-2004 M. Warner Losh. * 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. */ /* * Driver for ISA to PCMCIA bridges compliant with the Intel ExCA * specification. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "power_if.h" #include "card_if.h" /***************************************************************************** * Configurable parameters. *****************************************************************************/ /* sysctl vars */ static SYSCTL_NODE(_hw, OID_AUTO, pcic, CTLFLAG_RD, 0, "PCIC parameters"); static int isa_intr_mask = EXCA_INT_MASK_ALLOWED; SYSCTL_INT(_hw_pcic, OID_AUTO, intr_mask, CTLFLAG_RDTUN, &isa_intr_mask, 0, "Mask of allowable interrupts for this laptop. The default is generally" " correct, but some laptops do not route all the IRQ pins to the bridge to" " save wires. Sometimes you need a more restrictive mask because some of" " the hardware in your laptop may not have a driver so its IRQ might not be" " allocated."); /* * CL-PD6722's VSENSE method * 0: NO VSENSE (assume a 5.0V card always) * 1: 6710's method (default) * 2: 6729's method */ int pcic_pd6722_vsense = 1; SYSCTL_INT(_hw_pcic, OID_AUTO, pd6722_vsense, CTLFLAG_RDTUN, &pcic_pd6722_vsense, 1, "Select CL-PD6722's VSENSE method. VSENSE is used to determine the" " voltage of inserted cards. The CL-PD6722 has two methods to determine" " the voltage of the card. 0 means assume a 5.0V card and do not check. 1" " means use the same method that the CL-PD6710 uses (default). 2 means use" " the same method as the CL-PD6729. 2 is documented in the datasheet as" " being the correct way, but 1 seems to give better results on more" " laptops."); /***************************************************************************** * End of configurable parameters. *****************************************************************************/ #define DPRINTF(x) do { if (cbb_debug) printf x; } while (0) #define DEVPRINTF(x) do { if (cbb_debug) device_printf x; } while (0) -/* XXX Not sure that PNP0E03 should be claimed, except maybe on pc98 */ static struct isa_pnp_id pcic_ids[] = { {EXCA_PNP_ACTIONTEC, NULL}, /* AEI0218 */ {EXCA_PNP_IBM3765, NULL}, /* IBM3765 */ {EXCA_PNP_82365, NULL}, /* PNP0E00 */ {EXCA_PNP_CL_PD6720, NULL}, /* PNP0E01 */ {EXCA_PNP_VLSI_82C146, NULL}, /* PNP0E02 */ {EXCA_PNP_82365_CARDBUS, NULL}, /* PNP0E03 */ {EXCA_PNP_SCM_SWAPBOX, NULL}, /* SCM0469 */ {0} }; /************************************************************************/ /* Probe/Attach */ /************************************************************************/ static int cbb_isa_activate(device_t dev) { struct cbb_softc *sc = device_get_softc(dev); struct resource *res; int rid; int i; /* A little bogus, but go ahead and get the irq for CSC events */ rid = 0; res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); if (res == NULL) { /* * No IRQ specified, find one. This can be due to the PnP * data not specifying any IRQ, or the default kernel not * assinging an IRQ. */ for (i = 0; i < 16 && res == NULL; i++) { if (((1 << i) & isa_intr_mask) == 0) continue; res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, i, i, 1, RF_ACTIVE); } } if (res == NULL) return (ENXIO); sc->irq_res = res; rid = 0; res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); if (res == NULL) { bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); sc->irq_res = NULL; device_printf(dev, "Cannot allocate I/O\n"); return (ENOMEM); } sc->bst = rman_get_bustag(res); sc->bsh = rman_get_bushandle(res); sc->base_res = res; return (0); } static void cbb_isa_deactivate(device_t dev) { struct cbb_softc *sc = device_get_softc(dev); if (sc->irq_res) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); sc->irq_res = NULL; if (sc->base_res) bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->base_res); sc->base_res = NULL; } static int cbb_isa_probe(device_t dev) { int error; struct cbb_softc *sc = device_get_softc(dev); /* Check isapnp ids */ error = ISA_PNP_PROBE(device_get_parent(dev), dev, pcic_ids); if (error != 0 && error != ENOENT) return (error); error = cbb_isa_activate(dev); if (error != 0) return (error); /* Check to make sure that we have actual hardware */ error = exca_probe_slots(dev, &sc->exca[0], sc->bst, sc->bsh); cbb_isa_deactivate(dev); return (error); } static int cbb_isa_attach(device_t dev) { return (ENOMEM); } static int cbb_isa_suspend(device_t dev) { return (0); } static int cbb_isa_resume(device_t dev) { return (0); } static device_method_t cbb_methods[] = { /* Device interface */ DEVMETHOD(device_probe, cbb_isa_probe), DEVMETHOD(device_attach, cbb_isa_attach), DEVMETHOD(device_detach, cbb_detach), DEVMETHOD(device_suspend, cbb_isa_suspend), DEVMETHOD(device_resume, cbb_isa_resume), /* bus methods */ DEVMETHOD(bus_read_ivar, cbb_read_ivar), DEVMETHOD(bus_write_ivar, cbb_write_ivar), DEVMETHOD(bus_alloc_resource, cbb_alloc_resource), DEVMETHOD(bus_release_resource, cbb_release_resource), DEVMETHOD(bus_activate_resource, cbb_activate_resource), DEVMETHOD(bus_deactivate_resource, cbb_deactivate_resource), DEVMETHOD(bus_driver_added, cbb_driver_added), DEVMETHOD(bus_child_detached, cbb_child_detached), DEVMETHOD(bus_setup_intr, cbb_setup_intr), DEVMETHOD(bus_teardown_intr, cbb_teardown_intr), DEVMETHOD(bus_child_present, cbb_child_present), /* 16-bit card interface */ DEVMETHOD(card_set_res_flags, cbb_pcic_set_res_flags), DEVMETHOD(card_set_memory_offset, cbb_pcic_set_memory_offset), /* power interface */ DEVMETHOD(power_enable_socket, cbb_power_enable_socket), DEVMETHOD(power_disable_socket, cbb_power_disable_socket), DEVMETHOD_END }; static driver_t cbb_isa_driver = { "cbb", cbb_methods, sizeof(struct cbb_softc) }; DRIVER_MODULE(cbb, isa, cbb_isa_driver, cbb_devclass, 0, 0); MODULE_DEPEND(cbb, exca, 1, 1, 1); +ISA_PNP_INFO(pcic_ids); Index: head/sys/dev/ppc/ppc_isa.c =================================================================== --- head/sys/dev/ppc/ppc_isa.c (revision 327101) +++ head/sys/dev/ppc/ppc_isa.c (revision 327102) @@ -1,276 +1,277 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 1997-2000 Nicolas Souchu * Copyright (c) 2001 Alcove - Nicolas Souchu * 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ppbus_if.h" static int ppc_isa_probe(device_t dev); int ppc_isa_attach(device_t dev); int ppc_isa_write(device_t, char *, int, int); static device_method_t ppc_isa_methods[] = { /* device interface */ DEVMETHOD(device_probe, ppc_isa_probe), DEVMETHOD(device_attach, ppc_isa_attach), DEVMETHOD(device_detach, ppc_detach), /* bus interface */ DEVMETHOD(bus_read_ivar, ppc_read_ivar), DEVMETHOD(bus_write_ivar, ppc_write_ivar), DEVMETHOD(bus_alloc_resource, ppc_alloc_resource), DEVMETHOD(bus_release_resource, ppc_release_resource), /* ppbus interface */ DEVMETHOD(ppbus_io, ppc_io), DEVMETHOD(ppbus_exec_microseq, ppc_exec_microseq), DEVMETHOD(ppbus_reset_epp, ppc_reset_epp), DEVMETHOD(ppbus_setmode, ppc_setmode), DEVMETHOD(ppbus_ecp_sync, ppc_ecp_sync), DEVMETHOD(ppbus_read, ppc_read), DEVMETHOD(ppbus_write, ppc_isa_write), { 0, 0 } }; static driver_t ppc_isa_driver = { ppc_driver_name, ppc_isa_methods, sizeof(struct ppc_data), }; static struct isa_pnp_id lpc_ids[] = { { 0x0004d041, "Standard parallel printer port" }, /* PNP0400 */ { 0x0104d041, "ECP parallel printer port" }, /* PNP0401 */ { 0 } }; static void ppc_isa_dmadone(struct ppc_data *ppc) { isa_dmadone(ppc->ppc_dmaflags, ppc->ppc_dmaddr, ppc->ppc_dmacnt, ppc->ppc_dmachan); } int ppc_isa_attach(device_t dev) { struct ppc_data *ppc = device_get_softc(dev); if ((ppc->ppc_avm & PPB_ECP) && (ppc->ppc_dmachan > 0)) { /* acquire the DMA channel forever */ /* XXX */ isa_dma_acquire(ppc->ppc_dmachan); isa_dmainit(ppc->ppc_dmachan, 1024); /* nlpt.BUFSIZE */ ppc->ppc_dmadone = ppc_isa_dmadone; } return (ppc_attach(dev)); } static int ppc_isa_probe(device_t dev) { device_t parent; int error; parent = device_get_parent(dev); error = ISA_PNP_PROBE(parent, dev, lpc_ids); if (error == ENXIO) return (ENXIO); if (error != 0) /* XXX shall be set after detection */ device_set_desc(dev, "Parallel port"); return (ppc_probe(dev, 0)); } /* * Call this function if you want to send data in any advanced mode * of your parallel port: FIFO, DMA * * If what you want is not possible (no ECP, no DMA...), * EINVAL is returned */ int ppc_isa_write(device_t dev, char *buf, int len, int how) { struct ppc_data *ppc = device_get_softc(dev); char ecr, ecr_sav, ctr, ctr_sav; int error = 0; int spin; PPC_ASSERT_LOCKED(ppc); if (!(ppc->ppc_avm & PPB_ECP)) return (EINVAL); if (ppc->ppc_dmachan == 0) return (EINVAL); #ifdef PPC_DEBUG printf("w"); #endif ecr_sav = r_ecr(ppc); ctr_sav = r_ctr(ppc); /* * Send buffer with DMA, FIFO and interrupts */ /* byte mode, no intr, no DMA, dir=0, flush fifo */ ecr = PPC_ECR_STD | PPC_DISABLE_INTR; w_ecr(ppc, ecr); /* disable nAck interrupts */ ctr = r_ctr(ppc); ctr &= ~IRQENABLE; w_ctr(ppc, ctr); ppc->ppc_dmaflags = 0; ppc->ppc_dmaddr = (caddr_t)buf; ppc->ppc_dmacnt = (u_int)len; switch (ppc->ppc_mode) { case PPB_COMPATIBLE: /* compatible mode with FIFO, no intr, DMA, dir=0 */ ecr = PPC_ECR_FIFO | PPC_DISABLE_INTR | PPC_ENABLE_DMA; break; case PPB_ECP: ecr = PPC_ECR_ECP | PPC_DISABLE_INTR | PPC_ENABLE_DMA; break; default: error = EINVAL; goto error; } w_ecr(ppc, ecr); ecr = r_ecr(ppc); ppc->ppc_dmastat = PPC_DMA_INIT; /* enable interrupts */ ecr &= ~PPC_SERVICE_INTR; ppc->ppc_irqstat = PPC_IRQ_DMA; w_ecr(ppc, ecr); isa_dmastart(ppc->ppc_dmaflags, ppc->ppc_dmaddr, ppc->ppc_dmacnt, ppc->ppc_dmachan); ppc->ppc_dmastat = PPC_DMA_STARTED; #ifdef PPC_DEBUG printf("s%d", ppc->ppc_dmacnt); #endif /* Wait for the DMA completed interrupt. We hope we won't * miss it, otherwise a signal will be necessary to unlock the * process. */ do { /* release CPU */ error = mtx_sleep(ppc, &ppc->ppc_lock, PPBPRI | PCATCH, "ppcdma", 0); } while (error == EWOULDBLOCK); if (error) { #ifdef PPC_DEBUG printf("i"); #endif /* stop DMA */ isa_dmadone(ppc->ppc_dmaflags, ppc->ppc_dmaddr, ppc->ppc_dmacnt, ppc->ppc_dmachan); /* no dma, no interrupt, flush the fifo */ w_ecr(ppc, PPC_ECR_RESET); ppc->ppc_dmastat = PPC_DMA_INTERRUPTED; goto error; } /* wait for an empty fifo */ while (!(r_ecr(ppc) & PPC_FIFO_EMPTY)) { for (spin=100; spin; spin--) if (r_ecr(ppc) & PPC_FIFO_EMPTY) goto fifo_empty; #ifdef PPC_DEBUG printf("Z"); #endif error = mtx_sleep(ppc, &ppc->ppc_lock, PPBPRI | PCATCH, "ppcfifo", hz / 100); if (error != EWOULDBLOCK) { #ifdef PPC_DEBUG printf("I"); #endif /* no dma, no interrupt, flush the fifo */ w_ecr(ppc, PPC_ECR_RESET); ppc->ppc_dmastat = PPC_DMA_INTERRUPTED; error = EINTR; goto error; } } fifo_empty: /* no dma, no interrupt, flush the fifo */ w_ecr(ppc, PPC_ECR_RESET); error: /* PDRQ must be kept unasserted until nPDACK is * deasserted for a minimum of 350ns (SMC datasheet) * * Consequence may be a FIFO that never empty */ DELAY(1); w_ecr(ppc, ecr_sav); w_ctr(ppc, ctr_sav); return (error); } DRIVER_MODULE(ppc, isa, ppc_isa_driver, ppc_devclass, 0, 0); +ISA_PNP_INFO(lpc_ids); Index: head/sys/dev/sbni/if_sbni_isa.c =================================================================== --- head/sys/dev/sbni/if_sbni_isa.c (revision 327101) +++ head/sys/dev/sbni/if_sbni_isa.c (revision 327102) @@ -1,168 +1,168 @@ /*- * Copyright (c) 1997-2001 Granch, Ltd. All rights reserved. * Author: Denis I.Timofeev * * Redistributon 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 unmodified, 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 NEIGENCE 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int sbni_probe_isa(device_t); static int sbni_attach_isa(device_t); static device_method_t sbni_isa_methods[] = { /* Device interface */ DEVMETHOD(device_probe, sbni_probe_isa), DEVMETHOD(device_attach, sbni_attach_isa), { 0, 0 } }; static driver_t sbni_isa_driver = { "sbni", sbni_isa_methods, sizeof(struct sbni_softc) }; static devclass_t sbni_isa_devclass; static struct isa_pnp_id sbni_ids[] = { { 0, NULL } /* we have no pnp sbni cards atm. */ }; -DRIVER_MODULE(sbni, isa, sbni_isa_driver, sbni_isa_devclass, 0, 0); -MODULE_DEPEND(sbni, isa, 1, 1, 1); - static int sbni_probe_isa(device_t dev) { struct sbni_softc *sc; int error; error = ISA_PNP_PROBE(device_get_parent(dev), dev, sbni_ids); if (error && error != ENOENT) return (error); sc = device_get_softc(dev); sc->io_res = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &sc->io_rid, SBNI_PORTS, RF_ACTIVE); if (!sc->io_res) { printf("sbni: cannot allocate io ports!\n"); return (ENOENT); } if (sbni_probe(sc) != 0) { sbni_release_resources(sc); return (ENXIO); } device_set_desc(dev, "Granch SBNI12/ISA adapter"); return (0); } static int sbni_attach_isa(device_t dev) { struct sbni_softc *sc; struct sbni_flags flags; int error; sc = device_get_softc(dev); sc->dev = dev; sc->irq_res = bus_alloc_resource_any( dev, SYS_RES_IRQ, &sc->irq_rid, RF_ACTIVE); #ifndef SBNI_DUAL_COMPOUND if (sc->irq_res == NULL) { device_printf(dev, "irq conflict!\n"); sbni_release_resources(sc); return (ENOENT); } #else /* SBNI_DUAL_COMPOUND */ if (sc->irq_res) { sbni_add(sc); } else { struct sbni_softc *master; if ((master = connect_to_master(sc)) == NULL) { device_printf(dev, "failed to alloc irq\n"); sbni_release_resources(sc); return (ENXIO); } else { device_printf(dev, "shared irq with %s\n", master->ifp->if_xname); } } #endif /* SBNI_DUAL_COMPOUND */ *(u_int32_t*)&flags = device_get_flags(dev); error = sbni_attach(sc, device_get_unit(dev) * 2, flags); if (error) { device_printf(dev, "cannot initialize driver\n"); sbni_release_resources(sc); return (error); } if (sc->irq_res) { error = bus_setup_intr( dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE, NULL, sbni_intr, sc, &sc->irq_handle); if (error) { device_printf(dev, "bus_setup_intr\n"); sbni_detach(sc); sbni_release_resources(sc); return (error); } } return (0); } + +DRIVER_MODULE(sbni, isa, sbni_isa_driver, sbni_isa_devclass, 0, 0); +MODULE_DEPEND(sbni, isa, 1, 1, 1); Index: head/sys/dev/sio/sio_isa.c =================================================================== --- head/sys/dev/sio/sio_isa.c (revision 327101) +++ head/sys/dev/sio/sio_isa.c (revision 327102) @@ -1,177 +1,178 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2001 M. Warner Losh. 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_sio.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int sio_isa_attach(device_t dev); static int sio_isa_probe(device_t dev); static device_method_t sio_isa_methods[] = { /* Device interface */ DEVMETHOD(device_probe, sio_isa_probe), DEVMETHOD(device_attach, sio_isa_attach), DEVMETHOD(device_detach, siodetach), { 0, 0 } }; static driver_t sio_isa_driver = { sio_driver_name, sio_isa_methods, 0, }; static struct isa_pnp_id sio_ids[] = { {0x0005d041, "Standard PC COM port"}, /* PNP0500 */ {0x0105d041, "16550A-compatible COM port"}, /* PNP0501 */ {0x0205d041, "Multiport serial device (non-intelligent 16550)"}, /* PNP0502 */ {0x1005d041, "Generic IRDA-compatible device"}, /* PNP0510 */ {0x1105d041, "Generic IRDA-compatible device"}, /* PNP0511 */ /* Devices that do not have a compatid */ {0x12206804, NULL}, /* ACH2012 - 5634BTS 56K Video Ready Modem */ {0x7602a904, NULL}, /* AEI0276 - 56K v.90 Fax Modem (LKT) */ {0x00007905, NULL}, /* AKY0000 - 56K Plug&Play Modem */ {0x21107905, NULL}, /* AKY1021 - 56K Plug&Play Modem */ {0x01405407, NULL}, /* AZT4001 - AZT3000 PnP SOUND DEVICE, MODEM */ {0x56039008, NULL}, /* BDP0356 - Best Data 56x2 */ {0x56159008, NULL}, /* BDP1556 - B.D. Smart One 56SPS,Voice Modem*/ {0x36339008, NULL}, /* BDP3336 - Best Data Prods. 336F */ {0x0014490a, NULL}, /* BRI1400 - Boca 33.6 PnP */ {0x0015490a, NULL}, /* BRI1500 - Internal Fax Data */ {0x0034490a, NULL}, /* BRI3400 - Internal ACF Modem */ {0x0094490a, NULL}, /* BRI9400 - Boca K56Flex PnP */ {0x00b4490a, NULL}, /* BRIB400 - Boca 56k PnP */ {0x0010320d, NULL}, /* CIR1000 - Cirrus Logic V34 */ {0x0030320d, NULL}, /* CIR3000 - Cirrus Logic V43 */ {0x0100440e, NULL}, /* CRD0001 - Cardinal MVP288IV ? */ {0x01308c0e, NULL}, /* CTL3001 - Creative Labs Phoneblaster */ {0x36033610, NULL}, /* DAV0336 - DAVICOM 336PNP MODEM */ {0x01009416, NULL}, /* ETT0001 - E-Tech Bullet 33k6 PnP */ {0x0000aa1a, NULL}, /* FUJ0000 - FUJITSU Modem 33600 PNP/I2 */ {0x1200c31e, NULL}, /* GVC0012 - VF1128HV-R9 (win modem?) */ {0x0303c31e, NULL}, /* GVC0303 - MaxTech 33.6 PnP D/F/V */ {0x0505c31e, NULL}, /* GVC0505 - GVC 56k Faxmodem */ {0x0116c31e, NULL}, /* GVC1601 - Rockwell V.34 Plug & Play Modem */ {0x0050c31e, NULL}, /* GVC5000 - some GVC modem */ {0x3800f91e, NULL}, /* GWY0038 - Telepath with v.90 */ {0x9062f91e, NULL}, /* GWY6290 - Telepath with x2 Technology */ {0x8100e425, NULL}, /* IOD0081 - I-O DATA DEVICE,INC. IFML-560 */ {0x71004d24, NULL}, /* IBM0071 - IBM ThinkPad 240 IrDA controller*/ {0x21002534, NULL}, /* MAE0021 - Jetstream Int V.90 56k Voice Series 2*/ {0x0000f435, NULL}, /* MOT0000 - Motorola ModemSURFR 33.6 Intern */ {0x5015f435, NULL}, /* MOT1550 - Motorola ModemSURFR 56K Modem */ {0xf015f435, NULL}, /* MOT15F0 - Motorola VoiceSURFR 56K Modem */ {0x6045f435, NULL}, /* MOT4560 - Motorola ? */ {0x61e7a338, NULL}, /* NECE761 - 33.6Modem */ {0x0160633a, NULL}, /* NSC6001 - National Semi's IrDA Controller*/ {0x08804f3f, NULL}, /* OZO8008 - Zoom (33.6k Modem) */ {0x0f804f3f, NULL}, /* OZO800f - Zoom 2812 (56k Modem) */ {0x39804f3f, NULL}, /* OZO8039 - Zoom 56k flex */ {0x00914f3f, NULL}, /* OZO9100 - Zoom 2919 (K56 Faxmodem) */ {0x3024a341, NULL}, /* PMC2430 - Pace 56 Voice Internal Modem */ {0x1000eb49, NULL}, /* ROK0010 - Rockwell ? */ {0x1200b23d, NULL}, /* RSS0012 - OMRON ME5614ISA */ {0x5002734a, NULL}, /* RSS0250 - 5614Jx3(G) Internal Modem */ {0x6202734a, NULL}, /* RSS0262 - 5614Jx3[G] V90+K56Flex Modem */ {0x1010104d, NULL}, /* SHP1010 - Rockwell 33600bps Modem */ {0x10f0a34d, NULL}, /* SMCF010 - SMC IrCC*/ {0xc100ad4d, NULL}, /* SMM00C1 - Leopard 56k PnP */ {0x9012b04e, NULL}, /* SUP1290 - Supra ? */ {0x1013b04e, NULL}, /* SUP1310 - SupraExpress 336i PnP */ {0x8013b04e, NULL}, /* SUP1380 - SupraExpress 288i PnP Voice */ {0x8113b04e, NULL}, /* SUP1381 - SupraExpress 336i PnP Voice */ {0x5016b04e, NULL}, /* SUP1650 - Supra 336i Sp Intl */ {0x7016b04e, NULL}, /* SUP1670 - Supra 336i V+ Intl */ {0x7420b04e, NULL}, /* SUP2070 - Supra ? */ {0x8020b04e, NULL}, /* SUP2080 - Supra ? */ {0x8420b04e, NULL}, /* SUP2084 - SupraExpress 56i PnP */ {0x7121b04e, NULL}, /* SUP2171 - SupraExpress 56i Sp? */ {0x8024b04e, NULL}, /* SUP2480 - Supra ? */ {0x01007256, NULL}, /* USR0001 - U.S. Robotics Inc., Sportster W */ {0x02007256, NULL}, /* USR0002 - U.S. Robotics Inc. Sportster 33. */ {0x04007256, NULL}, /* USR0004 - USR Sportster 14.4k */ {0x06007256, NULL}, /* USR0006 - USR Sportster 33.6k */ {0x11007256, NULL}, /* USR0011 - USR ? */ {0x01017256, NULL}, /* USR0101 - USR ? */ {0x30207256, NULL}, /* USR2030 - U.S.Robotics Inc. Sportster 560 */ {0x50207256, NULL}, /* USR2050 - U.S.Robotics Inc. Sportster 33. */ {0x70207256, NULL}, /* USR2070 - U.S.Robotics Inc. Sportster 560 */ {0x30307256, NULL}, /* USR3030 - U.S. Robotics 56K FAX INT */ {0x31307256, NULL}, /* USR3031 - U.S. Robotics 56K FAX INT */ {0x50307256, NULL}, /* USR3050 - U.S. Robotics 56K FAX INT */ {0x70307256, NULL}, /* USR3070 - U.S. Robotics 56K Voice INT */ {0x90307256, NULL}, /* USR3090 - USR ? */ {0x70917256, NULL}, /* USR9170 - U.S. Robotics 56K FAX INT */ {0x90917256, NULL}, /* USR9190 - USR 56k Voice INT */ {0x04f0235c, NULL}, /* WACF004 - Wacom Tablet PC Screen*/ {0x0300695c, NULL}, /* WCI0003 - Fax/Voice/Modem/Speakphone/Asvd */ {0x01a0896a, NULL}, /* ZTIA001 - Zoom Internal V90 Faxmodem */ {0x61f7896a, NULL}, /* ZTIF761 - Zoom ComStar 33.6 */ {0} }; static int sio_isa_probe(dev) device_t dev; { /* Check isapnp ids */ if (ISA_PNP_PROBE(device_get_parent(dev), dev, sio_ids) == ENXIO) return (ENXIO); return (sioprobe(dev, 0, 0UL, 0)); } static int sio_isa_attach(dev) device_t dev; { return (sioattach(dev, 0, 0UL)); } DRIVER_MODULE(sio, isa, sio_isa_driver, sio_devclass, 0, 0); #ifndef COM_NO_ACPI DRIVER_MODULE(sio, acpi, sio_isa_driver, sio_devclass, 0, 0); #endif +ISA_PNP_INFO(sio_ids); Index: head/sys/dev/uart/uart_bus_isa.c =================================================================== --- head/sys/dev/uart/uart_bus_isa.c (revision 327101) +++ head/sys/dev/uart/uart_bus_isa.c (revision 327102) @@ -1,174 +1,175 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2008 TAKAHASHI Yoshihiro * Copyright (c) 2008 Marcel Moolenaar * Copyright (c) 2001 M. Warner Losh * 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 #include #include #include #include #include #include #include #include #include #include #include static int uart_isa_probe(device_t dev); static device_method_t uart_isa_methods[] = { /* Device interface */ DEVMETHOD(device_probe, uart_isa_probe), DEVMETHOD(device_attach, uart_bus_attach), DEVMETHOD(device_detach, uart_bus_detach), DEVMETHOD(device_resume, uart_bus_resume), { 0, 0 } }; static driver_t uart_isa_driver = { uart_driver_name, uart_isa_methods, sizeof(struct uart_softc), }; static struct isa_pnp_id isa_ns8250_ids[] = { {0x0005d041, "Standard PC COM port"}, /* PNP0500 */ {0x0105d041, "16550A-compatible COM port"}, /* PNP0501 */ {0x0205d041, "Multiport serial device (non-intelligent 16550)"}, /* PNP0502 */ {0x1005d041, "Generic IRDA-compatible device"}, /* PNP0510 */ {0x1105d041, "Generic IRDA-compatible device"}, /* PNP0511 */ /* Devices that do not have a compatid */ {0x12206804, NULL}, /* ACH2012 - 5634BTS 56K Video Ready Modem */ {0x7602a904, NULL}, /* AEI0276 - 56K v.90 Fax Modem (LKT) */ {0x00007905, NULL}, /* AKY0000 - 56K Plug&Play Modem */ {0x21107905, NULL}, /* AKY1021 - 56K Plug&Play Modem */ {0x01405407, NULL}, /* AZT4001 - AZT3000 PnP SOUND DEVICE, MODEM */ {0x56039008, NULL}, /* BDP0356 - Best Data 56x2 */ {0x56159008, NULL}, /* BDP1556 - B.D. Smart One 56SPS,Voice Modem*/ {0x36339008, NULL}, /* BDP3336 - Best Data Prods. 336F */ {0x0014490a, NULL}, /* BRI1400 - Boca 33.6 PnP */ {0x0015490a, NULL}, /* BRI1500 - Internal Fax Data */ {0x0034490a, NULL}, /* BRI3400 - Internal ACF Modem */ {0x0094490a, NULL}, /* BRI9400 - Boca K56Flex PnP */ {0x00b4490a, NULL}, /* BRIB400 - Boca 56k PnP */ {0x0010320d, NULL}, /* CIR1000 - Cirrus Logic V34 */ {0x0030320d, NULL}, /* CIR3000 - Cirrus Logic V43 */ {0x0100440e, NULL}, /* CRD0001 - Cardinal MVP288IV ? */ {0x01308c0e, NULL}, /* CTL3001 - Creative Labs Phoneblaster */ {0x36033610, NULL}, /* DAV0336 - DAVICOM 336PNP MODEM */ {0x01009416, NULL}, /* ETT0001 - E-Tech Bullet 33k6 PnP */ {0x0000aa1a, NULL}, /* FUJ0000 - FUJITSU Modem 33600 PNP/I2 */ {0x1200c31e, NULL}, /* GVC0012 - VF1128HV-R9 (win modem?) */ {0x0303c31e, NULL}, /* GVC0303 - MaxTech 33.6 PnP D/F/V */ {0x0505c31e, NULL}, /* GVC0505 - GVC 56k Faxmodem */ {0x0116c31e, NULL}, /* GVC1601 - Rockwell V.34 Plug & Play Modem */ {0x0050c31e, NULL}, /* GVC5000 - some GVC modem */ {0x3800f91e, NULL}, /* GWY0038 - Telepath with v.90 */ {0x9062f91e, NULL}, /* GWY6290 - Telepath with x2 Technology */ {0x8100e425, NULL}, /* IOD0081 - I-O DATA DEVICE,INC. IFML-560 */ {0x71004d24, NULL}, /* IBM0071 - IBM ThinkPad 240 IrDA controller*/ {0x21002534, NULL}, /* MAE0021 - Jetstream Int V.90 56k Voice Series 2*/ {0x0000f435, NULL}, /* MOT0000 - Motorola ModemSURFR 33.6 Intern */ {0x5015f435, NULL}, /* MOT1550 - Motorola ModemSURFR 56K Modem */ {0xf015f435, NULL}, /* MOT15F0 - Motorola VoiceSURFR 56K Modem */ {0x6045f435, NULL}, /* MOT4560 - Motorola ? */ {0x61e7a338, NULL}, /* NECE761 - 33.6Modem */ {0x0160633a, NULL}, /* NSC6001 - National Semi's IrDA Controller*/ {0x08804f3f, NULL}, /* OZO8008 - Zoom (33.6k Modem) */ {0x0f804f3f, NULL}, /* OZO800f - Zoom 2812 (56k Modem) */ {0x39804f3f, NULL}, /* OZO8039 - Zoom 56k flex */ {0x00914f3f, NULL}, /* OZO9100 - Zoom 2919 (K56 Faxmodem) */ {0x3024a341, NULL}, /* PMC2430 - Pace 56 Voice Internal Modem */ {0x1000eb49, NULL}, /* ROK0010 - Rockwell ? */ {0x1200b23d, NULL}, /* RSS0012 - OMRON ME5614ISA */ {0x5002734a, NULL}, /* RSS0250 - 5614Jx3(G) Internal Modem */ {0x6202734a, NULL}, /* RSS0262 - 5614Jx3[G] V90+K56Flex Modem */ {0x1010104d, NULL}, /* SHP1010 - Rockwell 33600bps Modem */ {0x10f0a34d, NULL}, /* SMCF010 - SMC IrCC*/ {0xc100ad4d, NULL}, /* SMM00C1 - Leopard 56k PnP */ {0x9012b04e, NULL}, /* SUP1290 - Supra ? */ {0x1013b04e, NULL}, /* SUP1310 - SupraExpress 336i PnP */ {0x8013b04e, NULL}, /* SUP1380 - SupraExpress 288i PnP Voice */ {0x8113b04e, NULL}, /* SUP1381 - SupraExpress 336i PnP Voice */ {0x5016b04e, NULL}, /* SUP1650 - Supra 336i Sp Intl */ {0x7016b04e, NULL}, /* SUP1670 - Supra 336i V+ Intl */ {0x7420b04e, NULL}, /* SUP2070 - Supra ? */ {0x8020b04e, NULL}, /* SUP2080 - Supra ? */ {0x8420b04e, NULL}, /* SUP2084 - SupraExpress 56i PnP */ {0x7121b04e, NULL}, /* SUP2171 - SupraExpress 56i Sp? */ {0x8024b04e, NULL}, /* SUP2480 - Supra ? */ {0x01007256, NULL}, /* USR0001 - U.S. Robotics Inc., Sportster W */ {0x02007256, NULL}, /* USR0002 - U.S. Robotics Inc. Sportster 33. */ {0x04007256, NULL}, /* USR0004 - USR Sportster 14.4k */ {0x06007256, NULL}, /* USR0006 - USR Sportster 33.6k */ {0x11007256, NULL}, /* USR0011 - USR ? */ {0x01017256, NULL}, /* USR0101 - USR ? */ {0x30207256, NULL}, /* USR2030 - U.S.Robotics Inc. Sportster 560 */ {0x50207256, NULL}, /* USR2050 - U.S.Robotics Inc. Sportster 33. */ {0x70207256, NULL}, /* USR2070 - U.S.Robotics Inc. Sportster 560 */ {0x30307256, NULL}, /* USR3030 - U.S. Robotics 56K FAX INT */ {0x31307256, NULL}, /* USR3031 - U.S. Robotics 56K FAX INT */ {0x50307256, NULL}, /* USR3050 - U.S. Robotics 56K FAX INT */ {0x70307256, NULL}, /* USR3070 - U.S. Robotics 56K Voice INT */ {0x90307256, NULL}, /* USR3090 - USR ? */ {0x70917256, NULL}, /* USR9170 - U.S. Robotics 56K FAX INT */ {0x90917256, NULL}, /* USR9190 - USR 56k Voice INT */ {0x04f0235c, NULL}, /* WACF004 - Wacom Tablet PC Screen */ {0x0ef0235c, NULL}, /* WACF00e - Wacom Tablet PC Screen 00e */ {0x0300695c, NULL}, /* WCI0003 - Fax/Voice/Modem/Speakphone/Asvd */ {0x01a0896a, NULL}, /* ZTIA001 - Zoom Internal V90 Faxmodem */ {0x61f7896a, NULL}, /* ZTIF761 - Zoom ComStar 33.6 */ {0} }; static int uart_isa_probe(device_t dev) { struct uart_softc *sc; device_t parent; parent = device_get_parent(dev); sc = device_get_softc(dev); /* Check PnP IDs */ if (ISA_PNP_PROBE(parent, dev, isa_ns8250_ids) == ENXIO) return (ENXIO); /* Probe PnP _and_ non-PnP ns8250 here. */ sc->sc_class = &uart_ns8250_class; return (uart_bus_probe(dev, 0, 0, 0, 0, 0)); } DRIVER_MODULE(uart, isa, uart_isa_driver, uart_devclass, 0, 0); +ISA_PNP_INFO(isa_ns8250_ids); Index: head/sys/isa/isavar.h =================================================================== --- head/sys/isa/isavar.h (revision 327101) +++ head/sys/isa/isavar.h (revision 327102) @@ -1,193 +1,197 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 1998 Doug Rabson * 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. * * $FreeBSD$ */ #ifndef _ISA_ISAVAR_H_ #define _ISA_ISAVAR_H_ struct isa_config; struct isa_pnp_id; typedef void isa_config_cb(void *arg, struct isa_config *config, int enable); #include "isa_if.h" #include #ifdef _KERNEL /* * ISA devices are partially ordered. This is to ensure that hardwired * devices the BIOS tells us are there appear first, then speculative * devices that are sensitive to the probe order, then devices that * are hinted to be there, then the most flexible devices which support * the ISA bus PNP standard. */ #define ISA_ORDER_PNPBIOS 10 /* plug-and-play BIOS inflexible hardware */ #define ISA_ORDER_SENSITIVE 20 /* legacy sensitive hardware */ #define ISA_ORDER_SPECULATIVE 30 /* legacy non-sensitive hardware */ #define ISA_ORDER_PNP 40 /* plug-and-play flexible hardware */ /* * Limits on resources that we can manage */ #define ISA_NPORT 50 #define ISA_NMEM 50 #define ISA_NIRQ 50 #define ISA_NDRQ 50 /* * Limits on resources the hardware can actually handle */ #define ISA_PNP_NPORT 8 #define ISA_PNP_NMEM 4 #define ISA_PNP_NIRQ 2 #define ISA_PNP_NDRQ 2 #define ISADMA_READ 0x00100000 #define ISADMA_WRITE 0 #define ISADMA_RAW 0x00080000 /* * Plug and play cards can support a range of resource * configurations. This structure is used by the isapnp parser to * inform the isa bus about the resource possibilities of the * device. Each different alternative should be supplied by calling * ISA_ADD_CONFIG(). */ struct isa_range { u_int32_t ir_start; u_int32_t ir_end; u_int32_t ir_size; u_int32_t ir_align; }; struct isa_config { struct isa_range ic_mem[ISA_NMEM]; struct isa_range ic_port[ISA_NPORT]; u_int32_t ic_irqmask[ISA_NIRQ]; u_int32_t ic_drqmask[ISA_NDRQ]; int ic_nmem; int ic_nport; int ic_nirq; int ic_ndrq; }; /* * Used to build lists of IDs and description strings for PnP drivers. */ struct isa_pnp_id { u_int32_t ip_id; const char *ip_desc; }; enum isa_device_ivars { ISA_IVAR_PORT, ISA_IVAR_PORT_0 = ISA_IVAR_PORT, ISA_IVAR_PORT_1, ISA_IVAR_PORTSIZE, ISA_IVAR_PORTSIZE_0 = ISA_IVAR_PORTSIZE, ISA_IVAR_PORTSIZE_1, ISA_IVAR_MADDR, ISA_IVAR_MADDR_0 = ISA_IVAR_MADDR, ISA_IVAR_MADDR_1, ISA_IVAR_MEMSIZE, ISA_IVAR_MEMSIZE_0 = ISA_IVAR_MEMSIZE, ISA_IVAR_MEMSIZE_1, ISA_IVAR_IRQ, ISA_IVAR_IRQ_0 = ISA_IVAR_IRQ, ISA_IVAR_IRQ_1, ISA_IVAR_DRQ, ISA_IVAR_DRQ_0 = ISA_IVAR_DRQ, ISA_IVAR_DRQ_1, ISA_IVAR_VENDORID, ISA_IVAR_SERIAL, ISA_IVAR_LOGICALID, ISA_IVAR_COMPATID, ISA_IVAR_CONFIGATTR, ISA_IVAR_PNP_CSN, ISA_IVAR_PNP_LDN, ISA_IVAR_PNPBIOS_HANDLE }; /* * ISA_IVAR_CONFIGATTR bits */ #define ISACFGATTR_CANDISABLE (1 << 0) /* can be disabled */ #define ISACFGATTR_DYNAMIC (1 << 1) /* dynamic configuration */ #define ISACFGATTR_HINTS (1 << 3) /* source of config is hints */ +#define ISA_PNP_DESCR "E:pnpid;D:#" +#define ISA_PNP_INFO(t) \ + MODULE_PNP_INFO(ISA_PNP_DESCR, pccard, t, t, sizeof(t[0]), nitems(t) - 1); \ + /* * Simplified accessors for isa devices */ #define ISA_ACCESSOR(var, ivar, type) \ __BUS_ACCESSOR(isa, var, ISA, ivar, type) ISA_ACCESSOR(port, PORT, int) ISA_ACCESSOR(portsize, PORTSIZE, int) ISA_ACCESSOR(irq, IRQ, int) ISA_ACCESSOR(drq, DRQ, int) ISA_ACCESSOR(maddr, MADDR, int) ISA_ACCESSOR(msize, MEMSIZE, int) ISA_ACCESSOR(vendorid, VENDORID, int) ISA_ACCESSOR(serial, SERIAL, int) ISA_ACCESSOR(logicalid, LOGICALID, int) ISA_ACCESSOR(compatid, COMPATID, int) ISA_ACCESSOR(configattr, CONFIGATTR, int) ISA_ACCESSOR(pnp_csn, PNP_CSN, int) ISA_ACCESSOR(pnp_ldn, PNP_LDN, int) ISA_ACCESSOR(pnpbios_handle, PNPBIOS_HANDLE, int) /* Device class for ISA bridges. */ extern devclass_t isab_devclass; extern intrmask_t isa_irq_pending(void); extern void isa_probe_children(device_t dev); void isa_dmacascade(int chan); void isa_dmadone(int flags, caddr_t addr, int nbytes, int chan); int isa_dma_init(int chan, u_int bouncebufsize, int flag); void isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan); int isa_dma_acquire(int chan); void isa_dma_release(int chan); int isa_dmastatus(int chan); int isa_dmastop(int chan); int isa_dmatc(int chan); #define isa_dmainit(chan, size) do { \ if (isa_dma_init(chan, size, M_NOWAIT)) \ printf("WARNING: isa_dma_init(%d, %ju) failed\n", \ (int)(chan), (uintmax_t)(size)); \ } while (0) void isa_hinted_child(device_t parent, const char *name, int unit); void isa_hint_device_unit(device_t bus, device_t child, const char *name, int *unitp); int isab_attach(device_t dev); #endif /* _KERNEL */ #endif /* !_ISA_ISAVAR_H_ */