aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/ataflop.c4
-rw-r--r--drivers/scsi/Kconfig8
-rw-r--r--drivers/scsi/atari_dma_emul.c468
-rw-r--r--drivers/scsi/atari_scsi.c27
4 files changed, 3 insertions, 504 deletions
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index 49f274197b16..432cf4018291 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -1882,10 +1882,6 @@ static int __init atari_floppy_init (void)
1882 /* Amiga, Mac, ... don't have Atari-compatible floppy :-) */ 1882 /* Amiga, Mac, ... don't have Atari-compatible floppy :-) */
1883 return -ENODEV; 1883 return -ENODEV;
1884 1884
1885 if (MACH_IS_HADES)
1886 /* Hades doesn't have Atari-compatible floppy */
1887 return -ENODEV;
1888
1889 if (register_blkdev(FLOPPY_MAJOR,"fd")) 1885 if (register_blkdev(FLOPPY_MAJOR,"fd"))
1890 return -EBUSY; 1886 return -EBUSY;
1891 1887
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index d3b211af4e1c..96033ecb675d 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -1670,14 +1670,6 @@ config ATARI_SCSI_RESET_BOOT
1670 boot process fractionally longer but may assist recovery from errors 1670 boot process fractionally longer but may assist recovery from errors
1671 that leave the devices with SCSI operations partway completed. 1671 that leave the devices with SCSI operations partway completed.
1672 1672
1673config TT_DMA_EMUL
1674 bool "Hades SCSI DMA emulator"
1675 depends on ATARI_SCSI && HADES
1676 help
1677 This option enables code which emulates the TT SCSI DMA chip on the
1678 Hades. This increases the SCSI transfer rates at least ten times
1679 compared to PIO transfers.
1680
1681config MAC_SCSI 1673config MAC_SCSI
1682 bool "Macintosh NCR5380 SCSI" 1674 bool "Macintosh NCR5380 SCSI"
1683 depends on MAC && SCSI=y 1675 depends on MAC && SCSI=y
diff --git a/drivers/scsi/atari_dma_emul.c b/drivers/scsi/atari_dma_emul.c
deleted file mode 100644
index cdc710ea00fa..000000000000
--- a/drivers/scsi/atari_dma_emul.c
+++ /dev/null
@@ -1,468 +0,0 @@
1/*
2 * atari_dma_emul.c -- TT SCSI DMA emulator for the Hades.
3 *
4 * Copyright 1997 Wout Klaren <W.Klaren@inter.nl.net>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
8 * for more details.
9 *
10 * This code was written using the Hades TOS source code as a
11 * reference. This source code can be found on the home page
12 * of Medusa Computer Systems.
13 *
14 * Version 0.1, 1997-09-24.
15 *
16 * This code should be considered experimental. It has only been
17 * tested on a Hades with a 68060. It might not work on a Hades
18 * with a 68040. Make backups of your hard drives before using
19 * this code.
20 */
21
22#include <linux/compiler.h>
23#include <asm/thread_info.h>
24#include <asm/uaccess.h>
25
26#define hades_dma_ctrl (*(unsigned char *) 0xffff8717)
27#define hades_psdm_reg (*(unsigned char *) 0xffff8741)
28
29#define TRANSFER_SIZE 16
30
31struct m68040_frame {
32 unsigned long effaddr; /* effective address */
33 unsigned short ssw; /* special status word */
34 unsigned short wb3s; /* write back 3 status */
35 unsigned short wb2s; /* write back 2 status */
36 unsigned short wb1s; /* write back 1 status */
37 unsigned long faddr; /* fault address */
38 unsigned long wb3a; /* write back 3 address */
39 unsigned long wb3d; /* write back 3 data */
40 unsigned long wb2a; /* write back 2 address */
41 unsigned long wb2d; /* write back 2 data */
42 unsigned long wb1a; /* write back 1 address */
43 unsigned long wb1dpd0; /* write back 1 data/push data 0*/
44 unsigned long pd1; /* push data 1*/
45 unsigned long pd2; /* push data 2*/
46 unsigned long pd3; /* push data 3*/
47};
48
49static void writeback (unsigned short wbs, unsigned long wba,
50 unsigned long wbd, void *old_buserr)
51{
52 mm_segment_t fs = get_fs();
53 static void *save_buserr;
54
55 __asm__ __volatile__ ("movec.l %%vbr,%%a0\n\t"
56 "move.l %0,8(%%a0)\n\t"
57 :
58 : "r" (&&bus_error)
59 : "a0" );
60
61 save_buserr = old_buserr;
62
63 set_fs (MAKE_MM_SEG(wbs & WBTM_040));
64
65 switch (wbs & WBSIZ_040) {
66 case BA_SIZE_BYTE:
67 put_user (wbd & 0xff, (char *)wba);
68 break;
69 case BA_SIZE_WORD:
70 put_user (wbd & 0xffff, (short *)wba);
71 break;
72 case BA_SIZE_LONG:
73 put_user (wbd, (int *)wba);
74 break;
75 }
76
77 set_fs (fs);
78 return;
79
80bus_error:
81 __asm__ __volatile__ ("cmp.l %0,2(%%sp)\n\t"
82 "bcs.s .jump_old\n\t"
83 "cmp.l %1,2(%%sp)\n\t"
84 "bls.s .restore_old\n"
85 ".jump_old:\n\t"
86 "move.l %2,-(%%sp)\n\t"
87 "rts\n"
88 ".restore_old:\n\t"
89 "move.l %%a0,-(%%sp)\n\t"
90 "movec.l %%vbr,%%a0\n\t"
91 "move.l %2,8(%%a0)\n\t"
92 "move.l (%%sp)+,%%a0\n\t"
93 "rte\n\t"
94 :
95 : "i" (writeback), "i" (&&bus_error),
96 "m" (save_buserr) );
97}
98
99/*
100 * static inline void set_restdata_reg(unsigned char *cur_addr)
101 *
102 * Set the rest data register if necessary.
103 */
104
105static inline void set_restdata_reg(unsigned char *cur_addr)
106{
107 if (((long) cur_addr & ~3) != 0)
108 tt_scsi_dma.dma_restdata =
109 *((unsigned long *) ((long) cur_addr & ~3));
110}
111
112/*
113 * void hades_dma_emulator(int irq, void *dummy)
114 *
115 * This code emulates TT SCSI DMA on the Hades.
116 *
117 * Note the following:
118 *
119 * 1. When there is no byte available to read from the SCSI bus, or
120 * when a byte cannot yet bet written to the SCSI bus, a bus
121 * error occurs when reading or writing the pseudo DMA data
122 * register (hades_psdm_reg). We have to catch this bus error
123 * and try again to read or write the byte. If after several tries
124 * we still get a bus error, the interrupt handler is left. When
125 * the byte can be read or written, the interrupt handler is
126 * called again.
127 *
128 * 2. The SCSI interrupt must be disabled in this interrupt handler.
129 *
130 * 3. If we set the EOP signal, the SCSI controller still expects one
131 * byte to be read or written. Therefore the last byte is transferred
132 * separately, after setting the EOP signal.
133 *
134 * 4. When this function is left, the address pointer (start_addr) is
135 * converted to a physical address. Because it points one byte
136 * further than the last transferred byte, it can point outside the
137 * current page. If virt_to_phys() is called with this address we
138 * might get an access error. Therefore virt_to_phys() is called with
139 * start_addr - 1 if the count has reached zero. The result is
140 * increased with one.
141 */
142
143static irqreturn_t hades_dma_emulator(int irq, void *dummy)
144{
145 unsigned long dma_base;
146 register unsigned long dma_cnt asm ("d3");
147 static long save_buserr;
148 register unsigned long save_sp asm ("d4");
149 register int tries asm ("d5");
150 register unsigned char *start_addr asm ("a3"), *end_addr asm ("a4");
151 register unsigned char *eff_addr;
152 register unsigned char *psdm_reg;
153 unsigned long rem;
154
155 atari_disable_irq(IRQ_TT_MFP_SCSI);
156
157 /*
158 * Read the dma address and count registers.
159 */
160
161 dma_base = SCSI_DMA_READ_P(dma_addr);
162 dma_cnt = SCSI_DMA_READ_P(dma_cnt);
163
164 /*
165 * Check if DMA is still enabled.
166 */
167
168 if ((tt_scsi_dma.dma_ctrl & 2) == 0)
169 {
170 atari_enable_irq(IRQ_TT_MFP_SCSI);
171 return IRQ_HANDLED;
172 }
173
174 if (dma_cnt == 0)
175 {
176 printk(KERN_NOTICE "DMA emulation: count is zero.\n");
177 tt_scsi_dma.dma_ctrl &= 0xfd; /* DMA ready. */
178 atari_enable_irq(IRQ_TT_MFP_SCSI);
179 return IRQ_HANDLED;
180 }
181
182 /*
183 * Install new bus error routine.
184 */
185
186 __asm__ __volatile__ ("movec.l %%vbr,%%a0\n\t"
187 "move.l 8(%%a0),%0\n\t"
188 "move.l %1,8(%%a0)\n\t"
189 : "=&r" (save_buserr)
190 : "r" (&&scsi_bus_error)
191 : "a0" );
192
193 hades_dma_ctrl &= 0xfc; /* Bus error and EOP off. */
194
195 /*
196 * Save the stack pointer.
197 */
198
199 __asm__ __volatile__ ("move.l %%sp,%0\n\t"
200 : "=&r" (save_sp) );
201
202 tries = 100; /* Maximum number of bus errors. */
203 start_addr = phys_to_virt(dma_base);
204 end_addr = start_addr + dma_cnt;
205
206scsi_loop:
207 dma_cnt--;
208 rem = dma_cnt & (TRANSFER_SIZE - 1);
209 dma_cnt &= ~(TRANSFER_SIZE - 1);
210 psdm_reg = &hades_psdm_reg;
211
212 if (tt_scsi_dma.dma_ctrl & 1) /* Read or write? */
213 {
214 /*
215 * SCSI write. Abort when count is zero.
216 */
217
218 switch (rem)
219 {
220 case 0:
221 while (dma_cnt > 0)
222 {
223 dma_cnt -= TRANSFER_SIZE;
224
225 *psdm_reg = *start_addr++;
226 case 15:
227 *psdm_reg = *start_addr++;
228 case 14:
229 *psdm_reg = *start_addr++;
230 case 13:
231 *psdm_reg = *start_addr++;
232 case 12:
233 *psdm_reg = *start_addr++;
234 case 11:
235 *psdm_reg = *start_addr++;
236 case 10:
237 *psdm_reg = *start_addr++;
238 case 9:
239 *psdm_reg = *start_addr++;
240 case 8:
241 *psdm_reg = *start_addr++;
242 case 7:
243 *psdm_reg = *start_addr++;
244 case 6:
245 *psdm_reg = *start_addr++;
246 case 5:
247 *psdm_reg = *start_addr++;
248 case 4:
249 *psdm_reg = *start_addr++;
250 case 3:
251 *psdm_reg = *start_addr++;
252 case 2:
253 *psdm_reg = *start_addr++;
254 case 1:
255 *psdm_reg = *start_addr++;
256 }
257 }
258
259 hades_dma_ctrl |= 1; /* Set EOP. */
260 udelay(10);
261 *psdm_reg = *start_addr++; /* Dummy byte. */
262 tt_scsi_dma.dma_ctrl &= 0xfd; /* DMA ready. */
263 }
264 else
265 {
266 /*
267 * SCSI read. Abort when count is zero.
268 */
269
270 switch (rem)
271 {
272 case 0:
273 while (dma_cnt > 0)
274 {
275 dma_cnt -= TRANSFER_SIZE;
276
277 *start_addr++ = *psdm_reg;
278 case 15:
279 *start_addr++ = *psdm_reg;
280 case 14:
281 *start_addr++ = *psdm_reg;
282 case 13:
283 *start_addr++ = *psdm_reg;
284 case 12:
285 *start_addr++ = *psdm_reg;
286 case 11:
287 *start_addr++ = *psdm_reg;
288 case 10:
289 *start_addr++ = *psdm_reg;
290 case 9:
291 *start_addr++ = *psdm_reg;
292 case 8:
293 *start_addr++ = *psdm_reg;
294 case 7:
295 *start_addr++ = *psdm_reg;
296 case 6:
297 *start_addr++ = *psdm_reg;
298 case 5:
299 *start_addr++ = *psdm_reg;
300 case 4:
301 *start_addr++ = *psdm_reg;
302 case 3:
303 *start_addr++ = *psdm_reg;
304 case 2:
305 *start_addr++ = *psdm_reg;
306 case 1:
307 *start_addr++ = *psdm_reg;
308 }
309 }
310
311 hades_dma_ctrl |= 1; /* Set EOP. */
312 udelay(10);
313 *start_addr++ = *psdm_reg;
314 tt_scsi_dma.dma_ctrl &= 0xfd; /* DMA ready. */
315
316 set_restdata_reg(start_addr);
317 }
318
319 if (start_addr != end_addr)
320 printk(KERN_CRIT "DMA emulation: FATAL: Count is not zero at end of transfer.\n");
321
322 dma_cnt = end_addr - start_addr;
323
324scsi_end:
325 dma_base = (dma_cnt == 0) ? virt_to_phys(start_addr - 1) + 1 :
326 virt_to_phys(start_addr);
327
328 SCSI_DMA_WRITE_P(dma_addr, dma_base);
329 SCSI_DMA_WRITE_P(dma_cnt, dma_cnt);
330
331 /*
332 * Restore old bus error routine.
333 */
334
335 __asm__ __volatile__ ("movec.l %%vbr,%%a0\n\t"
336 "move.l %0,8(%%a0)\n\t"
337 :
338 : "r" (save_buserr)
339 : "a0" );
340
341 atari_enable_irq(IRQ_TT_MFP_SCSI);
342
343 return IRQ_HANDLED;
344
345scsi_bus_error:
346 /*
347 * First check if the bus error is caused by our code.
348 * If not, call the original handler.
349 */
350
351 __asm__ __volatile__ ("cmp.l %0,2(%%sp)\n\t"
352 "bcs.s .old_vector\n\t"
353 "cmp.l %1,2(%%sp)\n\t"
354 "bls.s .scsi_buserr\n"
355 ".old_vector:\n\t"
356 "move.l %2,-(%%sp)\n\t"
357 "rts\n"
358 ".scsi_buserr:\n\t"
359 :
360 : "i" (&&scsi_loop), "i" (&&scsi_end),
361 "m" (save_buserr) );
362
363 if (CPU_IS_060)
364 {
365 /*
366 * Get effective address and restore the stack.
367 */
368
369 __asm__ __volatile__ ("move.l 8(%%sp),%0\n\t"
370 "move.l %1,%%sp\n\t"
371 : "=a&" (eff_addr)
372 : "r" (save_sp) );
373 }
374 else
375 {
376 register struct m68040_frame *frame;
377
378 __asm__ __volatile__ ("lea 8(%%sp),%0\n\t"
379 : "=a&" (frame) );
380
381 if (tt_scsi_dma.dma_ctrl & 1)
382 {
383 /*
384 * Bus error while writing.
385 */
386
387 if (frame->wb3s & WBV_040)
388 {
389 if (frame->wb3a == (long) &hades_psdm_reg)
390 start_addr--;
391 else
392 writeback(frame->wb3s, frame->wb3a,
393 frame->wb3d, &&scsi_bus_error);
394 }
395
396 if (frame->wb2s & WBV_040)
397 {
398 if (frame->wb2a == (long) &hades_psdm_reg)
399 start_addr--;
400 else
401 writeback(frame->wb2s, frame->wb2a,
402 frame->wb2d, &&scsi_bus_error);
403 }
404
405 if (frame->wb1s & WBV_040)
406 {
407 if (frame->wb1a == (long) &hades_psdm_reg)
408 start_addr--;
409 }
410 }
411 else
412 {
413 /*
414 * Bus error while reading.
415 */
416
417 if (frame->wb3s & WBV_040)
418 writeback(frame->wb3s, frame->wb3a,
419 frame->wb3d, &&scsi_bus_error);
420 }
421
422 eff_addr = (unsigned char *) frame->faddr;
423
424 __asm__ __volatile__ ("move.l %0,%%sp\n\t"
425 :
426 : "r" (save_sp) );
427 }
428
429 dma_cnt = end_addr - start_addr;
430
431 if (eff_addr == &hades_psdm_reg)
432 {
433 /*
434 * Bus error occurred while reading the pseudo
435 * DMA register. Time out.
436 */
437
438 tries--;
439
440 if (tries <= 0)
441 {
442 if ((tt_scsi_dma.dma_ctrl & 1) == 0) /* Read or write? */
443 set_restdata_reg(start_addr);
444
445 if (dma_cnt <= 1)
446 printk(KERN_CRIT "DMA emulation: Fatal "
447 "error while %s the last byte.\n",
448 (tt_scsi_dma.dma_ctrl & 1)
449 ? "writing" : "reading");
450
451 goto scsi_end;
452 }
453 else
454 goto scsi_loop;
455 }
456 else
457 {
458 /*
459 * Bus error during pseudo DMA transfer.
460 * Terminate the DMA transfer.
461 */
462
463 hades_dma_ctrl |= 3; /* Set EOP and bus error. */
464 if ((tt_scsi_dma.dma_ctrl & 1) == 0) /* Read or write? */
465 set_restdata_reg(start_addr);
466 goto scsi_end;
467 }
468}
diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c
index f5732d8f67fe..21fe07f9df87 100644
--- a/drivers/scsi/atari_scsi.c
+++ b/drivers/scsi/atari_scsi.c
@@ -249,10 +249,6 @@ static int setup_hostid = -1;
249module_param(setup_hostid, int, 0); 249module_param(setup_hostid, int, 0);
250 250
251 251
252#if defined(CONFIG_TT_DMA_EMUL)
253#include "atari_dma_emul.c"
254#endif
255
256#if defined(REAL_DMA) 252#if defined(REAL_DMA)
257 253
258static int scsi_dma_is_ignored_buserr(unsigned char dma_stat) 254static int scsi_dma_is_ignored_buserr(unsigned char dma_stat)
@@ -695,21 +691,8 @@ int atari_scsi_detect(struct scsi_host_template *host)
695#ifdef REAL_DMA 691#ifdef REAL_DMA
696 tt_scsi_dma.dma_ctrl = 0; 692 tt_scsi_dma.dma_ctrl = 0;
697 atari_dma_residual = 0; 693 atari_dma_residual = 0;
698#ifdef CONFIG_TT_DMA_EMUL 694
699 if (MACH_IS_HADES) { 695 if (MACH_IS_MEDUSA) {
700 if (request_irq(IRQ_AUTO_2, hades_dma_emulator,
701 IRQ_TYPE_PRIO, "Hades DMA emulator",
702 hades_dma_emulator)) {
703 printk(KERN_ERR "atari_scsi_detect: cannot allocate irq %d, aborting (MACH_IS_HADES)",IRQ_AUTO_2);
704 free_irq(IRQ_TT_MFP_SCSI, instance);
705 scsi_unregister(atari_scsi_host);
706 atari_stram_free(atari_dma_buffer);
707 atari_dma_buffer = 0;
708 return 0;
709 }
710 }
711#endif
712 if (MACH_IS_MEDUSA || MACH_IS_HADES) {
713 /* While the read overruns (described by Drew Eckhardt in 696 /* While the read overruns (described by Drew Eckhardt in
714 * NCR5380.c) never happened on TTs, they do in fact on the Medusa 697 * NCR5380.c) never happened on TTs, they do in fact on the Medusa
715 * (This was the cause why SCSI didn't work right for so long 698 * (This was the cause why SCSI didn't work right for so long
@@ -1007,11 +990,7 @@ static unsigned long atari_dma_xfer_len(unsigned long wanted_len,
1007 Scsi_Cmnd *cmd, int write_flag) 990 Scsi_Cmnd *cmd, int write_flag)
1008{ 991{
1009 unsigned long possible_len, limit; 992 unsigned long possible_len, limit;
1010#ifndef CONFIG_TT_DMA_EMUL 993
1011 if (MACH_IS_HADES)
1012 /* Hades has no SCSI DMA at all :-( Always force use of PIO */
1013 return 0;
1014#endif
1015 if (IS_A_TT()) 994 if (IS_A_TT())
1016 /* TT SCSI DMA can transfer arbitrary #bytes */ 995 /* TT SCSI DMA can transfer arbitrary #bytes */
1017 return wanted_len; 996 return wanted_len;