digi_pci.c revision 76848
1/*- 2 * Copyright (c) 2001 Brian Somers <brian@Awfulhak.org> 3 * based on work by Slawa Olhovchenkov 4 * John Prince <johnp@knight-trosoft.com> 5 * Eric Hernes 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $FreeBSD: head/sys/dev/digi/digi_pci.c 76848 2001-05-19 09:28:59Z brian $ 30 */ 31 32#include <sys/param.h> 33 34#include <sys/systm.h> 35#include <sys/kernel.h> 36#include <sys/tty.h> 37#include <sys/bus.h> 38#include <machine/bus.h> 39#include <sys/rman.h> 40#include <machine/resource.h> 41#include <vm/vm.h> 42#include <vm/pmap.h> 43#include <pci/pcivar.h> 44 45#include <sys/digiio.h> 46#include <digi/digireg.h> 47#include <digi/digi.h> 48#include <digi/digi_pci.h> 49 50static u_char * 51digi_pci_setwin(struct digi_softc *sc, unsigned int addr) 52{ 53 return (sc->vmem + addr); 54} 55 56static void 57digi_pci_hidewin(struct digi_softc *sc) 58{ 59 return; 60} 61 62static void 63digi_pci_towin(struct digi_softc *sc, int win) 64{ 65 return; 66} 67 68static int 69digi_pci_probe(device_t dev) 70{ 71 unsigned int device_id = pci_get_devid(dev); 72 73 if (device_get_unit(dev) >= 16) { 74 /* Don't overflow our control mask */ 75 device_printf(dev, "At most 16 digiboards may be used\n"); 76 return (ENXIO); 77 } 78 79 if ((device_id & 0xffff) != PCI_VENDOR_DIGI) 80 return (ENXIO); 81 82 switch (device_id >> 16) { 83 case PCI_DEVICE_EPC: 84 case PCI_DEVICE_XEM: 85 case PCI_DEVICE_XR: 86 case PCI_DEVICE_CX: 87 case PCI_DEVICE_XRJ: 88 case PCI_DEVICE_EPCJ: 89 case PCI_DEVICE_920_4: 90 case PCI_DEVICE_920_8: 91 case PCI_DEVICE_920_2: 92 return (0); 93 } 94 95 return (ENXIO); 96} 97 98static int 99digi_pci_attach(device_t dev) 100{ 101 struct digi_softc *sc; 102 u_int32_t device_id; 103#ifdef DIGI_INTERRUPT 104 int retVal = 0; 105#endif 106 107 sc = device_get_softc(dev); 108 KASSERT(sc, ("digi%d: softc not allocated in digi_pci_attach\n", 109 device_get_unit(dev))); 110 111 bzero(sc, sizeof(*sc)); 112 sc->dev = dev; 113 sc->res.unit = device_get_unit(dev); 114 115 device_id = pci_get_devid(dev); 116 switch (device_id >> 16) { 117 case PCI_DEVICE_EPC: 118 sc->name = "Digiboard PCI EPC/X ASIC"; 119 sc->res.mrid = 0x10; 120 sc->model = PCIEPCX; 121 sc->module = "EPCX_PCI"; 122 break; 123 case PCI_DEVICE_XEM: 124 sc->name = "Digiboard PCI PC/Xem ASIC"; 125 sc->res.mrid = 0x10; 126 sc->model = PCXEM; 127 sc->module = "Xem"; 128 break; 129 case PCI_DEVICE_XR: 130 sc->name = "Digiboard PCI PC/Xr ASIC"; 131 sc->res.mrid = 0x10; 132 sc->model = PCIXR; 133 sc->module = "Xr"; 134 break; 135 case PCI_DEVICE_CX: 136 sc->name = "Digiboard PCI C/X ASIC"; 137 sc->res.mrid = 0x10; 138 sc->model = PCCX; 139 sc->module = "CX_PCI"; 140 break; 141 case PCI_DEVICE_XRJ: 142 sc->name = "Digiboard PCI PC/Xr PLX"; 143 sc->res.mrid = 0x18; 144 sc->model = PCIXR; 145 sc->module = "Xr"; 146 break; 147 case PCI_DEVICE_EPCJ: 148 sc->name = "Digiboard PCI EPC/X PLX"; 149 sc->res.mrid = 0x18; 150 sc->model = PCIEPCX; 151 sc->module = "EPCX_PCI"; 152 break; 153 case PCI_DEVICE_920_4: /* Digi PCI4r 920 */ 154 sc->name = "Digiboard PCI4r 920"; 155 sc->res.mrid = 0x10; 156 sc->model = PCIXR; 157 sc->module = "Xr"; 158 break; 159 case PCI_DEVICE_920_8: /* Digi PCI8r 920 */ 160 sc->name = "Digiboard PCI8r 920"; 161 sc->res.mrid = 0x10; 162 sc->model = PCIXR; 163 sc->module = "Xr"; 164 break; 165 case PCI_DEVICE_920_2: /* Digi PCI2r 920 */ 166 sc->name = "Digiboard PCI2r 920"; 167 sc->res.mrid = 0x10; 168 sc->model = PCIXR; 169 sc->module = "Xr"; 170 break; 171 default: 172 device_printf(dev, "Unknown device id = %08x\n", device_id); 173 return (ENXIO); 174 } 175 176 pci_write_config(dev, 0x40, 0, 4); 177 pci_write_config(dev, 0x46, 0, 4); 178 179 sc->res.mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->res.mrid, 180 0, ~0, 1, RF_ACTIVE); 181 182#ifdef DIGI_INTERRUPT 183 sc->res.irqrid = 0; 184 sc->res.irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->res.irqrid, 185 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE); 186 if (sc->res.irq == NULL) { 187 device_printf(dev, "couldn't map interrupt\n"); 188 return (ENXIO); 189 } 190 retVal = bus_setup_intr(dev, sc->res.irq, INTR_TYPE_TTY, 191 digiintr, sc, &sc->res.irqHandler); 192#else 193 DLOG(DIGIDB_IRQ, (sc->dev, "Interrupt support compiled out\n")); 194#endif 195 196 sc->vmem = rman_get_virtual(sc->res.mem); 197 sc->pmem = vtophys(sc->vmem); 198 sc->pcibus = 1; 199 sc->win_size = 0x200000; 200 sc->win_bits = 21; 201 sc->csigs = &digi_normal_signals; 202 sc->status = DIGI_STATUS_NOTINIT; 203 callout_handle_init(&sc->callout); 204 callout_handle_init(&sc->inttest); 205 sc->setwin = digi_pci_setwin; 206 sc->hidewin = digi_pci_hidewin; 207 sc->towin = digi_pci_towin; 208 209 PCIPORT = FEPRST; 210 211 return (digi_attach(sc)); 212} 213 214static device_method_t digi_pci_methods[] = { 215 /* Device interface */ 216 DEVMETHOD(device_probe, digi_pci_probe), 217 DEVMETHOD(device_attach, digi_pci_attach), 218 DEVMETHOD(device_detach, digi_detach), 219 DEVMETHOD(device_shutdown, digi_shutdown), 220 {0, 0} 221}; 222 223static driver_t digi_pci_drv = { 224 "digi", 225 digi_pci_methods, 226 sizeof(struct digi_softc), 227}; 228 229 230DRIVER_MODULE(digi, pci, digi_pci_drv, digi_devclass, digi_modhandler, 0); 231