1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * wd33c93.h - Linux device driver definitions for the 4*4882a593Smuzhiyun * Commodore Amiga A2091/590 SCSI controller card 5*4882a593Smuzhiyun * 6*4882a593Smuzhiyun * IMPORTANT: This file is for version 1.25 - 09/Jul/1997 7*4882a593Smuzhiyun * 8*4882a593Smuzhiyun * Copyright (c) 1996 John Shifflett, GeoLog Consulting 9*4882a593Smuzhiyun * john@geolog.com 10*4882a593Smuzhiyun * jshiffle@netcom.com 11*4882a593Smuzhiyun */ 12*4882a593Smuzhiyun #ifndef WD33C93_H 13*4882a593Smuzhiyun #define WD33C93_H 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun #define PROC_INTERFACE /* add code for /proc/scsi/wd33c93/xxx interface */ 17*4882a593Smuzhiyun #ifdef PROC_INTERFACE 18*4882a593Smuzhiyun #define PROC_STATISTICS /* add code for keeping various real time stats */ 19*4882a593Smuzhiyun #endif 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun #define SYNC_DEBUG /* extra info on sync negotiation printed */ 22*4882a593Smuzhiyun #define DEBUGGING_ON /* enable command-line debugging bitmask */ 23*4882a593Smuzhiyun #define DEBUG_DEFAULTS 0 /* default debugging bitmask */ 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun #ifdef DEBUGGING_ON 27*4882a593Smuzhiyun #define DB(f,a) if (hostdata->args & (f)) a; 28*4882a593Smuzhiyun #else 29*4882a593Smuzhiyun #define DB(f,a) 30*4882a593Smuzhiyun #endif 31*4882a593Smuzhiyun 32*4882a593Smuzhiyun #define uchar unsigned char 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun /* wd register names */ 36*4882a593Smuzhiyun #define WD_OWN_ID 0x00 37*4882a593Smuzhiyun #define WD_CONTROL 0x01 38*4882a593Smuzhiyun #define WD_TIMEOUT_PERIOD 0x02 39*4882a593Smuzhiyun #define WD_CDB_1 0x03 40*4882a593Smuzhiyun #define WD_CDB_2 0x04 41*4882a593Smuzhiyun #define WD_CDB_3 0x05 42*4882a593Smuzhiyun #define WD_CDB_4 0x06 43*4882a593Smuzhiyun #define WD_CDB_5 0x07 44*4882a593Smuzhiyun #define WD_CDB_6 0x08 45*4882a593Smuzhiyun #define WD_CDB_7 0x09 46*4882a593Smuzhiyun #define WD_CDB_8 0x0a 47*4882a593Smuzhiyun #define WD_CDB_9 0x0b 48*4882a593Smuzhiyun #define WD_CDB_10 0x0c 49*4882a593Smuzhiyun #define WD_CDB_11 0x0d 50*4882a593Smuzhiyun #define WD_CDB_12 0x0e 51*4882a593Smuzhiyun #define WD_TARGET_LUN 0x0f 52*4882a593Smuzhiyun #define WD_COMMAND_PHASE 0x10 53*4882a593Smuzhiyun #define WD_SYNCHRONOUS_TRANSFER 0x11 54*4882a593Smuzhiyun #define WD_TRANSFER_COUNT_MSB 0x12 55*4882a593Smuzhiyun #define WD_TRANSFER_COUNT 0x13 56*4882a593Smuzhiyun #define WD_TRANSFER_COUNT_LSB 0x14 57*4882a593Smuzhiyun #define WD_DESTINATION_ID 0x15 58*4882a593Smuzhiyun #define WD_SOURCE_ID 0x16 59*4882a593Smuzhiyun #define WD_SCSI_STATUS 0x17 60*4882a593Smuzhiyun #define WD_COMMAND 0x18 61*4882a593Smuzhiyun #define WD_DATA 0x19 62*4882a593Smuzhiyun #define WD_QUEUE_TAG 0x1a 63*4882a593Smuzhiyun #define WD_AUXILIARY_STATUS 0x1f 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun /* WD commands */ 66*4882a593Smuzhiyun #define WD_CMD_RESET 0x00 67*4882a593Smuzhiyun #define WD_CMD_ABORT 0x01 68*4882a593Smuzhiyun #define WD_CMD_ASSERT_ATN 0x02 69*4882a593Smuzhiyun #define WD_CMD_NEGATE_ACK 0x03 70*4882a593Smuzhiyun #define WD_CMD_DISCONNECT 0x04 71*4882a593Smuzhiyun #define WD_CMD_RESELECT 0x05 72*4882a593Smuzhiyun #define WD_CMD_SEL_ATN 0x06 73*4882a593Smuzhiyun #define WD_CMD_SEL 0x07 74*4882a593Smuzhiyun #define WD_CMD_SEL_ATN_XFER 0x08 75*4882a593Smuzhiyun #define WD_CMD_SEL_XFER 0x09 76*4882a593Smuzhiyun #define WD_CMD_RESEL_RECEIVE 0x0a 77*4882a593Smuzhiyun #define WD_CMD_RESEL_SEND 0x0b 78*4882a593Smuzhiyun #define WD_CMD_WAIT_SEL_RECEIVE 0x0c 79*4882a593Smuzhiyun #define WD_CMD_TRANS_ADDR 0x18 80*4882a593Smuzhiyun #define WD_CMD_TRANS_INFO 0x20 81*4882a593Smuzhiyun #define WD_CMD_TRANSFER_PAD 0x21 82*4882a593Smuzhiyun #define WD_CMD_SBT_MODE 0x80 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun /* ASR register */ 85*4882a593Smuzhiyun #define ASR_INT (0x80) 86*4882a593Smuzhiyun #define ASR_LCI (0x40) 87*4882a593Smuzhiyun #define ASR_BSY (0x20) 88*4882a593Smuzhiyun #define ASR_CIP (0x10) 89*4882a593Smuzhiyun #define ASR_PE (0x02) 90*4882a593Smuzhiyun #define ASR_DBR (0x01) 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun /* SCSI Bus Phases */ 93*4882a593Smuzhiyun #define PHS_DATA_OUT 0x00 94*4882a593Smuzhiyun #define PHS_DATA_IN 0x01 95*4882a593Smuzhiyun #define PHS_COMMAND 0x02 96*4882a593Smuzhiyun #define PHS_STATUS 0x03 97*4882a593Smuzhiyun #define PHS_MESS_OUT 0x06 98*4882a593Smuzhiyun #define PHS_MESS_IN 0x07 99*4882a593Smuzhiyun 100*4882a593Smuzhiyun /* Command Status Register definitions */ 101*4882a593Smuzhiyun 102*4882a593Smuzhiyun /* reset state interrupts */ 103*4882a593Smuzhiyun #define CSR_RESET 0x00 104*4882a593Smuzhiyun #define CSR_RESET_AF 0x01 105*4882a593Smuzhiyun 106*4882a593Smuzhiyun /* successful completion interrupts */ 107*4882a593Smuzhiyun #define CSR_RESELECT 0x10 108*4882a593Smuzhiyun #define CSR_SELECT 0x11 109*4882a593Smuzhiyun #define CSR_SEL_XFER_DONE 0x16 110*4882a593Smuzhiyun #define CSR_XFER_DONE 0x18 111*4882a593Smuzhiyun 112*4882a593Smuzhiyun /* paused or aborted interrupts */ 113*4882a593Smuzhiyun #define CSR_MSGIN 0x20 114*4882a593Smuzhiyun #define CSR_SDP 0x21 115*4882a593Smuzhiyun #define CSR_SEL_ABORT 0x22 116*4882a593Smuzhiyun #define CSR_RESEL_ABORT 0x25 117*4882a593Smuzhiyun #define CSR_RESEL_ABORT_AM 0x27 118*4882a593Smuzhiyun #define CSR_ABORT 0x28 119*4882a593Smuzhiyun 120*4882a593Smuzhiyun /* terminated interrupts */ 121*4882a593Smuzhiyun #define CSR_INVALID 0x40 122*4882a593Smuzhiyun #define CSR_UNEXP_DISC 0x41 123*4882a593Smuzhiyun #define CSR_TIMEOUT 0x42 124*4882a593Smuzhiyun #define CSR_PARITY 0x43 125*4882a593Smuzhiyun #define CSR_PARITY_ATN 0x44 126*4882a593Smuzhiyun #define CSR_BAD_STATUS 0x45 127*4882a593Smuzhiyun #define CSR_UNEXP 0x48 128*4882a593Smuzhiyun 129*4882a593Smuzhiyun /* service required interrupts */ 130*4882a593Smuzhiyun #define CSR_RESEL 0x80 131*4882a593Smuzhiyun #define CSR_RESEL_AM 0x81 132*4882a593Smuzhiyun #define CSR_DISC 0x85 133*4882a593Smuzhiyun #define CSR_SRV_REQ 0x88 134*4882a593Smuzhiyun 135*4882a593Smuzhiyun /* Own ID/CDB Size register */ 136*4882a593Smuzhiyun #define OWNID_EAF 0x08 137*4882a593Smuzhiyun #define OWNID_EHP 0x10 138*4882a593Smuzhiyun #define OWNID_RAF 0x20 139*4882a593Smuzhiyun #define OWNID_FS_8 0x00 140*4882a593Smuzhiyun #define OWNID_FS_12 0x40 141*4882a593Smuzhiyun #define OWNID_FS_16 0x80 142*4882a593Smuzhiyun 143*4882a593Smuzhiyun /* define these so we don't have to change a2091.c, etc. */ 144*4882a593Smuzhiyun #define WD33C93_FS_8_10 OWNID_FS_8 145*4882a593Smuzhiyun #define WD33C93_FS_12_15 OWNID_FS_12 146*4882a593Smuzhiyun #define WD33C93_FS_16_20 OWNID_FS_16 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun /* pass input-clock explicitly. accepted mhz values are 8-10,12-20 */ 149*4882a593Smuzhiyun #define WD33C93_FS_MHZ(mhz) (mhz) 150*4882a593Smuzhiyun 151*4882a593Smuzhiyun /* Control register */ 152*4882a593Smuzhiyun #define CTRL_HSP 0x01 153*4882a593Smuzhiyun #define CTRL_HA 0x02 154*4882a593Smuzhiyun #define CTRL_IDI 0x04 155*4882a593Smuzhiyun #define CTRL_EDI 0x08 156*4882a593Smuzhiyun #define CTRL_HHP 0x10 157*4882a593Smuzhiyun #define CTRL_POLLED 0x00 158*4882a593Smuzhiyun #define CTRL_BURST 0x20 159*4882a593Smuzhiyun #define CTRL_BUS 0x40 160*4882a593Smuzhiyun #define CTRL_DMA 0x80 161*4882a593Smuzhiyun 162*4882a593Smuzhiyun /* Timeout Period register */ 163*4882a593Smuzhiyun #define TIMEOUT_PERIOD_VALUE 20 /* 20 = 200 ms */ 164*4882a593Smuzhiyun 165*4882a593Smuzhiyun /* Synchronous Transfer Register */ 166*4882a593Smuzhiyun #define STR_FSS 0x80 167*4882a593Smuzhiyun 168*4882a593Smuzhiyun /* Destination ID register */ 169*4882a593Smuzhiyun #define DSTID_DPD 0x40 170*4882a593Smuzhiyun #define DATA_OUT_DIR 0 171*4882a593Smuzhiyun #define DATA_IN_DIR 1 172*4882a593Smuzhiyun #define DSTID_SCC 0x80 173*4882a593Smuzhiyun 174*4882a593Smuzhiyun /* Source ID register */ 175*4882a593Smuzhiyun #define SRCID_MASK 0x07 176*4882a593Smuzhiyun #define SRCID_SIV 0x08 177*4882a593Smuzhiyun #define SRCID_DSP 0x20 178*4882a593Smuzhiyun #define SRCID_ES 0x40 179*4882a593Smuzhiyun #define SRCID_ER 0x80 180*4882a593Smuzhiyun 181*4882a593Smuzhiyun /* This is what the 3393 chip looks like to us */ 182*4882a593Smuzhiyun typedef struct { 183*4882a593Smuzhiyun #ifdef CONFIG_WD33C93_PIO 184*4882a593Smuzhiyun unsigned int SASR; 185*4882a593Smuzhiyun unsigned int SCMD; 186*4882a593Smuzhiyun #else 187*4882a593Smuzhiyun volatile unsigned char *SASR; 188*4882a593Smuzhiyun volatile unsigned char *SCMD; 189*4882a593Smuzhiyun #endif 190*4882a593Smuzhiyun } wd33c93_regs; 191*4882a593Smuzhiyun 192*4882a593Smuzhiyun 193*4882a593Smuzhiyun typedef int (*dma_setup_t) (struct scsi_cmnd *SCpnt, int dir_in); 194*4882a593Smuzhiyun typedef void (*dma_stop_t) (struct Scsi_Host *instance, 195*4882a593Smuzhiyun struct scsi_cmnd *SCpnt, int status); 196*4882a593Smuzhiyun 197*4882a593Smuzhiyun 198*4882a593Smuzhiyun #define ILLEGAL_STATUS_BYTE 0xff 199*4882a593Smuzhiyun 200*4882a593Smuzhiyun #define DEFAULT_SX_PER 376 /* (ns) fairly safe */ 201*4882a593Smuzhiyun #define DEFAULT_SX_OFF 0 /* aka async */ 202*4882a593Smuzhiyun 203*4882a593Smuzhiyun #define OPTIMUM_SX_PER 252 /* (ns) best we can do (mult-of-4) */ 204*4882a593Smuzhiyun #define OPTIMUM_SX_OFF 12 /* size of wd3393 fifo */ 205*4882a593Smuzhiyun 206*4882a593Smuzhiyun struct sx_period { 207*4882a593Smuzhiyun unsigned int period_ns; 208*4882a593Smuzhiyun uchar reg_value; 209*4882a593Smuzhiyun }; 210*4882a593Smuzhiyun 211*4882a593Smuzhiyun /* FEF: defines for hostdata->dma_buffer_pool */ 212*4882a593Smuzhiyun 213*4882a593Smuzhiyun #define BUF_CHIP_ALLOCED 0 214*4882a593Smuzhiyun #define BUF_SCSI_ALLOCED 1 215*4882a593Smuzhiyun 216*4882a593Smuzhiyun struct WD33C93_hostdata { 217*4882a593Smuzhiyun struct Scsi_Host *next; 218*4882a593Smuzhiyun wd33c93_regs regs; 219*4882a593Smuzhiyun spinlock_t lock; 220*4882a593Smuzhiyun uchar clock_freq; 221*4882a593Smuzhiyun uchar chip; /* what kind of wd33c93? */ 222*4882a593Smuzhiyun uchar microcode; /* microcode rev */ 223*4882a593Smuzhiyun uchar dma_buffer_pool; /* FEF: buffer from chip_ram? */ 224*4882a593Smuzhiyun int dma_dir; /* data transfer dir. */ 225*4882a593Smuzhiyun dma_setup_t dma_setup; 226*4882a593Smuzhiyun dma_stop_t dma_stop; 227*4882a593Smuzhiyun unsigned int dma_xfer_mask; 228*4882a593Smuzhiyun uchar *dma_bounce_buffer; 229*4882a593Smuzhiyun unsigned int dma_bounce_len; 230*4882a593Smuzhiyun volatile uchar busy[8]; /* index = target, bit = lun */ 231*4882a593Smuzhiyun volatile struct scsi_cmnd *input_Q; /* commands waiting to be started */ 232*4882a593Smuzhiyun volatile struct scsi_cmnd *selecting; /* trying to select this command */ 233*4882a593Smuzhiyun volatile struct scsi_cmnd *connected; /* currently connected command */ 234*4882a593Smuzhiyun volatile struct scsi_cmnd *disconnected_Q;/* commands waiting for reconnect */ 235*4882a593Smuzhiyun uchar state; /* what we are currently doing */ 236*4882a593Smuzhiyun uchar dma; /* current state of DMA (on/off) */ 237*4882a593Smuzhiyun uchar level2; /* extent to which Level-2 commands are used */ 238*4882a593Smuzhiyun uchar disconnect; /* disconnect/reselect policy */ 239*4882a593Smuzhiyun unsigned int args; /* set from command-line argument */ 240*4882a593Smuzhiyun uchar incoming_msg[8]; /* filled during message_in phase */ 241*4882a593Smuzhiyun int incoming_ptr; /* mainly used with EXTENDED messages */ 242*4882a593Smuzhiyun uchar outgoing_msg[8]; /* send this during next message_out */ 243*4882a593Smuzhiyun int outgoing_len; /* length of outgoing message */ 244*4882a593Smuzhiyun unsigned int default_sx_per; /* default transfer period for SCSI bus */ 245*4882a593Smuzhiyun uchar sync_xfer[8]; /* sync_xfer reg settings per target */ 246*4882a593Smuzhiyun uchar sync_stat[8]; /* status of sync negotiation per target */ 247*4882a593Smuzhiyun uchar no_sync; /* bitmask: don't do sync on these targets */ 248*4882a593Smuzhiyun uchar no_dma; /* set this flag to disable DMA */ 249*4882a593Smuzhiyun uchar dma_mode; /* DMA Burst Mode or Single Byte DMA */ 250*4882a593Smuzhiyun uchar fast; /* set this flag to enable Fast SCSI */ 251*4882a593Smuzhiyun struct sx_period sx_table[9]; /* transfer periods for actual DTC-setting */ 252*4882a593Smuzhiyun #ifdef PROC_INTERFACE 253*4882a593Smuzhiyun uchar proc; /* bitmask: what's in proc output */ 254*4882a593Smuzhiyun #ifdef PROC_STATISTICS 255*4882a593Smuzhiyun unsigned long cmd_cnt[8]; /* # of commands issued per target */ 256*4882a593Smuzhiyun unsigned long int_cnt; /* # of interrupts serviced */ 257*4882a593Smuzhiyun unsigned long pio_cnt; /* # of pio data transfers */ 258*4882a593Smuzhiyun unsigned long dma_cnt; /* # of DMA data transfers */ 259*4882a593Smuzhiyun unsigned long disc_allowed_cnt[8]; /* # of disconnects allowed per target */ 260*4882a593Smuzhiyun unsigned long disc_done_cnt[8]; /* # of disconnects done per target*/ 261*4882a593Smuzhiyun #endif 262*4882a593Smuzhiyun #endif 263*4882a593Smuzhiyun }; 264*4882a593Smuzhiyun 265*4882a593Smuzhiyun 266*4882a593Smuzhiyun /* defines for hostdata->chip */ 267*4882a593Smuzhiyun 268*4882a593Smuzhiyun #define C_WD33C93 0 269*4882a593Smuzhiyun #define C_WD33C93A 1 270*4882a593Smuzhiyun #define C_WD33C93B 2 271*4882a593Smuzhiyun #define C_UNKNOWN_CHIP 100 272*4882a593Smuzhiyun 273*4882a593Smuzhiyun /* defines for hostdata->state */ 274*4882a593Smuzhiyun 275*4882a593Smuzhiyun #define S_UNCONNECTED 0 276*4882a593Smuzhiyun #define S_SELECTING 1 277*4882a593Smuzhiyun #define S_RUNNING_LEVEL2 2 278*4882a593Smuzhiyun #define S_CONNECTED 3 279*4882a593Smuzhiyun #define S_PRE_TMP_DISC 4 280*4882a593Smuzhiyun #define S_PRE_CMP_DISC 5 281*4882a593Smuzhiyun 282*4882a593Smuzhiyun /* defines for hostdata->dma */ 283*4882a593Smuzhiyun 284*4882a593Smuzhiyun #define D_DMA_OFF 0 285*4882a593Smuzhiyun #define D_DMA_RUNNING 1 286*4882a593Smuzhiyun 287*4882a593Smuzhiyun /* defines for hostdata->level2 */ 288*4882a593Smuzhiyun /* NOTE: only the first 3 are implemented so far */ 289*4882a593Smuzhiyun 290*4882a593Smuzhiyun #define L2_NONE 1 /* no combination commands - we get lots of ints */ 291*4882a593Smuzhiyun #define L2_SELECT 2 /* start with SEL_ATN_XFER, but never resume it */ 292*4882a593Smuzhiyun #define L2_BASIC 3 /* resume after STATUS ints & RDP messages */ 293*4882a593Smuzhiyun #define L2_DATA 4 /* resume after DATA_IN/OUT ints */ 294*4882a593Smuzhiyun #define L2_MOST 5 /* resume after anything except a RESELECT int */ 295*4882a593Smuzhiyun #define L2_RESELECT 6 /* resume after everything, including RESELECT ints */ 296*4882a593Smuzhiyun #define L2_ALL 7 /* always resume */ 297*4882a593Smuzhiyun 298*4882a593Smuzhiyun /* defines for hostdata->disconnect */ 299*4882a593Smuzhiyun 300*4882a593Smuzhiyun #define DIS_NEVER 0 301*4882a593Smuzhiyun #define DIS_ADAPTIVE 1 302*4882a593Smuzhiyun #define DIS_ALWAYS 2 303*4882a593Smuzhiyun 304*4882a593Smuzhiyun /* defines for hostdata->args */ 305*4882a593Smuzhiyun 306*4882a593Smuzhiyun #define DB_TEST1 1<<0 307*4882a593Smuzhiyun #define DB_TEST2 1<<1 308*4882a593Smuzhiyun #define DB_QUEUE_COMMAND 1<<2 309*4882a593Smuzhiyun #define DB_EXECUTE 1<<3 310*4882a593Smuzhiyun #define DB_INTR 1<<4 311*4882a593Smuzhiyun #define DB_TRANSFER 1<<5 312*4882a593Smuzhiyun #define DB_MASK 0x3f 313*4882a593Smuzhiyun 314*4882a593Smuzhiyun /* defines for hostdata->sync_stat[] */ 315*4882a593Smuzhiyun 316*4882a593Smuzhiyun #define SS_UNSET 0 317*4882a593Smuzhiyun #define SS_FIRST 1 318*4882a593Smuzhiyun #define SS_WAITING 2 319*4882a593Smuzhiyun #define SS_SET 3 320*4882a593Smuzhiyun 321*4882a593Smuzhiyun /* defines for hostdata->proc */ 322*4882a593Smuzhiyun 323*4882a593Smuzhiyun #define PR_VERSION 1<<0 324*4882a593Smuzhiyun #define PR_INFO 1<<1 325*4882a593Smuzhiyun #define PR_STATISTICS 1<<2 326*4882a593Smuzhiyun #define PR_CONNECTED 1<<3 327*4882a593Smuzhiyun #define PR_INPUTQ 1<<4 328*4882a593Smuzhiyun #define PR_DISCQ 1<<5 329*4882a593Smuzhiyun #define PR_TEST 1<<6 330*4882a593Smuzhiyun #define PR_STOP 1<<7 331*4882a593Smuzhiyun 332*4882a593Smuzhiyun 333*4882a593Smuzhiyun void wd33c93_init (struct Scsi_Host *instance, const wd33c93_regs regs, 334*4882a593Smuzhiyun dma_setup_t setup, dma_stop_t stop, int clock_freq); 335*4882a593Smuzhiyun int wd33c93_abort (struct scsi_cmnd *cmd); 336*4882a593Smuzhiyun int wd33c93_queuecommand (struct Scsi_Host *h, struct scsi_cmnd *cmd); 337*4882a593Smuzhiyun void wd33c93_intr (struct Scsi_Host *instance); 338*4882a593Smuzhiyun int wd33c93_show_info(struct seq_file *, struct Scsi_Host *); 339*4882a593Smuzhiyun int wd33c93_write_info(struct Scsi_Host *, char *, int); 340*4882a593Smuzhiyun int wd33c93_host_reset (struct scsi_cmnd *); 341*4882a593Smuzhiyun 342*4882a593Smuzhiyun #endif /* WD33C93_H */ 343