wstsc.c revision 1.22 1 /* $NetBSD: wstsc.c,v 1.22 1998/11/19 21:44:37 thorpej 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 <dev/scsipi/scsi_all.h>
43 #include <dev/scsipi/scsipi_all.h>
44 #include <dev/scsipi/scsiconf.h>
45 #include <amiga/amiga/device.h>
46 #include <amiga/amiga/isr.h>
47 #include <amiga/dev/scireg.h>
48 #include <amiga/dev/scivar.h>
49 #include <amiga/dev/zbusvar.h>
50
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((void *));
63
64 struct scsipi_device wstsc_scsidev = {
65 NULL, /* use default error handler */
66 NULL, /* do not have a start functio */
67 NULL, /* have no async handler */
68 NULL, /* Use default done routine */
69 };
70
71 #ifdef DEBUG
72 extern int sci_debug;
73 #define QPRINTF(a) if (sci_debug > 1) printf a
74 #else
75 #define QPRINTF(a)
76 #endif
77
78 extern int sci_data_wait;
79
80 int supradma_pseudo = 0; /* 0=none, 1=byte, 2=word */
81
82 struct cfattach wstsc_ca = {
83 sizeof(struct sci_softc), wstscmatch, wstscattach
84 };
85
86 /*
87 * if this a Supra WordSync board
88 */
89 int
90 wstscmatch(pdp, cfp, auxp)
91 struct device *pdp;
92 struct cfdata *cfp;
93 void *auxp;
94 {
95 struct zbus_args *zap;
96
97 zap = auxp;
98
99 /*
100 * Check manufacturer and product id.
101 */
102 if (zap->manid == 1056 && (
103 zap->prodid == 12 || /* WordSync */
104 zap->prodid == 13)) /* ByteSync */
105 return(1);
106 else
107 return(0);
108 }
109
110 void
111 wstscattach(pdp, dp, auxp)
112 struct device *pdp, *dp;
113 void *auxp;
114 {
115 volatile u_char *rp;
116 struct sci_softc *sc;
117 struct zbus_args *zap;
118
119 printf("\n");
120
121 zap = auxp;
122
123 sc = (struct sci_softc *)dp;
124 rp = zap->va;
125 /*
126 * set up 5380 register pointers
127 * (Needs check on which Supra board this is - for now,
128 * just do the WordSync)
129 */
130 sc->sci_data = rp + 0;
131 sc->sci_odata = rp + 0;
132 sc->sci_icmd = rp + 2;
133 sc->sci_mode = rp + 4;
134 sc->sci_tcmd = rp + 6;
135 sc->sci_bus_csr = rp + 8;
136 sc->sci_sel_enb = rp + 8;
137 sc->sci_csr = rp + 10;
138 sc->sci_dma_send = rp + 10;
139 sc->sci_idata = rp + 12;
140 sc->sci_trecv = rp + 12;
141 sc->sci_iack = rp + 14;
142 sc->sci_irecv = rp + 14;
143
144 if (supradma_pseudo == 2) {
145 sc->dma_xfer_in = (int(*)(struct sci_softc *, int, u_char *, int))wstsc_dma_xfer_in2;
146 sc->dma_xfer_out = (int(*)(struct sci_softc *, int, u_char *, int))wstsc_dma_xfer_out2;
147 }
148 else if (supradma_pseudo == 1) {
149 sc->dma_xfer_in = wstsc_dma_xfer_in;
150 sc->dma_xfer_out = wstsc_dma_xfer_out;
151 }
152
153 sc->sc_isr.isr_intr = wstsc_intr;
154 sc->sc_isr.isr_arg = sc;
155 sc->sc_isr.isr_ipl = 2;
156 add_isr(&sc->sc_isr);
157
158 scireset(sc);
159
160 sc->sc_adapter.scsipi_cmd = sci_scsicmd;
161 sc->sc_adapter.scsipi_minphys = sci_minphys;
162
163 sc->sc_link.scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE;
164 sc->sc_link.adapter_softc = sc;
165 sc->sc_link.scsipi_scsi.adapter_target = 7;
166 sc->sc_link.adapter = &sc->sc_adapter;
167 sc->sc_link.device = &wstsc_scsidev;
168 sc->sc_link.openings = 1;
169 sc->sc_link.scsipi_scsi.max_target = 7;
170 sc->sc_link.type = BUS_SCSI;
171 TAILQ_INIT(&sc->sc_xslist);
172
173 /*
174 * attach all scsi units on us
175 */
176 config_found(dp, &sc->sc_link, scsiprint);
177 }
178
179 int
180 wstsc_dma_xfer_in (dev, len, buf, phase)
181 struct sci_softc *dev;
182 int len;
183 register u_char *buf;
184 int phase;
185 {
186 int wait = sci_data_wait;
187 volatile register u_char *sci_dma = dev->sci_idata;
188 volatile register u_char *sci_csr = dev->sci_csr;
189 #ifdef DEBUG
190 u_char *obp = (u_char *) buf;
191 #endif
192
193 QPRINTF(("supradma_in %d, csr=%02x\n", len, *dev->sci_bus_csr));
194
195 *dev->sci_tcmd = phase;
196 *dev->sci_icmd = 0;
197 *dev->sci_mode = SCI_MODE_DMA;
198 *dev->sci_irecv = 0;
199
200 while (len >= 128) {
201 wait = sci_data_wait;
202 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
203 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
204 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
205 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
206 || --wait < 0) {
207 #ifdef DEBUG
208 if (sci_debug | 1)
209 printf("supradma2_in fail: l%d i%x w%d\n",
210 len, *dev->sci_bus_csr, wait);
211 #endif
212 *dev->sci_mode = 0;
213 return 0;
214 }
215 }
216
217 #define R1 (*buf++ = *sci_dma)
218 R1; R1; R1; R1; R1; R1; R1; R1;
219 R1; R1; R1; R1; R1; R1; R1; R1;
220 R1; R1; R1; R1; R1; R1; R1; R1;
221 R1; R1; R1; R1; R1; R1; R1; R1;
222 R1; R1; R1; R1; R1; R1; R1; R1;
223 R1; R1; R1; R1; R1; R1; R1; R1;
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 len -= 128;
235 }
236
237 while (len > 0) {
238 wait = sci_data_wait;
239 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
240 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
241 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
242 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
243 || --wait < 0) {
244 #ifdef DEBUG
245 if (sci_debug | 1)
246 printf("supradma1_in fail: l%d i%x w%d\n",
247 len, *dev->sci_bus_csr, wait);
248 #endif
249 *dev->sci_mode = 0;
250 return 0;
251 }
252 }
253
254 *buf++ = *sci_dma;
255 len--;
256 }
257
258 QPRINTF(("supradma_in {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
259 len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5],
260 obp[6], obp[7], obp[8], obp[9]));
261
262 *dev->sci_mode = 0;
263 return 0;
264 }
265
266 int
267 wstsc_dma_xfer_out (dev, len, buf, phase)
268 struct sci_softc *dev;
269 int len;
270 register u_char *buf;
271 int phase;
272 {
273 int wait = sci_data_wait;
274 volatile register u_char *sci_dma = dev->sci_data;
275 volatile register u_char *sci_csr = dev->sci_csr;
276
277 QPRINTF(("supradma_out %d, csr=%02x\n", len, *dev->sci_bus_csr));
278
279 QPRINTF(("supradma_out {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
280 len, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
281 buf[6], buf[7], buf[8], buf[9]));
282
283 *dev->sci_tcmd = phase;
284 *dev->sci_mode = SCI_MODE_DMA;
285 *dev->sci_icmd = SCI_ICMD_DATA;
286 *dev->sci_dma_send = 0;
287 while (len > 0) {
288 wait = sci_data_wait;
289 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
290 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
291 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
292 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
293 || --wait < 0) {
294 #ifdef DEBUG
295 if (sci_debug)
296 printf("supradma_out fail: l%d i%x w%d\n",
297 len, *dev->sci_bus_csr, wait);
298 #endif
299 *dev->sci_mode = 0;
300 return 0;
301 }
302 }
303
304 *sci_dma = *buf++;
305 len--;
306 }
307
308 wait = sci_data_wait;
309 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) ==
310 SCI_CSR_PHASE_MATCH && --wait);
311
312
313 *dev->sci_mode = 0;
314 *dev->sci_icmd = 0;
315 return 0;
316 }
317
318
319 int
320 wstsc_dma_xfer_in2 (dev, len, buf, phase)
321 struct sci_softc *dev;
322 int len;
323 register u_short *buf;
324 int phase;
325 {
326 volatile register u_short *sci_dma = (u_short *)(dev->sci_idata + 0x10);
327 volatile register u_char *sci_csr = dev->sci_csr + 0x10;
328 #ifdef DEBUG
329 u_char *obp = (u_char *) buf;
330 #endif
331 #if 0
332 int wait = sci_data_wait;
333 #endif
334
335 QPRINTF(("supradma_in2 %d, csr=%02x\n", len, *dev->sci_bus_csr));
336
337 *dev->sci_tcmd = phase;
338 *dev->sci_mode = SCI_MODE_DMA;
339 *dev->sci_icmd = 0;
340 *(dev->sci_irecv + 16) = 0;
341 while (len >= 128) {
342 #if 0
343 wait = sci_data_wait;
344 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
345 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
346 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
347 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
348 || --wait < 0) {
349 #ifdef DEBUG
350 if (sci_debug | 1)
351 printf("supradma2_in2 fail: l%d i%x w%d\n",
352 len, *dev->sci_bus_csr, wait);
353 #endif
354 *dev->sci_mode &= ~SCI_MODE_DMA;
355 return 0;
356 }
357 }
358 #else
359 while (!(*sci_csr & SCI_CSR_DREQ))
360 ;
361 #endif
362
363 #define R2 (*buf++ = *sci_dma)
364 R2; R2; R2; R2; R2; R2; R2; R2;
365 R2; R2; R2; R2; R2; R2; R2; R2;
366 R2; R2; R2; R2; R2; R2; R2; R2;
367 R2; R2; R2; R2; R2; R2; R2; R2;
368 R2; R2; R2; R2; R2; R2; R2; R2;
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 len -= 128;
373 }
374 while (len > 0) {
375 #if 0
376 wait = sci_data_wait;
377 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
378 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
379 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
380 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
381 || --wait < 0) {
382 #ifdef DEBUG
383 if (sci_debug | 1)
384 printf("supradma1_in2 fail: l%d i%x w%d\n",
385 len, *dev->sci_bus_csr, wait);
386 #endif
387 *dev->sci_mode &= ~SCI_MODE_DMA;
388 return 0;
389 }
390 }
391 #else
392 while (!(*sci_csr * SCI_CSR_DREQ))
393 ;
394 #endif
395
396 *buf++ = *sci_dma;
397 len -= 2;
398 }
399
400 QPRINTF(("supradma_in2 {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
401 len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5],
402 obp[6], obp[7], obp[8], obp[9]));
403
404 *dev->sci_irecv = 0;
405 *dev->sci_mode = 0;
406 return 0;
407 }
408
409 int
410 wstsc_dma_xfer_out2 (dev, len, buf, phase)
411 struct sci_softc *dev;
412 int len;
413 register u_short *buf;
414 int phase;
415 {
416 volatile register u_short *sci_dma = (ushort *)(dev->sci_data + 0x10);
417 volatile register u_char *sci_bus_csr = dev->sci_bus_csr;
418 #ifdef DEBUG
419 u_char *obp = (u_char *) buf;
420 #endif
421 #if 0
422 int wait = sci_data_wait;
423 #endif
424
425 QPRINTF(("supradma_out2 %d, csr=%02x\n", len, *dev->sci_bus_csr));
426
427 QPRINTF(("supradma_out2 {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
428 len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5],
429 obp[6], obp[7], obp[8], obp[9]));
430
431 *dev->sci_tcmd = phase;
432 *dev->sci_mode = SCI_MODE_DMA;
433 *dev->sci_icmd = SCI_ICMD_DATA;
434 *dev->sci_dma_send = 0;
435 while (len > 64) {
436 #if 0
437 wait = sci_data_wait;
438 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
439 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
440 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
441 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
442 || --wait < 0) {
443 #ifdef DEBUG
444 if (sci_debug)
445 printf("supradma_out2 fail: l%d i%x w%d\n",
446 len, csr, wait);
447 #endif
448 *dev->sci_mode = 0;
449 return 0;
450 }
451 }
452 #else
453 *dev->sci_mode = 0;
454 *dev->sci_icmd &= ~SCI_ICMD_ACK;
455 while (!(*sci_bus_csr & SCI_BUS_REQ))
456 ;
457 *dev->sci_mode = SCI_MODE_DMA;
458 *dev->sci_dma_send = 0;
459 #endif
460
461 #define W2 (*sci_dma = *buf++)
462 W2; W2; W2; W2; W2; W2; W2; W2;
463 W2; W2; W2; W2; W2; W2; W2; W2;
464 if (*(sci_bus_csr + 0x10) & SCI_BUS_REQ)
465 ;
466 len -= 64;
467 }
468
469 while (len > 0) {
470 #if 0
471 wait = sci_data_wait;
472 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
473 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
474 if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
475 || !(*dev->sci_bus_csr & SCI_BUS_BSY)
476 || --wait < 0) {
477 #ifdef DEBUG
478 if (sci_debug)
479 printf("supradma_out2 fail: l%d i%x w%d\n",
480 len, csr, wait);
481 #endif
482 *dev->sci_mode = 0;
483 return 0;
484 }
485 }
486 #else
487 *dev->sci_mode = 0;
488 *dev->sci_icmd &= ~SCI_ICMD_ACK;
489 while (!(*sci_bus_csr & SCI_BUS_REQ))
490 ;
491 *dev->sci_mode = SCI_MODE_DMA;
492 *dev->sci_dma_send = 0;
493 #endif
494
495 *sci_dma = *buf++;
496 if (*(sci_bus_csr + 0x10) & SCI_BUS_REQ)
497 ;
498 len -= 2;
499 }
500
501 #if 0
502 wait = sci_data_wait;
503 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) ==
504 SCI_CSR_PHASE_MATCH && --wait);
505 #endif
506
507
508 *dev->sci_irecv = 0;
509 *dev->sci_icmd &= ~SCI_ICMD_ACK;
510 *dev->sci_mode = 0;
511 *dev->sci_icmd = 0;
512 return 0;
513 }
514
515 int
516 wstsc_intr(arg)
517 void *arg;
518 {
519 struct sci_softc *dev = arg;
520 u_char stat;
521
522 if ((*(dev->sci_csr + 0x10) & SCI_CSR_INT) == 0)
523 return (0);
524 stat = *(dev->sci_iack + 0x10);
525 return (1);
526 }
527