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 <r...@ispras.ru> > --- > 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 qiaoch...@loongson.cn > - * Copyright (c) 2010 Roland Elek <elek.rol...@gmail.com> > - * Copyright (c) 2010 Sebastian Herbszt <herb...@gmx.de> > - * Copyright (c) 2010 Alexander Graf <ag...@suse.de> > - * > - * 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 qiaoch...@loongson.cn > + * Copyright (c) 2010 Roland Elek <elek.rol...@gmail.com> > + * Copyright (c) 2010 Sebastian Herbszt <herb...@gmx.de> > + * Copyright (c) 2010 Alexander Graf <ag...@suse.de> > + * > + * 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 >