1195534Sscottl/*- 2230132Suqs * Copyright (c) 1998 - 2008 S��ren Schmidt <sos@FreeBSD.org> 3238805Smav * Copyright (c) 2009-2012 Alexander Motin <mav@FreeBSD.org> 4195534Sscottl * All rights reserved. 5195534Sscottl * 6195534Sscottl * Redistribution and use in source and binary forms, with or without 7195534Sscottl * modification, are permitted provided that the following conditions 8195534Sscottl * are met: 9195534Sscottl * 1. Redistributions of source code must retain the above copyright 10195534Sscottl * notice, this list of conditions and the following disclaimer, 11195534Sscottl * without modification, immediately at the beginning of the file. 12195534Sscottl * 2. Redistributions in binary form must reproduce the above copyright 13195534Sscottl * notice, this list of conditions and the following disclaimer in the 14195534Sscottl * documentation and/or other materials provided with the distribution. 15195534Sscottl * 16195534Sscottl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17195534Sscottl * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18195534Sscottl * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19195534Sscottl * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20195534Sscottl * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21195534Sscottl * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22195534Sscottl * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23195534Sscottl * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24195534Sscottl * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25195534Sscottl * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26195534Sscottl * 27195534Sscottl * $FreeBSD: stable/11/sys/dev/ahci/ahci.h 350793 2019-08-08 21:46:36Z mav $ 28195534Sscottl */ 29195534Sscottl 30195534Sscottl/* ATA register defines */ 31195534Sscottl#define ATA_DATA 0 /* (RW) data */ 32195534Sscottl 33195534Sscottl#define ATA_FEATURE 1 /* (W) feature */ 34195534Sscottl#define ATA_F_DMA 0x01 /* enable DMA */ 35195534Sscottl#define ATA_F_OVL 0x02 /* enable overlap */ 36195534Sscottl 37195534Sscottl#define ATA_COUNT 2 /* (W) sector count */ 38195534Sscottl 39195534Sscottl#define ATA_SECTOR 3 /* (RW) sector # */ 40195534Sscottl#define ATA_CYL_LSB 4 /* (RW) cylinder# LSB */ 41195534Sscottl#define ATA_CYL_MSB 5 /* (RW) cylinder# MSB */ 42195534Sscottl#define ATA_DRIVE 6 /* (W) Sector/Drive/Head */ 43195534Sscottl#define ATA_D_LBA 0x40 /* use LBA addressing */ 44195534Sscottl#define ATA_D_IBM 0xa0 /* 512 byte sectors, ECC */ 45195534Sscottl 46195534Sscottl#define ATA_COMMAND 7 /* (W) command */ 47195534Sscottl 48195534Sscottl#define ATA_ERROR 8 /* (R) error */ 49195534Sscottl#define ATA_E_ILI 0x01 /* illegal length */ 50195534Sscottl#define ATA_E_NM 0x02 /* no media */ 51195534Sscottl#define ATA_E_ABORT 0x04 /* command aborted */ 52195534Sscottl#define ATA_E_MCR 0x08 /* media change request */ 53195534Sscottl#define ATA_E_IDNF 0x10 /* ID not found */ 54195534Sscottl#define ATA_E_MC 0x20 /* media changed */ 55195534Sscottl#define ATA_E_UNC 0x40 /* uncorrectable data */ 56195534Sscottl#define ATA_E_ICRC 0x80 /* UDMA crc error */ 57195534Sscottl#define ATA_E_ATAPI_SENSE_MASK 0xf0 /* ATAPI sense key mask */ 58195534Sscottl 59195534Sscottl#define ATA_IREASON 9 /* (R) interrupt reason */ 60195534Sscottl#define ATA_I_CMD 0x01 /* cmd (1) | data (0) */ 61195534Sscottl#define ATA_I_IN 0x02 /* read (1) | write (0) */ 62195534Sscottl#define ATA_I_RELEASE 0x04 /* released bus (1) */ 63195534Sscottl#define ATA_I_TAGMASK 0xf8 /* tag mask */ 64195534Sscottl 65195534Sscottl#define ATA_STATUS 10 /* (R) status */ 66195534Sscottl#define ATA_ALTSTAT 11 /* (R) alternate status */ 67195534Sscottl#define ATA_S_ERROR 0x01 /* error */ 68195534Sscottl#define ATA_S_INDEX 0x02 /* index */ 69195534Sscottl#define ATA_S_CORR 0x04 /* data corrected */ 70195534Sscottl#define ATA_S_DRQ 0x08 /* data request */ 71195534Sscottl#define ATA_S_DSC 0x10 /* drive seek completed */ 72195534Sscottl#define ATA_S_SERVICE 0x10 /* drive needs service */ 73195534Sscottl#define ATA_S_DWF 0x20 /* drive write fault */ 74195534Sscottl#define ATA_S_DMA 0x20 /* DMA ready */ 75195534Sscottl#define ATA_S_READY 0x40 /* drive ready */ 76195534Sscottl#define ATA_S_BUSY 0x80 /* busy */ 77195534Sscottl 78195534Sscottl#define ATA_CONTROL 12 /* (W) control */ 79195534Sscottl#define ATA_A_IDS 0x02 /* disable interrupts */ 80195534Sscottl#define ATA_A_RESET 0x04 /* RESET controller */ 81195534Sscottl#define ATA_A_4BIT 0x08 /* 4 head bits */ 82195534Sscottl#define ATA_A_HOB 0x80 /* High Order Byte enable */ 83195534Sscottl 84195534Sscottl/* SATA register defines */ 85195534Sscottl#define ATA_SSTATUS 13 86195534Sscottl#define ATA_SS_DET_MASK 0x0000000f 87195534Sscottl#define ATA_SS_DET_NO_DEVICE 0x00000000 88195534Sscottl#define ATA_SS_DET_DEV_PRESENT 0x00000001 89195534Sscottl#define ATA_SS_DET_PHY_ONLINE 0x00000003 90195534Sscottl#define ATA_SS_DET_PHY_OFFLINE 0x00000004 91195534Sscottl 92195534Sscottl#define ATA_SS_SPD_MASK 0x000000f0 93195534Sscottl#define ATA_SS_SPD_NO_SPEED 0x00000000 94195534Sscottl#define ATA_SS_SPD_GEN1 0x00000010 95195534Sscottl#define ATA_SS_SPD_GEN2 0x00000020 96279963Smav#define ATA_SS_SPD_GEN3 0x00000030 97195534Sscottl 98195534Sscottl#define ATA_SS_IPM_MASK 0x00000f00 99195534Sscottl#define ATA_SS_IPM_NO_DEVICE 0x00000000 100195534Sscottl#define ATA_SS_IPM_ACTIVE 0x00000100 101195534Sscottl#define ATA_SS_IPM_PARTIAL 0x00000200 102195534Sscottl#define ATA_SS_IPM_SLUMBER 0x00000600 103253647Smav#define ATA_SS_IPM_DEVSLEEP 0x00000800 104195534Sscottl 105195534Sscottl#define ATA_SERROR 14 106195534Sscottl#define ATA_SE_DATA_CORRECTED 0x00000001 107195534Sscottl#define ATA_SE_COMM_CORRECTED 0x00000002 108195534Sscottl#define ATA_SE_DATA_ERR 0x00000100 109195534Sscottl#define ATA_SE_COMM_ERR 0x00000200 110195534Sscottl#define ATA_SE_PROT_ERR 0x00000400 111195534Sscottl#define ATA_SE_HOST_ERR 0x00000800 112195534Sscottl#define ATA_SE_PHY_CHANGED 0x00010000 113195534Sscottl#define ATA_SE_PHY_IERROR 0x00020000 114195534Sscottl#define ATA_SE_COMM_WAKE 0x00040000 115195534Sscottl#define ATA_SE_DECODE_ERR 0x00080000 116195534Sscottl#define ATA_SE_PARITY_ERR 0x00100000 117195534Sscottl#define ATA_SE_CRC_ERR 0x00200000 118195534Sscottl#define ATA_SE_HANDSHAKE_ERR 0x00400000 119195534Sscottl#define ATA_SE_LINKSEQ_ERR 0x00800000 120195534Sscottl#define ATA_SE_TRANSPORT_ERR 0x01000000 121195534Sscottl#define ATA_SE_UNKNOWN_FIS 0x02000000 122220657Smav#define ATA_SE_EXCHANGED 0x04000000 123195534Sscottl 124195534Sscottl#define ATA_SCONTROL 15 125195534Sscottl#define ATA_SC_DET_MASK 0x0000000f 126195534Sscottl#define ATA_SC_DET_IDLE 0x00000000 127195534Sscottl#define ATA_SC_DET_RESET 0x00000001 128195534Sscottl#define ATA_SC_DET_DISABLE 0x00000004 129195534Sscottl 130195534Sscottl#define ATA_SC_SPD_MASK 0x000000f0 131195534Sscottl#define ATA_SC_SPD_NO_SPEED 0x00000000 132195534Sscottl#define ATA_SC_SPD_SPEED_GEN1 0x00000010 133195534Sscottl#define ATA_SC_SPD_SPEED_GEN2 0x00000020 134279963Smav#define ATA_SC_SPD_SPEED_GEN3 0x00000030 135195534Sscottl 136195534Sscottl#define ATA_SC_IPM_MASK 0x00000f00 137195534Sscottl#define ATA_SC_IPM_NONE 0x00000000 138195534Sscottl#define ATA_SC_IPM_DIS_PARTIAL 0x00000100 139195534Sscottl#define ATA_SC_IPM_DIS_SLUMBER 0x00000200 140258173Smav#define ATA_SC_IPM_DIS_DEVSLEEP 0x00000400 141195534Sscottl 142195534Sscottl#define ATA_SACTIVE 16 143195534Sscottl 144195534Sscottl#define AHCI_MAX_PORTS 32 145195534Sscottl#define AHCI_MAX_SLOTS 32 146276012Ssmh#define AHCI_MAX_IRQS 16 147195534Sscottl 148195534Sscottl/* SATA AHCI v1.0 register defines */ 149195534Sscottl#define AHCI_CAP 0x00 150195534Sscottl#define AHCI_CAP_NPMASK 0x0000001f 151195534Sscottl#define AHCI_CAP_SXS 0x00000020 152195534Sscottl#define AHCI_CAP_EMS 0x00000040 153195534Sscottl#define AHCI_CAP_CCCS 0x00000080 154195534Sscottl#define AHCI_CAP_NCS 0x00001F00 155195534Sscottl#define AHCI_CAP_NCS_SHIFT 8 156195534Sscottl#define AHCI_CAP_PSC 0x00002000 157195534Sscottl#define AHCI_CAP_SSC 0x00004000 158195534Sscottl#define AHCI_CAP_PMD 0x00008000 159195534Sscottl#define AHCI_CAP_FBSS 0x00010000 160195534Sscottl#define AHCI_CAP_SPM 0x00020000 161195534Sscottl#define AHCI_CAP_SAM 0x00080000 162195534Sscottl#define AHCI_CAP_ISS 0x00F00000 163195534Sscottl#define AHCI_CAP_ISS_SHIFT 20 164195534Sscottl#define AHCI_CAP_SCLO 0x01000000 165195534Sscottl#define AHCI_CAP_SAL 0x02000000 166195534Sscottl#define AHCI_CAP_SALP 0x04000000 167195534Sscottl#define AHCI_CAP_SSS 0x08000000 168195534Sscottl#define AHCI_CAP_SMPS 0x10000000 169195534Sscottl#define AHCI_CAP_SSNTF 0x20000000 170195534Sscottl#define AHCI_CAP_SNCQ 0x40000000 171195534Sscottl#define AHCI_CAP_64BIT 0x80000000 172195534Sscottl 173195534Sscottl#define AHCI_GHC 0x04 174195534Sscottl#define AHCI_GHC_AE 0x80000000 175195534Sscottl#define AHCI_GHC_MRSM 0x00000004 176195534Sscottl#define AHCI_GHC_IE 0x00000002 177195534Sscottl#define AHCI_GHC_HR 0x00000001 178195534Sscottl 179195534Sscottl#define AHCI_IS 0x08 180195534Sscottl#define AHCI_PI 0x0c 181195534Sscottl#define AHCI_VS 0x10 182195534Sscottl 183196656Smav#define AHCI_CCCC 0x14 184196656Smav#define AHCI_CCCC_TV_MASK 0xffff0000 185196656Smav#define AHCI_CCCC_TV_SHIFT 16 186196656Smav#define AHCI_CCCC_CC_MASK 0x0000ff00 187196656Smav#define AHCI_CCCC_CC_SHIFT 8 188196656Smav#define AHCI_CCCC_INT_MASK 0x000000f8 189196656Smav#define AHCI_CCCC_INT_SHIFT 3 190196656Smav#define AHCI_CCCC_EN 0x00000001 191196656Smav#define AHCI_CCCP 0x18 192196656Smav 193203108Smav#define AHCI_EM_LOC 0x1C 194203108Smav#define AHCI_EM_CTL 0x20 195203108Smav#define AHCI_EM_MR 0x00000001 196203108Smav#define AHCI_EM_TM 0x00000100 197203108Smav#define AHCI_EM_RST 0x00000200 198203108Smav#define AHCI_EM_LED 0x00010000 199203108Smav#define AHCI_EM_SAFTE 0x00020000 200203108Smav#define AHCI_EM_SES2 0x00040000 201203108Smav#define AHCI_EM_SGPIO 0x00080000 202203108Smav#define AHCI_EM_SMB 0x01000000 203203108Smav#define AHCI_EM_XMT 0x02000000 204203108Smav#define AHCI_EM_ALHD 0x04000000 205203108Smav#define AHCI_EM_PM 0x08000000 206203108Smav 207196656Smav#define AHCI_CAP2 0x24 208196656Smav#define AHCI_CAP2_BOH 0x00000001 209196656Smav#define AHCI_CAP2_NVMP 0x00000002 210196656Smav#define AHCI_CAP2_APST 0x00000004 211253647Smav#define AHCI_CAP2_SDS 0x00000008 212253647Smav#define AHCI_CAP2_SADM 0x00000010 213253647Smav#define AHCI_CAP2_DESO 0x00000020 214196656Smav 215195534Sscottl#define AHCI_OFFSET 0x100 216195534Sscottl#define AHCI_STEP 0x80 217195534Sscottl 218195534Sscottl#define AHCI_P_CLB 0x00 219195534Sscottl#define AHCI_P_CLBU 0x04 220195534Sscottl#define AHCI_P_FB 0x08 221195534Sscottl#define AHCI_P_FBU 0x0c 222195534Sscottl#define AHCI_P_IS 0x10 223195534Sscottl#define AHCI_P_IE 0x14 224195534Sscottl#define AHCI_P_IX_DHR 0x00000001 225195534Sscottl#define AHCI_P_IX_PS 0x00000002 226195534Sscottl#define AHCI_P_IX_DS 0x00000004 227195534Sscottl#define AHCI_P_IX_SDB 0x00000008 228195534Sscottl#define AHCI_P_IX_UF 0x00000010 229195534Sscottl#define AHCI_P_IX_DP 0x00000020 230195534Sscottl#define AHCI_P_IX_PC 0x00000040 231220657Smav#define AHCI_P_IX_MP 0x00000080 232195534Sscottl 233195534Sscottl#define AHCI_P_IX_PRC 0x00400000 234195534Sscottl#define AHCI_P_IX_IPM 0x00800000 235195534Sscottl#define AHCI_P_IX_OF 0x01000000 236195534Sscottl#define AHCI_P_IX_INF 0x04000000 237195534Sscottl#define AHCI_P_IX_IF 0x08000000 238195534Sscottl#define AHCI_P_IX_HBD 0x10000000 239195534Sscottl#define AHCI_P_IX_HBF 0x20000000 240195534Sscottl#define AHCI_P_IX_TFE 0x40000000 241195534Sscottl#define AHCI_P_IX_CPD 0x80000000 242195534Sscottl 243195534Sscottl#define AHCI_P_CMD 0x18 244195534Sscottl#define AHCI_P_CMD_ST 0x00000001 245195534Sscottl#define AHCI_P_CMD_SUD 0x00000002 246195534Sscottl#define AHCI_P_CMD_POD 0x00000004 247195534Sscottl#define AHCI_P_CMD_CLO 0x00000008 248195534Sscottl#define AHCI_P_CMD_FRE 0x00000010 249195534Sscottl#define AHCI_P_CMD_CCS_MASK 0x00001f00 250195534Sscottl#define AHCI_P_CMD_CCS_SHIFT 8 251195534Sscottl#define AHCI_P_CMD_ISS 0x00002000 252195534Sscottl#define AHCI_P_CMD_FR 0x00004000 253195534Sscottl#define AHCI_P_CMD_CR 0x00008000 254195534Sscottl#define AHCI_P_CMD_CPS 0x00010000 255195534Sscottl#define AHCI_P_CMD_PMA 0x00020000 256195534Sscottl#define AHCI_P_CMD_HPCP 0x00040000 257203123Smav#define AHCI_P_CMD_MPSP 0x00080000 258195534Sscottl#define AHCI_P_CMD_CPD 0x00100000 259203123Smav#define AHCI_P_CMD_ESP 0x00200000 260203123Smav#define AHCI_P_CMD_FBSCP 0x00400000 261203123Smav#define AHCI_P_CMD_APSTE 0x00800000 262195534Sscottl#define AHCI_P_CMD_ATAPI 0x01000000 263195534Sscottl#define AHCI_P_CMD_DLAE 0x02000000 264195534Sscottl#define AHCI_P_CMD_ALPE 0x04000000 265195534Sscottl#define AHCI_P_CMD_ASP 0x08000000 266195534Sscottl#define AHCI_P_CMD_ICC_MASK 0xf0000000 267195534Sscottl#define AHCI_P_CMD_NOOP 0x00000000 268195534Sscottl#define AHCI_P_CMD_ACTIVE 0x10000000 269195534Sscottl#define AHCI_P_CMD_PARTIAL 0x20000000 270195534Sscottl#define AHCI_P_CMD_SLUMBER 0x60000000 271253647Smav#define AHCI_P_CMD_DEVSLEEP 0x80000000 272195534Sscottl 273195534Sscottl#define AHCI_P_TFD 0x20 274195534Sscottl#define AHCI_P_SIG 0x24 275195534Sscottl#define AHCI_P_SSTS 0x28 276195534Sscottl#define AHCI_P_SCTL 0x2c 277195534Sscottl#define AHCI_P_SERR 0x30 278195534Sscottl#define AHCI_P_SACT 0x34 279195534Sscottl#define AHCI_P_CI 0x38 280195534Sscottl#define AHCI_P_SNTF 0x3C 281195534Sscottl#define AHCI_P_FBS 0x40 282203123Smav#define AHCI_P_FBS_EN 0x00000001 283203123Smav#define AHCI_P_FBS_DEC 0x00000002 284203123Smav#define AHCI_P_FBS_SDE 0x00000004 285203123Smav#define AHCI_P_FBS_DEV 0x00000f00 286203123Smav#define AHCI_P_FBS_DEV_SHIFT 8 287203123Smav#define AHCI_P_FBS_ADO 0x0000f000 288203123Smav#define AHCI_P_FBS_ADO_SHIFT 12 289203123Smav#define AHCI_P_FBS_DWE 0x000f0000 290203123Smav#define AHCI_P_FBS_DWE_SHIFT 16 291258173Smav#define AHCI_P_DEVSLP 0x44 292258173Smav#define AHCI_P_DEVSLP_ADSE 0x00000001 293258173Smav#define AHCI_P_DEVSLP_DSP 0x00000002 294258173Smav#define AHCI_P_DEVSLP_DETO 0x000003fc 295258173Smav#define AHCI_P_DEVSLP_DETO_SHIFT 2 296258173Smav#define AHCI_P_DEVSLP_MDAT 0x00007c00 297258173Smav#define AHCI_P_DEVSLP_MDAT_SHIFT 10 298258173Smav#define AHCI_P_DEVSLP_DITO 0x01ff8000 299258173Smav#define AHCI_P_DEVSLP_DITO_SHIFT 15 300258173Smav#define AHCI_P_DEVSLP_DM 0x0e000000 301258173Smav#define AHCI_P_DEVSLP_DM_SHIFT 25 302195534Sscottl 303195534Sscottl/* Just to be sure, if building as module. */ 304195534Sscottl#if MAXPHYS < 512 * 1024 305195534Sscottl#undef MAXPHYS 306195534Sscottl#define MAXPHYS 512 * 1024 307195534Sscottl#endif 308195534Sscottl/* Pessimistic prognosis on number of required S/G entries */ 309195534Sscottl#define AHCI_SG_ENTRIES (roundup(btoc(MAXPHYS) + 1, 8)) 310195534Sscottl/* Command list. 32 commands. First, 1Kbyte aligned. */ 311195534Sscottl#define AHCI_CL_OFFSET 0 312195534Sscottl#define AHCI_CL_SIZE 32 313195534Sscottl/* Command tables. Up to 32 commands, Each, 128byte aligned. */ 314195534Sscottl#define AHCI_CT_OFFSET (AHCI_CL_OFFSET + AHCI_CL_SIZE * AHCI_MAX_SLOTS) 315195534Sscottl#define AHCI_CT_SIZE (128 + AHCI_SG_ENTRIES * 16) 316195534Sscottl/* Total main work area. */ 317195534Sscottl#define AHCI_WORK_SIZE (AHCI_CT_OFFSET + AHCI_CT_SIZE * ch->numslots) 318195534Sscottl 319195534Sscottlstruct ahci_dma_prd { 320195534Sscottl u_int64_t dba; 321195534Sscottl u_int32_t reserved; 322195534Sscottl u_int32_t dbc; /* 0 based */ 323195534Sscottl#define AHCI_PRD_MASK 0x003fffff /* max 4MB */ 324195534Sscottl#define AHCI_PRD_MAX (AHCI_PRD_MASK + 1) 325258780Seadler#define AHCI_PRD_IPC (1U << 31) 326195534Sscottl} __packed; 327195534Sscottl 328195534Sscottlstruct ahci_cmd_tab { 329195534Sscottl u_int8_t cfis[64]; 330195534Sscottl u_int8_t acmd[32]; 331195534Sscottl u_int8_t reserved[32]; 332195534Sscottl struct ahci_dma_prd prd_tab[AHCI_SG_ENTRIES]; 333195534Sscottl} __packed; 334195534Sscottl 335195534Sscottlstruct ahci_cmd_list { 336195534Sscottl u_int16_t cmd_flags; 337195534Sscottl#define AHCI_CMD_ATAPI 0x0020 338195534Sscottl#define AHCI_CMD_WRITE 0x0040 339195534Sscottl#define AHCI_CMD_PREFETCH 0x0080 340195534Sscottl#define AHCI_CMD_RESET 0x0100 341195534Sscottl#define AHCI_CMD_BIST 0x0200 342195534Sscottl#define AHCI_CMD_CLR_BUSY 0x0400 343195534Sscottl 344195534Sscottl u_int16_t prd_length; /* PRD entries */ 345195534Sscottl u_int32_t bytecount; 346195534Sscottl u_int64_t cmd_table_phys; /* 128byte aligned */ 347195534Sscottl} __packed; 348195534Sscottl 349195534Sscottl/* misc defines */ 350195534Sscottl#define ATA_IRQ_RID 0 351195534Sscottl#define ATA_INTR_FLAGS (INTR_MPSAFE|INTR_TYPE_BIO|INTR_ENTROPY) 352195534Sscottl 353195534Sscottlstruct ata_dmaslot { 354195534Sscottl bus_dmamap_t data_map; /* data DMA map */ 355195534Sscottl int nsegs; /* Number of segs loaded */ 356195534Sscottl}; 357195534Sscottl 358195534Sscottl/* structure holding DMA related information */ 359195534Sscottlstruct ata_dma { 360195534Sscottl bus_dma_tag_t work_tag; /* workspace DMA tag */ 361195534Sscottl bus_dmamap_t work_map; /* workspace DMA map */ 362195534Sscottl uint8_t *work; /* workspace */ 363195534Sscottl bus_addr_t work_bus; /* bus address of work */ 364195534Sscottl bus_dma_tag_t rfis_tag; /* RFIS list DMA tag */ 365195534Sscottl bus_dmamap_t rfis_map; /* RFIS list DMA map */ 366195534Sscottl uint8_t *rfis; /* FIS receive area */ 367195534Sscottl bus_addr_t rfis_bus; /* bus address of rfis */ 368195534Sscottl bus_dma_tag_t data_tag; /* data DMA tag */ 369195534Sscottl}; 370195534Sscottl 371195534Sscottlenum ahci_slot_states { 372195534Sscottl AHCI_SLOT_EMPTY, 373195534Sscottl AHCI_SLOT_LOADING, 374195534Sscottl AHCI_SLOT_RUNNING, 375198319Smav AHCI_SLOT_EXECUTING 376195534Sscottl}; 377195534Sscottl 378195534Sscottlstruct ahci_slot { 379271261Smav struct ahci_channel *ch; /* Channel */ 380195534Sscottl u_int8_t slot; /* Number of this slot */ 381195534Sscottl enum ahci_slot_states state; /* Slot state */ 382195534Sscottl union ccb *ccb; /* CCB occupying slot */ 383195534Sscottl struct ata_dmaslot dma; /* DMA data of this slot */ 384195534Sscottl struct callout timeout; /* Execution timeout */ 385195534Sscottl}; 386195534Sscottl 387199747Smavstruct ahci_device { 388199821Smav int revision; 389199747Smav int mode; 390199747Smav u_int bytecount; 391203376Smav u_int atapi; 392199747Smav u_int tags; 393207499Smav u_int caps; 394199747Smav}; 395199747Smav 396222039Smavstruct ahci_led { 397222039Smav device_t dev; /* Device handle */ 398222039Smav struct cdev *led; 399222039Smav uint8_t num; /* Number of this led */ 400222039Smav uint8_t state; /* State of this led */ 401222039Smav}; 402222039Smav 403222039Smav#define AHCI_NUM_LEDS 3 404222039Smav 405195534Sscottl/* structure describing an ATA channel */ 406195534Sscottlstruct ahci_channel { 407195534Sscottl device_t dev; /* Device handle */ 408195534Sscottl int unit; /* Physical channel */ 409195534Sscottl struct resource *r_mem; /* Memory of this channel */ 410195534Sscottl struct resource *r_irq; /* Interrupt of this channel */ 411195534Sscottl void *ih; /* Interrupt handle */ 412195534Sscottl struct ata_dma dma; /* DMA data */ 413195534Sscottl struct cam_sim *sim; 414195534Sscottl struct cam_path *path; 415195534Sscottl uint32_t caps; /* Controller capabilities */ 416196656Smav uint32_t caps2; /* Controller capabilities */ 417203123Smav uint32_t chcaps; /* Channel capabilities */ 418258173Smav uint32_t chscaps; /* Channel sleep capabilities */ 419271146Simp uint16_t vendorid; /* Vendor ID from the bus */ 420271146Simp uint16_t deviceid; /* Device ID from the bus */ 421271146Simp uint16_t subvendorid; /* Subvendor ID from the bus */ 422271146Simp uint16_t subdeviceid; /* Subdevice ID from the bus */ 423199322Smav int quirks; 424195534Sscottl int numslots; /* Number of present slots */ 425195534Sscottl int pm_level; /* power management level */ 426195534Sscottl int devices; /* What is present */ 427195534Sscottl int pm_present; /* PM presence reported */ 428203123Smav int fbs_enabled; /* FIS-based switching enabled */ 429271261Smav 430285090Sloos void (*start)(struct ahci_channel *); 431285090Sloos 432271261Smav union ccb *hold[AHCI_MAX_SLOTS]; 433271261Smav struct ahci_slot slot[AHCI_MAX_SLOTS]; 434199747Smav uint32_t oslots; /* Occupied slots */ 435195534Sscottl uint32_t rslots; /* Running slots */ 436195534Sscottl uint32_t aslots; /* Slots with atomic commands */ 437203123Smav uint32_t eslots; /* Slots in error */ 438203873Smav uint32_t toslots; /* Slots in timeout */ 439271261Smav int lastslot; /* Last used slot */ 440271261Smav int taggedtarget; /* Last tagged target */ 441195534Sscottl int numrslots; /* Number of running slots */ 442203123Smav int numrslotspd[16];/* Number of running slots per dev */ 443195534Sscottl int numtslots; /* Number of tagged slots */ 444203123Smav int numtslotspd[16];/* Number of tagged slots per dev */ 445220830Smav int numhslots; /* Number of held slots */ 446220565Smav int recoverycmd; /* Our READ LOG active */ 447298955Spfg int fatalerr; /* Fatal error happened */ 448220576Smav int resetting; /* Hard-reset in progress. */ 449220789Smav int resetpolldiv; /* Hard-reset poll divider. */ 450220657Smav int listening; /* SUD bit is cleared. */ 451224498Smav int wrongccs; /* CCS field in CMD was wrong */ 452195534Sscottl union ccb *frozen; /* Frozen command */ 453196656Smav struct callout pm_timer; /* Power management events */ 454220576Smav struct callout reset_timer; /* Hard-reset timeout */ 455199747Smav 456199747Smav struct ahci_device user[16]; /* User-specified settings */ 457199747Smav struct ahci_device curr[16]; /* Current settings */ 458271261Smav 459271261Smav struct mtx_padalign mtx; /* state lock */ 460271261Smav STAILQ_HEAD(, ccb_hdr) doneq; /* queue of completed CCBs */ 461271261Smav int batch; /* doneq is in use */ 462350792Smav 463350792Smav int disablephy; /* keep PHY disabled */ 464195534Sscottl}; 465195534Sscottl 466238805Smavstruct ahci_enclosure { 467238805Smav device_t dev; /* Device handle */ 468238805Smav struct resource *r_memc; /* Control register */ 469238805Smav struct resource *r_memt; /* Transmit buffer */ 470298955Spfg struct resource *r_memr; /* Receive buffer */ 471238805Smav struct cam_sim *sim; 472238805Smav struct cam_path *path; 473238805Smav struct mtx mtx; /* state lock */ 474238805Smav struct ahci_led leds[AHCI_MAX_PORTS * 3]; 475238805Smav uint32_t capsem; /* Controller capabilities */ 476238805Smav uint8_t status[AHCI_MAX_PORTS][4]; /* ArrayDev statuses */ 477238805Smav int quirks; 478238805Smav int channels; 479302402Smav uint32_t ichannels; 480238805Smav}; 481238805Smav 482195534Sscottl/* structure describing a AHCI controller */ 483195534Sscottlstruct ahci_controller { 484195534Sscottl device_t dev; 485249346Smav bus_dma_tag_t dma_tag; 486195534Sscottl int r_rid; 487285789Szbb int r_msix_tab_rid; 488285789Szbb int r_msix_pba_rid; 489271146Simp uint16_t vendorid; /* Vendor ID from the bus */ 490271146Simp uint16_t deviceid; /* Device ID from the bus */ 491271146Simp uint16_t subvendorid; /* Subvendor ID from the bus */ 492271146Simp uint16_t subdeviceid; /* Subdevice ID from the bus */ 493195534Sscottl struct resource *r_mem; 494285789Szbb struct resource *r_msix_table; 495285789Szbb struct resource *r_msix_pba; 496195534Sscottl struct rman sc_iomem; 497195534Sscottl struct ahci_controller_irq { 498195534Sscottl struct ahci_controller *ctlr; 499195534Sscottl struct resource *r_irq; 500195534Sscottl void *handle; 501195534Sscottl int r_irq_rid; 502195534Sscottl int mode; 503195534Sscottl#define AHCI_IRQ_MODE_ALL 0 504195534Sscottl#define AHCI_IRQ_MODE_AFTER 1 505195534Sscottl#define AHCI_IRQ_MODE_ONE 2 506276012Ssmh } irqs[AHCI_MAX_IRQS]; 507196656Smav uint32_t caps; /* Controller capabilities */ 508196656Smav uint32_t caps2; /* Controller capabilities */ 509203108Smav uint32_t capsem; /* Controller capabilities */ 510222039Smav uint32_t emloc; /* EM buffer location */ 511199322Smav int quirks; 512195534Sscottl int numirqs; 513195534Sscottl int channels; 514302402Smav uint32_t ichannels; 515196656Smav int ccc; /* CCC timeout */ 516196656Smav int cccv; /* CCC vector */ 517256843Smav int direct; /* Direct command completion */ 518256843Smav int msi; /* MSI interupts */ 519195534Sscottl struct { 520195534Sscottl void (*function)(void *); 521195534Sscottl void *argument; 522195534Sscottl } interrupt[AHCI_MAX_PORTS]; 523285090Sloos void (*ch_start)(struct ahci_channel *); 524350793Smav struct mtx ch_mtx; /* Lock for attached channels */ 525350793Smav struct ahci_channel *ch[AHCI_MAX_PORTS]; /* Attached channels */ 526195534Sscottl}; 527195534Sscottl 528195534Sscottlenum ahci_err_type { 529195534Sscottl AHCI_ERR_NONE, /* No error */ 530195534Sscottl AHCI_ERR_INVALID, /* Error detected by us before submitting. */ 531195534Sscottl AHCI_ERR_INNOCENT, /* Innocent victim. */ 532195534Sscottl AHCI_ERR_TFE, /* Task File Error. */ 533195534Sscottl AHCI_ERR_SATA, /* SATA error. */ 534195534Sscottl AHCI_ERR_TIMEOUT, /* Command execution timeout. */ 535195534Sscottl AHCI_ERR_NCQ, /* NCQ command error. CCB should be put on hold 536195534Sscottl * until READ LOG executed to reveal error. */ 537195534Sscottl}; 538195534Sscottl 539195534Sscottl/* macros to hide busspace uglyness */ 540195534Sscottl#define ATA_INB(res, offset) \ 541195534Sscottl bus_read_1((res), (offset)) 542195534Sscottl#define ATA_INW(res, offset) \ 543195534Sscottl bus_read_2((res), (offset)) 544195534Sscottl#define ATA_INL(res, offset) \ 545195534Sscottl bus_read_4((res), (offset)) 546195534Sscottl#define ATA_INSW(res, offset, addr, count) \ 547195534Sscottl bus_read_multi_2((res), (offset), (addr), (count)) 548195534Sscottl#define ATA_INSW_STRM(res, offset, addr, count) \ 549195534Sscottl bus_read_multi_stream_2((res), (offset), (addr), (count)) 550195534Sscottl#define ATA_INSL(res, offset, addr, count) \ 551195534Sscottl bus_read_multi_4((res), (offset), (addr), (count)) 552195534Sscottl#define ATA_INSL_STRM(res, offset, addr, count) \ 553195534Sscottl bus_read_multi_stream_4((res), (offset), (addr), (count)) 554195534Sscottl#define ATA_OUTB(res, offset, value) \ 555195534Sscottl bus_write_1((res), (offset), (value)) 556195534Sscottl#define ATA_OUTW(res, offset, value) \ 557195534Sscottl bus_write_2((res), (offset), (value)) 558195534Sscottl#define ATA_OUTL(res, offset, value) \ 559195534Sscottl bus_write_4((res), (offset), (value)) 560195534Sscottl#define ATA_OUTSW(res, offset, addr, count) \ 561195534Sscottl bus_write_multi_2((res), (offset), (addr), (count)) 562195534Sscottl#define ATA_OUTSW_STRM(res, offset, addr, count) \ 563195534Sscottl bus_write_multi_stream_2((res), (offset), (addr), (count)) 564195534Sscottl#define ATA_OUTSL(res, offset, addr, count) \ 565195534Sscottl bus_write_multi_4((res), (offset), (addr), (count)) 566195534Sscottl#define ATA_OUTSL_STRM(res, offset, addr, count) \ 567195534Sscottl bus_write_multi_stream_4((res), (offset), (addr), (count)) 568271146Simp 569291444Smmel/* 570291444Smmel * On some platforms, we must ensure proper interdevice write ordering. 571291444Smmel * The AHCI interrupt status register must be updated in HW before 572291444Smmel * registers in interrupt controller. 573291444Smmel * Unfortunately, only way how we can do it is readback. 574291444Smmel * 575291444Smmel * Currently, only ARM is known to have this issue. 576291444Smmel */ 577291444Smmel#if defined(__arm__) 578291444Smmel#define ATA_RBL(res, offset) \ 579291444Smmel bus_read_4((res), (offset)) 580291444Smmel#else 581291444Smmel#define ATA_RBL(res, offset) 582291444Smmel#endif 583271146Simp 584278034Ssmh#define AHCI_Q_NOFORCE 0x00000001 585278034Ssmh#define AHCI_Q_NOPMP 0x00000002 586278034Ssmh#define AHCI_Q_NONCQ 0x00000004 587278034Ssmh#define AHCI_Q_1CH 0x00000008 588278034Ssmh#define AHCI_Q_2CH 0x00000010 589278034Ssmh#define AHCI_Q_4CH 0x00000020 590278034Ssmh#define AHCI_Q_EDGEIS 0x00000040 591278034Ssmh#define AHCI_Q_SATA2 0x00000080 592278034Ssmh#define AHCI_Q_NOBSYRES 0x00000100 593278034Ssmh#define AHCI_Q_NOAA 0x00000200 594278034Ssmh#define AHCI_Q_NOCOUNT 0x00000400 595278034Ssmh#define AHCI_Q_ALTSIG 0x00000800 596278034Ssmh#define AHCI_Q_NOMSI 0x00001000 597278034Ssmh#define AHCI_Q_ATI_PMP_BUG 0x00002000 598278034Ssmh#define AHCI_Q_MAXIO_64K 0x00004000 599278034Ssmh#define AHCI_Q_SATA1_UNIT0 0x00008000 /* need better method for this */ 600278034Ssmh#define AHCI_Q_ABAR0 0x00010000 601278034Ssmh#define AHCI_Q_1MSI 0x00020000 602280184Szbb#define AHCI_Q_FORCE_PI 0x00040000 603280184Szbb#define AHCI_Q_RESTORE_CAP 0x00080000 604297447Szbb#define AHCI_Q_NOMSIX 0x00100000 605313445Smav#define AHCI_Q_NOCCS 0x00400000 606317673Smav#define AHCI_Q_NOAUX 0x00800000 607271146Simp 608271146Simp#define AHCI_Q_BIT_STRING \ 609283936Smav "\020" \ 610271146Simp "\001NOFORCE" \ 611271146Simp "\002NOPMP" \ 612271146Simp "\003NONCQ" \ 613271146Simp "\0041CH" \ 614271146Simp "\0052CH" \ 615271146Simp "\0064CH" \ 616271146Simp "\007EDGEIS" \ 617271146Simp "\010SATA2" \ 618271146Simp "\011NOBSYRES" \ 619271146Simp "\012NOAA" \ 620271146Simp "\013NOCOUNT" \ 621271146Simp "\014ALTSIG" \ 622271146Simp "\015NOMSI" \ 623271146Simp "\016ATI_PMP_BUG" \ 624271146Simp "\017MAXIO_64K" \ 625277126Skib "\020SATA1_UNIT0" \ 626278034Ssmh "\021ABAR0" \ 627280184Szbb "\0221MSI" \ 628285200Ssmh "\023FORCE_PI" \ 629297447Szbb "\024RESTORE_CAP" \ 630313445Smav "\025NOMSIX" \ 631317673Smav "\027NOCCS" \ 632317673Smav "\030NOAUX" 633271146Simp 634271146Simpint ahci_attach(device_t dev); 635271146Simpint ahci_detach(device_t dev); 636271146Simpint ahci_setup_interrupt(device_t dev); 637271146Simpint ahci_print_child(device_t dev, device_t child); 638271146Simpstruct resource *ahci_alloc_resource(device_t dev, device_t child, int type, int *rid, 639294883Sjhibbits rman_res_t start, rman_res_t end, rman_res_t count, u_int flags); 640271146Simpint ahci_release_resource(device_t dev, device_t child, int type, int rid, 641271146Simp struct resource *r); 642271146Simpint ahci_setup_intr(device_t dev, device_t child, struct resource *irq, 643271146Simp int flags, driver_filter_t *filter, driver_intr_t *function, 644271146Simp void *argument, void **cookiep); 645271146Simpint ahci_teardown_intr(device_t dev, device_t child, struct resource *irq, 646271146Simp void *cookie); 647271146Simpint ahci_child_location_str(device_t dev, device_t child, char *buf, 648271146Simp size_t buflen); 649271146Simpbus_dma_tag_t ahci_get_dma_tag(device_t dev, device_t child); 650271146Simpint ahci_ctlr_reset(device_t dev); 651271146Simpint ahci_ctlr_setup(device_t dev); 652285789Szbbvoid ahci_free_mem(device_t dev); 653331493Sian 654350793Smav/* Functions to allow AHCI EM to access other channels. */ 655350793Smavvoid ahci_attached(device_t dev, struct ahci_channel *ch); 656350793Smavvoid ahci_detached(device_t dev, struct ahci_channel *ch); 657350793Smavstruct ahci_channel * ahci_getch(device_t dev, int n); 658350793Smavvoid ahci_putch(struct ahci_channel *ch); 659350793Smav 660331493Sianextern devclass_t ahci_devclass; 661331493Sian 662