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