xref: /netbsd-src/sys/arch/amiga/dev/mlhsc.c (revision ae1bfcddc410612bc8c58b807e1830becb69a24c)
1 /*
2  * Copyright (c) 1982, 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by the University of
16  *	California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  *	@(#)mlhdma.c
34  *	$Id: mlhsc.c,v 1.1 1994/05/08 05:53:28 chopps Exp $
35  */
36 
37 /*
38  * dummy MLH 5380 DMA driver
39  */
40 
41 #include "mlhscsi.h"
42 
43 #if NMLHSCSI > 0
44 
45 #include <sys/param.h>
46 
47 #include <amiga/dev/device.h>
48 #include <amiga/dev/scivar.h>
49 #include <amiga/dev/scireg.h>
50 
51 #define QPRINTF
52 #ifdef DEBUG
53 extern int sci_debug;
54 #endif
55 #define	HIST(h,w)
56 
57 extern int sci_data_wait;
58 
59 static int dma_xfer_in __P((struct sci_softc *dev, int len,
60     register u_char *buf, int phase));
61 static int dma_xfer_out __P((struct sci_softc *dev, int len,
62     register u_char *buf, int phase));
63 
64 void
65 mlhdmainit (dev)
66 	struct sci_softc *dev;
67 {
68 	dev->dma_xfer_in = dma_xfer_in;
69 	dev->dma_xfer_out = dma_xfer_out;
70 }
71 
72 static int
73 dma_xfer_in (dev, len, buf, phase)
74 	struct sci_softc *dev;
75 	int len;
76 	register u_char *buf;
77 	int phase;
78 {
79 	int wait = sci_data_wait;
80 	u_char csr;
81 	u_char *obp = buf;
82 #if 1
83 	volatile register u_char *sci_dma = dev->sci_data + 16;
84 #else
85 	volatile register u_char *sci_dma = dev->sci_data + 12;
86 #endif
87 	volatile register u_char *sci_csr = dev->sci_csr;
88 	volatile register u_char *sci_icmd = dev->sci_icmd;
89 
90 	csr = *dev->sci_bus_csr;
91 
92 	QPRINTF(("mlhdma_in %d, csr=%02x\n", len, csr));
93 
94 	*dev->sci_tcmd = phase;
95 	*dev->sci_mode |= SCI_MODE_DMA;
96 	*dev->sci_icmd = 0;
97 	*dev->sci_irecv = 0;
98 	while (len > 128) {
99 		wait = sci_data_wait;
100 		while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
101 		  (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
102 			if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
103 			  || !(*dev->sci_bus_csr & SCI_BUS_BSY)
104 			  || --wait < 0) {
105 #ifdef DEBUG
106 				if (sci_debug)
107 					printf("mlhdma_in fail: l%d i%x w%d\n",
108 					len, csr, wait);
109 #endif
110 				HIST(ixin_wait, wait)
111 				*dev->sci_mode &= ~SCI_MODE_DMA;
112 				return 0;
113 			}
114 		}
115 
116 		*buf++ = *sci_dma;
117 		*buf++ = *sci_dma;
118 		*buf++ = *sci_dma;
119 		*buf++ = *sci_dma;
120 		*buf++ = *sci_dma;
121 		*buf++ = *sci_dma;
122 		*buf++ = *sci_dma;
123 		*buf++ = *sci_dma;
124 		*buf++ = *sci_dma;
125 		*buf++ = *sci_dma;
126 		*buf++ = *sci_dma;
127 		*buf++ = *sci_dma;
128 		*buf++ = *sci_dma;
129 		*buf++ = *sci_dma;
130 		*buf++ = *sci_dma;
131 		*buf++ = *sci_dma;
132 		*buf++ = *sci_dma;
133 		*buf++ = *sci_dma;
134 		*buf++ = *sci_dma;
135 		*buf++ = *sci_dma;
136 		*buf++ = *sci_dma;
137 		*buf++ = *sci_dma;
138 		*buf++ = *sci_dma;
139 		*buf++ = *sci_dma;
140 		*buf++ = *sci_dma;
141 		*buf++ = *sci_dma;
142 		*buf++ = *sci_dma;
143 		*buf++ = *sci_dma;
144 		*buf++ = *sci_dma;
145 		*buf++ = *sci_dma;
146 		*buf++ = *sci_dma;
147 		*buf++ = *sci_dma;
148 		*buf++ = *sci_dma;
149 		*buf++ = *sci_dma;
150 		*buf++ = *sci_dma;
151 		*buf++ = *sci_dma;
152 		*buf++ = *sci_dma;
153 		*buf++ = *sci_dma;
154 		*buf++ = *sci_dma;
155 		*buf++ = *sci_dma;
156 		*buf++ = *sci_dma;
157 		*buf++ = *sci_dma;
158 		*buf++ = *sci_dma;
159 		*buf++ = *sci_dma;
160 		*buf++ = *sci_dma;
161 		*buf++ = *sci_dma;
162 		*buf++ = *sci_dma;
163 		*buf++ = *sci_dma;
164 		*buf++ = *sci_dma;
165 		*buf++ = *sci_dma;
166 		*buf++ = *sci_dma;
167 		*buf++ = *sci_dma;
168 		*buf++ = *sci_dma;
169 		*buf++ = *sci_dma;
170 		*buf++ = *sci_dma;
171 		*buf++ = *sci_dma;
172 		*buf++ = *sci_dma;
173 		*buf++ = *sci_dma;
174 		*buf++ = *sci_dma;
175 		*buf++ = *sci_dma;
176 		*buf++ = *sci_dma;
177 		*buf++ = *sci_dma;
178 		*buf++ = *sci_dma;
179 		*buf++ = *sci_dma;
180 		*buf++ = *sci_dma;
181 		*buf++ = *sci_dma;
182 		*buf++ = *sci_dma;
183 		*buf++ = *sci_dma;
184 		*buf++ = *sci_dma;
185 		*buf++ = *sci_dma;
186 		*buf++ = *sci_dma;
187 		*buf++ = *sci_dma;
188 		*buf++ = *sci_dma;
189 		*buf++ = *sci_dma;
190 		*buf++ = *sci_dma;
191 		*buf++ = *sci_dma;
192 		*buf++ = *sci_dma;
193 		*buf++ = *sci_dma;
194 		*buf++ = *sci_dma;
195 		*buf++ = *sci_dma;
196 		*buf++ = *sci_dma;
197 		*buf++ = *sci_dma;
198 		*buf++ = *sci_dma;
199 		*buf++ = *sci_dma;
200 		*buf++ = *sci_dma;
201 		*buf++ = *sci_dma;
202 		*buf++ = *sci_dma;
203 		*buf++ = *sci_dma;
204 		*buf++ = *sci_dma;
205 		*buf++ = *sci_dma;
206 		*buf++ = *sci_dma;
207 		*buf++ = *sci_dma;
208 		*buf++ = *sci_dma;
209 		*buf++ = *sci_dma;
210 		*buf++ = *sci_dma;
211 		*buf++ = *sci_dma;
212 		*buf++ = *sci_dma;
213 		*buf++ = *sci_dma;
214 		*buf++ = *sci_dma;
215 		*buf++ = *sci_dma;
216 		*buf++ = *sci_dma;
217 		*buf++ = *sci_dma;
218 		*buf++ = *sci_dma;
219 		*buf++ = *sci_dma;
220 		*buf++ = *sci_dma;
221 		*buf++ = *sci_dma;
222 		*buf++ = *sci_dma;
223 		*buf++ = *sci_dma;
224 		*buf++ = *sci_dma;
225 		*buf++ = *sci_dma;
226 		*buf++ = *sci_dma;
227 		*buf++ = *sci_dma;
228 		*buf++ = *sci_dma;
229 		*buf++ = *sci_dma;
230 		*buf++ = *sci_dma;
231 		*buf++ = *sci_dma;
232 		*buf++ = *sci_dma;
233 		*buf++ = *sci_dma;
234 		*buf++ = *sci_dma;
235 		*buf++ = *sci_dma;
236 		*buf++ = *sci_dma;
237 		*buf++ = *sci_dma;
238 		*buf++ = *sci_dma;
239 		*buf++ = *sci_dma;
240 		*buf++ = *sci_dma;
241 		*buf++ = *sci_dma;
242 		*buf++ = *sci_dma;
243 		*buf++ = *sci_dma;
244 		len -= 128;
245 	}
246 	while (len > 0) {
247 		wait = sci_data_wait;
248 		while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
249 		  (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
250 			if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
251 			  || !(*dev->sci_bus_csr & SCI_BUS_BSY)
252 			  || --wait < 0) {
253 #ifdef DEBUG
254 				if (sci_debug)
255 					printf("mlhdma_in fail: l%d i%x w%d\n",
256 					len, csr, wait);
257 #endif
258 				HIST(ixin_wait, wait)
259 				*dev->sci_mode &= ~SCI_MODE_DMA;
260 				return 0;
261 			}
262 		}
263 
264 		*buf++ = *sci_dma;
265 		len--;
266 	}
267 
268 	QPRINTF(("mlhdma_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 	HIST(ixin_wait, wait)
273 	*dev->sci_mode &= ~SCI_MODE_DMA;
274 	return 0;
275 }
276 
277 static int
278 dma_xfer_out (dev, len, buf, phase)
279 	struct sci_softc *dev;
280 	int len;
281 	register u_char *buf;
282 	int phase;
283 {
284 	int wait = sci_data_wait;
285 	u_char csr;
286 	u_char *obp = buf;
287 	volatile register u_char *sci_dma = dev->sci_data + 16;
288 	volatile register u_char *sci_csr = dev->sci_csr;
289 	volatile register u_char *sci_icmd = dev->sci_icmd;
290 
291 	csr = *dev->sci_bus_csr;
292 
293 	QPRINTF(("mlhdma_xfer %d, csr=%02x\n", len, csr));
294 
295 	QPRINTF(("mlhgdma_out {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
296   	 len, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
297 	 buf[6], buf[7], buf[8], buf[9]));
298 
299 	*dev->sci_tcmd = phase;
300 	*dev->sci_mode |= SCI_MODE_DMA;
301 	*dev->sci_icmd = SCI_ICMD_DATA;
302 	*dev->sci_dma_send = 0;
303 	while (len > 64) {
304 		wait = sci_data_wait;
305 		while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
306 		  (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
307 			if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
308 			  || !(*dev->sci_bus_csr & SCI_BUS_BSY)
309 			  || --wait < 0) {
310 #ifdef DEBUG
311 				if (sci_debug)
312 					printf("mlhdma_out fail: l%d i%x w%d\n",
313 					len, csr, wait);
314 #endif
315 				HIST(ixin_wait, wait)
316 				*dev->sci_mode &= ~SCI_MODE_DMA;
317 				return 0;
318 			}
319 		}
320 
321 		*sci_dma = *buf++;
322 		*sci_dma = *buf++;
323 		*sci_dma = *buf++;
324 		*sci_dma = *buf++;
325 		*sci_dma = *buf++;
326 		*sci_dma = *buf++;
327 		*sci_dma = *buf++;
328 		*sci_dma = *buf++;
329 		*sci_dma = *buf++;
330 		*sci_dma = *buf++;
331 		*sci_dma = *buf++;
332 		*sci_dma = *buf++;
333 		*sci_dma = *buf++;
334 		*sci_dma = *buf++;
335 		*sci_dma = *buf++;
336 		*sci_dma = *buf++;
337 		*sci_dma = *buf++;
338 		*sci_dma = *buf++;
339 		*sci_dma = *buf++;
340 		*sci_dma = *buf++;
341 		*sci_dma = *buf++;
342 		*sci_dma = *buf++;
343 		*sci_dma = *buf++;
344 		*sci_dma = *buf++;
345 		*sci_dma = *buf++;
346 		*sci_dma = *buf++;
347 		*sci_dma = *buf++;
348 		*sci_dma = *buf++;
349 		*sci_dma = *buf++;
350 		*sci_dma = *buf++;
351 		*sci_dma = *buf++;
352 		*sci_dma = *buf++;
353 		*sci_dma = *buf++;
354 		*sci_dma = *buf++;
355 		*sci_dma = *buf++;
356 		*sci_dma = *buf++;
357 		*sci_dma = *buf++;
358 		*sci_dma = *buf++;
359 		*sci_dma = *buf++;
360 		*sci_dma = *buf++;
361 		*sci_dma = *buf++;
362 		*sci_dma = *buf++;
363 		*sci_dma = *buf++;
364 		*sci_dma = *buf++;
365 		*sci_dma = *buf++;
366 		*sci_dma = *buf++;
367 		*sci_dma = *buf++;
368 		*sci_dma = *buf++;
369 		*sci_dma = *buf++;
370 		*sci_dma = *buf++;
371 		*sci_dma = *buf++;
372 		*sci_dma = *buf++;
373 		*sci_dma = *buf++;
374 		*sci_dma = *buf++;
375 		*sci_dma = *buf++;
376 		*sci_dma = *buf++;
377 		*sci_dma = *buf++;
378 		*sci_dma = *buf++;
379 		*sci_dma = *buf++;
380 		*sci_dma = *buf++;
381 		*sci_dma = *buf++;
382 		*sci_dma = *buf++;
383 		*sci_dma = *buf++;
384 		*sci_dma = *buf++;
385 		len -= 64;
386 	}
387 	while (len > 0) {
388 		wait = sci_data_wait;
389 		while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
390 		  (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
391 			if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
392 			  || !(*dev->sci_bus_csr & SCI_BUS_BSY)
393 			  || --wait < 0) {
394 #ifdef DEBUG
395 				if (sci_debug)
396 					printf("mlhdma_out fail: l%d i%x w%d\n",
397 					len, csr, wait);
398 #endif
399 				HIST(ixin_wait, wait)
400 				*dev->sci_mode &= ~SCI_MODE_DMA;
401 				return 0;
402 			}
403 		}
404 
405 		*sci_dma = *buf++;
406 		len--;
407 	}
408 
409 	wait = sci_data_wait;
410 	while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) ==
411 	  SCI_CSR_PHASE_MATCH && --wait);
412 
413 	HIST(ixin_wait, wait)
414 	*dev->sci_mode &= ~SCI_MODE_DMA;
415 	return 0;
416 }
417 #endif
418