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 30#include <sys/cdefs.h> 31__FBSDID("$FreeBSD$"); 32 33#include <sys/param.h> 34 35#include <sys/systm.h> 36#include <sys/kernel.h> 37#include <sys/module.h> 38#include <sys/tty.h> 39#include <sys/bus.h> 40#include <machine/bus.h> 41#include <sys/rman.h> 42#include <machine/resource.h> 43#include <vm/vm.h> 44#include <vm/pmap.h> 45#include <dev/pci/pcivar.h> 46 47#include <sys/digiio.h> 48#include <dev/digi/digireg.h> 49#include <dev/digi/digi.h> 50#include <dev/digi/digi_pci.h> 51 52static u_char * 53digi_pci_setwin(struct digi_softc *sc, unsigned int addr) 54{ 55 return (sc->vmem + addr); 56} 57 58static void 59digi_pci_hidewin(struct digi_softc *sc) 60{ 61 return; 62} 63 64static void 65digi_pci_towin(struct digi_softc *sc, int win) 66{ 67 return; 68} 69 70static int 71digi_pci_probe(device_t dev) 72{ 73 unsigned int device_id = pci_get_devid(dev); 74 75 if (device_get_unit(dev) >= 16) { 76 /* Don't overflow our control mask */ 77 device_printf(dev, "At most 16 digiboards may be used\n"); 78 return (ENXIO); 79 } 80 81 if ((device_id & 0xffff) != PCI_VENDOR_DIGI) 82 return (ENXIO); 83 84 switch (device_id >> 16) { 85 case PCI_DEVICE_EPC: 86 case PCI_DEVICE_XEM: 87 case PCI_DEVICE_XR: 88 case PCI_DEVICE_CX: 89 case PCI_DEVICE_XRJ: 90 case PCI_DEVICE_EPCJ: 91 case PCI_DEVICE_920_4: 92 case PCI_DEVICE_920_8: 93 case PCI_DEVICE_920_2: 94 return (BUS_PROBE_DEFAULT); 95 } 96 97 return (ENXIO); 98} 99 100static int 101digi_pci_attach(device_t dev) 102{ 103 struct digi_softc *sc; 104 u_int32_t device_id; 105#ifdef DIGI_INTERRUPT 106 int retVal = 0; 107#endif 108 109 sc = device_get_softc(dev); 110 KASSERT(sc, ("digi%d: softc not allocated in digi_pci_attach\n", 111 device_get_unit(dev))); 112 113 bzero(sc, sizeof(*sc)); 114 sc->dev = dev; 115 sc->res.unit = device_get_unit(dev); 116 117 device_id = pci_get_devid(dev); 118 switch (device_id >> 16) { 119 case PCI_DEVICE_EPC: 120 sc->name = "Digiboard PCI EPC/X ASIC"; 121 sc->res.mrid = 0x10; 122 sc->model = PCIEPCX; 123 sc->module = "EPCX_PCI"; 124 break; 125 case PCI_DEVICE_XEM: 126 sc->name = "Digiboard PCI PC/Xem ASIC"; 127 sc->res.mrid = 0x10; 128 sc->model = PCXEM; 129 sc->module = "Xem"; 130 break; 131 case PCI_DEVICE_XR: 132 sc->name = "Digiboard PCI PC/Xr ASIC"; 133 sc->res.mrid = 0x10; 134 sc->model = PCIXR; 135 sc->module = "Xr"; 136 break; 137 case PCI_DEVICE_CX: 138 sc->name = "Digiboard PCI C/X ASIC"; 139 sc->res.mrid = 0x10; 140 sc->model = PCCX; 141 sc->module = "CX_PCI"; 142 break; 143 case PCI_DEVICE_XRJ: 144 sc->name = "Digiboard PCI PC/Xr PLX"; 145 sc->res.mrid = 0x18; 146 sc->model = PCIXR; 147 sc->module = "Xr"; 148 break; 149 case PCI_DEVICE_EPCJ: 150 sc->name = "Digiboard PCI EPC/X PLX"; 151 sc->res.mrid = 0x18; 152 sc->model = PCIEPCX; 153 sc->module = "EPCX_PCI"; 154 break; 155 case PCI_DEVICE_920_4: /* Digi PCI4r 920 */ 156 sc->name = "Digiboard PCI4r 920"; 157 sc->res.mrid = 0x10; 158 sc->model = PCIXR; 159 sc->module = "Xr"; 160 break; 161 case PCI_DEVICE_920_8: /* Digi PCI8r 920 */ 162 sc->name = "Digiboard PCI8r 920"; 163 sc->res.mrid = 0x10; 164 sc->model = PCIXR; 165 sc->module = "Xr"; 166 break; 167 case PCI_DEVICE_920_2: /* Digi PCI2r 920 */ 168 sc->name = "Digiboard PCI2r 920"; 169 sc->res.mrid = 0x10; 170 sc->model = PCIXR; 171 sc->module = "Xr"; 172 break; 173 default: 174 device_printf(dev, "Unknown device id = %08x\n", device_id); 175 return (ENXIO); 176 } 177 178 pci_write_config(dev, 0x40, 0, 4); 179 pci_write_config(dev, 0x46, 0, 4); 180 181 sc->res.mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->res.mrid, 182 RF_ACTIVE); 183 184#ifdef DIGI_INTERRUPT 185 sc->res.irqrid = 0; 186 sc->res.irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->res.irqrid, 187 RF_SHAREABLE | RF_ACTIVE); 188 if (sc->res.irq == NULL) { 189 device_printf(dev, "couldn't map interrupt\n"); 190 return (ENXIO); 191 } 192 retVal = bus_setup_intr(dev, sc->res.irq, INTR_TYPE_TTY, 193 digiintr, sc, &sc->res.irqHandler); 194#else 195 DLOG(DIGIDB_IRQ, (sc->dev, "Interrupt support compiled out\n")); 196#endif 197 198 sc->vmem = rman_get_virtual(sc->res.mem); 199 sc->pmem = vtophys(sc->vmem); 200 sc->pcibus = 1; 201 sc->win_size = 0x200000; 202 sc->win_bits = 21; 203 sc->csigs = &digi_normal_signals; 204 sc->status = DIGI_STATUS_NOTINIT; 205 callout_handle_init(&sc->callout); 206 callout_handle_init(&sc->inttest); 207 sc->setwin = digi_pci_setwin; 208 sc->hidewin = digi_pci_hidewin; 209 sc->towin = digi_pci_towin; 210 211 PCIPORT = FEPRST; 212 213 return (digi_attach(sc)); 214} 215 216static device_method_t digi_pci_methods[] = { 217 /* Device interface */ 218 DEVMETHOD(device_probe, digi_pci_probe), 219 DEVMETHOD(device_attach, digi_pci_attach), 220 DEVMETHOD(device_detach, digi_detach), 221 DEVMETHOD(device_shutdown, digi_shutdown), 222 223 DEVMETHOD_END 224}; 225 226static driver_t digi_pci_drv = { 227 "digi", 228 digi_pci_methods, 229 sizeof(struct digi_softc), 230}; 231DRIVER_MODULE(digi, pci, digi_pci_drv, digi_devclass, 0, 0); 232