[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-block] [PATCH 01/13] ide: move headers to include folder
From: |
Paolo Bonzini |
Subject: |
Re: [Qemu-block] [PATCH 01/13] ide: move headers to include folder |
Date: |
Fri, 17 Jun 2016 15:18:22 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.1.0 |
On 17/06/2016 15:10, Efimov Vasily wrote:
> The patch moves "hw/ide/achi.h", "hw/ide/pci.h" and "hw/ide/internal.h"
> headers
> to corresponding folders inside "include" folder alike other Qemu headers.
>
> Signed-off-by: Efimov Vasily <address@hidden>
> ---
> This patch only moves headers (with the exception of include path correction
> in 'ahci.c'). checkpatch.pl reports a lot of problems with legacy code in
> these headers but I think this patch is not the place to fix these problem
Use "git config --global diff.renames true". The patch will be shorter
and checkpatch will stop complaining!
> ---
> hw/ide/ahci.c | 2 +-
> hw/ide/ahci.h | 405 -----------------------------
> hw/ide/internal.h | 635
> ----------------------------------------------
> hw/ide/pci.h | 76 ------
> include/hw/ide/ahci.h | 405 +++++++++++++++++++++++++++++
> include/hw/ide/internal.h | 635
> ++++++++++++++++++++++++++++++++++++++++++++++
> include/hw/ide/pci.h | 76 ++++++
> 7 files changed, 1117 insertions(+), 1117 deletions(-)
> delete mode 100644 hw/ide/ahci.h
> delete mode 100644 hw/ide/internal.h
> delete mode 100644 hw/ide/pci.h
> create mode 100644 include/hw/ide/ahci.h
> create mode 100644 include/hw/ide/internal.h
> create mode 100644 include/hw/ide/pci.h
>
> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
> index 502d4f1..b1a7b65 100644
> --- a/hw/ide/ahci.c
> +++ b/hw/ide/ahci.c
> @@ -30,7 +30,7 @@
> #include "qemu/error-report.h"
> #include "sysemu/block-backend.h"
> #include "sysemu/dma.h"
> -#include "internal.h"
> +#include <hw/ide/internal.h>
> #include <hw/ide/pci.h>
> #include <hw/ide/ahci.h>
>
> diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h
> deleted file mode 100644
> index bc777ed..0000000
> --- a/hw/ide/ahci.h
> +++ /dev/null
> @@ -1,405 +0,0 @@
> -/*
> - * QEMU AHCI Emulation
> - *
> - * Copyright (c) 2010 address@hidden
> - * Copyright (c) 2010 Roland Elek <address@hidden>
> - * Copyright (c) 2010 Sebastian Herbszt <address@hidden>
> - * Copyright (c) 2010 Alexander Graf <address@hidden>
> - *
> - * This library is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU Lesser General Public
> - * License as published by the Free Software Foundation; either
> - * version 2 of the License, or (at your option) any later version.
> - *
> - * This library is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - * Lesser General Public License for more details.
> - *
> - * You should have received a copy of the GNU Lesser General Public
> - * License along with this library; if not, see
> <http://www.gnu.org/licenses/>.
> - *
> - */
> -
> -#ifndef HW_IDE_AHCI_H
> -#define HW_IDE_AHCI_H
> -
> -#include <hw/sysbus.h>
> -
> -#define AHCI_MEM_BAR_SIZE 0x1000
> -#define AHCI_MAX_PORTS 32
> -#define AHCI_MAX_SG 168 /* hardware max is 64K */
> -#define AHCI_DMA_BOUNDARY 0xffffffff
> -#define AHCI_USE_CLUSTERING 0
> -#define AHCI_MAX_CMDS 32
> -#define AHCI_CMD_SZ 32
> -#define AHCI_CMD_SLOT_SZ (AHCI_MAX_CMDS * AHCI_CMD_SZ)
> -#define AHCI_RX_FIS_SZ 256
> -#define AHCI_CMD_TBL_CDB 0x40
> -#define AHCI_CMD_TBL_HDR_SZ 0x80
> -#define AHCI_CMD_TBL_SZ (AHCI_CMD_TBL_HDR_SZ + (AHCI_MAX_SG * 16))
> -#define AHCI_CMD_TBL_AR_SZ (AHCI_CMD_TBL_SZ * AHCI_MAX_CMDS)
> -#define AHCI_PORT_PRIV_DMA_SZ (AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_AR_SZ + \
> - AHCI_RX_FIS_SZ)
> -
> -#define AHCI_IRQ_ON_SG (1U << 31)
> -#define AHCI_CMD_ATAPI (1 << 5)
> -#define AHCI_CMD_WRITE (1 << 6)
> -#define AHCI_CMD_PREFETCH (1 << 7)
> -#define AHCI_CMD_RESET (1 << 8)
> -#define AHCI_CMD_CLR_BUSY (1 << 10)
> -
> -#define RX_FIS_D2H_REG 0x40 /* offset of D2H Register FIS data */
> -#define RX_FIS_SDB 0x58 /* offset of SDB FIS data */
> -#define RX_FIS_UNK 0x60 /* offset of Unknown FIS data */
> -
> -/* global controller registers */
> -#define HOST_CAP 0x00 /* host capabilities */
> -#define HOST_CTL 0x04 /* global host control */
> -#define HOST_IRQ_STAT 0x08 /* interrupt status */
> -#define HOST_PORTS_IMPL 0x0c /* bitmap of implemented ports */
> -#define HOST_VERSION 0x10 /* AHCI spec. version compliancy */
> -
> -/* HOST_CTL bits */
> -#define HOST_CTL_RESET (1 << 0) /* reset controller; self-clear
> */
> -#define HOST_CTL_IRQ_EN (1 << 1) /* global IRQ enable */
> -#define HOST_CTL_AHCI_EN (1U << 31) /* AHCI enabled */
> -
> -/* HOST_CAP bits */
> -#define HOST_CAP_SSC (1 << 14) /* Slumber capable */
> -#define HOST_CAP_AHCI (1 << 18) /* AHCI only */
> -#define HOST_CAP_CLO (1 << 24) /* Command List Override support
> */
> -#define HOST_CAP_SSS (1 << 27) /* Staggered Spin-up */
> -#define HOST_CAP_NCQ (1 << 30) /* Native Command Queueing */
> -#define HOST_CAP_64 (1U << 31) /* PCI DAC (64-bit DMA) support
> */
> -
> -/* registers for each SATA port */
> -#define PORT_LST_ADDR 0x00 /* command list DMA addr */
> -#define PORT_LST_ADDR_HI 0x04 /* command list DMA addr hi */
> -#define PORT_FIS_ADDR 0x08 /* FIS rx buf addr */
> -#define PORT_FIS_ADDR_HI 0x0c /* FIS rx buf addr hi */
> -#define PORT_IRQ_STAT 0x10 /* interrupt status */
> -#define PORT_IRQ_MASK 0x14 /* interrupt enable/disable mask */
> -#define PORT_CMD 0x18 /* port command */
> -#define PORT_TFDATA 0x20 /* taskfile data */
> -#define PORT_SIG 0x24 /* device TF signature */
> -#define PORT_SCR_STAT 0x28 /* SATA phy register: SStatus */
> -#define PORT_SCR_CTL 0x2c /* SATA phy register: SControl */
> -#define PORT_SCR_ERR 0x30 /* SATA phy register: SError */
> -#define PORT_SCR_ACT 0x34 /* SATA phy register: SActive */
> -#define PORT_CMD_ISSUE 0x38 /* command issue */
> -#define PORT_RESERVED 0x3c /* reserved */
> -
> -/* PORT_IRQ_{STAT,MASK} bits */
> -#define PORT_IRQ_COLD_PRES (1U << 31) /* cold presence detect */
> -#define PORT_IRQ_TF_ERR (1 << 30) /* task file error */
> -#define PORT_IRQ_HBUS_ERR (1 << 29) /* host bus fatal error */
> -#define PORT_IRQ_HBUS_DATA_ERR (1 << 28) /* host bus data error */
> -#define PORT_IRQ_IF_ERR (1 << 27) /* interface fatal error */
> -#define PORT_IRQ_IF_NONFATAL (1 << 26) /* interface non-fatal error */
> -#define PORT_IRQ_OVERFLOW (1 << 24) /* xfer exhausted available S/G
> */
> -#define PORT_IRQ_BAD_PMP (1 << 23) /* incorrect port multiplier */
> -
> -#define PORT_IRQ_PHYRDY (1 << 22) /* PhyRdy changed */
> -#define PORT_IRQ_DEV_ILCK (1 << 7) /* device interlock */
> -#define PORT_IRQ_CONNECT (1 << 6) /* port connect change status */
> -#define PORT_IRQ_SG_DONE (1 << 5) /* descriptor processed */
> -#define PORT_IRQ_UNK_FIS (1 << 4) /* unknown FIS rx'd */
> -#define PORT_IRQ_SDB_FIS (1 << 3) /* Set Device Bits FIS rx'd */
> -#define PORT_IRQ_DMAS_FIS (1 << 2) /* DMA Setup FIS rx'd */
> -#define PORT_IRQ_PIOS_FIS (1 << 1) /* PIO Setup FIS rx'd */
> -#define PORT_IRQ_D2H_REG_FIS (1 << 0) /* D2H Register FIS rx'd */
> -
> -#define PORT_IRQ_FREEZE (PORT_IRQ_HBUS_ERR | PORT_IRQ_IF_ERR | \
> - PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY | \
> - PORT_IRQ_UNK_FIS)
> -#define PORT_IRQ_ERROR (PORT_IRQ_FREEZE | PORT_IRQ_TF_ERR | \
> - PORT_IRQ_HBUS_DATA_ERR)
> -#define DEF_PORT_IRQ (PORT_IRQ_ERROR | PORT_IRQ_SG_DONE | \
> - PORT_IRQ_SDB_FIS | PORT_IRQ_DMAS_FIS | \
> - PORT_IRQ_PIOS_FIS | PORT_IRQ_D2H_REG_FIS)
> -
> -/* PORT_CMD bits */
> -#define PORT_CMD_ATAPI (1 << 24) /* Device is ATAPI */
> -#define PORT_CMD_LIST_ON (1 << 15) /* cmd list DMA engine running */
> -#define PORT_CMD_FIS_ON (1 << 14) /* FIS DMA engine running */
> -#define PORT_CMD_FIS_RX (1 << 4) /* Enable FIS receive DMA engine
> */
> -#define PORT_CMD_CLO (1 << 3) /* Command list override */
> -#define PORT_CMD_POWER_ON (1 << 2) /* Power up device */
> -#define PORT_CMD_SPIN_UP (1 << 1) /* Spin up device */
> -#define PORT_CMD_START (1 << 0) /* Enable port DMA engine */
> -
> -#define PORT_CMD_ICC_MASK (0xfU << 28) /* i/f ICC state mask */
> -#define PORT_CMD_ICC_ACTIVE (0x1 << 28) /* Put i/f in active state */
> -#define PORT_CMD_ICC_PARTIAL (0x2 << 28) /* Put i/f in partial state */
> -#define PORT_CMD_ICC_SLUMBER (0x6 << 28) /* Put i/f in slumber state */
> -
> -#define PORT_CMD_RO_MASK 0x007dffe0 /* Which CMD bits are read
> only? */
> -
> -/* ap->flags bits */
> -#define AHCI_FLAG_NO_NCQ (1 << 24)
> -#define AHCI_FLAG_IGN_IRQ_IF_ERR (1 << 25) /* ignore IRQ_IF_ERR */
> -#define AHCI_FLAG_HONOR_PI (1 << 26) /* honor PORTS_IMPL */
> -#define AHCI_FLAG_IGN_SERR_INTERNAL (1 << 27) /* ignore SERR_INTERNAL
> */
> -#define AHCI_FLAG_32BIT_ONLY (1 << 28) /* force 32bit */
> -
> -#define ATA_SRST (1 << 2) /* software reset */
> -
> -#define STATE_RUN 0
> -#define STATE_RESET 1
> -
> -#define SATA_SCR_SSTATUS_DET_NODEV 0x0
> -#define SATA_SCR_SSTATUS_DET_DEV_PRESENT_PHY_UP 0x3
> -
> -#define SATA_SCR_SSTATUS_SPD_NODEV 0x00
> -#define SATA_SCR_SSTATUS_SPD_GEN1 0x10
> -
> -#define SATA_SCR_SSTATUS_IPM_NODEV 0x000
> -#define SATA_SCR_SSTATUS_IPM_ACTIVE 0X100
> -
> -#define AHCI_SCR_SCTL_DET 0xf
> -
> -#define SATA_FIS_TYPE_REGISTER_H2D 0x27
> -#define SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER 0x80
> -#define SATA_FIS_TYPE_REGISTER_D2H 0x34
> -#define SATA_FIS_TYPE_PIO_SETUP 0x5f
> -#define SATA_FIS_TYPE_SDB 0xA1
> -
> -#define AHCI_CMD_HDR_CMD_FIS_LEN 0x1f
> -#define AHCI_CMD_HDR_PRDT_LEN 16
> -
> -#define SATA_SIGNATURE_CDROM 0xeb140101
> -#define SATA_SIGNATURE_DISK 0x00000101
> -
> -#define AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR 0x20
> - /* Shouldn't this be 0x2c? */
> -
> -#define AHCI_PORT_REGS_START_ADDR 0x100
> -#define AHCI_PORT_ADDR_OFFSET_MASK 0x7f
> -#define AHCI_PORT_ADDR_OFFSET_LEN 0x80
> -
> -#define AHCI_NUM_COMMAND_SLOTS 31
> -#define AHCI_SUPPORTED_SPEED 20
> -#define AHCI_SUPPORTED_SPEED_GEN1 1
> -#define AHCI_VERSION_1_0 0x10000
> -
> -#define AHCI_PROGMODE_MAJOR_REV_1 1
> -
> -#define AHCI_COMMAND_TABLE_ACMD 0x40
> -
> -#define AHCI_PRDT_SIZE_MASK 0x3fffff
> -
> -#define IDE_FEATURE_DMA 1
> -
> -#define READ_FPDMA_QUEUED 0x60
> -#define WRITE_FPDMA_QUEUED 0x61
> -#define NCQ_NON_DATA 0x63
> -#define RECEIVE_FPDMA_QUEUED 0x65
> -#define SEND_FPDMA_QUEUED 0x64
> -
> -#define NCQ_FIS_FUA_MASK 0x80
> -#define NCQ_FIS_RARC_MASK 0x01
> -
> -#define RES_FIS_DSFIS 0x00
> -#define RES_FIS_PSFIS 0x20
> -#define RES_FIS_RFIS 0x40
> -#define RES_FIS_SDBFIS 0x58
> -#define RES_FIS_UFIS 0x60
> -
> -#define SATA_CAP_SIZE 0x8
> -#define SATA_CAP_REV 0x2
> -#define SATA_CAP_BAR 0x4
> -
> -typedef struct AHCIControlRegs {
> - uint32_t cap;
> - uint32_t ghc;
> - uint32_t irqstatus;
> - uint32_t impl;
> - uint32_t version;
> -} AHCIControlRegs;
> -
> -typedef struct AHCIPortRegs {
> - uint32_t lst_addr;
> - uint32_t lst_addr_hi;
> - uint32_t fis_addr;
> - uint32_t fis_addr_hi;
> - uint32_t irq_stat;
> - uint32_t irq_mask;
> - uint32_t cmd;
> - uint32_t unused0;
> - uint32_t tfdata;
> - uint32_t sig;
> - uint32_t scr_stat;
> - uint32_t scr_ctl;
> - uint32_t scr_err;
> - uint32_t scr_act;
> - uint32_t cmd_issue;
> - uint32_t reserved;
> -} AHCIPortRegs;
> -
> -typedef struct AHCICmdHdr {
> - uint16_t opts;
> - uint16_t prdtl;
> - uint32_t status;
> - uint64_t tbl_addr;
> - uint32_t reserved[4];
> -} QEMU_PACKED AHCICmdHdr;
> -
> -typedef struct AHCI_SG {
> - uint64_t addr;
> - uint32_t reserved;
> - uint32_t flags_size;
> -} QEMU_PACKED AHCI_SG;
> -
> -typedef struct AHCIDevice AHCIDevice;
> -
> -typedef struct NCQTransferState {
> - AHCIDevice *drive;
> - BlockAIOCB *aiocb;
> - AHCICmdHdr *cmdh;
> - QEMUSGList sglist;
> - BlockAcctCookie acct;
> - uint32_t sector_count;
> - uint64_t lba;
> - uint8_t tag;
> - uint8_t cmd;
> - uint8_t slot;
> - bool used;
> - bool halt;
> -} NCQTransferState;
> -
> -struct AHCIDevice {
> - IDEDMA dma;
> - IDEBus port;
> - int port_no;
> - uint32_t port_state;
> - uint32_t finished;
> - AHCIPortRegs port_regs;
> - struct AHCIState *hba;
> - QEMUBH *check_bh;
> - uint8_t *lst;
> - uint8_t *res_fis;
> - bool done_atapi_packet;
> - int32_t busy_slot;
> - bool init_d2h_sent;
> - AHCICmdHdr *cur_cmd;
> - NCQTransferState ncq_tfs[AHCI_MAX_CMDS];
> -};
> -
> -typedef struct AHCIState {
> - DeviceState *container;
> -
> - AHCIDevice *dev;
> - AHCIControlRegs control_regs;
> - MemoryRegion mem;
> - MemoryRegion idp; /* Index-Data Pair I/O port space */
> - unsigned idp_offset; /* Offset of index in I/O port space */
> - uint32_t idp_index; /* Current IDP index */
> - int32_t ports;
> - qemu_irq irq;
> - AddressSpace *as;
> -} AHCIState;
> -
> -typedef struct AHCIPCIState {
> - /*< private >*/
> - PCIDevice parent_obj;
> - /*< public >*/
> -
> - AHCIState ahci;
> -} AHCIPCIState;
> -
> -#define TYPE_ICH9_AHCI "ich9-ahci"
> -
> -#define ICH_AHCI(obj) \
> - OBJECT_CHECK(AHCIPCIState, (obj), TYPE_ICH9_AHCI)
> -
> -extern const VMStateDescription vmstate_ahci;
> -
> -#define VMSTATE_AHCI(_field, _state) { \
> - .name = (stringify(_field)), \
> - .size = sizeof(AHCIState), \
> - .vmsd = &vmstate_ahci, \
> - .flags = VMS_STRUCT, \
> - .offset = vmstate_offset_value(_state, _field, AHCIState), \
> -}
> -
> -/**
> - * NCQFrame is the same as a Register H2D FIS (described in SATA 3.2),
> - * but some fields have been re-mapped and re-purposed, as seen in
> - * SATA 3.2 section 13.6.4.1 ("READ FPDMA QUEUED")
> - *
> - * cmd_fis[3], feature 7:0, becomes sector count 7:0.
> - * cmd_fis[7], device 7:0, uses bit 7 as the Force Unit Access bit.
> - * cmd_fis[11], feature 15:8, becomes sector count 15:8.
> - * cmd_fis[12], count 7:0, becomes the NCQ TAG (7:3) and RARC bit (0)
> - * cmd_fis[13], count 15:8, becomes the priority value (7:6)
> - * bytes 16-19 become an le32 "auxiliary" field.
> - */
> -typedef struct NCQFrame {
> - uint8_t fis_type;
> - uint8_t c;
> - uint8_t command;
> - uint8_t sector_count_low; /* (feature 7:0) */
> - uint8_t lba0;
> - uint8_t lba1;
> - uint8_t lba2;
> - uint8_t fua; /* (device 7:0) */
> - uint8_t lba3;
> - uint8_t lba4;
> - uint8_t lba5;
> - uint8_t sector_count_high; /* (feature 15:8) */
> - uint8_t tag; /* (count 0:7) */
> - uint8_t prio; /* (count 15:8) */
> - uint8_t icc;
> - uint8_t control;
> - uint8_t aux0;
> - uint8_t aux1;
> - uint8_t aux2;
> - uint8_t aux3;
> -} QEMU_PACKED NCQFrame;
> -
> -typedef struct SDBFIS {
> - uint8_t type;
> - uint8_t flags;
> - uint8_t status;
> - uint8_t error;
> - uint32_t payload;
> -} QEMU_PACKED SDBFIS;
> -
> -void ahci_realize(AHCIState *s, DeviceState *qdev, AddressSpace *as, int
> ports);
> -void ahci_init(AHCIState *s, DeviceState *qdev);
> -void ahci_uninit(AHCIState *s);
> -
> -void ahci_reset(AHCIState *s);
> -
> -void ahci_ide_create_devs(PCIDevice *dev, DriveInfo **hd);
> -
> -#define TYPE_SYSBUS_AHCI "sysbus-ahci"
> -#define SYSBUS_AHCI(obj) OBJECT_CHECK(SysbusAHCIState, (obj),
> TYPE_SYSBUS_AHCI)
> -
> -typedef struct SysbusAHCIState {
> - /*< private >*/
> - SysBusDevice parent_obj;
> - /*< public >*/
> -
> - AHCIState ahci;
> - uint32_t num_ports;
> -} SysbusAHCIState;
> -
> -#define TYPE_ALLWINNER_AHCI "allwinner-ahci"
> -#define ALLWINNER_AHCI(obj) OBJECT_CHECK(AllwinnerAHCIState, (obj), \
> - TYPE_ALLWINNER_AHCI)
> -
> -#define ALLWINNER_AHCI_MMIO_OFF 0x80
> -#define ALLWINNER_AHCI_MMIO_SIZE 0x80
> -
> -struct AllwinnerAHCIState {
> - /*< private >*/
> - SysbusAHCIState parent_obj;
> - /*< public >*/
> -
> - MemoryRegion mmio;
> - uint32_t regs[ALLWINNER_AHCI_MMIO_SIZE/4];
> -};
> -
> -#endif /* HW_IDE_AHCI_H */
> diff --git a/hw/ide/internal.h b/hw/ide/internal.h
> deleted file mode 100644
> index 773928a..0000000
> --- a/hw/ide/internal.h
> +++ /dev/null
> @@ -1,635 +0,0 @@
> -#ifndef HW_IDE_INTERNAL_H
> -#define HW_IDE_INTERNAL_H
> -
> -/*
> - * QEMU IDE Emulation -- internal header file
> - * only files in hw/ide/ are supposed to include this file.
> - * non-internal declarations are in hw/ide.h
> - */
> -#include <hw/ide.h>
> -#include <hw/isa/isa.h>
> -#include "sysemu/dma.h"
> -#include "sysemu/sysemu.h"
> -#include "hw/block/block.h"
> -#include "block/scsi.h"
> -
> -/* debug IDE devices */
> -//#define DEBUG_IDE
> -//#define DEBUG_IDE_ATAPI
> -//#define DEBUG_AIO
> -#define USE_DMA_CDROM
> -
> -typedef struct IDEBus IDEBus;
> -typedef struct IDEDevice IDEDevice;
> -typedef struct IDEState IDEState;
> -typedef struct IDEDMA IDEDMA;
> -typedef struct IDEDMAOps IDEDMAOps;
> -
> -#define TYPE_IDE_BUS "IDE"
> -#define IDE_BUS(obj) OBJECT_CHECK(IDEBus, (obj), TYPE_IDE_BUS)
> -
> -/* Bits of HD_STATUS */
> -#define ERR_STAT 0x01
> -#define INDEX_STAT 0x02
> -#define ECC_STAT 0x04 /* Corrected error */
> -#define DRQ_STAT 0x08
> -#define SEEK_STAT 0x10
> -#define SRV_STAT 0x10
> -#define WRERR_STAT 0x20
> -#define READY_STAT 0x40
> -#define BUSY_STAT 0x80
> -
> -/* Bits for HD_ERROR */
> -#define MARK_ERR 0x01 /* Bad address mark */
> -#define TRK0_ERR 0x02 /* couldn't find track 0 */
> -#define ABRT_ERR 0x04 /* Command aborted */
> -#define MCR_ERR 0x08 /* media change request */
> -#define ID_ERR 0x10 /* ID field not found */
> -#define MC_ERR 0x20 /* media changed */
> -#define ECC_ERR 0x40 /* Uncorrectable ECC error */
> -#define BBD_ERR 0x80 /* pre-EIDE meaning: block
> marked bad */
> -#define ICRC_ERR 0x80 /* new meaning: CRC error during
> transfer */
> -
> -/* Bits of HD_NSECTOR */
> -#define CD 0x01
> -#define IO 0x02
> -#define REL 0x04
> -#define TAG_MASK 0xf8
> -
> -#define IDE_CMD_RESET 0x04
> -#define IDE_CMD_DISABLE_IRQ 0x02
> -
> -/* ACS-2 T13/2015-D Table B.2 Command codes */
> -#define WIN_NOP 0x00
> -/* reserved 0x01..0x02 */
> -#define CFA_REQ_EXT_ERROR_CODE 0x03 /* CFA Request Extended
> Error Code */
> -/* reserved 0x04..0x05 */
> -#define WIN_DSM 0x06
> -/* reserved 0x07 */
> -#define WIN_DEVICE_RESET 0x08
> -/* reserved 0x09..0x0a */
> -/* REQUEST SENSE DATA EXT 0x0B */
> -/* reserved 0x0C..0x0F */
> -#define WIN_RECAL 0x10 /* obsolete since ATA4 */
> -/* obsolete since ATA3, retired in ATA4 0x11..0x1F */
> -#define WIN_READ 0x20 /* 28-Bit */
> -#define WIN_READ_ONCE 0x21 /* 28-Bit w/o retries, obsolete
> since ATA5 */
> -/* obsolete since ATA4 0x22..0x23 */
> -#define WIN_READ_EXT 0x24 /* 48-Bit */
> -#define WIN_READDMA_EXT 0x25 /* 48-Bit */
> -#define WIN_READDMA_QUEUED_EXT 0x26 /* 48-Bit, obsolete since ACS2
> */
> -#define WIN_READ_NATIVE_MAX_EXT 0x27 /* 48-Bit */
> -/* reserved 0x28 */
> -#define WIN_MULTREAD_EXT 0x29 /* 48-Bit */
> -/* READ STREAM DMA EXT 0x2A */
> -/* READ STREAM EXT 0x2B */
> -/* reserved 0x2C..0x2E */
> -/* READ LOG EXT 0x2F */
> -#define WIN_WRITE 0x30 /* 28-Bit */
> -#define WIN_WRITE_ONCE 0x31 /* 28-Bit w/o retries, obsolete
> since ATA5 */
> -/* obsolete since ATA4 0x32..0x33 */
> -#define WIN_WRITE_EXT 0x34 /* 48-Bit */
> -#define WIN_WRITEDMA_EXT 0x35 /* 48-Bit */
> -#define WIN_WRITEDMA_QUEUED_EXT 0x36 /* 48-Bit */
> -#define WIN_SET_MAX_EXT 0x37 /* 48-Bit, obsolete since ACS2
> */
> -#define WIN_SET_MAX_EXT 0x37 /* 48-Bit */
> -#define CFA_WRITE_SECT_WO_ERASE 0x38 /* CFA Write Sectors
> without erase */
> -#define WIN_MULTWRITE_EXT 0x39 /* 48-Bit */
> -/* WRITE STREAM DMA EXT 0x3A */
> -/* WRITE STREAM EXT 0x3B */
> -#define WIN_WRITE_VERIFY 0x3C /* 28-Bit, obsolete since ATA4
> */
> -/* WRITE DMA FUA EXT 0x3D */
> -/* obsolete since ACS2 0x3E */
> -/* WRITE LOG EXT 0x3F */
> -#define WIN_VERIFY 0x40 /* 28-Bit - Read Verify Sectors */
> -#define WIN_VERIFY_ONCE 0x41 /* 28-Bit - w/o retries,
> obsolete since ATA5 */
> -#define WIN_VERIFY_EXT 0x42 /* 48-Bit */
> -/* reserved 0x43..0x44 */
> -/* WRITE UNCORRECTABLE EXT 0x45 */
> -/* reserved 0x46 */
> -/* READ LOG DMA EXT 0x47 */
> -/* reserved 0x48..0x4F */
> -/* obsolete since ATA4 0x50 */
> -/* CONFIGURE STREAM 0x51 */
> -/* reserved 0x52..0x56 */
> -/* WRITE LOG DMA EXT 0x57 */
> -/* reserved 0x58..0x5A */
> -/* TRUSTED NON DATA 0x5B */
> -/* TRUSTED RECEIVE 0x5C */
> -/* TRUSTED RECEIVE DMA 0x5D */
> -/* TRUSTED SEND 0x5E */
> -/* TRUSTED SEND DMA 0x5F */
> -/* READ FPDMA QUEUED 0x60 */
> -/* WRITE FPDMA QUEUED 0x61 */
> -/* reserved 0x62->0x6F */
> -#define WIN_SEEK 0x70 /* obsolete since ATA7 */
> -/* reserved 0x71-0x7F */
> -/* vendor specific 0x80-0x86 */
> -#define CFA_TRANSLATE_SECTOR 0x87 /* CFA Translate Sector */
> -/* vendor specific 0x88-0x8F */
> -#define WIN_DIAGNOSE 0x90
> -#define WIN_SPECIFY 0x91 /* set drive geometry
> translation, obsolete since ATA6 */
> -#define WIN_DOWNLOAD_MICROCODE 0x92
> -/* DOWNLOAD MICROCODE DMA 0x93 */
> -#define WIN_STANDBYNOW2 0x94 /* retired in ATA4 */
> -#define WIN_IDLEIMMEDIATE2 0x95 /* force drive to become
> "ready", retired in ATA4 */
> -#define WIN_STANDBY2 0x96 /* retired in ATA4 */
> -#define WIN_SETIDLE2 0x97 /* retired in ATA4 */
> -#define WIN_CHECKPOWERMODE2 0x98 /* retired in ATA4 */
> -#define WIN_SLEEPNOW2 0x99 /* retired in ATA4 */
> -/* vendor specific 0x9A */
> -/* reserved 0x9B..0x9F */
> -#define WIN_PACKETCMD 0xA0 /* Send a packet command.
> */
> -#define WIN_PIDENTIFY 0xA1 /* identify ATAPI device
> */
> -#define WIN_QUEUED_SERVICE 0xA2 /* obsolete since ACS2 */
> -/* reserved 0xA3..0xAF */
> -#define WIN_SMART 0xB0 /* self-monitoring and reporting */
> -/* Device Configuration Overlay 0xB1 */
> -/* reserved 0xB2..0xB3 */
> -/* Sanitize Device 0xB4 */
> -/* reserved 0xB5 */
> -/* NV Cache 0xB6 */
> -/* reserved for CFA 0xB7..0xBB */
> -#define CFA_ACCESS_METADATA_STORAGE 0xB8
> -/* reserved 0xBC..0xBF */
> -#define CFA_ERASE_SECTORS 0xC0 /* microdrives implement as NOP */
> -/* vendor specific 0xC1..0xC3 */
> -#define WIN_MULTREAD 0xC4 /* read sectors using multiple
> mode*/
> -#define WIN_MULTWRITE 0xC5 /* write sectors using
> multiple mode */
> -#define WIN_SETMULT 0xC6 /* enable/disable multiple mode */
> -#define WIN_READDMA_QUEUED 0xC7 /* read sectors using Queued
> DMA transfers, obsolete since ACS2 */
> -#define WIN_READDMA 0xC8 /* read sectors using DMA
> transfers */
> -#define WIN_READDMA_ONCE 0xC9 /* 28-Bit - w/o retries,
> obsolete since ATA5 */
> -#define WIN_WRITEDMA 0xCA /* write sectors using DMA
> transfers */
> -#define WIN_WRITEDMA_ONCE 0xCB /* 28-Bit - w/o retries,
> obsolete since ATA5 */
> -#define WIN_WRITEDMA_QUEUED 0xCC /* write sectors using Queued DMA
> transfers, obsolete since ACS2 */
> -#define CFA_WRITE_MULTI_WO_ERASE 0xCD /* CFA Write multiple without
> erase */
> -/* WRITE MULTIPLE FUA EXT 0xCE */
> -/* reserved 0xCF..0xDO */
> -/* CHECK MEDIA CARD TYPE 0xD1 */
> -/* reserved for media card pass through 0xD2..0xD4 */
> -/* reserved 0xD5..0xD9 */
> -#define WIN_GETMEDIASTATUS 0xDA /* obsolete since ATA8 */
> -/* obsolete since ATA3, retired in ATA4 0xDB..0xDD */
> -#define WIN_DOORLOCK 0xDE /* lock door on removable
> drives, obsolete since ATA8 */
> -#define WIN_DOORUNLOCK 0xDF /* unlock door on removable
> drives, obsolete since ATA8 */
> -#define WIN_STANDBYNOW1 0xE0
> -#define WIN_IDLEIMMEDIATE 0xE1 /* force drive to become "ready" */
> -#define WIN_STANDBY 0xE2 /* Set device in Standby Mode */
> -#define WIN_SETIDLE1 0xE3
> -#define WIN_READ_BUFFER 0xE4 /* force read only 1
> sector */
> -#define WIN_CHECKPOWERMODE1 0xE5
> -#define WIN_SLEEPNOW1 0xE6
> -#define WIN_FLUSH_CACHE 0xE7
> -#define WIN_WRITE_BUFFER 0xE8 /* force write only 1 sector */
> -/* READ BUFFER DMA 0xE9 */
> -#define WIN_FLUSH_CACHE_EXT 0xEA /* 48-Bit */
> -/* WRITE BUFFER DMA 0xEB */
> -#define WIN_IDENTIFY 0xEC /* ask drive to identify itself
> */
> -#define WIN_MEDIAEJECT 0xED /* obsolete since ATA8 */
> -/* obsolete since ATA4 0xEE */
> -#define WIN_SETFEATURES 0xEF /* set special drive
> features */
> -#define IBM_SENSE_CONDITION 0xF0 /* measure disk temperature,
> vendor specific */
> -#define WIN_SECURITY_SET_PASS 0xF1
> -#define WIN_SECURITY_UNLOCK 0xF2
> -#define WIN_SECURITY_ERASE_PREPARE 0xF3
> -#define WIN_SECURITY_ERASE_UNIT 0xF4
> -#define WIN_SECURITY_FREEZE_LOCK 0xF5
> -#define CFA_WEAR_LEVEL 0xF5 /* microdrives implement as
> NOP; not specified in T13! */
> -#define WIN_SECURITY_DISABLE 0xF6
> -/* vendor specific 0xF7 */
> -#define WIN_READ_NATIVE_MAX 0xF8 /* return the native maximum
> address */
> -#define WIN_SET_MAX 0xF9
> -/* vendor specific 0xFA..0xFF */
> -
> -/* set to 1 set disable mult support */
> -#define MAX_MULT_SECTORS 16
> -
> -#define IDE_DMA_BUF_SECTORS 256
> -
> -/* feature values for Data Set Management */
> -#define DSM_TRIM 0x01
> -
> -#if (IDE_DMA_BUF_SECTORS < MAX_MULT_SECTORS)
> -#error "IDE_DMA_BUF_SECTORS must be bigger or equal to MAX_MULT_SECTORS"
> -#endif
> -
> -/* ATAPI defines */
> -
> -#define ATAPI_PACKET_SIZE 12
> -
> -/* The generic packet command opcodes for CD/DVD Logical Units,
> - * From Table 57 of the SFF8090 Ver. 3 (Mt. Fuji) draft standard. */
> -#define GPCMD_BLANK 0xa1
> -#define GPCMD_CLOSE_TRACK 0x5b
> -#define GPCMD_FLUSH_CACHE 0x35
> -#define GPCMD_FORMAT_UNIT 0x04
> -#define GPCMD_GET_CONFIGURATION 0x46
> -#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a
> -#define GPCMD_GET_PERFORMANCE 0xac
> -#define GPCMD_INQUIRY 0x12
> -#define GPCMD_LOAD_UNLOAD 0xa6
> -#define GPCMD_MECHANISM_STATUS 0xbd
> -#define GPCMD_MODE_SELECT_10 0x55
> -#define GPCMD_MODE_SENSE_10 0x5a
> -#define GPCMD_PAUSE_RESUME 0x4b
> -#define GPCMD_PLAY_AUDIO_10 0x45
> -#define GPCMD_PLAY_AUDIO_MSF 0x47
> -#define GPCMD_PLAY_AUDIO_TI 0x48
> -#define GPCMD_PLAY_CD 0xbc
> -#define GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
> -#define GPCMD_READ_10 0x28
> -#define GPCMD_READ_12 0xa8
> -#define GPCMD_READ_CDVD_CAPACITY 0x25
> -#define GPCMD_READ_CD 0xbe
> -#define GPCMD_READ_CD_MSF 0xb9
> -#define GPCMD_READ_DISC_INFO 0x51
> -#define GPCMD_READ_DVD_STRUCTURE 0xad
> -#define GPCMD_READ_FORMAT_CAPACITIES 0x23
> -#define GPCMD_READ_HEADER 0x44
> -#define GPCMD_READ_TRACK_RZONE_INFO 0x52
> -#define GPCMD_READ_SUBCHANNEL 0x42
> -#define GPCMD_READ_TOC_PMA_ATIP 0x43
> -#define GPCMD_REPAIR_RZONE_TRACK 0x58
> -#define GPCMD_REPORT_KEY 0xa4
> -#define GPCMD_REQUEST_SENSE 0x03
> -#define GPCMD_RESERVE_RZONE_TRACK 0x53
> -#define GPCMD_SCAN 0xba
> -#define GPCMD_SEEK 0x2b
> -#define GPCMD_SEND_DVD_STRUCTURE 0xad
> -#define GPCMD_SEND_EVENT 0xa2
> -#define GPCMD_SEND_KEY 0xa3
> -#define GPCMD_SEND_OPC 0x54
> -#define GPCMD_SET_READ_AHEAD 0xa7
> -#define GPCMD_SET_STREAMING 0xb6
> -#define GPCMD_START_STOP_UNIT 0x1b
> -#define GPCMD_STOP_PLAY_SCAN 0x4e
> -#define GPCMD_TEST_UNIT_READY 0x00
> -#define GPCMD_VERIFY_10 0x2f
> -#define GPCMD_WRITE_10 0x2a
> -#define GPCMD_WRITE_AND_VERIFY_10 0x2e
> -/* This is listed as optional in ATAPI 2.6, but is (curiously)
> - * missing from Mt. Fuji, Table 57. It _is_ mentioned in Mt. Fuji
> - * Table 377 as an MMC command for SCSi devices though... Most ATAPI
> - * drives support it. */
> -#define GPCMD_SET_SPEED 0xbb
> -/* This seems to be a SCSI specific CD-ROM opcode
> - * to play data at track/index */
> -#define GPCMD_PLAYAUDIO_TI 0x48
> -/*
> - * From MS Media Status Notification Support Specification. For
> - * older drives only.
> - */
> -#define GPCMD_GET_MEDIA_STATUS 0xda
> -#define GPCMD_MODE_SENSE_6 0x1a
> -
> -#define ATAPI_INT_REASON_CD 0x01 /* 0 = data transfer */
> -#define ATAPI_INT_REASON_IO 0x02 /* 1 = transfer to the host */
> -#define ATAPI_INT_REASON_REL 0x04
> -#define ATAPI_INT_REASON_TAG 0xf8
> -
> -/* same constants as bochs */
> -#define ASC_NO_SEEK_COMPLETE 0x02
> -#define ASC_ILLEGAL_OPCODE 0x20
> -#define ASC_LOGICAL_BLOCK_OOR 0x21
> -#define ASC_INV_FIELD_IN_CMD_PACKET 0x24
> -#define ASC_MEDIUM_MAY_HAVE_CHANGED 0x28
> -#define ASC_INCOMPATIBLE_FORMAT 0x30
> -#define ASC_MEDIUM_NOT_PRESENT 0x3a
> -#define ASC_SAVING_PARAMETERS_NOT_SUPPORTED 0x39
> -#define ASC_DATA_PHASE_ERROR 0x4b
> -#define ASC_MEDIA_REMOVAL_PREVENTED 0x53
> -
> -#define CFA_NO_ERROR 0x00
> -#define CFA_MISC_ERROR 0x09
> -#define CFA_INVALID_COMMAND 0x20
> -#define CFA_INVALID_ADDRESS 0x21
> -#define CFA_ADDRESS_OVERFLOW 0x2f
> -
> -#define SMART_READ_DATA 0xd0
> -#define SMART_READ_THRESH 0xd1
> -#define SMART_ATTR_AUTOSAVE 0xd2
> -#define SMART_SAVE_ATTR 0xd3
> -#define SMART_EXECUTE_OFFLINE 0xd4
> -#define SMART_READ_LOG 0xd5
> -#define SMART_WRITE_LOG 0xd6
> -#define SMART_ENABLE 0xd8
> -#define SMART_DISABLE 0xd9
> -#define SMART_STATUS 0xda
> -
> -typedef enum { IDE_HD, IDE_CD, IDE_CFATA } IDEDriveKind;
> -
> -typedef void EndTransferFunc(IDEState *);
> -
> -typedef void DMAStartFunc(IDEDMA *, IDEState *, BlockCompletionFunc *);
> -typedef void DMAVoidFunc(IDEDMA *);
> -typedef int DMAIntFunc(IDEDMA *, int);
> -typedef int32_t DMAInt32Func(IDEDMA *, int32_t len);
> -typedef void DMAu32Func(IDEDMA *, uint32_t);
> -typedef void DMAStopFunc(IDEDMA *, bool);
> -typedef void DMARestartFunc(void *, int, RunState);
> -
> -struct unreported_events {
> - bool eject_request;
> - bool new_media;
> -};
> -
> -enum ide_dma_cmd {
> - IDE_DMA_READ,
> - IDE_DMA_WRITE,
> - IDE_DMA_TRIM,
> - IDE_DMA_ATAPI,
> -};
> -
> -#define ide_cmd_is_read(s) \
> - ((s)->dma_cmd == IDE_DMA_READ)
> -
> -typedef struct IDEBufferedRequest {
> - QLIST_ENTRY(IDEBufferedRequest) list;
> - struct iovec iov;
> - QEMUIOVector qiov;
> - QEMUIOVector *original_qiov;
> - BlockCompletionFunc *original_cb;
> - void *original_opaque;
> - bool orphaned;
> -} IDEBufferedRequest;
> -
> -/* NOTE: IDEState represents in fact one drive */
> -struct IDEState {
> - IDEBus *bus;
> - uint8_t unit;
> - /* ide config */
> - IDEDriveKind drive_kind;
> - int cylinders, heads, sectors, chs_trans;
> - int64_t nb_sectors;
> - int mult_sectors;
> - int identify_set;
> - uint8_t identify_data[512];
> - int drive_serial;
> - char drive_serial_str[21];
> - char drive_model_str[41];
> - uint64_t wwn;
> - /* ide regs */
> - uint8_t feature;
> - uint8_t error;
> - uint32_t nsector;
> - uint8_t sector;
> - uint8_t lcyl;
> - uint8_t hcyl;
> - /* other part of tf for lba48 support */
> - uint8_t hob_feature;
> - uint8_t hob_nsector;
> - uint8_t hob_sector;
> - uint8_t hob_lcyl;
> - uint8_t hob_hcyl;
> -
> - uint8_t select;
> - uint8_t status;
> -
> - /* set for lba48 access */
> - uint8_t lba48;
> - BlockBackend *blk;
> - char version[9];
> - /* ATAPI specific */
> - struct unreported_events events;
> - uint8_t sense_key;
> - uint8_t asc;
> - bool tray_open;
> - bool tray_locked;
> - uint8_t cdrom_changed;
> - int packet_transfer_size;
> - int elementary_transfer_size;
> - int32_t io_buffer_index;
> - int lba;
> - int cd_sector_size;
> - int atapi_dma; /* true if dma is requested for the packet cmd */
> - BlockAcctCookie acct;
> - BlockAIOCB *pio_aiocb;
> - struct iovec iov;
> - QEMUIOVector qiov;
> - QLIST_HEAD(, IDEBufferedRequest) buffered_requests;
> - /* ATA DMA state */
> - uint64_t io_buffer_offset;
> - int32_t io_buffer_size;
> - QEMUSGList sg;
> - /* PIO transfer handling */
> - int req_nb_sectors; /* number of sectors per interrupt */
> - EndTransferFunc *end_transfer_func;
> - uint8_t *data_ptr;
> - uint8_t *data_end;
> - uint8_t *io_buffer;
> - /* PIO save/restore */
> - int32_t io_buffer_total_len;
> - int32_t cur_io_buffer_offset;
> - int32_t cur_io_buffer_len;
> - uint8_t end_transfer_fn_idx;
> - QEMUTimer *sector_write_timer; /* only used for win2k install hack */
> - uint32_t irq_count; /* counts IRQs when using win2k install hack */
> - /* CF-ATA extended error */
> - uint8_t ext_error;
> - /* CF-ATA metadata storage */
> - uint32_t mdata_size;
> - uint8_t *mdata_storage;
> - int media_changed;
> - enum ide_dma_cmd dma_cmd;
> - /* SMART */
> - uint8_t smart_enabled;
> - uint8_t smart_autosave;
> - int smart_errors;
> - uint8_t smart_selftest_count;
> - uint8_t *smart_selftest_data;
> - /* AHCI */
> - int ncq_queues;
> -};
> -
> -struct IDEDMAOps {
> - DMAStartFunc *start_dma;
> - DMAVoidFunc *start_transfer;
> - DMAInt32Func *prepare_buf;
> - DMAu32Func *commit_buf;
> - DMAIntFunc *rw_buf;
> - DMAVoidFunc *restart;
> - DMAVoidFunc *restart_dma;
> - DMAStopFunc *set_inactive;
> - DMAVoidFunc *cmd_done;
> - DMAVoidFunc *reset;
> -};
> -
> -struct IDEDMA {
> - const struct IDEDMAOps *ops;
> - struct iovec iov;
> - QEMUIOVector qiov;
> - BlockAIOCB *aiocb;
> -};
> -
> -struct IDEBus {
> - BusState qbus;
> - IDEDevice *master;
> - IDEDevice *slave;
> - IDEState ifs[2];
> - QEMUBH *bh;
> -
> - int bus_id;
> - int max_units;
> - IDEDMA *dma;
> - uint8_t unit;
> - uint8_t cmd;
> - qemu_irq irq;
> -
> - int error_status;
> - uint8_t retry_unit;
> - int64_t retry_sector_num;
> - uint32_t retry_nsector;
> -};
> -
> -#define TYPE_IDE_DEVICE "ide-device"
> -#define IDE_DEVICE(obj) \
> - OBJECT_CHECK(IDEDevice, (obj), TYPE_IDE_DEVICE)
> -#define IDE_DEVICE_CLASS(klass) \
> - OBJECT_CLASS_CHECK(IDEDeviceClass, (klass), TYPE_IDE_DEVICE)
> -#define IDE_DEVICE_GET_CLASS(obj) \
> - OBJECT_GET_CLASS(IDEDeviceClass, (obj), TYPE_IDE_DEVICE)
> -
> -typedef struct IDEDeviceClass {
> - DeviceClass parent_class;
> - int (*init)(IDEDevice *dev);
> -} IDEDeviceClass;
> -
> -struct IDEDevice {
> - DeviceState qdev;
> - uint32_t unit;
> - BlockConf conf;
> - int chs_trans;
> - char *version;
> - char *serial;
> - char *model;
> - uint64_t wwn;
> -};
> -
> -/* These are used for the error_status field of IDEBus */
> -#define IDE_RETRY_MASK 0xf8
> -#define IDE_RETRY_DMA 0x08
> -#define IDE_RETRY_PIO 0x10
> -#define IDE_RETRY_ATAPI 0x20 /* reused IDE_RETRY_READ bit */
> -#define IDE_RETRY_READ 0x20
> -#define IDE_RETRY_FLUSH 0x40
> -#define IDE_RETRY_TRIM 0x80
> -#define IDE_RETRY_HBA 0x100
> -
> -#define IS_IDE_RETRY_DMA(_status) \
> - ((_status) & IDE_RETRY_DMA)
> -
> -#define IS_IDE_RETRY_PIO(_status) \
> - ((_status) & IDE_RETRY_PIO)
> -
> -/*
> - * The method of the IDE_RETRY_ATAPI determination is to use a previously
> - * impossible bit combination as a new status value.
> - */
> -#define IS_IDE_RETRY_ATAPI(_status) \
> - (((_status) & IDE_RETRY_MASK) == IDE_RETRY_ATAPI)
> -
> -static inline uint8_t ide_dma_cmd_to_retry(uint8_t dma_cmd)
> -{
> - switch (dma_cmd) {
> - case IDE_DMA_READ:
> - return IDE_RETRY_DMA | IDE_RETRY_READ;
> - case IDE_DMA_WRITE:
> - return IDE_RETRY_DMA;
> - case IDE_DMA_TRIM:
> - return IDE_RETRY_DMA | IDE_RETRY_TRIM;
> - case IDE_DMA_ATAPI:
> - return IDE_RETRY_ATAPI;
> - default:
> - break;
> - }
> - return 0;
> -}
> -
> -static inline IDEState *idebus_active_if(IDEBus *bus)
> -{
> - return bus->ifs + bus->unit;
> -}
> -
> -static inline void ide_set_irq(IDEBus *bus)
> -{
> - if (!(bus->cmd & IDE_CMD_DISABLE_IRQ)) {
> - qemu_irq_raise(bus->irq);
> - }
> -}
> -
> -/* hw/ide/core.c */
> -extern const VMStateDescription vmstate_ide_bus;
> -
> -#define VMSTATE_IDE_BUS(_field, _state) \
> - VMSTATE_STRUCT(_field, _state, 1, vmstate_ide_bus, IDEBus)
> -
> -#define VMSTATE_IDE_BUS_ARRAY(_field, _state, _num) \
> - VMSTATE_STRUCT_ARRAY(_field, _state, _num, 1, vmstate_ide_bus, IDEBus)
> -
> -extern const VMStateDescription vmstate_ide_drive;
> -
> -#define VMSTATE_IDE_DRIVES(_field, _state) \
> - VMSTATE_STRUCT_ARRAY(_field, _state, 2, 3, vmstate_ide_drive, IDEState)
> -
> -#define VMSTATE_IDE_DRIVE(_field, _state) \
> - VMSTATE_STRUCT(_field, _state, 1, vmstate_ide_drive, IDEState)
> -
> -void ide_bus_reset(IDEBus *bus);
> -int64_t ide_get_sector(IDEState *s);
> -void ide_set_sector(IDEState *s, int64_t sector_num);
> -
> -void ide_start_dma(IDEState *s, BlockCompletionFunc *cb);
> -void dma_buf_commit(IDEState *s, uint32_t tx_bytes);
> -void ide_dma_error(IDEState *s);
> -void ide_abort_command(IDEState *s);
> -
> -void ide_atapi_cmd_ok(IDEState *s);
> -void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc);
> -void ide_atapi_dma_restart(IDEState *s);
> -void ide_atapi_io_error(IDEState *s, int ret);
> -
> -void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val);
> -uint32_t ide_ioport_read(void *opaque, uint32_t addr1);
> -uint32_t ide_status_read(void *opaque, uint32_t addr);
> -void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val);
> -void ide_data_writew(void *opaque, uint32_t addr, uint32_t val);
> -uint32_t ide_data_readw(void *opaque, uint32_t addr);
> -void ide_data_writel(void *opaque, uint32_t addr, uint32_t val);
> -uint32_t ide_data_readl(void *opaque, uint32_t addr);
> -
> -int ide_init_drive(IDEState *s, BlockBackend *blk, IDEDriveKind kind,
> - const char *version, const char *serial, const char
> *model,
> - uint64_t wwn,
> - uint32_t cylinders, uint32_t heads, uint32_t secs,
> - int chs_trans);
> -void ide_init2(IDEBus *bus, qemu_irq irq);
> -void ide_init_ioport(IDEBus *bus, ISADevice *isa, int iobase, int iobase2);
> -void ide_register_restart_cb(IDEBus *bus);
> -
> -void ide_exec_cmd(IDEBus *bus, uint32_t val);
> -
> -void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
> - EndTransferFunc *end_transfer_func);
> -void ide_transfer_stop(IDEState *s);
> -void ide_set_inactive(IDEState *s, bool more);
> -BlockAIOCB *ide_issue_trim(
> - int64_t offset, QEMUIOVector *qiov,
> - BlockCompletionFunc *cb, void *cb_opaque, void *opaque);
> -BlockAIOCB *ide_buffered_readv(IDEState *s, int64_t sector_num,
> - QEMUIOVector *iov, int nb_sectors,
> - BlockCompletionFunc *cb, void *opaque);
> -void ide_cancel_dma_sync(IDEState *s);
> -
> -/* hw/ide/atapi.c */
> -void ide_atapi_cmd(IDEState *s);
> -void ide_atapi_cmd_reply_end(IDEState *s);
> -
> -/* hw/ide/qdev.c */
> -void ide_bus_new(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
> - int bus_id, int max_units);
> -IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive);
> -
> -int ide_handle_rw_error(IDEState *s, int error, int op);
> -
> -#endif /* HW_IDE_INTERNAL_H */
> diff --git a/hw/ide/pci.h b/hw/ide/pci.h
> deleted file mode 100644
> index 0f2d4b9..0000000
> --- a/hw/ide/pci.h
> +++ /dev/null
> @@ -1,76 +0,0 @@
> -#ifndef HW_IDE_PCI_H
> -#define HW_IDE_PCI_H
> -
> -#include <hw/ide/internal.h>
> -
> -#define BM_STATUS_DMAING 0x01
> -#define BM_STATUS_ERROR 0x02
> -#define BM_STATUS_INT 0x04
> -
> -#define BM_CMD_START 0x01
> -#define BM_CMD_READ 0x08
> -
> -typedef struct BMDMAState {
> - IDEDMA dma;
> - uint8_t cmd;
> - uint8_t status;
> - uint32_t addr;
> -
> - IDEBus *bus;
> - /* current transfer state */
> - uint32_t cur_addr;
> - uint32_t cur_prd_last;
> - uint32_t cur_prd_addr;
> - uint32_t cur_prd_len;
> - BlockCompletionFunc *dma_cb;
> - MemoryRegion addr_ioport;
> - MemoryRegion extra_io;
> - qemu_irq irq;
> -
> - /* Bit 0-2 and 7: BM status register
> - * Bit 3-6: bus->error_status */
> - uint8_t migration_compat_status;
> - uint8_t migration_retry_unit;
> - int64_t migration_retry_sector_num;
> - uint32_t migration_retry_nsector;
> -
> - struct PCIIDEState *pci_dev;
> -} BMDMAState;
> -
> -typedef struct CMD646BAR {
> - MemoryRegion cmd;
> - MemoryRegion data;
> - IDEBus *bus;
> - struct PCIIDEState *pci_dev;
> -} CMD646BAR;
> -
> -#define TYPE_PCI_IDE "pci-ide"
> -#define PCI_IDE(obj) OBJECT_CHECK(PCIIDEState, (obj), TYPE_PCI_IDE)
> -
> -typedef struct PCIIDEState {
> - /*< private >*/
> - PCIDevice parent_obj;
> - /*< public >*/
> -
> - IDEBus bus[2];
> - BMDMAState bmdma[2];
> - uint32_t secondary; /* used only for cmd646 */
> - MemoryRegion bmdma_bar;
> - CMD646BAR cmd646_bar[2]; /* used only for cmd646 */
> -} PCIIDEState;
> -
> -
> -static inline IDEState *bmdma_active_if(BMDMAState *bmdma)
> -{
> - assert(bmdma->bus->retry_unit != (uint8_t)-1);
> - return bmdma->bus->ifs + bmdma->bus->retry_unit;
> -}
> -
> -
> -void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
> -void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
> -extern MemoryRegionOps bmdma_addr_ioport_ops;
> -void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table);
> -
> -extern const VMStateDescription vmstate_ide_pci;
> -#endif
> diff --git a/include/hw/ide/ahci.h b/include/hw/ide/ahci.h
> new file mode 100644
> index 0000000..bc777ed
> --- /dev/null
> +++ b/include/hw/ide/ahci.h
> @@ -0,0 +1,405 @@
> +/*
> + * QEMU AHCI Emulation
> + *
> + * Copyright (c) 2010 address@hidden
> + * Copyright (c) 2010 Roland Elek <address@hidden>
> + * Copyright (c) 2010 Sebastian Herbszt <address@hidden>
> + * Copyright (c) 2010 Alexander Graf <address@hidden>
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, see
> <http://www.gnu.org/licenses/>.
> + *
> + */
> +
> +#ifndef HW_IDE_AHCI_H
> +#define HW_IDE_AHCI_H
> +
> +#include <hw/sysbus.h>
> +
> +#define AHCI_MEM_BAR_SIZE 0x1000
> +#define AHCI_MAX_PORTS 32
> +#define AHCI_MAX_SG 168 /* hardware max is 64K */
> +#define AHCI_DMA_BOUNDARY 0xffffffff
> +#define AHCI_USE_CLUSTERING 0
> +#define AHCI_MAX_CMDS 32
> +#define AHCI_CMD_SZ 32
> +#define AHCI_CMD_SLOT_SZ (AHCI_MAX_CMDS * AHCI_CMD_SZ)
> +#define AHCI_RX_FIS_SZ 256
> +#define AHCI_CMD_TBL_CDB 0x40
> +#define AHCI_CMD_TBL_HDR_SZ 0x80
> +#define AHCI_CMD_TBL_SZ (AHCI_CMD_TBL_HDR_SZ + (AHCI_MAX_SG * 16))
> +#define AHCI_CMD_TBL_AR_SZ (AHCI_CMD_TBL_SZ * AHCI_MAX_CMDS)
> +#define AHCI_PORT_PRIV_DMA_SZ (AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_AR_SZ + \
> + AHCI_RX_FIS_SZ)
> +
> +#define AHCI_IRQ_ON_SG (1U << 31)
> +#define AHCI_CMD_ATAPI (1 << 5)
> +#define AHCI_CMD_WRITE (1 << 6)
> +#define AHCI_CMD_PREFETCH (1 << 7)
> +#define AHCI_CMD_RESET (1 << 8)
> +#define AHCI_CMD_CLR_BUSY (1 << 10)
> +
> +#define RX_FIS_D2H_REG 0x40 /* offset of D2H Register FIS data */
> +#define RX_FIS_SDB 0x58 /* offset of SDB FIS data */
> +#define RX_FIS_UNK 0x60 /* offset of Unknown FIS data */
> +
> +/* global controller registers */
> +#define HOST_CAP 0x00 /* host capabilities */
> +#define HOST_CTL 0x04 /* global host control */
> +#define HOST_IRQ_STAT 0x08 /* interrupt status */
> +#define HOST_PORTS_IMPL 0x0c /* bitmap of implemented ports */
> +#define HOST_VERSION 0x10 /* AHCI spec. version compliancy */
> +
> +/* HOST_CTL bits */
> +#define HOST_CTL_RESET (1 << 0) /* reset controller; self-clear
> */
> +#define HOST_CTL_IRQ_EN (1 << 1) /* global IRQ enable */
> +#define HOST_CTL_AHCI_EN (1U << 31) /* AHCI enabled */
> +
> +/* HOST_CAP bits */
> +#define HOST_CAP_SSC (1 << 14) /* Slumber capable */
> +#define HOST_CAP_AHCI (1 << 18) /* AHCI only */
> +#define HOST_CAP_CLO (1 << 24) /* Command List Override support
> */
> +#define HOST_CAP_SSS (1 << 27) /* Staggered Spin-up */
> +#define HOST_CAP_NCQ (1 << 30) /* Native Command Queueing */
> +#define HOST_CAP_64 (1U << 31) /* PCI DAC (64-bit DMA) support
> */
> +
> +/* registers for each SATA port */
> +#define PORT_LST_ADDR 0x00 /* command list DMA addr */
> +#define PORT_LST_ADDR_HI 0x04 /* command list DMA addr hi */
> +#define PORT_FIS_ADDR 0x08 /* FIS rx buf addr */
> +#define PORT_FIS_ADDR_HI 0x0c /* FIS rx buf addr hi */
> +#define PORT_IRQ_STAT 0x10 /* interrupt status */
> +#define PORT_IRQ_MASK 0x14 /* interrupt enable/disable mask */
> +#define PORT_CMD 0x18 /* port command */
> +#define PORT_TFDATA 0x20 /* taskfile data */
> +#define PORT_SIG 0x24 /* device TF signature */
> +#define PORT_SCR_STAT 0x28 /* SATA phy register: SStatus */
> +#define PORT_SCR_CTL 0x2c /* SATA phy register: SControl */
> +#define PORT_SCR_ERR 0x30 /* SATA phy register: SError */
> +#define PORT_SCR_ACT 0x34 /* SATA phy register: SActive */
> +#define PORT_CMD_ISSUE 0x38 /* command issue */
> +#define PORT_RESERVED 0x3c /* reserved */
> +
> +/* PORT_IRQ_{STAT,MASK} bits */
> +#define PORT_IRQ_COLD_PRES (1U << 31) /* cold presence detect */
> +#define PORT_IRQ_TF_ERR (1 << 30) /* task file error */
> +#define PORT_IRQ_HBUS_ERR (1 << 29) /* host bus fatal error */
> +#define PORT_IRQ_HBUS_DATA_ERR (1 << 28) /* host bus data error */
> +#define PORT_IRQ_IF_ERR (1 << 27) /* interface fatal error */
> +#define PORT_IRQ_IF_NONFATAL (1 << 26) /* interface non-fatal error */
> +#define PORT_IRQ_OVERFLOW (1 << 24) /* xfer exhausted available S/G
> */
> +#define PORT_IRQ_BAD_PMP (1 << 23) /* incorrect port multiplier */
> +
> +#define PORT_IRQ_PHYRDY (1 << 22) /* PhyRdy changed */
> +#define PORT_IRQ_DEV_ILCK (1 << 7) /* device interlock */
> +#define PORT_IRQ_CONNECT (1 << 6) /* port connect change status */
> +#define PORT_IRQ_SG_DONE (1 << 5) /* descriptor processed */
> +#define PORT_IRQ_UNK_FIS (1 << 4) /* unknown FIS rx'd */
> +#define PORT_IRQ_SDB_FIS (1 << 3) /* Set Device Bits FIS rx'd */
> +#define PORT_IRQ_DMAS_FIS (1 << 2) /* DMA Setup FIS rx'd */
> +#define PORT_IRQ_PIOS_FIS (1 << 1) /* PIO Setup FIS rx'd */
> +#define PORT_IRQ_D2H_REG_FIS (1 << 0) /* D2H Register FIS rx'd */
> +
> +#define PORT_IRQ_FREEZE (PORT_IRQ_HBUS_ERR | PORT_IRQ_IF_ERR | \
> + PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY | \
> + PORT_IRQ_UNK_FIS)
> +#define PORT_IRQ_ERROR (PORT_IRQ_FREEZE | PORT_IRQ_TF_ERR | \
> + PORT_IRQ_HBUS_DATA_ERR)
> +#define DEF_PORT_IRQ (PORT_IRQ_ERROR | PORT_IRQ_SG_DONE | \
> + PORT_IRQ_SDB_FIS | PORT_IRQ_DMAS_FIS | \
> + PORT_IRQ_PIOS_FIS | PORT_IRQ_D2H_REG_FIS)
> +
> +/* PORT_CMD bits */
> +#define PORT_CMD_ATAPI (1 << 24) /* Device is ATAPI */
> +#define PORT_CMD_LIST_ON (1 << 15) /* cmd list DMA engine running */
> +#define PORT_CMD_FIS_ON (1 << 14) /* FIS DMA engine running */
> +#define PORT_CMD_FIS_RX (1 << 4) /* Enable FIS receive DMA engine
> */
> +#define PORT_CMD_CLO (1 << 3) /* Command list override */
> +#define PORT_CMD_POWER_ON (1 << 2) /* Power up device */
> +#define PORT_CMD_SPIN_UP (1 << 1) /* Spin up device */
> +#define PORT_CMD_START (1 << 0) /* Enable port DMA engine */
> +
> +#define PORT_CMD_ICC_MASK (0xfU << 28) /* i/f ICC state mask */
> +#define PORT_CMD_ICC_ACTIVE (0x1 << 28) /* Put i/f in active state */
> +#define PORT_CMD_ICC_PARTIAL (0x2 << 28) /* Put i/f in partial state */
> +#define PORT_CMD_ICC_SLUMBER (0x6 << 28) /* Put i/f in slumber state */
> +
> +#define PORT_CMD_RO_MASK 0x007dffe0 /* Which CMD bits are read
> only? */
> +
> +/* ap->flags bits */
> +#define AHCI_FLAG_NO_NCQ (1 << 24)
> +#define AHCI_FLAG_IGN_IRQ_IF_ERR (1 << 25) /* ignore IRQ_IF_ERR */
> +#define AHCI_FLAG_HONOR_PI (1 << 26) /* honor PORTS_IMPL */
> +#define AHCI_FLAG_IGN_SERR_INTERNAL (1 << 27) /* ignore SERR_INTERNAL
> */
> +#define AHCI_FLAG_32BIT_ONLY (1 << 28) /* force 32bit */
> +
> +#define ATA_SRST (1 << 2) /* software reset */
> +
> +#define STATE_RUN 0
> +#define STATE_RESET 1
> +
> +#define SATA_SCR_SSTATUS_DET_NODEV 0x0
> +#define SATA_SCR_SSTATUS_DET_DEV_PRESENT_PHY_UP 0x3
> +
> +#define SATA_SCR_SSTATUS_SPD_NODEV 0x00
> +#define SATA_SCR_SSTATUS_SPD_GEN1 0x10
> +
> +#define SATA_SCR_SSTATUS_IPM_NODEV 0x000
> +#define SATA_SCR_SSTATUS_IPM_ACTIVE 0X100
> +
> +#define AHCI_SCR_SCTL_DET 0xf
> +
> +#define SATA_FIS_TYPE_REGISTER_H2D 0x27
> +#define SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER 0x80
> +#define SATA_FIS_TYPE_REGISTER_D2H 0x34
> +#define SATA_FIS_TYPE_PIO_SETUP 0x5f
> +#define SATA_FIS_TYPE_SDB 0xA1
> +
> +#define AHCI_CMD_HDR_CMD_FIS_LEN 0x1f
> +#define AHCI_CMD_HDR_PRDT_LEN 16
> +
> +#define SATA_SIGNATURE_CDROM 0xeb140101
> +#define SATA_SIGNATURE_DISK 0x00000101
> +
> +#define AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR 0x20
> + /* Shouldn't this be 0x2c? */
> +
> +#define AHCI_PORT_REGS_START_ADDR 0x100
> +#define AHCI_PORT_ADDR_OFFSET_MASK 0x7f
> +#define AHCI_PORT_ADDR_OFFSET_LEN 0x80
> +
> +#define AHCI_NUM_COMMAND_SLOTS 31
> +#define AHCI_SUPPORTED_SPEED 20
> +#define AHCI_SUPPORTED_SPEED_GEN1 1
> +#define AHCI_VERSION_1_0 0x10000
> +
> +#define AHCI_PROGMODE_MAJOR_REV_1 1
> +
> +#define AHCI_COMMAND_TABLE_ACMD 0x40
> +
> +#define AHCI_PRDT_SIZE_MASK 0x3fffff
> +
> +#define IDE_FEATURE_DMA 1
> +
> +#define READ_FPDMA_QUEUED 0x60
> +#define WRITE_FPDMA_QUEUED 0x61
> +#define NCQ_NON_DATA 0x63
> +#define RECEIVE_FPDMA_QUEUED 0x65
> +#define SEND_FPDMA_QUEUED 0x64
> +
> +#define NCQ_FIS_FUA_MASK 0x80
> +#define NCQ_FIS_RARC_MASK 0x01
> +
> +#define RES_FIS_DSFIS 0x00
> +#define RES_FIS_PSFIS 0x20
> +#define RES_FIS_RFIS 0x40
> +#define RES_FIS_SDBFIS 0x58
> +#define RES_FIS_UFIS 0x60
> +
> +#define SATA_CAP_SIZE 0x8
> +#define SATA_CAP_REV 0x2
> +#define SATA_CAP_BAR 0x4
> +
> +typedef struct AHCIControlRegs {
> + uint32_t cap;
> + uint32_t ghc;
> + uint32_t irqstatus;
> + uint32_t impl;
> + uint32_t version;
> +} AHCIControlRegs;
> +
> +typedef struct AHCIPortRegs {
> + uint32_t lst_addr;
> + uint32_t lst_addr_hi;
> + uint32_t fis_addr;
> + uint32_t fis_addr_hi;
> + uint32_t irq_stat;
> + uint32_t irq_mask;
> + uint32_t cmd;
> + uint32_t unused0;
> + uint32_t tfdata;
> + uint32_t sig;
> + uint32_t scr_stat;
> + uint32_t scr_ctl;
> + uint32_t scr_err;
> + uint32_t scr_act;
> + uint32_t cmd_issue;
> + uint32_t reserved;
> +} AHCIPortRegs;
> +
> +typedef struct AHCICmdHdr {
> + uint16_t opts;
> + uint16_t prdtl;
> + uint32_t status;
> + uint64_t tbl_addr;
> + uint32_t reserved[4];
> +} QEMU_PACKED AHCICmdHdr;
> +
> +typedef struct AHCI_SG {
> + uint64_t addr;
> + uint32_t reserved;
> + uint32_t flags_size;
> +} QEMU_PACKED AHCI_SG;
> +
> +typedef struct AHCIDevice AHCIDevice;
> +
> +typedef struct NCQTransferState {
> + AHCIDevice *drive;
> + BlockAIOCB *aiocb;
> + AHCICmdHdr *cmdh;
> + QEMUSGList sglist;
> + BlockAcctCookie acct;
> + uint32_t sector_count;
> + uint64_t lba;
> + uint8_t tag;
> + uint8_t cmd;
> + uint8_t slot;
> + bool used;
> + bool halt;
> +} NCQTransferState;
> +
> +struct AHCIDevice {
> + IDEDMA dma;
> + IDEBus port;
> + int port_no;
> + uint32_t port_state;
> + uint32_t finished;
> + AHCIPortRegs port_regs;
> + struct AHCIState *hba;
> + QEMUBH *check_bh;
> + uint8_t *lst;
> + uint8_t *res_fis;
> + bool done_atapi_packet;
> + int32_t busy_slot;
> + bool init_d2h_sent;
> + AHCICmdHdr *cur_cmd;
> + NCQTransferState ncq_tfs[AHCI_MAX_CMDS];
> +};
> +
> +typedef struct AHCIState {
> + DeviceState *container;
> +
> + AHCIDevice *dev;
> + AHCIControlRegs control_regs;
> + MemoryRegion mem;
> + MemoryRegion idp; /* Index-Data Pair I/O port space */
> + unsigned idp_offset; /* Offset of index in I/O port space */
> + uint32_t idp_index; /* Current IDP index */
> + int32_t ports;
> + qemu_irq irq;
> + AddressSpace *as;
> +} AHCIState;
> +
> +typedef struct AHCIPCIState {
> + /*< private >*/
> + PCIDevice parent_obj;
> + /*< public >*/
> +
> + AHCIState ahci;
> +} AHCIPCIState;
> +
> +#define TYPE_ICH9_AHCI "ich9-ahci"
> +
> +#define ICH_AHCI(obj) \
> + OBJECT_CHECK(AHCIPCIState, (obj), TYPE_ICH9_AHCI)
> +
> +extern const VMStateDescription vmstate_ahci;
> +
> +#define VMSTATE_AHCI(_field, _state) { \
> + .name = (stringify(_field)), \
> + .size = sizeof(AHCIState), \
> + .vmsd = &vmstate_ahci, \
> + .flags = VMS_STRUCT, \
> + .offset = vmstate_offset_value(_state, _field, AHCIState), \
> +}
> +
> +/**
> + * NCQFrame is the same as a Register H2D FIS (described in SATA 3.2),
> + * but some fields have been re-mapped and re-purposed, as seen in
> + * SATA 3.2 section 13.6.4.1 ("READ FPDMA QUEUED")
> + *
> + * cmd_fis[3], feature 7:0, becomes sector count 7:0.
> + * cmd_fis[7], device 7:0, uses bit 7 as the Force Unit Access bit.
> + * cmd_fis[11], feature 15:8, becomes sector count 15:8.
> + * cmd_fis[12], count 7:0, becomes the NCQ TAG (7:3) and RARC bit (0)
> + * cmd_fis[13], count 15:8, becomes the priority value (7:6)
> + * bytes 16-19 become an le32 "auxiliary" field.
> + */
> +typedef struct NCQFrame {
> + uint8_t fis_type;
> + uint8_t c;
> + uint8_t command;
> + uint8_t sector_count_low; /* (feature 7:0) */
> + uint8_t lba0;
> + uint8_t lba1;
> + uint8_t lba2;
> + uint8_t fua; /* (device 7:0) */
> + uint8_t lba3;
> + uint8_t lba4;
> + uint8_t lba5;
> + uint8_t sector_count_high; /* (feature 15:8) */
> + uint8_t tag; /* (count 0:7) */
> + uint8_t prio; /* (count 15:8) */
> + uint8_t icc;
> + uint8_t control;
> + uint8_t aux0;
> + uint8_t aux1;
> + uint8_t aux2;
> + uint8_t aux3;
> +} QEMU_PACKED NCQFrame;
> +
> +typedef struct SDBFIS {
> + uint8_t type;
> + uint8_t flags;
> + uint8_t status;
> + uint8_t error;
> + uint32_t payload;
> +} QEMU_PACKED SDBFIS;
> +
> +void ahci_realize(AHCIState *s, DeviceState *qdev, AddressSpace *as, int
> ports);
> +void ahci_init(AHCIState *s, DeviceState *qdev);
> +void ahci_uninit(AHCIState *s);
> +
> +void ahci_reset(AHCIState *s);
> +
> +void ahci_ide_create_devs(PCIDevice *dev, DriveInfo **hd);
> +
> +#define TYPE_SYSBUS_AHCI "sysbus-ahci"
> +#define SYSBUS_AHCI(obj) OBJECT_CHECK(SysbusAHCIState, (obj),
> TYPE_SYSBUS_AHCI)
> +
> +typedef struct SysbusAHCIState {
> + /*< private >*/
> + SysBusDevice parent_obj;
> + /*< public >*/
> +
> + AHCIState ahci;
> + uint32_t num_ports;
> +} SysbusAHCIState;
> +
> +#define TYPE_ALLWINNER_AHCI "allwinner-ahci"
> +#define ALLWINNER_AHCI(obj) OBJECT_CHECK(AllwinnerAHCIState, (obj), \
> + TYPE_ALLWINNER_AHCI)
> +
> +#define ALLWINNER_AHCI_MMIO_OFF 0x80
> +#define ALLWINNER_AHCI_MMIO_SIZE 0x80
> +
> +struct AllwinnerAHCIState {
> + /*< private >*/
> + SysbusAHCIState parent_obj;
> + /*< public >*/
> +
> + MemoryRegion mmio;
> + uint32_t regs[ALLWINNER_AHCI_MMIO_SIZE/4];
> +};
> +
> +#endif /* HW_IDE_AHCI_H */
> diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h
> new file mode 100644
> index 0000000..773928a
> --- /dev/null
> +++ b/include/hw/ide/internal.h
> @@ -0,0 +1,635 @@
> +#ifndef HW_IDE_INTERNAL_H
> +#define HW_IDE_INTERNAL_H
> +
> +/*
> + * QEMU IDE Emulation -- internal header file
> + * only files in hw/ide/ are supposed to include this file.
> + * non-internal declarations are in hw/ide.h
> + */
> +#include <hw/ide.h>
> +#include <hw/isa/isa.h>
> +#include "sysemu/dma.h"
> +#include "sysemu/sysemu.h"
> +#include "hw/block/block.h"
> +#include "block/scsi.h"
> +
> +/* debug IDE devices */
> +//#define DEBUG_IDE
> +//#define DEBUG_IDE_ATAPI
> +//#define DEBUG_AIO
> +#define USE_DMA_CDROM
> +
> +typedef struct IDEBus IDEBus;
> +typedef struct IDEDevice IDEDevice;
> +typedef struct IDEState IDEState;
> +typedef struct IDEDMA IDEDMA;
> +typedef struct IDEDMAOps IDEDMAOps;
> +
> +#define TYPE_IDE_BUS "IDE"
> +#define IDE_BUS(obj) OBJECT_CHECK(IDEBus, (obj), TYPE_IDE_BUS)
> +
> +/* Bits of HD_STATUS */
> +#define ERR_STAT 0x01
> +#define INDEX_STAT 0x02
> +#define ECC_STAT 0x04 /* Corrected error */
> +#define DRQ_STAT 0x08
> +#define SEEK_STAT 0x10
> +#define SRV_STAT 0x10
> +#define WRERR_STAT 0x20
> +#define READY_STAT 0x40
> +#define BUSY_STAT 0x80
> +
> +/* Bits for HD_ERROR */
> +#define MARK_ERR 0x01 /* Bad address mark */
> +#define TRK0_ERR 0x02 /* couldn't find track 0 */
> +#define ABRT_ERR 0x04 /* Command aborted */
> +#define MCR_ERR 0x08 /* media change request */
> +#define ID_ERR 0x10 /* ID field not found */
> +#define MC_ERR 0x20 /* media changed */
> +#define ECC_ERR 0x40 /* Uncorrectable ECC error */
> +#define BBD_ERR 0x80 /* pre-EIDE meaning: block
> marked bad */
> +#define ICRC_ERR 0x80 /* new meaning: CRC error during
> transfer */
> +
> +/* Bits of HD_NSECTOR */
> +#define CD 0x01
> +#define IO 0x02
> +#define REL 0x04
> +#define TAG_MASK 0xf8
> +
> +#define IDE_CMD_RESET 0x04
> +#define IDE_CMD_DISABLE_IRQ 0x02
> +
> +/* ACS-2 T13/2015-D Table B.2 Command codes */
> +#define WIN_NOP 0x00
> +/* reserved 0x01..0x02 */
> +#define CFA_REQ_EXT_ERROR_CODE 0x03 /* CFA Request Extended
> Error Code */
> +/* reserved 0x04..0x05 */
> +#define WIN_DSM 0x06
> +/* reserved 0x07 */
> +#define WIN_DEVICE_RESET 0x08
> +/* reserved 0x09..0x0a */
> +/* REQUEST SENSE DATA EXT 0x0B */
> +/* reserved 0x0C..0x0F */
> +#define WIN_RECAL 0x10 /* obsolete since ATA4 */
> +/* obsolete since ATA3, retired in ATA4 0x11..0x1F */
> +#define WIN_READ 0x20 /* 28-Bit */
> +#define WIN_READ_ONCE 0x21 /* 28-Bit w/o retries, obsolete
> since ATA5 */
> +/* obsolete since ATA4 0x22..0x23 */
> +#define WIN_READ_EXT 0x24 /* 48-Bit */
> +#define WIN_READDMA_EXT 0x25 /* 48-Bit */
> +#define WIN_READDMA_QUEUED_EXT 0x26 /* 48-Bit, obsolete since ACS2
> */
> +#define WIN_READ_NATIVE_MAX_EXT 0x27 /* 48-Bit */
> +/* reserved 0x28 */
> +#define WIN_MULTREAD_EXT 0x29 /* 48-Bit */
> +/* READ STREAM DMA EXT 0x2A */
> +/* READ STREAM EXT 0x2B */
> +/* reserved 0x2C..0x2E */
> +/* READ LOG EXT 0x2F */
> +#define WIN_WRITE 0x30 /* 28-Bit */
> +#define WIN_WRITE_ONCE 0x31 /* 28-Bit w/o retries, obsolete
> since ATA5 */
> +/* obsolete since ATA4 0x32..0x33 */
> +#define WIN_WRITE_EXT 0x34 /* 48-Bit */
> +#define WIN_WRITEDMA_EXT 0x35 /* 48-Bit */
> +#define WIN_WRITEDMA_QUEUED_EXT 0x36 /* 48-Bit */
> +#define WIN_SET_MAX_EXT 0x37 /* 48-Bit, obsolete since ACS2
> */
> +#define WIN_SET_MAX_EXT 0x37 /* 48-Bit */
> +#define CFA_WRITE_SECT_WO_ERASE 0x38 /* CFA Write Sectors
> without erase */
> +#define WIN_MULTWRITE_EXT 0x39 /* 48-Bit */
> +/* WRITE STREAM DMA EXT 0x3A */
> +/* WRITE STREAM EXT 0x3B */
> +#define WIN_WRITE_VERIFY 0x3C /* 28-Bit, obsolete since ATA4
> */
> +/* WRITE DMA FUA EXT 0x3D */
> +/* obsolete since ACS2 0x3E */
> +/* WRITE LOG EXT 0x3F */
> +#define WIN_VERIFY 0x40 /* 28-Bit - Read Verify Sectors */
> +#define WIN_VERIFY_ONCE 0x41 /* 28-Bit - w/o retries,
> obsolete since ATA5 */
> +#define WIN_VERIFY_EXT 0x42 /* 48-Bit */
> +/* reserved 0x43..0x44 */
> +/* WRITE UNCORRECTABLE EXT 0x45 */
> +/* reserved 0x46 */
> +/* READ LOG DMA EXT 0x47 */
> +/* reserved 0x48..0x4F */
> +/* obsolete since ATA4 0x50 */
> +/* CONFIGURE STREAM 0x51 */
> +/* reserved 0x52..0x56 */
> +/* WRITE LOG DMA EXT 0x57 */
> +/* reserved 0x58..0x5A */
> +/* TRUSTED NON DATA 0x5B */
> +/* TRUSTED RECEIVE 0x5C */
> +/* TRUSTED RECEIVE DMA 0x5D */
> +/* TRUSTED SEND 0x5E */
> +/* TRUSTED SEND DMA 0x5F */
> +/* READ FPDMA QUEUED 0x60 */
> +/* WRITE FPDMA QUEUED 0x61 */
> +/* reserved 0x62->0x6F */
> +#define WIN_SEEK 0x70 /* obsolete since ATA7 */
> +/* reserved 0x71-0x7F */
> +/* vendor specific 0x80-0x86 */
> +#define CFA_TRANSLATE_SECTOR 0x87 /* CFA Translate Sector */
> +/* vendor specific 0x88-0x8F */
> +#define WIN_DIAGNOSE 0x90
> +#define WIN_SPECIFY 0x91 /* set drive geometry
> translation, obsolete since ATA6 */
> +#define WIN_DOWNLOAD_MICROCODE 0x92
> +/* DOWNLOAD MICROCODE DMA 0x93 */
> +#define WIN_STANDBYNOW2 0x94 /* retired in ATA4 */
> +#define WIN_IDLEIMMEDIATE2 0x95 /* force drive to become
> "ready", retired in ATA4 */
> +#define WIN_STANDBY2 0x96 /* retired in ATA4 */
> +#define WIN_SETIDLE2 0x97 /* retired in ATA4 */
> +#define WIN_CHECKPOWERMODE2 0x98 /* retired in ATA4 */
> +#define WIN_SLEEPNOW2 0x99 /* retired in ATA4 */
> +/* vendor specific 0x9A */
> +/* reserved 0x9B..0x9F */
> +#define WIN_PACKETCMD 0xA0 /* Send a packet command.
> */
> +#define WIN_PIDENTIFY 0xA1 /* identify ATAPI device
> */
> +#define WIN_QUEUED_SERVICE 0xA2 /* obsolete since ACS2 */
> +/* reserved 0xA3..0xAF */
> +#define WIN_SMART 0xB0 /* self-monitoring and reporting */
> +/* Device Configuration Overlay 0xB1 */
> +/* reserved 0xB2..0xB3 */
> +/* Sanitize Device 0xB4 */
> +/* reserved 0xB5 */
> +/* NV Cache 0xB6 */
> +/* reserved for CFA 0xB7..0xBB */
> +#define CFA_ACCESS_METADATA_STORAGE 0xB8
> +/* reserved 0xBC..0xBF */
> +#define CFA_ERASE_SECTORS 0xC0 /* microdrives implement as NOP */
> +/* vendor specific 0xC1..0xC3 */
> +#define WIN_MULTREAD 0xC4 /* read sectors using multiple
> mode*/
> +#define WIN_MULTWRITE 0xC5 /* write sectors using
> multiple mode */
> +#define WIN_SETMULT 0xC6 /* enable/disable multiple mode */
> +#define WIN_READDMA_QUEUED 0xC7 /* read sectors using Queued
> DMA transfers, obsolete since ACS2 */
> +#define WIN_READDMA 0xC8 /* read sectors using DMA
> transfers */
> +#define WIN_READDMA_ONCE 0xC9 /* 28-Bit - w/o retries,
> obsolete since ATA5 */
> +#define WIN_WRITEDMA 0xCA /* write sectors using DMA
> transfers */
> +#define WIN_WRITEDMA_ONCE 0xCB /* 28-Bit - w/o retries,
> obsolete since ATA5 */
> +#define WIN_WRITEDMA_QUEUED 0xCC /* write sectors using Queued DMA
> transfers, obsolete since ACS2 */
> +#define CFA_WRITE_MULTI_WO_ERASE 0xCD /* CFA Write multiple without
> erase */
> +/* WRITE MULTIPLE FUA EXT 0xCE */
> +/* reserved 0xCF..0xDO */
> +/* CHECK MEDIA CARD TYPE 0xD1 */
> +/* reserved for media card pass through 0xD2..0xD4 */
> +/* reserved 0xD5..0xD9 */
> +#define WIN_GETMEDIASTATUS 0xDA /* obsolete since ATA8 */
> +/* obsolete since ATA3, retired in ATA4 0xDB..0xDD */
> +#define WIN_DOORLOCK 0xDE /* lock door on removable
> drives, obsolete since ATA8 */
> +#define WIN_DOORUNLOCK 0xDF /* unlock door on removable
> drives, obsolete since ATA8 */
> +#define WIN_STANDBYNOW1 0xE0
> +#define WIN_IDLEIMMEDIATE 0xE1 /* force drive to become "ready" */
> +#define WIN_STANDBY 0xE2 /* Set device in Standby Mode */
> +#define WIN_SETIDLE1 0xE3
> +#define WIN_READ_BUFFER 0xE4 /* force read only 1
> sector */
> +#define WIN_CHECKPOWERMODE1 0xE5
> +#define WIN_SLEEPNOW1 0xE6
> +#define WIN_FLUSH_CACHE 0xE7
> +#define WIN_WRITE_BUFFER 0xE8 /* force write only 1 sector */
> +/* READ BUFFER DMA 0xE9 */
> +#define WIN_FLUSH_CACHE_EXT 0xEA /* 48-Bit */
> +/* WRITE BUFFER DMA 0xEB */
> +#define WIN_IDENTIFY 0xEC /* ask drive to identify itself
> */
> +#define WIN_MEDIAEJECT 0xED /* obsolete since ATA8 */
> +/* obsolete since ATA4 0xEE */
> +#define WIN_SETFEATURES 0xEF /* set special drive
> features */
> +#define IBM_SENSE_CONDITION 0xF0 /* measure disk temperature,
> vendor specific */
> +#define WIN_SECURITY_SET_PASS 0xF1
> +#define WIN_SECURITY_UNLOCK 0xF2
> +#define WIN_SECURITY_ERASE_PREPARE 0xF3
> +#define WIN_SECURITY_ERASE_UNIT 0xF4
> +#define WIN_SECURITY_FREEZE_LOCK 0xF5
> +#define CFA_WEAR_LEVEL 0xF5 /* microdrives implement as
> NOP; not specified in T13! */
> +#define WIN_SECURITY_DISABLE 0xF6
> +/* vendor specific 0xF7 */
> +#define WIN_READ_NATIVE_MAX 0xF8 /* return the native maximum
> address */
> +#define WIN_SET_MAX 0xF9
> +/* vendor specific 0xFA..0xFF */
> +
> +/* set to 1 set disable mult support */
> +#define MAX_MULT_SECTORS 16
> +
> +#define IDE_DMA_BUF_SECTORS 256
> +
> +/* feature values for Data Set Management */
> +#define DSM_TRIM 0x01
> +
> +#if (IDE_DMA_BUF_SECTORS < MAX_MULT_SECTORS)
> +#error "IDE_DMA_BUF_SECTORS must be bigger or equal to MAX_MULT_SECTORS"
> +#endif
> +
> +/* ATAPI defines */
> +
> +#define ATAPI_PACKET_SIZE 12
> +
> +/* The generic packet command opcodes for CD/DVD Logical Units,
> + * From Table 57 of the SFF8090 Ver. 3 (Mt. Fuji) draft standard. */
> +#define GPCMD_BLANK 0xa1
> +#define GPCMD_CLOSE_TRACK 0x5b
> +#define GPCMD_FLUSH_CACHE 0x35
> +#define GPCMD_FORMAT_UNIT 0x04
> +#define GPCMD_GET_CONFIGURATION 0x46
> +#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a
> +#define GPCMD_GET_PERFORMANCE 0xac
> +#define GPCMD_INQUIRY 0x12
> +#define GPCMD_LOAD_UNLOAD 0xa6
> +#define GPCMD_MECHANISM_STATUS 0xbd
> +#define GPCMD_MODE_SELECT_10 0x55
> +#define GPCMD_MODE_SENSE_10 0x5a
> +#define GPCMD_PAUSE_RESUME 0x4b
> +#define GPCMD_PLAY_AUDIO_10 0x45
> +#define GPCMD_PLAY_AUDIO_MSF 0x47
> +#define GPCMD_PLAY_AUDIO_TI 0x48
> +#define GPCMD_PLAY_CD 0xbc
> +#define GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
> +#define GPCMD_READ_10 0x28
> +#define GPCMD_READ_12 0xa8
> +#define GPCMD_READ_CDVD_CAPACITY 0x25
> +#define GPCMD_READ_CD 0xbe
> +#define GPCMD_READ_CD_MSF 0xb9
> +#define GPCMD_READ_DISC_INFO 0x51
> +#define GPCMD_READ_DVD_STRUCTURE 0xad
> +#define GPCMD_READ_FORMAT_CAPACITIES 0x23
> +#define GPCMD_READ_HEADER 0x44
> +#define GPCMD_READ_TRACK_RZONE_INFO 0x52
> +#define GPCMD_READ_SUBCHANNEL 0x42
> +#define GPCMD_READ_TOC_PMA_ATIP 0x43
> +#define GPCMD_REPAIR_RZONE_TRACK 0x58
> +#define GPCMD_REPORT_KEY 0xa4
> +#define GPCMD_REQUEST_SENSE 0x03
> +#define GPCMD_RESERVE_RZONE_TRACK 0x53
> +#define GPCMD_SCAN 0xba
> +#define GPCMD_SEEK 0x2b
> +#define GPCMD_SEND_DVD_STRUCTURE 0xad
> +#define GPCMD_SEND_EVENT 0xa2
> +#define GPCMD_SEND_KEY 0xa3
> +#define GPCMD_SEND_OPC 0x54
> +#define GPCMD_SET_READ_AHEAD 0xa7
> +#define GPCMD_SET_STREAMING 0xb6
> +#define GPCMD_START_STOP_UNIT 0x1b
> +#define GPCMD_STOP_PLAY_SCAN 0x4e
> +#define GPCMD_TEST_UNIT_READY 0x00
> +#define GPCMD_VERIFY_10 0x2f
> +#define GPCMD_WRITE_10 0x2a
> +#define GPCMD_WRITE_AND_VERIFY_10 0x2e
> +/* This is listed as optional in ATAPI 2.6, but is (curiously)
> + * missing from Mt. Fuji, Table 57. It _is_ mentioned in Mt. Fuji
> + * Table 377 as an MMC command for SCSi devices though... Most ATAPI
> + * drives support it. */
> +#define GPCMD_SET_SPEED 0xbb
> +/* This seems to be a SCSI specific CD-ROM opcode
> + * to play data at track/index */
> +#define GPCMD_PLAYAUDIO_TI 0x48
> +/*
> + * From MS Media Status Notification Support Specification. For
> + * older drives only.
> + */
> +#define GPCMD_GET_MEDIA_STATUS 0xda
> +#define GPCMD_MODE_SENSE_6 0x1a
> +
> +#define ATAPI_INT_REASON_CD 0x01 /* 0 = data transfer */
> +#define ATAPI_INT_REASON_IO 0x02 /* 1 = transfer to the host */
> +#define ATAPI_INT_REASON_REL 0x04
> +#define ATAPI_INT_REASON_TAG 0xf8
> +
> +/* same constants as bochs */
> +#define ASC_NO_SEEK_COMPLETE 0x02
> +#define ASC_ILLEGAL_OPCODE 0x20
> +#define ASC_LOGICAL_BLOCK_OOR 0x21
> +#define ASC_INV_FIELD_IN_CMD_PACKET 0x24
> +#define ASC_MEDIUM_MAY_HAVE_CHANGED 0x28
> +#define ASC_INCOMPATIBLE_FORMAT 0x30
> +#define ASC_MEDIUM_NOT_PRESENT 0x3a
> +#define ASC_SAVING_PARAMETERS_NOT_SUPPORTED 0x39
> +#define ASC_DATA_PHASE_ERROR 0x4b
> +#define ASC_MEDIA_REMOVAL_PREVENTED 0x53
> +
> +#define CFA_NO_ERROR 0x00
> +#define CFA_MISC_ERROR 0x09
> +#define CFA_INVALID_COMMAND 0x20
> +#define CFA_INVALID_ADDRESS 0x21
> +#define CFA_ADDRESS_OVERFLOW 0x2f
> +
> +#define SMART_READ_DATA 0xd0
> +#define SMART_READ_THRESH 0xd1
> +#define SMART_ATTR_AUTOSAVE 0xd2
> +#define SMART_SAVE_ATTR 0xd3
> +#define SMART_EXECUTE_OFFLINE 0xd4
> +#define SMART_READ_LOG 0xd5
> +#define SMART_WRITE_LOG 0xd6
> +#define SMART_ENABLE 0xd8
> +#define SMART_DISABLE 0xd9
> +#define SMART_STATUS 0xda
> +
> +typedef enum { IDE_HD, IDE_CD, IDE_CFATA } IDEDriveKind;
> +
> +typedef void EndTransferFunc(IDEState *);
> +
> +typedef void DMAStartFunc(IDEDMA *, IDEState *, BlockCompletionFunc *);
> +typedef void DMAVoidFunc(IDEDMA *);
> +typedef int DMAIntFunc(IDEDMA *, int);
> +typedef int32_t DMAInt32Func(IDEDMA *, int32_t len);
> +typedef void DMAu32Func(IDEDMA *, uint32_t);
> +typedef void DMAStopFunc(IDEDMA *, bool);
> +typedef void DMARestartFunc(void *, int, RunState);
> +
> +struct unreported_events {
> + bool eject_request;
> + bool new_media;
> +};
> +
> +enum ide_dma_cmd {
> + IDE_DMA_READ,
> + IDE_DMA_WRITE,
> + IDE_DMA_TRIM,
> + IDE_DMA_ATAPI,
> +};
> +
> +#define ide_cmd_is_read(s) \
> + ((s)->dma_cmd == IDE_DMA_READ)
> +
> +typedef struct IDEBufferedRequest {
> + QLIST_ENTRY(IDEBufferedRequest) list;
> + struct iovec iov;
> + QEMUIOVector qiov;
> + QEMUIOVector *original_qiov;
> + BlockCompletionFunc *original_cb;
> + void *original_opaque;
> + bool orphaned;
> +} IDEBufferedRequest;
> +
> +/* NOTE: IDEState represents in fact one drive */
> +struct IDEState {
> + IDEBus *bus;
> + uint8_t unit;
> + /* ide config */
> + IDEDriveKind drive_kind;
> + int cylinders, heads, sectors, chs_trans;
> + int64_t nb_sectors;
> + int mult_sectors;
> + int identify_set;
> + uint8_t identify_data[512];
> + int drive_serial;
> + char drive_serial_str[21];
> + char drive_model_str[41];
> + uint64_t wwn;
> + /* ide regs */
> + uint8_t feature;
> + uint8_t error;
> + uint32_t nsector;
> + uint8_t sector;
> + uint8_t lcyl;
> + uint8_t hcyl;
> + /* other part of tf for lba48 support */
> + uint8_t hob_feature;
> + uint8_t hob_nsector;
> + uint8_t hob_sector;
> + uint8_t hob_lcyl;
> + uint8_t hob_hcyl;
> +
> + uint8_t select;
> + uint8_t status;
> +
> + /* set for lba48 access */
> + uint8_t lba48;
> + BlockBackend *blk;
> + char version[9];
> + /* ATAPI specific */
> + struct unreported_events events;
> + uint8_t sense_key;
> + uint8_t asc;
> + bool tray_open;
> + bool tray_locked;
> + uint8_t cdrom_changed;
> + int packet_transfer_size;
> + int elementary_transfer_size;
> + int32_t io_buffer_index;
> + int lba;
> + int cd_sector_size;
> + int atapi_dma; /* true if dma is requested for the packet cmd */
> + BlockAcctCookie acct;
> + BlockAIOCB *pio_aiocb;
> + struct iovec iov;
> + QEMUIOVector qiov;
> + QLIST_HEAD(, IDEBufferedRequest) buffered_requests;
> + /* ATA DMA state */
> + uint64_t io_buffer_offset;
> + int32_t io_buffer_size;
> + QEMUSGList sg;
> + /* PIO transfer handling */
> + int req_nb_sectors; /* number of sectors per interrupt */
> + EndTransferFunc *end_transfer_func;
> + uint8_t *data_ptr;
> + uint8_t *data_end;
> + uint8_t *io_buffer;
> + /* PIO save/restore */
> + int32_t io_buffer_total_len;
> + int32_t cur_io_buffer_offset;
> + int32_t cur_io_buffer_len;
> + uint8_t end_transfer_fn_idx;
> + QEMUTimer *sector_write_timer; /* only used for win2k install hack */
> + uint32_t irq_count; /* counts IRQs when using win2k install hack */
> + /* CF-ATA extended error */
> + uint8_t ext_error;
> + /* CF-ATA metadata storage */
> + uint32_t mdata_size;
> + uint8_t *mdata_storage;
> + int media_changed;
> + enum ide_dma_cmd dma_cmd;
> + /* SMART */
> + uint8_t smart_enabled;
> + uint8_t smart_autosave;
> + int smart_errors;
> + uint8_t smart_selftest_count;
> + uint8_t *smart_selftest_data;
> + /* AHCI */
> + int ncq_queues;
> +};
> +
> +struct IDEDMAOps {
> + DMAStartFunc *start_dma;
> + DMAVoidFunc *start_transfer;
> + DMAInt32Func *prepare_buf;
> + DMAu32Func *commit_buf;
> + DMAIntFunc *rw_buf;
> + DMAVoidFunc *restart;
> + DMAVoidFunc *restart_dma;
> + DMAStopFunc *set_inactive;
> + DMAVoidFunc *cmd_done;
> + DMAVoidFunc *reset;
> +};
> +
> +struct IDEDMA {
> + const struct IDEDMAOps *ops;
> + struct iovec iov;
> + QEMUIOVector qiov;
> + BlockAIOCB *aiocb;
> +};
> +
> +struct IDEBus {
> + BusState qbus;
> + IDEDevice *master;
> + IDEDevice *slave;
> + IDEState ifs[2];
> + QEMUBH *bh;
> +
> + int bus_id;
> + int max_units;
> + IDEDMA *dma;
> + uint8_t unit;
> + uint8_t cmd;
> + qemu_irq irq;
> +
> + int error_status;
> + uint8_t retry_unit;
> + int64_t retry_sector_num;
> + uint32_t retry_nsector;
> +};
> +
> +#define TYPE_IDE_DEVICE "ide-device"
> +#define IDE_DEVICE(obj) \
> + OBJECT_CHECK(IDEDevice, (obj), TYPE_IDE_DEVICE)
> +#define IDE_DEVICE_CLASS(klass) \
> + OBJECT_CLASS_CHECK(IDEDeviceClass, (klass), TYPE_IDE_DEVICE)
> +#define IDE_DEVICE_GET_CLASS(obj) \
> + OBJECT_GET_CLASS(IDEDeviceClass, (obj), TYPE_IDE_DEVICE)
> +
> +typedef struct IDEDeviceClass {
> + DeviceClass parent_class;
> + int (*init)(IDEDevice *dev);
> +} IDEDeviceClass;
> +
> +struct IDEDevice {
> + DeviceState qdev;
> + uint32_t unit;
> + BlockConf conf;
> + int chs_trans;
> + char *version;
> + char *serial;
> + char *model;
> + uint64_t wwn;
> +};
> +
> +/* These are used for the error_status field of IDEBus */
> +#define IDE_RETRY_MASK 0xf8
> +#define IDE_RETRY_DMA 0x08
> +#define IDE_RETRY_PIO 0x10
> +#define IDE_RETRY_ATAPI 0x20 /* reused IDE_RETRY_READ bit */
> +#define IDE_RETRY_READ 0x20
> +#define IDE_RETRY_FLUSH 0x40
> +#define IDE_RETRY_TRIM 0x80
> +#define IDE_RETRY_HBA 0x100
> +
> +#define IS_IDE_RETRY_DMA(_status) \
> + ((_status) & IDE_RETRY_DMA)
> +
> +#define IS_IDE_RETRY_PIO(_status) \
> + ((_status) & IDE_RETRY_PIO)
> +
> +/*
> + * The method of the IDE_RETRY_ATAPI determination is to use a previously
> + * impossible bit combination as a new status value.
> + */
> +#define IS_IDE_RETRY_ATAPI(_status) \
> + (((_status) & IDE_RETRY_MASK) == IDE_RETRY_ATAPI)
> +
> +static inline uint8_t ide_dma_cmd_to_retry(uint8_t dma_cmd)
> +{
> + switch (dma_cmd) {
> + case IDE_DMA_READ:
> + return IDE_RETRY_DMA | IDE_RETRY_READ;
> + case IDE_DMA_WRITE:
> + return IDE_RETRY_DMA;
> + case IDE_DMA_TRIM:
> + return IDE_RETRY_DMA | IDE_RETRY_TRIM;
> + case IDE_DMA_ATAPI:
> + return IDE_RETRY_ATAPI;
> + default:
> + break;
> + }
> + return 0;
> +}
> +
> +static inline IDEState *idebus_active_if(IDEBus *bus)
> +{
> + return bus->ifs + bus->unit;
> +}
> +
> +static inline void ide_set_irq(IDEBus *bus)
> +{
> + if (!(bus->cmd & IDE_CMD_DISABLE_IRQ)) {
> + qemu_irq_raise(bus->irq);
> + }
> +}
> +
> +/* hw/ide/core.c */
> +extern const VMStateDescription vmstate_ide_bus;
> +
> +#define VMSTATE_IDE_BUS(_field, _state) \
> + VMSTATE_STRUCT(_field, _state, 1, vmstate_ide_bus, IDEBus)
> +
> +#define VMSTATE_IDE_BUS_ARRAY(_field, _state, _num) \
> + VMSTATE_STRUCT_ARRAY(_field, _state, _num, 1, vmstate_ide_bus, IDEBus)
> +
> +extern const VMStateDescription vmstate_ide_drive;
> +
> +#define VMSTATE_IDE_DRIVES(_field, _state) \
> + VMSTATE_STRUCT_ARRAY(_field, _state, 2, 3, vmstate_ide_drive, IDEState)
> +
> +#define VMSTATE_IDE_DRIVE(_field, _state) \
> + VMSTATE_STRUCT(_field, _state, 1, vmstate_ide_drive, IDEState)
> +
> +void ide_bus_reset(IDEBus *bus);
> +int64_t ide_get_sector(IDEState *s);
> +void ide_set_sector(IDEState *s, int64_t sector_num);
> +
> +void ide_start_dma(IDEState *s, BlockCompletionFunc *cb);
> +void dma_buf_commit(IDEState *s, uint32_t tx_bytes);
> +void ide_dma_error(IDEState *s);
> +void ide_abort_command(IDEState *s);
> +
> +void ide_atapi_cmd_ok(IDEState *s);
> +void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc);
> +void ide_atapi_dma_restart(IDEState *s);
> +void ide_atapi_io_error(IDEState *s, int ret);
> +
> +void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val);
> +uint32_t ide_ioport_read(void *opaque, uint32_t addr1);
> +uint32_t ide_status_read(void *opaque, uint32_t addr);
> +void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val);
> +void ide_data_writew(void *opaque, uint32_t addr, uint32_t val);
> +uint32_t ide_data_readw(void *opaque, uint32_t addr);
> +void ide_data_writel(void *opaque, uint32_t addr, uint32_t val);
> +uint32_t ide_data_readl(void *opaque, uint32_t addr);
> +
> +int ide_init_drive(IDEState *s, BlockBackend *blk, IDEDriveKind kind,
> + const char *version, const char *serial, const char
> *model,
> + uint64_t wwn,
> + uint32_t cylinders, uint32_t heads, uint32_t secs,
> + int chs_trans);
> +void ide_init2(IDEBus *bus, qemu_irq irq);
> +void ide_init_ioport(IDEBus *bus, ISADevice *isa, int iobase, int iobase2);
> +void ide_register_restart_cb(IDEBus *bus);
> +
> +void ide_exec_cmd(IDEBus *bus, uint32_t val);
> +
> +void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
> + EndTransferFunc *end_transfer_func);
> +void ide_transfer_stop(IDEState *s);
> +void ide_set_inactive(IDEState *s, bool more);
> +BlockAIOCB *ide_issue_trim(
> + int64_t offset, QEMUIOVector *qiov,
> + BlockCompletionFunc *cb, void *cb_opaque, void *opaque);
> +BlockAIOCB *ide_buffered_readv(IDEState *s, int64_t sector_num,
> + QEMUIOVector *iov, int nb_sectors,
> + BlockCompletionFunc *cb, void *opaque);
> +void ide_cancel_dma_sync(IDEState *s);
> +
> +/* hw/ide/atapi.c */
> +void ide_atapi_cmd(IDEState *s);
> +void ide_atapi_cmd_reply_end(IDEState *s);
> +
> +/* hw/ide/qdev.c */
> +void ide_bus_new(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
> + int bus_id, int max_units);
> +IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive);
> +
> +int ide_handle_rw_error(IDEState *s, int error, int op);
> +
> +#endif /* HW_IDE_INTERNAL_H */
> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
> new file mode 100644
> index 0000000..0f2d4b9
> --- /dev/null
> +++ b/include/hw/ide/pci.h
> @@ -0,0 +1,76 @@
> +#ifndef HW_IDE_PCI_H
> +#define HW_IDE_PCI_H
> +
> +#include <hw/ide/internal.h>
> +
> +#define BM_STATUS_DMAING 0x01
> +#define BM_STATUS_ERROR 0x02
> +#define BM_STATUS_INT 0x04
> +
> +#define BM_CMD_START 0x01
> +#define BM_CMD_READ 0x08
> +
> +typedef struct BMDMAState {
> + IDEDMA dma;
> + uint8_t cmd;
> + uint8_t status;
> + uint32_t addr;
> +
> + IDEBus *bus;
> + /* current transfer state */
> + uint32_t cur_addr;
> + uint32_t cur_prd_last;
> + uint32_t cur_prd_addr;
> + uint32_t cur_prd_len;
> + BlockCompletionFunc *dma_cb;
> + MemoryRegion addr_ioport;
> + MemoryRegion extra_io;
> + qemu_irq irq;
> +
> + /* Bit 0-2 and 7: BM status register
> + * Bit 3-6: bus->error_status */
> + uint8_t migration_compat_status;
> + uint8_t migration_retry_unit;
> + int64_t migration_retry_sector_num;
> + uint32_t migration_retry_nsector;
> +
> + struct PCIIDEState *pci_dev;
> +} BMDMAState;
> +
> +typedef struct CMD646BAR {
> + MemoryRegion cmd;
> + MemoryRegion data;
> + IDEBus *bus;
> + struct PCIIDEState *pci_dev;
> +} CMD646BAR;
> +
> +#define TYPE_PCI_IDE "pci-ide"
> +#define PCI_IDE(obj) OBJECT_CHECK(PCIIDEState, (obj), TYPE_PCI_IDE)
> +
> +typedef struct PCIIDEState {
> + /*< private >*/
> + PCIDevice parent_obj;
> + /*< public >*/
> +
> + IDEBus bus[2];
> + BMDMAState bmdma[2];
> + uint32_t secondary; /* used only for cmd646 */
> + MemoryRegion bmdma_bar;
> + CMD646BAR cmd646_bar[2]; /* used only for cmd646 */
> +} PCIIDEState;
> +
> +
> +static inline IDEState *bmdma_active_if(BMDMAState *bmdma)
> +{
> + assert(bmdma->bus->retry_unit != (uint8_t)-1);
> + return bmdma->bus->ifs + bmdma->bus->retry_unit;
> +}
> +
> +
> +void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
> +void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
> +extern MemoryRegionOps bmdma_addr_ioport_ops;
> +void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table);
> +
> +extern const VMStateDescription vmstate_ide_pci;
> +#endif
>
- [Qemu-block] [PATCH 00/13] Make Q35 devices closer to Qemu object model., Efimov Vasily, 2016/06/17
- [Qemu-block] [PATCH 03/13] vmport: identify vmport type by macro TYPE_VMPORT, Efimov Vasily, 2016/06/17
- [Qemu-block] [PATCH 04/13] pflash: make TYPE_CFI_PFLASH0{1, 2} macros public, Efimov Vasily, 2016/06/17
- [Qemu-block] [PATCH 12/13] MC146818 RTC: add GPIO access to output IRQ, Efimov Vasily, 2016/06/17
- [Qemu-block] [PATCH 01/13] ide: move headers to include folder, Efimov Vasily, 2016/06/17
- Re: [Qemu-block] [PATCH 01/13] ide: move headers to include folder,
Paolo Bonzini <=
- [Qemu-block] [PATCH 09/13] ICH9 SMB: make TYPE_ICH9_SMB_DEVICE macro public, Efimov Vasily, 2016/06/17
- [Qemu-block] [PATCH 10/13] ICH9 LPC: handle PIC and I/O APIC IRQs as qdev GPIO, Efimov Vasily, 2016/06/17
- [Qemu-block] [PATCH 05/13] Q35: implement property interfece to several parameters, Efimov Vasily, 2016/06/17
- [Qemu-block] [PATCH 08/13] port92: handle A20 IRQ as GPIO, Efimov Vasily, 2016/06/17
- [Qemu-block] [PATCH 13/13] ICH9 LPC: configure PCI IRQs routing internally, Efimov Vasily, 2016/06/17