162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* esp_scsi.h: Defines and structures for the ESP driver. 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (C) 2007 David S. Miller (davem@davemloft.net) 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#ifndef _ESP_SCSI_H 862306a36Sopenharmony_ci#define _ESP_SCSI_H 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci /* Access Description Offset */ 1162306a36Sopenharmony_ci#define ESP_TCLOW 0x00UL /* rw Low bits transfer count 0x00 */ 1262306a36Sopenharmony_ci#define ESP_TCMED 0x01UL /* rw Mid bits transfer count 0x04 */ 1362306a36Sopenharmony_ci#define ESP_FDATA 0x02UL /* rw FIFO data bits 0x08 */ 1462306a36Sopenharmony_ci#define ESP_CMD 0x03UL /* rw SCSI command bits 0x0c */ 1562306a36Sopenharmony_ci#define ESP_STATUS 0x04UL /* ro ESP status register 0x10 */ 1662306a36Sopenharmony_ci#define ESP_BUSID ESP_STATUS /* wo BusID for sel/resel 0x10 */ 1762306a36Sopenharmony_ci#define ESP_INTRPT 0x05UL /* ro Kind of interrupt 0x14 */ 1862306a36Sopenharmony_ci#define ESP_TIMEO ESP_INTRPT /* wo Timeout for sel/resel 0x14 */ 1962306a36Sopenharmony_ci#define ESP_SSTEP 0x06UL /* ro Sequence step register 0x18 */ 2062306a36Sopenharmony_ci#define ESP_STP ESP_SSTEP /* wo Transfer period/sync 0x18 */ 2162306a36Sopenharmony_ci#define ESP_FFLAGS 0x07UL /* ro Bits current FIFO info 0x1c */ 2262306a36Sopenharmony_ci#define ESP_SOFF ESP_FFLAGS /* wo Sync offset 0x1c */ 2362306a36Sopenharmony_ci#define ESP_CFG1 0x08UL /* rw First cfg register 0x20 */ 2462306a36Sopenharmony_ci#define ESP_CFACT 0x09UL /* wo Clock conv factor 0x24 */ 2562306a36Sopenharmony_ci#define ESP_STATUS2 ESP_CFACT /* ro HME status2 register 0x24 */ 2662306a36Sopenharmony_ci#define ESP_CTEST 0x0aUL /* wo Chip test register 0x28 */ 2762306a36Sopenharmony_ci#define ESP_CFG2 0x0bUL /* rw Second cfg register 0x2c */ 2862306a36Sopenharmony_ci#define ESP_CFG3 0x0cUL /* rw Third cfg register 0x30 */ 2962306a36Sopenharmony_ci#define ESP_CFG4 0x0dUL /* rw Fourth cfg register 0x34 */ 3062306a36Sopenharmony_ci#define ESP_TCHI 0x0eUL /* rw High bits transf count 0x38 */ 3162306a36Sopenharmony_ci#define ESP_UID ESP_TCHI /* ro Unique ID code 0x38 */ 3262306a36Sopenharmony_ci#define FAS_RLO ESP_TCHI /* rw HME extended counter 0x38 */ 3362306a36Sopenharmony_ci#define ESP_FGRND 0x0fUL /* rw Data base for fifo 0x3c */ 3462306a36Sopenharmony_ci#define FAS_RHI ESP_FGRND /* rw HME extended counter 0x3c */ 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci#define SBUS_ESP_REG_SIZE 0x40UL 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci/* Bitfield meanings for the above registers. */ 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci/* ESP config reg 1, read-write, found on all ESP chips */ 4162306a36Sopenharmony_ci#define ESP_CONFIG1_ID 0x07 /* My BUS ID bits */ 4262306a36Sopenharmony_ci#define ESP_CONFIG1_CHTEST 0x08 /* Enable ESP chip tests */ 4362306a36Sopenharmony_ci#define ESP_CONFIG1_PENABLE 0x10 /* Enable parity checks */ 4462306a36Sopenharmony_ci#define ESP_CONFIG1_PARTEST 0x20 /* Parity test mode enabled? */ 4562306a36Sopenharmony_ci#define ESP_CONFIG1_SRRDISAB 0x40 /* Disable SCSI reset reports */ 4662306a36Sopenharmony_ci#define ESP_CONFIG1_SLCABLE 0x80 /* Enable slow cable mode */ 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci/* ESP config reg 2, read-write, found only on esp100a+esp200+esp236 chips */ 4962306a36Sopenharmony_ci#define ESP_CONFIG2_DMAPARITY 0x01 /* enable DMA Parity (200,236) */ 5062306a36Sopenharmony_ci#define ESP_CONFIG2_REGPARITY 0x02 /* enable reg Parity (200,236) */ 5162306a36Sopenharmony_ci#define ESP_CONFIG2_BADPARITY 0x04 /* Bad parity target abort */ 5262306a36Sopenharmony_ci#define ESP_CONFIG2_SCSI2ENAB 0x08 /* Enable SCSI-2 features (tgtmode) */ 5362306a36Sopenharmony_ci#define ESP_CONFIG2_HI 0x10 /* High Impedance DREQ ??? */ 5462306a36Sopenharmony_ci#define ESP_CONFIG2_HMEFENAB 0x10 /* HME features enable */ 5562306a36Sopenharmony_ci#define ESP_CONFIG2_BCM 0x20 /* Enable byte-ctrl (236) */ 5662306a36Sopenharmony_ci#define ESP_CONFIG2_DISPINT 0x20 /* Disable pause irq (hme) */ 5762306a36Sopenharmony_ci#define ESP_CONFIG2_FENAB 0x40 /* Enable features (fas100,216) */ 5862306a36Sopenharmony_ci#define ESP_CONFIG2_SPL 0x40 /* Enable status-phase latch (236) */ 5962306a36Sopenharmony_ci#define ESP_CONFIG2_MKDONE 0x40 /* HME magic feature */ 6062306a36Sopenharmony_ci#define ESP_CONFIG2_HME32 0x80 /* HME 32 extended */ 6162306a36Sopenharmony_ci#define ESP_CONFIG2_MAGIC 0xe0 /* Invalid bits... */ 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci/* ESP config register 3 read-write, found only esp236+fas236+fas100a+hme chips */ 6462306a36Sopenharmony_ci#define ESP_CONFIG3_FCLOCK 0x01 /* FAST SCSI clock rate (esp100a/hme) */ 6562306a36Sopenharmony_ci#define ESP_CONFIG3_TEM 0x01 /* Enable thresh-8 mode (esp/fas236) */ 6662306a36Sopenharmony_ci#define ESP_CONFIG3_FAST 0x02 /* Enable FAST SCSI (esp100a/hme) */ 6762306a36Sopenharmony_ci#define ESP_CONFIG3_ADMA 0x02 /* Enable alternate-dma (esp/fas236) */ 6862306a36Sopenharmony_ci#define ESP_CONFIG3_TENB 0x04 /* group2 SCSI2 support (esp100a/hme) */ 6962306a36Sopenharmony_ci#define ESP_CONFIG3_SRB 0x04 /* Save residual byte (esp/fas236) */ 7062306a36Sopenharmony_ci#define ESP_CONFIG3_TMS 0x08 /* Three-byte msg's ok (esp100a/hme) */ 7162306a36Sopenharmony_ci#define ESP_CONFIG3_FCLK 0x08 /* Fast SCSI clock rate (esp/fas236) */ 7262306a36Sopenharmony_ci#define ESP_CONFIG3_IDMSG 0x10 /* ID message checking (esp100a/hme) */ 7362306a36Sopenharmony_ci#define ESP_CONFIG3_FSCSI 0x10 /* Enable FAST SCSI (esp/fas236) */ 7462306a36Sopenharmony_ci#define ESP_CONFIG3_GTM 0x20 /* group2 SCSI2 support (esp/fas236) */ 7562306a36Sopenharmony_ci#define ESP_CONFIG3_IDBIT3 0x20 /* Bit 3 of HME SCSI-ID (hme) */ 7662306a36Sopenharmony_ci#define ESP_CONFIG3_TBMS 0x40 /* Three-byte msg's ok (esp/fas236) */ 7762306a36Sopenharmony_ci#define ESP_CONFIG3_EWIDE 0x40 /* Enable Wide-SCSI (hme) */ 7862306a36Sopenharmony_ci#define ESP_CONFIG3_IMS 0x80 /* ID msg chk'ng (esp/fas236) */ 7962306a36Sopenharmony_ci#define ESP_CONFIG3_OBPUSH 0x80 /* Push odd-byte to dma (hme) */ 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci/* ESP config register 4 read-write */ 8262306a36Sopenharmony_ci#define ESP_CONFIG4_BBTE 0x01 /* Back-to-back transfers (fsc) */ 8362306a36Sopenharmony_ci#define ESP_CONGIG4_TEST 0x02 /* Transfer counter test mode (fsc) */ 8462306a36Sopenharmony_ci#define ESP_CONFIG4_RADE 0x04 /* Active negation (am53c974/fsc) */ 8562306a36Sopenharmony_ci#define ESP_CONFIG4_RAE 0x08 /* Act. negation REQ/ACK (am53c974) */ 8662306a36Sopenharmony_ci#define ESP_CONFIG4_PWD 0x20 /* Reduced power feature (am53c974) */ 8762306a36Sopenharmony_ci#define ESP_CONFIG4_GE0 0x40 /* Glitch eater bit 0 (am53c974) */ 8862306a36Sopenharmony_ci#define ESP_CONFIG4_GE1 0x80 /* Glitch eater bit 1 (am53c974) */ 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci#define ESP_CONFIG_GE_12NS (0) 9162306a36Sopenharmony_ci#define ESP_CONFIG_GE_25NS (ESP_CONFIG_GE1) 9262306a36Sopenharmony_ci#define ESP_CONFIG_GE_35NS (ESP_CONFIG_GE0) 9362306a36Sopenharmony_ci#define ESP_CONFIG_GE_0NS (ESP_CONFIG_GE0 | ESP_CONFIG_GE1) 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci/* ESP command register read-write */ 9662306a36Sopenharmony_ci/* Group 1 commands: These may be sent at any point in time to the ESP 9762306a36Sopenharmony_ci * chip. None of them can generate interrupts 'cept 9862306a36Sopenharmony_ci * the "SCSI bus reset" command if you have not disabled 9962306a36Sopenharmony_ci * SCSI reset interrupts in the config1 ESP register. 10062306a36Sopenharmony_ci */ 10162306a36Sopenharmony_ci#define ESP_CMD_NULL 0x00 /* Null command, ie. a nop */ 10262306a36Sopenharmony_ci#define ESP_CMD_FLUSH 0x01 /* FIFO Flush */ 10362306a36Sopenharmony_ci#define ESP_CMD_RC 0x02 /* Chip reset */ 10462306a36Sopenharmony_ci#define ESP_CMD_RS 0x03 /* SCSI bus reset */ 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci/* Group 2 commands: ESP must be an initiator and connected to a target 10762306a36Sopenharmony_ci * for these commands to work. 10862306a36Sopenharmony_ci */ 10962306a36Sopenharmony_ci#define ESP_CMD_TI 0x10 /* Transfer Information */ 11062306a36Sopenharmony_ci#define ESP_CMD_ICCSEQ 0x11 /* Initiator cmd complete sequence */ 11162306a36Sopenharmony_ci#define ESP_CMD_MOK 0x12 /* Message okie-dokie */ 11262306a36Sopenharmony_ci#define ESP_CMD_TPAD 0x18 /* Transfer Pad */ 11362306a36Sopenharmony_ci#define ESP_CMD_SATN 0x1a /* Set ATN */ 11462306a36Sopenharmony_ci#define ESP_CMD_RATN 0x1b /* De-assert ATN */ 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci/* Group 3 commands: ESP must be in the MSGOUT or MSGIN state and be connected 11762306a36Sopenharmony_ci * to a target as the initiator for these commands to work. 11862306a36Sopenharmony_ci */ 11962306a36Sopenharmony_ci#define ESP_CMD_SMSG 0x20 /* Send message */ 12062306a36Sopenharmony_ci#define ESP_CMD_SSTAT 0x21 /* Send status */ 12162306a36Sopenharmony_ci#define ESP_CMD_SDATA 0x22 /* Send data */ 12262306a36Sopenharmony_ci#define ESP_CMD_DSEQ 0x23 /* Discontinue Sequence */ 12362306a36Sopenharmony_ci#define ESP_CMD_TSEQ 0x24 /* Terminate Sequence */ 12462306a36Sopenharmony_ci#define ESP_CMD_TCCSEQ 0x25 /* Target cmd cmplt sequence */ 12562306a36Sopenharmony_ci#define ESP_CMD_DCNCT 0x27 /* Disconnect */ 12662306a36Sopenharmony_ci#define ESP_CMD_RMSG 0x28 /* Receive Message */ 12762306a36Sopenharmony_ci#define ESP_CMD_RCMD 0x29 /* Receive Command */ 12862306a36Sopenharmony_ci#define ESP_CMD_RDATA 0x2a /* Receive Data */ 12962306a36Sopenharmony_ci#define ESP_CMD_RCSEQ 0x2b /* Receive cmd sequence */ 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci/* Group 4 commands: The ESP must be in the disconnected state and must 13262306a36Sopenharmony_ci * not be connected to any targets as initiator for 13362306a36Sopenharmony_ci * these commands to work. 13462306a36Sopenharmony_ci */ 13562306a36Sopenharmony_ci#define ESP_CMD_RSEL 0x40 /* Reselect */ 13662306a36Sopenharmony_ci#define ESP_CMD_SEL 0x41 /* Select w/o ATN */ 13762306a36Sopenharmony_ci#define ESP_CMD_SELA 0x42 /* Select w/ATN */ 13862306a36Sopenharmony_ci#define ESP_CMD_SELAS 0x43 /* Select w/ATN & STOP */ 13962306a36Sopenharmony_ci#define ESP_CMD_ESEL 0x44 /* Enable selection */ 14062306a36Sopenharmony_ci#define ESP_CMD_DSEL 0x45 /* Disable selections */ 14162306a36Sopenharmony_ci#define ESP_CMD_SA3 0x46 /* Select w/ATN3 */ 14262306a36Sopenharmony_ci#define ESP_CMD_RSEL3 0x47 /* Reselect3 */ 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci/* This bit enables the ESP's DMA on the SBus */ 14562306a36Sopenharmony_ci#define ESP_CMD_DMA 0x80 /* Do DMA? */ 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci/* ESP status register read-only */ 14862306a36Sopenharmony_ci#define ESP_STAT_PIO 0x01 /* IO phase bit */ 14962306a36Sopenharmony_ci#define ESP_STAT_PCD 0x02 /* CD phase bit */ 15062306a36Sopenharmony_ci#define ESP_STAT_PMSG 0x04 /* MSG phase bit */ 15162306a36Sopenharmony_ci#define ESP_STAT_PMASK 0x07 /* Mask of phase bits */ 15262306a36Sopenharmony_ci#define ESP_STAT_TDONE 0x08 /* Transfer Completed */ 15362306a36Sopenharmony_ci#define ESP_STAT_TCNT 0x10 /* Transfer Counter Is Zero */ 15462306a36Sopenharmony_ci#define ESP_STAT_PERR 0x20 /* Parity error */ 15562306a36Sopenharmony_ci#define ESP_STAT_SPAM 0x40 /* Real bad error */ 15662306a36Sopenharmony_ci/* This indicates the 'interrupt pending' condition on esp236, it is a reserved 15762306a36Sopenharmony_ci * bit on other revs of the ESP. 15862306a36Sopenharmony_ci */ 15962306a36Sopenharmony_ci#define ESP_STAT_INTR 0x80 /* Interrupt */ 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci/* The status register can be masked with ESP_STAT_PMASK and compared 16262306a36Sopenharmony_ci * with the following values to determine the current phase the ESP 16362306a36Sopenharmony_ci * (at least thinks it) is in. For our purposes we also add our own 16462306a36Sopenharmony_ci * software 'done' bit for our phase management engine. 16562306a36Sopenharmony_ci */ 16662306a36Sopenharmony_ci#define ESP_DOP (0) /* Data Out */ 16762306a36Sopenharmony_ci#define ESP_DIP (ESP_STAT_PIO) /* Data In */ 16862306a36Sopenharmony_ci#define ESP_CMDP (ESP_STAT_PCD) /* Command */ 16962306a36Sopenharmony_ci#define ESP_STATP (ESP_STAT_PCD|ESP_STAT_PIO) /* Status */ 17062306a36Sopenharmony_ci#define ESP_MOP (ESP_STAT_PMSG|ESP_STAT_PCD) /* Message Out */ 17162306a36Sopenharmony_ci#define ESP_MIP (ESP_STAT_PMSG|ESP_STAT_PCD|ESP_STAT_PIO) /* Message In */ 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci/* HME only: status 2 register */ 17462306a36Sopenharmony_ci#define ESP_STAT2_SCHBIT 0x01 /* Upper bits 3-7 of sstep enabled */ 17562306a36Sopenharmony_ci#define ESP_STAT2_FFLAGS 0x02 /* The fifo flags are now latched */ 17662306a36Sopenharmony_ci#define ESP_STAT2_XCNT 0x04 /* The transfer counter is latched */ 17762306a36Sopenharmony_ci#define ESP_STAT2_CREGA 0x08 /* The command reg is active now */ 17862306a36Sopenharmony_ci#define ESP_STAT2_WIDE 0x10 /* Interface on this adapter is wide */ 17962306a36Sopenharmony_ci#define ESP_STAT2_F1BYTE 0x20 /* There is one byte at top of fifo */ 18062306a36Sopenharmony_ci#define ESP_STAT2_FMSB 0x40 /* Next byte in fifo is most significant */ 18162306a36Sopenharmony_ci#define ESP_STAT2_FEMPTY 0x80 /* FIFO is empty */ 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci/* ESP interrupt register read-only */ 18462306a36Sopenharmony_ci#define ESP_INTR_S 0x01 /* Select w/o ATN */ 18562306a36Sopenharmony_ci#define ESP_INTR_SATN 0x02 /* Select w/ATN */ 18662306a36Sopenharmony_ci#define ESP_INTR_RSEL 0x04 /* Reselected */ 18762306a36Sopenharmony_ci#define ESP_INTR_FDONE 0x08 /* Function done */ 18862306a36Sopenharmony_ci#define ESP_INTR_BSERV 0x10 /* Bus service */ 18962306a36Sopenharmony_ci#define ESP_INTR_DC 0x20 /* Disconnect */ 19062306a36Sopenharmony_ci#define ESP_INTR_IC 0x40 /* Illegal command given */ 19162306a36Sopenharmony_ci#define ESP_INTR_SR 0x80 /* SCSI bus reset detected */ 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci/* ESP sequence step register read-only */ 19462306a36Sopenharmony_ci#define ESP_STEP_VBITS 0x07 /* Valid bits */ 19562306a36Sopenharmony_ci#define ESP_STEP_ASEL 0x00 /* Selection&Arbitrate cmplt */ 19662306a36Sopenharmony_ci#define ESP_STEP_SID 0x01 /* One msg byte sent */ 19762306a36Sopenharmony_ci#define ESP_STEP_NCMD 0x02 /* Was not in command phase */ 19862306a36Sopenharmony_ci#define ESP_STEP_PPC 0x03 /* Early phase chg caused cmnd 19962306a36Sopenharmony_ci * bytes to be lost 20062306a36Sopenharmony_ci */ 20162306a36Sopenharmony_ci#define ESP_STEP_FINI4 0x04 /* Command was sent ok */ 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci/* Ho hum, some ESP's set the step register to this as well... */ 20462306a36Sopenharmony_ci#define ESP_STEP_FINI5 0x05 20562306a36Sopenharmony_ci#define ESP_STEP_FINI6 0x06 20662306a36Sopenharmony_ci#define ESP_STEP_FINI7 0x07 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci/* ESP chip-test register read-write */ 20962306a36Sopenharmony_ci#define ESP_TEST_TARG 0x01 /* Target test mode */ 21062306a36Sopenharmony_ci#define ESP_TEST_INI 0x02 /* Initiator test mode */ 21162306a36Sopenharmony_ci#define ESP_TEST_TS 0x04 /* Tristate test mode */ 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci/* ESP unique ID register read-only, found on fas236+fas100a only */ 21462306a36Sopenharmony_ci#define ESP_UID_FAM 0xf8 /* ESP family bitmask */ 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci#define ESP_FAMILY(uid) (((uid) & ESP_UID_FAM) >> 3) 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci/* Values for the ESP family bits */ 21962306a36Sopenharmony_ci#define ESP_UID_F100A 0x00 /* ESP FAS100A */ 22062306a36Sopenharmony_ci#define ESP_UID_F236 0x02 /* ESP FAS236 */ 22162306a36Sopenharmony_ci#define ESP_UID_HME 0x0a /* FAS HME */ 22262306a36Sopenharmony_ci#define ESP_UID_FSC 0x14 /* NCR/Symbios Logic 53CF9x-2 */ 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci/* ESP fifo flags register read-only */ 22562306a36Sopenharmony_ci/* Note that the following implies a 16 byte FIFO on the ESP. */ 22662306a36Sopenharmony_ci#define ESP_FF_FBYTES 0x1f /* Num bytes in FIFO */ 22762306a36Sopenharmony_ci#define ESP_FF_ONOTZERO 0x20 /* offset ctr not zero (esp100) */ 22862306a36Sopenharmony_ci#define ESP_FF_SSTEP 0xe0 /* Sequence step */ 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci/* ESP clock conversion factor register write-only */ 23162306a36Sopenharmony_ci#define ESP_CCF_F0 0x00 /* 35.01MHz - 40MHz */ 23262306a36Sopenharmony_ci#define ESP_CCF_NEVER 0x01 /* Set it to this and die */ 23362306a36Sopenharmony_ci#define ESP_CCF_F2 0x02 /* 10MHz */ 23462306a36Sopenharmony_ci#define ESP_CCF_F3 0x03 /* 10.01MHz - 15MHz */ 23562306a36Sopenharmony_ci#define ESP_CCF_F4 0x04 /* 15.01MHz - 20MHz */ 23662306a36Sopenharmony_ci#define ESP_CCF_F5 0x05 /* 20.01MHz - 25MHz */ 23762306a36Sopenharmony_ci#define ESP_CCF_F6 0x06 /* 25.01MHz - 30MHz */ 23862306a36Sopenharmony_ci#define ESP_CCF_F7 0x07 /* 30.01MHz - 35MHz */ 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci/* HME only... */ 24162306a36Sopenharmony_ci#define ESP_BUSID_RESELID 0x10 24262306a36Sopenharmony_ci#define ESP_BUSID_CTR32BIT 0x40 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci#define ESP_BUS_TIMEOUT 250 /* In milli-seconds */ 24562306a36Sopenharmony_ci#define ESP_TIMEO_CONST 8192 24662306a36Sopenharmony_ci#define ESP_NEG_DEFP(mhz, cfact) \ 24762306a36Sopenharmony_ci ((ESP_BUS_TIMEOUT * ((mhz) / 1000)) / (8192 * (cfact))) 24862306a36Sopenharmony_ci#define ESP_HZ_TO_CYCLE(hertz) ((1000000000) / ((hertz) / 1000)) 24962306a36Sopenharmony_ci#define ESP_TICK(ccf, cycle) ((7682 * (ccf) * (cycle) / 1000)) 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci/* For slow to medium speed input clock rates we shoot for 5mb/s, but for high 25262306a36Sopenharmony_ci * input clock rates we try to do 10mb/s although I don't think a transfer can 25362306a36Sopenharmony_ci * even run that fast with an ESP even with DMA2 scatter gather pipelining. 25462306a36Sopenharmony_ci */ 25562306a36Sopenharmony_ci#define SYNC_DEFP_SLOW 0x32 /* 5mb/s */ 25662306a36Sopenharmony_ci#define SYNC_DEFP_FAST 0x19 /* 10mb/s */ 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_cistruct esp_cmd_priv { 25962306a36Sopenharmony_ci int num_sg; 26062306a36Sopenharmony_ci int cur_residue; 26162306a36Sopenharmony_ci struct scatterlist *prv_sg; 26262306a36Sopenharmony_ci struct scatterlist *cur_sg; 26362306a36Sopenharmony_ci int tot_residue; 26462306a36Sopenharmony_ci}; 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci#define ESP_CMD_PRIV(cmd) ((struct esp_cmd_priv *)scsi_cmd_priv(cmd)) 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci/* NOTE: this enum is ordered based on chip features! */ 26962306a36Sopenharmony_cienum esp_rev { 27062306a36Sopenharmony_ci ESP100, /* NCR53C90 - very broken */ 27162306a36Sopenharmony_ci ESP100A, /* NCR53C90A */ 27262306a36Sopenharmony_ci ESP236, 27362306a36Sopenharmony_ci FAS236, 27462306a36Sopenharmony_ci PCSCSI, /* AM53c974 */ 27562306a36Sopenharmony_ci FSC, /* NCR/Symbios Logic 53CF9x-2 */ 27662306a36Sopenharmony_ci FAS100A, 27762306a36Sopenharmony_ci FAST, 27862306a36Sopenharmony_ci FASHME, 27962306a36Sopenharmony_ci}; 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_cistruct esp_cmd_entry { 28262306a36Sopenharmony_ci struct list_head list; 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci struct scsi_cmnd *cmd; 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci unsigned int saved_cur_residue; 28762306a36Sopenharmony_ci struct scatterlist *saved_prv_sg; 28862306a36Sopenharmony_ci struct scatterlist *saved_cur_sg; 28962306a36Sopenharmony_ci unsigned int saved_tot_residue; 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci u8 flags; 29262306a36Sopenharmony_ci#define ESP_CMD_FLAG_WRITE 0x01 /* DMA is a write */ 29362306a36Sopenharmony_ci#define ESP_CMD_FLAG_AUTOSENSE 0x04 /* Doing automatic REQUEST_SENSE */ 29462306a36Sopenharmony_ci#define ESP_CMD_FLAG_RESIDUAL 0x08 /* AM53c974 BLAST residual */ 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci u8 tag[2]; 29762306a36Sopenharmony_ci u8 orig_tag[2]; 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci u8 status; 30062306a36Sopenharmony_ci u8 message; 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci unsigned char *sense_ptr; 30362306a36Sopenharmony_ci unsigned char *saved_sense_ptr; 30462306a36Sopenharmony_ci dma_addr_t sense_dma; 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci struct completion *eh_done; 30762306a36Sopenharmony_ci}; 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci#define ESP_DEFAULT_TAGS 16 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci#define ESP_MAX_TARGET 16 31262306a36Sopenharmony_ci#define ESP_MAX_LUN 8 31362306a36Sopenharmony_ci#define ESP_MAX_TAG 256 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_cistruct esp_lun_data { 31662306a36Sopenharmony_ci struct esp_cmd_entry *non_tagged_cmd; 31762306a36Sopenharmony_ci int num_tagged; 31862306a36Sopenharmony_ci int hold; 31962306a36Sopenharmony_ci struct esp_cmd_entry *tagged_cmds[ESP_MAX_TAG]; 32062306a36Sopenharmony_ci}; 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_cistruct esp_target_data { 32362306a36Sopenharmony_ci /* These are the ESP_STP, ESP_SOFF, and ESP_CFG3 register values which 32462306a36Sopenharmony_ci * match the currently negotiated settings for this target. The SCSI 32562306a36Sopenharmony_ci * protocol values are maintained in spi_{offset,period,wide}(starget). 32662306a36Sopenharmony_ci */ 32762306a36Sopenharmony_ci u8 esp_period; 32862306a36Sopenharmony_ci u8 esp_offset; 32962306a36Sopenharmony_ci u8 esp_config3; 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci u8 flags; 33262306a36Sopenharmony_ci#define ESP_TGT_WIDE 0x01 33362306a36Sopenharmony_ci#define ESP_TGT_DISCONNECT 0x02 33462306a36Sopenharmony_ci#define ESP_TGT_NEGO_WIDE 0x04 33562306a36Sopenharmony_ci#define ESP_TGT_NEGO_SYNC 0x08 33662306a36Sopenharmony_ci#define ESP_TGT_CHECK_NEGO 0x40 33762306a36Sopenharmony_ci#define ESP_TGT_BROKEN 0x80 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci /* When ESP_TGT_CHECK_NEGO is set, on the next scsi command to this 34062306a36Sopenharmony_ci * device we will try to negotiate the following parameters. 34162306a36Sopenharmony_ci */ 34262306a36Sopenharmony_ci u8 nego_goal_period; 34362306a36Sopenharmony_ci u8 nego_goal_offset; 34462306a36Sopenharmony_ci u8 nego_goal_width; 34562306a36Sopenharmony_ci u8 nego_goal_tags; 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ci struct scsi_target *starget; 34862306a36Sopenharmony_ci}; 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_cistruct esp_event_ent { 35162306a36Sopenharmony_ci u8 type; 35262306a36Sopenharmony_ci#define ESP_EVENT_TYPE_EVENT 0x01 35362306a36Sopenharmony_ci#define ESP_EVENT_TYPE_CMD 0x02 35462306a36Sopenharmony_ci u8 val; 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_ci u8 sreg; 35762306a36Sopenharmony_ci u8 seqreg; 35862306a36Sopenharmony_ci u8 sreg2; 35962306a36Sopenharmony_ci u8 ireg; 36062306a36Sopenharmony_ci u8 select_state; 36162306a36Sopenharmony_ci u8 event; 36262306a36Sopenharmony_ci u8 __pad; 36362306a36Sopenharmony_ci}; 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_cistruct esp; 36662306a36Sopenharmony_cistruct esp_driver_ops { 36762306a36Sopenharmony_ci /* Read and write the ESP 8-bit registers. On some 36862306a36Sopenharmony_ci * applications of the ESP chip the registers are at 4-byte 36962306a36Sopenharmony_ci * instead of 1-byte intervals. 37062306a36Sopenharmony_ci */ 37162306a36Sopenharmony_ci void (*esp_write8)(struct esp *esp, u8 val, unsigned long reg); 37262306a36Sopenharmony_ci u8 (*esp_read8)(struct esp *esp, unsigned long reg); 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci /* Return non-zero if there is an IRQ pending. Usually this 37562306a36Sopenharmony_ci * status bit lives in the DMA controller sitting in front of 37662306a36Sopenharmony_ci * the ESP. This has to be accurate or else the ESP interrupt 37762306a36Sopenharmony_ci * handler will not run. 37862306a36Sopenharmony_ci */ 37962306a36Sopenharmony_ci int (*irq_pending)(struct esp *esp); 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci /* Return the maximum allowable size of a DMA transfer for a 38262306a36Sopenharmony_ci * given buffer. 38362306a36Sopenharmony_ci */ 38462306a36Sopenharmony_ci u32 (*dma_length_limit)(struct esp *esp, u32 dma_addr, 38562306a36Sopenharmony_ci u32 dma_len); 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci /* Reset the DMA engine entirely. On return, ESP interrupts 38862306a36Sopenharmony_ci * should be enabled. Often the interrupt enabling is 38962306a36Sopenharmony_ci * controlled in the DMA engine. 39062306a36Sopenharmony_ci */ 39162306a36Sopenharmony_ci void (*reset_dma)(struct esp *esp); 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci /* Drain any pending DMA in the DMA engine after a transfer. 39462306a36Sopenharmony_ci * This is for writes to memory. 39562306a36Sopenharmony_ci */ 39662306a36Sopenharmony_ci void (*dma_drain)(struct esp *esp); 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci /* Invalidate the DMA engine after a DMA transfer. */ 39962306a36Sopenharmony_ci void (*dma_invalidate)(struct esp *esp); 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_ci /* Setup an ESP command that will use a DMA transfer. 40262306a36Sopenharmony_ci * The 'esp_count' specifies what transfer length should be 40362306a36Sopenharmony_ci * programmed into the ESP transfer counter registers, whereas 40462306a36Sopenharmony_ci * the 'dma_count' is the length that should be programmed into 40562306a36Sopenharmony_ci * the DMA controller. Usually they are the same. If 'write' 40662306a36Sopenharmony_ci * is non-zero, this transfer is a write into memory. 'cmd' 40762306a36Sopenharmony_ci * holds the ESP command that should be issued by calling 40862306a36Sopenharmony_ci * scsi_esp_cmd() at the appropriate time while programming 40962306a36Sopenharmony_ci * the DMA hardware. 41062306a36Sopenharmony_ci */ 41162306a36Sopenharmony_ci void (*send_dma_cmd)(struct esp *esp, u32 dma_addr, u32 esp_count, 41262306a36Sopenharmony_ci u32 dma_count, int write, u8 cmd); 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ci /* Return non-zero if the DMA engine is reporting an error 41562306a36Sopenharmony_ci * currently. 41662306a36Sopenharmony_ci */ 41762306a36Sopenharmony_ci int (*dma_error)(struct esp *esp); 41862306a36Sopenharmony_ci}; 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci#define ESP_MAX_MSG_SZ 8 42162306a36Sopenharmony_ci#define ESP_EVENT_LOG_SZ 32 42262306a36Sopenharmony_ci 42362306a36Sopenharmony_ci#define ESP_QUICKIRQ_LIMIT 100 42462306a36Sopenharmony_ci#define ESP_RESELECT_TAG_LIMIT 2500 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_cistruct esp { 42762306a36Sopenharmony_ci void __iomem *regs; 42862306a36Sopenharmony_ci void __iomem *dma_regs; 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci const struct esp_driver_ops *ops; 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_ci struct Scsi_Host *host; 43362306a36Sopenharmony_ci struct device *dev; 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_ci struct esp_cmd_entry *active_cmd; 43662306a36Sopenharmony_ci 43762306a36Sopenharmony_ci struct list_head queued_cmds; 43862306a36Sopenharmony_ci struct list_head active_cmds; 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_ci u8 *command_block; 44162306a36Sopenharmony_ci dma_addr_t command_block_dma; 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ci unsigned int data_dma_len; 44462306a36Sopenharmony_ci 44562306a36Sopenharmony_ci /* The following are used to determine the cause of an IRQ. Upon every 44662306a36Sopenharmony_ci * IRQ entry we synchronize these with the hardware registers. 44762306a36Sopenharmony_ci */ 44862306a36Sopenharmony_ci u8 sreg; 44962306a36Sopenharmony_ci u8 seqreg; 45062306a36Sopenharmony_ci u8 sreg2; 45162306a36Sopenharmony_ci u8 ireg; 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_ci u32 prev_hme_dmacsr; 45462306a36Sopenharmony_ci u8 prev_soff; 45562306a36Sopenharmony_ci u8 prev_stp; 45662306a36Sopenharmony_ci u8 prev_cfg3; 45762306a36Sopenharmony_ci u8 num_tags; 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ci struct list_head esp_cmd_pool; 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci struct esp_target_data target[ESP_MAX_TARGET]; 46262306a36Sopenharmony_ci 46362306a36Sopenharmony_ci int fifo_cnt; 46462306a36Sopenharmony_ci u8 fifo[16]; 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ci struct esp_event_ent esp_event_log[ESP_EVENT_LOG_SZ]; 46762306a36Sopenharmony_ci int esp_event_cur; 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_ci u8 msg_out[ESP_MAX_MSG_SZ]; 47062306a36Sopenharmony_ci int msg_out_len; 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ci u8 msg_in[ESP_MAX_MSG_SZ]; 47362306a36Sopenharmony_ci int msg_in_len; 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ci u8 bursts; 47662306a36Sopenharmony_ci u8 config1; 47762306a36Sopenharmony_ci u8 config2; 47862306a36Sopenharmony_ci u8 config4; 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ci u8 scsi_id; 48162306a36Sopenharmony_ci u32 scsi_id_mask; 48262306a36Sopenharmony_ci 48362306a36Sopenharmony_ci enum esp_rev rev; 48462306a36Sopenharmony_ci 48562306a36Sopenharmony_ci u32 flags; 48662306a36Sopenharmony_ci#define ESP_FLAG_DIFFERENTIAL 0x00000001 48762306a36Sopenharmony_ci#define ESP_FLAG_RESETTING 0x00000002 48862306a36Sopenharmony_ci#define ESP_FLAG_WIDE_CAPABLE 0x00000008 48962306a36Sopenharmony_ci#define ESP_FLAG_QUICKIRQ_CHECK 0x00000010 49062306a36Sopenharmony_ci#define ESP_FLAG_DISABLE_SYNC 0x00000020 49162306a36Sopenharmony_ci#define ESP_FLAG_USE_FIFO 0x00000040 49262306a36Sopenharmony_ci#define ESP_FLAG_NO_DMA_MAP 0x00000080 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_ci u8 select_state; 49562306a36Sopenharmony_ci#define ESP_SELECT_NONE 0x00 /* Not selecting */ 49662306a36Sopenharmony_ci#define ESP_SELECT_BASIC 0x01 /* Select w/o MSGOUT phase */ 49762306a36Sopenharmony_ci#define ESP_SELECT_MSGOUT 0x02 /* Select with MSGOUT */ 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_ci /* When we are not selecting, we are expecting an event. */ 50062306a36Sopenharmony_ci u8 event; 50162306a36Sopenharmony_ci#define ESP_EVENT_NONE 0x00 50262306a36Sopenharmony_ci#define ESP_EVENT_CMD_START 0x01 50362306a36Sopenharmony_ci#define ESP_EVENT_CMD_DONE 0x02 50462306a36Sopenharmony_ci#define ESP_EVENT_DATA_IN 0x03 50562306a36Sopenharmony_ci#define ESP_EVENT_DATA_OUT 0x04 50662306a36Sopenharmony_ci#define ESP_EVENT_DATA_DONE 0x05 50762306a36Sopenharmony_ci#define ESP_EVENT_MSGIN 0x06 50862306a36Sopenharmony_ci#define ESP_EVENT_MSGIN_MORE 0x07 50962306a36Sopenharmony_ci#define ESP_EVENT_MSGIN_DONE 0x08 51062306a36Sopenharmony_ci#define ESP_EVENT_MSGOUT 0x09 51162306a36Sopenharmony_ci#define ESP_EVENT_MSGOUT_DONE 0x0a 51262306a36Sopenharmony_ci#define ESP_EVENT_STATUS 0x0b 51362306a36Sopenharmony_ci#define ESP_EVENT_FREE_BUS 0x0c 51462306a36Sopenharmony_ci#define ESP_EVENT_CHECK_PHASE 0x0d 51562306a36Sopenharmony_ci#define ESP_EVENT_RESET 0x10 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci /* Probed in esp_get_clock_params() */ 51862306a36Sopenharmony_ci u32 cfact; 51962306a36Sopenharmony_ci u32 cfreq; 52062306a36Sopenharmony_ci u32 ccycle; 52162306a36Sopenharmony_ci u32 ctick; 52262306a36Sopenharmony_ci u32 neg_defp; 52362306a36Sopenharmony_ci u32 sync_defp; 52462306a36Sopenharmony_ci 52562306a36Sopenharmony_ci /* Computed in esp_reset_esp() */ 52662306a36Sopenharmony_ci u32 max_period; 52762306a36Sopenharmony_ci u32 min_period; 52862306a36Sopenharmony_ci u32 radelay; 52962306a36Sopenharmony_ci 53062306a36Sopenharmony_ci /* ESP_CMD_SELAS command state */ 53162306a36Sopenharmony_ci u8 *cmd_bytes_ptr; 53262306a36Sopenharmony_ci int cmd_bytes_left; 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_ci struct completion *eh_reset; 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_ci void *dma; 53762306a36Sopenharmony_ci int dmarev; 53862306a36Sopenharmony_ci 53962306a36Sopenharmony_ci /* These are used by esp_send_pio_cmd() */ 54062306a36Sopenharmony_ci u8 __iomem *fifo_reg; 54162306a36Sopenharmony_ci int send_cmd_error; 54262306a36Sopenharmony_ci u32 send_cmd_residual; 54362306a36Sopenharmony_ci}; 54462306a36Sopenharmony_ci 54562306a36Sopenharmony_ci/* A front-end driver for the ESP chip should do the following in 54662306a36Sopenharmony_ci * it's device probe routine: 54762306a36Sopenharmony_ci * 1) Allocate the host and private area using scsi_host_alloc() 54862306a36Sopenharmony_ci * with size 'sizeof(struct esp)'. The first argument to 54962306a36Sopenharmony_ci * scsi_host_alloc() should be &scsi_esp_template. 55062306a36Sopenharmony_ci * 2) Set host->max_id as appropriate. 55162306a36Sopenharmony_ci * 3) Set esp->host to the scsi_host itself, and esp->dev 55262306a36Sopenharmony_ci * to the device object pointer. 55362306a36Sopenharmony_ci * 4) Hook up esp->ops to the front-end implementation. 55462306a36Sopenharmony_ci * 5) If the ESP chip supports wide transfers, set ESP_FLAG_WIDE_CAPABLE 55562306a36Sopenharmony_ci * in esp->flags. 55662306a36Sopenharmony_ci * 6) Map the DMA and ESP chip registers. 55762306a36Sopenharmony_ci * 7) DMA map the ESP command block, store the DMA address 55862306a36Sopenharmony_ci * in esp->command_block_dma. 55962306a36Sopenharmony_ci * 8) Register the scsi_esp_intr() interrupt handler. 56062306a36Sopenharmony_ci * 9) Probe for and provide the following chip properties: 56162306a36Sopenharmony_ci * esp->scsi_id (assign to esp->host->this_id too) 56262306a36Sopenharmony_ci * esp->scsi_id_mask 56362306a36Sopenharmony_ci * If ESP bus is differential, set ESP_FLAG_DIFFERENTIAL 56462306a36Sopenharmony_ci * esp->cfreq 56562306a36Sopenharmony_ci * DMA burst bit mask in esp->bursts, if necessary 56662306a36Sopenharmony_ci * 10) Perform any actions necessary before the ESP device can 56762306a36Sopenharmony_ci * be programmed for the first time. On some configs, for 56862306a36Sopenharmony_ci * example, the DMA engine has to be reset before ESP can 56962306a36Sopenharmony_ci * be programmed. 57062306a36Sopenharmony_ci * 11) If necessary, call dev_set_drvdata() as needed. 57162306a36Sopenharmony_ci * 12) Call scsi_esp_register() with prepared 'esp' structure. 57262306a36Sopenharmony_ci * 13) Check scsi_esp_register() return value, release all resources 57362306a36Sopenharmony_ci * if an error was returned. 57462306a36Sopenharmony_ci */ 57562306a36Sopenharmony_ciextern const struct scsi_host_template scsi_esp_template; 57662306a36Sopenharmony_ciextern int scsi_esp_register(struct esp *); 57762306a36Sopenharmony_ci 57862306a36Sopenharmony_ciextern void scsi_esp_unregister(struct esp *); 57962306a36Sopenharmony_ciextern irqreturn_t scsi_esp_intr(int, void *); 58062306a36Sopenharmony_ciextern void scsi_esp_cmd(struct esp *, u8); 58162306a36Sopenharmony_ci 58262306a36Sopenharmony_ciextern void esp_send_pio_cmd(struct esp *esp, u32 dma_addr, u32 esp_count, 58362306a36Sopenharmony_ci u32 dma_count, int write, u8 cmd); 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_ci#endif /* !(_ESP_SCSI_H) */ 586