18b89ef0aSSøren Schmidt /*- 24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 3718cf2ccSPedro F. Giffuni * 49a14aa01SUlrich Spörlein * Copyright (c) 1998 - 2008 Søren Schmidt <sos@FreeBSD.org> 58b89ef0aSSøren Schmidt * All rights reserved. 68b89ef0aSSøren Schmidt * 78b89ef0aSSøren Schmidt * Redistribution and use in source and binary forms, with or without 88b89ef0aSSøren Schmidt * modification, are permitted provided that the following conditions 98b89ef0aSSøren Schmidt * are met: 108b89ef0aSSøren Schmidt * 1. Redistributions of source code must retain the above copyright 118b89ef0aSSøren Schmidt * notice, this list of conditions and the following disclaimer, 128b89ef0aSSøren Schmidt * without modification, immediately at the beginning of the file. 138b89ef0aSSøren Schmidt * 2. Redistributions in binary form must reproduce the above copyright 148b89ef0aSSøren Schmidt * notice, this list of conditions and the following disclaimer in the 158b89ef0aSSøren Schmidt * documentation and/or other materials provided with the distribution. 168b89ef0aSSøren Schmidt * 178b89ef0aSSøren Schmidt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 188b89ef0aSSøren Schmidt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 198b89ef0aSSøren Schmidt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 208b89ef0aSSøren Schmidt * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 218b89ef0aSSøren Schmidt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 228b89ef0aSSøren Schmidt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 238b89ef0aSSøren Schmidt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 248b89ef0aSSøren Schmidt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 258b89ef0aSSøren Schmidt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 268b89ef0aSSøren Schmidt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 278b89ef0aSSøren Schmidt */ 288b89ef0aSSøren Schmidt 29f3755df1SNathan Whitehorn #if 0 30f3755df1SNathan Whitehorn #define ATA_LEGACY_SUPPORT /* Enable obsolete features that break 31f3755df1SNathan Whitehorn * some modern devices */ 32f3755df1SNathan Whitehorn #endif 33f3755df1SNathan Whitehorn 348b89ef0aSSøren Schmidt /* ATA register defines */ 350e1eb682SSøren Schmidt #define ATA_DATA 0 /* (RW) data */ 365fdbb0d2SSøren Schmidt 370e1eb682SSøren Schmidt #define ATA_FEATURE 1 /* (W) feature */ 380e1eb682SSøren Schmidt #define ATA_F_DMA 0x01 /* enable DMA */ 390e1eb682SSøren Schmidt #define ATA_F_OVL 0x02 /* enable overlap */ 400e1eb682SSøren Schmidt 410e1eb682SSøren Schmidt #define ATA_COUNT 2 /* (W) sector count */ 420e1eb682SSøren Schmidt 430e1eb682SSøren Schmidt #define ATA_SECTOR 3 /* (RW) sector # */ 440e1eb682SSøren Schmidt #define ATA_CYL_LSB 4 /* (RW) cylinder# LSB */ 450e1eb682SSøren Schmidt #define ATA_CYL_MSB 5 /* (RW) cylinder# MSB */ 460e1eb682SSøren Schmidt #define ATA_DRIVE 6 /* (W) Sector/Drive/Head */ 470e1eb682SSøren Schmidt #define ATA_D_LBA 0x40 /* use LBA addressing */ 480e1eb682SSøren Schmidt #define ATA_D_IBM 0xa0 /* 512 byte sectors, ECC */ 490e1eb682SSøren Schmidt 500e1eb682SSøren Schmidt #define ATA_COMMAND 7 /* (W) command */ 510e1eb682SSøren Schmidt 520e1eb682SSøren Schmidt #define ATA_ERROR 8 /* (R) error */ 535fdbb0d2SSøren Schmidt #define ATA_E_ILI 0x01 /* illegal length */ 543082a6dcSSøren Schmidt #define ATA_E_NM 0x02 /* no media */ 552b0a1c08SSøren Schmidt #define ATA_E_ABORT 0x04 /* command aborted */ 563082a6dcSSøren Schmidt #define ATA_E_MCR 0x08 /* media change request */ 573082a6dcSSøren Schmidt #define ATA_E_IDNF 0x10 /* ID not found */ 583082a6dcSSøren Schmidt #define ATA_E_MC 0x20 /* media changed */ 593082a6dcSSøren Schmidt #define ATA_E_UNC 0x40 /* uncorrectable data */ 603082a6dcSSøren Schmidt #define ATA_E_ICRC 0x80 /* UDMA crc error */ 61cd8a592bSSøren Schmidt #define ATA_E_ATAPI_SENSE_MASK 0xf0 /* ATAPI sense key mask */ 622b0a1c08SSøren Schmidt 630e1eb682SSøren Schmidt #define ATA_IREASON 9 /* (R) interrupt reason */ 648b89ef0aSSøren Schmidt #define ATA_I_CMD 0x01 /* cmd (1) | data (0) */ 658b89ef0aSSøren Schmidt #define ATA_I_IN 0x02 /* read (1) | write (0) */ 668b89ef0aSSøren Schmidt #define ATA_I_RELEASE 0x04 /* released bus (1) */ 6755bfaed1SSøren Schmidt #define ATA_I_TAGMASK 0xf8 /* tag mask */ 688b89ef0aSSøren Schmidt 690e1eb682SSøren Schmidt #define ATA_STATUS 10 /* (R) status */ 700e1eb682SSøren Schmidt #define ATA_ALTSTAT 11 /* (R) alternate status */ 718b89ef0aSSøren Schmidt #define ATA_S_ERROR 0x01 /* error */ 728b89ef0aSSøren Schmidt #define ATA_S_INDEX 0x02 /* index */ 738b89ef0aSSøren Schmidt #define ATA_S_CORR 0x04 /* data corrected */ 748b89ef0aSSøren Schmidt #define ATA_S_DRQ 0x08 /* data request */ 7555bfaed1SSøren Schmidt #define ATA_S_DSC 0x10 /* drive seek completed */ 762b0a1c08SSøren Schmidt #define ATA_S_SERVICE 0x10 /* drive needs service */ 778b89ef0aSSøren Schmidt #define ATA_S_DWF 0x20 /* drive write fault */ 782b0a1c08SSøren Schmidt #define ATA_S_DMA 0x20 /* DMA ready */ 792b0a1c08SSøren Schmidt #define ATA_S_READY 0x40 /* drive ready */ 802b0a1c08SSøren Schmidt #define ATA_S_BUSY 0x80 /* busy */ 818b89ef0aSSøren Schmidt 820e1eb682SSøren Schmidt #define ATA_CONTROL 12 /* (W) control */ 830e1eb682SSøren Schmidt 840e1eb682SSøren Schmidt #define ATA_CTLOFFSET 0x206 /* control register offset */ 850e1eb682SSøren Schmidt #define ATA_PCCARD_CTLOFFSET 0x0e /* do for PCCARD devices */ 868b89ef0aSSøren Schmidt #define ATA_A_IDS 0x02 /* disable interrupts */ 878b89ef0aSSøren Schmidt #define ATA_A_RESET 0x04 /* RESET controller */ 88f3755df1SNathan Whitehorn #ifdef ATA_LEGACY_SUPPORT 89f3755df1SNathan Whitehorn #define ATA_A_4BIT 0x08 /* 4 head bits: obsolete 1996 */ 90f3755df1SNathan Whitehorn #else 91f3755df1SNathan Whitehorn #define ATA_A_4BIT 0x00 92f3755df1SNathan Whitehorn #endif 938ca4df32SSøren Schmidt #define ATA_A_HOB 0x80 /* High Order Byte enable */ 948b89ef0aSSøren Schmidt 95b0a7e6a5SSøren Schmidt /* SATA register defines */ 96b0a7e6a5SSøren Schmidt #define ATA_SSTATUS 13 97b0a7e6a5SSøren Schmidt #define ATA_SS_DET_MASK 0x0000000f 98b0a7e6a5SSøren Schmidt #define ATA_SS_DET_NO_DEVICE 0x00000000 99b0a7e6a5SSøren Schmidt #define ATA_SS_DET_DEV_PRESENT 0x00000001 100b0a7e6a5SSøren Schmidt #define ATA_SS_DET_PHY_ONLINE 0x00000003 101b0a7e6a5SSøren Schmidt #define ATA_SS_DET_PHY_OFFLINE 0x00000004 102b0a7e6a5SSøren Schmidt 103b0a7e6a5SSøren Schmidt #define ATA_SS_SPD_MASK 0x000000f0 104b0a7e6a5SSøren Schmidt #define ATA_SS_SPD_NO_SPEED 0x00000000 105b0a7e6a5SSøren Schmidt #define ATA_SS_SPD_GEN1 0x00000010 106b0a7e6a5SSøren Schmidt #define ATA_SS_SPD_GEN2 0x00000020 107c21b342bSAlexander Motin #define ATA_SS_SPD_GEN3 0x00000030 108b0a7e6a5SSøren Schmidt 109b0a7e6a5SSøren Schmidt #define ATA_SS_IPM_MASK 0x00000f00 110b0a7e6a5SSøren Schmidt #define ATA_SS_IPM_NO_DEVICE 0x00000000 111b0a7e6a5SSøren Schmidt #define ATA_SS_IPM_ACTIVE 0x00000100 112b0a7e6a5SSøren Schmidt #define ATA_SS_IPM_PARTIAL 0x00000200 113b0a7e6a5SSøren Schmidt #define ATA_SS_IPM_SLUMBER 0x00000600 114b0a7e6a5SSøren Schmidt 115b0a7e6a5SSøren Schmidt #define ATA_SERROR 14 116b0a7e6a5SSøren Schmidt #define ATA_SE_DATA_CORRECTED 0x00000001 117b0a7e6a5SSøren Schmidt #define ATA_SE_COMM_CORRECTED 0x00000002 118b0a7e6a5SSøren Schmidt #define ATA_SE_DATA_ERR 0x00000100 119b0a7e6a5SSøren Schmidt #define ATA_SE_COMM_ERR 0x00000200 120b0a7e6a5SSøren Schmidt #define ATA_SE_PROT_ERR 0x00000400 121b0a7e6a5SSøren Schmidt #define ATA_SE_HOST_ERR 0x00000800 122b0a7e6a5SSøren Schmidt #define ATA_SE_PHY_CHANGED 0x00010000 123b0a7e6a5SSøren Schmidt #define ATA_SE_PHY_IERROR 0x00020000 124b0a7e6a5SSøren Schmidt #define ATA_SE_COMM_WAKE 0x00040000 125b0a7e6a5SSøren Schmidt #define ATA_SE_DECODE_ERR 0x00080000 126b0a7e6a5SSøren Schmidt #define ATA_SE_PARITY_ERR 0x00100000 127b0a7e6a5SSøren Schmidt #define ATA_SE_CRC_ERR 0x00200000 128b0a7e6a5SSøren Schmidt #define ATA_SE_HANDSHAKE_ERR 0x00400000 129b0a7e6a5SSøren Schmidt #define ATA_SE_LINKSEQ_ERR 0x00800000 130b0a7e6a5SSøren Schmidt #define ATA_SE_TRANSPORT_ERR 0x01000000 131b0a7e6a5SSøren Schmidt #define ATA_SE_UNKNOWN_FIS 0x02000000 132b0a7e6a5SSøren Schmidt 133b0a7e6a5SSøren Schmidt #define ATA_SCONTROL 15 134b0a7e6a5SSøren Schmidt #define ATA_SC_DET_MASK 0x0000000f 135abacbfafSSøren Schmidt #define ATA_SC_DET_IDLE 0x00000000 136b0a7e6a5SSøren Schmidt #define ATA_SC_DET_RESET 0x00000001 137b0a7e6a5SSøren Schmidt #define ATA_SC_DET_DISABLE 0x00000004 138b0a7e6a5SSøren Schmidt 139b0a7e6a5SSøren Schmidt #define ATA_SC_SPD_MASK 0x000000f0 140b0a7e6a5SSøren Schmidt #define ATA_SC_SPD_NO_SPEED 0x00000000 141b0a7e6a5SSøren Schmidt #define ATA_SC_SPD_SPEED_GEN1 0x00000010 142b0a7e6a5SSøren Schmidt #define ATA_SC_SPD_SPEED_GEN2 0x00000020 143c21b342bSAlexander Motin #define ATA_SC_SPD_SPEED_GEN3 0x00000030 144b0a7e6a5SSøren Schmidt 145b0a7e6a5SSøren Schmidt #define ATA_SC_IPM_MASK 0x00000f00 146b0a7e6a5SSøren Schmidt #define ATA_SC_IPM_NONE 0x00000000 147b0a7e6a5SSøren Schmidt #define ATA_SC_IPM_DIS_PARTIAL 0x00000100 148b0a7e6a5SSøren Schmidt #define ATA_SC_IPM_DIS_SLUMBER 0x00000200 149b0a7e6a5SSøren Schmidt 150d81c813fSSøren Schmidt #define ATA_SACTIVE 16 151d81c813fSSøren Schmidt 152b0a7e6a5SSøren Schmidt /* DMA register defines */ 153cd853791SKonstantin Belousov #define ATA_DMA_ENTRIES MAX(17, btoc(maxphys) + 1) 154b0a7e6a5SSøren Schmidt #define ATA_DMA_EOT 0x80000000 155b0a7e6a5SSøren Schmidt 156d81c813fSSøren Schmidt #define ATA_BMCMD_PORT 17 157b0a7e6a5SSøren Schmidt #define ATA_BMCMD_START_STOP 0x01 158b0a7e6a5SSøren Schmidt #define ATA_BMCMD_WRITE_READ 0x08 159b0a7e6a5SSøren Schmidt 160d81c813fSSøren Schmidt #define ATA_BMDEVSPEC_0 18 161d81c813fSSøren Schmidt #define ATA_BMSTAT_PORT 19 162b0a7e6a5SSøren Schmidt #define ATA_BMSTAT_ACTIVE 0x01 163b0a7e6a5SSøren Schmidt #define ATA_BMSTAT_ERROR 0x02 164b0a7e6a5SSøren Schmidt #define ATA_BMSTAT_INTERRUPT 0x04 165b0a7e6a5SSøren Schmidt #define ATA_BMSTAT_MASK 0x07 166b0a7e6a5SSøren Schmidt #define ATA_BMSTAT_DMA_MASTER 0x20 167b0a7e6a5SSøren Schmidt #define ATA_BMSTAT_DMA_SLAVE 0x40 168b0a7e6a5SSøren Schmidt #define ATA_BMSTAT_DMA_SIMPLEX 0x80 169b0a7e6a5SSøren Schmidt 170d81c813fSSøren Schmidt #define ATA_BMDEVSPEC_1 20 171d81c813fSSøren Schmidt #define ATA_BMDTP_PORT 21 172b0a7e6a5SSøren Schmidt 173d81c813fSSøren Schmidt #define ATA_IDX_ADDR 22 174d81c813fSSøren Schmidt #define ATA_IDX_DATA 23 175d81c813fSSøren Schmidt #define ATA_MAX_RES 24 1765fdbb0d2SSøren Schmidt 17755bfaed1SSøren Schmidt /* misc defines */ 1787dd6c388SSøren Schmidt #define ATA_PRIMARY 0x1f0 1797dd6c388SSøren Schmidt #define ATA_SECONDARY 0x170 1808b89ef0aSSøren Schmidt #define ATA_IOSIZE 0x08 1810e1eb682SSøren Schmidt #define ATA_CTLIOSIZE 0x01 182b17f7a1aSSøren Schmidt #define ATA_BMIOSIZE 0x08 183331c488dSSøren Schmidt #define ATA_IOADDR_RID 0 1840e1eb682SSøren Schmidt #define ATA_CTLADDR_RID 1 185566cf07aSSøren Schmidt #define ATA_BMADDR_RID 0x20 186331c488dSSøren Schmidt #define ATA_IRQ_RID 0 1871a796873SSøren Schmidt #define ATA_DEV(unit) ((unit > 0) ? 0x10 : 0) 188cd8a592bSSøren Schmidt #define ATA_CFA_MAGIC1 0x844A 189cd8a592bSSøren Schmidt #define ATA_CFA_MAGIC2 0x848A 190266d3a7aSRemko Lodder #define ATA_CFA_MAGIC3 0x8400 191b0a7e6a5SSøren Schmidt #define ATAPI_MAGIC_LSB 0x14 192b0a7e6a5SSøren Schmidt #define ATAPI_MAGIC_MSB 0xeb 193b0a7e6a5SSøren Schmidt #define ATAPI_P_READ (ATA_S_DRQ | ATA_I_IN) 194b0a7e6a5SSøren Schmidt #define ATAPI_P_WRITE (ATA_S_DRQ) 195b0a7e6a5SSøren Schmidt #define ATAPI_P_CMDOUT (ATA_S_DRQ | ATA_I_CMD) 196b0a7e6a5SSøren Schmidt #define ATAPI_P_DONEDRQ (ATA_S_DRQ | ATA_I_CMD | ATA_I_IN) 197b0a7e6a5SSøren Schmidt #define ATAPI_P_DONE (ATA_I_CMD | ATA_I_IN) 198b0a7e6a5SSøren Schmidt #define ATAPI_P_ABORT 0 1995fdbb0d2SSøren Schmidt #define ATA_INTR_FLAGS (INTR_MPSAFE|INTR_TYPE_BIO|INTR_ENTROPY) 2005fdbb0d2SSøren Schmidt #define ATA_OP_CONTINUES 0 2015fdbb0d2SSøren Schmidt #define ATA_OP_FINISHED 1 2026c22760cSSøren Schmidt #define ATA_MAX_28BIT_LBA 268435455UL 203241ce89eSSøren Schmidt 2048ca4df32SSøren Schmidt /* structure used for composite atomic operations */ 2058ec96d7bSSøren Schmidt #define MAX_COMPOSITES 32 /* u_int32_t bits */ 2068ca4df32SSøren Schmidt struct ata_composite { 2078ca4df32SSøren Schmidt struct mtx lock; /* control lock */ 2088ca4df32SSøren Schmidt u_int32_t rd_needed; /* needed read subdisks */ 2098ca4df32SSøren Schmidt u_int32_t rd_done; /* done read subdisks */ 2108ca4df32SSøren Schmidt u_int32_t wr_needed; /* needed write subdisks */ 2118ca4df32SSøren Schmidt u_int32_t wr_depend; /* write depends on subdisks */ 2128ca4df32SSøren Schmidt u_int32_t wr_done; /* done write subdisks */ 2138ec96d7bSSøren Schmidt struct ata_request *request[MAX_COMPOSITES]; 214e9bd25bfSSøren Schmidt u_int32_t residual; /* bytes still to transfer */ 2158ca4df32SSøren Schmidt caddr_t data_1; 2168ca4df32SSøren Schmidt caddr_t data_2; 2178ca4df32SSøren Schmidt }; 2185fdbb0d2SSøren Schmidt 2198ca4df32SSøren Schmidt /* structure used to queue an ATA/ATAPI request */ 2208ca4df32SSøren Schmidt struct ata_request { 2218ca4df32SSøren Schmidt device_t dev; /* device handle */ 22228baad63SSøren Schmidt device_t parent; /* channel handle */ 223ebbb35baSAlexander Motin int unit; /* physical unit */ 2245fdbb0d2SSøren Schmidt union { 2255fdbb0d2SSøren Schmidt struct { 2265fdbb0d2SSøren Schmidt u_int8_t command; /* command reg */ 227a6e97ccfSSøren Schmidt u_int16_t feature; /* feature reg */ 2285fdbb0d2SSøren Schmidt u_int16_t count; /* count reg */ 229f2972d7eSSøren Schmidt u_int64_t lba; /* lba reg */ 2305fdbb0d2SSøren Schmidt } ata; 2315fdbb0d2SSøren Schmidt struct { 2325fdbb0d2SSøren Schmidt u_int8_t ccb[16]; /* ATAPI command block */ 233cd8a592bSSøren Schmidt struct atapi_sense sense; /* ATAPI request sense data */ 234cd8a592bSSøren Schmidt u_int8_t saved_cmd; /* ATAPI saved command */ 2355fdbb0d2SSøren Schmidt } atapi; 2365fdbb0d2SSøren Schmidt } u; 2378ca4df32SSøren Schmidt u_int32_t bytecount; /* bytes to transfer */ 2388ca4df32SSøren Schmidt u_int32_t transfersize; /* bytes pr transfer */ 2398ca4df32SSøren Schmidt caddr_t data; /* pointer to data buf */ 2409f82379cSSøren Schmidt u_int32_t tag; /* HW tag of this request */ 2418ca4df32SSøren Schmidt int flags; 2428ca4df32SSøren Schmidt #define ATA_R_CONTROL 0x00000001 2438ca4df32SSøren Schmidt #define ATA_R_READ 0x00000002 2448ca4df32SSøren Schmidt #define ATA_R_WRITE 0x00000004 2451d968d22SSøren Schmidt #define ATA_R_ATAPI 0x00000008 2461d968d22SSøren Schmidt #define ATA_R_DMA 0x00000010 2478ca4df32SSøren Schmidt #define ATA_R_QUIET 0x00000020 2481d968d22SSøren Schmidt #define ATA_R_TIMEOUT 0x00000040 249ebbb35baSAlexander Motin #define ATA_R_48BIT 0x00000080 2508ca4df32SSøren Schmidt 2518ca4df32SSøren Schmidt #define ATA_R_ORDERED 0x00000100 2528ca4df32SSøren Schmidt #define ATA_R_AT_HEAD 0x00000200 2538ca4df32SSøren Schmidt #define ATA_R_REQUEUE 0x00000400 2548ca4df32SSøren Schmidt #define ATA_R_THREAD 0x00000800 255ea74abd5SAlexander Motin #define ATA_R_DIRECT 0x00001000 25623d9e39cSAlexander Motin #define ATA_R_NEEDRESULT 0x00002000 257512a3aa0SAlexander Motin #define ATA_R_DATA_IN_CCB 0x00004000 2588ca4df32SSøren Schmidt 259ebbb35baSAlexander Motin #define ATA_R_ATAPI16 0x00010000 260ebbb35baSAlexander Motin #define ATA_R_ATAPI_INTR 0x00020000 261ebbb35baSAlexander Motin 2628ca4df32SSøren Schmidt #define ATA_R_DEBUG 0x10000000 2630b03bcd2SSøren Schmidt #define ATA_R_DANGER1 0x20000000 2640b03bcd2SSøren Schmidt #define ATA_R_DANGER2 0x40000000 2655fdbb0d2SSøren Schmidt 266104c094eSSøren Schmidt struct ata_dmaslot *dma; /* DMA slot of this request */ 2675fdbb0d2SSøren Schmidt u_int8_t status; /* ATA status */ 2685fdbb0d2SSøren Schmidt u_int8_t error; /* ATA error */ 2695fdbb0d2SSøren Schmidt u_int32_t donecount; /* bytes transferred */ 2708ca4df32SSøren Schmidt int result; /* result error code */ 2719f06a427SSøren Schmidt void (*callback)(struct ata_request *request); 272a7a120f6SSøren Schmidt struct sema done; /* request done sema */ 2735fdbb0d2SSøren Schmidt int retries; /* retry count */ 2745fdbb0d2SSøren Schmidt int timeout; /* timeout for this cmd */ 275b5dee91fSSøren Schmidt struct callout callout; /* callout management */ 2765fdbb0d2SSøren Schmidt struct task task; /* task management */ 277816994ccSSøren Schmidt struct bio *bio; /* bio for this request */ 2788ca4df32SSøren Schmidt int this; /* this request ID */ 2798ca4df32SSøren Schmidt struct ata_composite *composite; /* for composite atomic ops */ 2808ca4df32SSøren Schmidt void *driver; /* driver specific */ 2815fdbb0d2SSøren Schmidt TAILQ_ENTRY(ata_request) chain; /* list management */ 282066f913aSAlexander Motin union ccb *ccb; 28355bfaed1SSøren Schmidt }; 28455bfaed1SSøren Schmidt 285a7a120f6SSøren Schmidt /* define this for debugging request processing */ 2860e1eb682SSøren Schmidt #if 0 287a7a120f6SSøren Schmidt #define ATA_DEBUG_RQ(request, string) \ 288a7a120f6SSøren Schmidt { \ 289a7a120f6SSøren Schmidt if (request->flags & ATA_R_DEBUG) \ 290ebbb35baSAlexander Motin device_printf(request->parent, "req=%p %s " string "\n", \ 291b5dee91fSSøren Schmidt request, ata_cmd2str(request)); \ 292a7a120f6SSøren Schmidt } 293a7a120f6SSøren Schmidt #else 294a7a120f6SSøren Schmidt #define ATA_DEBUG_RQ(request, string) 295a7a120f6SSøren Schmidt #endif 296a7a120f6SSøren Schmidt 2976ddce903SSøren Schmidt /* structure describing an ATA/ATAPI device */ 2986ddce903SSøren Schmidt struct ata_device { 2998ca4df32SSøren Schmidt device_t dev; /* device handle */ 3008ca4df32SSøren Schmidt int unit; /* physical unit */ 3016ddce903SSøren Schmidt #define ATA_MASTER 0x00 302d90a6aaeSSøren Schmidt #define ATA_SLAVE 0x01 3039f82379cSSøren Schmidt #define ATA_PM 0x0f 3046ddce903SSøren Schmidt 3058ca4df32SSøren Schmidt struct ata_params param; /* ata param structure */ 3068ca4df32SSøren Schmidt int mode; /* current transfermode */ 3078ca4df32SSøren Schmidt u_int32_t max_iosize; /* max IO size */ 30872d945abSPoul-Henning Kamp int spindown; /* idle spindown timeout */ 30972d945abSPoul-Henning Kamp struct callout spindown_timer; 31072d945abSPoul-Henning Kamp int spindown_state; 3116ddce903SSøren Schmidt int flags; 3126ddce903SSøren Schmidt #define ATA_D_USE_CHS 0x0001 3138ca4df32SSøren Schmidt #define ATA_D_MEDIA_CHANGED 0x0002 3148ca4df32SSøren Schmidt #define ATA_D_ENC_PRESENT 0x0004 3156ddce903SSøren Schmidt }; 3166ddce903SSøren Schmidt 3178b68793aSSøren Schmidt /* structure for holding DMA Physical Region Descriptors (PRD) entries */ 3188b68793aSSøren Schmidt struct ata_dma_prdentry { 3198b68793aSSøren Schmidt u_int32_t addr; 3205fdbb0d2SSøren Schmidt u_int32_t count; 3215fdbb0d2SSøren Schmidt }; 3225fdbb0d2SSøren Schmidt 3238b68793aSSøren Schmidt /* structure used by the setprd function */ 3248b68793aSSøren Schmidt struct ata_dmasetprd_args { 3258b68793aSSøren Schmidt void *dmatab; 326eeda55ceSSøren Schmidt int nsegs; 3278b68793aSSøren Schmidt int error; 3288b68793aSSøren Schmidt }; 3298b68793aSSøren Schmidt 330104c094eSSøren Schmidt struct ata_dmaslot { 331104c094eSSøren Schmidt u_int8_t status; /* DMA status */ 332104c094eSSøren Schmidt bus_dma_tag_t sg_tag; /* SG list DMA tag */ 333104c094eSSøren Schmidt bus_dmamap_t sg_map; /* SG list DMA map */ 334104c094eSSøren Schmidt void *sg; /* DMA transfer table */ 335104c094eSSøren Schmidt bus_addr_t sg_bus; /* bus address of dmatab */ 336104c094eSSøren Schmidt bus_dma_tag_t data_tag; /* data DMA tag */ 337104c094eSSøren Schmidt bus_dmamap_t data_map; /* data DMA map */ 338104c094eSSøren Schmidt }; 339104c094eSSøren Schmidt 340566cf07aSSøren Schmidt /* structure holding DMA related information */ 3415fdbb0d2SSøren Schmidt struct ata_dma { 342566cf07aSSøren Schmidt bus_dma_tag_t dmatag; /* parent DMA tag */ 3438ca4df32SSøren Schmidt bus_dma_tag_t work_tag; /* workspace DMA tag */ 3448ca4df32SSøren Schmidt bus_dmamap_t work_map; /* workspace DMA map */ 3458ca4df32SSøren Schmidt u_int8_t *work; /* workspace */ 3468ca4df32SSøren Schmidt bus_addr_t work_bus; /* bus address of dmatab */ 347104c094eSSøren Schmidt 348ebbb35baSAlexander Motin #define ATA_DMA_SLOTS 1 349104c094eSSøren Schmidt int dma_slots; /* DMA slots allocated */ 350104c094eSSøren Schmidt struct ata_dmaslot slot[ATA_DMA_SLOTS]; 35140fdf812SSøren Schmidt u_int32_t alignment; /* DMA SG list alignment */ 35240fdf812SSøren Schmidt u_int32_t boundary; /* DMA SG list boundary */ 35340fdf812SSøren Schmidt u_int32_t segsize; /* DMA SG list segment size */ 35440fdf812SSøren Schmidt u_int32_t max_iosize; /* DMA data max IO size */ 355f27a1465SSøren Schmidt u_int64_t max_address; /* highest DMA'able address */ 356566cf07aSSøren Schmidt int flags; 3579f82379cSSøren Schmidt #define ATA_DMA_ACTIVE 0x01 /* DMA transfer in progress */ 358566cf07aSSøren Schmidt 359eeda55ceSSøren Schmidt void (*alloc)(device_t dev); 360eeda55ceSSøren Schmidt void (*free)(device_t dev); 3618b68793aSSøren Schmidt void (*setprd)(void *xsc, bus_dma_segment_t *segs, int nsegs, int error); 3629f82379cSSøren Schmidt int (*load)(struct ata_request *request, void *addr, int *nsegs); 3639f82379cSSøren Schmidt int (*unload)(struct ata_request *request); 3649f82379cSSøren Schmidt int (*start)(struct ata_request *request); 3659f82379cSSøren Schmidt int (*stop)(struct ata_request *request); 366eeda55ceSSøren Schmidt void (*reset)(device_t dev); 367566cf07aSSøren Schmidt }; 368566cf07aSSøren Schmidt 3695fdbb0d2SSøren Schmidt /* structure holding lowlevel functions */ 3705fdbb0d2SSøren Schmidt struct ata_lowlevel { 3719f82379cSSøren Schmidt u_int32_t (*softreset)(device_t dev, int pmport); 3729f82379cSSøren Schmidt int (*pm_read)(device_t dev, int port, int reg, u_int32_t *result); 3739f82379cSSøren Schmidt int (*pm_write)(device_t dev, int port, int reg, u_int32_t value); 374f5f55db3SSøren Schmidt int (*status)(device_t dev); 375b5dee91fSSøren Schmidt int (*begin_transaction)(struct ata_request *request); 376b5dee91fSSøren Schmidt int (*end_transaction)(struct ata_request *request); 377eeda55ceSSøren Schmidt int (*command)(struct ata_request *request); 3784c088dcdSSøren Schmidt void (*tf_read)(struct ata_request *request); 3794c088dcdSSøren Schmidt void (*tf_write)(struct ata_request *request); 3805fdbb0d2SSøren Schmidt }; 3815fdbb0d2SSøren Schmidt 382566cf07aSSøren Schmidt /* structure holding resources for an ATA channel */ 383566cf07aSSøren Schmidt struct ata_resource { 384566cf07aSSøren Schmidt struct resource *res; 385566cf07aSSøren Schmidt int offset; 386bb5bdd38SSøren Schmidt }; 387bb5bdd38SSøren Schmidt 388066f913aSAlexander Motin struct ata_cam_device { 389066f913aSAlexander Motin u_int revision; 390066f913aSAlexander Motin int mode; 391066f913aSAlexander Motin u_int bytecount; 3924cca1530SAlexander Motin u_int atapi; 39395e97044SAlexander Motin u_int caps; 394066f913aSAlexander Motin }; 395066f913aSAlexander Motin 3966ddce903SSøren Schmidt /* structure describing an ATA channel */ 3976ddce903SSøren Schmidt struct ata_channel { 3988ca4df32SSøren Schmidt device_t dev; /* device handle */ 3998ca4df32SSøren Schmidt int unit; /* physical channel */ 400b50bb79cSAlexander Motin int attached; /* channel is attached */ 401566cf07aSSøren Schmidt struct ata_resource r_io[ATA_MAX_RES];/* I/O resources */ 40247351d27SSøren Schmidt struct resource *r_irq; /* interrupt of this channel */ 4031a488af6SSøren Schmidt void *ih; /* interrupt handle */ 4045fdbb0d2SSøren Schmidt struct ata_lowlevel hw; /* lowlevel HW functions */ 4059f82379cSSøren Schmidt struct ata_dma dma; /* DMA data / functions */ 406bb5bdd38SSøren Schmidt int flags; /* channel flags */ 4078975ededSSøren Schmidt #define ATA_NO_SLAVE 0x01 4088975ededSSøren Schmidt #define ATA_USE_16BIT 0x02 4096c357737SSøren Schmidt #define ATA_ATAPI_DMA_RO 0x04 41085047b1bSSøren Schmidt #define ATA_NO_48BIT_DMA 0x08 411f5f55db3SSøren Schmidt #define ATA_ALWAYS_DMASTAT 0x10 412066f913aSAlexander Motin #define ATA_CHECKS_CABLE 0x20 413066f913aSAlexander Motin #define ATA_NO_ATAPI_DMA 0x40 414066f913aSAlexander Motin #define ATA_SATA 0x80 415351129c7SNathan Whitehorn #define ATA_DMA_BEFORE_CMD 0x100 416a250a687SAlexander Motin #define ATA_KNOWN_PRESENCE 0x200 417c14e163aSNathan Whitehorn #define ATA_STATUS_IS_LONG 0x400 418bda55b6aSAlexander Motin #define ATA_PERIODIC_POLL 0x800 4196ddce903SSøren Schmidt 4204c10f2e6SAlexander Motin int pm_level; /* power management level */ 4218563f77dSSøren Schmidt int devices; /* what is present */ 4229f82379cSSøren Schmidt #define ATA_ATA_MASTER 0x00000001 4239f82379cSSøren Schmidt #define ATA_ATA_SLAVE 0x00000002 4249f82379cSSøren Schmidt #define ATA_PORTMULTIPLIER 0x00008000 4259f82379cSSøren Schmidt #define ATA_ATAPI_MASTER 0x00010000 4269f82379cSSøren Schmidt #define ATA_ATAPI_SLAVE 0x00020000 427f63c7e58SSøren Schmidt 428b5dee91fSSøren Schmidt struct mtx state_mtx; /* state lock */ 429b5dee91fSSøren Schmidt int state; /* ATA channel state */ 4308ea3ce2aSSøren Schmidt #define ATA_IDLE 0x0000 4315fdbb0d2SSøren Schmidt #define ATA_ACTIVE 0x0001 4328ca4df32SSøren Schmidt #define ATA_STALL_QUEUE 0x0002 4338b89ef0aSSøren Schmidt 434f2972d7eSSøren Schmidt struct ata_request *running; /* currently running request */ 4356030a3f0SAlexander Motin struct task conntask; /* PHY events handling task */ 436066f913aSAlexander Motin struct cam_sim *sim; 437066f913aSAlexander Motin struct cam_path *path; 438066f913aSAlexander Motin struct ata_cam_device user[16]; /* User-specified settings */ 439066f913aSAlexander Motin struct ata_cam_device curr[16]; /* Current settings */ 440f3c987e5SAlexander Motin int requestsense; /* CCB waiting for SENSE. */ 441bda55b6aSAlexander Motin struct callout poll_callout; /* Periodic status poll. */ 442217b4e02SAlexander Motin struct ata_request request; 4438b89ef0aSSøren Schmidt }; 4448b89ef0aSSøren Schmidt 44533ede9b3SSøren Schmidt /* disk bay/enclosure related */ 4466ddce903SSøren Schmidt #define ATA_LED_OFF 0x00 4476ddce903SSøren Schmidt #define ATA_LED_RED 0x01 4486ddce903SSøren Schmidt #define ATA_LED_GREEN 0x02 4496ddce903SSøren Schmidt #define ATA_LED_ORANGE 0x03 45033ede9b3SSøren Schmidt #define ATA_LED_MASK 0x03 4516ddce903SSøren Schmidt 4522c483f9eSSøren Schmidt /* externs */ 45347351d27SSøren Schmidt extern devclass_t ata_devclass; 454854d77bdSPhilip Paeps extern int ata_dma_check_80pin; 4558b89ef0aSSøren Schmidt 4568b89ef0aSSøren Schmidt /* public prototypes */ 4575fdbb0d2SSøren Schmidt /* ata-all.c: */ 4589f06a427SSøren Schmidt int ata_probe(device_t dev); 4599f06a427SSøren Schmidt int ata_attach(device_t dev); 4609f06a427SSøren Schmidt int ata_detach(device_t dev); 4618ca4df32SSøren Schmidt int ata_reinit(device_t dev); 4629f06a427SSøren Schmidt int ata_suspend(device_t dev); 4639f06a427SSøren Schmidt int ata_resume(device_t dev); 46446a309e2SAlexander Motin void ata_interrupt(void *data); 4659f82379cSSøren Schmidt int ata_getparam(struct ata_device *atadev, int init); 4660068f98fSSøren Schmidt void ata_default_registers(device_t dev); 4670f7cfb84SSøren Schmidt void ata_udelay(int interval); 468f924768cSMarius Strobl const char *ata_cmd2str(struct ata_request *request); 469066f913aSAlexander Motin const char *ata_mode2str(int mode); 470aac18bacSAlexander Motin void ata_setmode(device_t dev); 471aac18bacSAlexander Motin void ata_print_cable(device_t dev, u_int8_t *who); 4720966baf7SMarius Strobl int ata_atapi(device_t dev, int target); 47365d2f9c1SJohn Baldwin void ata_timeout(void *); 4745fdbb0d2SSøren Schmidt 4755fdbb0d2SSøren Schmidt /* ata-lowlevel.c: */ 4760068f98fSSøren Schmidt void ata_generic_hw(device_t dev); 477f5f55db3SSøren Schmidt int ata_begin_transaction(struct ata_request *); 478f5f55db3SSøren Schmidt int ata_end_transaction(struct ata_request *); 4790068f98fSSøren Schmidt void ata_generic_reset(device_t dev); 480eeda55ceSSøren Schmidt int ata_generic_command(struct ata_request *request); 481b17f7a1aSSøren Schmidt 48293588d5cSRafal Jaworowski /* ata-dma.c: */ 48393588d5cSRafal Jaworowski void ata_dmainit(device_t); 48493588d5cSRafal Jaworowski void ata_dmafini(device_t dev); 48593588d5cSRafal Jaworowski 48693588d5cSRafal Jaworowski /* ata-sata.c: */ 487bda55b6aSAlexander Motin void ata_sata_phy_check_events(device_t dev, int port); 48893588d5cSRafal Jaworowski int ata_sata_scr_read(struct ata_channel *ch, int port, int reg, uint32_t *val); 48993588d5cSRafal Jaworowski int ata_sata_scr_write(struct ata_channel *ch, int port, int reg, uint32_t val); 49093588d5cSRafal Jaworowski int ata_sata_phy_reset(device_t dev, int port, int quick); 491066f913aSAlexander Motin int ata_sata_setmode(device_t dev, int target, int mode); 492066f913aSAlexander Motin int ata_sata_getrev(device_t dev, int target); 49393588d5cSRafal Jaworowski int ata_request2fis_h2d(struct ata_request *request, u_int8_t *fis); 49493588d5cSRafal Jaworowski void ata_pm_identify(device_t dev); 49593588d5cSRafal Jaworowski 4968ca4df32SSøren Schmidt MALLOC_DECLARE(M_ATA); 4978ca4df32SSøren Schmidt 4988ca4df32SSøren Schmidt /* misc newbus defines */ 4998ca4df32SSøren Schmidt #define GRANDPARENT(dev) device_get_parent(device_get_parent(dev)) 5005df3ca78SSøren Schmidt 5018ea3ce2aSSøren Schmidt /* macros to hide busspace uglyness */ 502b17f7a1aSSøren Schmidt #define ATA_INB(res, offset) \ 50308d2425fSPoul-Henning Kamp bus_read_1((res), (offset)) 504566cf07aSSøren Schmidt 505b17f7a1aSSøren Schmidt #define ATA_INW(res, offset) \ 50608d2425fSPoul-Henning Kamp bus_read_2((res), (offset)) 507ba514351SMarius Strobl #define ATA_INW_STRM(res, offset) \ 508ba514351SMarius Strobl bus_read_stream_2((res), (offset)) 509b17f7a1aSSøren Schmidt #define ATA_INL(res, offset) \ 51008d2425fSPoul-Henning Kamp bus_read_4((res), (offset)) 511b17f7a1aSSøren Schmidt #define ATA_INSW(res, offset, addr, count) \ 51208d2425fSPoul-Henning Kamp bus_read_multi_2((res), (offset), (addr), (count)) 5137800211bSSøren Schmidt #define ATA_INSW_STRM(res, offset, addr, count) \ 51408d2425fSPoul-Henning Kamp bus_read_multi_stream_2((res), (offset), (addr), (count)) 515b17f7a1aSSøren Schmidt #define ATA_INSL(res, offset, addr, count) \ 51608d2425fSPoul-Henning Kamp bus_read_multi_4((res), (offset), (addr), (count)) 5177800211bSSøren Schmidt #define ATA_INSL_STRM(res, offset, addr, count) \ 51808d2425fSPoul-Henning Kamp bus_read_multi_stream_4((res), (offset), (addr), (count)) 519b17f7a1aSSøren Schmidt #define ATA_OUTB(res, offset, value) \ 52008d2425fSPoul-Henning Kamp bus_write_1((res), (offset), (value)) 521b17f7a1aSSøren Schmidt #define ATA_OUTW(res, offset, value) \ 52208d2425fSPoul-Henning Kamp bus_write_2((res), (offset), (value)) 523ba514351SMarius Strobl #define ATA_OUTW_STRM(res, offset, value) \ 524ba514351SMarius Strobl bus_write_stream_2((res), (offset), (value)) 525b17f7a1aSSøren Schmidt #define ATA_OUTL(res, offset, value) \ 52608d2425fSPoul-Henning Kamp bus_write_4((res), (offset), (value)) 527b17f7a1aSSøren Schmidt #define ATA_OUTSW(res, offset, addr, count) \ 52808d2425fSPoul-Henning Kamp bus_write_multi_2((res), (offset), (addr), (count)) 5297800211bSSøren Schmidt #define ATA_OUTSW_STRM(res, offset, addr, count) \ 53008d2425fSPoul-Henning Kamp bus_write_multi_stream_2((res), (offset), (addr), (count)) 531b17f7a1aSSøren Schmidt #define ATA_OUTSL(res, offset, addr, count) \ 53208d2425fSPoul-Henning Kamp bus_write_multi_4((res), (offset), (addr), (count)) 5337800211bSSøren Schmidt #define ATA_OUTSL_STRM(res, offset, addr, count) \ 53408d2425fSPoul-Henning Kamp bus_write_multi_stream_4((res), (offset), (addr), (count)) 5351b39bd24SSøren Schmidt 536566cf07aSSøren Schmidt #define ATA_IDX_INB(ch, idx) \ 537ad452ba4SSøren Schmidt ATA_INB(ch->r_io[idx].res, ch->r_io[idx].offset) 5381b39bd24SSøren Schmidt 539566cf07aSSøren Schmidt #define ATA_IDX_INW(ch, idx) \ 540ad452ba4SSøren Schmidt ATA_INW(ch->r_io[idx].res, ch->r_io[idx].offset) 5411b39bd24SSøren Schmidt 542ba514351SMarius Strobl #define ATA_IDX_INW_STRM(ch, idx) \ 543ba514351SMarius Strobl ATA_INW_STRM(ch->r_io[idx].res, ch->r_io[idx].offset) 544ba514351SMarius Strobl 545566cf07aSSøren Schmidt #define ATA_IDX_INL(ch, idx) \ 546ad452ba4SSøren Schmidt ATA_INL(ch->r_io[idx].res, ch->r_io[idx].offset) 5471b39bd24SSøren Schmidt 548566cf07aSSøren Schmidt #define ATA_IDX_INSW(ch, idx, addr, count) \ 549ad452ba4SSøren Schmidt ATA_INSW(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) 5501b39bd24SSøren Schmidt 551566cf07aSSøren Schmidt #define ATA_IDX_INSW_STRM(ch, idx, addr, count) \ 552ad452ba4SSøren Schmidt ATA_INSW_STRM(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) 5531b39bd24SSøren Schmidt 554566cf07aSSøren Schmidt #define ATA_IDX_INSL(ch, idx, addr, count) \ 555ad452ba4SSøren Schmidt ATA_INSL(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) 5561b39bd24SSøren Schmidt 557566cf07aSSøren Schmidt #define ATA_IDX_INSL_STRM(ch, idx, addr, count) \ 558ad452ba4SSøren Schmidt ATA_INSL_STRM(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) 5591b39bd24SSøren Schmidt 560566cf07aSSøren Schmidt #define ATA_IDX_OUTB(ch, idx, value) \ 561ad452ba4SSøren Schmidt ATA_OUTB(ch->r_io[idx].res, ch->r_io[idx].offset, value) 5621b39bd24SSøren Schmidt 563566cf07aSSøren Schmidt #define ATA_IDX_OUTW(ch, idx, value) \ 564ad452ba4SSøren Schmidt ATA_OUTW(ch->r_io[idx].res, ch->r_io[idx].offset, value) 5651b39bd24SSøren Schmidt 566ba514351SMarius Strobl #define ATA_IDX_OUTW_STRM(ch, idx, value) \ 567ba514351SMarius Strobl ATA_OUTW_STRM(ch->r_io[idx].res, ch->r_io[idx].offset, value) 568ba514351SMarius Strobl 569566cf07aSSøren Schmidt #define ATA_IDX_OUTL(ch, idx, value) \ 570ad452ba4SSøren Schmidt ATA_OUTL(ch->r_io[idx].res, ch->r_io[idx].offset, value) 5711b39bd24SSøren Schmidt 572566cf07aSSøren Schmidt #define ATA_IDX_OUTSW(ch, idx, addr, count) \ 573ad452ba4SSøren Schmidt ATA_OUTSW(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) 5741b39bd24SSøren Schmidt 575566cf07aSSøren Schmidt #define ATA_IDX_OUTSW_STRM(ch, idx, addr, count) \ 576ad452ba4SSøren Schmidt ATA_OUTSW_STRM(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) 5771b39bd24SSøren Schmidt 578566cf07aSSøren Schmidt #define ATA_IDX_OUTSL(ch, idx, addr, count) \ 579ad452ba4SSøren Schmidt ATA_OUTSL(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) 5801b39bd24SSøren Schmidt 581566cf07aSSøren Schmidt #define ATA_IDX_OUTSL_STRM(ch, idx, addr, count) \ 582ad452ba4SSøren Schmidt ATA_OUTSL_STRM(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) 583