Index: head/sys/dev/ahci/ahci.h =================================================================== --- head/sys/dev/ahci/ahci.h (revision 279962) +++ head/sys/dev/ahci/ahci.h (revision 279963) @@ -1,616 +1,616 @@ /*- * Copyright (c) 1998 - 2008 Søren Schmidt * Copyright (c) 2009-2012 Alexander Motin * All rights reserved. * * 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, * without modification, immediately at the beginning of the file. * 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. * * 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$ */ /* ATA register defines */ #define ATA_DATA 0 /* (RW) data */ #define ATA_FEATURE 1 /* (W) feature */ #define ATA_F_DMA 0x01 /* enable DMA */ #define ATA_F_OVL 0x02 /* enable overlap */ #define ATA_COUNT 2 /* (W) sector count */ #define ATA_SECTOR 3 /* (RW) sector # */ #define ATA_CYL_LSB 4 /* (RW) cylinder# LSB */ #define ATA_CYL_MSB 5 /* (RW) cylinder# MSB */ #define ATA_DRIVE 6 /* (W) Sector/Drive/Head */ #define ATA_D_LBA 0x40 /* use LBA addressing */ #define ATA_D_IBM 0xa0 /* 512 byte sectors, ECC */ #define ATA_COMMAND 7 /* (W) command */ #define ATA_ERROR 8 /* (R) error */ #define ATA_E_ILI 0x01 /* illegal length */ #define ATA_E_NM 0x02 /* no media */ #define ATA_E_ABORT 0x04 /* command aborted */ #define ATA_E_MCR 0x08 /* media change request */ #define ATA_E_IDNF 0x10 /* ID not found */ #define ATA_E_MC 0x20 /* media changed */ #define ATA_E_UNC 0x40 /* uncorrectable data */ #define ATA_E_ICRC 0x80 /* UDMA crc error */ #define ATA_E_ATAPI_SENSE_MASK 0xf0 /* ATAPI sense key mask */ #define ATA_IREASON 9 /* (R) interrupt reason */ #define ATA_I_CMD 0x01 /* cmd (1) | data (0) */ #define ATA_I_IN 0x02 /* read (1) | write (0) */ #define ATA_I_RELEASE 0x04 /* released bus (1) */ #define ATA_I_TAGMASK 0xf8 /* tag mask */ #define ATA_STATUS 10 /* (R) status */ #define ATA_ALTSTAT 11 /* (R) alternate status */ #define ATA_S_ERROR 0x01 /* error */ #define ATA_S_INDEX 0x02 /* index */ #define ATA_S_CORR 0x04 /* data corrected */ #define ATA_S_DRQ 0x08 /* data request */ #define ATA_S_DSC 0x10 /* drive seek completed */ #define ATA_S_SERVICE 0x10 /* drive needs service */ #define ATA_S_DWF 0x20 /* drive write fault */ #define ATA_S_DMA 0x20 /* DMA ready */ #define ATA_S_READY 0x40 /* drive ready */ #define ATA_S_BUSY 0x80 /* busy */ #define ATA_CONTROL 12 /* (W) control */ #define ATA_A_IDS 0x02 /* disable interrupts */ #define ATA_A_RESET 0x04 /* RESET controller */ #define ATA_A_4BIT 0x08 /* 4 head bits */ #define ATA_A_HOB 0x80 /* High Order Byte enable */ /* SATA register defines */ #define ATA_SSTATUS 13 #define ATA_SS_DET_MASK 0x0000000f #define ATA_SS_DET_NO_DEVICE 0x00000000 #define ATA_SS_DET_DEV_PRESENT 0x00000001 #define ATA_SS_DET_PHY_ONLINE 0x00000003 #define ATA_SS_DET_PHY_OFFLINE 0x00000004 #define ATA_SS_SPD_MASK 0x000000f0 #define ATA_SS_SPD_NO_SPEED 0x00000000 #define ATA_SS_SPD_GEN1 0x00000010 #define ATA_SS_SPD_GEN2 0x00000020 -#define ATA_SS_SPD_GEN3 0x00000040 +#define ATA_SS_SPD_GEN3 0x00000030 #define ATA_SS_IPM_MASK 0x00000f00 #define ATA_SS_IPM_NO_DEVICE 0x00000000 #define ATA_SS_IPM_ACTIVE 0x00000100 #define ATA_SS_IPM_PARTIAL 0x00000200 #define ATA_SS_IPM_SLUMBER 0x00000600 #define ATA_SS_IPM_DEVSLEEP 0x00000800 #define ATA_SERROR 14 #define ATA_SE_DATA_CORRECTED 0x00000001 #define ATA_SE_COMM_CORRECTED 0x00000002 #define ATA_SE_DATA_ERR 0x00000100 #define ATA_SE_COMM_ERR 0x00000200 #define ATA_SE_PROT_ERR 0x00000400 #define ATA_SE_HOST_ERR 0x00000800 #define ATA_SE_PHY_CHANGED 0x00010000 #define ATA_SE_PHY_IERROR 0x00020000 #define ATA_SE_COMM_WAKE 0x00040000 #define ATA_SE_DECODE_ERR 0x00080000 #define ATA_SE_PARITY_ERR 0x00100000 #define ATA_SE_CRC_ERR 0x00200000 #define ATA_SE_HANDSHAKE_ERR 0x00400000 #define ATA_SE_LINKSEQ_ERR 0x00800000 #define ATA_SE_TRANSPORT_ERR 0x01000000 #define ATA_SE_UNKNOWN_FIS 0x02000000 #define ATA_SE_EXCHANGED 0x04000000 #define ATA_SCONTROL 15 #define ATA_SC_DET_MASK 0x0000000f #define ATA_SC_DET_IDLE 0x00000000 #define ATA_SC_DET_RESET 0x00000001 #define ATA_SC_DET_DISABLE 0x00000004 #define ATA_SC_SPD_MASK 0x000000f0 #define ATA_SC_SPD_NO_SPEED 0x00000000 #define ATA_SC_SPD_SPEED_GEN1 0x00000010 #define ATA_SC_SPD_SPEED_GEN2 0x00000020 -#define ATA_SC_SPD_SPEED_GEN3 0x00000040 +#define ATA_SC_SPD_SPEED_GEN3 0x00000030 #define ATA_SC_IPM_MASK 0x00000f00 #define ATA_SC_IPM_NONE 0x00000000 #define ATA_SC_IPM_DIS_PARTIAL 0x00000100 #define ATA_SC_IPM_DIS_SLUMBER 0x00000200 #define ATA_SC_IPM_DIS_DEVSLEEP 0x00000400 #define ATA_SACTIVE 16 #define AHCI_MAX_PORTS 32 #define AHCI_MAX_SLOTS 32 #define AHCI_MAX_IRQS 16 /* SATA AHCI v1.0 register defines */ #define AHCI_CAP 0x00 #define AHCI_CAP_NPMASK 0x0000001f #define AHCI_CAP_SXS 0x00000020 #define AHCI_CAP_EMS 0x00000040 #define AHCI_CAP_CCCS 0x00000080 #define AHCI_CAP_NCS 0x00001F00 #define AHCI_CAP_NCS_SHIFT 8 #define AHCI_CAP_PSC 0x00002000 #define AHCI_CAP_SSC 0x00004000 #define AHCI_CAP_PMD 0x00008000 #define AHCI_CAP_FBSS 0x00010000 #define AHCI_CAP_SPM 0x00020000 #define AHCI_CAP_SAM 0x00080000 #define AHCI_CAP_ISS 0x00F00000 #define AHCI_CAP_ISS_SHIFT 20 #define AHCI_CAP_SCLO 0x01000000 #define AHCI_CAP_SAL 0x02000000 #define AHCI_CAP_SALP 0x04000000 #define AHCI_CAP_SSS 0x08000000 #define AHCI_CAP_SMPS 0x10000000 #define AHCI_CAP_SSNTF 0x20000000 #define AHCI_CAP_SNCQ 0x40000000 #define AHCI_CAP_64BIT 0x80000000 #define AHCI_GHC 0x04 #define AHCI_GHC_AE 0x80000000 #define AHCI_GHC_MRSM 0x00000004 #define AHCI_GHC_IE 0x00000002 #define AHCI_GHC_HR 0x00000001 #define AHCI_IS 0x08 #define AHCI_PI 0x0c #define AHCI_VS 0x10 #define AHCI_CCCC 0x14 #define AHCI_CCCC_TV_MASK 0xffff0000 #define AHCI_CCCC_TV_SHIFT 16 #define AHCI_CCCC_CC_MASK 0x0000ff00 #define AHCI_CCCC_CC_SHIFT 8 #define AHCI_CCCC_INT_MASK 0x000000f8 #define AHCI_CCCC_INT_SHIFT 3 #define AHCI_CCCC_EN 0x00000001 #define AHCI_CCCP 0x18 #define AHCI_EM_LOC 0x1C #define AHCI_EM_CTL 0x20 #define AHCI_EM_MR 0x00000001 #define AHCI_EM_TM 0x00000100 #define AHCI_EM_RST 0x00000200 #define AHCI_EM_LED 0x00010000 #define AHCI_EM_SAFTE 0x00020000 #define AHCI_EM_SES2 0x00040000 #define AHCI_EM_SGPIO 0x00080000 #define AHCI_EM_SMB 0x01000000 #define AHCI_EM_XMT 0x02000000 #define AHCI_EM_ALHD 0x04000000 #define AHCI_EM_PM 0x08000000 #define AHCI_CAP2 0x24 #define AHCI_CAP2_BOH 0x00000001 #define AHCI_CAP2_NVMP 0x00000002 #define AHCI_CAP2_APST 0x00000004 #define AHCI_CAP2_SDS 0x00000008 #define AHCI_CAP2_SADM 0x00000010 #define AHCI_CAP2_DESO 0x00000020 #define AHCI_OFFSET 0x100 #define AHCI_STEP 0x80 #define AHCI_P_CLB 0x00 #define AHCI_P_CLBU 0x04 #define AHCI_P_FB 0x08 #define AHCI_P_FBU 0x0c #define AHCI_P_IS 0x10 #define AHCI_P_IE 0x14 #define AHCI_P_IX_DHR 0x00000001 #define AHCI_P_IX_PS 0x00000002 #define AHCI_P_IX_DS 0x00000004 #define AHCI_P_IX_SDB 0x00000008 #define AHCI_P_IX_UF 0x00000010 #define AHCI_P_IX_DP 0x00000020 #define AHCI_P_IX_PC 0x00000040 #define AHCI_P_IX_MP 0x00000080 #define AHCI_P_IX_PRC 0x00400000 #define AHCI_P_IX_IPM 0x00800000 #define AHCI_P_IX_OF 0x01000000 #define AHCI_P_IX_INF 0x04000000 #define AHCI_P_IX_IF 0x08000000 #define AHCI_P_IX_HBD 0x10000000 #define AHCI_P_IX_HBF 0x20000000 #define AHCI_P_IX_TFE 0x40000000 #define AHCI_P_IX_CPD 0x80000000 #define AHCI_P_CMD 0x18 #define AHCI_P_CMD_ST 0x00000001 #define AHCI_P_CMD_SUD 0x00000002 #define AHCI_P_CMD_POD 0x00000004 #define AHCI_P_CMD_CLO 0x00000008 #define AHCI_P_CMD_FRE 0x00000010 #define AHCI_P_CMD_CCS_MASK 0x00001f00 #define AHCI_P_CMD_CCS_SHIFT 8 #define AHCI_P_CMD_ISS 0x00002000 #define AHCI_P_CMD_FR 0x00004000 #define AHCI_P_CMD_CR 0x00008000 #define AHCI_P_CMD_CPS 0x00010000 #define AHCI_P_CMD_PMA 0x00020000 #define AHCI_P_CMD_HPCP 0x00040000 #define AHCI_P_CMD_MPSP 0x00080000 #define AHCI_P_CMD_CPD 0x00100000 #define AHCI_P_CMD_ESP 0x00200000 #define AHCI_P_CMD_FBSCP 0x00400000 #define AHCI_P_CMD_APSTE 0x00800000 #define AHCI_P_CMD_ATAPI 0x01000000 #define AHCI_P_CMD_DLAE 0x02000000 #define AHCI_P_CMD_ALPE 0x04000000 #define AHCI_P_CMD_ASP 0x08000000 #define AHCI_P_CMD_ICC_MASK 0xf0000000 #define AHCI_P_CMD_NOOP 0x00000000 #define AHCI_P_CMD_ACTIVE 0x10000000 #define AHCI_P_CMD_PARTIAL 0x20000000 #define AHCI_P_CMD_SLUMBER 0x60000000 #define AHCI_P_CMD_DEVSLEEP 0x80000000 #define AHCI_P_TFD 0x20 #define AHCI_P_SIG 0x24 #define AHCI_P_SSTS 0x28 #define AHCI_P_SCTL 0x2c #define AHCI_P_SERR 0x30 #define AHCI_P_SACT 0x34 #define AHCI_P_CI 0x38 #define AHCI_P_SNTF 0x3C #define AHCI_P_FBS 0x40 #define AHCI_P_FBS_EN 0x00000001 #define AHCI_P_FBS_DEC 0x00000002 #define AHCI_P_FBS_SDE 0x00000004 #define AHCI_P_FBS_DEV 0x00000f00 #define AHCI_P_FBS_DEV_SHIFT 8 #define AHCI_P_FBS_ADO 0x0000f000 #define AHCI_P_FBS_ADO_SHIFT 12 #define AHCI_P_FBS_DWE 0x000f0000 #define AHCI_P_FBS_DWE_SHIFT 16 #define AHCI_P_DEVSLP 0x44 #define AHCI_P_DEVSLP_ADSE 0x00000001 #define AHCI_P_DEVSLP_DSP 0x00000002 #define AHCI_P_DEVSLP_DETO 0x000003fc #define AHCI_P_DEVSLP_DETO_SHIFT 2 #define AHCI_P_DEVSLP_MDAT 0x00007c00 #define AHCI_P_DEVSLP_MDAT_SHIFT 10 #define AHCI_P_DEVSLP_DITO 0x01ff8000 #define AHCI_P_DEVSLP_DITO_SHIFT 15 #define AHCI_P_DEVSLP_DM 0x0e000000 #define AHCI_P_DEVSLP_DM_SHIFT 25 /* Just to be sure, if building as module. */ #if MAXPHYS < 512 * 1024 #undef MAXPHYS #define MAXPHYS 512 * 1024 #endif /* Pessimistic prognosis on number of required S/G entries */ #define AHCI_SG_ENTRIES (roundup(btoc(MAXPHYS) + 1, 8)) /* Command list. 32 commands. First, 1Kbyte aligned. */ #define AHCI_CL_OFFSET 0 #define AHCI_CL_SIZE 32 /* Command tables. Up to 32 commands, Each, 128byte aligned. */ #define AHCI_CT_OFFSET (AHCI_CL_OFFSET + AHCI_CL_SIZE * AHCI_MAX_SLOTS) #define AHCI_CT_SIZE (128 + AHCI_SG_ENTRIES * 16) /* Total main work area. */ #define AHCI_WORK_SIZE (AHCI_CT_OFFSET + AHCI_CT_SIZE * ch->numslots) struct ahci_dma_prd { u_int64_t dba; u_int32_t reserved; u_int32_t dbc; /* 0 based */ #define AHCI_PRD_MASK 0x003fffff /* max 4MB */ #define AHCI_PRD_MAX (AHCI_PRD_MASK + 1) #define AHCI_PRD_IPC (1U << 31) } __packed; struct ahci_cmd_tab { u_int8_t cfis[64]; u_int8_t acmd[32]; u_int8_t reserved[32]; struct ahci_dma_prd prd_tab[AHCI_SG_ENTRIES]; } __packed; struct ahci_cmd_list { u_int16_t cmd_flags; #define AHCI_CMD_ATAPI 0x0020 #define AHCI_CMD_WRITE 0x0040 #define AHCI_CMD_PREFETCH 0x0080 #define AHCI_CMD_RESET 0x0100 #define AHCI_CMD_BIST 0x0200 #define AHCI_CMD_CLR_BUSY 0x0400 u_int16_t prd_length; /* PRD entries */ u_int32_t bytecount; u_int64_t cmd_table_phys; /* 128byte aligned */ } __packed; /* misc defines */ #define ATA_IRQ_RID 0 #define ATA_INTR_FLAGS (INTR_MPSAFE|INTR_TYPE_BIO|INTR_ENTROPY) struct ata_dmaslot { bus_dmamap_t data_map; /* data DMA map */ int nsegs; /* Number of segs loaded */ }; /* structure holding DMA related information */ struct ata_dma { bus_dma_tag_t work_tag; /* workspace DMA tag */ bus_dmamap_t work_map; /* workspace DMA map */ uint8_t *work; /* workspace */ bus_addr_t work_bus; /* bus address of work */ bus_dma_tag_t rfis_tag; /* RFIS list DMA tag */ bus_dmamap_t rfis_map; /* RFIS list DMA map */ uint8_t *rfis; /* FIS receive area */ bus_addr_t rfis_bus; /* bus address of rfis */ bus_dma_tag_t data_tag; /* data DMA tag */ }; enum ahci_slot_states { AHCI_SLOT_EMPTY, AHCI_SLOT_LOADING, AHCI_SLOT_RUNNING, AHCI_SLOT_EXECUTING }; struct ahci_slot { struct ahci_channel *ch; /* Channel */ u_int8_t slot; /* Number of this slot */ enum ahci_slot_states state; /* Slot state */ union ccb *ccb; /* CCB occupying slot */ struct ata_dmaslot dma; /* DMA data of this slot */ struct callout timeout; /* Execution timeout */ }; struct ahci_device { int revision; int mode; u_int bytecount; u_int atapi; u_int tags; u_int caps; }; struct ahci_led { device_t dev; /* Device handle */ struct cdev *led; uint8_t num; /* Number of this led */ uint8_t state; /* State of this led */ }; #define AHCI_NUM_LEDS 3 /* structure describing an ATA channel */ struct ahci_channel { device_t dev; /* Device handle */ int unit; /* Physical channel */ struct resource *r_mem; /* Memory of this channel */ struct resource *r_irq; /* Interrupt of this channel */ void *ih; /* Interrupt handle */ struct ata_dma dma; /* DMA data */ struct cam_sim *sim; struct cam_path *path; uint32_t caps; /* Controller capabilities */ uint32_t caps2; /* Controller capabilities */ uint32_t chcaps; /* Channel capabilities */ uint32_t chscaps; /* Channel sleep capabilities */ uint16_t vendorid; /* Vendor ID from the bus */ uint16_t deviceid; /* Device ID from the bus */ uint16_t subvendorid; /* Subvendor ID from the bus */ uint16_t subdeviceid; /* Subdevice ID from the bus */ int quirks; int numslots; /* Number of present slots */ int pm_level; /* power management level */ int devices; /* What is present */ int pm_present; /* PM presence reported */ int fbs_enabled; /* FIS-based switching enabled */ union ccb *hold[AHCI_MAX_SLOTS]; struct ahci_slot slot[AHCI_MAX_SLOTS]; uint32_t oslots; /* Occupied slots */ uint32_t rslots; /* Running slots */ uint32_t aslots; /* Slots with atomic commands */ uint32_t eslots; /* Slots in error */ uint32_t toslots; /* Slots in timeout */ int lastslot; /* Last used slot */ int taggedtarget; /* Last tagged target */ int numrslots; /* Number of running slots */ int numrslotspd[16];/* Number of running slots per dev */ int numtslots; /* Number of tagged slots */ int numtslotspd[16];/* Number of tagged slots per dev */ int numhslots; /* Number of held slots */ int recoverycmd; /* Our READ LOG active */ int fatalerr; /* Fatal error happend */ int resetting; /* Hard-reset in progress. */ int resetpolldiv; /* Hard-reset poll divider. */ int listening; /* SUD bit is cleared. */ int wrongccs; /* CCS field in CMD was wrong */ union ccb *frozen; /* Frozen command */ struct callout pm_timer; /* Power management events */ struct callout reset_timer; /* Hard-reset timeout */ struct ahci_device user[16]; /* User-specified settings */ struct ahci_device curr[16]; /* Current settings */ struct mtx_padalign mtx; /* state lock */ STAILQ_HEAD(, ccb_hdr) doneq; /* queue of completed CCBs */ int batch; /* doneq is in use */ }; struct ahci_enclosure { device_t dev; /* Device handle */ struct resource *r_memc; /* Control register */ struct resource *r_memt; /* Transmit buffer */ struct resource *r_memr; /* Recieve buffer */ struct cam_sim *sim; struct cam_path *path; struct mtx mtx; /* state lock */ struct ahci_led leds[AHCI_MAX_PORTS * 3]; uint32_t capsem; /* Controller capabilities */ uint8_t status[AHCI_MAX_PORTS][4]; /* ArrayDev statuses */ int quirks; int channels; int ichannels; }; /* structure describing a AHCI controller */ struct ahci_controller { device_t dev; bus_dma_tag_t dma_tag; int r_rid; uint16_t vendorid; /* Vendor ID from the bus */ uint16_t deviceid; /* Device ID from the bus */ uint16_t subvendorid; /* Subvendor ID from the bus */ uint16_t subdeviceid; /* Subdevice ID from the bus */ struct resource *r_mem; struct rman sc_iomem; struct ahci_controller_irq { struct ahci_controller *ctlr; struct resource *r_irq; void *handle; int r_irq_rid; int mode; #define AHCI_IRQ_MODE_ALL 0 #define AHCI_IRQ_MODE_AFTER 1 #define AHCI_IRQ_MODE_ONE 2 } irqs[AHCI_MAX_IRQS]; uint32_t caps; /* Controller capabilities */ uint32_t caps2; /* Controller capabilities */ uint32_t capsem; /* Controller capabilities */ uint32_t emloc; /* EM buffer location */ int quirks; int numirqs; int channels; int ichannels; int ccc; /* CCC timeout */ int cccv; /* CCC vector */ int direct; /* Direct command completion */ int msi; /* MSI interupts */ struct { void (*function)(void *); void *argument; } interrupt[AHCI_MAX_PORTS]; }; enum ahci_err_type { AHCI_ERR_NONE, /* No error */ AHCI_ERR_INVALID, /* Error detected by us before submitting. */ AHCI_ERR_INNOCENT, /* Innocent victim. */ AHCI_ERR_TFE, /* Task File Error. */ AHCI_ERR_SATA, /* SATA error. */ AHCI_ERR_TIMEOUT, /* Command execution timeout. */ AHCI_ERR_NCQ, /* NCQ command error. CCB should be put on hold * until READ LOG executed to reveal error. */ }; /* macros to hide busspace uglyness */ #define ATA_INB(res, offset) \ bus_read_1((res), (offset)) #define ATA_INW(res, offset) \ bus_read_2((res), (offset)) #define ATA_INL(res, offset) \ bus_read_4((res), (offset)) #define ATA_INSW(res, offset, addr, count) \ bus_read_multi_2((res), (offset), (addr), (count)) #define ATA_INSW_STRM(res, offset, addr, count) \ bus_read_multi_stream_2((res), (offset), (addr), (count)) #define ATA_INSL(res, offset, addr, count) \ bus_read_multi_4((res), (offset), (addr), (count)) #define ATA_INSL_STRM(res, offset, addr, count) \ bus_read_multi_stream_4((res), (offset), (addr), (count)) #define ATA_OUTB(res, offset, value) \ bus_write_1((res), (offset), (value)) #define ATA_OUTW(res, offset, value) \ bus_write_2((res), (offset), (value)) #define ATA_OUTL(res, offset, value) \ bus_write_4((res), (offset), (value)) #define ATA_OUTSW(res, offset, addr, count) \ bus_write_multi_2((res), (offset), (addr), (count)) #define ATA_OUTSW_STRM(res, offset, addr, count) \ bus_write_multi_stream_2((res), (offset), (addr), (count)) #define ATA_OUTSL(res, offset, addr, count) \ bus_write_multi_4((res), (offset), (addr), (count)) #define ATA_OUTSL_STRM(res, offset, addr, count) \ bus_write_multi_stream_4((res), (offset), (addr), (count)) #define AHCI_Q_NOFORCE 0x00000001 #define AHCI_Q_NOPMP 0x00000002 #define AHCI_Q_NONCQ 0x00000004 #define AHCI_Q_1CH 0x00000008 #define AHCI_Q_2CH 0x00000010 #define AHCI_Q_4CH 0x00000020 #define AHCI_Q_EDGEIS 0x00000040 #define AHCI_Q_SATA2 0x00000080 #define AHCI_Q_NOBSYRES 0x00000100 #define AHCI_Q_NOAA 0x00000200 #define AHCI_Q_NOCOUNT 0x00000400 #define AHCI_Q_ALTSIG 0x00000800 #define AHCI_Q_NOMSI 0x00001000 #define AHCI_Q_ATI_PMP_BUG 0x00002000 #define AHCI_Q_MAXIO_64K 0x00004000 #define AHCI_Q_SATA1_UNIT0 0x00008000 /* need better method for this */ #define AHCI_Q_ABAR0 0x00010000 #define AHCI_Q_1MSI 0x00020000 #define AHCI_Q_BIT_STRING \ "\021" \ "\001NOFORCE" \ "\002NOPMP" \ "\003NONCQ" \ "\0041CH" \ "\0052CH" \ "\0064CH" \ "\007EDGEIS" \ "\010SATA2" \ "\011NOBSYRES" \ "\012NOAA" \ "\013NOCOUNT" \ "\014ALTSIG" \ "\015NOMSI" \ "\016ATI_PMP_BUG" \ "\017MAXIO_64K" \ "\020SATA1_UNIT0" \ "\021ABAR0" \ "\0221MSI" int ahci_attach(device_t dev); int ahci_detach(device_t dev); int ahci_setup_interrupt(device_t dev); int ahci_print_child(device_t dev, device_t child); struct resource *ahci_alloc_resource(device_t dev, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags); int ahci_release_resource(device_t dev, device_t child, int type, int rid, struct resource *r); int ahci_setup_intr(device_t dev, device_t child, struct resource *irq, int flags, driver_filter_t *filter, driver_intr_t *function, void *argument, void **cookiep); int ahci_teardown_intr(device_t dev, device_t child, struct resource *irq, void *cookie); int ahci_child_location_str(device_t dev, device_t child, char *buf, size_t buflen); bus_dma_tag_t ahci_get_dma_tag(device_t dev, device_t child); int ahci_ctlr_reset(device_t dev); int ahci_ctlr_setup(device_t dev); Index: head/sys/dev/ata/ata-all.h =================================================================== --- head/sys/dev/ata/ata-all.h (revision 279962) +++ head/sys/dev/ata/ata-all.h (revision 279963) @@ -1,736 +1,737 @@ /*- * Copyright (c) 1998 - 2008 Søren Schmidt * All rights reserved. * * 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, * without modification, immediately at the beginning of the file. * 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. * * 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$ */ #if 0 #define ATA_LEGACY_SUPPORT /* Enable obsolete features that break * some modern devices */ #endif /* ATA register defines */ #define ATA_DATA 0 /* (RW) data */ #define ATA_FEATURE 1 /* (W) feature */ #define ATA_F_DMA 0x01 /* enable DMA */ #define ATA_F_OVL 0x02 /* enable overlap */ #define ATA_COUNT 2 /* (W) sector count */ #define ATA_SECTOR 3 /* (RW) sector # */ #define ATA_CYL_LSB 4 /* (RW) cylinder# LSB */ #define ATA_CYL_MSB 5 /* (RW) cylinder# MSB */ #define ATA_DRIVE 6 /* (W) Sector/Drive/Head */ #define ATA_D_LBA 0x40 /* use LBA addressing */ #define ATA_D_IBM 0xa0 /* 512 byte sectors, ECC */ #define ATA_COMMAND 7 /* (W) command */ #define ATA_ERROR 8 /* (R) error */ #define ATA_E_ILI 0x01 /* illegal length */ #define ATA_E_NM 0x02 /* no media */ #define ATA_E_ABORT 0x04 /* command aborted */ #define ATA_E_MCR 0x08 /* media change request */ #define ATA_E_IDNF 0x10 /* ID not found */ #define ATA_E_MC 0x20 /* media changed */ #define ATA_E_UNC 0x40 /* uncorrectable data */ #define ATA_E_ICRC 0x80 /* UDMA crc error */ #define ATA_E_ATAPI_SENSE_MASK 0xf0 /* ATAPI sense key mask */ #define ATA_IREASON 9 /* (R) interrupt reason */ #define ATA_I_CMD 0x01 /* cmd (1) | data (0) */ #define ATA_I_IN 0x02 /* read (1) | write (0) */ #define ATA_I_RELEASE 0x04 /* released bus (1) */ #define ATA_I_TAGMASK 0xf8 /* tag mask */ #define ATA_STATUS 10 /* (R) status */ #define ATA_ALTSTAT 11 /* (R) alternate status */ #define ATA_S_ERROR 0x01 /* error */ #define ATA_S_INDEX 0x02 /* index */ #define ATA_S_CORR 0x04 /* data corrected */ #define ATA_S_DRQ 0x08 /* data request */ #define ATA_S_DSC 0x10 /* drive seek completed */ #define ATA_S_SERVICE 0x10 /* drive needs service */ #define ATA_S_DWF 0x20 /* drive write fault */ #define ATA_S_DMA 0x20 /* DMA ready */ #define ATA_S_READY 0x40 /* drive ready */ #define ATA_S_BUSY 0x80 /* busy */ #define ATA_CONTROL 12 /* (W) control */ #define ATA_CTLOFFSET 0x206 /* control register offset */ #define ATA_PCCARD_CTLOFFSET 0x0e /* do for PCCARD devices */ #define ATA_PC98_CTLOFFSET 0x10c /* do for PC98 devices */ #define ATA_A_IDS 0x02 /* disable interrupts */ #define ATA_A_RESET 0x04 /* RESET controller */ #ifdef ATA_LEGACY_SUPPORT #define ATA_A_4BIT 0x08 /* 4 head bits: obsolete 1996 */ #else #define ATA_A_4BIT 0x00 #endif #define ATA_A_HOB 0x80 /* High Order Byte enable */ /* SATA register defines */ #define ATA_SSTATUS 13 #define ATA_SS_DET_MASK 0x0000000f #define ATA_SS_DET_NO_DEVICE 0x00000000 #define ATA_SS_DET_DEV_PRESENT 0x00000001 #define ATA_SS_DET_PHY_ONLINE 0x00000003 #define ATA_SS_DET_PHY_OFFLINE 0x00000004 #define ATA_SS_SPD_MASK 0x000000f0 #define ATA_SS_SPD_NO_SPEED 0x00000000 #define ATA_SS_SPD_GEN1 0x00000010 #define ATA_SS_SPD_GEN2 0x00000020 +#define ATA_SS_SPD_GEN3 0x00000030 #define ATA_SS_IPM_MASK 0x00000f00 #define ATA_SS_IPM_NO_DEVICE 0x00000000 #define ATA_SS_IPM_ACTIVE 0x00000100 #define ATA_SS_IPM_PARTIAL 0x00000200 #define ATA_SS_IPM_SLUMBER 0x00000600 #define ATA_SERROR 14 #define ATA_SE_DATA_CORRECTED 0x00000001 #define ATA_SE_COMM_CORRECTED 0x00000002 #define ATA_SE_DATA_ERR 0x00000100 #define ATA_SE_COMM_ERR 0x00000200 #define ATA_SE_PROT_ERR 0x00000400 #define ATA_SE_HOST_ERR 0x00000800 #define ATA_SE_PHY_CHANGED 0x00010000 #define ATA_SE_PHY_IERROR 0x00020000 #define ATA_SE_COMM_WAKE 0x00040000 #define ATA_SE_DECODE_ERR 0x00080000 #define ATA_SE_PARITY_ERR 0x00100000 #define ATA_SE_CRC_ERR 0x00200000 #define ATA_SE_HANDSHAKE_ERR 0x00400000 #define ATA_SE_LINKSEQ_ERR 0x00800000 #define ATA_SE_TRANSPORT_ERR 0x01000000 #define ATA_SE_UNKNOWN_FIS 0x02000000 #define ATA_SCONTROL 15 #define ATA_SC_DET_MASK 0x0000000f #define ATA_SC_DET_IDLE 0x00000000 #define ATA_SC_DET_RESET 0x00000001 #define ATA_SC_DET_DISABLE 0x00000004 #define ATA_SC_SPD_MASK 0x000000f0 #define ATA_SC_SPD_NO_SPEED 0x00000000 #define ATA_SC_SPD_SPEED_GEN1 0x00000010 #define ATA_SC_SPD_SPEED_GEN2 0x00000020 -#define ATA_SC_SPD_SPEED_GEN3 0x00000040 +#define ATA_SC_SPD_SPEED_GEN3 0x00000030 #define ATA_SC_IPM_MASK 0x00000f00 #define ATA_SC_IPM_NONE 0x00000000 #define ATA_SC_IPM_DIS_PARTIAL 0x00000100 #define ATA_SC_IPM_DIS_SLUMBER 0x00000200 #define ATA_SACTIVE 16 /* SATA AHCI v1.0 register defines */ #define ATA_AHCI_CAP 0x00 #define ATA_AHCI_CAP_NPMASK 0x0000001f #define ATA_AHCI_CAP_SXS 0x00000020 #define ATA_AHCI_CAP_EMS 0x00000040 #define ATA_AHCI_CAP_CCCS 0x00000080 #define ATA_AHCI_CAP_NCS 0x00001F00 #define ATA_AHCI_CAP_NCS_SHIFT 8 #define ATA_AHCI_CAP_PSC 0x00002000 #define ATA_AHCI_CAP_SSC 0x00004000 #define ATA_AHCI_CAP_PMD 0x00008000 #define ATA_AHCI_CAP_FBSS 0x00010000 #define ATA_AHCI_CAP_SPM 0x00020000 #define ATA_AHCI_CAP_SAM 0x00080000 #define ATA_AHCI_CAP_ISS 0x00F00000 #define ATA_AHCI_CAP_ISS_SHIFT 20 #define ATA_AHCI_CAP_SCLO 0x01000000 #define ATA_AHCI_CAP_SAL 0x02000000 #define ATA_AHCI_CAP_SALP 0x04000000 #define ATA_AHCI_CAP_SSS 0x08000000 #define ATA_AHCI_CAP_SMPS 0x10000000 #define ATA_AHCI_CAP_SSNTF 0x20000000 #define ATA_AHCI_CAP_SNCQ 0x40000000 #define ATA_AHCI_CAP_64BIT 0x80000000 #define ATA_AHCI_GHC 0x04 #define ATA_AHCI_GHC_AE 0x80000000 #define ATA_AHCI_GHC_IE 0x00000002 #define ATA_AHCI_GHC_HR 0x00000001 #define ATA_AHCI_IS 0x08 #define ATA_AHCI_PI 0x0c #define ATA_AHCI_VS 0x10 #define ATA_AHCI_OFFSET 0x80 #define ATA_AHCI_P_CLB 0x100 #define ATA_AHCI_P_CLBU 0x104 #define ATA_AHCI_P_FB 0x108 #define ATA_AHCI_P_FBU 0x10c #define ATA_AHCI_P_IS 0x110 #define ATA_AHCI_P_IE 0x114 #define ATA_AHCI_P_IX_DHR 0x00000001 #define ATA_AHCI_P_IX_PS 0x00000002 #define ATA_AHCI_P_IX_DS 0x00000004 #define ATA_AHCI_P_IX_SDB 0x00000008 #define ATA_AHCI_P_IX_UF 0x00000010 #define ATA_AHCI_P_IX_DP 0x00000020 #define ATA_AHCI_P_IX_PC 0x00000040 #define ATA_AHCI_P_IX_DI 0x00000080 #define ATA_AHCI_P_IX_PRC 0x00400000 #define ATA_AHCI_P_IX_IPM 0x00800000 #define ATA_AHCI_P_IX_OF 0x01000000 #define ATA_AHCI_P_IX_INF 0x04000000 #define ATA_AHCI_P_IX_IF 0x08000000 #define ATA_AHCI_P_IX_HBD 0x10000000 #define ATA_AHCI_P_IX_HBF 0x20000000 #define ATA_AHCI_P_IX_TFE 0x40000000 #define ATA_AHCI_P_IX_CPD 0x80000000 #define ATA_AHCI_P_CMD 0x118 #define ATA_AHCI_P_CMD_ST 0x00000001 #define ATA_AHCI_P_CMD_SUD 0x00000002 #define ATA_AHCI_P_CMD_POD 0x00000004 #define ATA_AHCI_P_CMD_CLO 0x00000008 #define ATA_AHCI_P_CMD_FRE 0x00000010 #define ATA_AHCI_P_CMD_CCS_MASK 0x00001f00 #define ATA_AHCI_P_CMD_ISS 0x00002000 #define ATA_AHCI_P_CMD_FR 0x00004000 #define ATA_AHCI_P_CMD_CR 0x00008000 #define ATA_AHCI_P_CMD_CPS 0x00010000 #define ATA_AHCI_P_CMD_PMA 0x00020000 #define ATA_AHCI_P_CMD_HPCP 0x00040000 #define ATA_AHCI_P_CMD_ISP 0x00080000 #define ATA_AHCI_P_CMD_CPD 0x00100000 #define ATA_AHCI_P_CMD_ATAPI 0x01000000 #define ATA_AHCI_P_CMD_DLAE 0x02000000 #define ATA_AHCI_P_CMD_ALPE 0x04000000 #define ATA_AHCI_P_CMD_ASP 0x08000000 #define ATA_AHCI_P_CMD_ICC_MASK 0xf0000000 #define ATA_AHCI_P_CMD_NOOP 0x00000000 #define ATA_AHCI_P_CMD_ACTIVE 0x10000000 #define ATA_AHCI_P_CMD_PARTIAL 0x20000000 #define ATA_AHCI_P_CMD_SLUMBER 0x60000000 #define ATA_AHCI_P_TFD 0x120 #define ATA_AHCI_P_SIG 0x124 #define ATA_AHCI_P_SSTS 0x128 #define ATA_AHCI_P_SCTL 0x12c #define ATA_AHCI_P_SERR 0x130 #define ATA_AHCI_P_SACT 0x134 #define ATA_AHCI_P_CI 0x138 #define ATA_AHCI_P_SNTF 0x13C #define ATA_AHCI_P_FBS 0x140 #define ATA_AHCI_CL_SIZE 32 #define ATA_AHCI_CL_OFFSET 0 #define ATA_AHCI_FB_OFFSET (ATA_AHCI_CL_SIZE * 32) #define ATA_AHCI_CT_OFFSET (ATA_AHCI_FB_OFFSET + 4096) #define ATA_AHCI_CT_SIZE (2176 + 128) struct ata_ahci_dma_prd { u_int64_t dba; u_int32_t reserved; u_int32_t dbc; /* 0 based */ #define ATA_AHCI_PRD_MASK 0x003fffff /* max 4MB */ #define ATA_AHCI_PRD_IPC (1<<31) } __packed; struct ata_ahci_cmd_tab { u_int8_t cfis[64]; u_int8_t acmd[32]; u_int8_t reserved[32]; #define ATA_AHCI_DMA_ENTRIES 129 struct ata_ahci_dma_prd prd_tab[ATA_AHCI_DMA_ENTRIES]; } __packed; struct ata_ahci_cmd_list { u_int16_t cmd_flags; #define ATA_AHCI_CMD_ATAPI 0x0020 #define ATA_AHCI_CMD_WRITE 0x0040 #define ATA_AHCI_CMD_PREFETCH 0x0080 #define ATA_AHCI_CMD_RESET 0x0100 #define ATA_AHCI_CMD_BIST 0x0200 #define ATA_AHCI_CMD_CLR_BUSY 0x0400 u_int16_t prd_length; /* PRD entries */ u_int32_t bytecount; u_int64_t cmd_table_phys; /* 128byte aligned */ } __packed; /* DMA register defines */ #define ATA_DMA_ENTRIES 256 #define ATA_DMA_EOT 0x80000000 #define ATA_BMCMD_PORT 17 #define ATA_BMCMD_START_STOP 0x01 #define ATA_BMCMD_WRITE_READ 0x08 #define ATA_BMDEVSPEC_0 18 #define ATA_BMSTAT_PORT 19 #define ATA_BMSTAT_ACTIVE 0x01 #define ATA_BMSTAT_ERROR 0x02 #define ATA_BMSTAT_INTERRUPT 0x04 #define ATA_BMSTAT_MASK 0x07 #define ATA_BMSTAT_DMA_MASTER 0x20 #define ATA_BMSTAT_DMA_SLAVE 0x40 #define ATA_BMSTAT_DMA_SIMPLEX 0x80 #define ATA_BMDEVSPEC_1 20 #define ATA_BMDTP_PORT 21 #define ATA_IDX_ADDR 22 #define ATA_IDX_DATA 23 #define ATA_MAX_RES 24 /* misc defines */ #define ATA_PRIMARY 0x1f0 #define ATA_SECONDARY 0x170 #define ATA_PC98_BANK 0x432 #define ATA_IOSIZE 0x08 #define ATA_PC98_IOSIZE 0x10 #define ATA_CTLIOSIZE 0x01 #define ATA_BMIOSIZE 0x08 #define ATA_PC98_BANKIOSIZE 0x01 #define ATA_IOADDR_RID 0 #define ATA_CTLADDR_RID 1 #define ATA_BMADDR_RID 0x20 #define ATA_PC98_CTLADDR_RID 8 #define ATA_PC98_BANKADDR_RID 9 #define ATA_IRQ_RID 0 #define ATA_DEV(unit) ((unit > 0) ? 0x10 : 0) #define ATA_CFA_MAGIC1 0x844A #define ATA_CFA_MAGIC2 0x848A #define ATA_CFA_MAGIC3 0x8400 #define ATAPI_MAGIC_LSB 0x14 #define ATAPI_MAGIC_MSB 0xeb #define ATAPI_P_READ (ATA_S_DRQ | ATA_I_IN) #define ATAPI_P_WRITE (ATA_S_DRQ) #define ATAPI_P_CMDOUT (ATA_S_DRQ | ATA_I_CMD) #define ATAPI_P_DONEDRQ (ATA_S_DRQ | ATA_I_CMD | ATA_I_IN) #define ATAPI_P_DONE (ATA_I_CMD | ATA_I_IN) #define ATAPI_P_ABORT 0 #define ATA_INTR_FLAGS (INTR_MPSAFE|INTR_TYPE_BIO|INTR_ENTROPY) #define ATA_OP_CONTINUES 0 #define ATA_OP_FINISHED 1 #define ATA_MAX_28BIT_LBA 268435455UL #ifndef ATA_REQUEST_TIMEOUT #define ATA_REQUEST_TIMEOUT 10 #endif /* structure used for composite atomic operations */ #define MAX_COMPOSITES 32 /* u_int32_t bits */ struct ata_composite { struct mtx lock; /* control lock */ u_int32_t rd_needed; /* needed read subdisks */ u_int32_t rd_done; /* done read subdisks */ u_int32_t wr_needed; /* needed write subdisks */ u_int32_t wr_depend; /* write depends on subdisks */ u_int32_t wr_done; /* done write subdisks */ struct ata_request *request[MAX_COMPOSITES]; u_int32_t residual; /* bytes still to transfer */ caddr_t data_1; caddr_t data_2; }; /* structure used to queue an ATA/ATAPI request */ struct ata_request { device_t dev; /* device handle */ device_t parent; /* channel handle */ int unit; /* physical unit */ union { struct { u_int8_t command; /* command reg */ u_int16_t feature; /* feature reg */ u_int16_t count; /* count reg */ u_int64_t lba; /* lba reg */ } ata; struct { u_int8_t ccb[16]; /* ATAPI command block */ struct atapi_sense sense; /* ATAPI request sense data */ u_int8_t saved_cmd; /* ATAPI saved command */ } atapi; } u; u_int32_t bytecount; /* bytes to transfer */ u_int32_t transfersize; /* bytes pr transfer */ caddr_t data; /* pointer to data buf */ u_int32_t tag; /* HW tag of this request */ int flags; #define ATA_R_CONTROL 0x00000001 #define ATA_R_READ 0x00000002 #define ATA_R_WRITE 0x00000004 #define ATA_R_ATAPI 0x00000008 #define ATA_R_DMA 0x00000010 #define ATA_R_QUIET 0x00000020 #define ATA_R_TIMEOUT 0x00000040 #define ATA_R_48BIT 0x00000080 #define ATA_R_ORDERED 0x00000100 #define ATA_R_AT_HEAD 0x00000200 #define ATA_R_REQUEUE 0x00000400 #define ATA_R_THREAD 0x00000800 #define ATA_R_DIRECT 0x00001000 #define ATA_R_NEEDRESULT 0x00002000 #define ATA_R_DATA_IN_CCB 0x00004000 #define ATA_R_ATAPI16 0x00010000 #define ATA_R_ATAPI_INTR 0x00020000 #define ATA_R_DEBUG 0x10000000 #define ATA_R_DANGER1 0x20000000 #define ATA_R_DANGER2 0x40000000 struct ata_dmaslot *dma; /* DMA slot of this request */ u_int8_t status; /* ATA status */ u_int8_t error; /* ATA error */ u_int32_t donecount; /* bytes transferred */ int result; /* result error code */ void (*callback)(struct ata_request *request); struct sema done; /* request done sema */ int retries; /* retry count */ int timeout; /* timeout for this cmd */ struct callout callout; /* callout management */ struct task task; /* task management */ struct bio *bio; /* bio for this request */ int this; /* this request ID */ struct ata_composite *composite; /* for composite atomic ops */ void *driver; /* driver specific */ TAILQ_ENTRY(ata_request) chain; /* list management */ union ccb *ccb; }; /* define this for debugging request processing */ #if 0 #define ATA_DEBUG_RQ(request, string) \ { \ if (request->flags & ATA_R_DEBUG) \ device_printf(request->parent, "req=%p %s " string "\n", \ request, ata_cmd2str(request)); \ } #else #define ATA_DEBUG_RQ(request, string) #endif /* structure describing an ATA/ATAPI device */ struct ata_device { device_t dev; /* device handle */ int unit; /* physical unit */ #define ATA_MASTER 0x00 #define ATA_SLAVE 0x01 #define ATA_PM 0x0f struct ata_params param; /* ata param structure */ int mode; /* current transfermode */ u_int32_t max_iosize; /* max IO size */ int spindown; /* idle spindown timeout */ struct callout spindown_timer; int spindown_state; int flags; #define ATA_D_USE_CHS 0x0001 #define ATA_D_MEDIA_CHANGED 0x0002 #define ATA_D_ENC_PRESENT 0x0004 }; /* structure for holding DMA Physical Region Descriptors (PRD) entries */ struct ata_dma_prdentry { u_int32_t addr; u_int32_t count; }; /* structure used by the setprd function */ struct ata_dmasetprd_args { void *dmatab; int nsegs; int error; }; struct ata_dmaslot { u_int8_t status; /* DMA status */ bus_dma_tag_t sg_tag; /* SG list DMA tag */ bus_dmamap_t sg_map; /* SG list DMA map */ void *sg; /* DMA transfer table */ bus_addr_t sg_bus; /* bus address of dmatab */ bus_dma_tag_t data_tag; /* data DMA tag */ bus_dmamap_t data_map; /* data DMA map */ }; /* structure holding DMA related information */ struct ata_dma { bus_dma_tag_t dmatag; /* parent DMA tag */ bus_dma_tag_t work_tag; /* workspace DMA tag */ bus_dmamap_t work_map; /* workspace DMA map */ u_int8_t *work; /* workspace */ bus_addr_t work_bus; /* bus address of dmatab */ #define ATA_DMA_SLOTS 1 int dma_slots; /* DMA slots allocated */ struct ata_dmaslot slot[ATA_DMA_SLOTS]; u_int32_t alignment; /* DMA SG list alignment */ u_int32_t boundary; /* DMA SG list boundary */ u_int32_t segsize; /* DMA SG list segment size */ u_int32_t max_iosize; /* DMA data max IO size */ u_int64_t max_address; /* highest DMA'able address */ int flags; #define ATA_DMA_ACTIVE 0x01 /* DMA transfer in progress */ void (*alloc)(device_t dev); void (*free)(device_t dev); void (*setprd)(void *xsc, bus_dma_segment_t *segs, int nsegs, int error); int (*load)(struct ata_request *request, void *addr, int *nsegs); int (*unload)(struct ata_request *request); int (*start)(struct ata_request *request); int (*stop)(struct ata_request *request); void (*reset)(device_t dev); }; /* structure holding lowlevel functions */ struct ata_lowlevel { u_int32_t (*softreset)(device_t dev, int pmport); int (*pm_read)(device_t dev, int port, int reg, u_int32_t *result); int (*pm_write)(device_t dev, int port, int reg, u_int32_t value); int (*status)(device_t dev); int (*begin_transaction)(struct ata_request *request); int (*end_transaction)(struct ata_request *request); int (*command)(struct ata_request *request); void (*tf_read)(struct ata_request *request); void (*tf_write)(struct ata_request *request); }; /* structure holding resources for an ATA channel */ struct ata_resource { struct resource *res; int offset; }; struct ata_cam_device { u_int revision; int mode; u_int bytecount; u_int atapi; u_int caps; }; /* structure describing an ATA channel */ struct ata_channel { device_t dev; /* device handle */ int unit; /* physical channel */ int attached; /* channel is attached */ struct ata_resource r_io[ATA_MAX_RES];/* I/O resources */ struct resource *r_irq; /* interrupt of this channel */ void *ih; /* interrupt handle */ struct ata_lowlevel hw; /* lowlevel HW functions */ struct ata_dma dma; /* DMA data / functions */ int flags; /* channel flags */ #define ATA_NO_SLAVE 0x01 #define ATA_USE_16BIT 0x02 #define ATA_ATAPI_DMA_RO 0x04 #define ATA_NO_48BIT_DMA 0x08 #define ATA_ALWAYS_DMASTAT 0x10 #define ATA_CHECKS_CABLE 0x20 #define ATA_NO_ATAPI_DMA 0x40 #define ATA_SATA 0x80 #define ATA_DMA_BEFORE_CMD 0x100 #define ATA_KNOWN_PRESENCE 0x200 #define ATA_STATUS_IS_LONG 0x400 #define ATA_PERIODIC_POLL 0x800 int pm_level; /* power management level */ int devices; /* what is present */ #define ATA_ATA_MASTER 0x00000001 #define ATA_ATA_SLAVE 0x00000002 #define ATA_PORTMULTIPLIER 0x00008000 #define ATA_ATAPI_MASTER 0x00010000 #define ATA_ATAPI_SLAVE 0x00020000 struct mtx state_mtx; /* state lock */ int state; /* ATA channel state */ #define ATA_IDLE 0x0000 #define ATA_ACTIVE 0x0001 #define ATA_STALL_QUEUE 0x0002 struct ata_request *running; /* currently running request */ struct task conntask; /* PHY events handling task */ struct cam_sim *sim; struct cam_path *path; struct ata_cam_device user[16]; /* User-specified settings */ struct ata_cam_device curr[16]; /* Current settings */ int requestsense; /* CCB waiting for SENSE. */ struct callout poll_callout; /* Periodic status poll. */ }; /* disk bay/enclosure related */ #define ATA_LED_OFF 0x00 #define ATA_LED_RED 0x01 #define ATA_LED_GREEN 0x02 #define ATA_LED_ORANGE 0x03 #define ATA_LED_MASK 0x03 /* externs */ extern int (*ata_raid_ioctl_func)(u_long cmd, caddr_t data); extern struct intr_config_hook *ata_delayed_attach; extern devclass_t ata_devclass; extern int ata_wc; extern int ata_setmax; extern int ata_dma_check_80pin; /* public prototypes */ /* ata-all.c: */ int ata_probe(device_t dev); int ata_attach(device_t dev); int ata_detach(device_t dev); int ata_reinit(device_t dev); int ata_suspend(device_t dev); int ata_resume(device_t dev); void ata_interrupt(void *data); int ata_getparam(struct ata_device *atadev, int init); void ata_default_registers(device_t dev); void ata_udelay(int interval); const char *ata_cmd2str(struct ata_request *request); const char *ata_mode2str(int mode); void ata_setmode(device_t dev); void ata_print_cable(device_t dev, u_int8_t *who); int ata_atapi(device_t dev, int target); void ata_timeout(struct ata_request *); /* ata-lowlevel.c: */ void ata_generic_hw(device_t dev); int ata_begin_transaction(struct ata_request *); int ata_end_transaction(struct ata_request *); void ata_generic_reset(device_t dev); int ata_generic_command(struct ata_request *request); /* ata-dma.c: */ void ata_dmainit(device_t); void ata_dmafini(device_t dev); /* ata-sata.c: */ void ata_sata_phy_check_events(device_t dev, int port); int ata_sata_scr_read(struct ata_channel *ch, int port, int reg, uint32_t *val); int ata_sata_scr_write(struct ata_channel *ch, int port, int reg, uint32_t val); int ata_sata_phy_reset(device_t dev, int port, int quick); int ata_sata_setmode(device_t dev, int target, int mode); int ata_sata_getrev(device_t dev, int target); int ata_request2fis_h2d(struct ata_request *request, u_int8_t *fis); void ata_pm_identify(device_t dev); /* macros for alloc/free of struct ata_request */ extern uma_zone_t ata_request_zone; #define ata_alloc_request() uma_zalloc(ata_request_zone, M_NOWAIT | M_ZERO) #define ata_free_request(request) { \ if (!(request->flags & ATA_R_DANGER2)) \ uma_zfree(ata_request_zone, request); \ } MALLOC_DECLARE(M_ATA); /* misc newbus defines */ #define GRANDPARENT(dev) device_get_parent(device_get_parent(dev)) /* macros to hide busspace uglyness */ #define ATA_INB(res, offset) \ bus_read_1((res), (offset)) #define ATA_INW(res, offset) \ bus_read_2((res), (offset)) #define ATA_INW_STRM(res, offset) \ bus_read_stream_2((res), (offset)) #define ATA_INL(res, offset) \ bus_read_4((res), (offset)) #define ATA_INSW(res, offset, addr, count) \ bus_read_multi_2((res), (offset), (addr), (count)) #define ATA_INSW_STRM(res, offset, addr, count) \ bus_read_multi_stream_2((res), (offset), (addr), (count)) #define ATA_INSL(res, offset, addr, count) \ bus_read_multi_4((res), (offset), (addr), (count)) #define ATA_INSL_STRM(res, offset, addr, count) \ bus_read_multi_stream_4((res), (offset), (addr), (count)) #define ATA_OUTB(res, offset, value) \ bus_write_1((res), (offset), (value)) #define ATA_OUTW(res, offset, value) \ bus_write_2((res), (offset), (value)) #define ATA_OUTW_STRM(res, offset, value) \ bus_write_stream_2((res), (offset), (value)) #define ATA_OUTL(res, offset, value) \ bus_write_4((res), (offset), (value)) #define ATA_OUTSW(res, offset, addr, count) \ bus_write_multi_2((res), (offset), (addr), (count)) #define ATA_OUTSW_STRM(res, offset, addr, count) \ bus_write_multi_stream_2((res), (offset), (addr), (count)) #define ATA_OUTSL(res, offset, addr, count) \ bus_write_multi_4((res), (offset), (addr), (count)) #define ATA_OUTSL_STRM(res, offset, addr, count) \ bus_write_multi_stream_4((res), (offset), (addr), (count)) #define ATA_IDX_INB(ch, idx) \ ATA_INB(ch->r_io[idx].res, ch->r_io[idx].offset) #define ATA_IDX_INW(ch, idx) \ ATA_INW(ch->r_io[idx].res, ch->r_io[idx].offset) #define ATA_IDX_INW_STRM(ch, idx) \ ATA_INW_STRM(ch->r_io[idx].res, ch->r_io[idx].offset) #define ATA_IDX_INL(ch, idx) \ ATA_INL(ch->r_io[idx].res, ch->r_io[idx].offset) #define ATA_IDX_INSW(ch, idx, addr, count) \ ATA_INSW(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) #define ATA_IDX_INSW_STRM(ch, idx, addr, count) \ ATA_INSW_STRM(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) #define ATA_IDX_INSL(ch, idx, addr, count) \ ATA_INSL(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) #define ATA_IDX_INSL_STRM(ch, idx, addr, count) \ ATA_INSL_STRM(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) #define ATA_IDX_OUTB(ch, idx, value) \ ATA_OUTB(ch->r_io[idx].res, ch->r_io[idx].offset, value) #define ATA_IDX_OUTW(ch, idx, value) \ ATA_OUTW(ch->r_io[idx].res, ch->r_io[idx].offset, value) #define ATA_IDX_OUTW_STRM(ch, idx, value) \ ATA_OUTW_STRM(ch->r_io[idx].res, ch->r_io[idx].offset, value) #define ATA_IDX_OUTL(ch, idx, value) \ ATA_OUTL(ch->r_io[idx].res, ch->r_io[idx].offset, value) #define ATA_IDX_OUTSW(ch, idx, addr, count) \ ATA_OUTSW(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) #define ATA_IDX_OUTSW_STRM(ch, idx, addr, count) \ ATA_OUTSW_STRM(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) #define ATA_IDX_OUTSL(ch, idx, addr, count) \ ATA_OUTSL(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) #define ATA_IDX_OUTSL_STRM(ch, idx, addr, count) \ ATA_OUTSL_STRM(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) Index: head/sys/dev/mvs/mvs.h =================================================================== --- head/sys/dev/mvs/mvs.h (revision 279962) +++ head/sys/dev/mvs/mvs.h (revision 279963) @@ -1,661 +1,661 @@ /*- * Copyright (c) 2010 Alexander Motin * All rights reserved. * * 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, * without modification, immediately at the beginning of the file. * 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. * * 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$ */ #include "mvs_if.h" /* Chip registers */ #define CHIP_PCIEIC 0x1900 /* PCIe Interrupt Cause */ #define CHIP_PCIEIM 0x1910 /* PCIe Interrupt Mask */ #define CHIP_PCIIC 0x1d58 /* PCI Interrupt Cause */ #define CHIP_PCIIM 0x1d5c /* PCI Interrupt Mask */ #define CHIP_MIC 0x1d60 /* Main Interrupt Cause */ #define CHIP_MIM 0x1d64 /* Main Interrupt Mask */ #define CHIP_SOC_MIC 0x20 /* SoC Main Interrupt Cause */ #define CHIP_SOC_MIM 0x24 /* SoC Main Interrupt Mask */ #define IC_ERR_IRQ (1 << 0) /* shift by (2 * port #) */ #define IC_DONE_IRQ (1 << 1) /* shift by (2 * port #) */ #define IC_HC0 0x000001ff /* bits 0-8 = HC0 */ #define IC_HC_SHIFT 9 /* HC1 shift */ #define IC_HC1 (IC_HC0 << IC_HC_SHIFT) /* 9-17 = HC1 */ #define IC_ERR_HC0 0x00000055 /* HC0 ERR_IRQ */ #define IC_DONE_HC0 0x000000aa /* HC0 DONE_IRQ */ #define IC_ERR_HC1 (IC_ERR_HC0 << IC_HC_SHIFT) /* HC1 ERR_IRQ */ #define IC_DONE_HC1 (IC_DONE_HC0 << IC_HC_SHIFT) /* HC1 DONE_IRQ */ #define IC_HC0_COAL_DONE (1 << 8) /* HC0 IRQ coalescing */ #define IC_HC1_COAL_DONE (1 << 17) /* HC1 IRQ coalescing */ #define IC_PCI_ERR (1 << 18) #define IC_TRAN_COAL_LO_DONE (1 << 19) /* transaction coalescing */ #define IC_TRAN_COAL_HI_DONE (1 << 20) /* transaction coalescing */ #define IC_ALL_PORTS_COAL_DONE (1 << 21) /* GEN_II(E) IRQ coalescing */ #define IC_GPIO_INT (1 << 22) #define IC_SELF_INT (1 << 23) #define IC_TWSI_INT (1 << 24) #define IC_MAIN_RSVD (0xfe000000) /* bits 31-25 */ #define IC_MAIN_RSVD_5 (0xfff10000) /* bits 31-19 */ #define IC_MAIN_RSVD_SOC (0xfffffec0) /* bits 31-9, 7-6 */ #define CHIP_SOC_LED 0x2C /* SoC LED Configuration */ /* Additional mask for SoC devices with less than 4 channels */ #define CHIP_SOC_HC0_MASK(num) (0xff >> ((4 - (num)) * 2)) /* Chip CCC registers */ #define CHIP_ICC 0x18008 #define CHIP_ICC_ALL_PORTS (1 << 4) /* all ports irq event */ #define CHIP_ICT 0x180cc #define CHIP_ITT 0x180d0 #define CHIP_TRAN_COAL_CAUSE_LO 0x18088 #define CHIP_TRAN_COAL_CAUSE_HI 0x1808c /* Host Controller registers */ #define HC_SIZE 0x10000 #define HC_OFFSET 0x20000 #define HC_BASE(hc) ((hc) * HC_SIZE + HC_OFFSET) #define HC_CFG 0x0 /* Configuration */ #define HC_CFG_TIMEOUT_MASK (0xff << 0) #define HC_CFG_NODMABS (1 << 8) #define HC_CFG_NOEDMABS (1 << 9) #define HC_CFG_NOPRDBS (1 << 10) #define HC_CFG_TIMEOUTEN (1 << 16) /* Timer Enable */ #define HC_CFG_COALDIS(p) (1 << ((p) + 24))/* Coalescing Disable*/ #define HC_RQOP 0x4 /* Request Queue Out-Pointer */ #define HC_RQIP 0x8 /* Response Queue In-Pointer */ #define HC_ICT 0xc /* Interrupt Coalescing Threshold */ #define HC_ICT_SAICOALT_MASK 0x000000ff #define HC_ITT 0x10 /* Interrupt Time Threshold */ #define HC_ITT_SAITMTH_MASK 0x00ffffff #define HC_IC 0x14 /* Interrupt Cause */ #define HC_IC_DONE(p) (1 << (p)) /* SaCrpb/DMA Done */ #define HC_IC_COAL (1 << 4) /* Intr Coalescing */ #define HC_IC_DEV(p) (1 << ((p) + 8)) /* Device Intr */ /* Port registers */ #define PORT_SIZE 0x2000 #define PORT_OFFSET 0x2000 #define PORT_BASE(hc) ((hc) * PORT_SIZE + PORT_OFFSET) #define EDMA_CFG 0x0 /* Configuration */ #define EDMA_CFG_RESERVED (0x1f << 0) /* Queue len ? */ #define EDMA_CFG_ESATANATVCMDQUE (1 << 5) #define EDMA_CFG_ERDBSZ (1 << 8) #define EDMA_CFG_EQUE (1 << 9) #define EDMA_CFG_ERDBSZEXT (1 << 11) #define EDMA_CFG_RESERVED2 (1 << 12) #define EDMA_CFG_EWRBUFFERLEN (1 << 13) #define EDMA_CFG_EDEVERR (1 << 14) #define EDMA_CFG_EEDMAFBS (1 << 16) #define EDMA_CFG_ECUTTHROUGHEN (1 << 17) #define EDMA_CFG_EEARLYCOMPLETIONEN (1 << 18) #define EDMA_CFG_EEDMAQUELEN (1 << 19) #define EDMA_CFG_EHOSTQUEUECACHEEN (1 << 22) #define EDMA_CFG_EMASKRXPM (1 << 23) #define EDMA_CFG_RESUMEDIS (1 << 24) #define EDMA_CFG_EDMAFBS (1 << 26) #define EDMA_T 0x4 /* Timer */ #define EDMA_IEC 0x8 /* Interrupt Error Cause */ #define EDMA_IEM 0xc /* Interrupt Error Mask */ #define EDMA_IE_EDEVERR (1 << 2) /* EDMA Device Error */ #define EDMA_IE_EDEVDIS (1 << 3) /* EDMA Dev Disconn */ #define EDMA_IE_EDEVCON (1 << 4) /* EDMA Dev Conn */ #define EDMA_IE_SERRINT (1 << 5) #define EDMA_IE_ESELFDIS (1 << 7) /* EDMA Self Disable */ #define EDMA_IE_ETRANSINT (1 << 8) /* Transport Layer */ #define EDMA_IE_EIORDYERR (1 << 12) /* EDMA IORdy Error */ #define EDMA_IE_LINKXERR_SATACRC (1 << 0) /* SATA CRC error */ #define EDMA_IE_LINKXERR_INTERNALFIFO (1 << 1) /* internal FIFO err */ #define EDMA_IE_LINKXERR_LINKLAYERRESET (1 << 2) /* Link Layer is reset by the reception of SYNC primitive from device */ #define EDMA_IE_LINKXERR_OTHERERRORS (1 << 3) /* * Link state errors, coding errors, or running disparity errors occur * during FIS reception. */ #define EDMA_IE_LINKTXERR_FISTXABORTED (1 << 4) /* FIS Tx is aborted */ #define EDMA_IE_LINKCTLRXERR(x) ((x) << 13) /* Link Ctrl Recv Err */ #define EDMA_IE_LINKDATARXERR(x) ((x) << 17) /* Link Data Recv Err */ #define EDMA_IE_LINKCTLTXERR(x) ((x) << 21) /* Link Ctrl Tx Error */ #define EDMA_IE_LINKDATATXERR(x) ((x) << 26) /* Link Data Tx Error */ #define EDMA_IE_TRANSPROTERR (1U << 31) /* Transport Proto E */ #define EDMA_IE_TRANSIENT (EDMA_IE_LINKCTLRXERR(0x0b) | \ EDMA_IE_LINKCTLTXERR(0x1f)) /* Non-fatal Errors */ #define EDMA_REQQBAH 0x10 /* Request Queue Base Address High */ #define EDMA_REQQIP 0x14 /* Request Queue In-Pointer */ #define EDMA_REQQOP 0x18 /* Request Queue Out-Pointer */ #define EDMA_REQQP_ERQQP_SHIFT 5 #define EDMA_REQQP_ERQQP_MASK 0x000003e0 #define EDMA_REQQP_ERQQBAP_MASK 0x00000c00 #define EDMA_REQQP_ERQQBA_MASK 0xfffff000 #define EDMA_RESQBAH 0x1c /* Response Queue Base Address High */ #define EDMA_RESQIP 0x20 /* Response Queue In-Pointer */ #define EDMA_RESQOP 0x24 /* Response Queue Out-Pointer */ #define EDMA_RESQP_ERPQP_SHIFT 3 #define EDMA_RESQP_ERPQP_MASK 0x000000f8 #define EDMA_RESQP_ERPQBAP_MASK 0x00000300 #define EDMA_RESQP_ERPQBA_MASK 0xfffffc00 #define EDMA_CMD 0x28 /* Command */ #define EDMA_CMD_EENEDMA (1 << 0) /* Enable EDMA */ #define EDMA_CMD_EDSEDMA (1 << 1) /* Disable EDMA */ #define EDMA_CMD_EATARST (1 << 2) /* ATA Device Reset */ #define EDMA_CMD_EEDMAFRZ (1 << 4) /* EDMA Freeze */ #define EDMA_TC 0x2c /* Test Control */ #define EDMA_S 0x30 /* Status */ #define EDMA_S_EDEVQUETAG(s) ((s) & 0x0000001f) #define EDMA_S_EDEVDIR_WRITE (0 << 5) #define EDMA_S_EDEVDIR_READ (1 << 5) #define EDMA_S_ECACHEEMPTY (1 << 6) #define EDMA_S_EDMAIDLE (1 << 7) #define EDMA_S_ESTATE(s) (((s) & 0x0000ff00) >> 8) #define EDMA_S_EIOID(s) (((s) & 0x003f0000) >> 16) #define EDMA_IORT 0x34 /* IORdy Timeout */ #define EDMA_CDT 0x40 /* Command Delay Threshold */ #define EDMA_HC 0x60 /* Halt Condition */ #define EDMA_UNKN_RESD 0x6C /* Unknown register */ #define EDMA_CQDCQOS(x) (0x90 + ((x) << 2) /* NCQ Done/TCQ Outstanding Status */ /* ATA register defines */ #define ATA_DATA 0x100 /* (RW) data */ #define ATA_FEATURE 0x104 /* (W) feature */ #define ATA_F_DMA 0x01 /* enable DMA */ #define ATA_F_OVL 0x02 /* enable overlap */ #define ATA_ERROR 0x104 /* (R) error */ #define ATA_E_ILI 0x01 /* illegal length */ #define ATA_E_NM 0x02 /* no media */ #define ATA_E_ABORT 0x04 /* command aborted */ #define ATA_E_MCR 0x08 /* media change request */ #define ATA_E_IDNF 0x10 /* ID not found */ #define ATA_E_MC 0x20 /* media changed */ #define ATA_E_UNC 0x40 /* uncorrectable data */ #define ATA_E_ICRC 0x80 /* UDMA crc error */ #define ATA_E_ATAPI_SENSE_MASK 0xf0 /* ATAPI sense key mask */ #define ATA_COUNT 0x108 /* (W) sector count */ #define ATA_IREASON 0x108 /* (R) interrupt reason */ #define ATA_I_CMD 0x01 /* cmd (1) | data (0) */ #define ATA_I_IN 0x02 /* read (1) | write (0) */ #define ATA_I_RELEASE 0x04 /* released bus (1) */ #define ATA_I_TAGMASK 0xf8 /* tag mask */ #define ATA_SECTOR 0x10c /* (RW) sector # */ #define ATA_CYL_LSB 0x110 /* (RW) cylinder# LSB */ #define ATA_CYL_MSB 0x114 /* (RW) cylinder# MSB */ #define ATA_DRIVE 0x118 /* (W) Sector/Drive/Head */ #define ATA_D_LBA 0x40 /* use LBA addressing */ #define ATA_D_IBM 0xa0 /* 512 byte sectors, ECC */ #define ATA_COMMAND 0x11c /* (W) command */ #define ATA_STATUS 0x11c /* (R) status */ #define ATA_S_ERROR 0x01 /* error */ #define ATA_S_INDEX 0x02 /* index */ #define ATA_S_CORR 0x04 /* data corrected */ #define ATA_S_DRQ 0x08 /* data request */ #define ATA_S_DSC 0x10 /* drive seek completed */ #define ATA_S_SERVICE 0x10 /* drive needs service */ #define ATA_S_DWF 0x20 /* drive write fault */ #define ATA_S_DMA 0x20 /* DMA ready */ #define ATA_S_READY 0x40 /* drive ready */ #define ATA_S_BUSY 0x80 /* busy */ #define ATA_CONTROL 0x120 /* (W) control */ #define ATA_A_IDS 0x02 /* disable interrupts */ #define ATA_A_RESET 0x04 /* RESET controller */ #define ATA_A_4BIT 0x08 /* 4 head bits */ #define ATA_A_HOB 0x80 /* High Order Byte enable */ #define ATA_ALTSTAT 0x120 /* (R) alternate status */ #define ATAPI_P_READ (ATA_S_DRQ | ATA_I_IN) #define ATAPI_P_WRITE (ATA_S_DRQ) #define ATAPI_P_CMDOUT (ATA_S_DRQ | ATA_I_CMD) #define ATAPI_P_DONEDRQ (ATA_S_DRQ | ATA_I_CMD | ATA_I_IN) #define ATAPI_P_DONE (ATA_I_CMD | ATA_I_IN) #define ATAPI_P_ABORT 0 /* Basic DMA Registers */ #define DMA_C 0x224 /* Basic DMA Command */ #define DMA_C_START (1 << 0) #define DMA_C_READ (1 << 3) #define DMA_C_DREGIONVALID (1 << 8) #define DMA_C_DREGIONLAST (1 << 9) #define DMA_C_CONTFROMPREV (1 << 10) #define DMA_C_DRBC(n) (((n) & 0xffff) << 16) #define DMA_S 0x228 /* Basic DMA Status */ #define DMA_S_ACT (1 << 0) /* Active */ #define DMA_S_ERR (1 << 1) /* Error */ #define DMA_S_PAUSED (1 << 2) /* Paused */ #define DMA_S_LAST (1 << 3) /* Last */ #define DMA_DTLBA 0x22c /* Descriptor Table Low Base Address */ #define DMA_DTLBA_MASK 0xfffffff0 #define DMA_DTHBA 0x230 /* Descriptor Table High Base Address */ #define DMA_DRLA 0x234 /* Data Region Low Address */ #define DMA_DRHA 0x238 /* Data Region High Address */ /* Serial-ATA Registers */ #define SATA_SS 0x300 /* SStatus */ #define SATA_SS_DET_MASK 0x0000000f #define SATA_SS_DET_NO_DEVICE 0x00000000 #define SATA_SS_DET_DEV_PRESENT 0x00000001 #define SATA_SS_DET_PHY_ONLINE 0x00000003 #define SATA_SS_DET_PHY_OFFLINE 0x00000004 #define SATA_SS_SPD_MASK 0x000000f0 #define SATA_SS_SPD_NO_SPEED 0x00000000 #define SATA_SS_SPD_GEN1 0x00000010 #define SATA_SS_SPD_GEN2 0x00000020 -#define SATA_SS_SPD_GEN3 0x00000040 +#define SATA_SS_SPD_GEN3 0x00000030 #define SATA_SS_IPM_MASK 0x00000f00 #define SATA_SS_IPM_NO_DEVICE 0x00000000 #define SATA_SS_IPM_ACTIVE 0x00000100 #define SATA_SS_IPM_PARTIAL 0x00000200 #define SATA_SS_IPM_SLUMBER 0x00000600 #define SATA_SE 0x304 /* SError */ #define SATA_SEIM 0x340 /* SError Interrupt Mask */ #define SATA_SE_DATA_CORRECTED 0x00000001 #define SATA_SE_COMM_CORRECTED 0x00000002 #define SATA_SE_DATA_ERR 0x00000100 #define SATA_SE_COMM_ERR 0x00000200 #define SATA_SE_PROT_ERR 0x00000400 #define SATA_SE_HOST_ERR 0x00000800 #define SATA_SE_PHY_CHANGED 0x00010000 #define SATA_SE_PHY_IERROR 0x00020000 #define SATA_SE_COMM_WAKE 0x00040000 #define SATA_SE_DECODE_ERR 0x00080000 #define SATA_SE_PARITY_ERR 0x00100000 #define SATA_SE_CRC_ERR 0x00200000 #define SATA_SE_HANDSHAKE_ERR 0x00400000 #define SATA_SE_LINKSEQ_ERR 0x00800000 #define SATA_SE_TRANSPORT_ERR 0x01000000 #define SATA_SE_UNKNOWN_FIS 0x02000000 #define SATA_SC 0x308 /* SControl */ #define SATA_SC_DET_MASK 0x0000000f #define SATA_SC_DET_IDLE 0x00000000 #define SATA_SC_DET_RESET 0x00000001 #define SATA_SC_DET_DISABLE 0x00000004 #define SATA_SC_SPD_MASK 0x000000f0 #define SATA_SC_SPD_NO_SPEED 0x00000000 #define SATA_SC_SPD_SPEED_GEN1 0x00000010 #define SATA_SC_SPD_SPEED_GEN2 0x00000020 -#define SATA_SC_SPD_SPEED_GEN3 0x00000040 +#define SATA_SC_SPD_SPEED_GEN3 0x00000030 #define SATA_SC_IPM_MASK 0x00000f00 #define SATA_SC_IPM_NONE 0x00000000 #define SATA_SC_IPM_DIS_PARTIAL 0x00000100 #define SATA_SC_IPM_DIS_SLUMBER 0x00000200 #define SATA_SC_SPM_MASK 0x0000f000 #define SATA_SC_SPM_NONE 0x00000000 #define SATA_SC_SPM_PARTIAL 0x00001000 #define SATA_SC_SPM_SLUMBER 0x00002000 #define SATA_SC_SPM_ACTIVE 0x00004000 #define SATA_LTM 0x30c /* LTMode */ #define SATA_PHYM3 0x310 /* PHY Mode 3 */ #define SATA_PHYM4 0x314 /* PHY Mode 4 */ #define SATA_PHYM1 0x32c /* PHY Mode 1 */ #define SATA_PHYM2 0x330 /* PHY Mode 2 */ #define SATA_BISTC 0x334 /* BIST Control */ #define SATA_BISTDW1 0x338 /* BIST DW1 */ #define SATA_BISTDW2 0x33c /* BIST DW2 */ #define SATA_SATAICFG 0x050 /* Serial-ATA Interface Configuration */ #define SATA_SATAICFG_REFCLKCNF_20MHZ (0 << 0) #define SATA_SATAICFG_REFCLKCNF_25MHZ (1 << 0) #define SATA_SATAICFG_REFCLKCNF_30MHZ (2 << 0) #define SATA_SATAICFG_REFCLKCNF_40MHZ (3 << 0) #define SATA_SATAICFG_REFCLKCNF_MASK (3 << 0) #define SATA_SATAICFG_REFCLKDIV_1 (0 << 2) #define SATA_SATAICFG_REFCLKDIV_2 (1 << 2) /* Used 20 or 25MHz */ #define SATA_SATAICFG_REFCLKDIV_4 (2 << 2) /* Used 40MHz */ #define SATA_SATAICFG_REFCLKDIV_3 (3 << 2) /* Used 30MHz */ #define SATA_SATAICFG_REFCLKDIV_MASK (3 << 2) #define SATA_SATAICFG_REFCLKFEEDDIV_50 (0 << 4) /* or 100, when Gen2En is 1 */ #define SATA_SATAICFG_REFCLKFEEDDIV_60 (1 << 4) /* or 120. Used 25MHz */ #define SATA_SATAICFG_REFCLKFEEDDIV_75 (2 << 4) /* or 150. Used 20MHz */ #define SATA_SATAICFG_REFCLKFEEDDIV_90 (3 << 4) /* or 180 */ #define SATA_SATAICFG_REFCLKFEEDDIV_MASK (3 << 4) #define SATA_SATAICFG_PHYSSCEN (1 << 6) #define SATA_SATAICFG_GEN2EN (1 << 7) #define SATA_SATAICFG_COMMEN (1 << 8) #define SATA_SATAICFG_PHYSHUTDOWN (1 << 9) #define SATA_SATAICFG_TARGETMODE (1 << 10) /* 1 = Initiator */ #define SATA_SATAICFG_COMCHANNEL (1 << 11) #define SATA_SATAICFG_IGNOREBSY (1 << 24) #define SATA_SATAICFG_LINKRSTEN (1 << 25) #define SATA_SATAICFG_CMDRETXDS (1 << 26) #define SATA_SATAICTL 0x344 /* Serial-ATA Interface Control */ #define SATA_SATAICTL_PMPTX_MASK 0x0000000f #define SATA_SATAICTL_PMPTX_SHIFT 0 #define SATA_SATAICTL_VUM (1 << 8) #define SATA_SATAICTL_VUS (1 << 9) #define SATA_SATAICTL_EDMAACT (1 << 16) #define SATA_SATAICTL_CLEARSTAT (1 << 24) #define SATA_SATAICTL_SRST (1 << 25) #define SATA_SATAITC 0x348 /* Serial-ATA Interface Test Control */ #define SATA_SATAIS 0x34c /* Serial-ATA Interface Status */ #define SATA_VU 0x35c /* Vendor Unique */ #define SATA_FISC 0x360 /* FIS Configuration */ #define SATA_FISC_FISWAIT4RDYEN_B0 (1 << 0) /* Device to Host FIS */ #define SATA_FISC_FISWAIT4RDYEN_B1 (1 << 1) /* SDB FIS rcv with bit 0 */ #define SATA_FISC_FISWAIT4RDYEN_B2 (1 << 2) /* DMA Activate FIS */ #define SATA_FISC_FISWAIT4RDYEN_B3 (1 << 3) /* DMA Setup FIS */ #define SATA_FISC_FISWAIT4RDYEN_B4 (1 << 4) /* Data FIS first DW */ #define SATA_FISC_FISWAIT4RDYEN_B5 (1 << 5) /* Data FIS entire FIS */ #define SATA_FISC_FISWAIT4HOSTRDYEN_B0 (1 << 8) /* Device to Host FIS with or */ #define SATA_FISC_FISWAIT4HOSTRDYEN_B1 (1 << 9) /* SDB FIS rcv with bit */ #define SATA_FISC_FISWAIT4HOSTRDYEN_B2 (1 << 10) /* SDB FIS rcv with */ #define SATA_FISC_FISWAIT4HOSTRDYEN_B3 (1 << 11) /* BIST Acivate FIS */ #define SATA_FISC_FISWAIT4HOSTRDYEN_B4 (1 << 12) /* PIO Setup FIS */ #define SATA_FISC_FISWAIT4HOSTRDYEN_B5 (1 << 13) /* Data FIS with Link error */ #define SATA_FISC_FISWAIT4HOSTRDYEN_B6 (1 << 14) /* Unrecognized FIS type */ #define SATA_FISC_FISWAIT4HOSTRDYEN_B7 (1 << 15) /* Any FIS */ #define SATA_FISC_FISDMAACTIVATESYNCRESP (1 << 16) #define SATA_FISC_FISUNRECTYPECONT (1 << 17) #define SATA_FISIC 0x364 /* FIS Interrupt Cause */ #define SATA_FISIM 0x368 /* FIS Interrupt Mask */ #define SATA_FISDW0 0x370 /* FIS DW0 */ #define SATA_FISDW1 0x374 /* FIS DW1 */ #define SATA_FISDW2 0x378 /* FIS DW2 */ #define SATA_FISDW3 0x37c /* FIS DW3 */ #define SATA_FISDW4 0x380 /* FIS DW4 */ #define SATA_FISDW5 0x384 /* FIS DW5 */ #define SATA_FISDW6 0x388 /* FIS DW6 */ #define SATA_PHYM9_GEN2 0x398 #define SATA_PHYM9_GEN1 0x39c #define SATA_PHYCFG_OFS 0x3a0 /* 65nm SoCs only */ #define MVS_MAX_PORTS 8 #define MVS_MAX_SLOTS 32 /* Pessimistic prognosis on number of required S/G entries */ #define MVS_SG_ENTRIES (btoc(MAXPHYS) + 1) /* EDMA Command Request Block (CRQB) Data */ struct mvs_crqb { uint32_t cprdbl; /* cPRD Desriptor Table Base Low Address */ uint32_t cprdbh; /* cPRD Desriptor Table Base High Address */ uint16_t ctrlflg; /* Control Flags */ #define MVS_CRQB_READ 0x0001 #define MVS_CRQB_TAG_MASK 0x003e #define MVS_CRQB_TAG_SHIFT 1 #define MVS_CRQB_PMP_MASK 0xf000 #define MVS_CRQB_PMP_SHIFT 12 uint8_t cmd[22]; } __packed; struct mvs_crqb_gen2e { uint32_t cprdbl; /* cPRD Desriptor Table Base Low Address */ uint32_t cprdbh; /* cPRD Desriptor Table Base High Address */ uint32_t ctrlflg; /* Control Flags */ #define MVS_CRQB2E_READ 0x00000001 #define MVS_CRQB2E_DTAG_MASK 0x0000003e #define MVS_CRQB2E_DTAG_SHIFT 1 #define MVS_CRQB2E_PMP_MASK 0x0000f000 #define MVS_CRQB2E_PMP_SHIFT 12 #define MVS_CRQB2E_CPRD 0x00010000 #define MVS_CRQB2E_HTAG_MASK 0x003e0000 #define MVS_CRQB2E_HTAG_SHIFT 17 uint32_t drbc; /* Data Region Byte Count */ uint8_t cmd[16]; } __packed; /* EDMA Phisical Region Descriptors (ePRD) Table Data Structure */ struct mvs_eprd { uint32_t prdbal; /* Address bits[31:1] */ uint32_t bytecount; /* Byte Count */ #define MVS_EPRD_MASK 0x0000ffff /* max 64KB */ #define MVS_EPRD_MAX (MVS_EPRD_MASK + 1) #define MVS_EPRD_EOF 0x80000000 uint32_t prdbah; /* Address bits[63:32] */ uint32_t resv; } __packed; /* Command request blocks. 32 commands. First 1Kbyte aligned. */ #define MVS_CRQB_OFFSET 0 #define MVS_CRQB_SIZE 32 /* sizeof(struct mvs_crqb) */ #define MVS_CRQB_MASK 0x000003e0 #define MVS_CRQB_SHIFT 5 #define MVS_CRQB_TO_ADDR(slot) ((slot) << MVS_CRQB_SHIFT) #define MVS_ADDR_TO_CRQB(addr) (((addr) & MVS_CRQB_MASK) >> MVS_CRQB_SHIFT) /* ePRD blocks. Up to 32 commands, Each 16byte aligned. */ #define MVS_EPRD_OFFSET (MVS_CRQB_OFFSET + MVS_CRQB_SIZE * MVS_MAX_SLOTS) #define MVS_EPRD_SIZE (MVS_SG_ENTRIES * 16) /* sizeof(struct mvs_eprd) */ /* Request work area. */ #define MVS_WORKRQ_SIZE (MVS_EPRD_OFFSET + MVS_EPRD_SIZE * MVS_MAX_SLOTS) /* EDMA Command Response Block (CRPB) Data */ struct mvs_crpb { uint16_t id; /* CRPB ID */ #define MVS_CRPB_TAG_MASK 0x001F #define MVS_CRPB_TAG_SHIFT 0 uint16_t rspflg; /* CPRB Response Flags */ #define MVS_CRPB_EDMASTS_MASK 0x007F #define MVS_CRPB_EDMASTS_SHIFT 0 #define MVS_CRPB_ATASTS_MASK 0xFF00 #define MVS_CRPB_ATASTS_SHIFT 8 uint32_t ts; /* CPRB Time Stamp */ } __packed; /* Command response blocks. 32 commands. First 256byte aligned. */ #define MVS_CRPB_OFFSET 0 #define MVS_CRPB_SIZE sizeof(struct mvs_crpb) #define MVS_CRPB_MASK 0x000000f8 #define MVS_CRPB_SHIFT 3 #define MVS_CRPB_TO_ADDR(slot) ((slot) << MVS_CRPB_SHIFT) #define MVS_ADDR_TO_CRPB(addr) (((addr) & MVS_CRPB_MASK) >> MVS_CRPB_SHIFT) /* Request work area. */ #define MVS_WORKRP_SIZE (MVS_CRPB_OFFSET + MVS_CRPB_SIZE * MVS_MAX_SLOTS) /* misc defines */ #define ATA_IRQ_RID 0 #define ATA_INTR_FLAGS (INTR_MPSAFE|INTR_TYPE_BIO|INTR_ENTROPY) struct ata_dmaslot { bus_dmamap_t data_map; /* Data DMA map */ bus_addr_t addr; /* Data address */ uint16_t len; /* Data size */ }; /* structure holding DMA related information */ struct mvs_dma { bus_dma_tag_t workrq_tag; /* Request workspace DMA tag */ bus_dmamap_t workrq_map; /* Request workspace DMA map */ uint8_t *workrq; /* Request workspace */ bus_addr_t workrq_bus; /* Request bus address */ bus_dma_tag_t workrp_tag; /* Reply workspace DMA tag */ bus_dmamap_t workrp_map; /* Reply workspace DMA map */ uint8_t *workrp; /* Reply workspace */ bus_addr_t workrp_bus; /* Reply bus address */ bus_dma_tag_t data_tag; /* Data DMA tag */ }; enum mvs_slot_states { MVS_SLOT_EMPTY, MVS_SLOT_LOADING, MVS_SLOT_RUNNING, MVS_SLOT_EXECUTING }; struct mvs_slot { device_t dev; /* Device handle */ int slot; /* Number of this slot */ int tag; /* Used command tag */ enum mvs_slot_states state; /* Slot state */ union ccb *ccb; /* CCB occupying slot */ struct ata_dmaslot dma; /* DMA data of this slot */ struct callout timeout; /* Execution timeout */ }; struct mvs_device { int revision; int mode; u_int bytecount; u_int atapi; u_int tags; u_int caps; }; enum mvs_edma_mode { MVS_EDMA_UNKNOWN, MVS_EDMA_OFF, MVS_EDMA_ON, MVS_EDMA_QUEUED, MVS_EDMA_NCQ, }; /* structure describing an ATA channel */ struct mvs_channel { device_t dev; /* Device handle */ int unit; /* Physical channel */ struct resource *r_mem; /* Memory of this channel */ struct resource *r_irq; /* Interrupt of this channel */ void *ih; /* Interrupt handle */ struct mvs_dma dma; /* DMA data */ struct cam_sim *sim; struct cam_path *path; int quirks; #define MVS_Q_GENI 1 #define MVS_Q_GENII 2 #define MVS_Q_GENIIE 4 #define MVS_Q_SOC 8 #define MVS_Q_CT 16 #define MVS_Q_SOC65 32 int pm_level; /* power management level */ struct mvs_slot slot[MVS_MAX_SLOTS]; union ccb *hold[MVS_MAX_SLOTS]; int holdtag[MVS_MAX_SLOTS]; /* Tags used for held commands. */ struct mtx mtx; /* state lock */ int devices; /* What is present */ int pm_present; /* PM presence reported */ enum mvs_edma_mode curr_mode; /* Current EDMA mode */ int fbs_enabled; /* FIS-based switching enabled */ uint32_t oslots; /* Occupied slots */ uint32_t otagspd[16]; /* Occupied device tags */ uint32_t rslots; /* Running slots */ uint32_t aslots; /* Slots with atomic commands */ uint32_t eslots; /* Slots in error */ uint32_t toslots; /* Slots in timeout */ int numrslots; /* Number of running slots */ int numrslotspd[16];/* Number of running slots per dev */ int numpslots; /* Number of PIO slots */ int numdslots; /* Number of DMA slots */ int numtslots; /* Number of NCQ slots */ int numtslotspd[16];/* Number of NCQ slots per dev */ int numhslots; /* Number of held slots */ int recoverycmd; /* Our READ LOG active */ int fatalerr; /* Fatal error happend */ int lastslot; /* Last used slot */ int taggedtarget; /* Last tagged target */ int resetting; /* Hard-reset in progress. */ int resetpolldiv; /* Hard-reset poll divider. */ int out_idx; /* Next written CRQB */ int in_idx; /* Next read CRPB */ u_int transfersize; /* PIO transfer size */ u_int donecount; /* PIO bytes sent/received */ u_int basic_dma; /* Basic DMA used for ATAPI */ u_int fake_busy; /* Fake busy bit after command submission */ union ccb *frozen; /* Frozen command */ struct callout pm_timer; /* Power management events */ struct callout reset_timer; /* Hard-reset timeout */ struct mvs_device user[16]; /* User-specified settings */ struct mvs_device curr[16]; /* Current settings */ }; /* structure describing a MVS controller */ struct mvs_controller { device_t dev; int r_rid; struct resource *r_mem; struct rman sc_iomem; struct mvs_controller_irq { struct resource *r_irq; void *handle; int r_irq_rid; } irq; int quirks; int channels; int ccc; /* CCC timeout */ int cccc; /* CCC commands */ struct mtx mtx; /* MIM access lock */ int gmim; /* Globally wanted MIM bits */ int pmim; /* Port wanted MIM bits */ int mim; /* Current MIM bits */ int msi; /* MSI enabled */ int msia; /* MSI active */ struct { void (*function)(void *); void *argument; } interrupt[MVS_MAX_PORTS]; }; enum mvs_err_type { MVS_ERR_NONE, /* No error */ MVS_ERR_INVALID, /* Error detected by us before submitting. */ MVS_ERR_INNOCENT, /* Innocent victim. */ MVS_ERR_TFE, /* Task File Error. */ MVS_ERR_SATA, /* SATA error. */ MVS_ERR_TIMEOUT, /* Command execution timeout. */ MVS_ERR_NCQ, /* NCQ command error. CCB should be put on hold * until READ LOG executed to reveal error. */ }; struct mvs_intr_arg { void *arg; u_int cause; }; extern devclass_t mvs_devclass; /* macros to hide busspace uglyness */ #define ATA_INB(res, offset) \ bus_read_1((res), (offset)) #define ATA_INW(res, offset) \ bus_read_2((res), (offset)) #define ATA_INL(res, offset) \ bus_read_4((res), (offset)) #define ATA_INSW(res, offset, addr, count) \ bus_read_multi_2((res), (offset), (addr), (count)) #define ATA_INSW_STRM(res, offset, addr, count) \ bus_read_multi_stream_2((res), (offset), (addr), (count)) #define ATA_INSL(res, offset, addr, count) \ bus_read_multi_4((res), (offset), (addr), (count)) #define ATA_INSL_STRM(res, offset, addr, count) \ bus_read_multi_stream_4((res), (offset), (addr), (count)) #define ATA_OUTB(res, offset, value) \ bus_write_1((res), (offset), (value)) #define ATA_OUTW(res, offset, value) \ bus_write_2((res), (offset), (value)) #define ATA_OUTL(res, offset, value) \ bus_write_4((res), (offset), (value)); #define ATA_OUTSW(res, offset, addr, count) \ bus_write_multi_2((res), (offset), (addr), (count)) #define ATA_OUTSW_STRM(res, offset, addr, count) \ bus_write_multi_stream_2((res), (offset), (addr), (count)) #define ATA_OUTSL(res, offset, addr, count) \ bus_write_multi_4((res), (offset), (addr), (count)) #define ATA_OUTSL_STRM(res, offset, addr, count) \ bus_write_multi_stream_4((res), (offset), (addr), (count)) Index: head/sys/dev/siis/siis.h =================================================================== --- head/sys/dev/siis/siis.h (revision 279962) +++ head/sys/dev/siis/siis.h (revision 279963) @@ -1,461 +1,461 @@ /*- * Copyright (c) 2009 Alexander Motin * All rights reserved. * * 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, * without modification, immediately at the beginning of the file. * 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. * * 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$ */ /* ATA register defines */ #define ATA_DATA 0 /* (RW) data */ #define ATA_FEATURE 1 /* (W) feature */ #define ATA_F_DMA 0x01 /* enable DMA */ #define ATA_F_OVL 0x02 /* enable overlap */ #define ATA_COUNT 2 /* (W) sector count */ #define ATA_SECTOR 3 /* (RW) sector # */ #define ATA_CYL_LSB 4 /* (RW) cylinder# LSB */ #define ATA_CYL_MSB 5 /* (RW) cylinder# MSB */ #define ATA_DRIVE 6 /* (W) Sector/Drive/Head */ #define ATA_D_LBA 0x40 /* use LBA addressing */ #define ATA_D_IBM 0xa0 /* 512 byte sectors, ECC */ #define ATA_COMMAND 7 /* (W) command */ #define ATA_ERROR 8 /* (R) error */ #define ATA_E_ILI 0x01 /* illegal length */ #define ATA_E_NM 0x02 /* no media */ #define ATA_E_ABORT 0x04 /* command aborted */ #define ATA_E_MCR 0x08 /* media change request */ #define ATA_E_IDNF 0x10 /* ID not found */ #define ATA_E_MC 0x20 /* media changed */ #define ATA_E_UNC 0x40 /* uncorrectable data */ #define ATA_E_ICRC 0x80 /* UDMA crc error */ #define ATA_E_ATAPI_SENSE_MASK 0xf0 /* ATAPI sense key mask */ #define ATA_IREASON 9 /* (R) interrupt reason */ #define ATA_I_CMD 0x01 /* cmd (1) | data (0) */ #define ATA_I_IN 0x02 /* read (1) | write (0) */ #define ATA_I_RELEASE 0x04 /* released bus (1) */ #define ATA_I_TAGMASK 0xf8 /* tag mask */ #define ATA_STATUS 10 /* (R) status */ #define ATA_ALTSTAT 11 /* (R) alternate status */ #define ATA_S_ERROR 0x01 /* error */ #define ATA_S_INDEX 0x02 /* index */ #define ATA_S_CORR 0x04 /* data corrected */ #define ATA_S_DRQ 0x08 /* data request */ #define ATA_S_DSC 0x10 /* drive seek completed */ #define ATA_S_SERVICE 0x10 /* drive needs service */ #define ATA_S_DWF 0x20 /* drive write fault */ #define ATA_S_DMA 0x20 /* DMA ready */ #define ATA_S_READY 0x40 /* drive ready */ #define ATA_S_BUSY 0x80 /* busy */ #define ATA_CONTROL 12 /* (W) control */ #define ATA_A_IDS 0x02 /* disable interrupts */ #define ATA_A_RESET 0x04 /* RESET controller */ #define ATA_A_4BIT 0x08 /* 4 head bits */ #define ATA_A_HOB 0x80 /* High Order Byte enable */ /* SATA register defines */ #define ATA_SSTATUS 13 #define ATA_SS_DET_MASK 0x0000000f #define ATA_SS_DET_NO_DEVICE 0x00000000 #define ATA_SS_DET_DEV_PRESENT 0x00000001 #define ATA_SS_DET_PHY_ONLINE 0x00000003 #define ATA_SS_DET_PHY_OFFLINE 0x00000004 #define ATA_SS_SPD_MASK 0x000000f0 #define ATA_SS_SPD_NO_SPEED 0x00000000 #define ATA_SS_SPD_GEN1 0x00000010 #define ATA_SS_SPD_GEN2 0x00000020 -#define ATA_SS_SPD_GEN3 0x00000040 +#define ATA_SS_SPD_GEN3 0x00000030 #define ATA_SS_IPM_MASK 0x00000f00 #define ATA_SS_IPM_NO_DEVICE 0x00000000 #define ATA_SS_IPM_ACTIVE 0x00000100 #define ATA_SS_IPM_PARTIAL 0x00000200 #define ATA_SS_IPM_SLUMBER 0x00000600 #define ATA_SERROR 14 #define ATA_SE_DATA_CORRECTED 0x00000001 #define ATA_SE_COMM_CORRECTED 0x00000002 #define ATA_SE_DATA_ERR 0x00000100 #define ATA_SE_COMM_ERR 0x00000200 #define ATA_SE_PROT_ERR 0x00000400 #define ATA_SE_HOST_ERR 0x00000800 #define ATA_SE_PHY_CHANGED 0x00010000 #define ATA_SE_PHY_IERROR 0x00020000 #define ATA_SE_COMM_WAKE 0x00040000 #define ATA_SE_DECODE_ERR 0x00080000 #define ATA_SE_PARITY_ERR 0x00100000 #define ATA_SE_CRC_ERR 0x00200000 #define ATA_SE_HANDSHAKE_ERR 0x00400000 #define ATA_SE_LINKSEQ_ERR 0x00800000 #define ATA_SE_TRANSPORT_ERR 0x01000000 #define ATA_SE_UNKNOWN_FIS 0x02000000 #define ATA_SCONTROL 15 #define ATA_SC_DET_MASK 0x0000000f #define ATA_SC_DET_IDLE 0x00000000 #define ATA_SC_DET_RESET 0x00000001 #define ATA_SC_DET_DISABLE 0x00000004 #define ATA_SC_SPD_MASK 0x000000f0 #define ATA_SC_SPD_NO_SPEED 0x00000000 #define ATA_SC_SPD_SPEED_GEN1 0x00000010 #define ATA_SC_SPD_SPEED_GEN2 0x00000020 -#define ATA_SC_SPD_SPEED_GEN3 0x00000040 +#define ATA_SC_SPD_SPEED_GEN3 0x00000030 #define ATA_SC_IPM_MASK 0x00000f00 #define ATA_SC_IPM_NONE 0x00000000 #define ATA_SC_IPM_DIS_PARTIAL 0x00000100 #define ATA_SC_IPM_DIS_SLUMBER 0x00000200 #define ATA_SACTIVE 16 /* * Global registers */ #define SIIS_GCTL 0x0040 /* Global Control */ #define SIIS_GCTL_GRESET 0x80000000 /* Global Reset */ #define SIIS_GCTL_MSIACK 0x40000000 /* MSI Ack */ #define SIIS_GCTL_I2C_IE 0x20000000 /* I2C int enable */ #define SIIS_GCTL_300CAP 0x01000000 /* 3Gb/s capable (R) */ #define SIIS_GCTL_PIE(n) (1 << (n)) /* Port int enable */ #define SIIS_IS 0x0044 /* Interrupt Status */ #define SIIS_IS_I2C 0x20000000 /* I2C Int Status */ #define SIIS_IS_PORT(n) (1 << (n)) /* Port interrupt stat */ #define SIIS_PHYCONF 0x0048 /* PHY Configuration */ #define SIIS_BIST_CTL 0x0050 #define SIIS_BIST_PATTERN 0x0054 /* 32 bit pattern */ #define SIIS_BIST_STATUS 0x0058 #define SIIS_I2C_CTL 0x0060 #define SIIS_I2C_STS 0x0064 #define SIIS_I2C_SADDR 0x0068 #define SIIS_I2C_DATA 0x006C #define SIIS_FLASH_ADDR 0x0070 #define SIIS_GPIO 0x0074 /* * Port registers */ #define SIIS_P_LRAM 0x0000 #define SIIS_P_LRAM_SLOT(i) (SIIS_P_LRAM + i * 128) #define SIIS_P_PMPSTS(i) (0x0F80 + i * 8) #define SIIS_P_PMPQACT(i) (0x0F80 + i * 8 + 4) #define SIIS_P_STS 0x1000 #define SIIS_P_CTLSET 0x1000 #define SIIS_P_CTLCLR 0x1004 #define SIIS_P_CTL_READY 0x80000000 #define SIIS_P_CTL_OOBB 0x02000000 #define SIIS_P_CTL_ACT 0x001F0000 #define SIIS_P_CTL_ACT_SHIFT 16 #define SIIS_P_CTL_LED_ON 0x00008000 #define SIIS_P_CTL_AIA 0x00004000 #define SIIS_P_CTL_PME 0x00002000 #define SIIS_P_CTL_IA 0x00001000 #define SIIS_P_CTL_IR 0x00000800 #define SIIS_P_CTL_32BIT 0x00000400 #define SIIS_P_CTL_SCR_DIS 0x00000200 #define SIIS_P_CTL_CONT_DIS 0x00000100 #define SIIS_P_CTL_TBIST 0x00000080 #define SIIS_P_CTL_RESUME 0x00000040 #define SIIS_P_CTL_PLENGTH 0x00000020 #define SIIS_P_CTL_LED_DIS 0x00000010 #define SIIS_P_CTL_INT_NCOR 0x00000008 #define SIIS_P_CTL_PORT_INIT 0x00000004 #define SIIS_P_CTL_DEV_RESET 0x00000002 #define SIIS_P_CTL_PORT_RESET 0x00000001 #define SIIS_P_IS 0x1008 #define SIIS_P_IX_SDBN 0x00000800 #define SIIS_P_IX_HS_ET 0x00000400 #define SIIS_P_IX_CRC_ET 0x00000200 #define SIIS_P_IX_8_10_ET 0x00000100 #define SIIS_P_IX_DEX 0x00000080 #define SIIS_P_IX_UNRECFIS 0x00000040 #define SIIS_P_IX_COMWAKE 0x00000020 #define SIIS_P_IX_PHYRDYCHG 0x00000010 #define SIIS_P_IX_PMCHG 0x00000008 #define SIIS_P_IX_READY 0x00000004 #define SIIS_P_IX_COMMERR 0x00000002 #define SIIS_P_IX_COMMCOMP 0x00000001 #define SIIS_P_IX_ENABLED SIIS_P_IX_COMMCOMP | SIIS_P_IX_COMMERR | \ SIIS_P_IX_PHYRDYCHG | SIIS_P_IX_SDBN #define SIIS_P_IESET 0x1010 #define SIIS_P_IECLR 0x1014 #define SIIS_P_CACTU 0x101C #define SIIS_P_CMDEFIFO 0x1020 #define SIIS_P_CMDERR 0x1024 #define SIIS_P_CMDERR_DEV 1 #define SIIS_P_CMDERR_SDB 2 #define SIIS_P_CMDERR_DATAFIS 3 #define SIIS_P_CMDERR_SENDFIS 4 #define SIIS_P_CMDERR_INCSTATE 5 #define SIIS_P_CMDERR_DIRECTION 6 #define SIIS_P_CMDERR_UNDERRUN 7 #define SIIS_P_CMDERR_OVERRUN 8 #define SIIS_P_CMDERR_LLOVERRUN 9 #define SIIS_P_CMDERR_PPE 11 #define SIIS_P_CMDERR_SGTALIGN 16 #define SIIS_P_CMDERR_PCITASGT 17 #define SIIS_P_CMDERR_OCIMASGT 18 #define SIIS_P_CMDERR_PCIPESGT 19 #define SIIS_P_CMDERR_PRBALIGN 24 #define SIIS_P_CMDERR_PCITAPRB 25 #define SIIS_P_CMDERR_PCIMAPRB 26 #define SIIS_P_CMDERR_PCIPEPRB 27 #define SIIS_P_CMDERR_PCITADATA 33 #define SIIS_P_CMDERR_PCIMADATA 34 #define SIIS_P_CMDERR_PCIPEDATA 35 #define SIIS_P_CMDERR_SERVICE 36 #define SIIS_P_FISCFG 0x1028 #define SIIS_P_PCIEFIFOTH 0x102C #define SIIS_P_8_10_DEC_ERR 0x1040 #define SIIS_P_CRC_ERR 0x1044 #define SIIS_P_HS_ERR 0x1048 #define SIIS_P_PHYCFG 0x1050 #define SIIS_P_SS 0x1800 #define SIIS_P_SS_ATTN 0x80000000 #define SIIS_P_CACTL(i) (0x1C00 + i * 8) #define SIIS_P_CACTH(i) (0x1C00 + i * 8 + 4) #define SIIS_P_CTX 0x1E04 #define SIIS_P_CTX_SLOT 0x0000001F #define SIIS_P_CTX_SLOT_SHIFT 0 #define SIIS_P_CTX_PMP 0x000001E0 #define SIIS_P_CTX_PMP_SHIFT 5 #define SIIS_P_SCTL 0x1F00 #define SIIS_P_SSTS 0x1F04 #define SIIS_P_SERR 0x1F08 #define SIIS_P_SACT 0x1F0C #define SIIS_P_SNTF 0x1F10 #define SIIS_MAX_PORTS 4 #define SIIS_MAX_SLOTS 31 #define SIIS_OFFSET 0x100 #define SIIS_STEP 0x80 /* Just to be sure, if building as module. */ #if MAXPHYS < 512 * 1024 #undef MAXPHYS #define MAXPHYS 512 * 1024 #endif /* Pessimistic prognosis on number of required S/G entries */ #define SIIS_SG_ENTRIES (roundup(btoc(MAXPHYS), 4) + 1) /* Command tables. Up to 32 commands, Each, 128byte aligned. */ #define SIIS_CT_OFFSET 0 #define SIIS_CT_SIZE (32 + 16 + SIIS_SG_ENTRIES * 16) /* Total main work area. */ #define SIIS_WORK_SIZE (SIIS_CT_OFFSET + SIIS_CT_SIZE * SIIS_MAX_SLOTS) struct siis_dma_prd { u_int64_t dba; u_int32_t dbc; u_int32_t control; #define SIIS_PRD_TRM 0x80000000 #define SIIS_PRD_LNK 0x40000000 #define SIIS_PRD_DRD 0x20000000 #define SIIS_PRD_XCF 0x10000000 } __packed; struct siis_cmd_ata { struct siis_dma_prd prd[1 + SIIS_SG_ENTRIES]; } __packed; struct siis_cmd_atapi { u_int8_t ccb[16]; struct siis_dma_prd prd[SIIS_SG_ENTRIES]; } __packed; struct siis_cmd { u_int16_t control; #define SIIS_PRB_PROTOCOL_OVERRIDE 0x0001 #define SIIS_PRB_RETRANSMIT 0x0002 #define SIIS_PRB_EXTERNAL_COMMAND 0x0004 #define SIIS_PRB_RECEIVE 0x0008 #define SIIS_PRB_PACKET_READ 0x0010 #define SIIS_PRB_PACKET_WRITE 0x0020 #define SIIS_PRB_INTERRUPT_MASK 0x0040 #define SIIS_PRB_SOFT_RESET 0x0080 u_int16_t protocol_override; #define SIIS_PRB_PROTO_PACKET 0x0001 #define SIIS_PRB_PROTO_TCQ 0x0002 #define SIIS_PRB_PROTO_NCQ 0x0004 #define SIIS_PRB_PROTO_READ 0x0008 #define SIIS_PRB_PROTO_WRITE 0x0010 #define SIIS_PRB_PROTO_TRANSPARENT 0x0020 u_int32_t transfer_count; u_int8_t fis[24]; union { struct siis_cmd_ata ata; struct siis_cmd_atapi atapi; } u; } __packed; /* misc defines */ #define ATA_IRQ_RID 0 #define ATA_INTR_FLAGS (INTR_MPSAFE|INTR_TYPE_BIO|INTR_ENTROPY) struct ata_dmaslot { bus_dmamap_t data_map; /* data DMA map */ int nsegs; /* Number of segs loaded */ }; /* structure holding DMA related information */ struct ata_dma { bus_dma_tag_t work_tag; /* workspace DMA tag */ bus_dmamap_t work_map; /* workspace DMA map */ uint8_t *work; /* workspace */ bus_addr_t work_bus; /* bus address of work */ bus_dma_tag_t data_tag; /* data DMA tag */ }; enum siis_slot_states { SIIS_SLOT_EMPTY, SIIS_SLOT_LOADING, SIIS_SLOT_RUNNING, SIIS_SLOT_WAITING }; struct siis_slot { device_t dev; /* Device handle */ u_int8_t slot; /* Number of this slot */ enum siis_slot_states state; /* Slot state */ union ccb *ccb; /* CCB occupying slot */ struct ata_dmaslot dma; /* DMA data of this slot */ struct callout timeout; /* Execution timeout */ }; struct siis_device { int revision; int mode; u_int bytecount; u_int atapi; u_int tags; u_int caps; }; /* structure describing an ATA channel */ struct siis_channel { device_t dev; /* Device handle */ int unit; /* Physical channel */ struct resource *r_mem; /* Memory of this channel */ struct resource *r_irq; /* Interrupt of this channel */ void *ih; /* Interrupt handle */ struct ata_dma dma; /* DMA data */ struct cam_sim *sim; struct cam_path *path; struct cdev *led; /* Activity led led(4) cdev. */ int quirks; int pm_level; /* power management level */ struct siis_slot slot[SIIS_MAX_SLOTS]; union ccb *hold[SIIS_MAX_SLOTS]; struct mtx mtx; /* state lock */ int devices; /* What is present */ int pm_present; /* PM presence reported */ uint32_t oslots; /* Occupied slots */ uint32_t rslots; /* Running slots */ uint32_t aslots; /* Slots with atomic commands */ uint32_t eslots; /* Slots in error */ uint32_t toslots; /* Slots in timeout */ int numrslots; /* Number of running slots */ int numtslots[SIIS_MAX_SLOTS]; /* Number of tagged slots */ int numhslots; /* Number of held slots */ int recoverycmd; /* Our READ LOG active */ int fatalerr; /* Fatal error happend */ int recovery; /* Some slots are in error */ union ccb *frozen; /* Frozen command */ struct siis_device user[16]; /* User-specified settings */ struct siis_device curr[16]; /* Current settings */ }; /* structure describing a SIIS controller */ struct siis_controller { device_t dev; int r_grid; struct resource *r_gmem; int r_rid; struct resource *r_mem; struct rman sc_iomem; struct siis_controller_irq { struct resource *r_irq; void *handle; int r_irq_rid; } irq; int quirks; int channels; uint32_t gctl; struct { void (*function)(void *); void *argument; } interrupt[SIIS_MAX_PORTS]; }; enum siis_err_type { SIIS_ERR_NONE, /* No error */ SIIS_ERR_INVALID, /* Error detected by us before submitting. */ SIIS_ERR_INNOCENT, /* Innocent victim. */ SIIS_ERR_TFE, /* Task File Error. */ SIIS_ERR_SATA, /* SATA error. */ SIIS_ERR_TIMEOUT, /* Command execution timeout. */ SIIS_ERR_NCQ, /* NCQ command error. CCB should be put on hold * until READ LOG executed to reveal error. */ }; /* macros to hide busspace uglyness */ #define ATA_INB(res, offset) \ bus_read_1((res), (offset)) #define ATA_INW(res, offset) \ bus_read_2((res), (offset)) #define ATA_INL(res, offset) \ bus_read_4((res), (offset)) #define ATA_INSW(res, offset, addr, count) \ bus_read_multi_2((res), (offset), (addr), (count)) #define ATA_INSW_STRM(res, offset, addr, count) \ bus_read_multi_stream_2((res), (offset), (addr), (count)) #define ATA_INSL(res, offset, addr, count) \ bus_read_multi_4((res), (offset), (addr), (count)) #define ATA_INSL_STRM(res, offset, addr, count) \ bus_read_multi_stream_4((res), (offset), (addr), (count)) #define ATA_OUTB(res, offset, value) \ bus_write_1((res), (offset), (value)) #define ATA_OUTW(res, offset, value) \ bus_write_2((res), (offset), (value)) #define ATA_OUTL(res, offset, value) \ bus_write_4((res), (offset), (value)) #define ATA_OUTSW(res, offset, addr, count) \ bus_write_multi_2((res), (offset), (addr), (count)) #define ATA_OUTSW_STRM(res, offset, addr, count) \ bus_write_multi_stream_2((res), (offset), (addr), (count)) #define ATA_OUTSL(res, offset, addr, count) \ bus_write_multi_4((res), (offset), (addr), (count)) #define ATA_OUTSL_STRM(res, offset, addr, count) \ bus_write_multi_stream_4((res), (offset), (addr), (count))