digi_pci.c revision 76853
1105197Ssam/*- 2105197Ssam * Copyright (c) 2001 Brian Somers <brian@Awfulhak.org> 3139823Simp * based on work by Slawa Olhovchenkov 4105197Ssam * John Prince <johnp@knight-trosoft.com> 5105197Ssam * Eric Hernes 6105197Ssam * All rights reserved. 7105197Ssam * 8105197Ssam * Redistribution and use in source and binary forms, with or without 9105197Ssam * modification, are permitted provided that the following conditions 10105197Ssam * are met: 11105197Ssam * 1. Redistributions of source code must retain the above copyright 12105197Ssam * notice, this list of conditions and the following disclaimer. 13105197Ssam * 2. Redistributions in binary form must reproduce the above copyright 14105197Ssam * notice, this list of conditions and the following disclaimer in the 15105197Ssam * documentation and/or other materials provided with the distribution. 16105197Ssam * 17105197Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18105197Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19105197Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20105197Ssam * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21105197Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22105197Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23105197Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24105197Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25105197Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26105197Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27105197Ssam * SUCH DAMAGE. 28105197Ssam * 29105197Ssam * $FreeBSD: head/sys/dev/digi/digi_pci.c 76853 2001-05-19 17:06:48Z brian $ 30105197Ssam */ 31105197Ssam 32105197Ssam#include <sys/param.h> 33105197Ssam 34105197Ssam#include <sys/systm.h> 35105197Ssam#include <sys/kernel.h> 36105197Ssam#include <sys/tty.h> 37105197Ssam#include <sys/bus.h> 38105197Ssam#include <machine/bus.h> 39105197Ssam#include <sys/rman.h> 40105197Ssam#include <machine/resource.h> 41105197Ssam#include <vm/vm.h> 42105197Ssam#include <vm/pmap.h> 43105197Ssam#include <pci/pcivar.h> 44105197Ssam 45105197Ssam#include <sys/digiio.h> 46105197Ssam#include <dev/digi/digireg.h> 47105197Ssam#include <dev/digi/digi.h> 48105197Ssam#include <dev/digi/digi_pci.h> 49105197Ssam 50105197Ssamstatic u_char * 51195699Srwatsondigi_pci_setwin(struct digi_softc *sc, unsigned int addr) 52105197Ssam{ 53105197Ssam return (sc->vmem + addr); 54105197Ssam} 55105197Ssam 56105197Ssamstatic void 57105197Ssamdigi_pci_hidewin(struct digi_softc *sc) 58105197Ssam{ 59105197Ssam return; 60105197Ssam} 61105197Ssam 62105197Ssamstatic void 63105197Ssamdigi_pci_towin(struct digi_softc *sc, int win) 64105197Ssam{ 65105197Ssam return; 66105197Ssam} 67105197Ssam 68105197Ssamstatic int 69105197Ssamdigi_pci_probe(device_t dev) 70105197Ssam{ 71105197Ssam unsigned int device_id = pci_get_devid(dev); 72105197Ssam 73105197Ssam if (device_get_unit(dev) >= 16) { 74105197Ssam /* Don't overflow our control mask */ 75105197Ssam device_printf(dev, "At most 16 digiboards may be used\n"); 76105197Ssam return (ENXIO); 77105197Ssam } 78105197Ssam 79195699Srwatson if ((device_id & 0xffff) != PCI_VENDOR_DIGI) 80195699Srwatson return (ENXIO); 81105197Ssam 82105197Ssam switch (device_id >> 16) { 83195699Srwatson case PCI_DEVICE_EPC: 84195699Srwatson case PCI_DEVICE_XEM: 85195699Srwatson case PCI_DEVICE_XR: 86195699Srwatson case PCI_DEVICE_CX: 87105197Ssam case PCI_DEVICE_XRJ: 88215701Sdim case PCI_DEVICE_EPCJ: 89195727Srwatson case PCI_DEVICE_920_4: 90195699Srwatson case PCI_DEVICE_920_8: 91105197Ssam case PCI_DEVICE_920_2: 92105197Ssam return (0); 93105197Ssam } 94105197Ssam 95105197Ssam return (ENXIO); 96105197Ssam} 97105197Ssam 98105197Ssamstatic int 99105197Ssamdigi_pci_attach(device_t dev) 100105197Ssam{ 101105197Ssam struct digi_softc *sc; 102105197Ssam u_int32_t device_id; 103105197Ssam#ifdef DIGI_INTERRUPT 104105197Ssam int retVal = 0; 105105197Ssam#endif 106105197Ssam 107105197Ssam sc = device_get_softc(dev); 108105197Ssam KASSERT(sc, ("digi%d: softc not allocated in digi_pci_attach\n", 109105197Ssam device_get_unit(dev))); 110105197Ssam 111105197Ssam bzero(sc, sizeof(*sc)); 112105197Ssam sc->dev = dev; 113105197Ssam sc->res.unit = device_get_unit(dev); 114105197Ssam 115105197Ssam device_id = pci_get_devid(dev); 116105197Ssam switch (device_id >> 16) { 117105197Ssam case PCI_DEVICE_EPC: 118169425Sgnn sc->name = "Digiboard PCI EPC/X ASIC"; 119169425Sgnn sc->res.mrid = 0x10; 120105197Ssam sc->model = PCIEPCX; 121105197Ssam sc->module = "EPCX_PCI"; 122105197Ssam break; 123105197Ssam case PCI_DEVICE_XEM: 124105197Ssam sc->name = "Digiboard PCI PC/Xem ASIC"; 125105197Ssam sc->res.mrid = 0x10; 126105197Ssam sc->model = PCXEM; 127105197Ssam sc->module = "Xem"; 128105197Ssam break; 129105197Ssam case PCI_DEVICE_XR: 130105197Ssam sc->name = "Digiboard PCI PC/Xr ASIC"; 131120585Ssam sc->res.mrid = 0x10; 132120585Ssam sc->model = PCIXR; 133105197Ssam sc->module = "Xr"; 134105197Ssam break; 135105197Ssam case PCI_DEVICE_CX: 136105197Ssam sc->name = "Digiboard PCI C/X ASIC"; 137105197Ssam sc->res.mrid = 0x10; 138105197Ssam sc->model = PCCX; 139105197Ssam sc->module = "CX_PCI"; 140105197Ssam break; 141105197Ssam case PCI_DEVICE_XRJ: 142105197Ssam sc->name = "Digiboard PCI PC/Xr PLX"; 143105197Ssam sc->res.mrid = 0x18; 144105197Ssam sc->model = PCIXR; 145105197Ssam sc->module = "Xr"; 146105197Ssam break; 147105197Ssam case PCI_DEVICE_EPCJ: 148105197Ssam sc->name = "Digiboard PCI EPC/X PLX"; 149105197Ssam sc->res.mrid = 0x18; 150181803Sbz sc->model = PCIEPCX; 151105197Ssam sc->module = "EPCX_PCI"; 152105197Ssam break; 153105197Ssam case PCI_DEVICE_920_4: /* Digi PCI4r 920 */ 154105197Ssam sc->name = "Digiboard PCI4r 920"; 155105197Ssam sc->res.mrid = 0x10; 156105197Ssam sc->model = PCIXR; 157105197Ssam sc->module = "Xr"; 158105197Ssam break; 159105197Ssam case PCI_DEVICE_920_8: /* Digi PCI8r 920 */ 160105197Ssam sc->name = "Digiboard PCI8r 920"; 161105197Ssam sc->res.mrid = 0x10; 162105197Ssam sc->model = PCIXR; 163105197Ssam sc->module = "Xr"; 164105197Ssam break; 165105197Ssam case PCI_DEVICE_920_2: /* Digi PCI2r 920 */ 166105197Ssam sc->name = "Digiboard PCI2r 920"; 167105197Ssam sc->res.mrid = 0x10; 168120585Ssam sc->model = PCIXR; 169120585Ssam sc->module = "Xr"; 170105197Ssam break; 171105197Ssam default: 172105197Ssam device_printf(dev, "Unknown device id = %08x\n", device_id); 173120585Ssam return (ENXIO); 174120585Ssam } 175105197Ssam 176105197Ssam pci_write_config(dev, 0x40, 0, 4); 177105197Ssam pci_write_config(dev, 0x46, 0, 4); 178120585Ssam 179120585Ssam sc->res.mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->res.mrid, 180105197Ssam 0, ~0, 1, RF_ACTIVE); 181105197Ssam 182105197Ssam#ifdef DIGI_INTERRUPT 183105197Ssam sc->res.irqrid = 0; 184120585Ssam sc->res.irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->res.irqrid, 185120585Ssam 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE); 186105197Ssam if (sc->res.irq == NULL) { 187105197Ssam device_printf(dev, "couldn't map interrupt\n"); 188105197Ssam return (ENXIO); 189105197Ssam } 190105197Ssam retVal = bus_setup_intr(dev, sc->res.irq, INTR_TYPE_TTY, 191105197Ssam digiintr, sc, &sc->res.irqHandler); 192105197Ssam#else 193105197Ssam DLOG(DIGIDB_IRQ, (sc->dev, "Interrupt support compiled out\n")); 194105197Ssam#endif 195105197Ssam 196105197Ssam sc->vmem = rman_get_virtual(sc->res.mem); 197105197Ssam sc->pmem = vtophys(sc->vmem); 198111119Simp sc->pcibus = 1; 199105197Ssam sc->win_size = 0x200000; 200120585Ssam sc->win_bits = 21; 201105197Ssam sc->csigs = &digi_normal_signals; 202105197Ssam sc->status = DIGI_STATUS_NOTINIT; 203105197Ssam callout_handle_init(&sc->callout); 204105197Ssam callout_handle_init(&sc->inttest); 205105197Ssam sc->setwin = digi_pci_setwin; 206105197Ssam sc->hidewin = digi_pci_hidewin; 207105197Ssam sc->towin = digi_pci_towin; 208105197Ssam 209105197Ssam PCIPORT = FEPRST; 210105197Ssam 211105197Ssam return (digi_attach(sc)); 212105197Ssam} 213105197Ssam 214105197Ssamstatic device_method_t digi_pci_methods[] = { 215105197Ssam /* Device interface */ 216105197Ssam DEVMETHOD(device_probe, digi_pci_probe), 217105197Ssam DEVMETHOD(device_attach, digi_pci_attach), 218105197Ssam DEVMETHOD(device_detach, digi_detach), 219105197Ssam DEVMETHOD(device_shutdown, digi_shutdown), 220105197Ssam {0, 0} 221105197Ssam}; 222157123Sgnn 223105197Ssamstatic driver_t digi_pci_drv = { 224105197Ssam "digi", 225105197Ssam digi_pci_methods, 226105197Ssam sizeof(struct digi_softc), 227105197Ssam}; 228105197Ssam 229181803Sbz 230105197SsamDRIVER_MODULE(digi, pci, digi_pci_drv, digi_devclass, digi_modhandler, 0); 231105197Ssam