freebsd-nq/sys/dev/amd/amd.h
Scott Long 52c9ce25d8 Separate the parallel scsi knowledge out of the core of the XPT, and
modularize it so that new transports can be created.

Add a transport for SATA

Add a periph+protocol layer for ATA

Add a driver for AHCI-compliant hardware.

Add a maxio field to CAM so that drivers can advertise their max
I/O capability.  Modify various drivers so that they are insulated
from the value of MAXPHYS.

The new ATA/SATA code supports AHCI-compliant hardware, and will override
the classic ATA driver if it is loaded as a module at boot time or compiled
into the kernel.  The stack now support NCQ (tagged queueing) for increased
performance on modern SATA drives.  It also supports port multipliers.

ATA drives are accessed via 'ada' device nodes.  ATAPI drives are
accessed via 'cd' device nodes.  They can all be enumerated and manipulated
via camcontrol, just like SCSI drives.  SCSI commands are not translated to
their ATA equivalents; ATA native commands are used throughout the entire
stack, including camcontrol.  See the camcontrol manpage for further
details.  Testing this code may require that you update your fstab, and
possibly modify your BIOS to enable AHCI functionality, if available.

This code is very experimental at the moment.  The userland ABI/API has
changed, so applications will need to be recompiled.  It may change
further in the near future.  The 'ada' device name may also change as
more infrastructure is completed in this project.  The goal is to
eventually put all CAM busses and devices until newbus, allowing for
interesting topology and management options.

Few functional changes will be seen with existing SCSI/SAS/FC drivers,
though the userland ABI has still changed.  In the future, transports
specific modules for SAS and FC may appear in order to better support
the topologies and capabilities of these technologies.

The modularization of CAM and the addition of the ATA/SATA modules is
meant to break CAM out of the mold of being specific to SCSI, letting it
grow to be a framework for arbitrary transports and protocols.  It also
allows drivers to be written to support discrete hardware without
jeopardizing the stability of non-related hardware.  While only an AHCI
driver is provided now, a Silicon Image driver is also in the works.
Drivers for ICH1-4, ICH5-6, PIIX, classic IDE, and any other hardware
is possible and encouraged.  Help with new transports is also encouraged.

Submitted by:	scottl, mav
Approved by:	re
2009-07-10 08:18:08 +00:00

586 lines
16 KiB
C

