Blame view

drivers/scsi/atari_scsi.c 34.7 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
  /*
   * atari_scsi.c -- Device dependent functions for the Atari generic SCSI port
   *
   * Copyright 1994 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
   *
   *   Loosely based on the work of Robert De Vries' team and added:
   *    - working real DMA
   *    - Falcon support (untested yet!)   ++bjoern fixed and now it works
   *    - lots of extensions and bug fixes.
   *
   * This file is subject to the terms and conditions of the GNU General Public
   * License.  See the file COPYING in the main directory of this archive
   * for more details.
   *
   */
  
  
  /**************************************************************************/
  /*                                                                        */
  /* Notes for Falcon SCSI:                                                 */
  /* ----------------------                                                 */
  /*                                                                        */
  /* Since the Falcon SCSI uses the ST-DMA chip, that is shared among       */
  /* several device drivers, locking and unlocking the access to this       */
  /* chip is required. But locking is not possible from an interrupt,       */
  /* since it puts the process to sleep if the lock is not available.       */
  /* This prevents "late" locking of the DMA chip, i.e. locking it just     */
  /* before using it, since in case of disconnection-reconnection           */
  /* commands, the DMA is started from the reselection interrupt.           */
  /*                                                                        */
  /* Two possible schemes for ST-DMA-locking would be:                      */
  /*  1) The lock is taken for each command separately and disconnecting    */
  /*     is forbidden (i.e. can_queue = 1).                                 */
  /*  2) The DMA chip is locked when the first command comes in and         */
  /*     released when the last command is finished and all queues are      */
  /*     empty.                                                             */
  /* The first alternative would result in bad performance, since the       */
  /* interleaving of commands would not be used. The second is unfair to    */
  /* other drivers using the ST-DMA, because the queues will seldom be      */
  /* totally empty if there is a lot of disk traffic.                       */
  /*                                                                        */
  /* For this reasons I decided to employ a more elaborate scheme:          */
  /*  - First, we give up the lock every time we can (for fairness), this    */
  /*    means every time a command finishes and there are no other commands */
  /*    on the disconnected queue.                                          */
  /*  - If there are others waiting to lock the DMA chip, we stop           */
  /*    issuing commands, i.e. moving them onto the issue queue.           */
  /*    Because of that, the disconnected queue will run empty in a         */
  /*    while. Instead we go to sleep on a 'fairness_queue'.                */
  /*  - If the lock is released, all processes waiting on the fairness      */
  /*    queue will be woken. The first of them tries to re-lock the DMA,     */
  /*    the others wait for the first to finish this task. After that,      */
  /*    they can all run on and do their commands...                        */
  /* This sounds complicated (and it is it :-(), but it seems to be a       */
  /* good compromise between fairness and performance: As long as no one     */
  /* else wants to work with the ST-DMA chip, SCSI can go along as          */
  /* usual. If now someone else comes, this behaviour is changed to a       */
  /* "fairness mode": just already initiated commands are finished and      */
  /* then the lock is released. The other one waiting will probably win     */
  /* the race for locking the DMA, since it was waiting for longer. And     */
  /* after it has finished, SCSI can go ahead again. Finally: I hope I      */
  /* have not produced any deadlock possibilities!                          */
  /*                                                                        */
  /**************************************************************************/
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65
66
67
  #include <linux/module.h>
  
  #define NDEBUG (0)
