| 1 | /* |
| 2 | * ide device definitions |
| 3 | * |
| 4 | * Copyright (c) 2009 Gerd Hoffmann <kraxel@redhat.com> |
| 5 | * |
| 6 | * This code is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU Lesser General Public |
| 8 | * License as published by the Free Software Foundation; either |
| 9 | * version 2.1 of the License, or (at your option) any later version. |
| 10 | * |
| 11 | * This library is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 14 | * Lesser General Public License for more details. |
| 15 | * |
| 16 | * You should have received a copy of the GNU Lesser General Public |
| 17 | * License along with this library; if not, see <http://www.gnu.org/licenses/>. |
| 18 | */ |
| 19 | |
| 20 | #ifndef IDE_DEV_H |
| 21 | #define IDE_DEV_H |
| 22 | |
| 23 | #include "system/dma.h" |
| 24 | #include "hw/core/qdev-properties.h" |
| 25 | #include "hw/block/block.h" |
| 26 | |
| 27 | typedef struct IDEDevice IDEDevice; |
| 28 | typedef struct IDEState IDEState; |
| 29 | typedef struct IDEBus IDEBus; |
| 30 | |
| 31 | typedef void EndTransferFunc(IDEState *); |
| 32 | |
| 33 | #define MAX_IDE_DEVS 2 |
| 34 | |
| 35 | #define TYPE_IDE_DEVICE "ide-device" |
| 36 | OBJECT_DECLARE_TYPE(IDEDevice, IDEDeviceClass, IDE_DEVICE) |
| 37 | |
| 38 | typedef enum { IDE_HD, IDE_CD, IDE_CFATA } IDEDriveKind; |
| 39 | |
| 40 | struct unreported_events { |
| 41 | bool eject_request; |
| 42 | bool new_media; |
| 43 | }; |
| 44 | |
| 45 | enum ide_dma_cmd { |
| 46 | IDE_DMA_READ = 0, |
| 47 | IDE_DMA_WRITE, |
| 48 | IDE_DMA_TRIM, |
| 49 | IDE_DMA_ATAPI, |
| 50 | IDE_DMA__COUNT |
| 51 | }; |
| 52 | |
| 53 | /* NOTE: IDEState represents in fact one drive */ |
| 54 | struct IDEState { |
| 55 | IDEBus *bus; |
| 56 | uint8_t unit; |
| 57 | /* ide config */ |
| 58 | IDEDriveKind drive_kind; |
| 59 | int drive_heads, drive_sectors; |
| 60 | int cylinders, heads, sectors, chs_trans; |
| 61 | int64_t nb_sectors; |
| 62 | int mult_sectors; |
| 63 | int identify_set; |
| 64 | uint8_t identify_data[512]; |
| 65 | int drive_serial; |
| 66 | char drive_serial_str[21]; |
| 67 | char drive_model_str[41]; |
| 68 | bool win2k_install_hack; |
| 69 | uint64_t wwn; |
| 70 | /* ide regs */ |
| 71 | uint8_t feature; |
| 72 | uint8_t error; |
| 73 | uint32_t nsector; |
| 74 | uint8_t sector; |
| 75 | uint8_t lcyl; |
| 76 | uint8_t hcyl; |
| 77 | /* other part of tf for lba48 support */ |
| 78 | uint8_t hob_feature; |
| 79 | uint8_t hob_nsector; |
| 80 | uint8_t hob_sector; |
| 81 | uint8_t hob_lcyl; |
| 82 | uint8_t hob_hcyl; |
| 83 | |
| 84 | uint8_t select; |
| 85 | uint8_t status; |
| 86 | |
| 87 | bool io8; |
| 88 | bool reset_reverts; |
| 89 | |
| 90 | /* set for lba48 access */ |
| 91 | uint8_t lba48; |
| 92 | BlockBackend *blk; |
| 93 | char version[9]; |
| 94 | /* ATAPI specific */ |
| 95 | struct unreported_events events; |
| 96 | uint8_t sense_key; |
| 97 | uint8_t asc; |
| 98 | bool tray_open; |
| 99 | bool tray_locked; |
| 100 | uint8_t cdrom_changed; |
| 101 | int packet_transfer_size; |
| 102 | int elementary_transfer_size; |
| 103 | int32_t io_buffer_index; |
| 104 | int lba; |
| 105 | int cd_sector_size; |
| 106 | int atapi_dma; /* true if dma is requested for the packet cmd */ |
| 107 | BlockAcctCookie acct; |
| 108 | BlockAIOCB *pio_aiocb; |
| 109 | QEMUIOVector qiov; |
| 110 | QLIST_HEAD(, IDEBufferedRequest) buffered_requests; |
| 111 | /* ATA DMA state */ |
| 112 | uint64_t io_buffer_offset; |
| 113 | int32_t io_buffer_size; |
| 114 | QEMUSGList sg; |
| 115 | /* PIO transfer handling */ |
| 116 | int req_nb_sectors; /* number of sectors per interrupt */ |
| 117 | EndTransferFunc *end_transfer_func; |
| 118 | uint8_t *data_ptr; |
| 119 | uint8_t *data_end; |
| 120 | uint8_t *io_buffer; |
| 121 | /* PIO save/restore */ |
| 122 | int32_t io_buffer_total_len; |
| 123 | int32_t cur_io_buffer_offset; |
| 124 | int32_t cur_io_buffer_len; |
| 125 | uint8_t end_transfer_fn_idx; |
| 126 | QEMUTimer *sector_write_timer; /* only used for win2k install hack */ |
| 127 | uint32_t irq_count; /* counts IRQs when using win2k install hack */ |
| 128 | /* CF-ATA extended error */ |
| 129 | uint8_t ext_error; |
| 130 | /* CF-ATA metadata storage */ |
| 131 | uint32_t mdata_size; |
| 132 | uint8_t *mdata_storage; |
| 133 | int media_changed; |
| 134 | enum ide_dma_cmd dma_cmd; |
| 135 | /* SMART */ |
| 136 | uint8_t smart_enabled; |
| 137 | uint8_t smart_autosave; |
| 138 | int smart_errors; |
| 139 | uint8_t smart_selftest_count; |
| 140 | uint8_t *smart_selftest_data; |
| 141 | /* AHCI */ |
| 142 | int ncq_queues; |
| 143 | }; |
| 144 | |
| 145 | struct IDEDeviceClass { |
| 146 | DeviceClass parent_class; |
| 147 | void (*realize)(IDEDevice *dev, Error **errp); |
| 148 | }; |
| 149 | |
| 150 | struct IDEDevice { |
| 151 | DeviceState qdev; |
| 152 | uint32_t unit; |
| 153 | BlockConf conf; |
| 154 | int chs_trans; |
| 155 | char *version; |
| 156 | char *serial; |
| 157 | char *model; |
| 158 | uint64_t wwn; |
| 159 | /* |
| 160 | * 0x0000 - rotation rate not reported |
| 161 | * 0x0001 - non-rotating medium (SSD) |
| 162 | * 0x0002-0x0400 - reserved |
| 163 | * 0x0401-0xfffe - rotations per minute |
| 164 | * 0xffff - reserved |
| 165 | */ |
| 166 | uint16_t rotation_rate; |
| 167 | bool win2k_install_hack; |
| 168 | }; |
| 169 | |
| 170 | typedef struct IDEDrive { |
| 171 | IDEDevice dev; |
| 172 | } IDEDrive; |
| 173 | |
| 174 | #define DEFINE_IDE_DEV_PROPERTIES() \ |
| 175 | DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf), \ |
| 176 | DEFINE_BLOCK_ERROR_PROPERTIES(IDEDrive, dev.conf), \ |
| 177 | DEFINE_PROP_STRING("ver", IDEDrive, dev.version), \ |
| 178 | DEFINE_PROP_UINT64("wwn", IDEDrive, dev.wwn, 0), \ |
| 179 | DEFINE_PROP_STRING("serial", IDEDrive, dev.serial),\ |
| 180 | DEFINE_PROP_STRING("model", IDEDrive, dev.model) |
| 181 | |
| 182 | void ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind, Error **errp); |
| 183 | |
| 184 | void ide_drive_get(DriveInfo **hd, int max_bus); |
| 185 | |
| 186 | #endif |