/*-
*********************************************************************
* FILE NAME : amd.h
* BY : C.L. Huang (ching@tekram.com.tw)
* Erich Chen (erich@tekram.com.tw)
* Description: Device Driver for the amd53c974 PCI Bus Master
* SCSI Host adapter found on cards such as
* the Tekram DC-390(T).
* (C)Copyright 1995-1999 Tekram Technology Co., Ltd.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*********************************************************************
* $FreeBSD$
*/
#ifndef AMD_H
#define AMD_H
#define AMD_TRANS_CUR 0x01 /* Modify current neogtiation status */
#define AMD_TRANS_ACTIVE 0x03 /* Assume this is the active target */
#define AMD_TRANS_GOAL 0x04 /* Modify negotiation goal */
#define AMD_TRANS_USER 0x08 /* Modify user negotiation settings */
/*
* Per target transfer parameters.
*/
struct amd_transinfo {
u_int8_t period;
u_int8_t offset;
};
struct amd_target_info {
/*
* Records the currently active and user/default settings for
* tagged queueing and disconnection for each target.
*/
u_int8_t disc_tag;
#define AMD_CUR_DISCENB 0x01
#define AMD_CUR_TAGENB 0x02
#define AMD_USR_DISCENB 0x04
#define AMD_USR_TAGENB 0x08
u_int8_t CtrlR1;
u_int8_t CtrlR3;
u_int8_t CtrlR4;
u_int8_t sync_period_reg;
u_int8_t sync_offset_reg;
/*
* Currently active transfer settings.
*/
struct amd_transinfo current;
/*
* Transfer settings we wish to achieve
* through negotiation.
*/
struct amd_transinfo goal;
/*
* User defined or default transfer settings.
*/
struct amd_transinfo user;
};
/*
* Scatter/Gather Segment entry.
*/
struct amd_sg {
u_int32_t SGXLen;
u_int32_t SGXPtr;
};
/*
* Chipset feature limits
*/
#define MAX_SCSI_ID 8
#define AMD_MAX_SYNC_OFFSET 15
#define AMD_TARGET_MAX 7
#define AMD_LUN_MAX 7
#define AMD_MAXPHYS (128 * 1024) /* legacy MAXPHYS */
#define AMD_NSEG (btoc(AMD_MAXPHYS) + 1)
#define AMD_MAXTRANSFER_SIZE 0xFFFFFF /* restricted by 24 bit counter */
#define MAX_DEVICES 10
#define MAX_TAGS_CMD_QUEUE 256
#define MAX_CMD_PER_LUN 6
#define MAX_SRB_CNT 256
#define MAX_START_JOB 256
/*
* BIT position to integer mapping.
*/
#define BIT(N) (0x01 << N)
/*
* EEPROM storage offsets and data structures.
*/
typedef struct _EEprom {
u_int8_t EE_MODE1;
u_int8_t EE_SPEED;
u_int8_t xx1;
u_int8_t xx2;
} EEprom, *PEEprom;
#define EE_ADAPT_SCSI_ID 64
#define EE_MODE2 65
#define EE_DELAY 66
#define EE_TAG_CMD_NUM 67
#define EE_DATA_SIZE 128
#define EE_CHECKSUM 0x1234
/*
* EE_MODE1 bits definition
*/
#define PARITY_CHK BIT(0)
#define SYNC_NEGO BIT(1)
#define EN_DISCONNECT BIT(2)
#define SEND_START BIT(3)
#define TAG_QUEUING BIT(4)
/*
* EE_MODE2 bits definition
*/
#define MORE2_DRV BIT(0)
#define GREATER_1G BIT(1)
#define RST_SCSI_BUS BIT(2)
#define ACTIVE_NEGATION BIT(3)
#define NO_SEEK BIT(4)
#define LUN_CHECK BIT(5)
#define ENABLE_CE 1
#define DISABLE_CE 0
#define EEPROM_READ 0x80
#define AMD_TAG_WILDCARD ((u_int)(~0))
/*
* SCSI Request Block
*/
struct amd_srb {
TAILQ_ENTRY(amd_srb) links;
u_int8_t CmdBlock[12];
union ccb *pccb;
bus_dmamap_t dmamap;
struct amd_sg *pSGlist;
u_int32_t TotalXferredLen;
u_int32_t SGPhysAddr; /* a segment starting address */
u_int32_t SGToBeXferLen; /* to be xfer length */
u_int32_t Segment0[2];
u_int32_t Segment1[2];
struct amd_sg SGsegment[AMD_NSEG];
struct amd_sg Segmentx;/* a one entry of S/G list table */
u_int8_t *pMsgPtr;
u_int16_t SRBState;
u_int8_t AdaptStatus;
u_int8_t TargetStatus;
u_int8_t MsgCnt;
u_int8_t EndMessage;
u_int8_t TagNumber;
u_int8_t SGcount;
u_int8_t SGIndex;
u_int8_t IORBFlag; /* ;81h-Reset, 2-retry */
u_int8_t SRBStatus;
u_int8_t SRBFlag;
/* ; b0-AutoReqSense,b6-Read,b7-write */
/* ; b4-settimeout,b5-Residual valid */
u_int8_t ScsiCmdLen;
};
TAILQ_HEAD(srb_queue, amd_srb);
/*
* Per-adapter, software configuration.
*/
struct amd_softc {
device_t dev;
bus_space_tag_t tag;
bus_space_handle_t bsh;
bus_dma_tag_t buffer_dmat; /* dmat for buffer I/O */
bus_dma_tag_t sense_dmat; /* dmat for sense buffer */
bus_dmamap_t sense_dmamap;
struct scsi_sense_data *sense_buffers;
bus_addr_t sense_busaddr;
int unit;
int last_phase;
int cur_target;
int cur_lun;
struct amd_srb *active_srb;
struct amd_srb *untagged_srbs[AMD_TARGET_MAX+1][AMD_LUN_MAX+1];
struct amd_target_info tinfo[AMD_TARGET_MAX+1];
u_int16_t disc_count[AMD_TARGET_MAX+1][AMD_LUN_MAX+1];
struct srb_queue free_srbs;
struct srb_queue waiting_srbs;
struct srb_queue running_srbs;
struct amd_srb *pTmpSRB;
u_int16_t SRBCount;
u_int16_t max_id;
u_int16_t max_lun;
/* Hooks into the CAM XPT */
struct cam_sim *psim;
struct cam_path *ppath;
u_int8_t msgin_buf[6];
u_int8_t msgout_buf[6];
u_int msgin_index;
u_int msgout_index;
u_int msgout_len;
u_int8_t status;
u_int8_t AdaptSCSIID; /* ; Adapter SCSI Target ID */
u_int8_t AdaptSCSILUN; /* ; Adapter SCSI LUN */
u_int8_t ACBFlag;
u_int8_t Gmode2;
u_int8_t HostID_Bit;
u_int8_t InitDCB_flag[8][8]; /* flag of initDCB for device */
struct amd_srb SRB_array[MAX_SRB_CNT]; /* +45Ch, Len= */
struct amd_srb TmpSRB;
/* Setup data stored in an 93c46 serial eeprom */
u_int8_t eepromBuf[EE_DATA_SIZE];
};
/*
* ----SRB State machine definition
*/
#define SRB_FREE 0
#define SRB_READY BIT(1)
#define SRB_MSGOUT BIT(2) /* ;arbitration+msg_out 1st byte */
#define SRB_MSGIN BIT(3)
#define SRB_MSGIN_MULTI BIT(4)
#define SRB_COMMAND BIT(5)
#define SRB_START BIT(6) /* ;arbitration+msg_out+command_out */
#define SRB_DISCONNECT BIT(7)
#define SRB_DATA_XFER BIT(8)
#define SRB_XFERPAD BIT(9)
#define SRB_STATUS BIT(10)
#define SRB_COMPLETED BIT(11)
#define SRB_ABORT_SENT BIT(12)
#define DO_SYNC_NEGO BIT(13)
#define SRB_UNEXPECT_RESEL BIT(14)
/*
* ---ACB Flag
*/
#define RESET_DEV BIT(0)
#define RESET_DETECT BIT(1)
#define RESET_DONE BIT(2)
/*
* ---DCB Flag
*/
#define ABORT_DEV_ BIT(0)
/*
* ---SRB status
*/
#define SRB_OK BIT(0)
#define ABORTION BIT(1)
#define OVER_RUN BIT(2)
#define UNDER_RUN BIT(3)
#define PARITY_ERROR BIT(4)
#define SRB_ERROR BIT(5)
/*
* ---SRB Flags
*/
#define DATAOUT BIT(7)
#define DATAIN BIT(6)
#define RESIDUAL_VALID BIT(5)
#define ENABLE_TIMER BIT(4)
#define RESET_DEV0 BIT(2)
#define ABORT_DEV BIT(1)
#define AUTO_REQSENSE BIT(0)
/*
* ---Adapter status
*/
#define H_STATUS_GOOD 0
#define H_SEL_TIMEOUT 0x11
#define H_OVER_UNDER_RUN 0x12
#define H_UNEXP_BUS_FREE 0x13
#define H_TARGET_PHASE_F 0x14
#define H_INVALID_CCB_OP 0x16
#define H_LINK_CCB_BAD 0x17
#define H_BAD_TARGET_DIR 0x18
#define H_DUPLICATE_CCB 0x19
#define H_BAD_CCB_OR_SG 0x1A
#define H_ABORT 0x0FF
/*
* AMD specific "status" codes returned in the SCSI status byte.
*/
#define AMD_SCSI_STAT_UNEXP_BUS_F 0xFD /* ; Unexpect Bus Free */
#define AMD_SCSI_STAT_BUS_RST_DETECT 0xFE /* ; Scsi Bus Reset detected */
#define AMD_SCSI_STAT_SEL_TIMEOUT 0xFF /* ; Selection Time out */
/*
* ---Sync_Mode
*/
#define SYNC_DISABLE 0
#define SYNC_ENABLE BIT(0)
#define SYNC_NEGO_DONE BIT(1)
#define WIDE_ENABLE BIT(2)
#define WIDE_NEGO_DONE BIT(3)
#define EN_TAG_QUEUING BIT(4)
#define EN_ATN_STOP BIT(5)
#define SYNC_NEGO_OFFSET 15
/*
* ---SCSI bus phase
*/
#define SCSI_DATA_OUT 0
#define SCSI_DATA_IN 1
#define SCSI_COMMAND 2
#define SCSI_STATUS 3
#define SCSI_NOP0 4
#define SCSI_ARBITRATING 5
#define SCSI_MSG_OUT 6
#define SCSI_MSG_IN 7
#define SCSI_BUS_FREE 8
/*
*==========================================================
* AMD 53C974 Registers bit Definition
*==========================================================
*/
/*
* ------SCSI Register-------
* Command Reg.(+0CH)
*/
#define DMA_COMMAND BIT(7)
#define NOP_CMD 0
#define CLEAR_FIFO_CMD 1
#define RST_DEVICE_CMD 2
#define RST_SCSI_BUS_CMD 3
#define INFO_XFER_CMD 0x10
#define INITIATOR_CMD_CMPLTE 0x11
#define MSG_ACCEPTED_CMD 0x12
#define XFER_PAD_BYTE 0x18
#define SET_ATN_CMD 0x1A
#define RESET_ATN_CMD 0x1B
#define SEL_W_ATN 0x42
#define SEL_W_ATN_STOP 0x43
#define EN_SEL_RESEL 0x44
#define SEL_W_ATN2 0x46
#define DATA_XFER_CMD INFO_XFER_CMD
/*
* ------SCSI Register-------
* SCSI Status Reg.(+10H)
*/
#define INTERRUPT BIT(7)
#define ILLEGAL_OP_ERR BIT(6)
#define PARITY_ERR BIT(5)
#define COUNT_2_ZERO BIT(4)
#define GROUP_CODE_VALID BIT(3)
#define SCSI_PHASE_MASK (BIT(2)+BIT(1)+BIT(0))
/*
* ------SCSI Register-------
* Interrupt Status Reg.(+14H)
*/
#define SCSI_RESET_ BIT(7)
#define INVALID_CMD BIT(6)
#define DISCONNECTED BIT(5)
#define SERVICE_REQUEST BIT(4)
#define SUCCESSFUL_OP BIT(3)
#define RESELECTED BIT(2)
#define SEL_ATTENTION BIT(1)
#define SELECTED BIT(0)
/*
* ------SCSI Register-------
* Internal State Reg.(+18H)
*/
#define SYNC_OFFSET_FLAG BIT(3)
#define INTRN_STATE_MASK (BIT(2)+BIT(1)+BIT(0))
/*
* ------SCSI Register-------
* Clock Factor Reg.(+24H)
*/
#define CLK_FREQ_40MHZ 0
#define CLK_FREQ_35MHZ (BIT(2)+BIT(1)+BIT(0))
#define CLK_FREQ_30MHZ (BIT(2)+BIT(1))
#define CLK_FREQ_25MHZ (BIT(2)+BIT(0))
#define CLK_FREQ_20MHZ BIT(2)
#define CLK_FREQ_15MHZ (BIT(1)+BIT(0))
#define CLK_FREQ_10MHZ BIT(1)
/*
* ------SCSI Register-------
* Control Reg. 1(+20H)
*/
#define EXTENDED_TIMING BIT(7)
#define DIS_INT_ON_SCSI_RST BIT(6)
#define PARITY_ERR_REPO BIT(4)
#define SCSI_ID_ON_BUS (BIT(2)+BIT(1)+BIT(0))
/*
* ------SCSI Register-------
* Control Reg. 2(+2CH)
*/
#define EN_FEATURE BIT(6)
#define EN_SCSI2_CMD BIT(3)
/*
* ------SCSI Register-------
* Control Reg. 3(+30H)
*/
#define ID_MSG_CHECK BIT(7)
#define EN_QTAG_MSG BIT(6)
#define EN_GRP2_CMD BIT(5)
#define FAST_SCSI BIT(4) /* ;10MB/SEC */
#define FAST_CLK BIT(3) /* ;25 - 40 MHZ */
/*
* ------SCSI Register-------
* Control Reg. 4(+34H)
*/
#define EATER_12NS 0
#define EATER_25NS BIT(7)
#define EATER_35NS BIT(6)
#define EATER_0NS (BIT(7)+BIT(6))
#define NEGATE_REQACKDATA BIT(2)
#define NEGATE_REQACK BIT(3)
/*
*========================================
* DMA Register
*========================================
*/
/*
* -------DMA Register--------
* DMA Command Reg.(+40H)
*/
#define READ_DIRECTION BIT(7)
#define WRITE_DIRECTION 0
#define EN_DMA_INT BIT(6)
#define MAP_TO_MDL BIT(5)
#define DMA_DIAGNOSTIC BIT(4)
#define DMA_IDLE_CMD 0
#define DMA_BLAST_CMD BIT(0)
#define DMA_ABORT_CMD BIT(1)
#define DMA_START_CMD (BIT(1)|BIT(0))
/*
* -------DMA Register--------
* DMA Status Reg.(+54H)
*/
#define PCI_MS_ABORT BIT(6)
#define BLAST_COMPLETE BIT(5)
#define SCSI_INTERRUPT BIT(4)
#define DMA_XFER_DONE BIT(3)
#define DMA_XFER_ABORT BIT(2)
#define DMA_XFER_ERROR BIT(1)
#define POWER_DOWN BIT(0)
/*
* -------DMA Register--------
* DMA SCSI Bus and Ctrl.(+70H)
* EN_INT_ON_PCI_ABORT
*/
/*
*==========================================================
* SCSI Chip register address offset
*==========================================================
*/
#define CTCREG_LOW 0x00 /* (R) current transfer count register low */
#define STCREG_LOW 0x00 /* (W) start transfer count register low */
#define CTCREG_MID 0x04 /* (R) current transfer count register
* middle */
#define STCREG_MID 0x04 /* (W) start transfer count register middle */
#define SCSIFIFOREG 0x08 /* (R/W) SCSI FIFO register */
#define SCSICMDREG 0x0C /* (R/W) SCSI command register */
#define SCSISTATREG 0x10 /* (R) SCSI status register */
#define SCSIDESTIDREG 0x10 /* (W) SCSI destination ID register */
#define INTSTATREG 0x14 /* (R) interrupt status register */
#define SCSITIMEOUTREG 0x14 /* (W) SCSI timeout register */
#define INTERNSTATREG 0x18 /* (R) internal state register */
#define SYNCPERIOREG 0x18 /* (W) synchronous transfer period register */
#define CURRENTFIFOREG 0x1C /* (R) current FIFO/internal state register */
#define SYNCOFFREG 0x1C/* (W) synchronous transfer period register */
#define CNTLREG1 0x20 /* (R/W) control register 1 */
#define CLKFACTREG 0x24 /* (W) clock factor register */
#define CNTLREG2 0x2C /* (R/W) control register 2 */
#define CNTLREG3 0x30 /* (R/W) control register 3 */
#define CNTLREG4 0x34 /* (R/W) control register 4 */
#define CURTXTCNTREG 0x38 /* (R) current transfer count register
* high/part-unique ID code */
#define STCREG_HIGH 0x38 /* (W) Start current transfer count register
* high */
/*
*********************************************************
*
* SCSI DMA register
*
*********************************************************
*/
#define DMA_Cmd 0x40 /* (R/W) command register */
#define DMA_XferCnt 0x44 /* (R/W) starting transfer count */
#define DMA_XferAddr 0x48 /* (R/W) starting Physical address */
#define DMA_Wk_ByteCntr 0x4C /* ( R ) working byte counter */
#define DMA_Wk_AddrCntr 0x50 /* ( R ) working address counter */
#define DMA_Status 0x54 /* ( R ) status register */
#define DMA_MDL_Addr 0x58 /* (R/W) starting memory descriptor list (MDL)
* address */
#define DMA_Wk_MDL_Cntr 0x5C /* ( R ) working MDL counter */
#define DMA_ScsiBusCtrl 0x70 /* (bits R/W) SCSI BUS and control */
/* ******************************************************* */
#define am_target SCSISTATREG
#define am_timeout INTSTATREG
#define am_seq_step SYNCPERIOREG
#define am_fifo_count SYNCOFFREG
#define amd_read8(amd, port) \
bus_space_read_1((amd)->tag, (amd)->bsh, port)
#define amd_read16(amd, port) \
bus_space_read_2((amd)->tag, (amd)->bsh, port)
#define amd_read32(amd, port) \
bus_space_read_4((amd)->tag, (amd)->bsh, port)
#define amd_write8(amd, port, value) \
bus_space_write_1((amd)->tag, (amd)->bsh, port, value)
#define amd_write8_multi(amd, port, ptr, len) \
bus_space_write_multi_1((amd)->tag, (amd)->bsh, port, ptr, len)
#define amd_write16(amd, port, value) \
bus_space_write_2((amd)->tag, (amd)->bsh, port, value)
#define amd_write32(amd, port, value) \
bus_space_write_4((amd)->tag, (amd)->bsh, port, value)
#endif /* AMD_H */