/* * ide device definitions * * Copyright (c) 2009 Gerd Hoffmann * * This code 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.1 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 . */ #ifndef IDE_DEV_H #define IDE_DEV_H #include "sysemu/dma.h" #include "hw/qdev-properties.h" #include "hw/block/block.h" typedef struct IDEDevice IDEDevice; typedef struct IDEState IDEState; typedef struct IDEBus IDEBus; typedef void EndTransferFunc(IDEState *); #define MAX_IDE_DEVS 2 #define TYPE_IDE_DEVICE "ide-device" OBJECT_DECLARE_TYPE(IDEDevice, IDEDeviceClass, IDE_DEVICE) typedef enum { IDE_HD, IDE_CD, IDE_CFATA } IDEDriveKind; struct unreported_events { bool eject_request; bool new_media; }; enum ide_dma_cmd { IDE_DMA_READ = 0, IDE_DMA_WRITE, IDE_DMA_TRIM, IDE_DMA_ATAPI, IDE_DMA__COUNT }; /* NOTE: IDEState represents in fact one drive */ struct IDEState { IDEBus *bus; uint8_t unit; /* ide config */ IDEDriveKind drive_kind; int drive_heads, drive_sectors; 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; bool io8; bool reset_reverts; /* 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; 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 IDEDeviceClass { DeviceClass parent_class; void (*realize)(IDEDevice *dev, Error **errp); }; struct IDEDevice { DeviceState qdev; uint32_t unit; BlockConf conf; int chs_trans; char *version; char *serial; char *model; uint64_t wwn; /* * 0x0000 - rotation rate not reported * 0x0001 - non-rotating medium (SSD) * 0x0002-0x0400 - reserved * 0x0401-0xffe - rotations per minute * 0xffff - reserved */ uint16_t rotation_rate; }; typedef struct IDEDrive { IDEDevice dev; } IDEDrive; #define DEFINE_IDE_DEV_PROPERTIES() \ DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf), \ DEFINE_BLOCK_ERROR_PROPERTIES(IDEDrive, dev.conf), \ DEFINE_PROP_STRING("ver", IDEDrive, dev.version), \ DEFINE_PROP_UINT64("wwn", IDEDrive, dev.wwn, 0), \ DEFINE_PROP_STRING("serial", IDEDrive, dev.serial),\ DEFINE_PROP_STRING("model", IDEDrive, dev.model) void ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind, Error **errp); void ide_drive_get(DriveInfo **hd, int max_bus); #endif