wstsc.c revision 1.9 1 /* $NetBSD: wstsc.c,v 1.9 1995/08/18 15:28:17 chopps Exp $ */
2
3 /*
4 * Copyright (c) 1994 Michael L. Hitch
5 * Copyright (c) 1982, 1990 The Regents of the University of California.
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 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * @(#)supradma.c
37 */
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/kernel.h>
41 #include <sys/device.h>
42 #include <scsi/scsi_all.h>
43 #include <scsi/scsiconf.h>
44 #include <amiga/amiga/device.h>
45 #include <amiga/amiga/isr.h>
46 #include <amiga/dev/scireg.h>
47 #include <amiga/dev/scivar.h>
48 #include <amiga/dev/zbusvar.h>
49
50 int wstscprint __P((void *auxp, char *));
51 void wstscattach __P((struct device *, struct device *, void *));
52 int wstscmatch __P((struct device *, struct cfdata *, void *));
53
54 int wstsc_dma_xfer_in __P((struct sci_softc *dev, int len,
55 register u_char *buf, int phase));
56 int wstsc_dma_xfer_out __P((struct sci_softc *dev, int len,
57 register u_char *buf, int phase));
58 int wstsc_dma_xfer_in2 __P((struct sci_softc *dev, int len,
59 register u_short *buf, int phase));
60 int wstsc_dma_xfer_out2 __P((struct sci_softc *dev, int len,
61 register u_short *buf, int phase));
62 int wstsc_intr __P((struct sci_softc *));
63
64 struct scsi_adapter wstsc_scsiswitch = {
65 sci_scsicmd,
66 sci_minphys,
67 0, /* no lun support */
68 0, /* no lun support */
69 };
70
71 struct scsi_device wstsc_scsidev = {
72 NULL, /* use default error handler */
73 NULL, /* do not have a start functio */
74 NULL, /* have no async handler */
75 NULL, /* Use default done routine */
76 };
77
78 #define QPRINTF
79
80 #ifdef DEBUG
81 extern int sci_debug;
82 #endif
83
84 extern int sci_data_wait;
85
86 int supradma_pseudo = 0; /* 0=none, 1=byte, 2=word */
87
88 struct cfdriver wstsccd = {
89 NULL, "wstsc", (cfmatch_t)wstscmatch, wstscattach,
90 DV_DULL, sizeof(struct sci_softc), NULL, 0 };
91
92 /*
93 * if this a Supra WordSync board
94 */
95 int
96 wstscmatch(pdp, cdp, auxp)
97 struct device *pdp;
98 struct cfdata *cdp;
99 void *auxp;
100 {
101 struct zbus_args *zap;
102
103 zap = auxp;
104
105 /*
106 * Check manufacturer and product id.
107 */
108 if (zap->manid == 1056 && (
109 zap->prodid == 12 || /* WordSync */
110 zap->prodid == 13)) /* ByteSync */
111 return(1);
112 else
113 return(0);
114 }
115
116 void
117 wstscattach(pdp, dp, auxp)
118 struct device *pdp, *dp;
119 void *auxp;
120 {
121 volatile u_char *rp;
122 struct sci_softc *sc;
123 struct zbus_args *zap;
124
125 printf("\n");
126
127 zap = auxp;
128
129 sc = (struct sci_softc *)dp;
130 rp = zap->va;
131 /*
132 * set up 5380 register pointers
133 * (Needs check on which Supra board this is - for now,
134 * just do the WordSync)
135 */
136 sc->sci_data = rp + 0;
137 sc->sci_odata = rp + 0;
138 sc->sci_icmd = rp + 2;
139 sc->sci_mode = rp + 4;
140 sc->sci_tcmd = rp + 6;
141 sc->sci_bus_csr = rp + 8;
142 sc->sci_sel_enb = rp + 8;
143 sc->sci_csr = rp + 10;
144 sc->sci_dma_send = rp + 10;
145 sc->sci_idata = rp + 12;
146 sc->sci_trecv = rp + 12;
147 sc->sci_iack = rp + 14;
148 sc->sci_irecv = rp + 14;
149
150 if (supradma_pseudo == 2) {
151 sc->dma_xfer_in = wstsc_dma_xfer_in2;
152 sc->dma_xfer_out = wstsc_dma_xfer_out2;
153 }
154 else if (supradma_pseudo == 1) {
155 sc->dma_xfer_in = wstsc_dma_xfer_in;
156 sc->dma_xfer_out = wstsc_dma_xfer_out;
157 }
158
159 sc->sc_isr.isr_intr = wstsc_intr;
160 sc->sc_isr.isr_arg = sc;
161 sc->sc_isr.isr_ipl = 2;
162 add_isr(&sc->sc_isr);
163
164 scireset(sc);
165
166 sc->sc_link.adapter_softc = sc;
167 sc->sc_link.adapter_target = 7;
168 sc->sc_link.adapter = &wstsc_scsiswitch;
169 sc->sc_link.device = &wstsc_scsidev;
170 sc->sc_link.openings = 1;
171 TAILQ_INIT(&sc->sc_xslist);
172
173 /*
174 * attach all scsi units on us
175 */
176 config_found(dp, &sc->sc_link, wstscprint);
177 }
178
179 /*
180 * print diag if pnp is NULL else just extra
181 */
182 int
183 wstscprint(auxp, pnp)
184 void *auxp;
185 char *pnp;
186 {
187 if (pnp == NULL)
188 return(UNCONF);
189 return(QUIET);
190 }
191
192 int
193 wstsc_dma_xfer_in (dev, len, buf, phase)
194 struct sci_softc *dev;
195 int len;
196 register u_char *buf;
197 int phase;
198 {
199 int wait = sci_data_wait;
200 u_char csr;
201 u_char *obp = (u_char *) buf;
202 volatile register u_char *sci_dma = dev->sci_idata;
203 volatile register u_char *sci_csr = dev->sci_csr;
204
205 QPRINTF(("supradma_in %d, csr=%02x\n", len, *dev->sci_bus_csr));
206
207 *dev->sci_tcmd = phase;
208 *dev->sci_icmd = 0;
209 *dev->sci_mode = SCI_MODE_DMA;
210 *dev->sci_irecv = 0;
211
212 while (len >= 128) {
213 wait = sci_data_wait;
214 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
215 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
216 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
217 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
218 || --wait < 0) {
219 #ifdef DEBUG
220 if (sci_debug | 1)
221 printf("supradma2_in fail: l%d i%x w%d\n",
222 len, *dev->sci_bus_csr, wait);
223 #endif
224 *dev->sci_mode = 0;
225 return 0;
226 }
227 }
228
229 #define R1 (*buf++ = *sci_dma)
230 R1; R1; R1; R1; R1; R1; R1; R1;
231 R1; R1; R1; R1; R1; R1; R1; R1;
232 R1; R1; R1; R1; R1; R1; R1; R1;
233 R1; R1; R1; R1; R1; R1; R1; R1;
234 R1; R1; R1; R1; R1; R1; R1; R1;
235 R1; R1; R1; R1; R1; R1; R1; R1;
236 R1; R1; R1; R1; R1; R1; R1; R1;
237 R1; R1; R1; R1; R1; R1; R1; R1;
238 R1; R1; R1; R1; R1; R1; R1; R1;
239 R1; R1; R1; R1; R1; R1; R1; R1;
240 R1; R1; R1; R1; R1; R1; R1; R1;
241 R1; R1; R1; R1; R1; R1; R1; R1;
242 R1; R1; R1; R1; R1; R1; R1; R1;
243 R1; R1; R1; R1; R1; R1; R1; R1;
244 R1; R1; R1; R1; R1; R1; R1; R1;
245 R1; R1; R1; R1; R1; R1; R1; R1;
246 len -= 128;
247 }
248
249 while (len > 0) {
250 wait = sci_data_wait;
251 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
252 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
253 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
254 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
255 || --wait < 0) {
256 #ifdef DEBUG
257 if (sci_debug | 1)
258 printf("supradma1_in fail: l%d i%x w%d\n",
259 len, *dev->sci_bus_csr, wait);
260 #endif
261 *dev->sci_mode = 0;
262 return 0;
263 }
264 }
265
266 *buf++ = *sci_dma;
267 len--;
268 }
269
270 QPRINTF(("supradma_in {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
271 len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5],
272 obp[6], obp[7], obp[8], obp[9]));
273
274 *dev->sci_mode = 0;
275 return 0;
276 }
277
278 int
279 wstsc_dma_xfer_out (dev, len, buf, phase)
280 struct sci_softc *dev;
281 int len;
282 register u_char *buf;
283 int phase;
284 {
285 int wait = sci_data_wait;
286 u_char csr;
287 u_char *obp = buf;
288 volatile register u_char *sci_dma = dev->sci_data;
289 volatile register u_char *sci_csr = dev->sci_csr;
290
291 QPRINTF(("supradma_out %d, csr=%02x\n", len, *dev->sci_bus_csr));
292
293 QPRINTF(("supradma_out {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
294 len, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
295 buf[6], buf[7], buf[8], buf[9]));
296
297 *dev->sci_tcmd = phase;
298 *dev->sci_mode = SCI_MODE_DMA;
299 *dev->sci_icmd = SCI_ICMD_DATA;
300 *dev->sci_dma_send = 0;
301 while (len > 0) {
302 wait = sci_data_wait;
303 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
304 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
305 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
306 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
307 || --wait < 0) {
308 #ifdef DEBUG
309 if (sci_debug)
310 printf("supradma_out fail: l%d i%x w%d\n",
311 len, csr, wait);
312 #endif
313 *dev->sci_mode = 0;
314 return 0;
315 }
316 }
317
318 *sci_dma = *buf++;
319 len--;
320 }
321
322 wait = sci_data_wait;
323 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) ==
324 SCI_CSR_PHASE_MATCH && --wait);
325
326
327 *dev->sci_mode = 0;
328 *dev->sci_icmd = 0;
329 return 0;
330 }
331
332
333 int
334 wstsc_dma_xfer_in2 (dev, len, buf, phase)
335 struct sci_softc *dev;
336 int len;
337 register u_short *buf;
338 int phase;
339 {
340 int wait = sci_data_wait;
341 u_char csr;
342 u_char *obp = (u_char *) buf;
343 volatile register u_short *sci_dma = (u_short *)(dev->sci_idata + 0x10);
344 volatile register u_char *sci_csr = dev->sci_csr + 0x10;
345
346 QPRINTF(("supradma_in2 %d, csr=%02x\n", len, *dev->sci_bus_csr));
347
348 *dev->sci_tcmd = phase;
349 *dev->sci_mode = SCI_MODE_DMA;
350 *dev->sci_icmd = 0;
351 *(dev->sci_irecv + 16) = 0;
352 while (len >= 128) {
353 #if 0
354 wait = sci_data_wait;
355 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
356 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
357 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
358 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
359 || --wait < 0) {
360 #ifdef DEBUG
361 if (sci_debug | 1)
362 printf("supradma2_in2 fail: l%d i%x w%d\n",
363 len, *dev->sci_bus_csr, wait);
364 #endif
365 *dev->sci_mode &= ~SCI_MODE_DMA;
366 return 0;
367 }
368 }
369 #else
370 while (!(*sci_csr & SCI_CSR_DREQ))
371 ;
372 #endif
373
374 #define R2 (*buf++ = *sci_dma)
375 R2; R2; R2; R2; R2; R2; R2; R2;
376 R2; R2; R2; R2; R2; R2; R2; R2;
377 R2; R2; R2; R2; R2; R2; R2; R2;
378 R2; R2; R2; R2; R2; R2; R2; R2;
379 R2; R2; R2; R2; R2; R2; R2; R2;
380 R2; R2; R2; R2; R2; R2; R2; R2;
381 R2; R2; R2; R2; R2; R2; R2; R2;
382 R2; R2; R2; R2; R2; R2; R2; R2;
383 len -= 128;
384 }
385 while (len > 0) {
386 #if 0
387 wait = sci_data_wait;
388 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
389 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
390 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
391 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
392 || --wait < 0) {
393 #ifdef DEBUG
394 if (sci_debug | 1)
395 printf("supradma1_in2 fail: l%d i%x w%d\n",
396 len, *dev->sci_bus_csr, wait);
397 #endif
398 *dev->sci_mode &= ~SCI_MODE_DMA;
399 return 0;
400 }
401 }
402 #else
403 while (!(*sci_csr * SCI_CSR_DREQ))
404 ;
405 #endif
406
407 *buf++ = *sci_dma;
408 len -= 2;
409 }
410
411 QPRINTF(("supradma_in2 {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
412 len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5],
413 obp[6], obp[7], obp[8], obp[9]));
414
415 *dev->sci_irecv = 0;
416 *dev->sci_mode = 0;
417 return 0;
418 }
419
420 int
421 wstsc_dma_xfer_out2 (dev, len, buf, phase)
422 struct sci_softc *dev;
423 int len;
424 register u_short *buf;
425 int phase;
426 {
427 int wait = sci_data_wait;
428 u_char csr;
429 u_char *obp = (u_char *) buf;
430 volatile register u_short *sci_dma = (ushort *)(dev->sci_data + 0x10);
431 volatile register u_char *sci_bus_csr = dev->sci_bus_csr;
432
433 QPRINTF(("supradma_out2 %d, csr=%02x\n", len, *dev->sci_bus_csr));
434
435 QPRINTF(("supradma_out2 {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
436 len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5],
437 obp[6], obp[7], obp[8], obp[9]));
438
439 *dev->sci_tcmd = phase;
440 *dev->sci_mode = SCI_MODE_DMA;
441 *dev->sci_icmd = SCI_ICMD_DATA;
442 *dev->sci_dma_send = 0;
443 while (len > 64) {
444 #if 0
445 wait = sci_data_wait;
446 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
447 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
448 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
449 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
450 || --wait < 0) {
451 #ifdef DEBUG
452 if (sci_debug)
453 printf("supradma_out2 fail: l%d i%x w%d\n",
454 len, csr, wait);
455 #endif
456 *dev->sci_mode = 0;
457 return 0;
458 }
459 }
460 #else
461 *dev->sci_mode = 0;
462 *dev->sci_icmd &= ~SCI_ICMD_ACK;
463 while (!(*sci_bus_csr & SCI_BUS_REQ))
464 ;
465 *dev->sci_mode = SCI_MODE_DMA;
466 *dev->sci_dma_send = 0;
467 #endif
468
469 #define W2 (*sci_dma = *buf++)
470 W2; W2; W2; W2; W2; W2; W2; W2;
471 W2; W2; W2; W2; W2; W2; W2; W2;
472 if (*(sci_bus_csr + 0x10) & SCI_BUS_REQ)
473 ;
474 len -= 64;
475 }
476
477 while (len > 0) {
478 #if 0
479 wait = sci_data_wait;
480 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
481 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
482 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
483 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
484 || --wait < 0) {
485 #ifdef DEBUG
486 if (sci_debug)
487 printf("supradma_out2 fail: l%d i%x w%d\n",
488 len, csr, wait);
489 #endif
490 *dev->sci_mode = 0;
491 return 0;
492 }
493 }
494 #else
495 *dev->sci_mode = 0;
496 *dev->sci_icmd &= ~SCI_ICMD_ACK;
497 while (!(*sci_bus_csr & SCI_BUS_REQ))
498 ;
499 *dev->sci_mode = SCI_MODE_DMA;
500 *dev->sci_dma_send = 0;
501 #endif
502
503 *sci_dma = *buf++;
504 if (*(sci_bus_csr + 0x10) & SCI_BUS_REQ)
505 ;
506 len -= 2;
507 }
508
509 #if 0
510 wait = sci_data_wait;
511 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) ==
512 SCI_CSR_PHASE_MATCH && --wait);
513 #endif
514
515
516 *dev->sci_irecv = 0;
517 *dev->sci_icmd &= ~SCI_ICMD_ACK;
518 *dev->sci_mode = 0;
519 *dev->sci_icmd = 0;
520 return 0;
521 }
522
523 int
524 wstsc_intr(dev)
525 struct sci_softc *dev;
526 {
527 int i, found;
528 u_char stat;
529
530 if ((*(dev->sci_csr + 0x10) & SCI_CSR_INT) == 0)
531 return (0);
532 stat = *(dev->sci_iack + 0x10);
533 return (1);
534 }
535