]> git.proxmox.com Git - mirror_qemu.git/blame - hw/ide/core.c
ide: code motion
[mirror_qemu.git] / hw / ide / core.c
CommitLineData
5391d806 1/*
38cdea7c 2 * QEMU IDE disk and CD/DVD-ROM Emulator
5fafdf24 3 *
5391d806 4 * Copyright (c) 2003 Fabrice Bellard
201a51fc 5 * Copyright (c) 2006 Openedhand Ltd.
5fafdf24 6 *
5391d806
FB
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
53239262 25#include "qemu/osdep.h"
59f2a787 26#include <hw/hw.h>
0d09e41a 27#include <hw/i386/pc.h>
a2cb15b0 28#include <hw/pci/pci.h>
0d09e41a 29#include <hw/isa/isa.h>
1de7afc9
PB
30#include "qemu/error-report.h"
31#include "qemu/timer.h"
9c17d615
PB
32#include "sysemu/sysemu.h"
33#include "sysemu/dma.h"
0d09e41a 34#include "hw/block/block.h"
4be74634 35#include "sysemu/block-backend.h"
59f2a787
GH
36
37#include <hw/ide/internal.h>
e8b54394 38
b93af93d
BW
39/* These values were based on a Seagate ST3500418AS but have been modified
40 to make more sense in QEMU */
41static const int smart_attributes[][12] = {
42 /* id, flags, hflags, val, wrst, raw (6 bytes), threshold */
43 /* raw read error rate*/
44 { 0x01, 0x03, 0x00, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06},
45 /* spin up */
46 { 0x03, 0x03, 0x00, 0x64, 0x64, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
47 /* start stop count */
48 { 0x04, 0x02, 0x00, 0x64, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14},
49 /* remapped sectors */
50 { 0x05, 0x03, 0x00, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24},
51 /* power on hours */
52 { 0x09, 0x03, 0x00, 0x64, 0x64, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
53 /* power cycle count */
54 { 0x0c, 0x03, 0x00, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
55 /* airflow-temperature-celsius */
56 { 190, 0x03, 0x00, 0x45, 0x45, 0x1f, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x32},
e8b54394
BW
57};
58
ce4b6522 59static int ide_handle_rw_error(IDEState *s, int error, int op);
40c4ed3f 60static void ide_dummy_transfer_stop(IDEState *s);
98087450 61
5391d806
FB
62static void padstr(char *str, const char *src, int len)
63{
64 int i, v;
65 for(i = 0; i < len; i++) {
66 if (*src)
67 v = *src++;
68 else
69 v = ' ';
69b34976 70 str[i^1] = v;
5391d806
FB
71 }
72}
73
67b915a5
FB
74static void put_le16(uint16_t *p, unsigned int v)
75{
0c4ad8dc 76 *p = cpu_to_le16(v);
67b915a5
FB
77}
78
01ce352e
JS
79static void ide_identify_size(IDEState *s)
80{
81 uint16_t *p = (uint16_t *)s->identify_data;
82 put_le16(p + 60, s->nb_sectors);
83 put_le16(p + 61, s->nb_sectors >> 16);
84 put_le16(p + 100, s->nb_sectors);
85 put_le16(p + 101, s->nb_sectors >> 16);
86 put_le16(p + 102, s->nb_sectors >> 32);
87 put_le16(p + 103, s->nb_sectors >> 48);
88}
89
5391d806
FB
90static void ide_identify(IDEState *s)
91{
92 uint16_t *p;
93 unsigned int oldsize;
d353fb72 94 IDEDevice *dev = s->unit ? s->bus->slave : s->bus->master;
5391d806 95
4bf6637d 96 p = (uint16_t *)s->identify_data;
94458802 97 if (s->identify_set) {
4bf6637d 98 goto fill_buffer;
94458802 99 }
4bf6637d 100 memset(p, 0, sizeof(s->identify_data));
94458802 101
67b915a5 102 put_le16(p + 0, 0x0040);
5fafdf24 103 put_le16(p + 1, s->cylinders);
67b915a5
FB
104 put_le16(p + 3, s->heads);
105 put_le16(p + 4, 512 * s->sectors); /* XXX: retired, remove ? */
106 put_le16(p + 5, 512); /* XXX: retired, remove ? */
5fafdf24 107 put_le16(p + 6, s->sectors);
fa879c64 108 padstr((char *)(p + 10), s->drive_serial_str, 20); /* serial number */
67b915a5
FB
109 put_le16(p + 20, 3); /* XXX: retired, remove ? */
110 put_le16(p + 21, 512); /* cache size in sectors */
111 put_le16(p + 22, 4); /* ecc bytes */
47c06340 112 padstr((char *)(p + 23), s->version, 8); /* firmware version */
27e0c9a1 113 padstr((char *)(p + 27), s->drive_model_str, 40); /* model */
3b46e624 114#if MAX_MULT_SECTORS > 1
67b915a5 115 put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
5391d806 116#endif
67b915a5 117 put_le16(p + 48, 1); /* dword I/O */
94458802 118 put_le16(p + 49, (1 << 11) | (1 << 9) | (1 << 8)); /* DMA and LBA supported */
67b915a5
FB
119 put_le16(p + 51, 0x200); /* PIO transfer cycle */
120 put_le16(p + 52, 0x200); /* DMA transfer cycle */
94458802 121 put_le16(p + 53, 1 | (1 << 1) | (1 << 2)); /* words 54-58,64-70,88 are valid */
67b915a5
FB
122 put_le16(p + 54, s->cylinders);
123 put_le16(p + 55, s->heads);
124 put_le16(p + 56, s->sectors);
5391d806 125 oldsize = s->cylinders * s->heads * s->sectors;
67b915a5
FB
126 put_le16(p + 57, oldsize);
127 put_le16(p + 58, oldsize >> 16);
5391d806 128 if (s->mult_sectors)
67b915a5 129 put_le16(p + 59, 0x100 | s->mult_sectors);
01ce352e
JS
130 /* *(p + 60) := nb_sectors -- see ide_identify_size */
131 /* *(p + 61) := nb_sectors >> 16 -- see ide_identify_size */
d1b5c20d 132 put_le16(p + 62, 0x07); /* single word dma0-2 supported */
94458802 133 put_le16(p + 63, 0x07); /* mdma0-2 supported */
79d1d331 134 put_le16(p + 64, 0x03); /* pio3-4 supported */
94458802
FB
135 put_le16(p + 65, 120);
136 put_le16(p + 66, 120);
137 put_le16(p + 67, 120);
138 put_le16(p + 68, 120);
d353fb72
CH
139 if (dev && dev->conf.discard_granularity) {
140 put_le16(p + 69, (1 << 14)); /* determinate TRIM behavior */
141 }
ccf0fd8b
RE
142
143 if (s->ncq_queues) {
144 put_le16(p + 75, s->ncq_queues - 1);
145 /* NCQ supported */
146 put_le16(p + 76, (1 << 8));
147 }
148
94458802
FB
149 put_le16(p + 80, 0xf0); /* ata3 -> ata6 supported */
150 put_le16(p + 81, 0x16); /* conforms to ata5 */
a58b8d54
CH
151 /* 14=NOP supported, 5=WCACHE supported, 0=SMART supported */
152 put_le16(p + 82, (1 << 14) | (1 << 5) | 1);
c2ff060f
FB
153 /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
154 put_le16(p + 83, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
95ebda85
FB
155 /* 14=set to 1, 8=has WWN, 1=SMART self test, 0=SMART error logging */
156 if (s->wwn) {
157 put_le16(p + 84, (1 << 14) | (1 << 8) | 0);
158 } else {
159 put_le16(p + 84, (1 << 14) | 0);
160 }
e900a7b7 161 /* 14 = NOP supported, 5=WCACHE enabled, 0=SMART feature set enabled */
4be74634
MA
162 if (blk_enable_write_cache(s->blk)) {
163 put_le16(p + 85, (1 << 14) | (1 << 5) | 1);
164 } else {
165 put_le16(p + 85, (1 << 14) | 1);
166 }
c2ff060f 167 /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
2844bdd9 168 put_le16(p + 86, (1 << 13) | (1 <<12) | (1 << 10));
95ebda85
FB
169 /* 14=set to 1, 8=has WWN, 1=SMART self test, 0=SMART error logging */
170 if (s->wwn) {
171 put_le16(p + 87, (1 << 14) | (1 << 8) | 0);
172 } else {
173 put_le16(p + 87, (1 << 14) | 0);
174 }
94458802
FB
175 put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
176 put_le16(p + 93, 1 | (1 << 14) | 0x2000);
01ce352e
JS
177 /* *(p + 100) := nb_sectors -- see ide_identify_size */
178 /* *(p + 101) := nb_sectors >> 16 -- see ide_identify_size */
179 /* *(p + 102) := nb_sectors >> 32 -- see ide_identify_size */
180 /* *(p + 103) := nb_sectors >> 48 -- see ide_identify_size */
d353fb72 181
57dac7ef
MA
182 if (dev && dev->conf.physical_block_size)
183 put_le16(p + 106, 0x6000 | get_physical_block_exp(&dev->conf));
95ebda85
FB
184 if (s->wwn) {
185 /* LE 16-bit words 111-108 contain 64-bit World Wide Name */
186 put_le16(p + 108, s->wwn >> 48);
187 put_le16(p + 109, s->wwn >> 32);
188 put_le16(p + 110, s->wwn >> 16);
189 put_le16(p + 111, s->wwn);
190 }
d353fb72
CH
191 if (dev && dev->conf.discard_granularity) {
192 put_le16(p + 169, 1); /* TRIM support */
193 }
94458802 194
01ce352e 195 ide_identify_size(s);
94458802 196 s->identify_set = 1;
4bf6637d
JS
197
198fill_buffer:
199 memcpy(s->io_buffer, p, sizeof(s->identify_data));
5391d806
FB
200}
201
202static void ide_atapi_identify(IDEState *s)
203{
204 uint16_t *p;
205
4bf6637d 206 p = (uint16_t *)s->identify_data;
94458802 207 if (s->identify_set) {
4bf6637d 208 goto fill_buffer;
94458802 209 }
4bf6637d 210 memset(p, 0, sizeof(s->identify_data));
94458802 211
5391d806 212 /* Removable CDROM, 50us response, 12 byte packets */
67b915a5 213 put_le16(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0));
fa879c64 214 padstr((char *)(p + 10), s->drive_serial_str, 20); /* serial number */
67b915a5
FB
215 put_le16(p + 20, 3); /* buffer type */
216 put_le16(p + 21, 512); /* cache size in sectors */
217 put_le16(p + 22, 4); /* ecc bytes */
47c06340 218 padstr((char *)(p + 23), s->version, 8); /* firmware version */
27e0c9a1 219 padstr((char *)(p + 27), s->drive_model_str, 40); /* model */
67b915a5 220 put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
8ccad811
FB
221#ifdef USE_DMA_CDROM
222 put_le16(p + 49, 1 << 9 | 1 << 8); /* DMA and LBA supported */
223 put_le16(p + 53, 7); /* words 64-70, 54-58, 88 valid */
d1b5c20d 224 put_le16(p + 62, 7); /* single word dma0-2 supported */
8ccad811 225 put_le16(p + 63, 7); /* mdma0-2 supported */
8ccad811 226#else
67b915a5
FB
227 put_le16(p + 49, 1 << 9); /* LBA supported, no DMA */
228 put_le16(p + 53, 3); /* words 64-70, 54-58 valid */
229 put_le16(p + 63, 0x103); /* DMA modes XXX: may be incorrect */
8ccad811 230#endif
79d1d331 231 put_le16(p + 64, 3); /* pio3-4 supported */
67b915a5
FB
232 put_le16(p + 65, 0xb4); /* minimum DMA multiword tx cycle time */
233 put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */
234 put_le16(p + 67, 0x12c); /* minimum PIO cycle time without flow control */
235 put_le16(p + 68, 0xb4); /* minimum PIO cycle time with IORDY flow control */
94458802 236
67b915a5
FB
237 put_le16(p + 71, 30); /* in ns */
238 put_le16(p + 72, 30); /* in ns */
5391d806 239
1bdaa28d
AG
240 if (s->ncq_queues) {
241 put_le16(p + 75, s->ncq_queues - 1);
242 /* NCQ supported */
243 put_le16(p + 76, (1 << 8));
244 }
245
67b915a5 246 put_le16(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */
c5fe97e3
JS
247 if (s->wwn) {
248 put_le16(p + 84, (1 << 8)); /* supports WWN for words 108-111 */
249 put_le16(p + 87, (1 << 8)); /* WWN enabled */
250 }
251
8ccad811
FB
252#ifdef USE_DMA_CDROM
253 put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
254#endif
c5fe97e3
JS
255
256 if (s->wwn) {
257 /* LE 16-bit words 111-108 contain 64-bit World Wide Name */
258 put_le16(p + 108, s->wwn >> 48);
259 put_le16(p + 109, s->wwn >> 32);
260 put_le16(p + 110, s->wwn >> 16);
261 put_le16(p + 111, s->wwn);
262 }
263
94458802 264 s->identify_set = 1;
4bf6637d
JS
265
266fill_buffer:
267 memcpy(s->io_buffer, p, sizeof(s->identify_data));
5391d806
FB
268}
269
01ce352e
JS
270static void ide_cfata_identify_size(IDEState *s)
271{
272 uint16_t *p = (uint16_t *)s->identify_data;
273 put_le16(p + 7, s->nb_sectors >> 16); /* Sectors per card */
274 put_le16(p + 8, s->nb_sectors); /* Sectors per card */
275 put_le16(p + 60, s->nb_sectors); /* Total LBA sectors */
276 put_le16(p + 61, s->nb_sectors >> 16); /* Total LBA sectors */
277}
278
201a51fc
AZ
279static void ide_cfata_identify(IDEState *s)
280{
281 uint16_t *p;
282 uint32_t cur_sec;
201a51fc 283
4bf6637d
JS
284 p = (uint16_t *)s->identify_data;
285 if (s->identify_set) {
201a51fc 286 goto fill_buffer;
4bf6637d 287 }
201a51fc
AZ
288 memset(p, 0, sizeof(s->identify_data));
289
290 cur_sec = s->cylinders * s->heads * s->sectors;
291
292 put_le16(p + 0, 0x848a); /* CF Storage Card signature */
293 put_le16(p + 1, s->cylinders); /* Default cylinders */
294 put_le16(p + 3, s->heads); /* Default heads */
295 put_le16(p + 6, s->sectors); /* Default sectors per track */
01ce352e
JS
296 /* *(p + 7) := nb_sectors >> 16 -- see ide_cfata_identify_size */
297 /* *(p + 8) := nb_sectors -- see ide_cfata_identify_size */
fa879c64 298 padstr((char *)(p + 10), s->drive_serial_str, 20); /* serial number */
201a51fc 299 put_le16(p + 22, 0x0004); /* ECC bytes */
47c06340 300 padstr((char *) (p + 23), s->version, 8); /* Firmware Revision */
27e0c9a1 301 padstr((char *) (p + 27), s->drive_model_str, 40);/* Model number */
201a51fc
AZ
302#if MAX_MULT_SECTORS > 1
303 put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
304#else
305 put_le16(p + 47, 0x0000);
306#endif
307 put_le16(p + 49, 0x0f00); /* Capabilities */
308 put_le16(p + 51, 0x0002); /* PIO cycle timing mode */
309 put_le16(p + 52, 0x0001); /* DMA cycle timing mode */
310 put_le16(p + 53, 0x0003); /* Translation params valid */
311 put_le16(p + 54, s->cylinders); /* Current cylinders */
312 put_le16(p + 55, s->heads); /* Current heads */
313 put_le16(p + 56, s->sectors); /* Current sectors */
314 put_le16(p + 57, cur_sec); /* Current capacity */
315 put_le16(p + 58, cur_sec >> 16); /* Current capacity */
316 if (s->mult_sectors) /* Multiple sector setting */
317 put_le16(p + 59, 0x100 | s->mult_sectors);
01ce352e
JS
318 /* *(p + 60) := nb_sectors -- see ide_cfata_identify_size */
319 /* *(p + 61) := nb_sectors >> 16 -- see ide_cfata_identify_size */
201a51fc
AZ
320 put_le16(p + 63, 0x0203); /* Multiword DMA capability */
321 put_le16(p + 64, 0x0001); /* Flow Control PIO support */
322 put_le16(p + 65, 0x0096); /* Min. Multiword DMA cycle */
323 put_le16(p + 66, 0x0096); /* Rec. Multiword DMA cycle */
324 put_le16(p + 68, 0x00b4); /* Min. PIO cycle time */
325 put_le16(p + 82, 0x400c); /* Command Set supported */
326 put_le16(p + 83, 0x7068); /* Command Set supported */
327 put_le16(p + 84, 0x4000); /* Features supported */
328 put_le16(p + 85, 0x000c); /* Command Set enabled */
329 put_le16(p + 86, 0x7044); /* Command Set enabled */
330 put_le16(p + 87, 0x4000); /* Features enabled */
331 put_le16(p + 91, 0x4060); /* Current APM level */
332 put_le16(p + 129, 0x0002); /* Current features option */
333 put_le16(p + 130, 0x0005); /* Reassigned sectors */
334 put_le16(p + 131, 0x0001); /* Initial power mode */
335 put_le16(p + 132, 0x0000); /* User signature */
336 put_le16(p + 160, 0x8100); /* Power requirement */
337 put_le16(p + 161, 0x8001); /* CF command set */
338
01ce352e 339 ide_cfata_identify_size(s);
201a51fc
AZ
340 s->identify_set = 1;
341
342fill_buffer:
343 memcpy(s->io_buffer, p, sizeof(s->identify_data));
344}
345
5391d806
FB
346static void ide_set_signature(IDEState *s)
347{
348 s->select &= 0xf0; /* clear head */
349 /* put signature */
350 s->nsector = 1;
351 s->sector = 1;
cd8722bb 352 if (s->drive_kind == IDE_CD) {
5391d806
FB
353 s->lcyl = 0x14;
354 s->hcyl = 0xeb;
4be74634 355 } else if (s->blk) {
5391d806
FB
356 s->lcyl = 0;
357 s->hcyl = 0;
358 } else {
359 s->lcyl = 0xff;
360 s->hcyl = 0xff;
361 }
362}
363
d353fb72 364typedef struct TrimAIOCB {
7c84b1b8 365 BlockAIOCB common;
a987ee1f 366 BlockBackend *blk;
d353fb72
CH
367 QEMUBH *bh;
368 int ret;
501378c3 369 QEMUIOVector *qiov;
7c84b1b8 370 BlockAIOCB *aiocb;
501378c3 371 int i, j;
d353fb72
CH
372} TrimAIOCB;
373
7c84b1b8 374static void trim_aio_cancel(BlockAIOCB *acb)
d353fb72
CH
375{
376 TrimAIOCB *iocb = container_of(acb, TrimAIOCB, common);
377
e551c999 378 /* Exit the loop so ide_issue_trim_cb will not continue */
501378c3
PB
379 iocb->j = iocb->qiov->niov - 1;
380 iocb->i = (iocb->qiov->iov[iocb->j].iov_len / 8) - 1;
381
e551c999 382 iocb->ret = -ECANCELED;
501378c3
PB
383
384 if (iocb->aiocb) {
4be74634 385 blk_aio_cancel_async(iocb->aiocb);
e551c999 386 iocb->aiocb = NULL;
501378c3 387 }
d353fb72
CH
388}
389
d7331bed 390static const AIOCBInfo trim_aiocb_info = {
d353fb72 391 .aiocb_size = sizeof(TrimAIOCB),
e551c999 392 .cancel_async = trim_aio_cancel,
d353fb72
CH
393};
394
395static void ide_trim_bh_cb(void *opaque)
396{
397 TrimAIOCB *iocb = opaque;
398
399 iocb->common.cb(iocb->common.opaque, iocb->ret);
400
401 qemu_bh_delete(iocb->bh);
402 iocb->bh = NULL;
8007429a 403 qemu_aio_unref(iocb);
d353fb72
CH
404}
405
501378c3
PB
406static void ide_issue_trim_cb(void *opaque, int ret)
407{
408 TrimAIOCB *iocb = opaque;
409 if (ret >= 0) {
410 while (iocb->j < iocb->qiov->niov) {
411 int j = iocb->j;
412 while (++iocb->i < iocb->qiov->iov[j].iov_len / 8) {
413 int i = iocb->i;
414 uint64_t *buffer = iocb->qiov->iov[j].iov_base;
415
416 /* 6-byte LBA + 2-byte range per entry */
417 uint64_t entry = le64_to_cpu(buffer[i]);
418 uint64_t sector = entry & 0x0000ffffffffffffULL;
419 uint16_t count = entry >> 48;
420
421 if (count == 0) {
422 continue;
423 }
424
425 /* Got an entry! Submit and exit. */
a987ee1f
MA
426 iocb->aiocb = blk_aio_discard(iocb->blk, sector, count,
427 ide_issue_trim_cb, opaque);
501378c3
PB
428 return;
429 }
430
431 iocb->j++;
432 iocb->i = -1;
433 }
434 } else {
435 iocb->ret = ret;
436 }
437
438 iocb->aiocb = NULL;
439 if (iocb->bh) {
440 qemu_bh_schedule(iocb->bh);
441 }
442}
443
4be74634 444BlockAIOCB *ide_issue_trim(BlockBackend *blk,
d353fb72 445 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
097310b5 446 BlockCompletionFunc *cb, void *opaque)
d353fb72
CH
447{
448 TrimAIOCB *iocb;
d353fb72 449
4be74634 450 iocb = blk_aio_get(&trim_aiocb_info, blk, cb, opaque);
a987ee1f 451 iocb->blk = blk;
d353fb72
CH
452 iocb->bh = qemu_bh_new(ide_trim_bh_cb, iocb);
453 iocb->ret = 0;
501378c3
PB
454 iocb->qiov = qiov;
455 iocb->i = -1;
456 iocb->j = 0;
457 ide_issue_trim_cb(iocb, 0);
d353fb72
CH
458 return &iocb->common;
459}
460
9ef2e93f 461void ide_abort_command(IDEState *s)
5391d806 462{
08ee9e33 463 ide_transfer_stop(s);
5391d806
FB
464 s->status = READY_STAT | ERR_STAT;
465 s->error = ABRT_ERR;
466}
467
5391d806 468/* prepare data transfer and tell what to do after */
33231e0e
KW
469void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
470 EndTransferFunc *end_transfer_func)
5391d806
FB
471{
472 s->end_transfer_func = end_transfer_func;
473 s->data_ptr = buf;
474 s->data_end = buf + size;
40a6238a 475 if (!(s->status & ERR_STAT)) {
7603d156 476 s->status |= DRQ_STAT;
40a6238a 477 }
44635123
PB
478 if (s->bus->dma->ops->start_transfer) {
479 s->bus->dma->ops->start_transfer(s->bus->dma);
480 }
5391d806
FB
481}
482
c7e73adb
PB
483static void ide_cmd_done(IDEState *s)
484{
485 if (s->bus->dma->ops->cmd_done) {
486 s->bus->dma->ops->cmd_done(s->bus->dma);
487 }
488}
489
33231e0e 490void ide_transfer_stop(IDEState *s)
5391d806
FB
491{
492 s->end_transfer_func = ide_transfer_stop;
493 s->data_ptr = s->io_buffer;
494 s->data_end = s->io_buffer;
495 s->status &= ~DRQ_STAT;
c7e73adb 496 ide_cmd_done(s);
5391d806
FB
497}
498
356721ae 499int64_t ide_get_sector(IDEState *s)
5391d806
FB
500{
501 int64_t sector_num;
502 if (s->select & 0x40) {
503 /* lba */
c2ff060f
FB
504 if (!s->lba48) {
505 sector_num = ((s->select & 0x0f) << 24) | (s->hcyl << 16) |
506 (s->lcyl << 8) | s->sector;
507 } else {
508 sector_num = ((int64_t)s->hob_hcyl << 40) |
509 ((int64_t) s->hob_lcyl << 32) |
510 ((int64_t) s->hob_sector << 24) |
511 ((int64_t) s->hcyl << 16) |
512 ((int64_t) s->lcyl << 8) | s->sector;
513 }
5391d806
FB
514 } else {
515 sector_num = ((s->hcyl << 8) | s->lcyl) * s->heads * s->sectors +
c2ff060f 516 (s->select & 0x0f) * s->sectors + (s->sector - 1);
5391d806
FB
517 }
518 return sector_num;
519}
520
356721ae 521void ide_set_sector(IDEState *s, int64_t sector_num)
5391d806
FB
522{
523 unsigned int cyl, r;
524 if (s->select & 0x40) {
c2ff060f
FB
525 if (!s->lba48) {
526 s->select = (s->select & 0xf0) | (sector_num >> 24);
527 s->hcyl = (sector_num >> 16);
528 s->lcyl = (sector_num >> 8);
529 s->sector = (sector_num);
530 } else {
531 s->sector = sector_num;
532 s->lcyl = sector_num >> 8;
533 s->hcyl = sector_num >> 16;
534 s->hob_sector = sector_num >> 24;
535 s->hob_lcyl = sector_num >> 32;
536 s->hob_hcyl = sector_num >> 40;
537 }
5391d806
FB
538 } else {
539 cyl = sector_num / (s->heads * s->sectors);
540 r = sector_num % (s->heads * s->sectors);
541 s->hcyl = cyl >> 8;
542 s->lcyl = cyl;
1b8eb456 543 s->select = (s->select & 0xf0) | ((r / s->sectors) & 0x0f);
5391d806
FB
544 s->sector = (r % s->sectors) + 1;
545 }
546}
547
e162cfb0
AZ
548static void ide_rw_error(IDEState *s) {
549 ide_abort_command(s);
9cdd03a7 550 ide_set_irq(s->bus);
e162cfb0
AZ
551}
552
58ac3211
MA
553static bool ide_sect_range_ok(IDEState *s,
554 uint64_t sector, uint64_t nb_sectors)
555{
556 uint64_t total_sectors;
557
4be74634 558 blk_get_geometry(s->blk, &total_sectors);
58ac3211
MA
559 if (sector > total_sectors || nb_sectors > total_sectors - sector) {
560 return false;
561 }
562 return true;
563}
564
1d8c11d6
PL
565static void ide_buffered_readv_cb(void *opaque, int ret)
566{
567 IDEBufferedRequest *req = opaque;
568 if (!req->orphaned) {
569 if (!ret) {
570 qemu_iovec_from_buf(req->original_qiov, 0, req->iov.iov_base,
571 req->original_qiov->size);
572 }
573 req->original_cb(req->original_opaque, ret);
574 }
575 QLIST_REMOVE(req, list);
576 qemu_vfree(req->iov.iov_base);
577 g_free(req);
578}
579
580#define MAX_BUFFERED_REQS 16
581
582BlockAIOCB *ide_buffered_readv(IDEState *s, int64_t sector_num,
583 QEMUIOVector *iov, int nb_sectors,
584 BlockCompletionFunc *cb, void *opaque)
585{
586 BlockAIOCB *aioreq;
587 IDEBufferedRequest *req;
588 int c = 0;
589
590 QLIST_FOREACH(req, &s->buffered_requests, list) {
591 c++;
592 }
593 if (c > MAX_BUFFERED_REQS) {
594 return blk_abort_aio_request(s->blk, cb, opaque, -EIO);
595 }
596
597 req = g_new0(IDEBufferedRequest, 1);
598 req->original_qiov = iov;
599 req->original_cb = cb;
600 req->original_opaque = opaque;
601 req->iov.iov_base = qemu_blockalign(blk_bs(s->blk), iov->size);
602 req->iov.iov_len = iov->size;
603 qemu_iovec_init_external(&req->qiov, &req->iov, 1);
604
605 aioreq = blk_aio_readv(s->blk, sector_num, &req->qiov, nb_sectors,
606 ide_buffered_readv_cb, req);
607
608 QLIST_INSERT_HEAD(&s->buffered_requests, req, list);
609 return aioreq;
610}
611
4e2b8b4a
PB
612static void ide_sector_read(IDEState *s);
613
bef0fd59
SH
614static void ide_sector_read_cb(void *opaque, int ret)
615{
616 IDEState *s = opaque;
617 int n;
618
619 s->pio_aiocb = NULL;
620 s->status &= ~BUSY_STAT;
621
0d910cfe
FZ
622 if (ret == -ECANCELED) {
623 return;
624 }
bef0fd59 625 if (ret != 0) {
fd648f10
PB
626 if (ide_handle_rw_error(s, -ret, IDE_RETRY_PIO |
627 IDE_RETRY_READ)) {
bef0fd59
SH
628 return;
629 }
630 }
631
ecca3b39
AG
632 block_acct_done(blk_get_stats(s->blk), &s->acct);
633
bef0fd59
SH
634 n = s->nsector;
635 if (n > s->req_nb_sectors) {
636 n = s->req_nb_sectors;
637 }
638
bef0fd59
SH
639 ide_set_sector(s, ide_get_sector(s) + n);
640 s->nsector -= n;
dd0bf7ba
JS
641 /* Allow the guest to read the io_buffer */
642 ide_transfer_start(s, s->io_buffer, n * BDRV_SECTOR_SIZE, ide_sector_read);
dd0bf7ba 643 ide_set_irq(s->bus);
bef0fd59
SH
644}
645
4e2b8b4a 646static void ide_sector_read(IDEState *s)
5391d806
FB
647{
648 int64_t sector_num;
bef0fd59 649 int n;
5391d806
FB
650
651 s->status = READY_STAT | SEEK_STAT;
a136e5a8 652 s->error = 0; /* not needed by IDE spec, but needed by Windows */
5391d806
FB
653 sector_num = ide_get_sector(s);
654 n = s->nsector;
bef0fd59 655
5391d806 656 if (n == 0) {
5391d806 657 ide_transfer_stop(s);
bef0fd59
SH
658 return;
659 }
660
661 s->status |= BUSY_STAT;
662
663 if (n > s->req_nb_sectors) {
664 n = s->req_nb_sectors;
665 }
666
5391d806 667#if defined(DEBUG_IDE)
bef0fd59 668 printf("sector=%" PRId64 "\n", sector_num);
5391d806 669#endif
a597e79c 670
58ac3211
MA
671 if (!ide_sect_range_ok(s, sector_num, n)) {
672 ide_rw_error(s);
ecca3b39 673 block_acct_invalid(blk_get_stats(s->blk), BLOCK_ACCT_READ);
58ac3211
MA
674 return;
675 }
676
bef0fd59
SH
677 s->iov.iov_base = s->io_buffer;
678 s->iov.iov_len = n * BDRV_SECTOR_SIZE;
679 qemu_iovec_init_external(&s->qiov, &s->iov, 1);
680
4be74634 681 block_acct_start(blk_get_stats(s->blk), &s->acct,
5366d0c8 682 n * BDRV_SECTOR_SIZE, BLOCK_ACCT_READ);
d66a8fa8
PL
683 s->pio_aiocb = ide_buffered_readv(s, sector_num, &s->qiov, n,
684 ide_sector_read_cb, s);
5391d806
FB
685}
686
aaeda4a3 687void dma_buf_commit(IDEState *s, uint32_t tx_bytes)
7aea4412 688{
659142ec
JS
689 if (s->bus->dma->ops->commit_buf) {
690 s->bus->dma->ops->commit_buf(s->bus->dma, tx_bytes);
691 }
aaeda4a3 692 s->io_buffer_offset += tx_bytes;
1fb8648d 693 qemu_sglist_destroy(&s->sg);
7aea4412
AL
694}
695
0e7ce54c 696void ide_set_inactive(IDEState *s, bool more)
8337606d 697{
40a6238a 698 s->bus->dma->aiocb = NULL;
a96cb236 699 s->bus->retry_unit = -1;
dc5d0af4
PB
700 s->bus->retry_sector_num = 0;
701 s->bus->retry_nsector = 0;
829b933b 702 if (s->bus->dma->ops->set_inactive) {
0e7ce54c 703 s->bus->dma->ops->set_inactive(s->bus->dma, more);
829b933b 704 }
c7e73adb 705 ide_cmd_done(s);
8337606d
KW
706}
707
356721ae 708void ide_dma_error(IDEState *s)
e162cfb0 709{
659142ec 710 dma_buf_commit(s, 0);
08ee9e33 711 ide_abort_command(s);
0e7ce54c 712 ide_set_inactive(s, false);
9cdd03a7 713 ide_set_irq(s->bus);
e162cfb0
AZ
714}
715
ce4b6522 716static int ide_handle_rw_error(IDEState *s, int error, int op)
428c5705 717{
fd648f10 718 bool is_read = (op & IDE_RETRY_READ) != 0;
4be74634 719 BlockErrorAction action = blk_get_error_action(s->blk, is_read, error);
428c5705 720
a589569f 721 if (action == BLOCK_ERROR_ACTION_STOP) {
a96cb236 722 assert(s->bus->retry_unit == s->unit);
def93791 723 s->bus->error_status = op;
a589569f 724 } else if (action == BLOCK_ERROR_ACTION_REPORT) {
ecca3b39 725 block_acct_failed(blk_get_stats(s->blk), &s->acct);
fd648f10 726 if (op & IDE_RETRY_DMA) {
428c5705 727 ide_dma_error(s);
7aea4412 728 } else {
428c5705 729 ide_rw_error(s);
7aea4412 730 }
428c5705 731 }
4be74634 732 blk_error_action(s->blk, action, is_read, error);
a589569f 733 return action != BLOCK_ERROR_ACTION_IGNORE;
428c5705
AL
734}
735
4e2b8b4a 736static void ide_dma_cb(void *opaque, int ret)
98087450 737{
40a6238a 738 IDEState *s = opaque;
8ccad811
FB
739 int n;
740 int64_t sector_num;
038268e2 741 bool stay_active = false;
8ccad811 742
0d910cfe
FZ
743 if (ret == -ECANCELED) {
744 return;
745 }
e162cfb0 746 if (ret < 0) {
fd648f10 747 int op = IDE_RETRY_DMA;
cd369c46 748
4e1e0051 749 if (s->dma_cmd == IDE_DMA_READ)
fd648f10 750 op |= IDE_RETRY_READ;
d353fb72 751 else if (s->dma_cmd == IDE_DMA_TRIM)
fd648f10 752 op |= IDE_RETRY_TRIM;
d353fb72 753
cd369c46 754 if (ide_handle_rw_error(s, -ret, op)) {
ce4b6522
KW
755 return;
756 }
e162cfb0
AZ
757 }
758
8ccad811 759 n = s->io_buffer_size >> 9;
038268e2
KW
760 if (n > s->nsector) {
761 /* The PRDs were longer than needed for this request. Shorten them so
762 * we don't get a negative remainder. The Active bit must remain set
763 * after the request completes. */
764 n = s->nsector;
765 stay_active = true;
766 }
767
8ccad811
FB
768 sector_num = ide_get_sector(s);
769 if (n > 0) {
a718978e
JS
770 assert(n * 512 == s->sg.size);
771 dma_buf_commit(s, s->sg.size);
8ccad811
FB
772 sector_num += n;
773 ide_set_sector(s, sector_num);
774 s->nsector -= n;
8ccad811
FB
775 }
776
777 /* end of transfer ? */
778 if (s->nsector == 0) {
98087450 779 s->status = READY_STAT | SEEK_STAT;
9cdd03a7 780 ide_set_irq(s->bus);
cd369c46 781 goto eot;
98087450 782 }
8ccad811
FB
783
784 /* launch next transfer */
785 n = s->nsector;
596bb44d 786 s->io_buffer_index = 0;
8ccad811 787 s->io_buffer_size = n * 512;
a718978e 788 if (s->bus->dma->ops->prepare_buf(s->bus->dma, s->io_buffer_size) < 512) {
69c38b8f
KW
789 /* The PRDs were too short. Reset the Active bit, but don't raise an
790 * interrupt. */
72bcca73 791 s->status = READY_STAT | SEEK_STAT;
3251bdcf 792 dma_buf_commit(s, 0);
7aea4412 793 goto eot;
69c38b8f 794 }
cd369c46 795
8ccad811 796#ifdef DEBUG_AIO
4e1e0051
CH
797 printf("ide_dma_cb: sector_num=%" PRId64 " n=%d, cmd_cmd=%d\n",
798 sector_num, n, s->dma_cmd);
8ccad811 799#endif
cd369c46 800
d66168ed
MT
801 if ((s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) &&
802 !ide_sect_range_ok(s, sector_num, n)) {
58ac3211 803 ide_dma_error(s);
ecca3b39 804 block_acct_invalid(blk_get_stats(s->blk), s->acct.type);
58ac3211
MA
805 return;
806 }
807
4e1e0051
CH
808 switch (s->dma_cmd) {
809 case IDE_DMA_READ:
4be74634
MA
810 s->bus->dma->aiocb = dma_blk_read(s->blk, &s->sg, sector_num,
811 ide_dma_cb, s);
4e1e0051
CH
812 break;
813 case IDE_DMA_WRITE:
4be74634
MA
814 s->bus->dma->aiocb = dma_blk_write(s->blk, &s->sg, sector_num,
815 ide_dma_cb, s);
4e1e0051 816 break;
d353fb72 817 case IDE_DMA_TRIM:
4be74634
MA
818 s->bus->dma->aiocb = dma_blk_io(s->blk, &s->sg, sector_num,
819 ide_issue_trim, ide_dma_cb, s,
820 DMA_DIRECTION_TO_DEVICE);
d353fb72 821 break;
cd369c46 822 }
cd369c46
CH
823 return;
824
825eot:
a597e79c 826 if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) {
4be74634 827 block_acct_done(blk_get_stats(s->blk), &s->acct);
a597e79c 828 }
0e7ce54c 829 ide_set_inactive(s, stay_active);
98087450
FB
830}
831
4e1e0051 832static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd)
98087450 833{
8ccad811 834 s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
98087450 835 s->io_buffer_size = 0;
4e1e0051 836 s->dma_cmd = dma_cmd;
a597e79c
CH
837
838 switch (dma_cmd) {
839 case IDE_DMA_READ:
4be74634 840 block_acct_start(blk_get_stats(s->blk), &s->acct,
5366d0c8 841 s->nsector * BDRV_SECTOR_SIZE, BLOCK_ACCT_READ);
a597e79c
CH
842 break;
843 case IDE_DMA_WRITE:
4be74634 844 block_acct_start(blk_get_stats(s->blk), &s->acct,
5366d0c8 845 s->nsector * BDRV_SECTOR_SIZE, BLOCK_ACCT_WRITE);
a597e79c
CH
846 break;
847 default:
848 break;
849 }
850
4855b576
PB
851 ide_start_dma(s, ide_dma_cb);
852}
853
097310b5 854void ide_start_dma(IDEState *s, BlockCompletionFunc *cb)
4855b576 855{
c71c06d4 856 s->io_buffer_index = 0;
a96cb236 857 s->bus->retry_unit = s->unit;
dc5d0af4
PB
858 s->bus->retry_sector_num = ide_get_sector(s);
859 s->bus->retry_nsector = s->nsector;
4855b576
PB
860 if (s->bus->dma->ops->start_dma) {
861 s->bus->dma->ops->start_dma(s->bus->dma, s, cb);
862 }
98087450
FB
863}
864
4e2b8b4a
PB
865static void ide_sector_write(IDEState *s);
866
a09db21f
FB
867static void ide_sector_write_timer_cb(void *opaque)
868{
869 IDEState *s = opaque;
9cdd03a7 870 ide_set_irq(s->bus);
a09db21f
FB
871}
872
e82dabd8 873static void ide_sector_write_cb(void *opaque, int ret)
5391d806 874{
e82dabd8
SH
875 IDEState *s = opaque;
876 int n;
a597e79c 877
0d910cfe
FZ
878 if (ret == -ECANCELED) {
879 return;
880 }
428c5705 881
e82dabd8
SH
882 s->pio_aiocb = NULL;
883 s->status &= ~BUSY_STAT;
884
e162cfb0 885 if (ret != 0) {
fd648f10 886 if (ide_handle_rw_error(s, -ret, IDE_RETRY_PIO)) {
428c5705 887 return;
e82dabd8 888 }
e162cfb0
AZ
889 }
890
ecca3b39
AG
891 block_acct_done(blk_get_stats(s->blk), &s->acct);
892
e82dabd8
SH
893 n = s->nsector;
894 if (n > s->req_nb_sectors) {
895 n = s->req_nb_sectors;
896 }
5391d806 897 s->nsector -= n;
36334faf 898
6aff22c0 899 ide_set_sector(s, ide_get_sector(s) + n);
5391d806 900 if (s->nsector == 0) {
292eef5a 901 /* no more sectors to write */
5391d806
FB
902 ide_transfer_stop(s);
903 } else {
e82dabd8
SH
904 int n1 = s->nsector;
905 if (n1 > s->req_nb_sectors) {
5391d806 906 n1 = s->req_nb_sectors;
e82dabd8
SH
907 }
908 ide_transfer_start(s, s->io_buffer, n1 * BDRV_SECTOR_SIZE,
909 ide_sector_write);
5391d806 910 }
3b46e624 911
31c2a146
TS
912 if (win2k_install_hack && ((++s->irq_count % 16) == 0)) {
913 /* It seems there is a bug in the Windows 2000 installer HDD
914 IDE driver which fills the disk with empty logs when the
915 IDE write IRQ comes too early. This hack tries to correct
916 that at the expense of slower write performances. Use this
917 option _only_ to install Windows 2000. You must disable it
918 for normal use. */
bc72ad67
AB
919 timer_mod(s->sector_write_timer,
920 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (get_ticks_per_sec() / 1000));
f7736b91 921 } else {
9cdd03a7 922 ide_set_irq(s->bus);
31c2a146 923 }
5391d806
FB
924}
925
4e2b8b4a 926static void ide_sector_write(IDEState *s)
e82dabd8
SH
927{
928 int64_t sector_num;
929 int n;
930
931 s->status = READY_STAT | SEEK_STAT | BUSY_STAT;
932 sector_num = ide_get_sector(s);
933#if defined(DEBUG_IDE)
934 printf("sector=%" PRId64 "\n", sector_num);
935#endif
936 n = s->nsector;
937 if (n > s->req_nb_sectors) {
938 n = s->req_nb_sectors;
939 }
940
58ac3211
MA
941 if (!ide_sect_range_ok(s, sector_num, n)) {
942 ide_rw_error(s);
ecca3b39 943 block_acct_invalid(blk_get_stats(s->blk), BLOCK_ACCT_WRITE);
58ac3211
MA
944 return;
945 }
946
e82dabd8
SH
947 s->iov.iov_base = s->io_buffer;
948 s->iov.iov_len = n * BDRV_SECTOR_SIZE;
949 qemu_iovec_init_external(&s->qiov, &s->iov, 1);
950
4be74634 951 block_acct_start(blk_get_stats(s->blk), &s->acct,
c618f331 952 n * BDRV_SECTOR_SIZE, BLOCK_ACCT_WRITE);
4be74634
MA
953 s->pio_aiocb = blk_aio_writev(s->blk, sector_num, &s->qiov, n,
954 ide_sector_write_cb, s);
e82dabd8
SH
955}
956
b0484ae4
CH
957static void ide_flush_cb(void *opaque, int ret)
958{
959 IDEState *s = opaque;
960
69f72a22
PB
961 s->pio_aiocb = NULL;
962
0d910cfe
FZ
963 if (ret == -ECANCELED) {
964 return;
965 }
e2bcadad
KW
966 if (ret < 0) {
967 /* XXX: What sector number to set here? */
fd648f10 968 if (ide_handle_rw_error(s, -ret, IDE_RETRY_FLUSH)) {
e2bcadad
KW
969 return;
970 }
971 }
b0484ae4 972
4be74634
MA
973 if (s->blk) {
974 block_acct_done(blk_get_stats(s->blk), &s->acct);
f7f3ff1d 975 }
b0484ae4 976 s->status = READY_STAT | SEEK_STAT;
c7e73adb 977 ide_cmd_done(s);
b0484ae4
CH
978 ide_set_irq(s->bus);
979}
980
4e2b8b4a 981static void ide_flush_cache(IDEState *s)
6bcb1a79 982{
4be74634 983 if (s->blk == NULL) {
6bcb1a79 984 ide_flush_cb(s, 0);
b2df7531
KW
985 return;
986 }
987
f68ec837 988 s->status |= BUSY_STAT;
4be74634
MA
989 block_acct_start(blk_get_stats(s->blk), &s->acct, 0, BLOCK_ACCT_FLUSH);
990 s->pio_aiocb = blk_aio_flush(s->blk, ide_flush_cb, s);
6bcb1a79
KW
991}
992
201a51fc
AZ
993static void ide_cfata_metadata_inquiry(IDEState *s)
994{
995 uint16_t *p;
996 uint32_t spd;
997
998 p = (uint16_t *) s->io_buffer;
999 memset(p, 0, 0x200);
1000 spd = ((s->mdata_size - 1) >> 9) + 1;
1001
1002 put_le16(p + 0, 0x0001); /* Data format revision */
1003 put_le16(p + 1, 0x0000); /* Media property: silicon */
1004 put_le16(p + 2, s->media_changed); /* Media status */
1005 put_le16(p + 3, s->mdata_size & 0xffff); /* Capacity in bytes (low) */
1006 put_le16(p + 4, s->mdata_size >> 16); /* Capacity in bytes (high) */
1007 put_le16(p + 5, spd & 0xffff); /* Sectors per device (low) */
1008 put_le16(p + 6, spd >> 16); /* Sectors per device (high) */
1009}
1010
1011static void ide_cfata_metadata_read(IDEState *s)
1012{
1013 uint16_t *p;
1014
1015 if (((s->hcyl << 16) | s->lcyl) << 9 > s->mdata_size + 2) {
1016 s->status = ERR_STAT;
1017 s->error = ABRT_ERR;
1018 return;
1019 }
1020
1021 p = (uint16_t *) s->io_buffer;
1022 memset(p, 0, 0x200);
1023
1024 put_le16(p + 0, s->media_changed); /* Media status */
1025 memcpy(p + 1, s->mdata_storage + (((s->hcyl << 16) | s->lcyl) << 9),
1026 MIN(MIN(s->mdata_size - (((s->hcyl << 16) | s->lcyl) << 9),
1027 s->nsector << 9), 0x200 - 2));
1028}
1029
1030static void ide_cfata_metadata_write(IDEState *s)
1031{
1032 if (((s->hcyl << 16) | s->lcyl) << 9 > s->mdata_size + 2) {
1033 s->status = ERR_STAT;
1034 s->error = ABRT_ERR;
1035 return;
1036 }
1037
1038 s->media_changed = 0;
1039
1040 memcpy(s->mdata_storage + (((s->hcyl << 16) | s->lcyl) << 9),
1041 s->io_buffer + 2,
1042 MIN(MIN(s->mdata_size - (((s->hcyl << 16) | s->lcyl) << 9),
1043 s->nsector << 9), 0x200 - 2));
1044}
1045
bd491d6a 1046/* called when the inserted state of the media has changed */
7d4b4ba5 1047static void ide_cd_change_cb(void *opaque, bool load)
bd491d6a
TS
1048{
1049 IDEState *s = opaque;
96b8f136 1050 uint64_t nb_sectors;
bd491d6a 1051
25ad22bc 1052 s->tray_open = !load;
4be74634 1053 blk_get_geometry(s->blk, &nb_sectors);
bd491d6a 1054 s->nb_sectors = nb_sectors;
9118e7f0 1055
4b9b7092
AS
1056 /*
1057 * First indicate to the guest that a CD has been removed. That's
1058 * done on the next command the guest sends us.
1059 *
67cc61e4 1060 * Then we set UNIT_ATTENTION, by which the guest will
4b9b7092
AS
1061 * detect a new CD in the drive. See ide_atapi_cmd() for details.
1062 */
93c8cfd9 1063 s->cdrom_changed = 1;
996faf1a 1064 s->events.new_media = true;
2df0a3a3
PB
1065 s->events.eject_request = false;
1066 ide_set_irq(s->bus);
1067}
1068
1069static void ide_cd_eject_request_cb(void *opaque, bool force)
1070{
1071 IDEState *s = opaque;
1072
1073 s->events.eject_request = true;
1074 if (force) {
1075 s->tray_locked = false;
1076 }
9cdd03a7 1077 ide_set_irq(s->bus);
bd491d6a
TS
1078}
1079
c2ff060f
FB
1080static void ide_cmd_lba48_transform(IDEState *s, int lba48)
1081{
1082 s->lba48 = lba48;
1083
1084 /* handle the 'magic' 0 nsector count conversion here. to avoid
1085 * fiddling with the rest of the read logic, we just store the
1086 * full sector count in ->nsector and ignore ->hob_nsector from now
1087 */
1088 if (!s->lba48) {
1089 if (!s->nsector)
1090 s->nsector = 256;
1091 } else {
1092 if (!s->nsector && !s->hob_nsector)
1093 s->nsector = 65536;
1094 else {
1095 int lo = s->nsector;
1096 int hi = s->hob_nsector;
1097
1098 s->nsector = (hi << 8) | lo;
1099 }
1100 }
1101}
1102
bcbdc4d3 1103static void ide_clear_hob(IDEBus *bus)
c2ff060f
FB
1104{
1105 /* any write clears HOB high bit of device control register */
bcbdc4d3
GH
1106 bus->ifs[0].select &= ~(1 << 7);
1107 bus->ifs[1].select &= ~(1 << 7);
c2ff060f
FB
1108}
1109
356721ae 1110void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
caed8802 1111{
bcbdc4d3 1112 IDEBus *bus = opaque;
5391d806
FB
1113
1114#ifdef DEBUG_IDE
1115 printf("IDE: write addr=0x%x val=0x%02x\n", addr, val);
1116#endif
c2ff060f 1117
5391d806 1118 addr &= 7;
fcdd25ab
AL
1119
1120 /* ignore writes to command block while busy with previous command */
bcbdc4d3 1121 if (addr != 7 && (idebus_active_if(bus)->status & (BUSY_STAT|DRQ_STAT)))
fcdd25ab
AL
1122 return;
1123
5391d806
FB
1124 switch(addr) {
1125 case 0:
1126 break;
1127 case 1:
bcbdc4d3 1128 ide_clear_hob(bus);
c45c3d00 1129 /* NOTE: data is written to the two drives */
bcbdc4d3
GH
1130 bus->ifs[0].hob_feature = bus->ifs[0].feature;
1131 bus->ifs[1].hob_feature = bus->ifs[1].feature;
1132 bus->ifs[0].feature = val;
1133 bus->ifs[1].feature = val;
5391d806
FB
1134 break;
1135 case 2:
bcbdc4d3
GH
1136 ide_clear_hob(bus);
1137 bus->ifs[0].hob_nsector = bus->ifs[0].nsector;
1138 bus->ifs[1].hob_nsector = bus->ifs[1].nsector;
1139 bus->ifs[0].nsector = val;
1140 bus->ifs[1].nsector = val;
5391d806
FB
1141 break;
1142 case 3:
bcbdc4d3
GH
1143 ide_clear_hob(bus);
1144 bus->ifs[0].hob_sector = bus->ifs[0].sector;
1145 bus->ifs[1].hob_sector = bus->ifs[1].sector;
1146 bus->ifs[0].sector = val;
1147 bus->ifs[1].sector = val;
5391d806
FB
1148 break;
1149 case 4:
bcbdc4d3
GH
1150 ide_clear_hob(bus);
1151 bus->ifs[0].hob_lcyl = bus->ifs[0].lcyl;
1152 bus->ifs[1].hob_lcyl = bus->ifs[1].lcyl;
1153 bus->ifs[0].lcyl = val;
1154 bus->ifs[1].lcyl = val;
5391d806
FB
1155 break;
1156 case 5:
bcbdc4d3
GH
1157 ide_clear_hob(bus);
1158 bus->ifs[0].hob_hcyl = bus->ifs[0].hcyl;
1159 bus->ifs[1].hob_hcyl = bus->ifs[1].hcyl;
1160 bus->ifs[0].hcyl = val;
1161 bus->ifs[1].hcyl = val;
5391d806
FB
1162 break;
1163 case 6:
c2ff060f 1164 /* FIXME: HOB readback uses bit 7 */
bcbdc4d3
GH
1165 bus->ifs[0].select = (val & ~0x10) | 0xa0;
1166 bus->ifs[1].select = (val | 0x10) | 0xa0;
5391d806 1167 /* select drive */
bcbdc4d3 1168 bus->unit = (val >> 4) & 1;
5391d806
FB
1169 break;
1170 default:
1171 case 7:
1172 /* command */
7cff87ff
AG
1173 ide_exec_cmd(bus, val);
1174 break;
1175 }
1176}
1177
4590355b
JS
1178static void ide_reset(IDEState *s)
1179{
1180#ifdef DEBUG_IDE
1181 printf("ide: reset\n");
1182#endif
1183
1184 if (s->pio_aiocb) {
1185 blk_aio_cancel(s->pio_aiocb);
1186 s->pio_aiocb = NULL;
1187 }
1188
1189 if (s->drive_kind == IDE_CFATA)
1190 s->mult_sectors = 0;
1191 else
1192 s->mult_sectors = MAX_MULT_SECTORS;
1193 /* ide regs */
1194 s->feature = 0;
1195 s->error = 0;
1196 s->nsector = 0;
1197 s->sector = 0;
1198 s->lcyl = 0;
1199 s->hcyl = 0;
1200
1201 /* lba48 */
1202 s->hob_feature = 0;
1203 s->hob_sector = 0;
1204 s->hob_nsector = 0;
1205 s->hob_lcyl = 0;
1206 s->hob_hcyl = 0;
1207
1208 s->select = 0xa0;
1209 s->status = READY_STAT | SEEK_STAT;
1210
1211 s->lba48 = 0;
1212
1213 /* ATAPI specific */
1214 s->sense_key = 0;
1215 s->asc = 0;
1216 s->cdrom_changed = 0;
1217 s->packet_transfer_size = 0;
1218 s->elementary_transfer_size = 0;
1219 s->io_buffer_index = 0;
1220 s->cd_sector_size = 0;
1221 s->atapi_dma = 0;
1222 s->tray_locked = 0;
1223 s->tray_open = 0;
1224 /* ATA DMA state */
1225 s->io_buffer_size = 0;
1226 s->req_nb_sectors = 0;
1227
1228 ide_set_signature(s);
1229 /* init the transfer handler so that 0xffff is returned on data
1230 accesses */
1231 s->end_transfer_func = ide_dummy_transfer_stop;
1232 ide_dummy_transfer_stop(s);
1233 s->media_changed = 0;
1234}
1235
b300337e
KW
1236static bool cmd_nop(IDEState *s, uint8_t cmd)
1237{
1238 return true;
1239}
1240
4286434c
KW
1241static bool cmd_data_set_management(IDEState *s, uint8_t cmd)
1242{
1243 switch (s->feature) {
1244 case DSM_TRIM:
4be74634 1245 if (s->blk) {
4286434c
KW
1246 ide_sector_start_dma(s, IDE_DMA_TRIM);
1247 return false;
1248 }
1249 break;
1250 }
1251
1252 ide_abort_command(s);
1253 return true;
1254}
1255
1c66869a
KW
1256static bool cmd_identify(IDEState *s, uint8_t cmd)
1257{
4be74634 1258 if (s->blk && s->drive_kind != IDE_CD) {
1c66869a
KW
1259 if (s->drive_kind != IDE_CFATA) {
1260 ide_identify(s);
1261 } else {
1262 ide_cfata_identify(s);
1263 }
1264 s->status = READY_STAT | SEEK_STAT;
1265 ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
1266 ide_set_irq(s->bus);
1267 return false;
1268 } else {
1269 if (s->drive_kind == IDE_CD) {
1270 ide_set_signature(s);
1271 }
1272 ide_abort_command(s);
1273 }
1274
1275 return true;
1276}
1277
413860cf
KW
1278static bool cmd_verify(IDEState *s, uint8_t cmd)
1279{
1280 bool lba48 = (cmd == WIN_VERIFY_EXT);
1281
1282 /* do sector number check ? */
1283 ide_cmd_lba48_transform(s, lba48);
1284
1285 return true;
1286}
1287
adf3a2c4
KW
1288static bool cmd_set_multiple_mode(IDEState *s, uint8_t cmd)
1289{
1290 if (s->drive_kind == IDE_CFATA && s->nsector == 0) {
1291 /* Disable Read and Write Multiple */
1292 s->mult_sectors = 0;
1293 } else if ((s->nsector & 0xff) != 0 &&
1294 ((s->nsector & 0xff) > MAX_MULT_SECTORS ||
1295 (s->nsector & (s->nsector - 1)) != 0)) {
1296 ide_abort_command(s);
1297 } else {
1298 s->mult_sectors = s->nsector & 0xff;
1299 }
1300
1301 return true;
1302}
1303
1304static bool cmd_read_multiple(IDEState *s, uint8_t cmd)
1305{
1306 bool lba48 = (cmd == WIN_MULTREAD_EXT);
1307
4be74634 1308 if (!s->blk || !s->mult_sectors) {
adf3a2c4
KW
1309 ide_abort_command(s);
1310 return true;
1311 }
1312
1313 ide_cmd_lba48_transform(s, lba48);
1314 s->req_nb_sectors = s->mult_sectors;
1315 ide_sector_read(s);
1316 return false;
1317}
1318
1319static bool cmd_write_multiple(IDEState *s, uint8_t cmd)
1320{
1321 bool lba48 = (cmd == WIN_MULTWRITE_EXT);
1322 int n;
1323
4be74634 1324 if (!s->blk || !s->mult_sectors) {
adf3a2c4
KW
1325 ide_abort_command(s);
1326 return true;
1327 }
1328
1329 ide_cmd_lba48_transform(s, lba48);
1330
1331 s->req_nb_sectors = s->mult_sectors;
1332 n = MIN(s->nsector, s->req_nb_sectors);
1333
1334 s->status = SEEK_STAT | READY_STAT;
1335 ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
1336
1337 s->media_changed = 1;
1338
1339 return false;
1340}
1341
0e6498ed
KW
1342static bool cmd_read_pio(IDEState *s, uint8_t cmd)
1343{
1344 bool lba48 = (cmd == WIN_READ_EXT);
1345
1346 if (s->drive_kind == IDE_CD) {
1347 ide_set_signature(s); /* odd, but ATA4 8.27.5.2 requires it */
1348 ide_abort_command(s);
1349 return true;
1350 }
1351
4be74634 1352 if (!s->blk) {
0e6498ed
KW
1353 ide_abort_command(s);
1354 return true;
1355 }
1356
1357 ide_cmd_lba48_transform(s, lba48);
1358 s->req_nb_sectors = 1;
1359 ide_sector_read(s);
1360
1361 return false;
1362}
1363
1364static bool cmd_write_pio(IDEState *s, uint8_t cmd)
1365{
1366 bool lba48 = (cmd == WIN_WRITE_EXT);
1367
4be74634 1368 if (!s->blk) {
0e6498ed
KW
1369 ide_abort_command(s);
1370 return true;
1371 }
1372
1373 ide_cmd_lba48_transform(s, lba48);
1374
1375 s->req_nb_sectors = 1;
1376 s->status = SEEK_STAT | READY_STAT;
1377 ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
1378
1379 s->media_changed = 1;
1380
1381 return false;
1382}
1383
92a6a6f6
KW
1384static bool cmd_read_dma(IDEState *s, uint8_t cmd)
1385{
1386 bool lba48 = (cmd == WIN_READDMA_EXT);
1387
4be74634 1388 if (!s->blk) {
92a6a6f6
KW
1389 ide_abort_command(s);
1390 return true;
1391 }
1392
1393 ide_cmd_lba48_transform(s, lba48);
1394 ide_sector_start_dma(s, IDE_DMA_READ);
1395
1396 return false;
1397}
1398
1399static bool cmd_write_dma(IDEState *s, uint8_t cmd)
1400{
1401 bool lba48 = (cmd == WIN_WRITEDMA_EXT);
1402
4be74634 1403 if (!s->blk) {
92a6a6f6
KW
1404 ide_abort_command(s);
1405 return true;
1406 }
1407
1408 ide_cmd_lba48_transform(s, lba48);
1409 ide_sector_start_dma(s, IDE_DMA_WRITE);
1410
1411 s->media_changed = 1;
1412
1413 return false;
1414}
1415
9afce429
KW
1416static bool cmd_flush_cache(IDEState *s, uint8_t cmd)
1417{
1418 ide_flush_cache(s);
1419 return false;
1420}
1421
61fdda37
KW
1422static bool cmd_seek(IDEState *s, uint8_t cmd)
1423{
1424 /* XXX: Check that seek is within bounds */
1425 return true;
1426}
1427
63a82e6a
KW
1428static bool cmd_read_native_max(IDEState *s, uint8_t cmd)
1429{
1430 bool lba48 = (cmd == WIN_READ_NATIVE_MAX_EXT);
1431
1432 /* Refuse if no sectors are addressable (e.g. medium not inserted) */
1433 if (s->nb_sectors == 0) {
1434 ide_abort_command(s);
1435 return true;
1436 }
1437
1438 ide_cmd_lba48_transform(s, lba48);
1439 ide_set_sector(s, s->nb_sectors - 1);
1440
1441 return true;
1442}
1443
785f6320
KW
1444static bool cmd_check_power_mode(IDEState *s, uint8_t cmd)
1445{
1446 s->nsector = 0xff; /* device active or idle */
1447 return true;
1448}
1449
ee03398c
KW
1450static bool cmd_set_features(IDEState *s, uint8_t cmd)
1451{
1452 uint16_t *identify_data;
1453
4be74634 1454 if (!s->blk) {
ee03398c
KW
1455 ide_abort_command(s);
1456 return true;
1457 }
1458
1459 /* XXX: valid for CDROM ? */
1460 switch (s->feature) {
1461 case 0x02: /* write cache enable */
4be74634 1462 blk_set_enable_write_cache(s->blk, true);
ee03398c
KW
1463 identify_data = (uint16_t *)s->identify_data;
1464 put_le16(identify_data + 85, (1 << 14) | (1 << 5) | 1);
1465 return true;
1466 case 0x82: /* write cache disable */
4be74634 1467 blk_set_enable_write_cache(s->blk, false);
ee03398c
KW
1468 identify_data = (uint16_t *)s->identify_data;
1469 put_le16(identify_data + 85, (1 << 14) | 1);
1470 ide_flush_cache(s);
1471 return false;
1472 case 0xcc: /* reverting to power-on defaults enable */
1473 case 0x66: /* reverting to power-on defaults disable */
1474 case 0xaa: /* read look-ahead enable */
1475 case 0x55: /* read look-ahead disable */
1476 case 0x05: /* set advanced power management mode */
1477 case 0x85: /* disable advanced power management mode */
1478 case 0x69: /* NOP */
1479 case 0x67: /* NOP */
1480 case 0x96: /* NOP */
1481 case 0x9a: /* NOP */
1482 case 0x42: /* enable Automatic Acoustic Mode */
1483 case 0xc2: /* disable Automatic Acoustic Mode */
1484 return true;
1485 case 0x03: /* set transfer mode */
1486 {
1487 uint8_t val = s->nsector & 0x07;
1488 identify_data = (uint16_t *)s->identify_data;
1489
1490 switch (s->nsector >> 3) {
1491 case 0x00: /* pio default */
1492 case 0x01: /* pio mode */
1493 put_le16(identify_data + 62, 0x07);
1494 put_le16(identify_data + 63, 0x07);
1495 put_le16(identify_data + 88, 0x3f);
1496 break;
1497 case 0x02: /* sigle word dma mode*/
1498 put_le16(identify_data + 62, 0x07 | (1 << (val + 8)));
1499 put_le16(identify_data + 63, 0x07);
1500 put_le16(identify_data + 88, 0x3f);
1501 break;
1502 case 0x04: /* mdma mode */
1503 put_le16(identify_data + 62, 0x07);
1504 put_le16(identify_data + 63, 0x07 | (1 << (val + 8)));
1505 put_le16(identify_data + 88, 0x3f);
1506 break;
1507 case 0x08: /* udma mode */
1508 put_le16(identify_data + 62, 0x07);
1509 put_le16(identify_data + 63, 0x07);
1510 put_le16(identify_data + 88, 0x3f | (1 << (val + 8)));
1511 break;
1512 default:
1513 goto abort_cmd;
1514 }
1515 return true;
1516 }
1517 }
1518
1519abort_cmd:
1520 ide_abort_command(s);
1521 return true;
1522}
1523
ee425c78
KW
1524
1525/*** ATAPI commands ***/
1526
1527static bool cmd_identify_packet(IDEState *s, uint8_t cmd)
1528{
1529 ide_atapi_identify(s);
1530 s->status = READY_STAT | SEEK_STAT;
1531 ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
1532 ide_set_irq(s->bus);
1533 return false;
1534}
1535
1536static bool cmd_exec_dev_diagnostic(IDEState *s, uint8_t cmd)
1537{
1538 ide_set_signature(s);
1539
1540 if (s->drive_kind == IDE_CD) {
1541 s->status = 0; /* ATAPI spec (v6) section 9.10 defines packet
1542 * devices to return a clear status register
1543 * with READY_STAT *not* set. */
850484a2 1544 s->error = 0x01;
ee425c78
KW
1545 } else {
1546 s->status = READY_STAT | SEEK_STAT;
1547 /* The bits of the error register are not as usual for this command!
1548 * They are part of the regular output (this is why ERR_STAT isn't set)
1549 * Device 0 passed, Device 1 passed or not present. */
1550 s->error = 0x01;
1551 ide_set_irq(s->bus);
1552 }
1553
1554 return false;
1555}
1556
1557static bool cmd_device_reset(IDEState *s, uint8_t cmd)
1558{
1559 ide_set_signature(s);
1560 s->status = 0x00; /* NOTE: READY is _not_ set */
1561 s->error = 0x01;
1562
1563 return false;
1564}
1565
1566static bool cmd_packet(IDEState *s, uint8_t cmd)
1567{
1568 /* overlapping commands not supported */
1569 if (s->feature & 0x02) {
1570 ide_abort_command(s);
1571 return true;
1572 }
1573
1574 s->status = READY_STAT | SEEK_STAT;
1575 s->atapi_dma = s->feature & 1;
1576 s->nsector = 1;
1577 ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,
1578 ide_atapi_cmd);
1579 return false;
1580}
1581
6b1dd744
KW
1582
1583/*** CF-ATA commands ***/
1584
1585static bool cmd_cfa_req_ext_error_code(IDEState *s, uint8_t cmd)
1586{
1587 s->error = 0x09; /* miscellaneous error */
1588 s->status = READY_STAT | SEEK_STAT;
1589 ide_set_irq(s->bus);
1590
1591 return false;
1592}
1593
1594static bool cmd_cfa_erase_sectors(IDEState *s, uint8_t cmd)
1595{
1596 /* WIN_SECURITY_FREEZE_LOCK has the same ID as CFA_WEAR_LEVEL and is
1597 * required for Windows 8 to work with AHCI */
1598
1599 if (cmd == CFA_WEAR_LEVEL) {
1600 s->nsector = 0;
1601 }
1602
1603 if (cmd == CFA_ERASE_SECTORS) {
1604 s->media_changed = 1;
1605 }
1606
1607 return true;
1608}
1609
1610static bool cmd_cfa_translate_sector(IDEState *s, uint8_t cmd)
1611{
1612 s->status = READY_STAT | SEEK_STAT;
1613
1614 memset(s->io_buffer, 0, 0x200);
1615 s->io_buffer[0x00] = s->hcyl; /* Cyl MSB */
1616 s->io_buffer[0x01] = s->lcyl; /* Cyl LSB */
1617 s->io_buffer[0x02] = s->select; /* Head */
1618 s->io_buffer[0x03] = s->sector; /* Sector */
1619 s->io_buffer[0x04] = ide_get_sector(s) >> 16; /* LBA MSB */
1620 s->io_buffer[0x05] = ide_get_sector(s) >> 8; /* LBA */
1621 s->io_buffer[0x06] = ide_get_sector(s) >> 0; /* LBA LSB */
1622 s->io_buffer[0x13] = 0x00; /* Erase flag */
1623 s->io_buffer[0x18] = 0x00; /* Hot count */
1624 s->io_buffer[0x19] = 0x00; /* Hot count */
1625 s->io_buffer[0x1a] = 0x01; /* Hot count */
1626
1627 ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1628 ide_set_irq(s->bus);
1629
1630 return false;
1631}
1632
1633static bool cmd_cfa_access_metadata_storage(IDEState *s, uint8_t cmd)
1634{
1635 switch (s->feature) {
1636 case 0x02: /* Inquiry Metadata Storage */
1637 ide_cfata_metadata_inquiry(s);
1638 break;
1639 case 0x03: /* Read Metadata Storage */
1640 ide_cfata_metadata_read(s);
1641 break;
1642 case 0x04: /* Write Metadata Storage */
1643 ide_cfata_metadata_write(s);
1644 break;
1645 default:
1646 ide_abort_command(s);
1647 return true;
1648 }
1649
1650 ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1651 s->status = 0x00; /* NOTE: READY is _not_ set */
1652 ide_set_irq(s->bus);
1653
1654 return false;
1655}
1656
1657static bool cmd_ibm_sense_condition(IDEState *s, uint8_t cmd)
1658{
1659 switch (s->feature) {
1660 case 0x01: /* sense temperature in device */
1661 s->nsector = 0x50; /* +20 C */
1662 break;
1663 default:
1664 ide_abort_command(s);
1665 return true;
1666 }
1667
1668 return true;
1669}
1670
ff352677
KW
1671
1672/*** SMART commands ***/
1673
1674static bool cmd_smart(IDEState *s, uint8_t cmd)
1675{
1676 int n;
1677
1678 if (s->hcyl != 0xc2 || s->lcyl != 0x4f) {
1679 goto abort_cmd;
1680 }
1681
1682 if (!s->smart_enabled && s->feature != SMART_ENABLE) {
1683 goto abort_cmd;
1684 }
1685
1686 switch (s->feature) {
1687 case SMART_DISABLE:
1688 s->smart_enabled = 0;
1689 return true;
1690
1691 case SMART_ENABLE:
1692 s->smart_enabled = 1;
1693 return true;
1694
1695 case SMART_ATTR_AUTOSAVE:
1696 switch (s->sector) {
1697 case 0x00:
1698 s->smart_autosave = 0;
1699 break;
1700 case 0xf1:
1701 s->smart_autosave = 1;
1702 break;
1703 default:
1704 goto abort_cmd;
1705 }
1706 return true;
1707
1708 case SMART_STATUS:
1709 if (!s->smart_errors) {
1710 s->hcyl = 0xc2;
1711 s->lcyl = 0x4f;
1712 } else {
1713 s->hcyl = 0x2c;
1714 s->lcyl = 0xf4;
1715 }
1716 return true;
1717
1718 case SMART_READ_THRESH:
1719 memset(s->io_buffer, 0, 0x200);
1720 s->io_buffer[0] = 0x01; /* smart struct version */
1721
1722 for (n = 0; n < ARRAY_SIZE(smart_attributes); n++) {
1723 s->io_buffer[2 + 0 + (n * 12)] = smart_attributes[n][0];
1724 s->io_buffer[2 + 1 + (n * 12)] = smart_attributes[n][11];
1725 }
1726
1727 /* checksum */
1728 for (n = 0; n < 511; n++) {
1729 s->io_buffer[511] += s->io_buffer[n];
1730 }
1731 s->io_buffer[511] = 0x100 - s->io_buffer[511];
1732
1733 s->status = READY_STAT | SEEK_STAT;
1734 ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1735 ide_set_irq(s->bus);
1736 return false;
1737
1738 case SMART_READ_DATA:
1739 memset(s->io_buffer, 0, 0x200);
1740 s->io_buffer[0] = 0x01; /* smart struct version */
1741
1742 for (n = 0; n < ARRAY_SIZE(smart_attributes); n++) {
1743 int i;
1744 for (i = 0; i < 11; i++) {
1745 s->io_buffer[2 + i + (n * 12)] = smart_attributes[n][i];
1746 }
1747 }
1748
1749 s->io_buffer[362] = 0x02 | (s->smart_autosave ? 0x80 : 0x00);
1750 if (s->smart_selftest_count == 0) {
1751 s->io_buffer[363] = 0;
1752 } else {
1753 s->io_buffer[363] =
1754 s->smart_selftest_data[3 +
1755 (s->smart_selftest_count - 1) *
1756 24];
1757 }
1758 s->io_buffer[364] = 0x20;
1759 s->io_buffer[365] = 0x01;
1760 /* offline data collection capacity: execute + self-test*/
1761 s->io_buffer[367] = (1 << 4 | 1 << 3 | 1);
1762 s->io_buffer[368] = 0x03; /* smart capability (1) */
1763 s->io_buffer[369] = 0x00; /* smart capability (2) */
1764 s->io_buffer[370] = 0x01; /* error logging supported */
1765 s->io_buffer[372] = 0x02; /* minutes for poll short test */
1766 s->io_buffer[373] = 0x36; /* minutes for poll ext test */
1767 s->io_buffer[374] = 0x01; /* minutes for poll conveyance */
1768
1769 for (n = 0; n < 511; n++) {
1770 s->io_buffer[511] += s->io_buffer[n];
1771 }
1772 s->io_buffer[511] = 0x100 - s->io_buffer[511];
1773
1774 s->status = READY_STAT | SEEK_STAT;
1775 ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1776 ide_set_irq(s->bus);
1777 return false;
1778
1779 case SMART_READ_LOG:
1780 switch (s->sector) {
1781 case 0x01: /* summary smart error log */
1782 memset(s->io_buffer, 0, 0x200);
1783 s->io_buffer[0] = 0x01;
1784 s->io_buffer[1] = 0x00; /* no error entries */
1785 s->io_buffer[452] = s->smart_errors & 0xff;
1786 s->io_buffer[453] = (s->smart_errors & 0xff00) >> 8;
1787
1788 for (n = 0; n < 511; n++) {
1789 s->io_buffer[511] += s->io_buffer[n];
1790 }
1791 s->io_buffer[511] = 0x100 - s->io_buffer[511];
1792 break;
1793 case 0x06: /* smart self test log */
1794 memset(s->io_buffer, 0, 0x200);
1795 s->io_buffer[0] = 0x01;
1796 if (s->smart_selftest_count == 0) {
1797 s->io_buffer[508] = 0;
1798 } else {
1799 s->io_buffer[508] = s->smart_selftest_count;
1800 for (n = 2; n < 506; n++) {
1801 s->io_buffer[n] = s->smart_selftest_data[n];
1802 }
1803 }
1804
1805 for (n = 0; n < 511; n++) {
1806 s->io_buffer[511] += s->io_buffer[n];
1807 }
1808 s->io_buffer[511] = 0x100 - s->io_buffer[511];
1809 break;
1810 default:
1811 goto abort_cmd;
1812 }
1813 s->status = READY_STAT | SEEK_STAT;
1814 ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1815 ide_set_irq(s->bus);
1816 return false;
1817
1818 case SMART_EXECUTE_OFFLINE:
1819 switch (s->sector) {
1820 case 0: /* off-line routine */
1821 case 1: /* short self test */
1822 case 2: /* extended self test */
1823 s->smart_selftest_count++;
1824 if (s->smart_selftest_count > 21) {
940973ae 1825 s->smart_selftest_count = 1;
ff352677
KW
1826 }
1827 n = 2 + (s->smart_selftest_count - 1) * 24;
1828 s->smart_selftest_data[n] = s->sector;
1829 s->smart_selftest_data[n + 1] = 0x00; /* OK and finished */
1830 s->smart_selftest_data[n + 2] = 0x34; /* hour count lsb */
1831 s->smart_selftest_data[n + 3] = 0x12; /* hour count msb */
1832 break;
1833 default:
1834 goto abort_cmd;
1835 }
1836 return true;
1837 }
1838
1839abort_cmd:
1840 ide_abort_command(s);
1841 return true;
1842}
1843
844505b1
MA
1844#define HD_OK (1u << IDE_HD)
1845#define CD_OK (1u << IDE_CD)
1846#define CFA_OK (1u << IDE_CFATA)
1847#define HD_CFA_OK (HD_OK | CFA_OK)
1848#define ALL_OK (HD_OK | CD_OK | CFA_OK)
1849
a0436e92
KW
1850/* Set the Disk Seek Completed status bit during completion */
1851#define SET_DSC (1u << 8)
1852
844505b1 1853/* See ACS-2 T13/2015-D Table B.2 Command codes */
a0436e92
KW
1854static const struct {
1855 /* Returns true if the completion code should be run */
1856 bool (*handler)(IDEState *s, uint8_t cmd);
1857 int flags;
1858} ide_cmd_table[0x100] = {
844505b1 1859 /* NOP not implemented, mandatory for CD */
6b1dd744 1860 [CFA_REQ_EXT_ERROR_CODE] = { cmd_cfa_req_ext_error_code, CFA_OK },
d9033e1d 1861 [WIN_DSM] = { cmd_data_set_management, HD_CFA_OK },
ee425c78 1862 [WIN_DEVICE_RESET] = { cmd_device_reset, CD_OK },
b300337e 1863 [WIN_RECAL] = { cmd_nop, HD_CFA_OK | SET_DSC},
0e6498ed 1864 [WIN_READ] = { cmd_read_pio, ALL_OK },
d9033e1d 1865 [WIN_READ_ONCE] = { cmd_read_pio, HD_CFA_OK },
0e6498ed 1866 [WIN_READ_EXT] = { cmd_read_pio, HD_CFA_OK },
92a6a6f6 1867 [WIN_READDMA_EXT] = { cmd_read_dma, HD_CFA_OK },
63a82e6a 1868 [WIN_READ_NATIVE_MAX_EXT] = { cmd_read_native_max, HD_CFA_OK | SET_DSC },
adf3a2c4 1869 [WIN_MULTREAD_EXT] = { cmd_read_multiple, HD_CFA_OK },
0e6498ed
KW
1870 [WIN_WRITE] = { cmd_write_pio, HD_CFA_OK },
1871 [WIN_WRITE_ONCE] = { cmd_write_pio, HD_CFA_OK },
1872 [WIN_WRITE_EXT] = { cmd_write_pio, HD_CFA_OK },
92a6a6f6 1873 [WIN_WRITEDMA_EXT] = { cmd_write_dma, HD_CFA_OK },
0e6498ed 1874 [CFA_WRITE_SECT_WO_ERASE] = { cmd_write_pio, CFA_OK },
adf3a2c4 1875 [WIN_MULTWRITE_EXT] = { cmd_write_multiple, HD_CFA_OK },
0e6498ed 1876 [WIN_WRITE_VERIFY] = { cmd_write_pio, HD_CFA_OK },
413860cf
KW
1877 [WIN_VERIFY] = { cmd_verify, HD_CFA_OK | SET_DSC },
1878 [WIN_VERIFY_ONCE] = { cmd_verify, HD_CFA_OK | SET_DSC },
1879 [WIN_VERIFY_EXT] = { cmd_verify, HD_CFA_OK | SET_DSC },
61fdda37 1880 [WIN_SEEK] = { cmd_seek, HD_CFA_OK | SET_DSC },
6b1dd744 1881 [CFA_TRANSLATE_SECTOR] = { cmd_cfa_translate_sector, CFA_OK },
ee425c78 1882 [WIN_DIAGNOSE] = { cmd_exec_dev_diagnostic, ALL_OK },
b300337e 1883 [WIN_SPECIFY] = { cmd_nop, HD_CFA_OK | SET_DSC },
d9033e1d
JS
1884 [WIN_STANDBYNOW2] = { cmd_nop, HD_CFA_OK },
1885 [WIN_IDLEIMMEDIATE2] = { cmd_nop, HD_CFA_OK },
1886 [WIN_STANDBY2] = { cmd_nop, HD_CFA_OK },
1887 [WIN_SETIDLE2] = { cmd_nop, HD_CFA_OK },
1888 [WIN_CHECKPOWERMODE2] = { cmd_check_power_mode, HD_CFA_OK | SET_DSC },
1889 [WIN_SLEEPNOW2] = { cmd_nop, HD_CFA_OK },
ee425c78
KW
1890 [WIN_PACKETCMD] = { cmd_packet, CD_OK },
1891 [WIN_PIDENTIFY] = { cmd_identify_packet, CD_OK },
ff352677 1892 [WIN_SMART] = { cmd_smart, HD_CFA_OK | SET_DSC },
6b1dd744
KW
1893 [CFA_ACCESS_METADATA_STORAGE] = { cmd_cfa_access_metadata_storage, CFA_OK },
1894 [CFA_ERASE_SECTORS] = { cmd_cfa_erase_sectors, CFA_OK | SET_DSC },
adf3a2c4
KW
1895 [WIN_MULTREAD] = { cmd_read_multiple, HD_CFA_OK },
1896 [WIN_MULTWRITE] = { cmd_write_multiple, HD_CFA_OK },
1897 [WIN_SETMULT] = { cmd_set_multiple_mode, HD_CFA_OK | SET_DSC },
92a6a6f6
KW
1898 [WIN_READDMA] = { cmd_read_dma, HD_CFA_OK },
1899 [WIN_READDMA_ONCE] = { cmd_read_dma, HD_CFA_OK },
1900 [WIN_WRITEDMA] = { cmd_write_dma, HD_CFA_OK },
1901 [WIN_WRITEDMA_ONCE] = { cmd_write_dma, HD_CFA_OK },
adf3a2c4 1902 [CFA_WRITE_MULTI_WO_ERASE] = { cmd_write_multiple, CFA_OK },
d9033e1d
JS
1903 [WIN_STANDBYNOW1] = { cmd_nop, HD_CFA_OK },
1904 [WIN_IDLEIMMEDIATE] = { cmd_nop, HD_CFA_OK },
1905 [WIN_STANDBY] = { cmd_nop, HD_CFA_OK },
1906 [WIN_SETIDLE1] = { cmd_nop, HD_CFA_OK },
1907 [WIN_CHECKPOWERMODE1] = { cmd_check_power_mode, HD_CFA_OK | SET_DSC },
1908 [WIN_SLEEPNOW1] = { cmd_nop, HD_CFA_OK },
9afce429
KW
1909 [WIN_FLUSH_CACHE] = { cmd_flush_cache, ALL_OK },
1910 [WIN_FLUSH_CACHE_EXT] = { cmd_flush_cache, HD_CFA_OK },
1c66869a 1911 [WIN_IDENTIFY] = { cmd_identify, ALL_OK },
ee03398c 1912 [WIN_SETFEATURES] = { cmd_set_features, ALL_OK | SET_DSC },
6b1dd744
KW
1913 [IBM_SENSE_CONDITION] = { cmd_ibm_sense_condition, CFA_OK | SET_DSC },
1914 [CFA_WEAR_LEVEL] = { cmd_cfa_erase_sectors, HD_CFA_OK | SET_DSC },
d9033e1d 1915 [WIN_READ_NATIVE_MAX] = { cmd_read_native_max, HD_CFA_OK | SET_DSC },
844505b1
MA
1916};
1917
1918static bool ide_cmd_permitted(IDEState *s, uint32_t cmd)
1919{
1920 return cmd < ARRAY_SIZE(ide_cmd_table)
a0436e92 1921 && (ide_cmd_table[cmd].flags & (1u << s->drive_kind));
844505b1 1922}
7cff87ff
AG
1923
1924void ide_exec_cmd(IDEBus *bus, uint32_t val)
1925{
1926 IDEState *s;
dfe1ea8f 1927 bool complete;
7cff87ff 1928
5391d806 1929#if defined(DEBUG_IDE)
6ef2ba5e 1930 printf("ide: CMD=%02x\n", val);
5391d806 1931#endif
6ef2ba5e 1932 s = idebus_active_if(bus);
66a0a2cb 1933 /* ignore commands to non existent slave */
4be74634 1934 if (s != bus->ifs && !s->blk) {
6ef2ba5e 1935 return;
4be74634 1936 }
c2ff060f 1937
266e7781
JS
1938 /* Only RESET is allowed while BSY and/or DRQ are set,
1939 * and only to ATAPI devices. */
1940 if (s->status & (BUSY_STAT|DRQ_STAT)) {
1941 if (val != WIN_DEVICE_RESET || s->drive_kind != IDE_CD) {
1942 return;
1943 }
1944 }
fcdd25ab 1945
844505b1 1946 if (!ide_cmd_permitted(s, val)) {
dfe1ea8f
KW
1947 ide_abort_command(s);
1948 ide_set_irq(s->bus);
1949 return;
844505b1
MA
1950 }
1951
dfe1ea8f
KW
1952 s->status = READY_STAT | BUSY_STAT;
1953 s->error = 0;
36334faf 1954 s->io_buffer_offset = 0;
a0436e92 1955
dfe1ea8f
KW
1956 complete = ide_cmd_table[val].handler(s, val);
1957 if (complete) {
1958 s->status &= ~BUSY_STAT;
1959 assert(!!s->error == !!(s->status & ERR_STAT));
a0436e92 1960
dfe1ea8f
KW
1961 if ((ide_cmd_table[val].flags & SET_DSC) && !s->error) {
1962 s->status |= SEEK_STAT;
a0436e92
KW
1963 }
1964
c7e73adb 1965 ide_cmd_done(s);
6ef2ba5e 1966 ide_set_irq(s->bus);
6ef2ba5e 1967 }
5391d806
FB
1968}
1969
356721ae 1970uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
5391d806 1971{
bcbdc4d3
GH
1972 IDEBus *bus = opaque;
1973 IDEState *s = idebus_active_if(bus);
5391d806 1974 uint32_t addr;
c2ff060f 1975 int ret, hob;
5391d806
FB
1976
1977 addr = addr1 & 7;
c2ff060f
FB
1978 /* FIXME: HOB readback uses bit 7, but it's always set right now */
1979 //hob = s->select & (1 << 7);
1980 hob = 0;
5391d806
FB
1981 switch(addr) {
1982 case 0:
1983 ret = 0xff;
1984 break;
1985 case 1:
4be74634
MA
1986 if ((!bus->ifs[0].blk && !bus->ifs[1].blk) ||
1987 (s != bus->ifs && !s->blk)) {
c45c3d00 1988 ret = 0;
4be74634 1989 } else if (!hob) {
c45c3d00 1990 ret = s->error;
4be74634 1991 } else {
c2ff060f 1992 ret = s->hob_feature;
4be74634 1993 }
5391d806
FB
1994 break;
1995 case 2:
4be74634 1996 if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
c45c3d00 1997 ret = 0;
4be74634 1998 } else if (!hob) {
c45c3d00 1999 ret = s->nsector & 0xff;
4be74634 2000 } else {
c2ff060f 2001 ret = s->hob_nsector;
4be74634 2002 }
5391d806
FB
2003 break;
2004 case 3:
4be74634 2005 if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
c45c3d00 2006 ret = 0;
4be74634 2007 } else if (!hob) {
c45c3d00 2008 ret = s->sector;
4be74634 2009 } else {
c2ff060f 2010 ret = s->hob_sector;
4be74634 2011 }
5391d806
FB
2012 break;
2013 case 4:
4be74634 2014 if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
c45c3d00 2015 ret = 0;
4be74634 2016 } else if (!hob) {
c45c3d00 2017 ret = s->lcyl;
4be74634 2018 } else {
c2ff060f 2019 ret = s->hob_lcyl;
4be74634 2020 }
5391d806
FB
2021 break;
2022 case 5:
4be74634 2023 if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
c45c3d00 2024 ret = 0;
4be74634 2025 } else if (!hob) {
c45c3d00 2026 ret = s->hcyl;
4be74634 2027 } else {
c2ff060f 2028 ret = s->hob_hcyl;
4be74634 2029 }
5391d806
FB
2030 break;
2031 case 6:
4be74634 2032 if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
c45c3d00 2033 ret = 0;
4be74634 2034 } else {
7ae98627 2035 ret = s->select;
4be74634 2036 }
5391d806
FB
2037 break;
2038 default:
2039 case 7:
4be74634
MA
2040 if ((!bus->ifs[0].blk && !bus->ifs[1].blk) ||
2041 (s != bus->ifs && !s->blk)) {
c45c3d00 2042 ret = 0;
4be74634 2043 } else {
c45c3d00 2044 ret = s->status;
4be74634 2045 }
9cdd03a7 2046 qemu_irq_lower(bus->irq);
5391d806
FB
2047 break;
2048 }
2049#ifdef DEBUG_IDE
2050 printf("ide: read addr=0x%x val=%02x\n", addr1, ret);
2051#endif
2052 return ret;
2053}
2054
356721ae 2055uint32_t ide_status_read(void *opaque, uint32_t addr)
5391d806 2056{
bcbdc4d3
GH
2057 IDEBus *bus = opaque;
2058 IDEState *s = idebus_active_if(bus);
5391d806 2059 int ret;
7ae98627 2060
4be74634
MA
2061 if ((!bus->ifs[0].blk && !bus->ifs[1].blk) ||
2062 (s != bus->ifs && !s->blk)) {
7ae98627 2063 ret = 0;
4be74634 2064 } else {
7ae98627 2065 ret = s->status;
4be74634 2066 }
5391d806
FB
2067#ifdef DEBUG_IDE
2068 printf("ide: read status addr=0x%x val=%02x\n", addr, ret);
2069#endif
2070 return ret;
2071}
2072
356721ae 2073void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
5391d806 2074{
bcbdc4d3 2075 IDEBus *bus = opaque;
5391d806
FB
2076 IDEState *s;
2077 int i;
2078
2079#ifdef DEBUG_IDE
2080 printf("ide: write control addr=0x%x val=%02x\n", addr, val);
2081#endif
2082 /* common for both drives */
9cdd03a7 2083 if (!(bus->cmd & IDE_CMD_RESET) &&
5391d806
FB
2084 (val & IDE_CMD_RESET)) {
2085 /* reset low to high */
2086 for(i = 0;i < 2; i++) {
bcbdc4d3 2087 s = &bus->ifs[i];
5391d806
FB
2088 s->status = BUSY_STAT | SEEK_STAT;
2089 s->error = 0x01;
2090 }
9cdd03a7 2091 } else if ((bus->cmd & IDE_CMD_RESET) &&
5391d806
FB
2092 !(val & IDE_CMD_RESET)) {
2093 /* high to low */
2094 for(i = 0;i < 2; i++) {
bcbdc4d3 2095 s = &bus->ifs[i];
cd8722bb 2096 if (s->drive_kind == IDE_CD)
6b136f9e
FB
2097 s->status = 0x00; /* NOTE: READY is _not_ set */
2098 else
56bf1d37 2099 s->status = READY_STAT | SEEK_STAT;
5391d806
FB
2100 ide_set_signature(s);
2101 }
2102 }
2103
9cdd03a7 2104 bus->cmd = val;
5391d806
FB
2105}
2106
40c4ed3f
KW
2107/*
2108 * Returns true if the running PIO transfer is a PIO out (i.e. data is
2109 * transferred from the device to the guest), false if it's a PIO in
2110 */
2111static bool ide_is_pio_out(IDEState *s)
2112{
2113 if (s->end_transfer_func == ide_sector_write ||
2114 s->end_transfer_func == ide_atapi_cmd) {
2115 return false;
2116 } else if (s->end_transfer_func == ide_sector_read ||
2117 s->end_transfer_func == ide_transfer_stop ||
2118 s->end_transfer_func == ide_atapi_cmd_reply_end ||
2119 s->end_transfer_func == ide_dummy_transfer_stop) {
2120 return true;
2121 }
2122
2123 abort();
2124}
2125
356721ae 2126void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
5391d806 2127{
bcbdc4d3
GH
2128 IDEBus *bus = opaque;
2129 IDEState *s = idebus_active_if(bus);
5391d806
FB
2130 uint8_t *p;
2131
40c4ed3f
KW
2132 /* PIO data access allowed only when DRQ bit is set. The result of a write
2133 * during PIO out is indeterminate, just ignore it. */
2134 if (!(s->status & DRQ_STAT) || ide_is_pio_out(s)) {
fcdd25ab 2135 return;
40c4ed3f 2136 }
fcdd25ab 2137
5391d806 2138 p = s->data_ptr;
d2ff8585
KW
2139 if (p + 2 > s->data_end) {
2140 return;
2141 }
2142
0c4ad8dc 2143 *(uint16_t *)p = le16_to_cpu(val);
5391d806
FB
2144 p += 2;
2145 s->data_ptr = p;
cb72cba8
KW
2146 if (p >= s->data_end) {
2147 s->status &= ~DRQ_STAT;
5391d806 2148 s->end_transfer_func(s);
cb72cba8 2149 }
5391d806
FB
2150}
2151
356721ae 2152uint32_t ide_data_readw(void *opaque, uint32_t addr)
5391d806 2153{
bcbdc4d3
GH
2154 IDEBus *bus = opaque;
2155 IDEState *s = idebus_active_if(bus);
5391d806
FB
2156 uint8_t *p;
2157 int ret;
fcdd25ab 2158
40c4ed3f
KW
2159 /* PIO data access allowed only when DRQ bit is set. The result of a read
2160 * during PIO in is indeterminate, return 0 and don't move forward. */
2161 if (!(s->status & DRQ_STAT) || !ide_is_pio_out(s)) {
fcdd25ab 2162 return 0;
40c4ed3f 2163 }
fcdd25ab 2164
5391d806 2165 p = s->data_ptr;
d2ff8585
KW
2166 if (p + 2 > s->data_end) {
2167 return 0;
2168 }
2169
0c4ad8dc 2170 ret = cpu_to_le16(*(uint16_t *)p);
5391d806
FB
2171 p += 2;
2172 s->data_ptr = p;
cb72cba8
KW
2173 if (p >= s->data_end) {
2174 s->status &= ~DRQ_STAT;
5391d806 2175 s->end_transfer_func(s);
cb72cba8 2176 }
5391d806
FB
2177 return ret;
2178}
2179
356721ae 2180void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
5391d806 2181{
bcbdc4d3
GH
2182 IDEBus *bus = opaque;
2183 IDEState *s = idebus_active_if(bus);
5391d806
FB
2184 uint8_t *p;
2185
40c4ed3f
KW
2186 /* PIO data access allowed only when DRQ bit is set. The result of a write
2187 * during PIO out is indeterminate, just ignore it. */
2188 if (!(s->status & DRQ_STAT) || ide_is_pio_out(s)) {
fcdd25ab 2189 return;
40c4ed3f 2190 }
fcdd25ab 2191
5391d806 2192 p = s->data_ptr;
d2ff8585
KW
2193 if (p + 4 > s->data_end) {
2194 return;
2195 }
2196
0c4ad8dc 2197 *(uint32_t *)p = le32_to_cpu(val);
5391d806
FB
2198 p += 4;
2199 s->data_ptr = p;
cb72cba8
KW
2200 if (p >= s->data_end) {
2201 s->status &= ~DRQ_STAT;
5391d806 2202 s->end_transfer_func(s);
cb72cba8 2203 }
5391d806
FB
2204}
2205
356721ae 2206uint32_t ide_data_readl(void *opaque, uint32_t addr)
5391d806 2207{
bcbdc4d3
GH
2208 IDEBus *bus = opaque;
2209 IDEState *s = idebus_active_if(bus);
5391d806
FB
2210 uint8_t *p;
2211 int ret;
3b46e624 2212
40c4ed3f
KW
2213 /* PIO data access allowed only when DRQ bit is set. The result of a read
2214 * during PIO in is indeterminate, return 0 and don't move forward. */
2215 if (!(s->status & DRQ_STAT) || !ide_is_pio_out(s)) {
fcdd25ab 2216 return 0;
40c4ed3f 2217 }
fcdd25ab 2218
5391d806 2219 p = s->data_ptr;
d2ff8585
KW
2220 if (p + 4 > s->data_end) {
2221 return 0;
2222 }
2223
0c4ad8dc 2224 ret = cpu_to_le32(*(uint32_t *)p);
5391d806
FB
2225 p += 4;
2226 s->data_ptr = p;
cb72cba8
KW
2227 if (p >= s->data_end) {
2228 s->status &= ~DRQ_STAT;
5391d806 2229 s->end_transfer_func(s);
cb72cba8 2230 }
5391d806
FB
2231 return ret;
2232}
2233
a7dfe172
FB
2234static void ide_dummy_transfer_stop(IDEState *s)
2235{
2236 s->data_ptr = s->io_buffer;
2237 s->data_end = s->io_buffer;
2238 s->io_buffer[0] = 0xff;
2239 s->io_buffer[1] = 0xff;
2240 s->io_buffer[2] = 0xff;
2241 s->io_buffer[3] = 0xff;
2242}
2243
4a643563
BS
2244void ide_bus_reset(IDEBus *bus)
2245{
2246 bus->unit = 0;
2247 bus->cmd = 0;
2248 ide_reset(&bus->ifs[0]);
2249 ide_reset(&bus->ifs[1]);
2250 ide_clear_hob(bus);
40a6238a
AG
2251
2252 /* pending async DMA */
2253 if (bus->dma->aiocb) {
2254#ifdef DEBUG_AIO
2255 printf("aio_cancel\n");
2256#endif
4be74634 2257 blk_aio_cancel(bus->dma->aiocb);
40a6238a
AG
2258 bus->dma->aiocb = NULL;
2259 }
2260
2261 /* reset dma provider too */
1374bec0
PB
2262 if (bus->dma->ops->reset) {
2263 bus->dma->ops->reset(bus->dma);
2264 }
4a643563
BS
2265}
2266
e4def80b
MA
2267static bool ide_cd_is_tray_open(void *opaque)
2268{
2269 return ((IDEState *)opaque)->tray_open;
2270}
2271
f107639a
MA
2272static bool ide_cd_is_medium_locked(void *opaque)
2273{
2274 return ((IDEState *)opaque)->tray_locked;
2275}
2276
01ce352e
JS
2277static void ide_resize_cb(void *opaque)
2278{
2279 IDEState *s = opaque;
2280 uint64_t nb_sectors;
2281
2282 if (!s->identify_set) {
2283 return;
2284 }
2285
4be74634 2286 blk_get_geometry(s->blk, &nb_sectors);
01ce352e
JS
2287 s->nb_sectors = nb_sectors;
2288
2289 /* Update the identify data buffer. */
2290 if (s->drive_kind == IDE_CFATA) {
2291 ide_cfata_identify_size(s);
2292 } else {
2293 /* IDE_CD uses a different set of callbacks entirely. */
2294 assert(s->drive_kind != IDE_CD);
2295 ide_identify_size(s);
2296 }
2297}
2298
0e49de52 2299static const BlockDevOps ide_cd_block_ops = {
145feb17 2300 .change_media_cb = ide_cd_change_cb,
2df0a3a3 2301 .eject_request_cb = ide_cd_eject_request_cb,
e4def80b 2302 .is_tray_open = ide_cd_is_tray_open,
f107639a 2303 .is_medium_locked = ide_cd_is_medium_locked,
0e49de52
MA
2304};
2305
01ce352e
JS
2306static const BlockDevOps ide_hd_block_ops = {
2307 .resize_cb = ide_resize_cb,
2308};
2309
4be74634 2310int ide_init_drive(IDEState *s, BlockBackend *blk, IDEDriveKind kind,
95ebda85 2311 const char *version, const char *serial, const char *model,
ba801960
MA
2312 uint64_t wwn,
2313 uint32_t cylinders, uint32_t heads, uint32_t secs,
2314 int chs_trans)
88804180 2315{
88804180
GH
2316 uint64_t nb_sectors;
2317
4be74634 2318 s->blk = blk;
1f56e32a
MA
2319 s->drive_kind = kind;
2320
4be74634 2321 blk_get_geometry(blk, &nb_sectors);
870111c8
MA
2322 s->cylinders = cylinders;
2323 s->heads = heads;
2324 s->sectors = secs;
ba801960 2325 s->chs_trans = chs_trans;
870111c8 2326 s->nb_sectors = nb_sectors;
95ebda85 2327 s->wwn = wwn;
870111c8
MA
2328 /* The SMART values should be preserved across power cycles
2329 but they aren't. */
2330 s->smart_enabled = 1;
2331 s->smart_autosave = 1;
2332 s->smart_errors = 0;
2333 s->smart_selftest_count = 0;
1f56e32a 2334 if (kind == IDE_CD) {
4be74634
MA
2335 blk_set_dev_ops(blk, &ide_cd_block_ops, s);
2336 blk_set_guest_block_size(blk, 2048);
7aa9c811 2337 } else {
4be74634 2338 if (!blk_is_inserted(s->blk)) {
98f28ad7
MA
2339 error_report("Device needs media, but drive is empty");
2340 return -1;
2341 }
4be74634 2342 if (blk_is_read_only(blk)) {
7aa9c811
MA
2343 error_report("Can't use a read-only drive");
2344 return -1;
2345 }
4be74634 2346 blk_set_dev_ops(blk, &ide_hd_block_ops, s);
88804180 2347 }
f8b6cc00 2348 if (serial) {
aa2c91bd 2349 pstrcpy(s->drive_serial_str, sizeof(s->drive_serial_str), serial);
6ced55a5 2350 } else {
88804180
GH
2351 snprintf(s->drive_serial_str, sizeof(s->drive_serial_str),
2352 "QM%05d", s->drive_serial);
870111c8 2353 }
27e0c9a1
FB
2354 if (model) {
2355 pstrcpy(s->drive_model_str, sizeof(s->drive_model_str), model);
2356 } else {
2357 switch (kind) {
2358 case IDE_CD:
2359 strcpy(s->drive_model_str, "QEMU DVD-ROM");
2360 break;
2361 case IDE_CFATA:
2362 strcpy(s->drive_model_str, "QEMU MICRODRIVE");
2363 break;
2364 default:
2365 strcpy(s->drive_model_str, "QEMU HARDDISK");
2366 break;
2367 }
2368 }
2369
47c06340
GH
2370 if (version) {
2371 pstrcpy(s->version, sizeof(s->version), version);
2372 } else {
35c2c8dc 2373 pstrcpy(s->version, sizeof(s->version), qemu_hw_version());
47c06340 2374 }
40a6238a 2375
88804180 2376 ide_reset(s);
4be74634 2377 blk_iostatus_enable(blk);
c4d74df7 2378 return 0;
88804180
GH
2379}
2380
57234ee4 2381static void ide_init1(IDEBus *bus, int unit)
d459da0e
MA
2382{
2383 static int drive_serial = 1;
2384 IDEState *s = &bus->ifs[unit];
2385
2386 s->bus = bus;
2387 s->unit = unit;
2388 s->drive_serial = drive_serial++;
1b2adf28 2389 /* we need at least 2k alignment for accessing CDROMs using O_DIRECT */
50641c5c 2390 s->io_buffer_total_len = IDE_DMA_BUF_SECTORS*512 + 4;
c925400b
KW
2391 s->io_buffer = qemu_memalign(2048, s->io_buffer_total_len);
2392 memset(s->io_buffer, 0, s->io_buffer_total_len);
2393
4be74634 2394 s->smart_selftest_data = blk_blockalign(s->blk, 512);
c925400b
KW
2395 memset(s->smart_selftest_data, 0, 512);
2396
bc72ad67 2397 s->sector_write_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
d459da0e 2398 ide_sector_write_timer_cb, s);
57234ee4
MA
2399}
2400
40a6238a
AG
2401static int ide_nop_int(IDEDMA *dma, int x)
2402{
2403 return 0;
2404}
2405
9898586d
PB
2406static void ide_nop(IDEDMA *dma)
2407{
2408}
2409
a718978e 2410static int32_t ide_nop_int32(IDEDMA *dma, int32_t l)
3251bdcf
JS
2411{
2412 return 0;
2413}
2414
40a6238a 2415static const IDEDMAOps ide_dma_nop_ops = {
3251bdcf 2416 .prepare_buf = ide_nop_int32,
9898586d 2417 .restart_dma = ide_nop,
40a6238a 2418 .rw_buf = ide_nop_int,
40a6238a
AG
2419};
2420
9898586d
PB
2421static void ide_restart_dma(IDEState *s, enum ide_dma_cmd dma_cmd)
2422{
a96cb236 2423 s->unit = s->bus->retry_unit;
dc5d0af4
PB
2424 ide_set_sector(s, s->bus->retry_sector_num);
2425 s->nsector = s->bus->retry_nsector;
9898586d 2426 s->bus->dma->ops->restart_dma(s->bus->dma);
9898586d
PB
2427 s->io_buffer_size = 0;
2428 s->dma_cmd = dma_cmd;
2429 ide_start_dma(s, ide_dma_cb);
2430}
2431
2432static void ide_restart_bh(void *opaque)
2433{
2434 IDEBus *bus = opaque;
2435 IDEState *s;
2436 bool is_read;
2437 int error_status;
2438
2439 qemu_bh_delete(bus->bh);
2440 bus->bh = NULL;
2441
2442 error_status = bus->error_status;
2443 if (bus->error_status == 0) {
2444 return;
2445 }
2446
2447 s = idebus_active_if(bus);
2448 is_read = (bus->error_status & IDE_RETRY_READ) != 0;
2449
2450 /* The error status must be cleared before resubmitting the request: The
2451 * request may fail again, and this case can only be distinguished if the
2452 * called function can set a new error status. */
2453 bus->error_status = 0;
2454
7c03a691
JS
2455 /* The HBA has generically asked to be kicked on retry */
2456 if (error_status & IDE_RETRY_HBA) {
2457 if (s->bus->dma->ops->restart) {
2458 s->bus->dma->ops->restart(s->bus->dma);
2459 }
2460 }
2461
9898586d
PB
2462 if (error_status & IDE_RETRY_DMA) {
2463 if (error_status & IDE_RETRY_TRIM) {
2464 ide_restart_dma(s, IDE_DMA_TRIM);
2465 } else {
2466 ide_restart_dma(s, is_read ? IDE_DMA_READ : IDE_DMA_WRITE);
2467 }
2468 } else if (error_status & IDE_RETRY_PIO) {
2469 if (is_read) {
2470 ide_sector_read(s);
2471 } else {
2472 ide_sector_write(s);
2473 }
2474 } else if (error_status & IDE_RETRY_FLUSH) {
2475 ide_flush_cache(s);
2476 } else {
2477 /*
2478 * We've not got any bits to tell us about ATAPI - but
2479 * we do have the end_transfer_func that tells us what
2480 * we're trying to do.
2481 */
2482 if (s->end_transfer_func == ide_atapi_cmd) {
2483 ide_atapi_dma_restart(s);
2484 }
2485 }
2486}
2487
2488static void ide_restart_cb(void *opaque, int running, RunState state)
2489{
2490 IDEBus *bus = opaque;
2491
2492 if (!running)
2493 return;
2494
2495 if (!bus->bh) {
2496 bus->bh = qemu_bh_new(ide_restart_bh, bus);
2497 qemu_bh_schedule(bus->bh);
2498 }
2499}
2500
f878c916
PB
2501void ide_register_restart_cb(IDEBus *bus)
2502{
9898586d
PB
2503 if (bus->dma->ops->restart_dma) {
2504 qemu_add_vm_change_state_handler(ide_restart_cb, bus);
2505 }
f878c916
PB
2506}
2507
40a6238a
AG
2508static IDEDMA ide_dma_nop = {
2509 .ops = &ide_dma_nop_ops,
2510 .aiocb = NULL,
2511};
2512
57234ee4
MA
2513void ide_init2(IDEBus *bus, qemu_irq irq)
2514{
2515 int i;
2516
2517 for(i = 0; i < 2; i++) {
2518 ide_init1(bus, i);
2519 ide_reset(&bus->ifs[i]);
870111c8 2520 }
57234ee4 2521 bus->irq = irq;
40a6238a 2522 bus->dma = &ide_dma_nop;
d459da0e
MA
2523}
2524
4a91d3b3
RH
2525static const MemoryRegionPortio ide_portio_list[] = {
2526 { 0, 8, 1, .read = ide_ioport_read, .write = ide_ioport_write },
e477317c
PB
2527 { 0, 1, 2, .read = ide_data_readw, .write = ide_data_writew },
2528 { 0, 1, 4, .read = ide_data_readl, .write = ide_data_writel },
4a91d3b3
RH
2529 PORTIO_END_OF_LIST(),
2530};
2531
2532static const MemoryRegionPortio ide_portio2_list[] = {
2533 { 0, 1, 1, .read = ide_status_read, .write = ide_cmd_write },
2534 PORTIO_END_OF_LIST(),
2535};
2536
2537void ide_init_ioport(IDEBus *bus, ISADevice *dev, int iobase, int iobase2)
69b91039 2538{
4a91d3b3
RH
2539 /* ??? Assume only ISA and PCI configurations, and that the PCI-ISA
2540 bridge has been setup properly to always register with ISA. */
2541 isa_register_portio_list(dev, iobase, ide_portio_list, bus, "ide");
2542
caed8802 2543 if (iobase2) {
4a91d3b3 2544 isa_register_portio_list(dev, iobase2, ide_portio2_list, bus, "ide");
5391d806 2545 }
5391d806 2546}
69b91039 2547
37159f13 2548static bool is_identify_set(void *opaque, int version_id)
aa941b94 2549{
37159f13
JQ
2550 IDEState *s = opaque;
2551
2552 return s->identify_set != 0;
2553}
2554
50641c5c
JQ
2555static EndTransferFunc* transfer_end_table[] = {
2556 ide_sector_read,
2557 ide_sector_write,
2558 ide_transfer_stop,
2559 ide_atapi_cmd_reply_end,
2560 ide_atapi_cmd,
2561 ide_dummy_transfer_stop,
2562};
2563
2564static int transfer_end_table_idx(EndTransferFunc *fn)
2565{
2566 int i;
2567
2568 for (i = 0; i < ARRAY_SIZE(transfer_end_table); i++)
2569 if (transfer_end_table[i] == fn)
2570 return i;
2571
2572 return -1;
2573}
2574
37159f13 2575static int ide_drive_post_load(void *opaque, int version_id)
aa941b94 2576{
37159f13
JQ
2577 IDEState *s = opaque;
2578
6b896ab2 2579 if (s->blk && s->identify_set) {
4be74634 2580 blk_set_enable_write_cache(s->blk, !!(s->identify_data[85] & (1 << 5)));
7cdd481c 2581 }
37159f13 2582 return 0;
aa941b94
AZ
2583}
2584
50641c5c
JQ
2585static int ide_drive_pio_post_load(void *opaque, int version_id)
2586{
2587 IDEState *s = opaque;
2588
fb60105d 2589 if (s->end_transfer_fn_idx >= ARRAY_SIZE(transfer_end_table)) {
50641c5c
JQ
2590 return -EINVAL;
2591 }
2592 s->end_transfer_func = transfer_end_table[s->end_transfer_fn_idx];
2593 s->data_ptr = s->io_buffer + s->cur_io_buffer_offset;
2594 s->data_end = s->data_ptr + s->cur_io_buffer_len;
819fa276 2595 s->atapi_dma = s->feature & 1; /* as per cmd_packet */
50641c5c
JQ
2596
2597 return 0;
2598}
2599
2600static void ide_drive_pio_pre_save(void *opaque)
2601{
2602 IDEState *s = opaque;
2603 int idx;
2604
2605 s->cur_io_buffer_offset = s->data_ptr - s->io_buffer;
2606 s->cur_io_buffer_len = s->data_end - s->data_ptr;
2607
2608 idx = transfer_end_table_idx(s->end_transfer_func);
2609 if (idx == -1) {
2610 fprintf(stderr, "%s: invalid end_transfer_func for DRQ_STAT\n",
2611 __func__);
2612 s->end_transfer_fn_idx = 2;
2613 } else {
2614 s->end_transfer_fn_idx = idx;
2615 }
2616}
2617
2618static bool ide_drive_pio_state_needed(void *opaque)
2619{
2620 IDEState *s = opaque;
2621
fdc650d7 2622 return ((s->status & DRQ_STAT) != 0)
fd648f10 2623 || (s->bus->error_status & IDE_RETRY_PIO);
50641c5c
JQ
2624}
2625
db118fe7
MA
2626static bool ide_tray_state_needed(void *opaque)
2627{
2628 IDEState *s = opaque;
2629
2630 return s->tray_open || s->tray_locked;
2631}
2632
996faf1a
AS
2633static bool ide_atapi_gesn_needed(void *opaque)
2634{
2635 IDEState *s = opaque;
2636
2637 return s->events.new_media || s->events.eject_request;
2638}
2639
def93791
KW
2640static bool ide_error_needed(void *opaque)
2641{
2642 IDEBus *bus = opaque;
2643
2644 return (bus->error_status != 0);
2645}
2646
996faf1a 2647/* Fields for GET_EVENT_STATUS_NOTIFICATION ATAPI command */
656fbeff 2648static const VMStateDescription vmstate_ide_atapi_gesn_state = {
996faf1a
AS
2649 .name ="ide_drive/atapi/gesn_state",
2650 .version_id = 1,
2651 .minimum_version_id = 1,
5cd8cada 2652 .needed = ide_atapi_gesn_needed,
35d08458 2653 .fields = (VMStateField[]) {
996faf1a
AS
2654 VMSTATE_BOOL(events.new_media, IDEState),
2655 VMSTATE_BOOL(events.eject_request, IDEState),
0754f9ec 2656 VMSTATE_END_OF_LIST()
996faf1a
AS
2657 }
2658};
2659
db118fe7
MA
2660static const VMStateDescription vmstate_ide_tray_state = {
2661 .name = "ide_drive/tray_state",
2662 .version_id = 1,
2663 .minimum_version_id = 1,
5cd8cada 2664 .needed = ide_tray_state_needed,
db118fe7
MA
2665 .fields = (VMStateField[]) {
2666 VMSTATE_BOOL(tray_open, IDEState),
2667 VMSTATE_BOOL(tray_locked, IDEState),
2668 VMSTATE_END_OF_LIST()
2669 }
2670};
2671
656fbeff 2672static const VMStateDescription vmstate_ide_drive_pio_state = {
50641c5c
JQ
2673 .name = "ide_drive/pio_state",
2674 .version_id = 1,
2675 .minimum_version_id = 1,
50641c5c
JQ
2676 .pre_save = ide_drive_pio_pre_save,
2677 .post_load = ide_drive_pio_post_load,
5cd8cada 2678 .needed = ide_drive_pio_state_needed,
35d08458 2679 .fields = (VMStateField[]) {
50641c5c
JQ
2680 VMSTATE_INT32(req_nb_sectors, IDEState),
2681 VMSTATE_VARRAY_INT32(io_buffer, IDEState, io_buffer_total_len, 1,
2682 vmstate_info_uint8, uint8_t),
2683 VMSTATE_INT32(cur_io_buffer_offset, IDEState),
2684 VMSTATE_INT32(cur_io_buffer_len, IDEState),
2685 VMSTATE_UINT8(end_transfer_fn_idx, IDEState),
2686 VMSTATE_INT32(elementary_transfer_size, IDEState),
2687 VMSTATE_INT32(packet_transfer_size, IDEState),
2688 VMSTATE_END_OF_LIST()
2689 }
2690};
2691
37159f13
JQ
2692const VMStateDescription vmstate_ide_drive = {
2693 .name = "ide_drive",
3abb6260 2694 .version_id = 3,
37159f13 2695 .minimum_version_id = 0,
37159f13 2696 .post_load = ide_drive_post_load,
35d08458 2697 .fields = (VMStateField[]) {
37159f13
JQ
2698 VMSTATE_INT32(mult_sectors, IDEState),
2699 VMSTATE_INT32(identify_set, IDEState),
2700 VMSTATE_BUFFER_TEST(identify_data, IDEState, is_identify_set),
2701 VMSTATE_UINT8(feature, IDEState),
2702 VMSTATE_UINT8(error, IDEState),
2703 VMSTATE_UINT32(nsector, IDEState),
2704 VMSTATE_UINT8(sector, IDEState),
2705 VMSTATE_UINT8(lcyl, IDEState),
2706 VMSTATE_UINT8(hcyl, IDEState),
2707 VMSTATE_UINT8(hob_feature, IDEState),
2708 VMSTATE_UINT8(hob_sector, IDEState),
2709 VMSTATE_UINT8(hob_nsector, IDEState),
2710 VMSTATE_UINT8(hob_lcyl, IDEState),
2711 VMSTATE_UINT8(hob_hcyl, IDEState),
2712 VMSTATE_UINT8(select, IDEState),
2713 VMSTATE_UINT8(status, IDEState),
2714 VMSTATE_UINT8(lba48, IDEState),
2715 VMSTATE_UINT8(sense_key, IDEState),
2716 VMSTATE_UINT8(asc, IDEState),
2717 VMSTATE_UINT8_V(cdrom_changed, IDEState, 3),
37159f13 2718 VMSTATE_END_OF_LIST()
50641c5c 2719 },
5cd8cada
JQ
2720 .subsections = (const VMStateDescription*[]) {
2721 &vmstate_ide_drive_pio_state,
2722 &vmstate_ide_tray_state,
2723 &vmstate_ide_atapi_gesn_state,
2724 NULL
37159f13
JQ
2725 }
2726};
2727
656fbeff 2728static const VMStateDescription vmstate_ide_error_status = {
def93791 2729 .name ="ide_bus/error",
d12b9ff2 2730 .version_id = 2,
def93791 2731 .minimum_version_id = 1,
5cd8cada 2732 .needed = ide_error_needed,
35d08458 2733 .fields = (VMStateField[]) {
def93791 2734 VMSTATE_INT32(error_status, IDEBus),
d12b9ff2
PB
2735 VMSTATE_INT64_V(retry_sector_num, IDEBus, 2),
2736 VMSTATE_UINT32_V(retry_nsector, IDEBus, 2),
2737 VMSTATE_UINT8_V(retry_unit, IDEBus, 2),
def93791
KW
2738 VMSTATE_END_OF_LIST()
2739 }
2740};
2741
6521dc62
JQ
2742const VMStateDescription vmstate_ide_bus = {
2743 .name = "ide_bus",
2744 .version_id = 1,
2745 .minimum_version_id = 1,
35d08458 2746 .fields = (VMStateField[]) {
6521dc62
JQ
2747 VMSTATE_UINT8(cmd, IDEBus),
2748 VMSTATE_UINT8(unit, IDEBus),
2749 VMSTATE_END_OF_LIST()
def93791 2750 },
5cd8cada
JQ
2751 .subsections = (const VMStateDescription*[]) {
2752 &vmstate_ide_error_status,
2753 NULL
6521dc62
JQ
2754 }
2755};
75717903 2756
d8f94e1b 2757void ide_drive_get(DriveInfo **hd, int n)
75717903
IY
2758{
2759 int i;
d8f94e1b
JS
2760 int highest_bus = drive_get_max_bus(IF_IDE) + 1;
2761 int max_devs = drive_get_max_devs(IF_IDE);
2762 int n_buses = max_devs ? (n / max_devs) : n;
75717903 2763
d8f94e1b
JS
2764 /*
2765 * Note: The number of actual buses available is not known.
2766 * We compute this based on the size of the DriveInfo* array, n.
2767 * If it is less than max_devs * <num_real_buses>,
2768 * We will stop looking for drives prematurely instead of overfilling
2769 * the array.
2770 */
2771
2772 if (highest_bus > n_buses) {
2773 error_report("Too many IDE buses defined (%d > %d)",
2774 highest_bus, n_buses);
75717903
IY
2775 exit(1);
2776 }
2777
d8f94e1b
JS
2778 for (i = 0; i < n; i++) {
2779 hd[i] = drive_get_by_index(IF_IDE, i);
75717903
IY
2780 }
2781}