Ignore machine-check MSRs
[freebsd-src/fkvm-freebsd.git] / sys / dev / sr / if_sr_isa.c
blob3f68e001295b66e9ed81a30d527db7547dfbaa03
1 /*-
2 * Copyright (c) 1996 - 2001 John Hay.
3 * Copyright (c) 1996 SDL Communications, Inc.
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the author nor the names of any co-contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/conf.h> /* cdevsw stuff */
38 #include <sys/kernel.h> /* SYSINIT stuff */
39 #include <sys/uio.h> /* SYSINIT stuff */
40 #include <sys/malloc.h> /* malloc region definitions */
41 #include <sys/module.h>
42 #include <sys/bus.h>
43 #include <machine/bus.h>
44 #include <machine/resource.h>
45 #include <sys/rman.h>
46 #include <sys/time.h>
48 #include <isa/isavar.h>
49 #include "isa_if.h"
51 #include <dev/ic/hd64570.h>
52 #include <dev/sr/if_srregs.h>
55 * List of valid interrupt numbers for the N2 ISA card.
57 static int sr_irqtable[16] = {
58 0, /* 0 */
59 0, /* 1 */
60 0, /* 2 */
61 1, /* 3 */
62 1, /* 4 */
63 1, /* 5 */
64 0, /* 6 */
65 1, /* 7 */
66 0, /* 8 */
67 0, /* 9 */
68 1, /* 10 */
69 1, /* 11 */
70 1, /* 12 */
71 0, /* 13 */
72 0, /* 14 */
73 1 /* 15 */
76 static int sr_isa_probe (device_t);
77 static int sr_isa_attach (device_t);
79 static struct isa_pnp_id sr_ids[] = {
80 {0, NULL}
83 static device_method_t sr_methods[] = {
84 DEVMETHOD(device_probe, sr_isa_probe),
85 DEVMETHOD(device_attach, sr_isa_attach),
86 DEVMETHOD(device_detach, sr_detach),
87 { 0, 0 }
90 static driver_t sr_isa_driver = {
91 "sr",
92 sr_methods,
93 sizeof (struct sr_hardc)
96 DRIVER_MODULE(sr, isa, sr_isa_driver, sr_devclass, 0, 0);
97 MODULE_DEPEND(sr, isa, 1, 1, 1);
99 static u_int src_get8_io(struct sr_hardc *hc, u_int off);
100 static u_int src_get16_io(struct sr_hardc *hc, u_int off);
101 static void src_put8_io(struct sr_hardc *hc, u_int off, u_int val);
102 static void src_put16_io(struct sr_hardc *hc, u_int off, u_int val);
103 static u_int src_dpram_size(device_t device);
106 * Probe for an ISA card. If it is there, size its memory. Then get the
107 * rest of its information and fill it in.
109 static int
110 sr_isa_probe (device_t device)
112 struct sr_hardc *hc;
113 int error;
114 u_int32_t flags;
115 u_int i, tmp;
116 u_long irq, junk, membase, memsize;
117 sca_regs *sca = 0;
119 error = ISA_PNP_PROBE(device_get_parent(device), device, sr_ids);
120 if (error == ENXIO || error == 0)
121 return (error);
123 hc = device_get_softc(device);
124 bzero(hc, sizeof(struct sr_hardc));
126 if (sr_allocate_ioport(device, 0, SRC_IO_SIZ)) {
127 return (ENXIO);
131 * Now see if the card is realy there.
133 hc->cardtype = SR_CRD_N2;
134 hc->cunit = device_get_unit(device);
136 * We have to fill these in early because the SRC_PUT* and SRC_GET*
137 * macros use them.
139 hc->src_get8 = src_get8_io;
140 hc->src_get16 = src_get16_io;
141 hc->src_put8 = src_put8_io;
142 hc->src_put16 = src_put16_io;
144 hc->sca = 0;
145 hc->numports = NCHAN; /* assumed # of channels on the card */
147 flags = device_get_flags(device);
148 if (flags & SR_FLAGS_NCHAN_MSK)
149 hc->numports = flags & SR_FLAGS_NCHAN_MSK;
151 sr_outb(hc, SR_PCR, 0); /* turn off the card */
154 * Next, we'll test the Base Address Register to retension of
155 * data... ... seeing if we're *really* talking to an N2.
157 for (i = 0; i < 0x100; i++) {
158 sr_outb(hc, SR_BAR, i);
159 sr_inb(hc, SR_PCR);
160 tmp = sr_inb(hc, SR_BAR);
161 if (tmp != i) {
162 printf("sr%d: probe failed BAR %x, %x.\n",
163 hc->cunit, i, tmp);
164 goto errexit;
169 * Now see if we can see the SCA.
171 sr_outb(hc, SR_PCR, SR_PCR_SCARUN | sr_inb(hc, SR_PCR));
172 SRC_PUT8(hc, sca->wcrl, 0);
173 SRC_PUT8(hc, sca->wcrm, 0);
174 SRC_PUT8(hc, sca->wcrh, 0);
175 SRC_PUT8(hc, sca->pcr, 0);
176 SRC_PUT8(hc, sca->msci[0].tmc, 0);
177 sr_inb(hc, 0);
179 tmp = SRC_GET8(hc, sca->msci[0].tmc);
180 if (tmp != 0) {
181 printf("sr%d: Error reading SCA 0, %x\n", hc->cunit, tmp);
182 goto errexit;
184 SRC_PUT8(hc, sca->msci[0].tmc, 0x5A);
185 sr_inb(hc, 0);
187 tmp = SRC_GET8(hc, sca->msci[0].tmc);
188 if (tmp != 0x5A) {
189 printf("sr%d: Error reading SCA 0x5A, %x\n", hc->cunit, tmp);
190 goto errexit;
192 SRC_PUT16(hc, sca->dmac[0].cda, 0);
193 sr_inb(hc, 0);
195 tmp = SRC_GET16(hc, sca->dmac[0].cda);
196 if (tmp != 0) {
197 printf("sr%d: Error reading SCA 0, %x\n", hc->cunit, tmp);
198 goto errexit;
200 SRC_PUT16(hc, sca->dmac[0].cda, 0x55AA);
201 sr_inb(hc, 0);
203 tmp = SRC_GET16(hc, sca->dmac[0].cda);
204 if (tmp != 0x55AA) {
205 printf("sr%d: Error reading SCA 0x55AA, %x\n",
206 hc->cunit, tmp);
207 goto errexit;
210 membase = bus_get_resource_start(device, SYS_RES_MEMORY, 0);
211 memsize = SRC_WIN_SIZ;
212 if (bus_set_resource(device, SYS_RES_MEMORY, 0, membase, memsize))
213 goto errexit;
215 if (sr_allocate_memory(device, 0, SRC_WIN_SIZ))
216 goto errexit;
218 if (src_dpram_size(device) < 4)
219 goto errexit;
221 if (sr_allocate_irq(device, 0, 1))
222 goto errexit;
224 if (bus_get_resource(device, SYS_RES_IRQ, 0, &irq, &junk)) {
225 goto errexit;
228 * Do a little sanity check.
230 if (sr_irqtable[irq] == 0)
231 printf("sr%d: Warning: illegal interrupt %ld chosen.\n",
232 hc->cunit, irq);
235 * Bogus card configuration
237 if ((hc->numports > NCHAN) /* only 2 ports/card */
238 ||(hc->memsize > (512 * 1024))) /* no more than 256K */
239 goto errexit;
241 sr_deallocate_resources(device);
242 return (0);
244 errexit:
245 sr_deallocate_resources(device);
246 return (ENXIO);
250 * srattach_isa and srattach_pci allocate memory for hardc, softc and
251 * data buffers. It also does any initialization that is bus specific.
252 * At the end they call the common srattach() function.
254 static int
255 sr_isa_attach (device_t device)
257 u_char mar;
258 u_int32_t flags;
259 struct sr_hardc *hc;
261 hc = device_get_softc(device);
262 bzero(hc, sizeof(struct sr_hardc));
264 if (sr_allocate_ioport(device, 0, SRC_IO_SIZ))
265 goto errexit;
266 if (sr_allocate_memory(device, 0, SRC_WIN_SIZ))
267 goto errexit;
268 if (sr_allocate_irq(device, 0, 1))
269 goto errexit;
272 * We have to fill these in early because the SRC_PUT* and SRC_GET*
273 * macros use them.
275 hc->src_get8 = src_get8_io;
276 hc->src_get16 = src_get16_io;
277 hc->src_put8 = src_put8_io;
278 hc->src_put16 = src_put16_io;
280 hc->cardtype = SR_CRD_N2;
281 hc->cunit = device_get_unit(device);
282 hc->sca = 0;
283 hc->numports = NCHAN; /* assumed # of channels on the card */
284 flags = device_get_flags(device);
285 if (flags & SR_FLAGS_NCHAN_MSK)
286 hc->numports = flags & SR_FLAGS_NCHAN_MSK;
288 hc->mem_start = (caddr_t)rman_get_virtual(hc->res_memory);
289 hc->mem_end = hc->mem_start + SRC_WIN_SIZ;
290 hc->mem_pstart = 0;
291 hc->winmsk = SRC_WIN_MSK;
293 hc->mempages = src_dpram_size(device);
294 hc->memsize = hc->mempages * SRC_WIN_SIZ;
296 sr_outb(hc, SR_PCR, sr_inb(hc, SR_PCR) | SR_PCR_SCARUN);
297 sr_outb(hc, SR_PSR, sr_inb(hc, SR_PSR) | SR_PSR_EN_SCA_DMA);
298 sr_outb(hc, SR_MCR,
299 SR_MCR_DTR0 | SR_MCR_DTR1 | SR_MCR_TE0 | SR_MCR_TE1);
301 SRC_SET_ON(hc);
304 * Configure the card. Mem address, irq,
306 mar = (rman_get_start(hc->res_memory) >> 16) & SR_PCR_16M_SEL;
307 sr_outb(hc, SR_PCR, mar | (sr_inb(hc, SR_PCR) & ~SR_PCR_16M_SEL));
308 mar = rman_get_start(hc->res_memory) >> 12;
309 sr_outb(hc, SR_BAR, mar);
311 return sr_attach(device);
313 errexit:
314 sr_deallocate_resources(device);
315 return (ENXIO);
319 * I/O for ISA N2 card(s)
321 #define SRC_REG(y) ((((y) & 0xf) + (((y) & 0xf0) << 6)) | 0x8000)
323 static u_int
324 src_get8_io(struct sr_hardc *hc, u_int off)
326 return bus_space_read_1(hc->bt_ioport, hc->bh_ioport, SRC_REG(off));
329 static u_int
330 src_get16_io(struct sr_hardc *hc, u_int off)
332 return bus_space_read_2(hc->bt_ioport, hc->bh_ioport, SRC_REG(off));
335 static void
336 src_put8_io(struct sr_hardc *hc, u_int off, u_int val)
338 bus_space_write_1(hc->bt_ioport, hc->bh_ioport, SRC_REG(off), val);
341 static void
342 src_put16_io(struct sr_hardc *hc, u_int off, u_int val)
344 bus_space_write_2(hc->bt_ioport, hc->bh_ioport, SRC_REG(off), val);
347 static u_int
348 src_dpram_size(device_t device)
350 u_int pgs, i;
351 u_short *smem;
352 u_char mar;
353 u_long membase;
354 struct sr_hardc *hc;
356 hc = device_get_softc(device);
359 * OK, the board's interface registers seem to work. Now we'll see
360 * if the Dual-Ported RAM is fully accessible...
362 sr_outb(hc, SR_PCR, SR_PCR_EN_VPM | SR_PCR_ISA16);
363 sr_outb(hc, SR_PSR, SR_PSR_WIN_16K);
366 * Take the kernel "virtual" address supplied to us and convert
367 * it to a "real" address. Then program the card to use that.
369 membase = rman_get_start(hc->res_memory);
370 mar = (membase >> 16) & SR_PCR_16M_SEL;
371 sr_outb(hc, SR_PCR, mar | sr_inb(hc, SR_PCR));
372 mar = membase >> 12;
373 sr_outb(hc, SR_BAR, mar);
374 sr_outb(hc, SR_PCR, sr_inb(hc, SR_PCR) | SR_PCR_MEM_WIN);
375 smem = (u_short *)rman_get_virtual(hc->res_memory);/* DP RAM Address */
377 * Here we will perform the memory scan to size the device.
379 * This is done by marking each potential page with a magic number.
380 * We then loop through the pages looking for that magic number. As
381 * soon as we no longer see that magic number, we'll quit the scan,
382 * knowing that no more memory is present. This provides the number
383 * of pages present on the card.
385 * Note: We're sizing 16K memory granules.
387 for (i = 0; i <= SR_PSR_PG_SEL; i++) {
388 sr_outb(hc, SR_PSR, (sr_inb(hc, SR_PSR) & ~SR_PSR_PG_SEL) | i);
389 *smem = 0xAA55;
392 for (i = 0; i <= SR_PSR_PG_SEL; i++) {
393 sr_outb(hc, SR_PSR, (sr_inb(hc, SR_PSR) & ~SR_PSR_PG_SEL) | i);
394 if (*smem != 0xAA55) {
396 * If we have less than 64k of memory, give up. That
397 * is 4 x 16k pages.
399 if (i < 4) {
400 printf("sr%d: Bad mem page %d, mem %x, %x.\n",
401 hc->cunit, i, 0xAA55, *smem);
402 return 0;
404 break;
406 *smem = i;
409 hc->mempages = i;
410 hc->memsize = i * SRC_WIN_SIZ;
411 hc->winmsk = SRC_WIN_MSK;
412 pgs = i; /* final count of 16K pages */
415 * This next loop erases the contents of that page in DPRAM
417 for (i = 0; i <= pgs; i++) {
418 sr_outb(hc, SR_PSR, (sr_inb(hc, SR_PSR) & ~SR_PSR_PG_SEL) | i);
419 bzero(smem, SRC_WIN_SIZ);
422 SRC_SET_OFF(hc);
423 return (pgs);