bzsc.c revision 1.18 1 1.18 mhitch /* $NetBSD: bzsc.c,v 1.18 1997/10/10 04:53:39 mhitch Exp $ */
2 1.7 veego
3 1.1 chopps /*
4 1.1 chopps * Copyright (c) 1995 Daniel Widenfalk
5 1.1 chopps * Copyright (c) 1994 Christian E. Hopps
6 1.1 chopps * Copyright (c) 1982, 1990 The Regents of the University of California.
7 1.1 chopps * All rights reserved.
8 1.1 chopps *
9 1.1 chopps * Redistribution and use in source and binary forms, with or without
10 1.1 chopps * modification, are permitted provided that the following conditions
11 1.1 chopps * are met:
12 1.1 chopps * 1. Redistributions of source code must retain the above copyright
13 1.1 chopps * notice, this list of conditions and the following disclaimer.
14 1.1 chopps * 2. Redistributions in binary form must reproduce the above copyright
15 1.1 chopps * notice, this list of conditions and the following disclaimer in the
16 1.1 chopps * documentation and/or other materials provided with the distribution.
17 1.1 chopps * 3. All advertising materials mentioning features or use of this software
18 1.1 chopps * must display the following acknowledgement:
19 1.18 mhitch * This product includes software developed by the University of
20 1.18 mhitch * California, Berkeley and its contributors.
21 1.1 chopps * 4. Neither the name of the University nor the names of its contributors
22 1.1 chopps * may be used to endorse or promote products derived from this software
23 1.1 chopps * without specific prior written permission.
24 1.1 chopps *
25 1.1 chopps * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 1.1 chopps * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 1.1 chopps * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 1.1 chopps * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 1.1 chopps * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 1.1 chopps * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 1.1 chopps * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 1.1 chopps * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 1.1 chopps * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 1.1 chopps * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 1.1 chopps * SUCH DAMAGE.
36 1.18 mhitch *
37 1.18 mhitch * @(#)dma.c
38 1.1 chopps */
39 1.1 chopps
40 1.1 chopps #include <sys/param.h>
41 1.1 chopps #include <sys/systm.h>
42 1.1 chopps #include <sys/kernel.h>
43 1.1 chopps #include <sys/device.h>
44 1.18 mhitch #include <scsi/scsi_all.h>
45 1.18 mhitch #include <scsi/scsiconf.h>
46 1.18 mhitch #include <vm/vm.h>
47 1.18 mhitch #include <vm/vm_kern.h>
48 1.18 mhitch #include <vm/vm_page.h>
49 1.18 mhitch #include <machine/pmap.h>
50 1.18 mhitch #include <amiga/amiga/custom.h>
51 1.18 mhitch #include <amiga/amiga/cc.h>
52 1.18 mhitch #include <amiga/amiga/device.h>
53 1.1 chopps #include <amiga/amiga/isr.h>
54 1.18 mhitch #include <amiga/dev/sfasreg.h>
55 1.18 mhitch #include <amiga/dev/sfasvar.h>
56 1.18 mhitch #include <amiga/dev/zbusvar.h>
57 1.18 mhitch #include <amiga/dev/bzscreg.h>
58 1.17 mhitch #include <amiga/dev/bzscvar.h>
59 1.1 chopps
60 1.18 mhitch void bzscattach __P((struct device *, struct device *, void *));
61 1.18 mhitch int bzscmatch __P((struct device *, struct cfdata *, void *));
62 1.17 mhitch
63 1.18 mhitch struct scsi_adapter bzsc_scsiswitch = {
64 1.18 mhitch sfas_scsicmd,
65 1.18 mhitch sfas_minphys,
66 1.18 mhitch 0, /* no lun support */
67 1.18 mhitch 0, /* no lun support */
68 1.17 mhitch };
69 1.1 chopps
70 1.18 mhitch struct scsi_device bzsc_scsidev = {
71 1.18 mhitch NULL, /* use default error handler */
72 1.18 mhitch NULL, /* do not have a start functio */
73 1.18 mhitch NULL, /* have no async handler */
74 1.18 mhitch NULL, /* Use default done routine */
75 1.1 chopps };
76 1.1 chopps
77 1.18 mhitch struct cfattach bzsc_ca = {
78 1.18 mhitch sizeof(struct bzsc_softc), bzscmatch, bzscattach
79 1.1 chopps };
80 1.1 chopps
81 1.18 mhitch struct cfdriver bzsc_cd = {
82 1.18 mhitch NULL, "bzsc", DV_DULL, NULL, 0
83 1.6 thorpej };
84 1.1 chopps
85 1.18 mhitch int bzsc_intr __P((void *));
86 1.18 mhitch void bzsc_set_dma_adr __P((struct sfas_softc *sc, vm_offset_t ptr, int mode));
87 1.18 mhitch void bzsc_set_dma_tc __P((struct sfas_softc *sc, unsigned int len));
88 1.18 mhitch int bzsc_setup_dma __P((struct sfas_softc *sc, vm_offset_t ptr, int len,
89 1.18 mhitch int mode));
90 1.18 mhitch int bzsc_build_dma_chain __P((struct sfas_softc *sc,
91 1.18 mhitch struct sfas_dma_chain *chain, void *p, int l));
92 1.18 mhitch int bzsc_need_bump __P((struct sfas_softc *sc, vm_offset_t ptr, int len));
93 1.18 mhitch void bzsc_led_dummy __P((struct sfas_softc *sc, int mode));
94 1.1 chopps
95 1.1 chopps /*
96 1.18 mhitch * if we are an Advanced Systems & Software FastlaneZ3
97 1.1 chopps */
98 1.7 veego int
99 1.18 mhitch bzscmatch(pdp, cfp, auxp)
100 1.18 mhitch struct device *pdp;
101 1.18 mhitch struct cfdata *cfp;
102 1.18 mhitch void *auxp;
103 1.1 chopps {
104 1.7 veego struct zbus_args *zap;
105 1.18 mhitch vu_char *ta;
106 1.1 chopps
107 1.7 veego if (!is_a1200())
108 1.7 veego return(0);
109 1.18 mhitch
110 1.18 mhitch zap = auxp;
111 1.18 mhitch if (zap->manid != 0x2140 || zap->prodid != 11)
112 1.18 mhitch return(0);
113 1.18 mhitch
114 1.18 mhitch ta = (vu_char *)(((char *)zap->va)+0x10010);
115 1.18 mhitch if (badbaddr((caddr_t)ta))
116 1.18 mhitch return(0);
117 1.18 mhitch
118 1.18 mhitch *ta = 0;
119 1.18 mhitch *ta = 1;
120 1.18 mhitch DELAY(5);
121 1.18 mhitch if (*ta != 1)
122 1.9 is return(0);
123 1.18 mhitch
124 1.9 is return(1);
125 1.1 chopps }
126 1.1 chopps
127 1.7 veego void
128 1.18 mhitch bzscattach(pdp, dp, auxp)
129 1.18 mhitch struct device *pdp;
130 1.18 mhitch struct device *dp;
131 1.18 mhitch void *auxp;
132 1.1 chopps {
133 1.18 mhitch struct bzsc_softc *sc;
134 1.1 chopps struct zbus_args *zap;
135 1.18 mhitch bzsc_regmap_p rp;
136 1.18 mhitch vu_char *fas;
137 1.1 chopps
138 1.18 mhitch zap = auxp;
139 1.18 mhitch fas = (vu_char *)(((char *)zap->va)+0x10000);
140 1.1 chopps
141 1.18 mhitch sc = (struct bzsc_softc *)dp;
142 1.18 mhitch rp = &sc->sc_regmap;
143 1.17 mhitch
144 1.18 mhitch rp->FAS216.sfas_tc_low = &fas[0x00];
145 1.18 mhitch rp->FAS216.sfas_tc_mid = &fas[0x02];
146 1.18 mhitch rp->FAS216.sfas_fifo = &fas[0x04];
147 1.18 mhitch rp->FAS216.sfas_command = &fas[0x06];
148 1.18 mhitch rp->FAS216.sfas_dest_id = &fas[0x08];
149 1.18 mhitch rp->FAS216.sfas_timeout = &fas[0x0A];
150 1.18 mhitch rp->FAS216.sfas_syncper = &fas[0x0C];
151 1.18 mhitch rp->FAS216.sfas_syncoff = &fas[0x0E];
152 1.18 mhitch rp->FAS216.sfas_config1 = &fas[0x10];
153 1.18 mhitch rp->FAS216.sfas_clkconv = &fas[0x12];
154 1.18 mhitch rp->FAS216.sfas_test = &fas[0x14];
155 1.18 mhitch rp->FAS216.sfas_config2 = &fas[0x16];
156 1.18 mhitch rp->FAS216.sfas_config3 = &fas[0x18];
157 1.18 mhitch rp->FAS216.sfas_tc_high = &fas[0x1C];
158 1.18 mhitch rp->FAS216.sfas_fifo_bot = &fas[0x1E];
159 1.18 mhitch rp->cclkaddr = &fas[0x21];
160 1.18 mhitch rp->epowaddr = &fas[0x31];
161 1.18 mhitch
162 1.18 mhitch sc->sc_softc.sc_fas = (sfas_regmap_p)rp;
163 1.18 mhitch sc->sc_softc.sc_spec = 0;
164 1.18 mhitch
165 1.18 mhitch sc->sc_softc.sc_led = bzsc_led_dummy;
166 1.18 mhitch
167 1.18 mhitch sc->sc_softc.sc_setup_dma = bzsc_setup_dma;
168 1.18 mhitch sc->sc_softc.sc_build_dma_chain = bzsc_build_dma_chain;
169 1.18 mhitch sc->sc_softc.sc_need_bump = bzsc_need_bump;
170 1.18 mhitch
171 1.18 mhitch sc->sc_softc.sc_clock_freq = 40; /* BlizzardII 1230 runs at 40MHz? */
172 1.18 mhitch sc->sc_softc.sc_timeout = 250; /* Set default timeout to 250ms */
173 1.18 mhitch sc->sc_softc.sc_config_flags = 0;
174 1.18 mhitch sc->sc_softc.sc_host_id = 7;
175 1.18 mhitch
176 1.18 mhitch sc->sc_softc.sc_bump_sz = NBPG;
177 1.18 mhitch sc->sc_softc.sc_bump_pa = 0x0;
178 1.18 mhitch
179 1.18 mhitch sfasinitialize((struct sfas_softc *)sc);
180 1.18 mhitch
181 1.18 mhitch sc->sc_softc.sc_link.channel = SCSI_CHANNEL_ONLY_ONE;
182 1.18 mhitch sc->sc_softc.sc_link.adapter_softc = sc;
183 1.18 mhitch sc->sc_softc.sc_link.adapter_target = sc->sc_softc.sc_host_id;
184 1.18 mhitch sc->sc_softc.sc_link.adapter = &bzsc_scsiswitch;
185 1.18 mhitch sc->sc_softc.sc_link.device = &bzsc_scsidev;
186 1.18 mhitch sc->sc_softc.sc_link.openings = 1;
187 1.18 mhitch sc->sc_softc.sc_link.max_target = 7;
188 1.17 mhitch
189 1.18 mhitch printf("\n");
190 1.1 chopps
191 1.18 mhitch sc->sc_softc.sc_isr.isr_intr = bzsc_intr;
192 1.18 mhitch sc->sc_softc.sc_isr.isr_arg = &sc->sc_softc;
193 1.18 mhitch sc->sc_softc.sc_isr.isr_ipl = 2;
194 1.18 mhitch add_isr(&sc->sc_softc.sc_isr);
195 1.1 chopps
196 1.18 mhitch /* attach all scsi units on us */
197 1.18 mhitch config_found(dp, &sc->sc_softc.sc_link, scsiprint);
198 1.17 mhitch }
199 1.17 mhitch
200 1.18 mhitch int
201 1.18 mhitch bzsc_intr(arg)
202 1.18 mhitch void *arg;
203 1.18 mhitch {
204 1.18 mhitch struct sfas_softc *dev = arg;
205 1.18 mhitch bzsc_regmap_p rp;
206 1.18 mhitch int quickints;
207 1.18 mhitch
208 1.18 mhitch rp = (bzsc_regmap_p)dev->sc_fas;
209 1.18 mhitch
210 1.18 mhitch if (!(*rp->FAS216.sfas_status & SFAS_STAT_INTERRUPT_PENDING))
211 1.18 mhitch return(0);
212 1.18 mhitch
213 1.18 mhitch quickints = 16;
214 1.18 mhitch do {
215 1.18 mhitch dev->sc_status = *rp->FAS216.sfas_status;
216 1.18 mhitch dev->sc_interrupt = *rp->FAS216.sfas_interrupt;
217 1.18 mhitch
218 1.18 mhitch if (dev->sc_interrupt & SFAS_INT_RESELECTED) {
219 1.18 mhitch dev->sc_resel[0] = *rp->FAS216.sfas_fifo;
220 1.18 mhitch dev->sc_resel[1] = *rp->FAS216.sfas_fifo;
221 1.18 mhitch }
222 1.18 mhitch sfasintr(dev);
223 1.18 mhitch } while((*rp->FAS216.sfas_status & SFAS_STAT_INTERRUPT_PENDING) &&
224 1.18 mhitch --quickints);
225 1.1 chopps
226 1.18 mhitch return(1);
227 1.18 mhitch }
228 1.1 chopps
229 1.18 mhitch /* --------- */
230 1.18 mhitch void
231 1.18 mhitch bzsc_set_dma_adr(sc, ptr, mode)
232 1.18 mhitch struct sfas_softc *sc;
233 1.18 mhitch vm_offset_t ptr;
234 1.18 mhitch int mode;
235 1.18 mhitch {
236 1.18 mhitch bzsc_regmap_p rp;
237 1.18 mhitch unsigned long p;
238 1.18 mhitch
239 1.18 mhitch rp = (bzsc_regmap_p)sc->sc_fas;
240 1.18 mhitch
241 1.18 mhitch p = ((unsigned long)ptr)>>1;
242 1.18 mhitch
243 1.18 mhitch if (mode == SFAS_DMA_WRITE)
244 1.18 mhitch p |= BZSC_DMA_WRITE;
245 1.18 mhitch else
246 1.18 mhitch p |= BZSC_DMA_READ;
247 1.18 mhitch
248 1.18 mhitch *rp->epowaddr = (u_char)(p>>24) & 0xFF;
249 1.18 mhitch *rp->cclkaddr = (u_char)(p>>16) & 0xFF;
250 1.18 mhitch *rp->cclkaddr = (u_char)(p>> 8) & 0xFF;
251 1.18 mhitch *rp->cclkaddr = (u_char)(p ) & 0xFF;
252 1.1 chopps }
253 1.1 chopps
254 1.18 mhitch /* Set DMA transfer counter */
255 1.17 mhitch void
256 1.18 mhitch bzsc_set_dma_tc(sc, len)
257 1.18 mhitch struct sfas_softc *sc;
258 1.18 mhitch unsigned int len;
259 1.1 chopps {
260 1.18 mhitch *sc->sc_fas->sfas_tc_low = len; len >>= 8;
261 1.18 mhitch *sc->sc_fas->sfas_tc_mid = len; len >>= 8;
262 1.18 mhitch *sc->sc_fas->sfas_tc_high = len;
263 1.17 mhitch }
264 1.1 chopps
265 1.18 mhitch /* Initialize DMA for transfer */
266 1.17 mhitch int
267 1.18 mhitch bzsc_setup_dma(sc, ptr, len, mode)
268 1.18 mhitch struct sfas_softc *sc;
269 1.18 mhitch vm_offset_t ptr;
270 1.18 mhitch int len;
271 1.18 mhitch int mode;
272 1.18 mhitch {
273 1.18 mhitch int retval;
274 1.18 mhitch
275 1.18 mhitch retval = 0;
276 1.18 mhitch
277 1.18 mhitch switch(mode) {
278 1.18 mhitch case SFAS_DMA_READ:
279 1.18 mhitch case SFAS_DMA_WRITE:
280 1.18 mhitch bzsc_set_dma_adr(sc, ptr, mode);
281 1.18 mhitch bzsc_set_dma_tc(sc, len);
282 1.18 mhitch break;
283 1.18 mhitch case SFAS_DMA_CLEAR:
284 1.18 mhitch default:
285 1.18 mhitch retval = (*sc->sc_fas->sfas_tc_high << 16) |
286 1.18 mhitch (*sc->sc_fas->sfas_tc_mid << 8) |
287 1.18 mhitch *sc->sc_fas->sfas_tc_low;
288 1.18 mhitch
289 1.18 mhitch bzsc_set_dma_tc(sc, 0);
290 1.18 mhitch break;
291 1.18 mhitch }
292 1.1 chopps
293 1.18 mhitch return(retval);
294 1.1 chopps }
295 1.1 chopps
296 1.18 mhitch /* Check if address and len is ok for DMA transfer */
297 1.18 mhitch int
298 1.18 mhitch bzsc_need_bump(sc, ptr, len)
299 1.18 mhitch struct sfas_softc *sc;
300 1.18 mhitch vm_offset_t ptr;
301 1.18 mhitch int len;
302 1.1 chopps {
303 1.18 mhitch int p;
304 1.1 chopps
305 1.18 mhitch p = (int)ptr & 0x03;
306 1.1 chopps
307 1.18 mhitch if (p) {
308 1.18 mhitch p = 4-p;
309 1.1 chopps
310 1.18 mhitch if (len < 256)
311 1.18 mhitch p = len;
312 1.17 mhitch }
313 1.1 chopps
314 1.18 mhitch return(p);
315 1.1 chopps }
316 1.1 chopps
317 1.18 mhitch /* Interrupt driven routines */
318 1.7 veego int
319 1.18 mhitch bzsc_build_dma_chain(sc, chain, p, l)
320 1.18 mhitch struct sfas_softc *sc;
321 1.18 mhitch struct sfas_dma_chain *chain;
322 1.18 mhitch void *p;
323 1.18 mhitch int l;
324 1.1 chopps {
325 1.18 mhitch int n;
326 1.18 mhitch
327 1.18 mhitch if (!l)
328 1.18 mhitch return(0);
329 1.18 mhitch
330 1.18 mhitch #define set_link(n, p, l, f)\
331 1.18 mhitch do { chain[n].ptr = (p); chain[n].len = (l); chain[n++].flg = (f); } while(0)
332 1.1 chopps
333 1.18 mhitch n = 0;
334 1.1 chopps
335 1.18 mhitch if (l < 512)
336 1.18 mhitch set_link(n, (vm_offset_t)p, l, SFAS_CHAIN_BUMP);
337 1.18 mhitch else if (
338 1.8 is #if defined(M68040) || defined(M68060)
339 1.18 mhitch ((mmutype == MMU_68040) && ((vm_offset_t)p >= 0xFFFC0000)) &&
340 1.1 chopps #endif
341 1.18 mhitch ((vm_offset_t)p >= 0xFF000000)) {
342 1.18 mhitch int len;
343 1.1 chopps
344 1.18 mhitch while(l) {
345 1.18 mhitch len = ((l > sc->sc_bump_sz) ? sc->sc_bump_sz : l);
346 1.1 chopps
347 1.18 mhitch set_link(n, (vm_offset_t)p, len, SFAS_CHAIN_BUMP);
348 1.1 chopps
349 1.18 mhitch p += len;
350 1.18 mhitch l -= len;
351 1.18 mhitch }
352 1.18 mhitch } else {
353 1.18 mhitch char *ptr;
354 1.18 mhitch vm_offset_t pa, lastpa;
355 1.18 mhitch int len, prelen, max_t;
356 1.18 mhitch
357 1.18 mhitch ptr = p;
358 1.18 mhitch len = l;
359 1.18 mhitch
360 1.18 mhitch pa = kvtop(ptr);
361 1.18 mhitch prelen = ((int)ptr & 0x03);
362 1.18 mhitch
363 1.18 mhitch if (prelen) {
364 1.18 mhitch prelen = 4-prelen;
365 1.18 mhitch set_link(n, (vm_offset_t)ptr, prelen, SFAS_CHAIN_BUMP);
366 1.18 mhitch ptr += prelen;
367 1.18 mhitch len -= prelen;
368 1.18 mhitch }
369 1.1 chopps
370 1.18 mhitch lastpa = 0;
371 1.18 mhitch while(len > 3) {
372 1.18 mhitch pa = kvtop(ptr);
373 1.18 mhitch max_t = NBPG - (pa & PGOFSET);
374 1.18 mhitch if (max_t > len)
375 1.18 mhitch max_t = len;
376 1.18 mhitch
377 1.18 mhitch max_t &= ~3;
378 1.18 mhitch
379 1.18 mhitch if (lastpa == pa)
380 1.18 mhitch sc->sc_chain[n-1].len += max_t;
381 1.18 mhitch else
382 1.18 mhitch set_link(n, pa, max_t, SFAS_CHAIN_DMA);
383 1.18 mhitch
384 1.18 mhitch lastpa = pa+max_t;
385 1.18 mhitch
386 1.18 mhitch ptr += max_t;
387 1.18 mhitch len -= max_t;
388 1.18 mhitch }
389 1.18 mhitch
390 1.18 mhitch if (len)
391 1.18 mhitch set_link(n, (vm_offset_t)ptr, len, SFAS_CHAIN_BUMP);
392 1.18 mhitch }
393 1.1 chopps
394 1.18 mhitch return(n);
395 1.1 chopps }
396 1.1 chopps
397 1.18 mhitch /* Turn on led */
398 1.18 mhitch void bzsc_led_dummy(sc, mode)
399 1.18 mhitch struct sfas_softc *sc;
400 1.18 mhitch int mode;
401 1.1 chopps {
402 1.1 chopps }
403