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