wstsc.c revision 1.8 1 /* $NetBSD: wstsc.c,v 1.8 1995/02/12 19:19:31 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 && zap->prodid == 12) /* add other boards? */
109 return(1);
110 else
111 return(0);
112 }
113
114 void
115 wstscattach(pdp, dp, auxp)
116 struct device *pdp, *dp;
117 void *auxp;
118 {
119 volatile u_char *rp;
120 struct sci_softc *sc;
121 struct zbus_args *zap;
122
123 printf("\n");
124
125 zap = auxp;
126
127 sc = (struct sci_softc *)dp;
128 rp = zap->va;
129 /*
130 * set up 5380 register pointers
131 * (Needs check on which Supra board this is - for now,
132 * just do the WordSync)
133 */
134 sc->sci_data = rp + 0;
135 sc->sci_odata = rp + 0;
136 sc->sci_icmd = rp + 2;
137 sc->sci_mode = rp + 4;
138 sc->sci_tcmd = rp + 6;
139 sc->sci_bus_csr = rp + 8;
140 sc->sci_sel_enb = rp + 8;
141 sc->sci_csr = rp + 10;
142 sc->sci_dma_send = rp + 10;
143 sc->sci_idata = rp + 12;
144 sc->sci_trecv = rp + 12;
145 sc->sci_iack = rp + 14;
146 sc->sci_irecv = rp + 14;
147
148 if (supradma_pseudo == 2) {
149 sc->dma_xfer_in = wstsc_dma_xfer_in2;
150 sc->dma_xfer_out = wstsc_dma_xfer_out2;
151 }
152 else if (supradma_pseudo == 1) {
153 sc->dma_xfer_in = wstsc_dma_xfer_in;
154 sc->dma_xfer_out = wstsc_dma_xfer_out;
155 }
156
157 sc->sc_isr.isr_intr = wstsc_intr;
158 sc->sc_isr.isr_arg = sc;
159 sc->sc_isr.isr_ipl = 2;
160 add_isr(&sc->sc_isr);
161
162 scireset(sc);
163
164 sc->sc_link.adapter_softc = sc;
165 sc->sc_link.adapter_target = 7;
166 sc->sc_link.adapter = &wstsc_scsiswitch;
167 sc->sc_link.device = &wstsc_scsidev;
168 sc->sc_link.openings = 1;
169 TAILQ_INIT(&sc->sc_xslist);
170
171 /*
172 * attach all scsi units on us
173 */
174 config_found(dp, &sc->sc_link, wstscprint);
175 }
176
177 /*
178 * print diag if pnp is NULL else just extra
179 */
180 int
181 wstscprint(auxp, pnp)
182 void *auxp;
183 char *pnp;
184 {
185 if (pnp == NULL)
186 return(UNCONF);
187 return(QUIET);
188 }
189
190 int
191 wstsc_dma_xfer_in (dev, len, buf, phase)
192 struct sci_softc *dev;
193 int len;
194 register u_char *buf;
195 int phase;
196 {
197 int wait = sci_data_wait;
198 u_char csr;
199 u_char *obp = (u_char *) buf;
200 volatile register u_char *sci_dma = dev->sci_idata;
201 volatile register u_char *sci_csr = dev->sci_csr;
202
203 QPRINTF(("supradma_in %d, csr=%02x\n", len, *dev->sci_bus_csr));
204
205 *dev->sci_tcmd = phase;
206 *dev->sci_icmd = 0;
207 *dev->sci_mode = SCI_MODE_DMA;
208 *dev->sci_irecv = 0;
209
210 while (len >= 128) {
211 wait = sci_data_wait;
212 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
213 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
214 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
215 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
216 || --wait < 0) {
217 #ifdef DEBUG
218 if (sci_debug | 1)
219 printf("supradma2_in fail: l%d i%x w%d\n",
220 len, *dev->sci_bus_csr, wait);
221 #endif
222 *dev->sci_mode = 0;
223 return 0;
224 }
225 }
226
227 #define R1 (*buf++ = *sci_dma)
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 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 len -= 128;
245 }
246
247 while (len > 0) {
248 wait = sci_data_wait;
249 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
250 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
251 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
252 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
253 || --wait < 0) {
254 #ifdef DEBUG
255 if (sci_debug | 1)
256 printf("supradma1_in fail: l%d i%x w%d\n",
257 len, *dev->sci_bus_csr, wait);
258 #endif
259 *dev->sci_mode = 0;
260 return 0;
261 }
262 }
263
264 *buf++ = *sci_dma;
265 len--;
266 }
267
268 QPRINTF(("supradma_in {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
269 len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5],
270 obp[6], obp[7], obp[8], obp[9]));
271
272 *dev->sci_mode = 0;
273 return 0;
274 }
275
276 int
277 wstsc_dma_xfer_out (dev, len, buf, phase)
278 struct sci_softc *dev;
279 int len;
280 register u_char *buf;
281 int phase;
282 {
283 int wait = sci_data_wait;
284 u_char csr;
285 u_char *obp = buf;
286 volatile register u_char *sci_dma = dev->sci_data;
287 volatile register u_char *sci_csr = dev->sci_csr;
288
289 QPRINTF(("supradma_out %d, csr=%02x\n", len, *dev->sci_bus_csr));
290
291 QPRINTF(("supradma_out {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
292 len, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
293 buf[6], buf[7], buf[8], buf[9]));
294
295 *dev->sci_tcmd = phase;
296 *dev->sci_mode = SCI_MODE_DMA;
297 *dev->sci_icmd = SCI_ICMD_DATA;
298 *dev->sci_dma_send = 0;
299 while (len > 0) {
300 wait = sci_data_wait;
301 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
302 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
303 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
304 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
305 || --wait < 0) {
306 #ifdef DEBUG
307 if (sci_debug)
308 printf("supradma_out fail: l%d i%x w%d\n",
309 len, csr, wait);
310 #endif
311 *dev->sci_mode = 0;
312 return 0;
313 }
314 }
315
316 *sci_dma = *buf++;
317 len--;
318 }
319
320 wait = sci_data_wait;
321 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) ==
322 SCI_CSR_PHASE_MATCH && --wait);
323
324
325 *dev->sci_mode = 0;
326 *dev->sci_icmd = 0;
327 return 0;
328 }
329
330
331 int
332 wstsc_dma_xfer_in2 (dev, len, buf, phase)
333 struct sci_softc *dev;
334 int len;
335 register u_short *buf;
336 int phase;
337 {
338 int wait = sci_data_wait;
339 u_char csr;
340 u_char *obp = (u_char *) buf;
341 volatile register u_short *sci_dma = (u_short *)(dev->sci_idata + 0x10);
342 volatile register u_char *sci_csr = dev->sci_csr + 0x10;
343
344 QPRINTF(("supradma_in2 %d, csr=%02x\n", len, *dev->sci_bus_csr));
345
346 *dev->sci_tcmd = phase;
347 *dev->sci_mode = SCI_MODE_DMA;
348 *dev->sci_icmd = 0;
349 *(dev->sci_irecv + 16) = 0;
350 while (len >= 128) {
351 #if 0
352 wait = sci_data_wait;
353 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
354 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
355 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
356 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
357 || --wait < 0) {
358 #ifdef DEBUG
359 if (sci_debug | 1)
360 printf("supradma2_in2 fail: l%d i%x w%d\n",
361 len, *dev->sci_bus_csr, wait);
362 #endif
363 *dev->sci_mode &= ~SCI_MODE_DMA;
364 return 0;
365 }
366 }
367 #else
368 while (!(*sci_csr & SCI_CSR_DREQ))
369 ;
370 #endif
371
372 #define R2 (*buf++ = *sci_dma)
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 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 len -= 128;
382 }
383 while (len > 0) {
384 #if 0
385 wait = sci_data_wait;
386 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
387 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
388 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
389 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
390 || --wait < 0) {
391 #ifdef DEBUG
392 if (sci_debug | 1)
393 printf("supradma1_in2 fail: l%d i%x w%d\n",
394 len, *dev->sci_bus_csr, wait);
395 #endif
396 *dev->sci_mode &= ~SCI_MODE_DMA;
397 return 0;
398 }
399 }
400 #else
401 while (!(*sci_csr * SCI_CSR_DREQ))
402 ;
403 #endif
404
405 *buf++ = *sci_dma;
406 len -= 2;
407 }
408
409 QPRINTF(("supradma_in2 {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
410 len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5],
411 obp[6], obp[7], obp[8], obp[9]));
412
413 *dev->sci_irecv = 0;
414 *dev->sci_mode = 0;
415 return 0;
416 }
417
418 int
419 wstsc_dma_xfer_out2 (dev, len, buf, phase)
420 struct sci_softc *dev;
421 int len;
422 register u_short *buf;
423 int phase;
424 {
425 int wait = sci_data_wait;
426 u_char csr;
427 u_char *obp = (u_char *) buf;
428 volatile register u_short *sci_dma = (ushort *)(dev->sci_data + 0x10);
429 volatile register u_char *sci_bus_csr = dev->sci_bus_csr;
430
431 QPRINTF(("supradma_out2 %d, csr=%02x\n", len, *dev->sci_bus_csr));
432
433 QPRINTF(("supradma_out2 {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
434 len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5],
435 obp[6], obp[7], obp[8], obp[9]));
436
437 *dev->sci_tcmd = phase;
438 *dev->sci_mode = SCI_MODE_DMA;
439 *dev->sci_icmd = SCI_ICMD_DATA;
440 *dev->sci_dma_send = 0;
441 while (len > 64) {
442 #if 0
443 wait = sci_data_wait;
444 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
445 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
446 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
447 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
448 || --wait < 0) {
449 #ifdef DEBUG
450 if (sci_debug)
451 printf("supradma_out2 fail: l%d i%x w%d\n",
452 len, csr, wait);
453 #endif
454 *dev->sci_mode = 0;
455 return 0;
456 }
457 }
458 #else
459 *dev->sci_mode = 0;
460 *dev->sci_icmd &= ~SCI_ICMD_ACK;
461 while (!(*sci_bus_csr & SCI_BUS_REQ))
462 ;
463 *dev->sci_mode = SCI_MODE_DMA;
464 *dev->sci_dma_send = 0;
465 #endif
466
467 #define W2 (*sci_dma = *buf++)
468 W2; W2; W2; W2; W2; W2; W2; W2;
469 W2; W2; W2; W2; W2; W2; W2; W2;
470 if (*(sci_bus_csr + 0x10) & SCI_BUS_REQ)
471 ;
472 len -= 64;
473 }
474
475 while (len > 0) {
476 #if 0
477 wait = sci_data_wait;
478 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
479 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
480 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
481 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
482 || --wait < 0) {
483 #ifdef DEBUG
484 if (sci_debug)
485 printf("supradma_out2 fail: l%d i%x w%d\n",
486 len, csr, wait);
487 #endif
488 *dev->sci_mode = 0;
489 return 0;
490 }
491 }
492 #else
493 *dev->sci_mode = 0;
494 *dev->sci_icmd &= ~SCI_ICMD_ACK;
495 while (!(*sci_bus_csr & SCI_BUS_REQ))
496 ;
497 *dev->sci_mode = SCI_MODE_DMA;
498 *dev->sci_dma_send = 0;
499 #endif
500
501 *sci_dma = *buf++;
502 if (*(sci_bus_csr + 0x10) & SCI_BUS_REQ)
503 ;
504 len -= 2;
505 }
506
507 #if 0
508 wait = sci_data_wait;
509 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) ==
510 SCI_CSR_PHASE_MATCH && --wait);
511 #endif
512
513
514 *dev->sci_irecv = 0;
515 *dev->sci_icmd &= ~SCI_ICMD_ACK;
516 *dev->sci_mode = 0;
517 *dev->sci_icmd = 0;
518 return 0;
519 }
520
521 int
522 wstsc_intr(dev)
523 struct sci_softc *dev;
524 {
525 int i, found;
526 u_char stat;
527
528 if ((*(dev->sci_csr + 0x10) & SCI_CSR_INT) == 0)
529 return (0);
530 stat = *(dev->sci_iack + 0x10);
531 return (1);
532 }
533