/*
 * atari_scsi.h -- Header file for the Atari native SCSI driver
 *
 * Copyright 1994 Roman Hodek
 *   EMail: rnhodek@cip.informatik.uni-erlangen.de (Internet)
 *      or: Roman_Hodek@n.maus.de (MausNet, NO mail > 16 KB!)
 *
 * (Loosely based on the work of Robert De Vries' team)
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file README.legal in the main directory of this archive
 * for more details.
 *
 */


#ifndef ATARI_SCSI_H
#define ATARI_SCSI_H

/* IMPORTANT NOTE:
 * ===============
 *
 * The NCR5380 is said to have a nasty characteristic when
 * re-programming the DMA while a command is ongoing (see comment in
 * atari_NCR5380.c in function NCR5380_transfer_dma()). The author of
 * the generic 5380 driver, Drew Eckhardt, provided a trick to
 * compensate that. It is activated by defining the symbol
 * 'READ_OVERRUNS'. The problem in short: If the end of DMA doesn't
 * happen at the same time as a SCSI phase change, the 5380 may loose
 * one byte. This is compensated by programming the DMA for 2 bytes
 * less than wanted and transfer these last two bytes by hand. This
 * also implies that the READ_OVERRUNS trick cannot work on the
 * Falcon, since the ST-DMA can only process 512 byte blocks and hence
 * not two bytes less. This in turns implies that no scatter-gather
 * operations are possible, which causes a drastic loss of performance :-(
 *
 * While testing the SCSI driver, I wondered that such overruns
 * never occured. After the driver worked reliably, I tried without
 * READ_OVERRUNS and that works fine, too. But -- I can't be sure that
 * this is the case with all machines. Maybe may TT is a exception and
 * has a (maybe newer) 5380 that doesn't have the problem. So I
 * decided to make the overrun fix user-definable by the symbol
 * 'I_HAVE_OVERRUNS', defined below. It can have the values 0 to 3:
 *
 *   - 0:
 *     This means, you also never have seen overruns like me and have no
 *     problems with read faults or the like. The READ_OVERRUNS trick
 *     is turned off (i.e. the whole transfer is done by DMA, no two
 *     polled bytes). If this value is choosen, scatter-gather is
 *     enabled (on both TT and Falcon).
 *
 *   - 1:
 *     You don't know if you have overruns or not. For TT's, the
 *     READ_OVERRUNS trick is used and scatter-gather remains
 *     enabled. If overruns should occur, you get kernel messages or
 *     other effects (see below). THIS MODE MUST NOT BE SELECTED ON
 *     THE FALCON! Defining READ_OVERRUNS is not possible there.
 *        Every time a overrun really occurs you receive a kernel
 *	   message: "overrun handled (dont't worry)". If you see this
 *	   message, you have overruns for sure and it'd be better to
 *	   define I_HAVE_OVERRUNS to 2. Another symptom of read overruns
 *	   may be suprious -- but not explicitly reported -- read faults,
 *	   causing programs of all sorts to get SIGSEGV's, bad kernel
 *	   traps and more abnormalities.  Characteristic is that this
 *	   doesn`t happen always on the same binaries.
 *        If you see such symptoms and have to turn on the
 *     overrun trick and the symptoms go away by that, please report
 *     this to
 *        rnhodek@cip.informatik.uni-erlangen.de
 *     or
 *        Roman_Hodek@n.maus.de
 *     If many people have such overruns, the overrun trick may become
 *     the default.
 *
 *   - 2:
 *     You have a TT and surely know that you have overruns and need
 *     the overrun trick for proper operation. THIS MODE MUST NOT BE
 *     SELECTED ON THE FALCON!
 *
 *   - 3:
 *     This mode should be selected by Falcon users that have
 *     overruns. Overruns are not handled (this is not possible on the
 *     Falcon), but their deeper reason is eleminated by disabling
 *     scatter-gather operations. This means a performance loss of up
 *     to 90% (sorry!).
 *
 *                                                               Roman
 *
 */

