digi_pci.c revision 76195
176195Sbrian/*- 276195Sbrian * Copyright (c) 2001 Brian Somers <brian@Awfulhak.org> 376195Sbrian * All rights reserved. 476195Sbrian * 576195Sbrian * Redistribution and use in source and binary forms, with or without 676195Sbrian * modification, are permitted provided that the following conditions 776195Sbrian * are met: 876195Sbrian * 1. Redistributions of source code must retain the above copyright 976195Sbrian * notice, this list of conditions and the following disclaimer. 1076195Sbrian * 2. Redistributions in binary form must reproduce the above copyright 1176195Sbrian * notice, this list of conditions and the following disclaimer in the 1276195Sbrian * documentation and/or other materials provided with the distribution. 1376195Sbrian * 1476195Sbrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1576195Sbrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1676195Sbrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1776195Sbrian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1876195Sbrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1976195Sbrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2076195Sbrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2176195Sbrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2276195Sbrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2376195Sbrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2476195Sbrian * SUCH DAMAGE. 2576195Sbrian * 2676195Sbrian * $FreeBSD: head/sys/dev/digi/digi_pci.c 76195 2001-05-02 01:08:09Z brian $ 2776195Sbrian */ 2876195Sbrian 2976195Sbrian#include <sys/param.h> 3076195Sbrian 3176195Sbrian#include <sys/systm.h> 3276195Sbrian#include <sys/kernel.h> 3376195Sbrian#include <sys/tty.h> 3476195Sbrian#include <sys/syslog.h> 3576195Sbrian#include <sys/bus.h> 3676195Sbrian#include <machine/bus.h> 3776195Sbrian#include <sys/rman.h> 3876195Sbrian#include <machine/resource.h> 3976195Sbrian#include <vm/vm.h> 4076195Sbrian#include <vm/pmap.h> 4176195Sbrian#include <pci/pcivar.h> 4276195Sbrian 4376195Sbrian#include <digi/digireg.h> 4476195Sbrian#include <digi/digiio.h> 4576195Sbrian#include <digi/digi.h> 4676195Sbrian#include <digi/digi_pci.h> 4776195Sbrian 4876195Sbrianstatic u_char * 4976195Sbriandigi_pci_setwin(struct digi_softc *sc, unsigned int addr) 5076195Sbrian{ 5176195Sbrian return (sc->vmem + addr); 5276195Sbrian} 5376195Sbrian 5476195Sbrianstatic void 5576195Sbriandigi_pci_hidewin(struct digi_softc *sc) 5676195Sbrian{ 5776195Sbrian return; 5876195Sbrian} 5976195Sbrian 6076195Sbrianstatic void 6176195Sbriandigi_pci_towin(struct digi_softc *sc, int win) 6276195Sbrian{ 6376195Sbrian return; 6476195Sbrian} 6576195Sbrian 6676195Sbrianstatic int 6776195Sbriandigi_pci_probe(device_t dev) 6876195Sbrian{ 6976195Sbrian unsigned int device_id = pci_get_devid(dev); 7076195Sbrian 7176195Sbrian if (device_get_unit(dev) >= 16) { 7276195Sbrian /* Don't overflow our control mask */ 7376195Sbrian device_printf(dev, "At most 16 digiboards may be used\n"); 7476195Sbrian return (ENXIO); 7576195Sbrian } 7676195Sbrian 7776195Sbrian if ((device_id & 0xffff) != PCI_VENDOR_DIGI) 7876195Sbrian return (ENXIO); 7976195Sbrian 8076195Sbrian switch (device_id >> 16) { 8176195Sbrian case PCI_DEVICE_EPC: 8276195Sbrian case PCI_DEVICE_XEM: 8376195Sbrian case PCI_DEVICE_XR: 8476195Sbrian case PCI_DEVICE_CX: 8576195Sbrian case PCI_DEVICE_XRJ: 8676195Sbrian case PCI_DEVICE_EPCJ: 8776195Sbrian case PCI_DEVICE_920_4: 8876195Sbrian case PCI_DEVICE_920_8: 8976195Sbrian case PCI_DEVICE_920_2: 9076195Sbrian return 0; 9176195Sbrian } 9276195Sbrian 9376195Sbrian return ENXIO; 9476195Sbrian} 9576195Sbrian 9676195Sbrianstatic int 9776195Sbriandigi_pci_attach(device_t dev) 9876195Sbrian{ 9976195Sbrian struct digi_softc *sc; 10076195Sbrian u_int32_t device_id; 10176195Sbrian#ifdef DIGI_INTERRUPT 10276195Sbrian int retVal = 0; 10376195Sbrian#endif 10476195Sbrian 10576195Sbrian sc = device_get_softc(dev); 10676195Sbrian KASSERT(sc, ("digi%d: softc not allocated in digi_pci_attach\n", 10776195Sbrian device_get_unit(dev))); 10876195Sbrian 10976195Sbrian bzero(sc, sizeof(*sc)); 11076195Sbrian sc->dev = dev; 11176195Sbrian sc->res.unit = device_get_unit(dev); 11276195Sbrian 11376195Sbrian device_id = pci_get_devid(dev); 11476195Sbrian switch (device_id >> 16) { 11576195Sbrian case PCI_DEVICE_EPC: 11676195Sbrian sc->name = "Digiboard PCI EPC/X ASIC"; 11776195Sbrian sc->res.mrid = 0x10; 11876195Sbrian sc->model = PCIEPCX; 11976195Sbrian sc->module = "EPCX_PCI"; 12076195Sbrian break; 12176195Sbrian case PCI_DEVICE_XEM: 12276195Sbrian sc->name = "Digiboard PCI PC/Xem ASIC"; 12376195Sbrian sc->res.mrid = 0x10; 12476195Sbrian sc->model = PCXEM; 12576195Sbrian sc->module = "Xem"; 12676195Sbrian break; 12776195Sbrian case PCI_DEVICE_XR: 12876195Sbrian sc->name = "Digiboard PCI PC/Xr ASIC"; 12976195Sbrian sc->res.mrid = 0x10; 13076195Sbrian sc->model = PCIXR; 13176195Sbrian sc->module = "Xr"; 13276195Sbrian break; 13376195Sbrian case PCI_DEVICE_CX: 13476195Sbrian sc->name = "Digiboard PCI C/X ASIC"; 13576195Sbrian sc->res.mrid = 0x10; 13676195Sbrian sc->model = PCCX; 13776195Sbrian sc->module = "CX_PCI"; 13876195Sbrian break; 13976195Sbrian case PCI_DEVICE_XRJ: 14076195Sbrian sc->name = "Digiboard PCI PC/Xr PLX"; 14176195Sbrian sc->res.mrid = 0x18; 14276195Sbrian sc->model = PCIXR; 14376195Sbrian sc->module = "Xr"; 14476195Sbrian break; 14576195Sbrian case PCI_DEVICE_EPCJ: 14676195Sbrian sc->name = "Digiboard PCI EPC/X PLX"; 14776195Sbrian sc->res.mrid = 0x18; 14876195Sbrian sc->model = PCIEPCX; 14976195Sbrian sc->module = "EPCX_PCI"; 15076195Sbrian break; 15176195Sbrian case PCI_DEVICE_920_4: /* Digi PCI4r 920 */ 15276195Sbrian sc->name = "Digiboard PCI4r 920"; 15376195Sbrian sc->res.mrid = 0x10; 15476195Sbrian sc->model = PCIXR; 15576195Sbrian sc->module = "Xr"; 15676195Sbrian break; 15776195Sbrian case PCI_DEVICE_920_8: /* Digi PCI8r 920 */ 15876195Sbrian sc->name = "Digiboard PCI8r 920"; 15976195Sbrian sc->res.mrid = 0x10; 16076195Sbrian sc->model = PCIXR; 16176195Sbrian sc->module = "Xr"; 16276195Sbrian break; 16376195Sbrian case PCI_DEVICE_920_2: /* Digi PCI2r 920 */ 16476195Sbrian sc->name = "Digiboard PCI2r 920"; 16576195Sbrian sc->res.mrid = 0x10; 16676195Sbrian sc->model = PCIXR; 16776195Sbrian sc->module = "Xr"; 16876195Sbrian break; 16976195Sbrian default: 17076195Sbrian device_printf(dev, "Unknown device id = %08x\n", device_id); 17176195Sbrian return (ENXIO); 17276195Sbrian } 17376195Sbrian 17476195Sbrian pci_write_config(dev, 0x40, 0, 4); 17576195Sbrian pci_write_config(dev, 0x46, 0, 4); 17676195Sbrian 17776195Sbrian sc->res.mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->res.mrid, 17876195Sbrian 0, ~0, 1, RF_ACTIVE); 17976195Sbrian 18076195Sbrian#ifdef DIGI_INTERRUPT 18176195Sbrian sc->res.irqrid = 0; 18276195Sbrian sc->res.irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->res.irqrid, 18376195Sbrian 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE); 18476195Sbrian if (sc->res.irq == NULL) { 18576195Sbrian device_printf(dev, "couldn't map interrupt\n"); 18676195Sbrian return ENXIO; 18776195Sbrian } 18876195Sbrian retVal = bus_setup_intr(dev, sc->res.irq, INTR_TYPE_TTY, 18976195Sbrian digiintr, sc, &sc->res.irqHandler); 19076195Sbrian#else 19176195Sbrian DLOG(DIGIDB_IRQ, (sc->dev, "Interrupt support compiled out\n")); 19276195Sbrian#endif 19376195Sbrian 19476195Sbrian sc->vmem = rman_get_virtual(sc->res.mem); 19576195Sbrian sc->pmem = vtophys(sc->vmem); 19676195Sbrian sc->pcibus = 1; 19776195Sbrian sc->win_size = 0x200000; 19876195Sbrian sc->win_bits = 21; 19976195Sbrian sc->csigs = &digi_normal_signals; 20076195Sbrian sc->status = DIGI_STATUS_NOTINIT; 20176195Sbrian callout_handle_init(&sc->callout); 20276195Sbrian callout_handle_init(&sc->inttest); 20376195Sbrian sc->setwin = digi_pci_setwin; 20476195Sbrian sc->hidewin = digi_pci_hidewin; 20576195Sbrian sc->towin = digi_pci_towin; 20676195Sbrian 20776195Sbrian PCIPORT = FEPRST; 20876195Sbrian 20976195Sbrian return (digi_attach(sc)); 21076195Sbrian} 21176195Sbrian 21276195Sbrianstatic device_method_t digi_pci_methods[] = { 21376195Sbrian /* Device interface */ 21476195Sbrian DEVMETHOD(device_probe, digi_pci_probe), 21576195Sbrian DEVMETHOD(device_attach, digi_pci_attach), 21676195Sbrian DEVMETHOD(device_detach, digi_detach), 21776195Sbrian DEVMETHOD(device_shutdown, digi_shutdown), 21876195Sbrian {0, 0} 21976195Sbrian}; 22076195Sbrian 22176195Sbrianstatic driver_t digi_pci_drv = { 22276195Sbrian "digi", 22376195Sbrian digi_pci_methods, 22476195Sbrian sizeof(struct digi_softc), 22576195Sbrian}; 22676195Sbrian 22776195Sbrian 22876195SbrianDRIVER_MODULE(digi, pci, digi_pci_drv, digi_devclass, digi_modhandler, 0); 229