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 31#include <sys/cdefs.h>
| 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 31#include <sys/cdefs.h>
|
32__FBSDID("$FreeBSD: head/sys/dev/digi/digi_isa.c 272904 2014-10-10 19:12:04Z jhb $");
| 32__FBSDID("$FreeBSD: head/sys/dev/digi/digi_isa.c 296137 2016-02-27 03:38:01Z jhibbits $");
|
33 34/*- 35 * TODO: 36 * Figure out how to make the non-Xi boards use memory addresses other 37 * than 0xd0000 !!! 38 */ 39 40#include <sys/param.h> 41 42#include <sys/systm.h> 43#include <sys/kernel.h> 44#include <sys/module.h> 45#include <sys/tty.h> 46#include <sys/bus.h> 47#include <machine/bus.h> 48#include <sys/rman.h> 49#include <machine/resource.h> 50#include <vm/vm.h> 51#include <vm/pmap.h> 52 53#include <sys/digiio.h> 54#include <dev/digi/digireg.h> 55#include <dev/digi/digi.h> 56 57/* Valid i/o addresses are any of these with either 0 or 4 added */ 58static u_long digi_validio[] = { 59 0x100, 0x110, 0x120, 0x200, 0x220, 0x300, 0x320 60}; 61#define DIGI_NVALIDIO (sizeof(digi_validio) / sizeof(digi_validio[0])) 62#define IO_SIZE 0x04 63 64static u_long digi_validmem[] = { 65 0x80000, 0x88000, 0x90000, 0x98000, 0xa0000, 0xa8000, 0xb0000, 0xb8000, 66 0xc0000, 0xc8000, 0xd0000, 0xd8000, 0xe0000, 0xe8000, 0xf0000, 0xf8000, 67 0xf0000000, 0xf1000000, 0xf2000000, 0xf3000000, 0xf4000000, 0xf5000000, 68 0xf6000000, 0xf7000000, 0xf8000000, 0xf9000000, 0xfa000000, 0xfb000000, 69 0xfc000000, 0xfd000000, 0xfe000000, 0xff000000 70}; 71#define DIGI_NVALIDMEM (sizeof(digi_validmem) / sizeof(digi_validmem[0])) 72 73static u_char * 74digi_isa_setwin(struct digi_softc *sc, unsigned int addr) 75{ 76 outb(sc->wport, sc->window = FEPWIN | (addr >> sc->win_bits)); 77 return (sc->vmem + (addr % sc->win_size)); 78} 79 80static u_char * 81digi_xi_setwin(struct digi_softc *sc, unsigned int addr) 82{ 83 outb(sc->wport, sc->window = FEPMEM); 84 return (sc->vmem + addr); 85} 86 87static void 88digi_isa_hidewin(struct digi_softc *sc) 89{ 90 outb(sc->wport, sc->window = 0); 91 /* outb(sc->port, 0); */ 92} 93 94static void 95digi_isa_towin(struct digi_softc *sc, int win) 96{ 97 outb(sc->wport, sc->window = win); 98} 99 100static void 101digi_xi_towin(struct digi_softc *sc, int win) 102{ 103 outb(sc->wport, sc->window = FEPMEM); 104} 105 106/* 107 * sc->port should be set and its resource allocated. 108 */ 109static int 110digi_isa_check(struct digi_softc *sc) 111{ 112 int i, ident; 113 114 sc->name = NULL; 115 116 /* Invasive probe - reset the card */ 117 outb(sc->port, FEPRST); 118 for (i = 0; (inb(sc->port) & FEPMASK) != FEPRST; i++) { 119 if (i == hz / 10) 120 return (0); 121 digi_delay(sc, "digirst", 1); 122 } 123 DLOG(DIGIDB_INIT, (sc->dev, "got reset after %d iterations\n", i)); 124 125 ident = inb(sc->port); 126 127 /* 128 * NOTE, this probe is all wrong. I haven't got the data sheets ! 129 */ 130 131 DLOG(DIGIDB_INIT, (sc->dev, "board type is 0x%x\n", ident)); 132 if (ident & 0x1) { 133 switch (ident) { 134 case 0x05: 135 case 0x15: 136 case 0x25: 137 case 0x35: 138 sc->model = PCXI; 139 sc->csigs = &digi_xixe_signals; 140 switch (ident & 0x30) { 141 case 0: 142 sc->name = "Digiboard PC/Xi 64K"; 143 sc->mem_seg = 0xf000; 144 sc->win_size = 0x10000; 145 sc->win_bits = 16; 146 break; 147 case 0x10: 148 sc->name = "Digiboard PC/Xi 128K"; 149 sc->mem_seg = 0xE000; 150 sc->win_size = 0x20000; 151 sc->win_bits = 17; 152 break; 153 case 0x20: 154 sc->name = "Digiboard PC/Xi 256K"; 155 sc->mem_seg = 0xC000; 156 sc->win_size = 0x40000; 157 sc->win_bits = 18; 158 break; 159 case 0x30: 160 sc->name = "Digiboard PC/Xi 512K"; 161 sc->mem_seg = 0x8000; 162 sc->win_size = 0x80000; 163 sc->win_bits = 19; 164 break; 165 } 166 sc->wport = sc->port; 167 sc->module = "Xe"; 168 169 sc->setwin = digi_xi_setwin; 170 sc->hidewin = digi_isa_hidewin; 171 sc->towin = digi_xi_towin; 172 break; 173 174 case 0xf5: 175 sc->name = "Digiboard PC/Xem"; 176 sc->model = PCXEM; 177 sc->csigs = &digi_normal_signals; 178 sc->win_size = 0x8000; 179 sc->win_bits = 15; 180 sc->wport = sc->port + 1; 181 sc->module = "Xem"; 182 183 sc->setwin = digi_isa_setwin; 184 sc->hidewin = digi_isa_hidewin; 185 sc->towin = digi_isa_towin; 186 break; 187 } 188 } else { 189 outb(sc->port, 1); 190 ident = inb(sc->port); 191 192 if (ident & 0x1) { 193 device_printf(sc->dev, "PC/Xm is unsupported\n"); 194 return (0); 195 } 196 197 sc->mem_seg = 0xf000; 198 199 if (!(ident & 0xc0)) { 200 sc->name = "Digiboard PC/Xe 64K"; 201 sc->model = PCXE; 202 sc->csigs = &digi_xixe_signals; 203 sc->win_size = 0x10000; 204 sc->win_bits = 16; 205 sc->wport = sc->port; 206 } else { 207 sc->name = "Digiboard PC/Xe 64/8K (windowed)"; 208 sc->model = PCXEVE; 209 sc->csigs = &digi_normal_signals; 210 sc->win_size = 0x2000; 211 sc->win_bits = 13; 212 sc->wport = sc->port + 1; 213 } 214 sc->module = "Xe"; 215 216 sc->setwin = digi_isa_setwin; 217 sc->hidewin = digi_isa_hidewin; 218 sc->towin = digi_isa_towin; 219 } 220 221 return (sc->name != NULL); 222} 223 224static int 225digi_isa_probe(device_t dev) 226{ 227 struct digi_softc *sc = device_get_softc(dev); 228 int i; 229 230 KASSERT(sc, ("digi%d: softc not allocated in digi_isa_probe\n", 231 device_get_unit(dev))); 232 233 bzero(sc, sizeof(*sc)); 234 sc->status = DIGI_STATUS_NOTINIT; 235 sc->dev = dev; 236 sc->res.unit = device_get_unit(dev); 237 if (sc->res.unit >= 16) { 238 /* Don't overflow our control mask */ 239 device_printf(dev, "At most 16 digiboards may be used\n"); 240 return (ENXIO); 241 } 242 DLOG(DIGIDB_INIT, (sc->dev, "probing on isa bus\n")); 243 244 /* Check that we've got a valid i/o address */ 245 if ((sc->port = bus_get_resource_start(dev, SYS_RES_IOPORT, 0)) == 0) { 246 DLOG(DIGIDB_INIT, (sc->dev, "io address not given\n")); 247 return (ENXIO); 248 } 249 for (i = 0; i < DIGI_NVALIDIO; i++) 250 if (sc->port == digi_validio[i] || 251 sc->port == digi_validio[i] + 4) 252 break; 253 if (i == DIGI_NVALIDIO) { 254 device_printf(dev, "0x%03x: Invalid i/o address\n", sc->port); 255 return (ENXIO); 256 } 257 258 /* Ditto for our memory address */ 259 if ((sc->pmem = bus_get_resource_start(dev, SYS_RES_MEMORY, 0)) == 0) 260 return (ENXIO); 261 for (i = 0; i < DIGI_NVALIDMEM; i++) 262 if (sc->pmem == digi_validmem[i]) 263 break; 264 if (i == DIGI_NVALIDMEM) { 265 device_printf(dev, "0x%lx: Invalid memory address\n", sc->pmem); 266 return (ENXIO); 267 } 268 if ((sc->pmem & 0xfffffful) != sc->pmem) { 269 device_printf(dev, "0x%lx: Memory address not supported\n", 270 sc->pmem); 271 return (ENXIO); 272 } 273 sc->vmem = (u_char *)sc->pmem; 274 275 DLOG(DIGIDB_INIT, (sc->dev, "isa? port 0x%03x mem 0x%lx\n", 276 sc->port, sc->pmem)); 277 278 /* Temporarily map our io ports */ 279 sc->res.iorid = 0;
| 33 34/*- 35 * TODO: 36 * Figure out how to make the non-Xi boards use memory addresses other 37 * than 0xd0000 !!! 38 */ 39 40#include <sys/param.h> 41 42#include <sys/systm.h> 43#include <sys/kernel.h> 44#include <sys/module.h> 45#include <sys/tty.h> 46#include <sys/bus.h> 47#include <machine/bus.h> 48#include <sys/rman.h> 49#include <machine/resource.h> 50#include <vm/vm.h> 51#include <vm/pmap.h> 52 53#include <sys/digiio.h> 54#include <dev/digi/digireg.h> 55#include <dev/digi/digi.h> 56 57/* Valid i/o addresses are any of these with either 0 or 4 added */ 58static u_long digi_validio[] = { 59 0x100, 0x110, 0x120, 0x200, 0x220, 0x300, 0x320 60}; 61#define DIGI_NVALIDIO (sizeof(digi_validio) / sizeof(digi_validio[0])) 62#define IO_SIZE 0x04 63 64static u_long digi_validmem[] = { 65 0x80000, 0x88000, 0x90000, 0x98000, 0xa0000, 0xa8000, 0xb0000, 0xb8000, 66 0xc0000, 0xc8000, 0xd0000, 0xd8000, 0xe0000, 0xe8000, 0xf0000, 0xf8000, 67 0xf0000000, 0xf1000000, 0xf2000000, 0xf3000000, 0xf4000000, 0xf5000000, 68 0xf6000000, 0xf7000000, 0xf8000000, 0xf9000000, 0xfa000000, 0xfb000000, 69 0xfc000000, 0xfd000000, 0xfe000000, 0xff000000 70}; 71#define DIGI_NVALIDMEM (sizeof(digi_validmem) / sizeof(digi_validmem[0])) 72 73static u_char * 74digi_isa_setwin(struct digi_softc *sc, unsigned int addr) 75{ 76 outb(sc->wport, sc->window = FEPWIN | (addr >> sc->win_bits)); 77 return (sc->vmem + (addr % sc->win_size)); 78} 79 80static u_char * 81digi_xi_setwin(struct digi_softc *sc, unsigned int addr) 82{ 83 outb(sc->wport, sc->window = FEPMEM); 84 return (sc->vmem + addr); 85} 86 87static void 88digi_isa_hidewin(struct digi_softc *sc) 89{ 90 outb(sc->wport, sc->window = 0); 91 /* outb(sc->port, 0); */ 92} 93 94static void 95digi_isa_towin(struct digi_softc *sc, int win) 96{ 97 outb(sc->wport, sc->window = win); 98} 99 100static void 101digi_xi_towin(struct digi_softc *sc, int win) 102{ 103 outb(sc->wport, sc->window = FEPMEM); 104} 105 106/* 107 * sc->port should be set and its resource allocated. 108 */ 109static int 110digi_isa_check(struct digi_softc *sc) 111{ 112 int i, ident; 113 114 sc->name = NULL; 115 116 /* Invasive probe - reset the card */ 117 outb(sc->port, FEPRST); 118 for (i = 0; (inb(sc->port) & FEPMASK) != FEPRST; i++) { 119 if (i == hz / 10) 120 return (0); 121 digi_delay(sc, "digirst", 1); 122 } 123 DLOG(DIGIDB_INIT, (sc->dev, "got reset after %d iterations\n", i)); 124 125 ident = inb(sc->port); 126 127 /* 128 * NOTE, this probe is all wrong. I haven't got the data sheets ! 129 */ 130 131 DLOG(DIGIDB_INIT, (sc->dev, "board type is 0x%x\n", ident)); 132 if (ident & 0x1) { 133 switch (ident) { 134 case 0x05: 135 case 0x15: 136 case 0x25: 137 case 0x35: 138 sc->model = PCXI; 139 sc->csigs = &digi_xixe_signals; 140 switch (ident & 0x30) { 141 case 0: 142 sc->name = "Digiboard PC/Xi 64K"; 143 sc->mem_seg = 0xf000; 144 sc->win_size = 0x10000; 145 sc->win_bits = 16; 146 break; 147 case 0x10: 148 sc->name = "Digiboard PC/Xi 128K"; 149 sc->mem_seg = 0xE000; 150 sc->win_size = 0x20000; 151 sc->win_bits = 17; 152 break; 153 case 0x20: 154 sc->name = "Digiboard PC/Xi 256K"; 155 sc->mem_seg = 0xC000; 156 sc->win_size = 0x40000; 157 sc->win_bits = 18; 158 break; 159 case 0x30: 160 sc->name = "Digiboard PC/Xi 512K"; 161 sc->mem_seg = 0x8000; 162 sc->win_size = 0x80000; 163 sc->win_bits = 19; 164 break; 165 } 166 sc->wport = sc->port; 167 sc->module = "Xe"; 168 169 sc->setwin = digi_xi_setwin; 170 sc->hidewin = digi_isa_hidewin; 171 sc->towin = digi_xi_towin; 172 break; 173 174 case 0xf5: 175 sc->name = "Digiboard PC/Xem"; 176 sc->model = PCXEM; 177 sc->csigs = &digi_normal_signals; 178 sc->win_size = 0x8000; 179 sc->win_bits = 15; 180 sc->wport = sc->port + 1; 181 sc->module = "Xem"; 182 183 sc->setwin = digi_isa_setwin; 184 sc->hidewin = digi_isa_hidewin; 185 sc->towin = digi_isa_towin; 186 break; 187 } 188 } else { 189 outb(sc->port, 1); 190 ident = inb(sc->port); 191 192 if (ident & 0x1) { 193 device_printf(sc->dev, "PC/Xm is unsupported\n"); 194 return (0); 195 } 196 197 sc->mem_seg = 0xf000; 198 199 if (!(ident & 0xc0)) { 200 sc->name = "Digiboard PC/Xe 64K"; 201 sc->model = PCXE; 202 sc->csigs = &digi_xixe_signals; 203 sc->win_size = 0x10000; 204 sc->win_bits = 16; 205 sc->wport = sc->port; 206 } else { 207 sc->name = "Digiboard PC/Xe 64/8K (windowed)"; 208 sc->model = PCXEVE; 209 sc->csigs = &digi_normal_signals; 210 sc->win_size = 0x2000; 211 sc->win_bits = 13; 212 sc->wport = sc->port + 1; 213 } 214 sc->module = "Xe"; 215 216 sc->setwin = digi_isa_setwin; 217 sc->hidewin = digi_isa_hidewin; 218 sc->towin = digi_isa_towin; 219 } 220 221 return (sc->name != NULL); 222} 223 224static int 225digi_isa_probe(device_t dev) 226{ 227 struct digi_softc *sc = device_get_softc(dev); 228 int i; 229 230 KASSERT(sc, ("digi%d: softc not allocated in digi_isa_probe\n", 231 device_get_unit(dev))); 232 233 bzero(sc, sizeof(*sc)); 234 sc->status = DIGI_STATUS_NOTINIT; 235 sc->dev = dev; 236 sc->res.unit = device_get_unit(dev); 237 if (sc->res.unit >= 16) { 238 /* Don't overflow our control mask */ 239 device_printf(dev, "At most 16 digiboards may be used\n"); 240 return (ENXIO); 241 } 242 DLOG(DIGIDB_INIT, (sc->dev, "probing on isa bus\n")); 243 244 /* Check that we've got a valid i/o address */ 245 if ((sc->port = bus_get_resource_start(dev, SYS_RES_IOPORT, 0)) == 0) { 246 DLOG(DIGIDB_INIT, (sc->dev, "io address not given\n")); 247 return (ENXIO); 248 } 249 for (i = 0; i < DIGI_NVALIDIO; i++) 250 if (sc->port == digi_validio[i] || 251 sc->port == digi_validio[i] + 4) 252 break; 253 if (i == DIGI_NVALIDIO) { 254 device_printf(dev, "0x%03x: Invalid i/o address\n", sc->port); 255 return (ENXIO); 256 } 257 258 /* Ditto for our memory address */ 259 if ((sc->pmem = bus_get_resource_start(dev, SYS_RES_MEMORY, 0)) == 0) 260 return (ENXIO); 261 for (i = 0; i < DIGI_NVALIDMEM; i++) 262 if (sc->pmem == digi_validmem[i]) 263 break; 264 if (i == DIGI_NVALIDMEM) { 265 device_printf(dev, "0x%lx: Invalid memory address\n", sc->pmem); 266 return (ENXIO); 267 } 268 if ((sc->pmem & 0xfffffful) != sc->pmem) { 269 device_printf(dev, "0x%lx: Memory address not supported\n", 270 sc->pmem); 271 return (ENXIO); 272 } 273 sc->vmem = (u_char *)sc->pmem; 274 275 DLOG(DIGIDB_INIT, (sc->dev, "isa? port 0x%03x mem 0x%lx\n", 276 sc->port, sc->pmem)); 277 278 /* Temporarily map our io ports */ 279 sc->res.iorid = 0;
|
280 sc->res.io = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->res.iorid, 281 0ul, ~0ul, IO_SIZE, RF_ACTIVE);
| 280 sc->res.io = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, 281 &sc->res.iorid, IO_SIZE, RF_ACTIVE);
|
282 if (sc->res.io == NULL) 283 return (ENXIO); 284 285 /* Check the type of card and get internal memory characteristics */ 286 if (!digi_isa_check(sc)) { 287 bus_release_resource(dev, SYS_RES_IOPORT, sc->res.iorid, 288 sc->res.io); 289 return (ENXIO); 290 } 291 292 /* Temporarily map our memory */ 293 sc->res.mrid = 0;
| 282 if (sc->res.io == NULL) 283 return (ENXIO); 284 285 /* Check the type of card and get internal memory characteristics */ 286 if (!digi_isa_check(sc)) { 287 bus_release_resource(dev, SYS_RES_IOPORT, sc->res.iorid, 288 sc->res.io); 289 return (ENXIO); 290 } 291 292 /* Temporarily map our memory */ 293 sc->res.mrid = 0;
|
294 sc->res.mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->res.mrid, 295 0ul, ~0ul, sc->win_size, 0);
| 294 sc->res.mem = bus_alloc_resource_anywhere(dev, SYS_RES_MEMORY, 295 &sc->res.mrid, sc->win_size, 0);
|
296 if (sc->res.mem == NULL) { 297 device_printf(dev, "0x%lx: Memory range is in use\n", sc->pmem); 298 bus_release_resource(dev, SYS_RES_IOPORT, sc->res.iorid, 299 sc->res.io); 300 return (ENXIO); 301 } 302 303 outb(sc->port, FEPCLR); /* drop RESET */ 304 sc->hidewin(sc); /* set initial sc->window */ 305 306 bus_release_resource(dev, SYS_RES_MEMORY, sc->res.mrid, sc->res.mem); 307 bus_release_resource(dev, SYS_RES_IOPORT, sc->res.iorid, sc->res.io); 308 309 /* Let digi_isa_attach() know what we've found */ 310 bus_set_resource(dev, SYS_RES_IOPORT, 0, sc->port, IO_SIZE); 311 bus_set_resource(dev, SYS_RES_MEMORY, 0, sc->pmem, sc->win_size); 312 313 DLOG(DIGIDB_INIT, (sc->dev, "Probe returns -10\n")); 314 315 return (-10); /* Other drivers are preferred for now */ 316} 317 318static int 319digi_isa_attach(device_t dev) 320{ 321 struct digi_softc *sc = device_get_softc(dev); 322 int i, t, res; 323 u_char *ptr; 324 int reset; 325 u_long msize, iosize; 326 long scport; 327 328 KASSERT(sc, ("digi%d: softc not allocated in digi_isa_attach\n", 329 device_get_unit(dev))); 330 331 res = ENXIO; 332 bzero(sc, sizeof(*sc)); 333 sc->status = DIGI_STATUS_NOTINIT; 334 sc->dev = dev; 335 sc->res.unit = device_get_unit(dev); 336 DLOG(DIGIDB_INIT, (sc->dev, "attaching\n")); 337 338 bus_get_resource(dev, SYS_RES_IOPORT, 0, &scport, &iosize); 339 bus_get_resource(dev, SYS_RES_MEMORY, 0, &sc->pmem, &msize); 340 sc->port = scport; 341 /* sc->altpin = !!(device_get_flags(dev) & DGBFLAG_ALTPIN); */ 342 343 /* Allocate resources (verified in digi_isa_probe()) */ 344 sc->res.iorid = 0;
| 296 if (sc->res.mem == NULL) { 297 device_printf(dev, "0x%lx: Memory range is in use\n", sc->pmem); 298 bus_release_resource(dev, SYS_RES_IOPORT, sc->res.iorid, 299 sc->res.io); 300 return (ENXIO); 301 } 302 303 outb(sc->port, FEPCLR); /* drop RESET */ 304 sc->hidewin(sc); /* set initial sc->window */ 305 306 bus_release_resource(dev, SYS_RES_MEMORY, sc->res.mrid, sc->res.mem); 307 bus_release_resource(dev, SYS_RES_IOPORT, sc->res.iorid, sc->res.io); 308 309 /* Let digi_isa_attach() know what we've found */ 310 bus_set_resource(dev, SYS_RES_IOPORT, 0, sc->port, IO_SIZE); 311 bus_set_resource(dev, SYS_RES_MEMORY, 0, sc->pmem, sc->win_size); 312 313 DLOG(DIGIDB_INIT, (sc->dev, "Probe returns -10\n")); 314 315 return (-10); /* Other drivers are preferred for now */ 316} 317 318static int 319digi_isa_attach(device_t dev) 320{ 321 struct digi_softc *sc = device_get_softc(dev); 322 int i, t, res; 323 u_char *ptr; 324 int reset; 325 u_long msize, iosize; 326 long scport; 327 328 KASSERT(sc, ("digi%d: softc not allocated in digi_isa_attach\n", 329 device_get_unit(dev))); 330 331 res = ENXIO; 332 bzero(sc, sizeof(*sc)); 333 sc->status = DIGI_STATUS_NOTINIT; 334 sc->dev = dev; 335 sc->res.unit = device_get_unit(dev); 336 DLOG(DIGIDB_INIT, (sc->dev, "attaching\n")); 337 338 bus_get_resource(dev, SYS_RES_IOPORT, 0, &scport, &iosize); 339 bus_get_resource(dev, SYS_RES_MEMORY, 0, &sc->pmem, &msize); 340 sc->port = scport; 341 /* sc->altpin = !!(device_get_flags(dev) & DGBFLAG_ALTPIN); */ 342 343 /* Allocate resources (verified in digi_isa_probe()) */ 344 sc->res.iorid = 0;
|
345 sc->res.io = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->res.iorid, 346 0ul, ~0ul, iosize, RF_ACTIVE);
| 345 sc->res.io = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, 346 &sc->res.iorid, iosize, RF_ACTIVE);
|
347 if (sc->res.io == NULL) 348 return (ENXIO); 349 350 /* Check the type of card and get internal memory characteristics */ 351 DLOG(DIGIDB_INIT, (sc->dev, "Checking card type\n")); 352 if (!digi_isa_check(sc)) 353 goto failed; 354 355 callout_handle_init(&sc->callout); 356 callout_handle_init(&sc->inttest); 357 358 sc->res.mrid = 0;
| 347 if (sc->res.io == NULL) 348 return (ENXIO); 349 350 /* Check the type of card and get internal memory characteristics */ 351 DLOG(DIGIDB_INIT, (sc->dev, "Checking card type\n")); 352 if (!digi_isa_check(sc)) 353 goto failed; 354 355 callout_handle_init(&sc->callout); 356 callout_handle_init(&sc->inttest); 357 358 sc->res.mrid = 0;
|
359 sc->res.mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->res.mrid, 360 0ul, ~0ul, msize, RF_ACTIVE);
| 359 sc->res.mem = bus_alloc_resource_anywhere(dev, SYS_RES_MEMORY, 360 &sc->res.mrid, msize, RF_ACTIVE);
|
361 if (sc->res.mem == NULL) { 362 device_printf(dev, "0x%lx: Memory range is in use\n", sc->pmem); 363 sc->hidewin(sc); 364 goto failed; 365 } 366 367 /* map memory */ 368 sc->vmem = pmap_mapdev(sc->pmem, msize); 369 370 DLOG(DIGIDB_INIT, (sc->dev, "internal memory segment 0x%x\n", 371 sc->mem_seg)); 372 373 /* Start by resetting the card */ 374 reset = FEPRST; 375 if (sc->model == PCXI) 376 reset |= FEPMEM; 377 378 outb(sc->port, reset); 379 for (i = 0; (inb(sc->port) & FEPMASK) != reset; i++) { 380 if (i == hz / 10) { 381 device_printf(dev, "1st reset failed\n"); 382 sc->hidewin(sc); 383 goto failed; 384 } 385 digi_delay(sc, "digirst1", 1); 386 } 387 DLOG(DIGIDB_INIT, (sc->dev, "got reset after %d iterations\n", i)); 388 389 if (sc->model != PCXI) { 390 t = (sc->pmem >> 8) & 0xffe0; 391 if (sc->model == PCXEVE) 392 t |= 0x10; /* enable windowing */ 393 outb(sc->port + 2, t & 0xff); 394 outb(sc->port + 3, t >> 8); 395 } 396 397 if (sc->model == PCXI || sc->model == PCXE) { 398 outb(sc->port, FEPRST | FEPMEM); 399 for (i = 0; (inb(sc->port) & FEPMASK) != FEPRST; i++) { 400 if (i == hz / 10) { 401 device_printf(dev, 402 "memory reservation failed (0x%02x)\n", 403 inb(sc->port)); 404 sc->hidewin(sc); 405 goto failed; 406 } 407 digi_delay(sc, "digirst2", 1); 408 } 409 DLOG(DIGIDB_INIT, (sc->dev, "got memory after %d iterations\n", 410 i)); 411 } 412 413 DLOG(DIGIDB_INIT, (sc->dev, "short memory test\n")); 414 ptr = sc->setwin(sc, BOTWIN); 415 vD(ptr) = 0xA55A3CC3; 416 if (vD(ptr) != 0xA55A3CC3) { 417 device_printf(dev, "1st memory test failed\n"); 418 sc->hidewin(sc); 419 goto failed; 420 } 421 DLOG(DIGIDB_INIT, (sc->dev, "1st memory test ok\n")); 422 423 ptr = sc->setwin(sc, TOPWIN); 424 vD(ptr) = 0x5AA5C33C; 425 if (vD(ptr) != 0x5AA5C33C) { 426 device_printf(dev, "2nd memory test failed\n"); 427 sc->hidewin(sc); 428 goto failed; 429 } 430 DLOG(DIGIDB_INIT, (sc->dev, "2nd memory test ok\n")); 431 432 ptr = sc->setwin(sc, BIOSCODE + ((0xf000 - sc->mem_seg) << 4)); 433 vD(ptr) = 0x5AA5C33C; 434 if (vD(ptr) != 0x5AA5C33C) { 435 device_printf(dev, "3rd (BIOS) memory test failed\n"); 436 sc->hidewin(sc); 437 goto failed; 438 } 439 DLOG(DIGIDB_INIT, (sc->dev, "3rd memory test ok\n")); 440 441 if ((res = digi_attach(sc)) == 0) 442 return (0); 443 444failed: 445 if (sc->res.mem != NULL) { 446 bus_release_resource(dev, SYS_RES_MEMORY, sc->res.mrid, 447 sc->res.mem); 448 sc->res.mem = NULL; 449 } 450 if (sc->res.io != NULL) { 451 bus_release_resource(dev, SYS_RES_IOPORT, sc->res.iorid, 452 sc->res.io); 453 sc->res.io = NULL; 454 } 455 456 return (res); 457} 458 459static device_method_t digi_isa_methods[] = { 460 /* Device interface */ 461 DEVMETHOD(device_probe, digi_isa_probe), 462 DEVMETHOD(device_attach, digi_isa_attach), 463 DEVMETHOD(device_detach, digi_detach), 464 DEVMETHOD(device_shutdown, digi_shutdown), 465 466 DEVMETHOD_END 467}; 468 469static driver_t digi_isa_drv = { 470 "digi", 471 digi_isa_methods, 472 sizeof(struct digi_softc), 473}; 474DRIVER_MODULE(digi, isa, digi_isa_drv, digi_devclass, 0, 0);
| 361 if (sc->res.mem == NULL) { 362 device_printf(dev, "0x%lx: Memory range is in use\n", sc->pmem); 363 sc->hidewin(sc); 364 goto failed; 365 } 366 367 /* map memory */ 368 sc->vmem = pmap_mapdev(sc->pmem, msize); 369 370 DLOG(DIGIDB_INIT, (sc->dev, "internal memory segment 0x%x\n", 371 sc->mem_seg)); 372 373 /* Start by resetting the card */ 374 reset = FEPRST; 375 if (sc->model == PCXI) 376 reset |= FEPMEM; 377 378 outb(sc->port, reset); 379 for (i = 0; (inb(sc->port) & FEPMASK) != reset; i++) { 380 if (i == hz / 10) { 381 device_printf(dev, "1st reset failed\n"); 382 sc->hidewin(sc); 383 goto failed; 384 } 385 digi_delay(sc, "digirst1", 1); 386 } 387 DLOG(DIGIDB_INIT, (sc->dev, "got reset after %d iterations\n", i)); 388 389 if (sc->model != PCXI) { 390 t = (sc->pmem >> 8) & 0xffe0; 391 if (sc->model == PCXEVE) 392 t |= 0x10; /* enable windowing */ 393 outb(sc->port + 2, t & 0xff); 394 outb(sc->port + 3, t >> 8); 395 } 396 397 if (sc->model == PCXI || sc->model == PCXE) { 398 outb(sc->port, FEPRST | FEPMEM); 399 for (i = 0; (inb(sc->port) & FEPMASK) != FEPRST; i++) { 400 if (i == hz / 10) { 401 device_printf(dev, 402 "memory reservation failed (0x%02x)\n", 403 inb(sc->port)); 404 sc->hidewin(sc); 405 goto failed; 406 } 407 digi_delay(sc, "digirst2", 1); 408 } 409 DLOG(DIGIDB_INIT, (sc->dev, "got memory after %d iterations\n", 410 i)); 411 } 412 413 DLOG(DIGIDB_INIT, (sc->dev, "short memory test\n")); 414 ptr = sc->setwin(sc, BOTWIN); 415 vD(ptr) = 0xA55A3CC3; 416 if (vD(ptr) != 0xA55A3CC3) { 417 device_printf(dev, "1st memory test failed\n"); 418 sc->hidewin(sc); 419 goto failed; 420 } 421 DLOG(DIGIDB_INIT, (sc->dev, "1st memory test ok\n")); 422 423 ptr = sc->setwin(sc, TOPWIN); 424 vD(ptr) = 0x5AA5C33C; 425 if (vD(ptr) != 0x5AA5C33C) { 426 device_printf(dev, "2nd memory test failed\n"); 427 sc->hidewin(sc); 428 goto failed; 429 } 430 DLOG(DIGIDB_INIT, (sc->dev, "2nd memory test ok\n")); 431 432 ptr = sc->setwin(sc, BIOSCODE + ((0xf000 - sc->mem_seg) << 4)); 433 vD(ptr) = 0x5AA5C33C; 434 if (vD(ptr) != 0x5AA5C33C) { 435 device_printf(dev, "3rd (BIOS) memory test failed\n"); 436 sc->hidewin(sc); 437 goto failed; 438 } 439 DLOG(DIGIDB_INIT, (sc->dev, "3rd memory test ok\n")); 440 441 if ((res = digi_attach(sc)) == 0) 442 return (0); 443 444failed: 445 if (sc->res.mem != NULL) { 446 bus_release_resource(dev, SYS_RES_MEMORY, sc->res.mrid, 447 sc->res.mem); 448 sc->res.mem = NULL; 449 } 450 if (sc->res.io != NULL) { 451 bus_release_resource(dev, SYS_RES_IOPORT, sc->res.iorid, 452 sc->res.io); 453 sc->res.io = NULL; 454 } 455 456 return (res); 457} 458 459static device_method_t digi_isa_methods[] = { 460 /* Device interface */ 461 DEVMETHOD(device_probe, digi_isa_probe), 462 DEVMETHOD(device_attach, digi_isa_attach), 463 DEVMETHOD(device_detach, digi_detach), 464 DEVMETHOD(device_shutdown, digi_shutdown), 465 466 DEVMETHOD_END 467}; 468 469static driver_t digi_isa_drv = { 470 "digi", 471 digi_isa_methods, 472 sizeof(struct digi_softc), 473}; 474DRIVER_MODULE(digi, isa, digi_isa_drv, digi_devclass, 0, 0);
|