Alexander Graf | f83a40d | 2011-02-01 15:51:27 +0100 | [diff] [blame] | 1 | /* |
| 2 | * QEMU AHCI Emulation |
| 3 | * |
| 4 | * Copyright (c) 2010 qiaochong@loongson.cn |
| 5 | * Copyright (c) 2010 Roland Elek <elek.roland@gmail.com> |
| 6 | * Copyright (c) 2010 Sebastian Herbszt <herbszt@gmx.de> |
| 7 | * Copyright (c) 2010 Alexander Graf <agraf@suse.de> |
| 8 | * |
| 9 | * This library is free software; you can redistribute it and/or |
| 10 | * modify it under the terms of the GNU Lesser General Public |
| 11 | * License as published by the Free Software Foundation; either |
| 12 | * version 2 of the License, or (at your option) any later version. |
| 13 | * |
| 14 | * This library is distributed in the hope that it will be useful, |
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 17 | * Lesser General Public License for more details. |
| 18 | * |
| 19 | * You should have received a copy of the GNU Lesser General Public |
| 20 | * License along with this library; if not, see <http://www.gnu.org/licenses/>. |
| 21 | * |
| 22 | */ |
| 23 | |
Sebastian Herbszt | 03c7a6a | 2011-02-01 15:51:26 +0100 | [diff] [blame] | 24 | #ifndef HW_IDE_AHCI_H |
| 25 | #define HW_IDE_AHCI_H |
| 26 | |
Daniel Verkamp | 465f1ab | 2011-08-27 02:12:28 -0700 | [diff] [blame] | 27 | #define AHCI_MEM_BAR_SIZE 0x1000 |
Sebastian Herbszt | 03c7a6a | 2011-02-01 15:51:26 +0100 | [diff] [blame] | 28 | #define AHCI_MAX_PORTS 32 |
| 29 | #define AHCI_MAX_SG 168 /* hardware max is 64K */ |
| 30 | #define AHCI_DMA_BOUNDARY 0xffffffff |
| 31 | #define AHCI_USE_CLUSTERING 0 |
| 32 | #define AHCI_MAX_CMDS 32 |
| 33 | #define AHCI_CMD_SZ 32 |
| 34 | #define AHCI_CMD_SLOT_SZ (AHCI_MAX_CMDS * AHCI_CMD_SZ) |
| 35 | #define AHCI_RX_FIS_SZ 256 |
| 36 | #define AHCI_CMD_TBL_CDB 0x40 |
| 37 | #define AHCI_CMD_TBL_HDR_SZ 0x80 |
| 38 | #define AHCI_CMD_TBL_SZ (AHCI_CMD_TBL_HDR_SZ + (AHCI_MAX_SG * 16)) |
| 39 | #define AHCI_CMD_TBL_AR_SZ (AHCI_CMD_TBL_SZ * AHCI_MAX_CMDS) |
| 40 | #define AHCI_PORT_PRIV_DMA_SZ (AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_AR_SZ + \ |
| 41 | AHCI_RX_FIS_SZ) |
| 42 | |
| 43 | #define AHCI_IRQ_ON_SG (1 << 31) |
| 44 | #define AHCI_CMD_ATAPI (1 << 5) |
| 45 | #define AHCI_CMD_WRITE (1 << 6) |
| 46 | #define AHCI_CMD_PREFETCH (1 << 7) |
| 47 | #define AHCI_CMD_RESET (1 << 8) |
| 48 | #define AHCI_CMD_CLR_BUSY (1 << 10) |
| 49 | |
| 50 | #define RX_FIS_D2H_REG 0x40 /* offset of D2H Register FIS data */ |
| 51 | #define RX_FIS_SDB 0x58 /* offset of SDB FIS data */ |
| 52 | #define RX_FIS_UNK 0x60 /* offset of Unknown FIS data */ |
| 53 | |
| 54 | /* global controller registers */ |
| 55 | #define HOST_CAP 0x00 /* host capabilities */ |
| 56 | #define HOST_CTL 0x04 /* global host control */ |
| 57 | #define HOST_IRQ_STAT 0x08 /* interrupt status */ |
| 58 | #define HOST_PORTS_IMPL 0x0c /* bitmap of implemented ports */ |
| 59 | #define HOST_VERSION 0x10 /* AHCI spec. version compliancy */ |
| 60 | |
| 61 | /* HOST_CTL bits */ |
| 62 | #define HOST_CTL_RESET (1 << 0) /* reset controller; self-clear */ |
| 63 | #define HOST_CTL_IRQ_EN (1 << 1) /* global IRQ enable */ |
| 64 | #define HOST_CTL_AHCI_EN (1 << 31) /* AHCI enabled */ |
| 65 | |
| 66 | /* HOST_CAP bits */ |
| 67 | #define HOST_CAP_SSC (1 << 14) /* Slumber capable */ |
| 68 | #define HOST_CAP_AHCI (1 << 18) /* AHCI only */ |
| 69 | #define HOST_CAP_CLO (1 << 24) /* Command List Override support */ |
| 70 | #define HOST_CAP_SSS (1 << 27) /* Staggered Spin-up */ |
| 71 | #define HOST_CAP_NCQ (1 << 30) /* Native Command Queueing */ |
| 72 | #define HOST_CAP_64 (1 << 31) /* PCI DAC (64-bit DMA) support */ |
| 73 | |
| 74 | /* registers for each SATA port */ |
| 75 | #define PORT_LST_ADDR 0x00 /* command list DMA addr */ |
| 76 | #define PORT_LST_ADDR_HI 0x04 /* command list DMA addr hi */ |
| 77 | #define PORT_FIS_ADDR 0x08 /* FIS rx buf addr */ |
| 78 | #define PORT_FIS_ADDR_HI 0x0c /* FIS rx buf addr hi */ |
| 79 | #define PORT_IRQ_STAT 0x10 /* interrupt status */ |
| 80 | #define PORT_IRQ_MASK 0x14 /* interrupt enable/disable mask */ |
| 81 | #define PORT_CMD 0x18 /* port command */ |
| 82 | #define PORT_TFDATA 0x20 /* taskfile data */ |
| 83 | #define PORT_SIG 0x24 /* device TF signature */ |
| 84 | #define PORT_SCR_STAT 0x28 /* SATA phy register: SStatus */ |
| 85 | #define PORT_SCR_CTL 0x2c /* SATA phy register: SControl */ |
| 86 | #define PORT_SCR_ERR 0x30 /* SATA phy register: SError */ |
| 87 | #define PORT_SCR_ACT 0x34 /* SATA phy register: SActive */ |
| 88 | #define PORT_CMD_ISSUE 0x38 /* command issue */ |
| 89 | #define PORT_RESERVED 0x3c /* reserved */ |
| 90 | |
| 91 | /* PORT_IRQ_{STAT,MASK} bits */ |
| 92 | #define PORT_IRQ_COLD_PRES (1 << 31) /* cold presence detect */ |
| 93 | #define PORT_IRQ_TF_ERR (1 << 30) /* task file error */ |
| 94 | #define PORT_IRQ_HBUS_ERR (1 << 29) /* host bus fatal error */ |
| 95 | #define PORT_IRQ_HBUS_DATA_ERR (1 << 28) /* host bus data error */ |
| 96 | #define PORT_IRQ_IF_ERR (1 << 27) /* interface fatal error */ |
| 97 | #define PORT_IRQ_IF_NONFATAL (1 << 26) /* interface non-fatal error */ |
| 98 | #define PORT_IRQ_OVERFLOW (1 << 24) /* xfer exhausted available S/G */ |
| 99 | #define PORT_IRQ_BAD_PMP (1 << 23) /* incorrect port multiplier */ |
| 100 | |
| 101 | #define PORT_IRQ_PHYRDY (1 << 22) /* PhyRdy changed */ |
| 102 | #define PORT_IRQ_DEV_ILCK (1 << 7) /* device interlock */ |
| 103 | #define PORT_IRQ_CONNECT (1 << 6) /* port connect change status */ |
| 104 | #define PORT_IRQ_SG_DONE (1 << 5) /* descriptor processed */ |
| 105 | #define PORT_IRQ_UNK_FIS (1 << 4) /* unknown FIS rx'd */ |
| 106 | #define PORT_IRQ_SDB_FIS (1 << 3) /* Set Device Bits FIS rx'd */ |
| 107 | #define PORT_IRQ_DMAS_FIS (1 << 2) /* DMA Setup FIS rx'd */ |
| 108 | #define PORT_IRQ_PIOS_FIS (1 << 1) /* PIO Setup FIS rx'd */ |
| 109 | #define PORT_IRQ_D2H_REG_FIS (1 << 0) /* D2H Register FIS rx'd */ |
| 110 | |
| 111 | #define PORT_IRQ_FREEZE (PORT_IRQ_HBUS_ERR | PORT_IRQ_IF_ERR | \ |
| 112 | PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY | \ |
| 113 | PORT_IRQ_UNK_FIS) |
| 114 | #define PORT_IRQ_ERROR (PORT_IRQ_FREEZE | PORT_IRQ_TF_ERR | \ |
| 115 | PORT_IRQ_HBUS_DATA_ERR) |
| 116 | #define DEF_PORT_IRQ (PORT_IRQ_ERROR | PORT_IRQ_SG_DONE | \ |
| 117 | PORT_IRQ_SDB_FIS | PORT_IRQ_DMAS_FIS | \ |
| 118 | PORT_IRQ_PIOS_FIS | PORT_IRQ_D2H_REG_FIS) |
| 119 | |
| 120 | /* PORT_CMD bits */ |
| 121 | #define PORT_CMD_ATAPI (1 << 24) /* Device is ATAPI */ |
| 122 | #define PORT_CMD_LIST_ON (1 << 15) /* cmd list DMA engine running */ |
| 123 | #define PORT_CMD_FIS_ON (1 << 14) /* FIS DMA engine running */ |
| 124 | #define PORT_CMD_FIS_RX (1 << 4) /* Enable FIS receive DMA engine */ |
| 125 | #define PORT_CMD_CLO (1 << 3) /* Command list override */ |
| 126 | #define PORT_CMD_POWER_ON (1 << 2) /* Power up device */ |
| 127 | #define PORT_CMD_SPIN_UP (1 << 1) /* Spin up device */ |
| 128 | #define PORT_CMD_START (1 << 0) /* Enable port DMA engine */ |
| 129 | |
| 130 | #define PORT_CMD_ICC_MASK (0xf << 28) /* i/f ICC state mask */ |
| 131 | #define PORT_CMD_ICC_ACTIVE (0x1 << 28) /* Put i/f in active state */ |
| 132 | #define PORT_CMD_ICC_PARTIAL (0x2 << 28) /* Put i/f in partial state */ |
| 133 | #define PORT_CMD_ICC_SLUMBER (0x6 << 28) /* Put i/f in slumber state */ |
| 134 | |
| 135 | #define PORT_IRQ_STAT_DHRS (1 << 0) /* Device to Host Register FIS */ |
| 136 | #define PORT_IRQ_STAT_PSS (1 << 1) /* PIO Setup FIS */ |
| 137 | #define PORT_IRQ_STAT_DSS (1 << 2) /* DMA Setup FIS */ |
| 138 | #define PORT_IRQ_STAT_SDBS (1 << 3) /* Set Device Bits */ |
| 139 | #define PORT_IRQ_STAT_UFS (1 << 4) /* Unknown FIS */ |
| 140 | #define PORT_IRQ_STAT_DPS (1 << 5) /* Descriptor Processed */ |
| 141 | #define PORT_IRQ_STAT_PCS (1 << 6) /* Port Connect Change Status */ |
| 142 | #define PORT_IRQ_STAT_DMPS (1 << 7) /* Device Mechanical Presence |
| 143 | Status */ |
| 144 | #define PORT_IRQ_STAT_PRCS (1 << 22) /* File Ready Status */ |
| 145 | #define PORT_IRQ_STAT_IPMS (1 << 23) /* Incorrect Port Multiplier |
| 146 | Status */ |
| 147 | #define PORT_IRQ_STAT_OFS (1 << 24) /* Overflow Status */ |
| 148 | #define PORT_IRQ_STAT_INFS (1 << 26) /* Interface Non-Fatal Error |
| 149 | Status */ |
| 150 | #define PORT_IRQ_STAT_IFS (1 << 27) /* Interface Fatal Error */ |
| 151 | #define PORT_IRQ_STAT_HBDS (1 << 28) /* Host Bus Data Error Status */ |
| 152 | #define PORT_IRQ_STAT_HBFS (1 << 29) /* Host Bus Fatal Error Status */ |
| 153 | #define PORT_IRQ_STAT_TFES (1 << 30) /* Task File Error Status */ |
| 154 | #define PORT_IRQ_STAT_CPDS (1 << 31) /* Code Port Detect Status */ |
| 155 | |
| 156 | /* ap->flags bits */ |
| 157 | #define AHCI_FLAG_NO_NCQ (1 << 24) |
| 158 | #define AHCI_FLAG_IGN_IRQ_IF_ERR (1 << 25) /* ignore IRQ_IF_ERR */ |
| 159 | #define AHCI_FLAG_HONOR_PI (1 << 26) /* honor PORTS_IMPL */ |
| 160 | #define AHCI_FLAG_IGN_SERR_INTERNAL (1 << 27) /* ignore SERR_INTERNAL */ |
| 161 | #define AHCI_FLAG_32BIT_ONLY (1 << 28) /* force 32bit */ |
| 162 | |
| 163 | #define ATA_SRST (1 << 2) /* software reset */ |
| 164 | |
| 165 | #define STATE_RUN 0 |
| 166 | #define STATE_RESET 1 |
| 167 | |
| 168 | #define SATA_SCR_SSTATUS_DET_NODEV 0x0 |
| 169 | #define SATA_SCR_SSTATUS_DET_DEV_PRESENT_PHY_UP 0x3 |
| 170 | |
| 171 | #define SATA_SCR_SSTATUS_SPD_NODEV 0x00 |
| 172 | #define SATA_SCR_SSTATUS_SPD_GEN1 0x10 |
| 173 | |
| 174 | #define SATA_SCR_SSTATUS_IPM_NODEV 0x000 |
| 175 | #define SATA_SCR_SSTATUS_IPM_ACTIVE 0X100 |
| 176 | |
| 177 | #define AHCI_SCR_SCTL_DET 0xf |
| 178 | |
| 179 | #define SATA_FIS_TYPE_REGISTER_H2D 0x27 |
| 180 | #define SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER 0x80 |
| 181 | |
| 182 | #define AHCI_CMD_HDR_CMD_FIS_LEN 0x1f |
| 183 | #define AHCI_CMD_HDR_PRDT_LEN 16 |
| 184 | |
| 185 | #define SATA_SIGNATURE_CDROM 0xeb140000 |
| 186 | #define SATA_SIGNATURE_DISK 0x00000101 |
| 187 | |
| 188 | #define AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR 0x20 |
| 189 | /* Shouldn't this be 0x2c? */ |
| 190 | |
Sebastian Herbszt | 03c7a6a | 2011-02-01 15:51:26 +0100 | [diff] [blame] | 191 | #define AHCI_PORT_REGS_START_ADDR 0x100 |
Sebastian Herbszt | 03c7a6a | 2011-02-01 15:51:26 +0100 | [diff] [blame] | 192 | #define AHCI_PORT_ADDR_OFFSET_MASK 0x7f |
Alexander Graf | 2c4b9d0 | 2011-02-01 15:51:31 +0100 | [diff] [blame] | 193 | #define AHCI_PORT_ADDR_OFFSET_LEN 0x80 |
Sebastian Herbszt | 03c7a6a | 2011-02-01 15:51:26 +0100 | [diff] [blame] | 194 | |
| 195 | #define AHCI_NUM_COMMAND_SLOTS 31 |
| 196 | #define AHCI_SUPPORTED_SPEED 20 |
| 197 | #define AHCI_SUPPORTED_SPEED_GEN1 1 |
| 198 | #define AHCI_VERSION_1_0 0x10000 |
| 199 | |
| 200 | #define AHCI_PROGMODE_MAJOR_REV_1 1 |
| 201 | |
| 202 | #define AHCI_COMMAND_TABLE_ACMD 0x40 |
| 203 | |
| 204 | #define IDE_FEATURE_DMA 1 |
| 205 | |
| 206 | #define READ_FPDMA_QUEUED 0x60 |
| 207 | #define WRITE_FPDMA_QUEUED 0x61 |
| 208 | |
| 209 | #define RES_FIS_DSFIS 0x00 |
| 210 | #define RES_FIS_PSFIS 0x20 |
| 211 | #define RES_FIS_RFIS 0x40 |
| 212 | #define RES_FIS_SDBFIS 0x58 |
| 213 | #define RES_FIS_UFIS 0x60 |
| 214 | |
Daniel Verkamp | 465f1ab | 2011-08-27 02:12:28 -0700 | [diff] [blame] | 215 | #define SATA_CAP_SIZE 0x8 |
| 216 | #define SATA_CAP_REV 0x2 |
| 217 | #define SATA_CAP_BAR 0x4 |
| 218 | |
Sebastian Herbszt | 03c7a6a | 2011-02-01 15:51:26 +0100 | [diff] [blame] | 219 | typedef struct AHCIControlRegs { |
| 220 | uint32_t cap; |
| 221 | uint32_t ghc; |
| 222 | uint32_t irqstatus; |
| 223 | uint32_t impl; |
| 224 | uint32_t version; |
| 225 | } AHCIControlRegs; |
| 226 | |
| 227 | typedef struct AHCIPortRegs { |
| 228 | uint32_t lst_addr; |
| 229 | uint32_t lst_addr_hi; |
| 230 | uint32_t fis_addr; |
| 231 | uint32_t fis_addr_hi; |
| 232 | uint32_t irq_stat; |
| 233 | uint32_t irq_mask; |
| 234 | uint32_t cmd; |
| 235 | uint32_t unused0; |
| 236 | uint32_t tfdata; |
| 237 | uint32_t sig; |
| 238 | uint32_t scr_stat; |
| 239 | uint32_t scr_ctl; |
| 240 | uint32_t scr_err; |
| 241 | uint32_t scr_act; |
| 242 | uint32_t cmd_issue; |
| 243 | uint32_t reserved; |
| 244 | } AHCIPortRegs; |
| 245 | |
| 246 | typedef struct AHCICmdHdr { |
| 247 | uint32_t opts; |
| 248 | uint32_t status; |
| 249 | uint64_t tbl_addr; |
| 250 | uint32_t reserved[4]; |
Stefan Weil | 541dc0d | 2011-08-31 12:38:01 +0200 | [diff] [blame] | 251 | } QEMU_PACKED AHCICmdHdr; |
Sebastian Herbszt | 03c7a6a | 2011-02-01 15:51:26 +0100 | [diff] [blame] | 252 | |
| 253 | typedef struct AHCI_SG { |
| 254 | uint64_t addr; |
| 255 | uint32_t reserved; |
| 256 | uint32_t flags_size; |
Stefan Weil | 541dc0d | 2011-08-31 12:38:01 +0200 | [diff] [blame] | 257 | } QEMU_PACKED AHCI_SG; |
Sebastian Herbszt | 03c7a6a | 2011-02-01 15:51:26 +0100 | [diff] [blame] | 258 | |
| 259 | typedef struct AHCIDevice AHCIDevice; |
| 260 | |
| 261 | typedef struct NCQTransferState { |
| 262 | AHCIDevice *drive; |
| 263 | BlockDriverAIOCB *aiocb; |
| 264 | QEMUSGList sglist; |
Christoph Hellwig | a597e79 | 2011-08-25 08:26:01 +0200 | [diff] [blame] | 265 | BlockAcctCookie acct; |
Sebastian Herbszt | 03c7a6a | 2011-02-01 15:51:26 +0100 | [diff] [blame] | 266 | uint16_t sector_count; |
| 267 | uint64_t lba; |
| 268 | uint8_t tag; |
| 269 | int slot; |
| 270 | int used; |
| 271 | } NCQTransferState; |
| 272 | |
| 273 | struct AHCIDevice { |
| 274 | IDEDMA dma; |
| 275 | IDEBus port; |
| 276 | int port_no; |
| 277 | uint32_t port_state; |
| 278 | uint32_t finished; |
| 279 | AHCIPortRegs port_regs; |
| 280 | struct AHCIState *hba; |
| 281 | QEMUBH *check_bh; |
| 282 | uint8_t *lst; |
| 283 | uint8_t *res_fis; |
Kevin Wolf | 4ac557c | 2013-01-15 16:12:09 +0100 | [diff] [blame] | 284 | bool done_atapi_packet; |
| 285 | int32_t busy_slot; |
| 286 | bool init_d2h_sent; |
Sebastian Herbszt | 03c7a6a | 2011-02-01 15:51:26 +0100 | [diff] [blame] | 287 | AHCICmdHdr *cur_cmd; |
| 288 | NCQTransferState ncq_tfs[AHCI_MAX_CMDS]; |
| 289 | }; |
| 290 | |
| 291 | typedef struct AHCIState { |
Alexander Graf | 2c4b9d0 | 2011-02-01 15:51:31 +0100 | [diff] [blame] | 292 | AHCIDevice *dev; |
Sebastian Herbszt | 03c7a6a | 2011-02-01 15:51:26 +0100 | [diff] [blame] | 293 | AHCIControlRegs control_regs; |
Avi Kivity | 67e576c | 2011-08-08 16:09:14 +0300 | [diff] [blame] | 294 | MemoryRegion mem; |
Daniel Verkamp | 465f1ab | 2011-08-27 02:12:28 -0700 | [diff] [blame] | 295 | MemoryRegion idp; /* Index-Data Pair I/O port space */ |
| 296 | unsigned idp_offset; /* Offset of index in I/O port space */ |
| 297 | uint32_t idp_index; /* Current IDP index */ |
Kevin Wolf | 4ac557c | 2013-01-15 16:12:09 +0100 | [diff] [blame] | 298 | int32_t ports; |
Sebastian Herbszt | 03c7a6a | 2011-02-01 15:51:26 +0100 | [diff] [blame] | 299 | qemu_irq irq; |
Paolo Bonzini | df32fd1 | 2013-04-10 18:15:49 +0200 | [diff] [blame] | 300 | AddressSpace *as; |
Sebastian Herbszt | 03c7a6a | 2011-02-01 15:51:26 +0100 | [diff] [blame] | 301 | } AHCIState; |
| 302 | |
| 303 | typedef struct AHCIPCIState { |
Andreas Färber | 0d3aea5 | 2013-06-30 14:19:24 +0200 | [diff] [blame] | 304 | /*< private >*/ |
| 305 | PCIDevice parent_obj; |
| 306 | /*< public >*/ |
| 307 | |
Sebastian Herbszt | 03c7a6a | 2011-02-01 15:51:26 +0100 | [diff] [blame] | 308 | AHCIState ahci; |
| 309 | } AHCIPCIState; |
| 310 | |
Peter Crosthwaite | fd58922 | 2013-06-24 16:55:45 +1000 | [diff] [blame] | 311 | #define TYPE_ICH9_AHCI "ich9-ahci" |
| 312 | |
| 313 | #define ICH_AHCI(obj) \ |
| 314 | OBJECT_CHECK(AHCIPCIState, (obj), TYPE_ICH9_AHCI) |
| 315 | |
Jason Baron | a262302 | 2013-01-04 14:44:42 -0500 | [diff] [blame] | 316 | extern const VMStateDescription vmstate_ahci; |
| 317 | |
| 318 | #define VMSTATE_AHCI(_field, _state) { \ |
| 319 | .name = (stringify(_field)), \ |
| 320 | .size = sizeof(AHCIState), \ |
| 321 | .vmsd = &vmstate_ahci, \ |
| 322 | .flags = VMS_STRUCT, \ |
| 323 | .offset = vmstate_offset_value(_state, _field, AHCIState), \ |
| 324 | } |
| 325 | |
Sebastian Herbszt | 03c7a6a | 2011-02-01 15:51:26 +0100 | [diff] [blame] | 326 | typedef struct NCQFrame { |
| 327 | uint8_t fis_type; |
| 328 | uint8_t c; |
| 329 | uint8_t command; |
| 330 | uint8_t sector_count_low; |
| 331 | uint8_t lba0; |
| 332 | uint8_t lba1; |
| 333 | uint8_t lba2; |
| 334 | uint8_t fua; |
| 335 | uint8_t lba3; |
| 336 | uint8_t lba4; |
| 337 | uint8_t lba5; |
| 338 | uint8_t sector_count_high; |
| 339 | uint8_t tag; |
| 340 | uint8_t reserved5; |
| 341 | uint8_t reserved6; |
| 342 | uint8_t control; |
| 343 | uint8_t reserved7; |
| 344 | uint8_t reserved8; |
| 345 | uint8_t reserved9; |
| 346 | uint8_t reserved10; |
Stefan Weil | 541dc0d | 2011-08-31 12:38:01 +0200 | [diff] [blame] | 347 | } QEMU_PACKED NCQFrame; |
Sebastian Herbszt | 03c7a6a | 2011-02-01 15:51:26 +0100 | [diff] [blame] | 348 | |
Paolo Bonzini | df32fd1 | 2013-04-10 18:15:49 +0200 | [diff] [blame] | 349 | void ahci_init(AHCIState *s, DeviceState *qdev, AddressSpace *as, int ports); |
Alexander Graf | 2c4b9d0 | 2011-02-01 15:51:31 +0100 | [diff] [blame] | 350 | void ahci_uninit(AHCIState *s); |
Sebastian Herbszt | 03c7a6a | 2011-02-01 15:51:26 +0100 | [diff] [blame] | 351 | |
Jan Kiszka | 8ab60a0 | 2012-05-11 11:42:36 -0300 | [diff] [blame] | 352 | void ahci_reset(AHCIState *s); |
Sebastian Herbszt | 03c7a6a | 2011-02-01 15:51:26 +0100 | [diff] [blame] | 353 | |
| 354 | #endif /* HW_IDE_AHCI_H */ |