digi_pci.c revision 143161
122347Spst/*- 222347Spst * Copyright (c) 2001 Brian Somers <brian@Awfulhak.org> 329967Sache * based on work by Slawa Olhovchenkov 492914Smarkm * John Prince <johnp@knight-trosoft.com> 522347Spst * Eric Hernes 622347Spst * All rights reserved. 722347Spst * 822347Spst * Redistribution and use in source and binary forms, with or without 922347Spst * modification, are permitted provided that the following conditions 1022347Spst * are met: 1122347Spst * 1. Redistributions of source code must retain the above copyright 1222347Spst * notice, this list of conditions and the following disclaimer. 1322347Spst * 2. Redistributions in binary form must reproduce the above copyright 1422347Spst * notice, this list of conditions and the following disclaimer in the 1522347Spst * documentation and/or other materials provided with the distribution. 1622347Spst * 1722347Spst * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1822347Spst * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1922347Spst * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2022347Spst * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2122347Spst * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2259121Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2322347Spst * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2422347Spst * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2522347Spst * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2622347Spst * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2722347Spst * SUCH DAMAGE. 2822347Spst */ 2922347Spst 3022347Spst#include <sys/cdefs.h> 3122347Spst__FBSDID("$FreeBSD: head/sys/dev/digi/digi_pci.c 143161 2005-03-05 18:30:12Z imp $"); 3222347Spst 3322347Spst#include <sys/param.h> 3422347Spst 3522347Spst#include <sys/systm.h> 3622347Spst#include <sys/kernel.h> 3722347Spst#include <sys/module.h> 3822347Spst#include <sys/tty.h> 3922347Spst#include <sys/bus.h> 4022347Spst#include <machine/bus.h> 4122347Spst#include <sys/rman.h> 4222347Spst#include <machine/resource.h> 4322347Spst#include <vm/vm.h> 4422347Spst#include <vm/pmap.h> 4522347Spst#include <dev/pci/pcivar.h> 4622347Spst 4722347Spst#include <sys/digiio.h> 4822347Spst#include <dev/digi/digireg.h> 4922347Spst#include <dev/digi/digi.h> 5022347Spst#include <dev/digi/digi_pci.h> 5122347Spst 5222347Spststatic u_char * 5322347Spstdigi_pci_setwin(struct digi_softc *sc, unsigned int addr) 5422347Spst{ 5522347Spst return (sc->vmem + addr); 5622347Spst} 5722347Spst 5822347Spststatic void 5922347Spstdigi_pci_hidewin(struct digi_softc *sc) 6022347Spst{ 6122347Spst return; 6222347Spst} 6322347Spst 6422347Spststatic void 6522347Spstdigi_pci_towin(struct digi_softc *sc, int win) 6622347Spst{ 6722347Spst return; 6822347Spst} 6922347Spst 7022347Spststatic int 7122347Spstdigi_pci_probe(device_t dev) 7222347Spst{ 7322347Spst unsigned int device_id = pci_get_devid(dev); 7422347Spst 7522347Spst if (device_get_unit(dev) >= 16) { 7622347Spst /* Don't overflow our control mask */ 7722347Spst device_printf(dev, "At most 16 digiboards may be used\n"); 7822347Spst return (ENXIO); 7922347Spst } 8022347Spst 8122347Spst if ((device_id & 0xffff) != PCI_VENDOR_DIGI) 8222347Spst return (ENXIO); 8322372Spst 8422372Spst switch (device_id >> 16) { 8522372Spst case PCI_DEVICE_EPC: 8622347Spst case PCI_DEVICE_XEM: 8722347Spst case PCI_DEVICE_XR: 8822347Spst case PCI_DEVICE_CX: 8922347Spst case PCI_DEVICE_XRJ: 9022347Spst case PCI_DEVICE_EPCJ: 9122347Spst case PCI_DEVICE_920_4: 9222347Spst case PCI_DEVICE_920_8: 9322347Spst case PCI_DEVICE_920_2: 9422347Spst return (BUS_PROBE_DEFAULT); 9522347Spst } 9622347Spst 9722347Spst return (ENXIO); 9822347Spst} 9922347Spst 10022347Spststatic 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 {0, 0} 223}; 224 225static driver_t digi_pci_drv = { 226 "digi", 227 digi_pci_methods, 228 sizeof(struct digi_softc), 229}; 230DRIVER_MODULE(digi, pci, digi_pci_drv, digi_devclass, 0, 0); 231