| /* | |
| * ide device definitions | |
| * | |
| * Copyright (c) 2009 Gerd Hoffmann <kraxel@redhat.com> | |
| * | |
| * 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 <http://www.gnu.org/licenses/>. | |
| */ | |
| #ifndef IDE_DEV_H | |
| #define IDE_DEV_H | |
| #include "system/dma.h" | |
| #include "hw/core/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]; | |
| bool win2k_install_hack; | |
| 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-0xfffe - rotations per minute | |
| * 0xffff - reserved | |
| */ | |
| uint16_t rotation_rate; | |
| bool win2k_install_hack; | |
| }; | |
| 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 |