pcii.c revision 141747
1141121Sphk/*- 2141121Sphk * Copyright (c) 2005 Poul-Henning Kamp <phk@FreeBSD.org> 3141121Sphk * All rights reserved. 4141121Sphk * 5141121Sphk * Redistribution and use in source and binary forms, with or without 6141121Sphk * modification, are permitted provided that the following conditions 7141121Sphk * are met: 8141121Sphk * 1. Redistributions of source code must retain the above copyright 9141398Sphk * notice, this list of conditions and the following disclaimer. 10141121Sphk * 2. Redistributions in binary form must reproduce the above copyright 11141121Sphk * notice, this list of conditions and the following disclaimer in the 12141121Sphk * documentation and/or other materials provided with the distribution. 13141121Sphk * 14141398Sphk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15141398Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16141398Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17141398Sphk * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18141398Sphk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19141398Sphk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20141398Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21141398Sphk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22141398Sphk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23141398Sphk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24141398Sphk * SUCH DAMAGE. 25141121Sphk * 26141398Sphk * Driver for GPIB cards based on NEC �PD7210 and compatibles. 27141398Sphk * 28141398Sphk * This driver just hooks up to the hardware and leaves all the interesting 29141398Sphk * stuff to upd7210.c. 30141398Sphk * 31141121Sphk * Supported hardware: 32141123Sphk * PCIIA compatible cards. 33141123Sphk * 34141123Sphk * Tested and known working: 35141121Sphk * "B&C Microsystems PC488A-0" 36141121Sphk * 37141121Sphk */ 38141121Sphk 39141121Sphk#include <sys/cdefs.h> 40141121Sphk__FBSDID("$FreeBSD: head/sys/dev/ieee488/pcii.c 141747 2005-02-12 17:39:50Z phk $"); 41141121Sphk 42141121Sphk#include <sys/param.h> 43141121Sphk#include <sys/systm.h> 44141398Sphk#include <sys/lock.h> 45141398Sphk#include <sys/mutex.h> 46141121Sphk#include <sys/kernel.h> 47141121Sphk#include <sys/module.h> 48141121Sphk#include <sys/bus.h> 49141121Sphk#include <machine/bus.h> 50141121Sphk#include <machine/resource.h> 51141121Sphk#include <sys/rman.h> 52141398Sphk#include <isa/isavar.h> 53141121Sphk 54141747Sphk#define UPD7210_HW_DRIVER 55141398Sphk#include <dev/ieee488/upd7210.h> 56141121Sphk 57141121Sphkstruct pcii_softc { 58141121Sphk int foo; 59141121Sphk struct resource *port[8]; 60141121Sphk struct resource *irq; 61141398Sphk struct resource *dma; 62141121Sphk void *intr_handler; 63141121Sphk struct upd7210 upd7210; 64141121Sphk}; 65141121Sphk 66141121Sphkstatic devclass_t pcii_devclass; 67141121Sphk 68141121Sphkstatic int pcii_probe(device_t dev); 69141121Sphkstatic int pcii_attach(device_t dev); 70141121Sphk 71141121Sphkstatic device_method_t pcii_methods[] = { 72141121Sphk DEVMETHOD(device_probe, pcii_probe), 73141121Sphk DEVMETHOD(device_attach, pcii_attach), 74141121Sphk DEVMETHOD(device_suspend, bus_generic_suspend), 75141121Sphk DEVMETHOD(device_resume, bus_generic_resume), 76141121Sphk 77141121Sphk { 0, 0 } 78141121Sphk}; 79141121Sphk 80141121Sphkstatic driver_t pcii_driver = { 81141121Sphk "pcii", 82141121Sphk pcii_methods, 83141423Sphk sizeof(struct pcii_softc), 84141121Sphk}; 85141121Sphk 86141121Sphkstatic int 87141121Sphkpcii_probe(device_t dev) 88141121Sphk{ 89141121Sphk struct resource *port; 90141121Sphk int rid; 91141121Sphk u_long start, count; 92141121Sphk int i, j, error = 0; 93141121Sphk 94141121Sphk device_set_desc(dev, "PCII IEEE-4888 controller"); 95141121Sphk 96141121Sphk rid = 0; 97141121Sphk if (bus_get_resource(dev, SYS_RES_IOPORT, rid, &start, &count) != 0) 98141121Sphk return ENXIO; 99141121Sphk if ((start & 0x3ff) != 0x2e1) 100141121Sphk return (ENXIO); 101141121Sphk count = 1; 102141121Sphk if (bus_set_resource(dev, SYS_RES_IOPORT, rid, start, count) != 0) 103141121Sphk return ENXIO; 104141121Sphk for (i = 0; i < 8; i++) { 105141121Sphk j = bus_set_resource(dev, SYS_RES_IOPORT, i, 106141121Sphk start + 0x400 * i, 1); 107141121Sphk if (j) { 108141121Sphk error = ENXIO; 109141121Sphk break; 110141121Sphk } 111141121Sphk rid = i; 112141121Sphk port = bus_alloc_resource_any(dev, SYS_RES_IOPORT, 113141121Sphk &rid, RF_ACTIVE); 114141121Sphk if (port == NULL) 115141121Sphk return (ENXIO); 116141121Sphk else 117141121Sphk bus_release_resource(dev, SYS_RES_IOPORT, i, port); 118141121Sphk } 119141121Sphk 120141121Sphk rid = 0; 121141121Sphk port = bus_alloc_resource_any(dev, 122141121Sphk SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); 123141121Sphk if (port == NULL) 124141121Sphk return (ENXIO); 125141121Sphk bus_release_resource(dev, SYS_RES_IRQ, rid, port); 126141121Sphk 127141121Sphk return (error); 128141121Sphk} 129141121Sphk 130141121Sphkstatic int 131141121Sphkpcii_attach(device_t dev) 132141121Sphk{ 133141121Sphk struct pcii_softc *sc; 134141121Sphk int unit; 135141121Sphk int rid; 136141121Sphk int i, error = 0; 137141121Sphk 138141121Sphk unit = device_get_unit(dev); 139141121Sphk sc = device_get_softc(dev); 140141121Sphk memset(sc, 0, sizeof *sc); 141141121Sphk 142141121Sphk device_set_desc(dev, "PCII IEEE-4888 controller"); 143141121Sphk 144141121Sphk for (rid = 0; rid < 8; rid++) { 145141121Sphk sc->port[rid] = bus_alloc_resource_any(dev, 146141121Sphk SYS_RES_IOPORT, &rid, RF_ACTIVE); 147141121Sphk if (sc->port[rid] == NULL) { 148141121Sphk error = ENXIO; 149141121Sphk break; 150141121Sphk } 151141121Sphk sc->upd7210.reg_tag[rid] = rman_get_bustag(sc->port[rid]); 152141121Sphk sc->upd7210.reg_handle[rid] = rman_get_bushandle(sc->port[rid]); 153141121Sphk } 154141121Sphk if (!error) { 155141121Sphk rid = 0; 156141121Sphk sc->irq = bus_alloc_resource_any(dev, 157141121Sphk SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); 158141121Sphk if (sc->irq == NULL) { 159141121Sphk error = ENXIO; 160141121Sphk } else { 161141123Sphk error = bus_setup_intr(dev, sc->irq, 162141123Sphk INTR_TYPE_MISC | INTR_MPSAFE, 163141121Sphk upd7210intr, &sc->upd7210, &sc->intr_handler); 164141121Sphk } 165141121Sphk } 166141398Sphk if (!error) { 167141398Sphk rid = 0; 168141398Sphk sc->dma = bus_alloc_resource_any(dev, 169141398Sphk SYS_RES_DRQ, &rid, RF_ACTIVE | RF_SHAREABLE); 170141398Sphk if (sc->dma == NULL) 171141398Sphk sc->upd7210.dmachan = -1; 172141398Sphk else 173141398Sphk sc->upd7210.dmachan = rman_get_start(sc->dma); 174141398Sphk } 175141121Sphk if (error) { 176141121Sphk for (i = 0; i < 8; i++) { 177141121Sphk if (sc->port[i] == NULL) 178141121Sphk break; 179141121Sphk bus_release_resource(dev, SYS_RES_IOPORT, 180141121Sphk 0, sc->port[i]); 181141121Sphk } 182141121Sphk if (sc->intr_handler != NULL) 183141121Sphk bus_teardown_intr(dev, sc->irq, sc->intr_handler); 184141121Sphk if (sc->irq != NULL) 185141121Sphk bus_release_resource(dev, SYS_RES_IRQ, i, sc->irq); 186141121Sphk } 187141121Sphk upd7210attach(&sc->upd7210); 188141121Sphk return (error); 189141121Sphk} 190141121Sphk 191141121SphkDRIVER_MODULE(pcii, isa, pcii_driver, pcii_devclass, 0, 0); 192141121SphkDRIVER_MODULE(pcii, acpi, pcii_driver, pcii_devclass, 0, 0); 193