/* Select here whether you have overruns:
 *  0 = no (TT and Falcon)
 *  1 = don't know (TT)
 *  2 = yes (TT)
 *  3 = yes (Falcon)
 */
#define	I_HAVE_OVERRUNS	0

#ifndef ASM
int atari_scsi_abort (Scsi_Cmnd *, int);
int atari_scsi_detect (int);
const char *atari_scsi_info (void);
int atari_scsi_queue_command (Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
int atari_scsi_reset (Scsi_Cmnd *);

/* The values for CMD_PER_LUN and CAN_QUEUE are somehow arbitrary. Higher
 * values may work, too; try it! (but it costs memory!) */

#ifndef CMD_PER_LUN
#define CMD_PER_LUN 16
#endif

#ifndef CAN_QUEUE
#define CAN_QUEUE 16
#endif

#ifndef I_HAVE_OVERRUNS
#error I_HAVE_OVERRUNS is not defined. See comment at start of atari_scsi.h
#endif


#ifdef HOSTS_C

#if I_HAVE_OVERRUNS > 2

#define ATARI_SCSI {							\
  "Atari native SCSI",							\
  atari_scsi_detect,							\
  atari_scsi_info,								\
  /* command */ NULL,							\
  atari_scsi_queue_command,						\
  atari_scsi_abort,								\
  atari_scsi_reset,								\
  /* slave_attach */ NULL,						\
  /* bios_param */ NULL,						\
  /* can queue */ 			CAN_QUEUE,			\
  /* host_id */				7,					\
  /* scatter gather */ 		SG_NONE,			\
  /* cmd per lun */ 		CMD_PER_LUN,		\
  /* present */ 			0,					\
  /* unchecked ISA DMA */	0 }

#else

#define ATARI_SCSI {							\
  "Atari native SCSI",							\
  atari_scsi_detect,							\
  atari_scsi_info,								\
  /* command */ NULL,							\
  atari_scsi_queue_command,						\
  atari_scsi_abort,								\
  atari_scsi_reset,								\
  /* slave_attach */ NULL,						\
  /* bios_param */ NULL,						\
  /* can queue */ 			CAN_QUEUE,			\
  /* host_id */				7,					\
  /* scatter gather */ 		SG_ALL,				\
  /* cmd per lun */ 		CMD_PER_LUN,		\
  /* present */ 			0,					\
  /* unchecked ISA DMA */	0 }

#endif

#else

#define NCR5380_implementation_fields 	   /* none */
#define NCR5380_local_declare() int __none /* bad design */
#define NCR5380_setup(instance) __none = 0 /* to avoid warning */

#define NCR5380_read(reg)		  atari_scsi_reg_read( reg )
#define NCR5380_write(reg, value) atari_scsi_reg_write( reg, value )

#define NCR5380_intr atari_scsi_intr
#define NCR5380_queue_command atari_scsi_queue_command
#define NCR5380_abort atari_scsi_abort
/* #define NCR5380_reset atari_scsi_reset */
#define NCR5380_dma_read_setup(inst,d,c) atari_scsi_dma_setup (inst, d, c, 0)
#define NCR5380_dma_write_setup(inst,d,c) atari_scsi_dma_setup (inst, d, c, 1)
#define NCR5380_dma_residual(inst) atari_scsi_dma_residual( inst )
/* #define NCR5380_pread(instance, d, c) atari_scsi_pread (instance, d, c) */
/* #define NCR5380_pwrite(instance, d, c) atari_scsi_pwrite (instance, d, c) */
#define	NCR5380_dma_xfer_len(i,cmd) atari_dma_xfer_len(cmd->SCp.this_residual)

#endif /* else def HOSTS_C */
#endif /* ndef ASM */
#endif /* ATARI_SCSI_H */


