Deleted Added
full compact
1/*
2 * Device driver for Specialix range (SI/XIO) of serial line multiplexors.
3 *
4 * Copyright (C) 2000, Peter Wemm <peter@netplex.com.au>
5 *
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 * notices, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notices, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED
16 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
18 * NO EVENT SHALL THE AUTHORS BE LIABLE.
19 *
20 * $FreeBSD: head/sys/dev/si/si_isa.c 106572 2002-11-07 19:56:21Z jhb $
20 */
21
22#include <sys/cdefs.h>
23__FBSDID("$FreeBSD: head/sys/dev/si/si_isa.c 119419 2003-08-24 18:03:45Z obrien $");
24
25#include "opt_debug_si.h"
26
27#include <sys/param.h>
28#include <sys/systm.h>
29#include <sys/kernel.h>
30#include <sys/bus.h>
31#include <machine/bus.h>
32#include <sys/rman.h>
33#include <machine/resource.h>
34
35#include <dev/si/sireg.h>
36#include <dev/si/sivar.h>
37
38#include <isa/isavar.h>
39
40/* Look for a valid board at the given mem addr */
41static int
42si_isa_probe(device_t dev)
43{
44 struct si_softc *sc;
45 int type;
46 u_int i, ramsize;
47 volatile unsigned char was, *ux;
48 volatile unsigned char *maddr;
49 unsigned char *paddr;
50 int unit;
51
52 /* No pnp support */
53 if (isa_get_vendorid(dev))
54 return (ENXIO);
55
56 sc = device_get_softc(dev);
57 unit = device_get_unit(dev);
58
59 sc->sc_mem_rid = 0;
60 sc->sc_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
61 &sc->sc_mem_rid,
62 0, ~0, SIPROBEALLOC, RF_ACTIVE);
63 if (!sc->sc_mem_res) {
64 device_printf(dev, "cannot allocate memory resource\n");
65 return ENXIO;
66 }
67 paddr = (caddr_t)rman_get_start(sc->sc_mem_res);/* physical */
68 maddr = rman_get_virtual(sc->sc_mem_res); /* in kvm */
69
70 DPRINT((0, DBG_AUTOBOOT, "si%d: probe at virtual=0x%x physical=0x%x\n",
71 unit, maddr, paddr));
72
73 /*
74 * this is a lie, but it's easier than trying to handle caching
75 * and ram conflicts in the >1M and <16M region.
76 */
77 if ((caddr_t)paddr < (caddr_t)0xA0000 ||
78 (caddr_t)paddr >= (caddr_t)0x100000) {
79 device_printf(dev, "maddr (%p) out of range\n", paddr);
80 goto fail;
81 }
82
83 if (((uintptr_t)paddr & 0x7fff) != 0) {
84 device_printf(dev, "maddr (%p) not on 32k boundary\n", paddr);
85 goto fail;
86 }
87
88 /* Is there anything out there? (0x17 is just an arbitrary number) */
89 *maddr = 0x17;
90 if (*maddr != 0x17) {
91 device_printf(dev, "0x17 check fail at phys %p\n", paddr);
92 goto fail;
93 }
94 /*
95 * Let's look first for a JET ISA card, since that's pretty easy
96 *
97 * All jet hosts are supposed to have this string in the IDROM,
98 * but it's not worth checking on self-IDing busses like PCI.
99 */
100 {
101 unsigned char *jet_chk_str = "JET HOST BY KEV#";
102
103 for (i = 0; i < strlen(jet_chk_str); i++)
104 if (jet_chk_str[i] != *(maddr + SIJETIDSTR + 2 * i))
105 goto try_mk2;
106 }
107 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL, "si%d: JET first check - 0x%x\n",
108 unit, (*(maddr+SIJETIDBASE))));
109 if (*(maddr+SIJETIDBASE) != (SISPLXID&0xff))
110 goto try_mk2;
111 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL, "si%d: JET second check - 0x%x\n",
112 unit, (*(maddr+SIJETIDBASE+2))));
113 if (*(maddr+SIJETIDBASE+2) != ((SISPLXID&0xff00)>>8))
114 goto try_mk2;
115 /* It must be a Jet ISA or RIO card */
116 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL, "si%d: JET id check - 0x%x\n",
117 unit, (*(maddr+SIUNIQID))));
118 if ((*(maddr+SIUNIQID) & 0xf0) != 0x20)
119 goto try_mk2;
120 /* It must be a Jet ISA SI/XIO card */
121 *(maddr + SIJETCONFIG) = 0;
122 type = SIJETISA;
123 ramsize = SIJET_RAMSIZE;
124 goto got_card;
125
126try_mk2:
127 /*
128 * OK, now to see if whatever responded is really an SI card.
129 * Try for a MK II next (SIHOST2)
130 */
131 for (i = SIPLSIG; i < SIPLSIG + 8; i++)
132 if ((*(maddr+i) & 7) != (~(unsigned char)i & 7))
133 goto try_mk1;
134
135 /* It must be an SIHOST2 */
136 *(maddr + SIPLRESET) = 0;
137 *(maddr + SIPLIRQCLR) = 0;
138 *(maddr + SIPLIRQSET) = 0x10;
139 type = SIHOST2;
140 ramsize = SIHOST2_RAMSIZE;
141 goto got_card;
142
143try_mk1:
144 /*
145 * Its not a MK II, so try for a MK I (SIHOST)
146 */
147 *(maddr+SIRESET) = 0x0; /* reset the card */
148 *(maddr+SIINTCL) = 0x0; /* clear int */
149 *(maddr+SIRAM) = 0x17;
150 if (*(maddr+SIRAM) != (unsigned char)0x17)
151 goto fail;
152 *(maddr+0x7ff8) = 0x17;
153 if (*(maddr+0x7ff8) != (unsigned char)0x17) {
154 device_printf(dev, "0x17 check fail at phys %p = 0x%x\n",
155 paddr+0x77f8, *(maddr+0x77f8));
156 goto fail;
157 }
158
159 /* It must be an SIHOST (maybe?) - there must be a better way XXX */
160 type = SIHOST;
161 ramsize = SIHOST_RAMSIZE;
162
163got_card:
164 DPRINT((0, DBG_AUTOBOOT, "si%d: found type %d card, try memory test\n",
165 unit, type));
166 /* Try the acid test */
167 ux = maddr + SIRAM;
168 for (i = 0; i < ramsize; i++, ux++)
169 *ux = (unsigned char)(i&0xff);
170 ux = maddr + SIRAM;
171 for (i = 0; i < ramsize; i++, ux++) {
172 if ((was = *ux) != (unsigned char)(i&0xff)) {
173 device_printf(dev,
174 "memtest fail at phys %p, was %x should be %x\n",
175 paddr + i, was, i & 0xff);
176 goto fail;
177 }
178 }
179
180 /* clear out the RAM */
181 ux = maddr + SIRAM;
182 for (i = 0; i < ramsize; i++)
183 *ux++ = 0;
184 ux = maddr + SIRAM;
185 for (i = 0; i < ramsize; i++) {
186 if ((was = *ux++) != 0) {
187 device_printf(dev, "clear fail at phys %p, was %x\n",
188 paddr + i, was);
189 goto fail;
190 }
191 }
192
193 /*
194 * Success, we've found a valid board, now fill in
195 * the adapter structure.
196 */
197 switch (type) {
198 case SIHOST2:
199 switch (isa_get_irq(dev)) {
200 case 11:
201 case 12:
202 case 15:
203 break;
204 default:
205 device_printf(dev,
206 "bad IRQ value - %d (11, 12, 15 allowed)\n",
207 isa_get_irq(dev));
208 goto fail;
209 }
210 sc->sc_memsize = SIHOST2_MEMSIZE;
211 break;
212 case SIHOST:
213 switch (isa_get_irq(dev)) {
214 case 11:
215 case 12:
216 case 15:
217 break;
218 default:
219 device_printf(dev,
220 "bad IRQ value - %d (11, 12, 15 allowed)\n",
221 isa_get_irq(dev));
222 goto fail;
223 }
224 sc->sc_memsize = SIHOST_MEMSIZE;
225 break;
226 case SIJETISA:
227 switch (isa_get_irq(dev)) {
228 case 9:
229 case 10:
230 case 11:
231 case 12:
232 case 15:
233 break;
234 default:
235 device_printf(dev,
236 "bad IRQ value - %d (9, 10, 11, 12, 15 allowed)\n",
237 isa_get_irq(dev));
238 goto fail;
239 }
240 sc->sc_memsize = SIJETISA_MEMSIZE;
241 break;
242 case SIMCA: /* MCA */
243 default:
244 device_printf(dev, "card type %d not supported\n", type);
245 goto fail;
246 }
247 sc->sc_type = type;
248 bus_release_resource(dev, SYS_RES_MEMORY,
249 sc->sc_mem_rid, sc->sc_mem_res);
250 sc->sc_mem_res = 0;
251 return (0); /* success! */
252
253fail:
254 if (sc->sc_mem_res) {
255 bus_release_resource(dev, SYS_RES_MEMORY,
256 sc->sc_mem_rid, sc->sc_mem_res);
257 sc->sc_mem_res = 0;
258 }
259 return(EINVAL);
260}
261
262static int
263si_isa_attach(device_t dev)
264{
265 int error;
266 void *ih;
267 struct si_softc *sc;
268
269 error = 0;
270 ih = NULL;
271 sc = device_get_softc(dev);
272
273 sc->sc_mem_rid = 0;
274 sc->sc_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
275 &sc->sc_mem_rid,
276 0, ~0, 1, RF_ACTIVE);
277 if (!sc->sc_mem_res) {
278 device_printf(dev, "couldn't map memory\n");
279 goto fail;
280 }
281 sc->sc_paddr = (caddr_t)rman_get_start(sc->sc_mem_res);
282 sc->sc_maddr = rman_get_virtual(sc->sc_mem_res);
283
284 sc->sc_irq_rid = 0;
285 sc->sc_irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->sc_irq_rid,
286 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
287 if (!sc->sc_irq_res) {
288 device_printf(dev, "couldn't allocate interrupt\n");
289 goto fail;
290 }
291 sc->sc_irq = rman_get_start(sc->sc_irq_res);
292 error = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_TTY,
293 si_intr, sc,&ih);
294 if (error) {
295 device_printf(dev, "couldn't activate interrupt\n");
296 goto fail;
297 }
298
299 error = siattach(dev);
300 if (error)
301 goto fail;
302 return (0); /* success */
303
304fail:
305 if (error == 0)
306 error = ENXIO;
307 if (sc->sc_irq_res) {
308 if (ih)
309 bus_teardown_intr(dev, sc->sc_irq_res, ih);
310 bus_release_resource(dev, SYS_RES_IRQ,
311 sc->sc_irq_rid, sc->sc_irq_res);
312 sc->sc_irq_res = 0;
313 }
314 if (sc->sc_mem_res) {
315 bus_release_resource(dev, SYS_RES_MEMORY,
316 sc->sc_mem_rid, sc->sc_mem_res);
317 sc->sc_mem_res = 0;
318 }
319 return (error);
320}
321
322static device_method_t si_isa_methods[] = {
323 /* Device interface */
324 DEVMETHOD(device_probe, si_isa_probe),
325 DEVMETHOD(device_attach, si_isa_attach),
326
327 { 0, 0 }
328};
329
330static driver_t si_isa_driver = {
331 "si",
332 si_isa_methods,
333 sizeof(struct si_softc),
334};
335
336DRIVER_MODULE(si, isa, si_isa_driver, si_devclass, 0, 0);