| 1 | /* | 
|---|
| 2 | * Copyright (c) 2012 Petr Jerman | 
|---|
| 3 | * All rights reserved. | 
|---|
| 4 | * | 
|---|
| 5 | * Redistribution and use in source and binary forms, with or without | 
|---|
| 6 | * modification, are permitted provided that the following conditions | 
|---|
| 7 | * are met: | 
|---|
| 8 | * | 
|---|
| 9 | * - Redistributions of source code must retain the above copyright | 
|---|
| 10 | *   notice, this list of conditions and the following disclaimer. | 
|---|
| 11 | * - Redistributions in binary form must reproduce the above copyright | 
|---|
| 12 | *   notice, this list of conditions and the following disclaimer in the | 
|---|
| 13 | *   documentation and/or other materials provided with the distribution. | 
|---|
| 14 | * - The name of the author may not be used to endorse or promote products | 
|---|
| 15 | *   derived from this software without specific prior written permission. | 
|---|
| 16 | * | 
|---|
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 
|---|
| 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 
|---|
| 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 
|---|
| 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 
|---|
| 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 
|---|
| 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
|---|
| 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
|---|
| 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
|---|
| 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 
|---|
| 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|---|
| 27 | */ | 
|---|
| 28 |  | 
|---|
| 29 | /** @file | 
|---|
| 30 | * Header for AHCI driver (SATA/ATA and related things). | 
|---|
| 31 | */ | 
|---|
| 32 |  | 
|---|
| 33 | #ifndef __AHCI_SATA_H__ | 
|---|
| 34 | #define __AHCI_SATA_H__ | 
|---|
| 35 |  | 
|---|
| 36 | #include <stdint.h> | 
|---|
| 37 |  | 
|---|
| 38 | /*----------------------------------------------------------------------------*/ | 
|---|
| 39 | /*-- SATA Buffer Lengths -----------------------------------------------------*/ | 
|---|
| 40 | /*----------------------------------------------------------------------------*/ | 
|---|
| 41 |  | 
|---|
| 42 | /** Default sector size in bytes. */ | 
|---|
| 43 | #define SATA_DEFAULT_SECTOR_SIZE  512 | 
|---|
| 44 |  | 
|---|
| 45 | /** Size for set feature command buffer in bytes. */ | 
|---|
| 46 | #define SATA_SET_FEATURE_BUFFER_LENGTH  512 | 
|---|
| 47 |  | 
|---|
| 48 | /** Size for indentify (packet) device buffer in bytes. */ | 
|---|
| 49 | #define SATA_IDENTIFY_DEVICE_BUFFER_LENGTH  512 | 
|---|
| 50 |  | 
|---|
| 51 | /*----------------------------------------------------------------------------*/ | 
|---|
| 52 | /*-- SATA Fis Frames ---------------------------------------------------------*/ | 
|---|
| 53 | /*----------------------------------------------------------------------------*/ | 
|---|
| 54 |  | 
|---|
| 55 | /** Sata FIS Type number. */ | 
|---|
| 56 | #define SATA_CMD_FIS_TYPE  0x27 | 
|---|
| 57 |  | 
|---|
| 58 | /** Sata FIS Type command indicator. */ | 
|---|
| 59 | #define SATA_CMD_FIS_COMMAND_INDICATOR  0x80 | 
|---|
| 60 |  | 
|---|
| 61 | /** Standard Command frame. */ | 
|---|
| 62 | typedef struct { | 
|---|
| 63 | /** FIS type - always SATA_CMD_FIS_TYPE. */ | 
|---|
| 64 | unsigned int fis_type : 8; | 
|---|
| 65 | /** Indicate that FIS is a Command - always SATA_CMD_FIS_COMMAND_INDICATOR. */ | 
|---|
| 66 | unsigned int c : 8; | 
|---|
| 67 | /** Command - Identity device - 0xec, Set fetures - 0xef. */ | 
|---|
| 68 | unsigned int command : 8; | 
|---|
| 69 | /** Features - subcommand for set features - set tranfer mode - 0x03. */ | 
|---|
| 70 | unsigned int features : 8; | 
|---|
| 71 | /** 0:23 bits of LBA. */ | 
|---|
| 72 | unsigned int lba_lower : 24; | 
|---|
| 73 | /** Device. */ | 
|---|
| 74 | unsigned int device : 8; | 
|---|
| 75 | /** 24:47 bits of LBA. */ | 
|---|
| 76 | unsigned int lba_upper : 24; | 
|---|
| 77 | /** Features - subcommand for set features - set tranfer mode - 0x03. */ | 
|---|
| 78 | unsigned int features_upper : 8; | 
|---|
| 79 | /** Sector count - transfer mode for set transfer mode operation. */ | 
|---|
| 80 | unsigned int count : 16; | 
|---|
| 81 | /** Reserved. */ | 
|---|
| 82 | unsigned int reserved1 : 8; | 
|---|
| 83 | /** Control. */ | 
|---|
| 84 | unsigned int control : 8; | 
|---|
| 85 | /** Reserved. */ | 
|---|
| 86 | unsigned int reserved2 : 32; | 
|---|
| 87 | } sata_std_command_frame_t; | 
|---|
| 88 |  | 
|---|
| 89 | /** Command frame for NCQ data operation. */ | 
|---|
| 90 | typedef struct { | 
|---|
| 91 | /** FIS type - always 0x27. */ | 
|---|
| 92 | uint8_t fis_type; | 
|---|
| 93 | /** Indicate that FIS is a Command - always SATA_CMD_FIS_COMMAND_INDICATOR. */ | 
|---|
| 94 | uint8_t c; | 
|---|
| 95 | /** Command - FPDMA Read - 0x60, FPDMA Write - 0x61. */ | 
|---|
| 96 | uint8_t command; | 
|---|
| 97 | /** bits 7:0 of sector count. */ | 
|---|
| 98 | uint8_t sector_count_low; | 
|---|
| 99 | /** bits 7:0 of lba. */ | 
|---|
| 100 | uint8_t lba0; | 
|---|
| 101 | /** bits 15:8 of lba. */ | 
|---|
| 102 | uint8_t lba1; | 
|---|
| 103 | /** bits 23:16 of lba. */ | 
|---|
| 104 | uint8_t lba2; | 
|---|
| 105 | uint8_t fua; | 
|---|
| 106 | /** bits 31:24 of lba. */ | 
|---|
| 107 | uint8_t lba3; | 
|---|
| 108 | /** bits 39:32 of lba. */ | 
|---|
| 109 | uint8_t lba4; | 
|---|
| 110 | /** bits 47:40 of lba. */ | 
|---|
| 111 | uint8_t lba5; | 
|---|
| 112 | /** bits 15:8 of sector count. */ | 
|---|
| 113 | uint8_t sector_count_high; | 
|---|
| 114 | /** Tag number of NCQ operation. */ | 
|---|
| 115 | uint8_t tag; | 
|---|
| 116 | /** Reserved. */ | 
|---|
| 117 | uint8_t reserved1; | 
|---|
| 118 | /** Reserved. */ | 
|---|
| 119 | uint8_t reserved2; | 
|---|
| 120 | /** Control. */ | 
|---|
| 121 | uint8_t control; | 
|---|
| 122 | /** Reserved. */ | 
|---|
| 123 | uint8_t reserved3; | 
|---|
| 124 | /** Reserved. */ | 
|---|
| 125 | uint8_t reserved4; | 
|---|
| 126 | /** Reserved. */ | 
|---|
| 127 | uint8_t reserved5; | 
|---|
| 128 | /** Reserved. */ | 
|---|
| 129 | uint8_t reserved6; | 
|---|
| 130 | } sata_ncq_command_frame_t; | 
|---|
| 131 |  | 
|---|
| 132 | /*----------------------------------------------------------------------------*/ | 
|---|
| 133 | /*-- SATA Identify device ----------------------------------------------------*/ | 
|---|
| 134 | /*----------------------------------------------------------------------------*/ | 
|---|
| 135 |  | 
|---|
| 136 | /** Data returned from identify device and identify packet device command. */ | 
|---|
| 137 | typedef struct { | 
|---|
| 138 | uint16_t gen_conf; | 
|---|
| 139 | uint16_t cylinders; | 
|---|
| 140 | uint16_t reserved2; | 
|---|
| 141 | uint16_t heads; | 
|---|
| 142 | uint16_t _vs4; | 
|---|
| 143 | uint16_t _vs5; | 
|---|
| 144 | uint16_t sectors; | 
|---|
| 145 | uint16_t _vs7; | 
|---|
| 146 | uint16_t _vs8; | 
|---|
| 147 | uint16_t _vs9; | 
|---|
| 148 |  | 
|---|
| 149 | uint16_t serial_number[10]; | 
|---|
| 150 | uint16_t _vs20; | 
|---|
| 151 | uint16_t _vs21; | 
|---|
| 152 | uint16_t vs_bytes; | 
|---|
| 153 | uint16_t firmware_rev[4]; | 
|---|
| 154 | uint16_t model_name[20]; | 
|---|
| 155 |  | 
|---|
| 156 | uint16_t max_rw_multiple; | 
|---|
| 157 | uint16_t reserved48; | 
|---|
| 158 | /* Different meaning for packet device. */ | 
|---|
| 159 | uint16_t caps; | 
|---|
| 160 | uint16_t reserved50; | 
|---|
| 161 | uint16_t pio_timing; | 
|---|
| 162 | uint16_t dma_timing; | 
|---|
| 163 |  | 
|---|
| 164 | uint16_t validity; | 
|---|
| 165 | uint16_t cur_cyl; | 
|---|
| 166 | uint16_t cur_heads; | 
|---|
| 167 | uint16_t cur_sectors; | 
|---|
| 168 | uint16_t cur_capacity0; | 
|---|
| 169 | uint16_t cur_capacity1; | 
|---|
| 170 | uint16_t mss; | 
|---|
| 171 | uint16_t total_lba28_0; | 
|---|
| 172 | uint16_t total_lba28_1; | 
|---|
| 173 | uint16_t sw_dma; | 
|---|
| 174 | uint16_t mw_dma; | 
|---|
| 175 | uint16_t pio_modes; | 
|---|
| 176 | uint16_t min_mw_dma_cycle; | 
|---|
| 177 | uint16_t rec_mw_dma_cycle; | 
|---|
| 178 | uint16_t min_raw_pio_cycle; | 
|---|
| 179 | uint16_t min_iordy_pio_cycle; | 
|---|
| 180 |  | 
|---|
| 181 | uint16_t reserved69; | 
|---|
| 182 | uint16_t reserved70; | 
|---|
| 183 | uint16_t reserved71; | 
|---|
| 184 | uint16_t reserved72; | 
|---|
| 185 | uint16_t reserved73; | 
|---|
| 186 | uint16_t reserved74; | 
|---|
| 187 |  | 
|---|
| 188 | uint16_t queue_depth; | 
|---|
| 189 | /** SATA capatibilities - different meaning for packet device. */ | 
|---|
| 190 | uint16_t sata_cap; | 
|---|
| 191 | /** SATA additional capatibilities - different meaning for packet device. */ | 
|---|
| 192 | uint16_t sata_cap2; | 
|---|
| 193 | uint16_t reserved78[1 + 79 - 78]; | 
|---|
| 194 | uint16_t version_maj; | 
|---|
| 195 | uint16_t version_min; | 
|---|
| 196 | uint16_t cmd_set0; | 
|---|
| 197 | uint16_t cmd_set1; | 
|---|
| 198 | uint16_t csf_sup_ext; | 
|---|
| 199 | uint16_t csf_enabled0; | 
|---|
| 200 | uint16_t csf_enabled1; | 
|---|
| 201 | uint16_t csf_default; | 
|---|
| 202 | uint16_t udma; | 
|---|
| 203 |  | 
|---|
| 204 | uint16_t reserved89[1 + 99 - 89]; | 
|---|
| 205 |  | 
|---|
| 206 | /* Total number of blocks in LBA-48 addressing. */ | 
|---|
| 207 | uint16_t total_lba48_0; | 
|---|
| 208 | uint16_t total_lba48_1; | 
|---|
| 209 | uint16_t total_lba48_2; | 
|---|
| 210 | uint16_t total_lba48_3; | 
|---|
| 211 |  | 
|---|
| 212 | uint16_t reserved104[1 + 105 - 104]; | 
|---|
| 213 | uint16_t physical_logic_sector_size; | 
|---|
| 214 | /* Note: more fields are defined in ATA/ATAPI-7. */ | 
|---|
| 215 | uint16_t reserved107[1 + 127 - 107]; | 
|---|
| 216 | uint16_t reserved128[1 + 159 - 128]; | 
|---|
| 217 | uint16_t reserved160[1 + 255 - 160]; | 
|---|
| 218 | } sata_identify_data_t; | 
|---|
| 219 |  | 
|---|
| 220 | /** Capability bits for register device. */ | 
|---|
| 221 | enum sata_rd_caps { | 
|---|
| 222 | sata_rd_cap_iordy = 0x0800, | 
|---|
| 223 | sata_rd_cap_iordy_cbd = 0x0400, | 
|---|
| 224 | sata_rd_cap_lba = 0x0200, | 
|---|
| 225 | sata_rd_cap_dma = 0x0100 | 
|---|
| 226 | }; | 
|---|
| 227 |  | 
|---|
| 228 | /** Bits of @c identify_data_t.cmd_set1. */ | 
|---|
| 229 | enum sata_cs1 { | 
|---|
| 230 | /** 48-bit address feature set. */ | 
|---|
| 231 | sata_cs1_addr48 = 0x0400 | 
|---|
| 232 | }; | 
|---|
| 233 |  | 
|---|
| 234 | /** SATA capatibilities for not packet device - Serial ATA revision 3_1. */ | 
|---|
| 235 | enum sata_np_caps { | 
|---|
| 236 | /** Supports READ LOG DMA EXT. */ | 
|---|
| 237 | sata_np_cap_log_ext = 0x8000, | 
|---|
| 238 | /** Supports Device Automatic Partial to Slumber transitions. */ | 
|---|
| 239 | sata_np_cap_dev_slm = 0x4000, | 
|---|
| 240 | /** Supports Host Automatic Partial to Slumber transitions. */ | 
|---|
| 241 | sata_np_cap_host_slm = 0x2000, | 
|---|
| 242 | /** Supports NCQ priority information. */ | 
|---|
| 243 | sata_np_cap_ncq_prio = 0x1000, | 
|---|
| 244 | /** Supports Unload while NCQ command outstanding. */ | 
|---|
| 245 | sata_np_cap_unload_ncq = 0x0800, | 
|---|
| 246 | /** Supports Phy event counters. */ | 
|---|
| 247 | sata_np_cap_phy_ctx = 0x0400, | 
|---|
| 248 | /** Supports recepits of host-initiated interface power management. */ | 
|---|
| 249 | sata_np_cap_host_pmngmnt = 0x0200, | 
|---|
| 250 |  | 
|---|
| 251 | /** Supports NCQ. */ | 
|---|
| 252 | sata_np_cap_ncq = 0x0100, | 
|---|
| 253 |  | 
|---|
| 254 | /** Supports SATA 3. */ | 
|---|
| 255 | sata_np_cap_sata_3 = 0x0008, | 
|---|
| 256 | /** Supports SATA 2. */ | 
|---|
| 257 | sata_np_cap_sata_2 = 0x0004, | 
|---|
| 258 | /** Supports SATA 1. */ | 
|---|
| 259 | sata_np_cap_sata_1 = 0x0002 | 
|---|
| 260 | }; | 
|---|
| 261 |  | 
|---|
| 262 | /** SATA capatibilities for packet device - Serial ATA revision 3_1. */ | 
|---|
| 263 | enum sata_pt_caps { | 
|---|
| 264 | /** Supports READ LOG DMA EXT. */ | 
|---|
| 265 | sata_pt_cap_log_ext = 0x8000, | 
|---|
| 266 | /** Supports Device Automatic Partial to Slumber transitions. */ | 
|---|
| 267 | sata_pt_cap_dev_slm = 0x4000, | 
|---|
| 268 | /** Supports Host Automatic Partial to Slumber transitions. */ | 
|---|
| 269 | sata_pt_cap_host_slm = 0x2000, | 
|---|
| 270 | /** Supports Phy event counters. */ | 
|---|
| 271 | sata_pt_cap_phy_ctx = 0x0400, | 
|---|
| 272 | /** Supports recepits of host-initiated interface power management. */ | 
|---|
| 273 | sata_pt_cap_host_pmngmnt = 0x0200, | 
|---|
| 274 |  | 
|---|
| 275 | /** Supports SATA 3. */ | 
|---|
| 276 | sata_pt_cap_sat_3 = 0x0008, | 
|---|
| 277 | /** Supports SATA 2. */ | 
|---|
| 278 | sata_pt_cap_sat_2 = 0x0004, | 
|---|
| 279 | /** Supports SATA 1. */ | 
|---|
| 280 | sata_pt_cap_sat_1 = 0x0002 | 
|---|
| 281 | }; | 
|---|
| 282 |  | 
|---|
| 283 | #endif | 
|---|