wstsc.c revision 1.4 1 /* $NetBSD: wstsc.c,v 1.4 1994/10/26 02:05:13 cgd 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/dev/scireg.h>
46 #include <amiga/dev/scivar.h>
47 #include <amiga/dev/ztwobusvar.h>
48
49 int wstscprint __P((void *auxp, char *));
50 void wstscattach __P((struct device *, struct device *, void *));
51 int wstscmatch __P((struct device *, struct cfdata *, void *));
52
53 int wstsc_dma_xfer_in __P((struct sci_softc *dev, int len,
54 register u_char *buf, int phase));
55 int wstsc_dma_xfer_out __P((struct sci_softc *dev, int len,
56 register u_char *buf, int phase));
57 int wstsc_dma_xfer_in2 __P((struct sci_softc *dev, int len,
58 register u_short *buf, int phase));
59 int wstsc_dma_xfer_out2 __P((struct sci_softc *dev, int len,
60 register u_short *buf, int phase));
61
62 struct scsi_adapter wstsc_scsiswitch = {
63 sci_scsicmd,
64 sci_minphys,
65 0, /* no lun support */
66 0, /* no lun support */
67 sci_adinfo,
68 "wstsc",
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 "wstsc",
77 0,
78 };
79
80 #define QPRINTF
81
82 #ifdef DEBUG
83 extern int sci_debug;
84 #endif
85
86 extern int sci_data_wait;
87
88 int supradma_pseudo = 0; /* 0=none, 1=byte, 2=word */
89
90 struct cfdriver wstsccd = {
91 NULL, "wstsc", wstscmatch, wstscattach,
92 DV_DULL, sizeof(struct sci_softc), NULL, 0 };
93
94 /*
95 * if this a Supra WordSync board
96 */
97 int
98 wstscmatch(pdp, cdp, auxp)
99 struct device *pdp;
100 struct cfdata *cdp;
101 void *auxp;
102 {
103 struct ztwobus_args *zap;
104
105 zap = auxp;
106
107 /*
108 * Check manufacturer and product id.
109 */
110 if (zap->manid == 1056 && zap->prodid == 12) /* add other boards? */
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 ztwobus_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 scireset(sc);
160
161 sc->sc_link.adapter_softc = sc;
162 sc->sc_link.adapter_targ = 7;
163 sc->sc_link.adapter = &wstsc_scsiswitch;
164 sc->sc_link.device = &wstsc_scsidev;
165 TAILQ_INIT(&sc->sc_xslist);
166
167 /*
168 * attach all scsi units on us
169 */
170 config_found(dp, &sc->sc_link, wstscprint);
171 }
172
173 /*
174 * print diag if pnp is NULL else just extra
175 */
176 int
177 wstscprint(auxp, pnp)
178 void *auxp;
179 char *pnp;
180 {
181 if (pnp == NULL)
182 return(UNCONF);
183 return(QUIET);
184 }
185
186 int
187 wstsc_dma_xfer_in (dev, len, buf, phase)
188 struct sci_softc *dev;
189 int len;
190 register u_char *buf;
191 int phase;
192 {
193 int wait = sci_data_wait;
194 u_char csr;
195 u_char *obp = (u_char *) buf;
196 volatile register u_char *sci_dma = dev->sci_idata;
197 volatile register u_char *sci_csr = dev->sci_csr;
198
199 QPRINTF(("supradma_in %d, csr=%02x\n", len, *dev->sci_bus_csr));
200
201 *dev->sci_tcmd = phase;
202 *dev->sci_icmd = 0;
203 *dev->sci_mode = SCI_MODE_DMA;
204 *dev->sci_irecv = 0;
205
206 while (len >= 128) {
207 wait = sci_data_wait;
208 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
209 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
210 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
211 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
212 || --wait < 0) {
213 #ifdef DEBUG
214 if (sci_debug | 1)
215 printf("supradma2_in fail: l%d i%x w%d\n",
216 len, *dev->sci_bus_csr, wait);
217 #endif
218 *dev->sci_mode = 0;
219 return 0;
220 }
221 }
222
223 #define R1 (*buf++ = *sci_dma)
224 R1; R1; R1; R1; R1; R1; R1; R1;
225 R1; R1; R1; R1; R1; R1; R1; R1;
226 R1; R1; R1; R1; R1; R1; R1; R1;
227 R1; R1; R1; R1; R1; R1; R1; R1;
228 R1; R1; R1; R1; R1; R1; R1; R1;
229 R1; R1; R1; R1; R1; R1; R1; R1;
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 len -= 128;
241 }
242
243 while (len > 0) {
244 wait = sci_data_wait;
245 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
246 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
247 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
248 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
249 || --wait < 0) {
250 #ifdef DEBUG
251 if (sci_debug | 1)
252 printf("supradma1_in fail: l%d i%x w%d\n",
253 len, *dev->sci_bus_csr, wait);
254 #endif
255 *dev->sci_mode = 0;
256 return 0;
257 }
258 }
259
260 *buf++ = *sci_dma;
261 len--;
262 }
263
264 QPRINTF(("supradma_in {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
265 len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5],
266 obp[6], obp[7], obp[8], obp[9]));
267
268 *dev->sci_mode = 0;
269 return 0;
270 }
271
272 int
273 wstsc_dma_xfer_out (dev, len, buf, phase)
274 struct sci_softc *dev;
275 int len;
276 register u_char *buf;
277 int phase;
278 {
279 int wait = sci_data_wait;
280 u_char csr;
281 u_char *obp = buf;
282 volatile register u_char *sci_dma = dev->sci_data;
283 volatile register u_char *sci_csr = dev->sci_csr;
284
285 QPRINTF(("supradma_out %d, csr=%02x\n", len, *dev->sci_bus_csr));
286
287 QPRINTF(("supradma_out {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
288 len, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
289 buf[6], buf[7], buf[8], buf[9]));
290
291 *dev->sci_tcmd = phase;
292 *dev->sci_mode = SCI_MODE_DMA;
293 *dev->sci_icmd = SCI_ICMD_DATA;
294 *dev->sci_dma_send = 0;
295 while (len > 0) {
296 wait = sci_data_wait;
297 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
298 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
299 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
300 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
301 || --wait < 0) {
302 #ifdef DEBUG
303 if (sci_debug)
304 printf("supradma_out fail: l%d i%x w%d\n",
305 len, csr, wait);
306 #endif
307 *dev->sci_mode = 0;
308 return 0;
309 }
310 }
311
312 *sci_dma = *buf++;
313 len--;
314 }
315
316 wait = sci_data_wait;
317 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) ==
318 SCI_CSR_PHASE_MATCH && --wait);
319
320
321 *dev->sci_mode = 0;
322 *dev->sci_icmd = 0;
323 return 0;
324 }
325
326
327 int
328 wstsc_dma_xfer_in2 (dev, len, buf, phase)
329 struct sci_softc *dev;
330 int len;
331 register u_short *buf;
332 int phase;
333 {
334 int wait = sci_data_wait;
335 u_char csr;
336 u_char *obp = (u_char *) buf;
337 volatile register u_short *sci_dma = (u_short *)(dev->sci_idata + 0x10);
338 volatile register u_char *sci_csr = dev->sci_csr + 0x10;
339
340 QPRINTF(("supradma_in2 %d, csr=%02x\n", len, *dev->sci_bus_csr));
341
342 *dev->sci_tcmd = phase;
343 *dev->sci_mode = SCI_MODE_DMA;
344 *dev->sci_icmd = 0;
345 *(dev->sci_irecv + 16) = 0;
346 while (len >= 128) {
347 #if 0
348 wait = sci_data_wait;
349 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
350 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
351 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
352 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
353 || --wait < 0) {
354 #ifdef DEBUG
355 if (sci_debug | 1)
356 printf("supradma2_in2 fail: l%d i%x w%d\n",
357 len, *dev->sci_bus_csr, wait);
358 #endif
359 *dev->sci_mode &= ~SCI_MODE_DMA;
360 return 0;
361 }
362 }
363 #else
364 while (!(*sci_csr & SCI_CSR_DREQ))
365 ;
366 #endif
367
368 #define R2 (*buf++ = *sci_dma)
369 R2; R2; R2; R2; R2; R2; R2; R2;
370 R2; R2; R2; R2; R2; R2; R2; R2;
371 R2; R2; R2; R2; R2; R2; R2; R2;
372 R2; R2; R2; R2; R2; R2; R2; R2;
373 R2; R2; R2; R2; R2; R2; R2; R2;
374 R2; R2; R2; R2; R2; R2; R2; R2;
375 R2; R2; R2; R2; R2; R2; R2; R2;
376 R2; R2; R2; R2; R2; R2; R2; R2;
377 len -= 128;
378 }
379 while (len > 0) {
380 #if 0
381 wait = sci_data_wait;
382 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
383 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
384 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
385 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
386 || --wait < 0) {
387 #ifdef DEBUG
388 if (sci_debug | 1)
389 printf("supradma1_in2 fail: l%d i%x w%d\n",
390 len, *dev->sci_bus_csr, wait);
391 #endif
392 *dev->sci_mode &= ~SCI_MODE_DMA;
393 return 0;
394 }
395 }
396 #else
397 while (!(*sci_csr * SCI_CSR_DREQ))
398 ;
399 #endif
400
401 *buf++ = *sci_dma;
402 len -= 2;
403 }
404
405 QPRINTF(("supradma_in2 {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
406 len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5],
407 obp[6], obp[7], obp[8], obp[9]));
408
409 *dev->sci_irecv = 0;
410 *dev->sci_mode = 0;
411 return 0;
412 }
413
414 int
415 wstsc_dma_xfer_out2 (dev, len, buf, phase)
416 struct sci_softc *dev;
417 int len;
418 register u_short *buf;
419 int phase;
420 {
421 int wait = sci_data_wait;
422 u_char csr;
423 u_char *obp = (u_char *) buf;
424 volatile register u_short *sci_dma = (ushort *)(dev->sci_data + 0x10);
425 volatile register u_char *sci_bus_csr = dev->sci_bus_csr;
426
427 QPRINTF(("supradma_out2 %d, csr=%02x\n", len, *dev->sci_bus_csr));
428
429 QPRINTF(("supradma_out2 {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
430 len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5],
431 obp[6], obp[7], obp[8], obp[9]));
432
433 *dev->sci_tcmd = phase;
434 *dev->sci_mode = SCI_MODE_DMA;
435 *dev->sci_icmd = SCI_ICMD_DATA;
436 *dev->sci_dma_send = 0;
437 while (len > 64) {
438 #if 0
439 wait = sci_data_wait;
440 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
441 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
442 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
443 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
444 || --wait < 0) {
445 #ifdef DEBUG
446 if (sci_debug)
447 printf("supradma_out2 fail: l%d i%x w%d\n",
448 len, csr, wait);
449 #endif
450 *dev->sci_mode = 0;
451 return 0;
452 }
453 }
454 #else
455 *dev->sci_mode = 0;
456 *dev->sci_icmd &= ~SCI_ICMD_ACK;
457 while (!(*sci_bus_csr & SCI_BUS_REQ))
458 ;
459 *dev->sci_mode = SCI_MODE_DMA;
460 *dev->sci_dma_send = 0;
461 #endif
462
463 #define W2 (*sci_dma = *buf++)
464 W2; W2; W2; W2; W2; W2; W2; W2;
465 W2; W2; W2; W2; W2; W2; W2; W2;
466 if (*(sci_bus_csr + 0x10) & SCI_BUS_REQ)
467 ;
468 len -= 64;
469 }
470
471 while (len > 0) {
472 #if 0
473 wait = sci_data_wait;
474 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
475 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
476 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
477 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
478 || --wait < 0) {
479 #ifdef DEBUG
480 if (sci_debug)
481 printf("supradma_out2 fail: l%d i%x w%d\n",
482 len, csr, wait);
483 #endif
484 *dev->sci_mode = 0;
485 return 0;
486 }
487 }
488 #else
489 *dev->sci_mode = 0;
490 *dev->sci_icmd &= ~SCI_ICMD_ACK;
491 while (!(*sci_bus_csr & SCI_BUS_REQ))
492 ;
493 *dev->sci_mode = SCI_MODE_DMA;
494 *dev->sci_dma_send = 0;
495 #endif
496
497 *sci_dma = *buf++;
498 if (*(sci_bus_csr + 0x10) & SCI_BUS_REQ)
499 ;
500 len -= 2;
501 }
502
503 #if 0
504 wait = sci_data_wait;
505 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) ==
506 SCI_CSR_PHASE_MATCH && --wait);
507 #endif
508
509
510 *dev->sci_irecv = 0;
511 *dev->sci_icmd &= ~SCI_ICMD_ACK;
512 *dev->sci_mode = 0;
513 *dev->sci_icmd = 0;
514 return 0;
515 }
516
517 int
518 wstsc_intr()
519 {
520 struct sci_softc *dev;
521 int i, found;
522 u_char stat;
523
524 found = 0;
525 for (i = 0; i < wstsccd.cd_ndevs; i++) {
526 dev = wstsccd.cd_devs[i];
527 if (dev == NULL)
528 continue;
529 if ((*(dev->sci_csr + 0x10) & SCI_CSR_INT) == 0)
530 continue;
531 ++found;
532 stat = *(dev->sci_iack + 0x10);
533 }
534 return (found);
535 }
536