3130d905b   Roman Zippel   m68k: Atari SCSI ...
68
69
70
  #define NDEBUG_ABORT		0x00100000
  #define NDEBUG_TAGS		0x00200000
  #define NDEBUG_MERGING		0x00400000
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
72
73
74
75
76
77
78
79
80
81
82
83
84
  
  #define AUTOSENSE
  /* For the Atari version, use only polled IO or REAL_DMA */
  #define	REAL_DMA
  /* Support tagged queuing? (on devices that are able to... :-) */
  #define	SUPPORT_TAGS
  #define	MAX_TAGS 32
  
  #include <linux/types.h>
  #include <linux/stddef.h>
  #include <linux/ctype.h>
  #include <linux/delay.h>
  #include <linux/mm.h>
  #include <linux/blkdev.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
  #include <linux/interrupt.h>
  #include <linux/init.h>
  #include <linux/nvram.h>
  #include <linux/bitops.h>
  
  #include <asm/setup.h>
  #include <asm/atarihw.h>
  #include <asm/atariints.h>
  #include <asm/page.h>
  #include <asm/pgtable.h>
  #include <asm/irq.h>
  #include <asm/traps.h>
  
  #include "scsi.h"
  #include <scsi/scsi_host.h>
  #include "atari_scsi.h"
  #include "NCR5380.h"
  #include <asm/atari_stdma.h>
  #include <asm/atari_stram.h>
  #include <asm/io.h>
  
  #include <linux/stat.h>
  
  #define	IS_A_TT()	ATARIHW_PRESENT(TT_SCSI)
  
  #define	SCSI_DMA_WRITE_P(elt,val)				\
  	do {							\
  		unsigned long v = val;				\
  		tt_scsi_dma.elt##_lo = v & 0xff;		\
  		v >>= 8;					\
  		tt_scsi_dma.elt##_lmd = v & 0xff;		\
  		v >>= 8;					\
  		tt_scsi_dma.elt##_hmd = v & 0xff;		\
  		v >>= 8;					\
  		tt_scsi_dma.elt##_hi = v & 0xff;		\
  	} while(0)
  
  #define	SCSI_DMA_READ_P(elt)					\
  	(((((((unsigned long)tt_scsi_dma.elt##_hi << 8) |	\
  	     (unsigned long)tt_scsi_dma.elt##_hmd) << 8) |	\
  	   (unsigned long)tt_scsi_dma.elt##_lmd) << 8) |	\
  	 (unsigned long)tt_scsi_dma.elt##_lo)
  
  
  static inline void SCSI_DMA_SETADR(unsigned long adr)
  {
  	st_dma.dma_lo = (unsigned char)adr;
  	MFPDELAY();
  	adr >>= 8;
  	st_dma.dma_md = (unsigned char)adr;
  	MFPDELAY();
  	adr >>= 8;
  	st_dma.dma_hi = (unsigned char)adr;
  	MFPDELAY();
  }
  
  static inline unsigned long SCSI_DMA_GETADR(void)
  {
  	unsigned long adr;
  	adr = st_dma.dma_lo;
  	MFPDELAY();
  	adr |= (st_dma.dma_md & 0xff) << 8;
  	MFPDELAY();
  	adr |= (st_dma.dma_hi & 0xff) << 16;
  	MFPDELAY();
  	return adr;
  }
  
  static inline void ENABLE_IRQ(void)
  {
  	if (IS_A_TT())
  		atari_enable_irq(IRQ_TT_MFP_SCSI);
  	else
  		atari_enable_irq(IRQ_MFP_FSCSI);
  }
  
  static inline void DISABLE_IRQ(void)
  {
  	if (IS_A_TT())
  		atari_disable_irq(IRQ_TT_MFP_SCSI);
  	else
  		atari_disable_irq(IRQ_MFP_FSCSI);
  }
  
  
  #define HOSTDATA_DMALEN		(((struct NCR5380_hostdata *) \
  				(atari_scsi_host->hostdata))->dma_len)
  
  /* Time (in jiffies) to wait after a reset; the SCSI standard calls for 250ms,
   * we usually do 0.5s to be on the safe side. But Toshiba CD-ROMs once more
   * need ten times the standard value... */
  #ifndef CONFIG_ATARI_SCSI_TOSHIBA_DELAY
  #define	AFTER_RESET_DELAY	(HZ/2)
  #else
  #define	AFTER_RESET_DELAY	(5*HZ/2)
  #endif
  
  /***************************** Prototypes *****************************/
  
  #ifdef REAL_DMA
c28bda251   Roman Zippel   m68k: Reformat th...
185
186
187
188
189
190
  static int scsi_dma_is_ignored_buserr(unsigned char dma_stat);
  static void atari_scsi_fetch_restbytes(void);
  static long atari_scsi_dma_residual(struct Scsi_Host *instance);
  static int falcon_classify_cmd(Scsi_Cmnd *cmd);
  static unsigned long atari_dma_xfer_len(unsigned long wanted_len,
  					Scsi_Cmnd *cmd, int write_flag);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191
  #endif
c28bda251   Roman Zippel   m68k: Reformat th...
192
193
194
195
  static irqreturn_t scsi_tt_intr(int irq, void *dummy);
  static irqreturn_t scsi_falcon_intr(int irq, void *dummy);
  static void falcon_release_lock_if_possible(struct NCR5380_hostdata *hostdata);
  static void falcon_get_lock(void);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
196
  #ifdef CONFIG_ATARI_SCSI_RESET_BOOT
c28bda251   Roman Zippel   m68k: Reformat th...
197
  static void atari_scsi_reset_boot(void);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
198
  #endif
c28bda251   Roman Zippel   m68k: Reformat th...
199
200
201
202
  static unsigned char atari_scsi_tt_reg_read(unsigned char reg);
  static void atari_scsi_tt_reg_write(unsigned char reg, unsigned char value);
  static unsigned char atari_scsi_falcon_reg_read(unsigned char reg);
  static void atari_scsi_falcon_reg_write(unsigned char reg, unsigned char value);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
203
204
  
  /************************* End of Prototypes **************************/
c28bda251   Roman Zippel   m68k: Reformat th...
205
206
207
  static struct Scsi_Host *atari_scsi_host;
  static unsigned char (*atari_scsi_reg_read)(unsigned char reg);
  static void (*atari_scsi_reg_write)(unsigned char reg, unsigned char value);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208
209
210
211
212
  
  #ifdef REAL_DMA
  static unsigned long	atari_dma_residual, atari_dma_startaddr;
  static short		atari_dma_active;
  /* pointer to the dribble buffer */
c28bda251   Roman Zippel   m68k: Reformat th...
213
  static char		*atari_dma_buffer;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
  /* precalculated physical address of the dribble buffer */
  static unsigned long	atari_dma_phys_buffer;
  /* != 0 tells the Falcon int handler to copy data from the dribble buffer */
  static char		*atari_dma_orig_addr;
  /* size of the dribble buffer; 4k seems enough, since the Falcon cannot use
   * scatter-gather anyway, so most transfers are 1024 byte only. In the rare
   * cases where requests to physical contiguous buffers have been merged, this
   * request is <= 4k (one page). So I don't think we have to split transfers
   * just due to this buffer size...
   */
  #define	STRAM_BUFFER_SIZE	(4096)
  /* mask for address bits that can't be used with the ST-DMA */
  static unsigned long	atari_dma_stram_mask;
  #define STRAM_ADDR(a)	(((a) & atari_dma_stram_mask) == 0)
  /* number of bytes to cut from a transfer to handle NCR overruns */
c28bda251   Roman Zippel   m68k: Reformat th...
229
  static int atari_read_overruns;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
230
231
232
  #endif
  
  static int setup_can_queue = -1;
8d3b33f67   Rusty Russell   [PATCH] Remove MO...
233
  module_param(setup_can_queue, int, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
  static int setup_cmd_per_lun = -1;
8d3b33f67   Rusty Russell   [PATCH] Remove MO...
235
  module_param(setup_cmd_per_lun, int, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
236
  static int setup_sg_tablesize = -1;
8d3b33f67   Rusty Russell   [PATCH] Remove MO...
237
  module_param(setup_sg_tablesize, int, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
238
239
  #ifdef SUPPORT_TAGS
  static int setup_use_tagged_queuing = -1;
8d3b33f67   Rusty Russell   [PATCH] Remove MO...
240
  module_param(setup_use_tagged_queuing, int, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
241
242
  #endif
  static int setup_hostid = -1;
8d3b33f67   Rusty Russell   [PATCH] Remove MO...
243
  module_param(setup_hostid, int, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
244

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245
  #if defined(REAL_DMA)
c28bda251   Roman Zippel   m68k: Reformat th...
246
  static int scsi_dma_is_ignored_buserr(unsigned char dma_stat)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
247
248
  {
  	int i;
c28bda251   Roman Zippel   m68k: Reformat th...
249
  	unsigned long addr = SCSI_DMA_READ_P(dma_addr), end_addr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
250
251
252
253
254
255
256
  
  	if (dma_stat & 0x01) {
  
  		/* A bus error happens when DMA-ing from the last page of a
  		 * physical memory chunk (DMA prefetch!), but that doesn't hurt.
  		 * Check for this case:
  		 */
c28bda251   Roman Zippel   m68k: Reformat th...
257
258
259
  
  		for (i = 0; i < m68k_num_memory; ++i) {
  			end_addr = m68k_memory[i].addr + m68k_memory[i].size;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
260
  			if (end_addr <= addr && addr <= end_addr + 4)
c28bda251   Roman Zippel   m68k: Reformat th...
261
  				return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262
263
  		}
  	}
c28bda251   Roman Zippel   m68k: Reformat th...
264
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
266
267
268
269
270
271
272
  }
  
  
  #if 0
  /* Dead code... wasn't called anyway :-) and causes some trouble, because at
   * end-of-DMA, both SCSI ints are triggered simultaneously, so the NCR int has
   * to clear the DMA int pending bit before it allows other level 6 interrupts.
   */
c28bda251   Roman Zippel   m68k: Reformat th...
273
  static void scsi_dma_buserr(int irq, void *dummy)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
274
  {
c28bda251   Roman Zippel   m68k: Reformat th...
275
  	unsigned char dma_stat = tt_scsi_dma.dma_ctrl;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
276
277
278
  
  	/* Don't do anything if a NCR interrupt is pending. Probably it's just
  	 * masked... */
c28bda251   Roman Zippel   m68k: Reformat th...
279
  	if (atari_irq_pending(IRQ_TT_MFP_SCSI))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
280
  		return;
c28bda251   Roman Zippel   m68k: Reformat th...
281

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
282
283
284
285
  	printk("Bad SCSI DMA interrupt! dma_addr=0x%08lx dma_stat=%02x dma_cnt=%08lx
  ",
  	       SCSI_DMA_READ_P(dma_addr), dma_stat, SCSI_DMA_READ_P(dma_cnt));
  	if (dma_stat & 0x80) {
c28bda251   Roman Zippel   m68k: Reformat th...
286
287
288
289
  		if (!scsi_dma_is_ignored_buserr(dma_stat))
  			printk("SCSI DMA bus error -- bad DMA programming!
  ");
  	} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
290
291
292
293
294
  		/* Under normal circumstances we never should get to this point,
  		 * since both interrupts are triggered simultaneously and the 5380
  		 * int has higher priority. When this irq is handled, that DMA
  		 * interrupt is cleared. So a warning message is printed here.
  		 */
c28bda251   Roman Zippel   m68k: Reformat th...
295
296
  		printk("SCSI DMA intr ?? -- this shouldn't happen!
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
297
298
299
300
301
  	}
  }
  #endif
  
  #endif
c28bda251   Roman Zippel   m68k: Reformat th...
302
  static irqreturn_t scsi_tt_intr(int irq, void *dummy)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303
304
305
306
307
308
309
310
311
312
313
314
315
316
  {
  #ifdef REAL_DMA
  	int dma_stat;
  
  	dma_stat = tt_scsi_dma.dma_ctrl;
  
  	INT_PRINTK("scsi%d: NCR5380 interrupt, DMA status = %02x
  ",
  		   atari_scsi_host->host_no, dma_stat & 0xff);
  
  	/* Look if it was the DMA that has interrupted: First possibility
  	 * is that a bus error occurred...
  	 */
  	if (dma_stat & 0x80) {
c28bda251   Roman Zippel   m68k: Reformat th...
317
  		if (!scsi_dma_is_ignored_buserr(dma_stat)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
  			printk(KERN_ERR "SCSI DMA caused bus error near 0x%08lx
  ",
  			       SCSI_DMA_READ_P(dma_addr));
  			printk(KERN_CRIT "SCSI DMA bus error -- bad DMA programming!");
  		}
  	}
  
  	/* If the DMA is active but not finished, we have the case
  	 * that some other 5380 interrupt occurred within the DMA transfer.
  	 * This means we have residual bytes, if the desired end address
  	 * is not yet reached. Maybe we have to fetch some bytes from the
  	 * rest data register, too. The residual must be calculated from
  	 * the address pointer, not the counter register, because only the
  	 * addr reg counts bytes not yet written and pending in the rest
  	 * data reg!
  	 */
  	if ((dma_stat & 0x02) && !(dma_stat & 0x40)) {
c28bda251   Roman Zippel   m68k: Reformat th...
335
  		atari_dma_residual = HOSTDATA_DMALEN - (SCSI_DMA_READ_P(dma_addr) - atari_dma_startaddr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
336
337
338
339
340
341
342
343
  
  		DMA_PRINTK("SCSI DMA: There are %ld residual bytes.
  ",
  			   atari_dma_residual);
  
  		if ((signed int)atari_dma_residual < 0)
  			atari_dma_residual = 0;
  		if ((dma_stat & 1) == 0) {
c28bda251   Roman Zippel   m68k: Reformat th...
344
345
346
347
  			/*
  			 * After read operations, we maybe have to
  			 * transport some rest bytes
  			 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
348
  			atari_scsi_fetch_restbytes();
c28bda251   Roman Zippel   m68k: Reformat th...
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
  		} else {
  			/*
  			 * There seems to be a nasty bug in some SCSI-DMA/NCR
  			 * combinations: If a target disconnects while a write
  			 * operation is going on, the address register of the
  			 * DMA may be a few bytes farer than it actually read.
  			 * This is probably due to DMA prefetching and a delay
  			 * between DMA and NCR.  Experiments showed that the
  			 * dma_addr is 9 bytes to high, but this could vary.
  			 * The problem is, that the residual is thus calculated
  			 * wrong and the next transfer will start behind where
  			 * it should.  So we round up the residual to the next
  			 * multiple of a sector size, if it isn't already a
  			 * multiple and the originally expected transfer size
  			 * was.  The latter condition is there to ensure that
  			 * the correction is taken only for "real" data
  			 * transfers and not for, e.g., the parameters of some
  			 * other command.  These shouldn't disconnect anyway.
  			 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
  			if (atari_dma_residual & 0x1ff) {
  				DMA_PRINTK("SCSI DMA: DMA bug corrected, "
  					   "difference %ld bytes
  ",
  					   512 - (atari_dma_residual & 0x1ff));
  				atari_dma_residual = (atari_dma_residual + 511) & ~0x1ff;
  			}
  		}
  		tt_scsi_dma.dma_ctrl = 0;
  	}
  
  	/* If the DMA is finished, fetch the rest bytes and turn it off */
  	if (dma_stat & 0x40) {
  		atari_dma_residual = 0;
  		if ((dma_stat & 1) == 0)
  			atari_scsi_fetch_restbytes();
  		tt_scsi_dma.dma_ctrl = 0;
  	}
  
  #endif /* REAL_DMA */
c28bda251   Roman Zippel   m68k: Reformat th...
388

1e6416643   Jeff Garzik   [SCSI] NCR5380: F...
389
  	NCR5380_intr(irq, dummy);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
390
391
392
  
  #if 0
  	/* To be sure the int is not masked */
c28bda251   Roman Zippel   m68k: Reformat th...
393
  	atari_enable_irq(IRQ_TT_MFP_SCSI);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
394
395
396
  #endif
  	return IRQ_HANDLED;
  }
c28bda251   Roman Zippel   m68k: Reformat th...
397
  static irqreturn_t scsi_falcon_intr(int irq, void *dummy)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
  {
  #ifdef REAL_DMA
  	int dma_stat;
  
  	/* Turn off DMA and select sector counter register before
  	 * accessing the status register (Atari recommendation!)
  	 */
  	st_dma.dma_mode_status = 0x90;
  	dma_stat = st_dma.dma_mode_status;
  
  	/* Bit 0 indicates some error in the DMA process... don't know
  	 * what happened exactly (no further docu).
  	 */
  	if (!(dma_stat & 0x01)) {
  		/* DMA error */
  		printk(KERN_CRIT "SCSI DMA error near 0x%08lx!
  ", SCSI_DMA_GETADR());
  	}
  
  	/* If the DMA was active, but now bit 1 is not clear, it is some
  	 * other 5380 interrupt that finishes the DMA transfer. We have to
  	 * calculate the number of residual bytes and give a warning if
  	 * bytes are stuck in the ST-DMA fifo (there's no way to reach them!)
  	 */
  	if (atari_dma_active && (dma_stat & 0x02)) {
c28bda251   Roman Zippel   m68k: Reformat th...
423
  		unsigned long transferred;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
  
  		transferred = SCSI_DMA_GETADR() - atari_dma_startaddr;
  		/* The ST-DMA address is incremented in 2-byte steps, but the
  		 * data are written only in 16-byte chunks. If the number of
  		 * transferred bytes is not divisible by 16, the remainder is
  		 * lost somewhere in outer space.
  		 */
  		if (transferred & 15)
  			printk(KERN_ERR "SCSI DMA error: %ld bytes lost in "
  			       "ST-DMA fifo
  ", transferred & 15);
  
  		atari_dma_residual = HOSTDATA_DMALEN - transferred;
  		DMA_PRINTK("SCSI DMA: There are %ld residual bytes.
  ",
  			   atari_dma_residual);
c28bda251   Roman Zippel   m68k: Reformat th...
440
  	} else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
441
442
443
444
445
446
447
448
449
450
451
452
453
  		atari_dma_residual = 0;
  	atari_dma_active = 0;
  
  	if (atari_dma_orig_addr) {
  		/* If the dribble buffer was used on a read operation, copy the DMA-ed
  		 * data to the original destination address.
  		 */
  		memcpy(atari_dma_orig_addr, phys_to_virt(atari_dma_startaddr),
  		       HOSTDATA_DMALEN - atari_dma_residual);
  		atari_dma_orig_addr = NULL;
  	}
  
  #endif /* REAL_DMA */
1e6416643   Jeff Garzik   [SCSI] NCR5380: F...
454
  	NCR5380_intr(irq, dummy);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
455
456
457
458
459
  	return IRQ_HANDLED;
  }
  
  
  #ifdef REAL_DMA
c28bda251   Roman Zippel   m68k: Reformat th...
460
  static void atari_scsi_fetch_restbytes(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
  {
  	int nr;
  	char *src, *dst;
  	unsigned long phys_dst;
  
  	/* fetch rest bytes in the DMA register */
  	phys_dst = SCSI_DMA_READ_P(dma_addr);
  	nr = phys_dst & 3;
  	if (nr) {
  		/* there are 'nr' bytes left for the last long address
  		   before the DMA pointer */
  		phys_dst ^= nr;
  		DMA_PRINTK("SCSI DMA: there are %d rest bytes for phys addr 0x%08lx",
  			   nr, phys_dst);
  		/* The content of the DMA pointer is a physical address!  */
  		dst = phys_to_virt(phys_dst);
  		DMA_PRINTK(" = virt addr %p
  ", dst);
  		for (src = (char *)&tt_scsi_dma.dma_restdata; nr != 0; --nr)
  			*dst++ = *src++;
  	}
  }
  #endif /* REAL_DMA */
  
  
  static int falcon_got_lock = 0;
  static DECLARE_WAIT_QUEUE_HEAD(falcon_fairness_wait);
  static int falcon_trying_lock = 0;
  static DECLARE_WAIT_QUEUE_HEAD(falcon_try_wait);
  static int falcon_dont_release = 0;
  
  /* This function releases the lock on the DMA chip if there is no
   * connected command and the disconnected queue is empty. On
   * releasing, instances of falcon_get_lock are awoken, that put
   * themselves to sleep for fairness. They can now try to get the lock
   * again (but others waiting longer more probably will win).
   */
c28bda251   Roman Zippel   m68k: Reformat th...
498
  static void falcon_release_lock_if_possible(struct NCR5380_hostdata *hostdata)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
499
500
  {
  	unsigned long flags;
c28bda251   Roman Zippel   m68k: Reformat th...
501
502
503
  
  	if (IS_A_TT())
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
504
  	local_irq_save(flags);
c28bda251   Roman Zippel   m68k: Reformat th...
505
506
  	if (falcon_got_lock && !hostdata->disconnected_queue &&
  	    !hostdata->issue_queue && !hostdata->connected) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
507
508
509
510
511
512
513
514
515
516
517
  
  		if (falcon_dont_release) {
  #if 0
  			printk("WARNING: Lock release not allowed. Ignored
  ");
  #endif
  			local_irq_restore(flags);
  			return;
  		}
  		falcon_got_lock = 0;
  		stdma_release();
c28bda251   Roman Zippel   m68k: Reformat th...
518
  		wake_up(&falcon_fairness_wait);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
  	}
  
  	local_irq_restore(flags);
  }
  
  /* This function manages the locking of the ST-DMA.
   * If the DMA isn't locked already for SCSI, it tries to lock it by
   * calling stdma_lock(). But if the DMA is locked by the SCSI code and
   * there are other drivers waiting for the chip, we do not issue the
   * command immediately but wait on 'falcon_fairness_queue'. We will be
   * waked up when the DMA is unlocked by some SCSI interrupt. After that
   * we try to get the lock again.
   * But we must be prepared that more than one instance of
   * falcon_get_lock() is waiting on the fairness queue. They should not
   * try all at once to call stdma_lock(), one is enough! For that, the
   * first one sets 'falcon_trying_lock', others that see that variable
   * set wait on the queue 'falcon_try_wait'.
   * Complicated, complicated.... Sigh...
   */
c28bda251   Roman Zippel   m68k: Reformat th...
538
  static void falcon_get_lock(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
539
540
  {
  	unsigned long flags;
c28bda251   Roman Zippel   m68k: Reformat th...
541
542
  	if (IS_A_TT())
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
543
544
  
  	local_irq_save(flags);
fb810d121   Michael Schmitz   m68k: Atari SCSI ...
545
  	while (!in_irq() && falcon_got_lock && stdma_others_waiting())
c28bda251   Roman Zippel   m68k: Reformat th...
546
  		sleep_on(&falcon_fairness_wait);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
547
548
  
  	while (!falcon_got_lock) {
fb810d121   Michael Schmitz   m68k: Atari SCSI ...
549
  		if (in_irq())
c28bda251   Roman Zippel   m68k: Reformat th...
550
  			panic("Falcon SCSI hasn't ST-DMA lock in interrupt");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
551
552
553
554
555
  		if (!falcon_trying_lock) {
  			falcon_trying_lock = 1;
  			stdma_lock(scsi_falcon_intr, NULL);
  			falcon_got_lock = 1;
  			falcon_trying_lock = 0;
c28bda251   Roman Zippel   m68k: Reformat th...
556
557
558
  			wake_up(&falcon_try_wait);
  		} else {
  			sleep_on(&falcon_try_wait);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
559
  		}
c28bda251   Roman Zippel   m68k: Reformat th...
560
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
561
562
563
564
565
566
  
  	local_irq_restore(flags);
  	if (!falcon_got_lock)
  		panic("Falcon SCSI: someone stole the lock :-(
  ");
  }
95fde7a83   Michael Schmitz   m68k: section mis...
567
  int __init atari_scsi_detect(struct scsi_host_template *host)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
568
569
570
571
572
573
574
  {
  	static int called = 0;
  	struct Scsi_Host *instance;
  
  	if (!MACH_IS_ATARI ||
  	    (!ATARIHW_PRESENT(ST_SCSI) && !ATARIHW_PRESENT(TT_SCSI)) ||
  	    called)
c28bda251   Roman Zippel   m68k: Reformat th...
575
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
  
  	host->proc_name = "Atari";
  
  	atari_scsi_reg_read  = IS_A_TT() ? atari_scsi_tt_reg_read :
  					   atari_scsi_falcon_reg_read;
  	atari_scsi_reg_write = IS_A_TT() ? atari_scsi_tt_reg_write :
  					   atari_scsi_falcon_reg_write;
  
  	/* setup variables */
  	host->can_queue =
  		(setup_can_queue > 0) ? setup_can_queue :
  		IS_A_TT() ? ATARI_TT_CAN_QUEUE : ATARI_FALCON_CAN_QUEUE;
  	host->cmd_per_lun =
  		(setup_cmd_per_lun > 0) ? setup_cmd_per_lun :
  		IS_A_TT() ? ATARI_TT_CMD_PER_LUN : ATARI_FALCON_CMD_PER_LUN;
  	/* Force sg_tablesize to 0 on a Falcon! */
  	host->sg_tablesize =
  		!IS_A_TT() ? ATARI_FALCON_SG_TABLESIZE :
  		(setup_sg_tablesize >= 0) ? setup_sg_tablesize : ATARI_TT_SG_TABLESIZE;
  
  	if (setup_hostid >= 0)
  		host->this_id = setup_hostid;
  	else {
  		/* use 7 as default */
  		host->this_id = 7;
  		/* Test if a host id is set in the NVRam */
  		if (ATARIHW_PRESENT(TT_CLK) && nvram_check_checksum()) {
  			unsigned char b = nvram_read_byte( 14 );
  			/* Arbitration enabled? (for TOS) If yes, use configured host ID */
  			if (b & 0x80)
  				host->this_id = b & 7;
  		}
  	}
  
  #ifdef SUPPORT_TAGS
  	if (setup_use_tagged_queuing < 0)
  		setup_use_tagged_queuing = DEFAULT_USE_TAGGED_QUEUING;
  #endif
  #ifdef REAL_DMA
  	/* If running on a Falcon and if there's TT-Ram (i.e., more than one
  	 * memory block, since there's always ST-Ram in a Falcon), then allocate a
  	 * STRAM_BUFFER_SIZE byte dribble buffer for transfers from/to alternative
  	 * Ram.
  	 */
  	if (MACH_IS_ATARI && ATARIHW_PRESENT(ST_SCSI) &&
  	    !ATARIHW_PRESENT(EXTD_DMA) && m68k_num_memory > 1) {
  		atari_dma_buffer = atari_stram_alloc(STRAM_BUFFER_SIZE, "SCSI");
  		if (!atari_dma_buffer) {
c28bda251   Roman Zippel   m68k: Reformat th...
624
625
626
627
  			printk(KERN_ERR "atari_scsi_detect: can't allocate ST-RAM "
  					"double buffer
  ");
  			return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
628
  		}
c28bda251   Roman Zippel   m68k: Reformat th...
629
  		atari_dma_phys_buffer = virt_to_phys(atari_dma_buffer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
630
631
632
  		atari_dma_orig_addr = 0;
  	}
  #endif
c28bda251   Roman Zippel   m68k: Reformat th...
633
634
  	instance = scsi_register(host, sizeof(struct NCR5380_hostdata));
  	if (instance == NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
635
636
637
638
639
  		atari_stram_free(atari_dma_buffer);
  		atari_dma_buffer = 0;
  		return 0;
  	}
  	atari_scsi_host = instance;
c28bda251   Roman Zippel   m68k: Reformat th...
640
641
642
643
644
645
  	/*
  	 * Set irq to 0, to avoid that the mid-level code disables our interrupt
  	 * during queue_command calls. This is completely unnecessary, and even
  	 * worse causes bad problems on the Falcon, where the int is shared with
  	 * IDE and floppy!
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
646
647
648
649
650
         instance->irq = 0;
  
  #ifdef CONFIG_ATARI_SCSI_RESET_BOOT
  	atari_scsi_reset_boot();
  #endif
c28bda251   Roman Zippel   m68k: Reformat th...
651
  	NCR5380_init(instance, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
652
653
654
655
656
657
658
  
  	if (IS_A_TT()) {
  
  		/* This int is actually "pseudo-slow", i.e. it acts like a slow
  		 * interrupt after having cleared the pending flag for the DMA
  		 * interrupt. */
  		if (request_irq(IRQ_TT_MFP_SCSI, scsi_tt_intr, IRQ_TYPE_SLOW,
1e6416643   Jeff Garzik   [SCSI] NCR5380: F...
659
  				 "SCSI NCR5380", instance)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
660
661
662
663
664
665
666
667
668
669
  			printk(KERN_ERR "atari_scsi_detect: cannot allocate irq %d, aborting",IRQ_TT_MFP_SCSI);
  			scsi_unregister(atari_scsi_host);
  			atari_stram_free(atari_dma_buffer);
  			atari_dma_buffer = 0;
  			return 0;
  		}
  		tt_mfp.active_edge |= 0x80;		/* SCSI int on L->H */
  #ifdef REAL_DMA
  		tt_scsi_dma.dma_ctrl = 0;
  		atari_dma_residual = 0;
29c8a2467   Adrian Bunk   m68k: Remove the ...
670
671
  
  		if (MACH_IS_MEDUSA) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
672
673
674
675
676
677
678
679
680
681
682
683
684
  			/* While the read overruns (described by Drew Eckhardt in
  			 * NCR5380.c) never happened on TTs, they do in fact on the Medusa
  			 * (This was the cause why SCSI didn't work right for so long
  			 * there.) Since handling the overruns slows down a bit, I turned
  			 * the #ifdef's into a runtime condition.
  			 *
  			 * In principle it should be sufficient to do max. 1 byte with
  			 * PIO, but there is another problem on the Medusa with the DMA
  			 * rest data register. So 'atari_read_overruns' is currently set
  			 * to 4 to avoid having transfers that aren't a multiple of 4. If
  			 * the rest data bug is fixed, this can be lowered to 1.
  			 */
  			atari_read_overruns = 4;
c28bda251   Roman Zippel   m68k: Reformat th...
685
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
686
  #endif /*REAL_DMA*/
c28bda251   Roman Zippel   m68k: Reformat th...
687
  	} else { /* ! IS_A_TT */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
  		/* Nothing to do for the interrupt: the ST-DMA is initialized
  		 * already by atari_init_INTS()
  		 */
  
  #ifdef REAL_DMA
  		atari_dma_residual = 0;
  		atari_dma_active = 0;
  		atari_dma_stram_mask = (ATARIHW_PRESENT(EXTD_DMA) ? 0x00000000
  					: 0xff000000);
  #endif
  	}
  
  	printk(KERN_INFO "scsi%d: options CAN_QUEUE=%d CMD_PER_LUN=%d SCAT-GAT=%d "
  #ifdef SUPPORT_TAGS
  			"TAGGED-QUEUING=%s "
  #endif
  			"HOSTID=%d",
  			instance->host_no, instance->hostt->can_queue,
  			instance->hostt->cmd_per_lun,
  			instance->hostt->sg_tablesize,
  #ifdef SUPPORT_TAGS
  			setup_use_tagged_queuing ? "yes" : "no",
  #endif
  			instance->hostt->this_id );
c28bda251   Roman Zippel   m68k: Reformat th...
712
713
714
  	NCR5380_print_options(instance);
  	printk("
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
715
716
  
  	called = 1;
c28bda251   Roman Zippel   m68k: Reformat th...
717
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
718
  }
c28bda251   Roman Zippel   m68k: Reformat th...
719
  int atari_scsi_release(struct Scsi_Host *sh)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
720
721
  {
  	if (IS_A_TT())
1e6416643   Jeff Garzik   [SCSI] NCR5380: F...
722
  		free_irq(IRQ_TT_MFP_SCSI, sh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
723
  	if (atari_dma_buffer)
c28bda251   Roman Zippel   m68k: Reformat th...
724
  		atari_stram_free(atari_dma_buffer);
6323e4fe7   Geert Uytterhoeven   [SCSI] atari_NCR5...
725
  	NCR5380_exit(sh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
726
727
  	return 1;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
728
729
730
731
732
733
734
735
  
  void __init atari_scsi_setup(char *str, int *ints)
  {
  	/* Format of atascsi parameter is:
  	 *   atascsi=<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
  	 * Defaults depend on TT or Falcon, hostid determined at run time.
  	 * Negative values mean don't change.
  	 */
c28bda251   Roman Zippel   m68k: Reformat th...
736

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
737
  	if (ints[0] < 1) {
c28bda251   Roman Zippel   m68k: Reformat th...
738
739
  		printk("atari_scsi_setup: no arguments!
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
  		return;
  	}
  
  	if (ints[0] >= 1) {
  		if (ints[1] > 0)
  			/* no limits on this, just > 0 */
  			setup_can_queue = ints[1];
  	}
  	if (ints[0] >= 2) {
  		if (ints[2] > 0)
  			setup_cmd_per_lun = ints[2];
  	}
  	if (ints[0] >= 3) {
  		if (ints[3] >= 0) {
  			setup_sg_tablesize = ints[3];
  			/* Must be <= SG_ALL (255) */
  			if (setup_sg_tablesize > SG_ALL)
  				setup_sg_tablesize = SG_ALL;
  		}
  	}
  	if (ints[0] >= 4) {
  		/* Must be between 0 and 7 */
  		if (ints[4] >= 0 && ints[4] <= 7)
  			setup_hostid = ints[4];
  		else if (ints[4] > 7)
c28bda251   Roman Zippel   m68k: Reformat th...
765
766
  			printk("atari_scsi_setup: invalid host ID %d !
  ", ints[4]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
767
768
769
770
771
772
773
774
775
776
777
  	}
  #ifdef SUPPORT_TAGS
  	if (ints[0] >= 5) {
  		if (ints[5] >= 0)
  			setup_use_tagged_queuing = !!ints[5];
  	}
  #endif
  }
  
  int atari_scsi_bus_reset(Scsi_Cmnd *cmd)
  {
c28bda251   Roman Zippel   m68k: Reformat th...
778
  	int rv;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
779
780
781
782
783
784
785
786
787
  	struct NCR5380_hostdata *hostdata =
  		(struct NCR5380_hostdata *)cmd->device->host->hostdata;
  
  	/* For doing the reset, SCSI interrupts must be disabled first,
  	 * since the 5380 raises its IRQ line while _RST is active and we
  	 * can't disable interrupts completely, since we need the timer.
  	 */
  	/* And abort a maybe active DMA transfer */
  	if (IS_A_TT()) {
c28bda251   Roman Zippel   m68k: Reformat th...
788
  		atari_turnoff_irq(IRQ_TT_MFP_SCSI);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
789
790
791
  #ifdef REAL_DMA
  		tt_scsi_dma.dma_ctrl = 0;
  #endif /* REAL_DMA */
c28bda251   Roman Zippel   m68k: Reformat th...
792
793
  	} else {
  		atari_turnoff_irq(IRQ_MFP_FSCSI);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
794
795
796
797
798
799
800
801
802
803
804
  #ifdef REAL_DMA
  		st_dma.dma_mode_status = 0x90;
  		atari_dma_active = 0;
  		atari_dma_orig_addr = NULL;
  #endif /* REAL_DMA */
  	}
  
  	rv = NCR5380_bus_reset(cmd);
  
  	/* Re-enable ints */
  	if (IS_A_TT()) {
c28bda251   Roman Zippel   m68k: Reformat th...
805
806
807
  		atari_turnon_irq(IRQ_TT_MFP_SCSI);
  	} else {
  		atari_turnon_irq(IRQ_MFP_FSCSI);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
808
809
810
  	}
  	if ((rv & SCSI_RESET_ACTION) == SCSI_RESET_SUCCESS)
  		falcon_release_lock_if_possible(hostdata);
c28bda251   Roman Zippel   m68k: Reformat th...
811
  	return rv;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
812
  }
c28bda251   Roman Zippel   m68k: Reformat th...
813

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
814
815
816
817
  #ifdef CONFIG_ATARI_SCSI_RESET_BOOT
  static void __init atari_scsi_reset_boot(void)
  {
  	unsigned long end;
c28bda251   Roman Zippel   m68k: Reformat th...
818

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
819
820
821
822
  	/*
  	 * Do a SCSI reset to clean up the bus during initialization. No messing
  	 * with the queues, interrupts, or locks necessary here.
  	 */
c28bda251   Roman Zippel   m68k: Reformat th...
823
  	printk("Atari SCSI: resetting the SCSI bus...");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
824
825
  
  	/* get in phase */
c28bda251   Roman Zippel   m68k: Reformat th...
826
827
  	NCR5380_write(TARGET_COMMAND_REG,
  		      PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG)));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
828
829
  
  	/* assert RST */
c28bda251   Roman Zippel   m68k: Reformat th...
830
  	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
831
  	/* The min. reset hold time is 25us, so 40us should be enough */
c28bda251   Roman Zippel   m68k: Reformat th...
832
  	udelay(50);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
833
  	/* reset RST and interrupt */
c28bda251   Roman Zippel   m68k: Reformat th...
834
835
  	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
  	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
836
837
838
839
  
  	end = jiffies + AFTER_RESET_DELAY;
  	while (time_before(jiffies, end))
  		barrier();
c28bda251   Roman Zippel   m68k: Reformat th...
840
841
  	printk(" done
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
842
843
  }
  #endif
c28bda251   Roman Zippel   m68k: Reformat th...
844
  const char *atari_scsi_info(struct Scsi_Host *host)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
845
846
847
848
849
850
851
852
  {
  	/* atari_scsi_detect() is verbose enough... */
  	static const char string[] = "Atari native SCSI";
  	return string;
  }
  
  
  #if defined(REAL_DMA)
c28bda251   Roman Zippel   m68k: Reformat th...
853
854
  unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance, void *data,
  				   unsigned long count, int dir)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
855
  {
c28bda251   Roman Zippel   m68k: Reformat th...
856
  	unsigned long addr = virt_to_phys(data);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
857
858
859
860
861
862
863
864
865
866
867
868
  
  	DMA_PRINTK("scsi%d: setting up dma, data = %p, phys = %lx, count = %ld, "
  		   "dir = %d
  ", instance->host_no, data, addr, count, dir);
  
  	if (!IS_A_TT() && !STRAM_ADDR(addr)) {
  		/* If we have a non-DMAable address on a Falcon, use the dribble
  		 * buffer; 'orig_addr' != 0 in the read case tells the interrupt
  		 * handler to copy data from the dribble buffer to the originally
  		 * wanted address.
  		 */
  		if (dir)
c28bda251   Roman Zippel   m68k: Reformat th...
869
  			memcpy(atari_dma_buffer, data, count);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
870
871
872
873
  		else
  			atari_dma_orig_addr = data;
  		addr = atari_dma_phys_buffer;
  	}
c28bda251   Roman Zippel   m68k: Reformat th...
874

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
875
  	atari_dma_startaddr = addr;	/* Needed for calculating residual later. */
c28bda251   Roman Zippel   m68k: Reformat th...
876

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
877
878
879
880
881
  	/* Cache cleanup stuff: On writes, push any dirty cache out before sending
  	 * it to the peripheral. (Must be done before DMA setup, since at least
  	 * the ST-DMA begins to fill internal buffers right after setup. For
  	 * reads, invalidate any cache, may be altered after DMA without CPU
  	 * knowledge.
c28bda251   Roman Zippel   m68k: Reformat th...
882
  	 *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
883
884
885
  	 * ++roman: For the Medusa, there's no need at all for that cache stuff,
  	 * because the hardware does bus snooping (fine!).
  	 */
c28bda251   Roman Zippel   m68k: Reformat th...
886
  	dma_cache_maintenance(addr, count, dir);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
887
888
889
890
891
892
893
  
  	if (count == 0)
  		printk(KERN_NOTICE "SCSI warning: DMA programmed for 0 bytes !
  ");
  
  	if (IS_A_TT()) {
  		tt_scsi_dma.dma_ctrl = dir;
c28bda251   Roman Zippel   m68k: Reformat th...
894
895
  		SCSI_DMA_WRITE_P(dma_addr, addr);
  		SCSI_DMA_WRITE_P(dma_cnt, count);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
896
  		tt_scsi_dma.dma_ctrl = dir | 2;
c28bda251   Roman Zippel   m68k: Reformat th...
897
  	} else { /* ! IS_A_TT */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
898
  		/* set address */
c28bda251   Roman Zippel   m68k: Reformat th...
899
  		SCSI_DMA_SETADR(addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
  
  		/* toggle direction bit to clear FIFO and set DMA direction */
  		dir <<= 8;
  		st_dma.dma_mode_status = 0x90 | dir;
  		st_dma.dma_mode_status = 0x90 | (dir ^ 0x100);
  		st_dma.dma_mode_status = 0x90 | dir;
  		udelay(40);
  		/* On writes, round up the transfer length to the next multiple of 512
  		 * (see also comment at atari_dma_xfer_len()). */
  		st_dma.fdc_acces_seccount = (count + (dir ? 511 : 0)) >> 9;
  		udelay(40);
  		st_dma.dma_mode_status = 0x10 | dir;
  		udelay(40);
  		/* need not restore value of dir, only boolean value is tested */
  		atari_dma_active = 1;
  	}
c28bda251   Roman Zippel   m68k: Reformat th...
916
  	return count;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
917
  }
c28bda251   Roman Zippel   m68k: Reformat th...
918
  static long atari_scsi_dma_residual(struct Scsi_Host *instance)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
919
  {
c28bda251   Roman Zippel   m68k: Reformat th...
920
  	return atari_dma_residual;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
921
922
923
924
925
926
  }
  
  
  #define	CMD_SURELY_BLOCK_MODE	0
  #define	CMD_SURELY_BYTE_MODE	1
  #define	CMD_MODE_UNKNOWN		2
c28bda251   Roman Zippel   m68k: Reformat th...
927
  static int falcon_classify_cmd(Scsi_Cmnd *cmd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
928
929
  {
  	unsigned char opcode = cmd->cmnd[0];
c28bda251   Roman Zippel   m68k: Reformat th...
930

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
931
  	if (opcode == READ_DEFECT_DATA || opcode == READ_LONG ||
c28bda251   Roman Zippel   m68k: Reformat th...
932
933
  	    opcode == READ_BUFFER)
  		return CMD_SURELY_BYTE_MODE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
934
935
936
937
938
939
940
  	else if (opcode == READ_6 || opcode == READ_10 ||
  		 opcode == 0xa8 /* READ_12 */ || opcode == READ_REVERSE ||
  		 opcode == RECOVER_BUFFERED_DATA) {
  		/* In case of a sequential-access target (tape), special care is
  		 * needed here: The transfer is block-mode only if the 'fixed' bit is
  		 * set! */
  		if (cmd->device->type == TYPE_TAPE && !(cmd->cmnd[1] & 1))
c28bda251   Roman Zippel   m68k: Reformat th...
941
  			return CMD_SURELY_BYTE_MODE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
942
  		else
c28bda251   Roman Zippel   m68k: Reformat th...
943
944
945
  			return CMD_SURELY_BLOCK_MODE;
  	} else
  		return CMD_MODE_UNKNOWN;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
946
947
948
949
950
951
952
953
954
955
956
  }
  
  
  /* This function calculates the number of bytes that can be transferred via
   * DMA. On the TT, this is arbitrary, but on the Falcon we have to use the
   * ST-DMA chip. There are only multiples of 512 bytes possible and max.
   * 255*512 bytes :-( This means also, that defining READ_OVERRUNS is not
   * possible on the Falcon, since that would require to program the DMA for
   * n*512 - atari_read_overrun bytes. But it seems that the Falcon doesn't have
   * the overrun problem, so this question is academic :-)
   */
c28bda251   Roman Zippel   m68k: Reformat th...
957
958
  static unsigned long atari_dma_xfer_len(unsigned long wanted_len,
  					Scsi_Cmnd *cmd, int write_flag)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
959
960
  {
  	unsigned long	possible_len, limit;
29c8a2467   Adrian Bunk   m68k: Remove the ...
961

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
962
963
  	if (IS_A_TT())
  		/* TT SCSI DMA can transfer arbitrary #bytes */
c28bda251   Roman Zippel   m68k: Reformat th...
964
  		return wanted_len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
  
  	/* ST DMA chip is stupid -- only multiples of 512 bytes! (and max.
  	 * 255*512 bytes, but this should be enough)
  	 *
  	 * ++roman: Aaargl! Another Falcon-SCSI problem... There are some commands
  	 * that return a number of bytes which cannot be known beforehand. In this
  	 * case, the given transfer length is an "allocation length". Now it
  	 * can happen that this allocation length is a multiple of 512 bytes and
  	 * the DMA is used. But if not n*512 bytes really arrive, some input data
  	 * will be lost in the ST-DMA's FIFO :-( Thus, we have to distinguish
  	 * between commands that do block transfers and those that do byte
  	 * transfers. But this isn't easy... there are lots of vendor specific
  	 * commands, and the user can issue any command via the
  	 * SCSI_IOCTL_SEND_COMMAND.
  	 *
  	 * The solution: We classify SCSI commands in 1) surely block-mode cmd.s,
  	 * 2) surely byte-mode cmd.s and 3) cmd.s with unknown mode. In case 1)
  	 * and 3), the thing to do is obvious: allow any number of blocks via DMA
  	 * or none. In case 2), we apply some heuristic: Byte mode is assumed if
  	 * the transfer (allocation) length is < 1024, hoping that no cmd. not
  	 * explicitly known as byte mode have such big allocation lengths...
  	 * BTW, all the discussion above applies only to reads. DMA writes are
  	 * unproblematic anyways, since the targets aborts the transfer after
  	 * receiving a sufficient number of bytes.
  	 *
  	 * Another point: If the transfer is from/to an non-ST-RAM address, we
  	 * use the dribble buffer and thus can do only STRAM_BUFFER_SIZE bytes.
  	 */
  
  	if (write_flag) {
  		/* Write operation can always use the DMA, but the transfer size must
  		 * be rounded up to the next multiple of 512 (atari_dma_setup() does
  		 * this).
  		 */
  		possible_len = wanted_len;
c28bda251   Roman Zippel   m68k: Reformat th...
1000
  	} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1001
1002
1003
1004
1005
1006
1007
1008
1009
  		/* Read operations: if the wanted transfer length is not a multiple of
  		 * 512, we cannot use DMA, since the ST-DMA cannot split transfers
  		 * (no interrupt on DMA finished!)
  		 */
  		if (wanted_len & 0x1ff)
  			possible_len = 0;
  		else {
  			/* Now classify the command (see above) and decide whether it is
  			 * allowed to do DMA at all */
c28bda251   Roman Zippel   m68k: Reformat th...
1010
1011
  			switch (falcon_classify_cmd(cmd)) {
  			case CMD_SURELY_BLOCK_MODE:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1012
1013
  				possible_len = wanted_len;
  				break;
c28bda251   Roman Zippel   m68k: Reformat th...
1014
  			case CMD_SURELY_BYTE_MODE:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1015
1016
  				possible_len = 0; /* DMA prohibited */
  				break;
c28bda251   Roman Zippel   m68k: Reformat th...
1017
1018
  			case CMD_MODE_UNKNOWN:
  			default:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1019
1020
1021
1022
1023
1024
1025
  				/* For unknown commands assume block transfers if the transfer
  				 * size/allocation length is >= 1024 */
  				possible_len = (wanted_len < 1024) ? 0 : wanted_len;
  				break;
  			}
  		}
  	}
c28bda251   Roman Zippel   m68k: Reformat th...
1026

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1027
  	/* Last step: apply the hard limit on DMA transfers */
c28bda251   Roman Zippel   m68k: Reformat th...
1028
  	limit = (atari_dma_buffer && !STRAM_ADDR(virt_to_phys(cmd->SCp.ptr))) ?
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1029
1030
1031
1032
1033
1034
1035
1036
  		    STRAM_BUFFER_SIZE : 255*512;
  	if (possible_len > limit)
  		possible_len = limit;
  
  	if (possible_len != wanted_len)
  		DMA_PRINTK("Sorry, must cut DMA transfer size to %ld bytes "
  			   "instead of %ld
  ", possible_len, wanted_len);
c28bda251   Roman Zippel   m68k: Reformat th...
1037
  	return possible_len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
  }
  
  
  #endif	/* REAL_DMA */
  
  
  /* NCR5380 register access functions
   *
   * There are separate functions for TT and Falcon, because the access
   * methods are quite different. The calling macros NCR5380_read and
   * NCR5380_write call these functions via function pointers.
   */
c28bda251   Roman Zippel   m68k: Reformat th...
1050
  static unsigned char atari_scsi_tt_reg_read(unsigned char reg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1051
  {
c28bda251   Roman Zippel   m68k: Reformat th...
1052
  	return tt_scsi_regp[reg * 2];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1053
  }
c28bda251   Roman Zippel   m68k: Reformat th...
1054
  static void atari_scsi_tt_reg_write(unsigned char reg, unsigned char value)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1055
1056
1057
  {
  	tt_scsi_regp[reg * 2] = value;
  }
c28bda251   Roman Zippel   m68k: Reformat th...
1058
  static unsigned char atari_scsi_falcon_reg_read(unsigned char reg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1059
1060
  {
  	dma_wd.dma_mode_status= (u_short)(0x88 + reg);
c28bda251   Roman Zippel   m68k: Reformat th...
1061
  	return (u_char)dma_wd.fdc_acces_seccount;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1062
  }
c28bda251   Roman Zippel   m68k: Reformat th...
1063
  static void atari_scsi_falcon_reg_write(unsigned char reg, unsigned char value)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1064
1065
1066
1067
1068
1069
1070
  {
  	dma_wd.dma_mode_status = (u_short)(0x88 + reg);
  	dma_wd.fdc_acces_seccount = (u_short)value;
  }
  
  
  #include "atari_NCR5380.c"
d0be4a7d2   Christoph Hellwig   [SCSI] remove Scs...
1071
  static struct scsi_host_template driver_template = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
  	.proc_info		= atari_scsi_proc_info,
  	.name			= "Atari native SCSI",
  	.detect			= atari_scsi_detect,
  	.release		= atari_scsi_release,
  	.info			= atari_scsi_info,
  	.queuecommand		= atari_scsi_queue_command,
  	.eh_abort_handler	= atari_scsi_abort,
  	.eh_bus_reset_handler	= atari_scsi_bus_reset,
  	.can_queue		= 0, /* initialized at run-time */
  	.this_id		= 0, /* initialized at run-time */
  	.sg_tablesize		= 0, /* initialized at run-time */
  	.cmd_per_lun		= 0, /* initialized at run-time */
  	.use_clustering		= DISABLE_CLUSTERING
  };
  
  
  #include "scsi_module.c"
  
  MODULE_LICENSE("GPL");