1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include "qemu/osdep.h"
27#include "hw/isa/isa.h"
28#include "migration/vmstate.h"
29#include "qemu/error-report.h"
30#include "qemu/main-loop.h"
31#include "qemu/timer.h"
32#include "qemu/hw-version.h"
33#include "qemu/memalign.h"
34#include "sysemu/sysemu.h"
35#include "sysemu/blockdev.h"
36#include "sysemu/dma.h"
37#include "hw/block/block.h"
38#include "sysemu/block-backend.h"
39#include "qapi/error.h"
40#include "qemu/cutils.h"
41#include "sysemu/replay.h"
42#include "sysemu/runstate.h"
43#include "hw/ide/internal.h"
44#include "trace.h"
45
46
47
48static const int smart_attributes[][12] = {
49
50
51 { 0x01, 0x03, 0x00, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06},
52
53 { 0x03, 0x03, 0x00, 0x64, 0x64, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
54
55 { 0x04, 0x02, 0x00, 0x64, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14},
56
57 { 0x05, 0x03, 0x00, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24},
58
59 { 0x09, 0x03, 0x00, 0x64, 0x64, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
60
61 { 0x0c, 0x03, 0x00, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
62
63 { 190, 0x03, 0x00, 0x45, 0x45, 0x1f, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x32},
64};
65
66const char *IDE_DMA_CMD_lookup[IDE_DMA__COUNT] = {
67 [IDE_DMA_READ] = "DMA READ",
68 [IDE_DMA_WRITE] = "DMA WRITE",
69 [IDE_DMA_TRIM] = "DMA TRIM",
70 [IDE_DMA_ATAPI] = "DMA ATAPI"
71};
72
73static const char *IDE_DMA_CMD_str(enum ide_dma_cmd enval)
74{
75 if ((unsigned)enval < IDE_DMA__COUNT) {
76 return IDE_DMA_CMD_lookup[enval];
77 }
78 return "DMA UNKNOWN CMD";
79}
80
81static void ide_dummy_transfer_stop(IDEState *s);
82
83static void padstr(char *str, const char *src, int len)
84{
85 int i, v;
86 for(i = 0; i < len; i++) {
87 if (*src)
88 v = *src++;
89 else
90 v = ' ';
91 str[i^1] = v;
92 }
93}
94
95static void put_le16(uint16_t *p, unsigned int v)
96{
97 *p = cpu_to_le16(v);
98}
99
100static void ide_identify_size(IDEState *s)
101{
102 uint16_t *p = (uint16_t *)s->identify_data;
103 int64_t nb_sectors_lba28 = s->nb_sectors;
104 if (nb_sectors_lba28 >= 1 << 28) {
105 nb_sectors_lba28 = (1 << 28) - 1;
106 }
107 put_le16(p + 60, nb_sectors_lba28);
108 put_le16(p + 61, nb_sectors_lba28 >> 16);
109 put_le16(p + 100, s->nb_sectors);
110 put_le16(p + 101, s->nb_sectors >> 16);
111 put_le16(p + 102, s->nb_sectors >> 32);
112 put_le16(p + 103, s->nb_sectors >> 48);
113}
114
115static void ide_identify(IDEState *s)
116{
117 uint16_t *p;
118 unsigned int oldsize;
119 IDEDevice *dev = s->unit ? s->bus->slave : s->bus->master;
120
121 p = (uint16_t *)s->identify_data;
122 if (s->identify_set) {
123 goto fill_buffer;
124 }
125 memset(p, 0, sizeof(s->identify_data));
126
127 put_le16(p + 0, 0x0040);
128 put_le16(p + 1, s->cylinders);
129 put_le16(p + 3, s->heads);
130 put_le16(p + 4, 512 * s->sectors);
131 put_le16(p + 5, 512);
132 put_le16(p + 6, s->sectors);
133 padstr((char *)(p + 10), s->drive_serial_str, 20);
134 put_le16(p + 20, 3);
135 put_le16(p + 21, 512);
136 put_le16(p + 22, 4);
137 padstr((char *)(p + 23), s->version, 8);
138 padstr((char *)(p + 27), s->drive_model_str, 40);
139#if MAX_MULT_SECTORS > 1
140 put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
141#endif
142 put_le16(p + 48, 1);
143 put_le16(p + 49, (1 << 11) | (1 << 9) | (1 << 8));
144 put_le16(p + 51, 0x200);
145 put_le16(p + 52, 0x200);
146 put_le16(p + 53, 1 | (1 << 1) | (1 << 2));
147 put_le16(p + 54, s->cylinders);
148 put_le16(p + 55, s->heads);
149 put_le16(p + 56, s->sectors);
150 oldsize = s->cylinders * s->heads * s->sectors;
151 put_le16(p + 57, oldsize);
152 put_le16(p + 58, oldsize >> 16);
153 if (s->mult_sectors)
154 put_le16(p + 59, 0x100 | s->mult_sectors);
155
156
157 put_le16(p + 62, 0x07);
158 put_le16(p + 63, 0x07);
159 put_le16(p + 64, 0x03);
160 put_le16(p + 65, 120);
161 put_le16(p + 66, 120);
162 put_le16(p + 67, 120);
163 put_le16(p + 68, 120);
164 if (dev && dev->conf.discard_granularity) {
165 put_le16(p + 69, (1 << 14));
166 }
167
168 if (s->ncq_queues) {
169 put_le16(p + 75, s->ncq_queues - 1);
170
171 put_le16(p + 76, (1 << 8));
172 }
173
174 put_le16(p + 80, 0xf0);
175 put_le16(p + 81, 0x16);
176
177 put_le16(p + 82, (1 << 14) | (1 << 5) | 1);
178
179 put_le16(p + 83, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
180
181 if (s->wwn) {
182 put_le16(p + 84, (1 << 14) | (1 << 8) | 0);
183 } else {
184 put_le16(p + 84, (1 << 14) | 0);
185 }
186
187 if (blk_enable_write_cache(s->blk)) {
188 put_le16(p + 85, (1 << 14) | (1 << 5) | 1);
189 } else {
190 put_le16(p + 85, (1 << 14) | 1);
191 }
192
193 put_le16(p + 86, (1 << 13) | (1 <<12) | (1 << 10));
194
195 if (s->wwn) {
196 put_le16(p + 87, (1 << 14) | (1 << 8) | 0);
197 } else {
198 put_le16(p + 87, (1 << 14) | 0);
199 }
200 put_le16(p + 88, 0x3f | (1 << 13));
201 put_le16(p + 93, 1 | (1 << 14) | 0x2000);
202
203
204
205
206
207 if (dev && dev->conf.physical_block_size)
208 put_le16(p + 106, 0x6000 | get_physical_block_exp(&dev->conf));
209 if (s->wwn) {
210
211 put_le16(p + 108, s->wwn >> 48);
212 put_le16(p + 109, s->wwn >> 32);
213 put_le16(p + 110, s->wwn >> 16);
214 put_le16(p + 111, s->wwn);
215 }
216 if (dev && dev->conf.discard_granularity) {
217 put_le16(p + 169, 1);
218 }
219 if (dev) {
220 put_le16(p + 217, dev->rotation_rate);
221 }
222
223 ide_identify_size(s);
224 s->identify_set = 1;
225
226fill_buffer:
227 memcpy(s->io_buffer, p, sizeof(s->identify_data));
228}
229
230static void ide_atapi_identify(IDEState *s)
231{
232 uint16_t *p;
233
234 p = (uint16_t *)s->identify_data;
235 if (s->identify_set) {
236 goto fill_buffer;
237 }
238 memset(p, 0, sizeof(s->identify_data));
239
240
241 put_le16(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0));
242 padstr((char *)(p + 10), s->drive_serial_str, 20);
243 put_le16(p + 20, 3);
244 put_le16(p + 21, 512);
245 put_le16(p + 22, 4);
246 padstr((char *)(p + 23), s->version, 8);
247 padstr((char *)(p + 27), s->drive_model_str, 40);
248 put_le16(p + 48, 1);
249#ifdef USE_DMA_CDROM
250 put_le16(p + 49, 1 << 9 | 1 << 8);
251 put_le16(p + 53, 7);
252 put_le16(p + 62, 7);
253 put_le16(p + 63, 7);
254#else
255 put_le16(p + 49, 1 << 9);
256 put_le16(p + 53, 3);
257 put_le16(p + 63, 0x103);
258#endif
259 put_le16(p + 64, 3);
260 put_le16(p + 65, 0xb4);
261 put_le16(p + 66, 0xb4);
262 put_le16(p + 67, 0x12c);
263 put_le16(p + 68, 0xb4);
264
265 put_le16(p + 71, 30);
266 put_le16(p + 72, 30);
267
268 if (s->ncq_queues) {
269 put_le16(p + 75, s->ncq_queues - 1);
270
271 put_le16(p + 76, (1 << 8));
272 }
273
274 put_le16(p + 80, 0x1e);
275 if (s->wwn) {
276 put_le16(p + 84, (1 << 8));
277 put_le16(p + 87, (1 << 8));
278 }
279
280#ifdef USE_DMA_CDROM
281 put_le16(p + 88, 0x3f | (1 << 13));
282#endif
283
284 if (s->wwn) {
285
286 put_le16(p + 108, s->wwn >> 48);
287 put_le16(p + 109, s->wwn >> 32);
288 put_le16(p + 110, s->wwn >> 16);
289 put_le16(p + 111, s->wwn);
290 }
291
292 s->identify_set = 1;
293
294fill_buffer:
295 memcpy(s->io_buffer, p, sizeof(s->identify_data));
296}
297
298static void ide_cfata_identify_size(IDEState *s)
299{
300 uint16_t *p = (uint16_t *)s->identify_data;
301 put_le16(p + 7, s->nb_sectors >> 16);
302 put_le16(p + 8, s->nb_sectors);
303 put_le16(p + 60, s->nb_sectors);
304 put_le16(p + 61, s->nb_sectors >> 16);
305}
306
307static void ide_cfata_identify(IDEState *s)
308{
309 uint16_t *p;
310 uint32_t cur_sec;
311
312 p = (uint16_t *)s->identify_data;
313 if (s->identify_set) {
314 goto fill_buffer;
315 }
316 memset(p, 0, sizeof(s->identify_data));
317
318 cur_sec = s->cylinders * s->heads * s->sectors;
319
320 put_le16(p + 0, 0x848a);
321 put_le16(p + 1, s->cylinders);
322 put_le16(p + 3, s->heads);
323 put_le16(p + 6, s->sectors);
324
325
326 padstr((char *)(p + 10), s->drive_serial_str, 20);
327 put_le16(p + 22, 0x0004);
328 padstr((char *) (p + 23), s->version, 8);
329 padstr((char *) (p + 27), s->drive_model_str, 40);
330#if MAX_MULT_SECTORS > 1
331 put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
332#else
333 put_le16(p + 47, 0x0000);
334#endif
335 put_le16(p + 49, 0x0f00);
336 put_le16(p + 51, 0x0002);
337 put_le16(p + 52, 0x0001);
338 put_le16(p + 53, 0x0003);
339 put_le16(p + 54, s->cylinders);
340 put_le16(p + 55, s->heads);
341 put_le16(p + 56, s->sectors);
342 put_le16(p + 57, cur_sec);
343 put_le16(p + 58, cur_sec >> 16);
344 if (s->mult_sectors)
345 put_le16(p + 59, 0x100 | s->mult_sectors);
346
347
348 put_le16(p + 63, 0x0203);
349 put_le16(p + 64, 0x0001);
350 put_le16(p + 65, 0x0096);
351 put_le16(p + 66, 0x0096);
352 put_le16(p + 68, 0x00b4);
353 put_le16(p + 82, 0x400c);
354 put_le16(p + 83, 0x7068);
355 put_le16(p + 84, 0x4000);
356 put_le16(p + 85, 0x000c);
357 put_le16(p + 86, 0x7044);
358 put_le16(p + 87, 0x4000);
359 put_le16(p + 91, 0x4060);
360 put_le16(p + 129, 0x0002);
361 put_le16(p + 130, 0x0005);
362 put_le16(p + 131, 0x0001);
363 put_le16(p + 132, 0x0000);
364 put_le16(p + 160, 0x8100);
365 put_le16(p + 161, 0x8001);
366
367 ide_cfata_identify_size(s);
368 s->identify_set = 1;
369
370fill_buffer:
371 memcpy(s->io_buffer, p, sizeof(s->identify_data));
372}
373
374static void ide_set_signature(IDEState *s)
375{
376 s->select &= ~(ATA_DEV_HS);
377
378 s->nsector = 1;
379 s->sector = 1;
380 if (s->drive_kind == IDE_CD) {
381 s->lcyl = 0x14;
382 s->hcyl = 0xeb;
383 } else if (s->blk) {
384 s->lcyl = 0;
385 s->hcyl = 0;
386 } else {
387 s->lcyl = 0xff;
388 s->hcyl = 0xff;
389 }
390}
391
392static bool ide_sect_range_ok(IDEState *s,
393 uint64_t sector, uint64_t nb_sectors)
394{
395 uint64_t total_sectors;
396
397 blk_get_geometry(s->blk, &total_sectors);
398 if (sector > total_sectors || nb_sectors > total_sectors - sector) {
399 return false;
400 }
401 return true;
402}
403
404typedef struct TrimAIOCB {
405 BlockAIOCB common;
406 IDEState *s;
407 QEMUBH *bh;
408 int ret;
409 QEMUIOVector *qiov;
410 BlockAIOCB *aiocb;
411 int i, j;
412} TrimAIOCB;
413
414static void trim_aio_cancel(BlockAIOCB *acb)
415{
416 TrimAIOCB *iocb = container_of(acb, TrimAIOCB, common);
417
418
419 iocb->j = iocb->qiov->niov - 1;
420 iocb->i = (iocb->qiov->iov[iocb->j].iov_len / 8) - 1;
421
422 iocb->ret = -ECANCELED;
423
424 if (iocb->aiocb) {
425 blk_aio_cancel_async(iocb->aiocb);
426 iocb->aiocb = NULL;
427 }
428}
429
430static const AIOCBInfo trim_aiocb_info = {
431 .aiocb_size = sizeof(TrimAIOCB),
432 .cancel_async = trim_aio_cancel,
433};
434
435static void ide_trim_bh_cb(void *opaque)
436{
437 TrimAIOCB *iocb = opaque;
438 BlockBackend *blk = iocb->s->blk;
439
440 iocb->common.cb(iocb->common.opaque, iocb->ret);
441
442 qemu_bh_delete(iocb->bh);
443 iocb->bh = NULL;
444 qemu_aio_unref(iocb);
445
446
447 blk_dec_in_flight(blk);
448}
449
450static void ide_issue_trim_cb(void *opaque, int ret)
451{
452 TrimAIOCB *iocb = opaque;
453 IDEState *s = iocb->s;
454
455 if (iocb->i >= 0) {
456 if (ret >= 0) {
457 block_acct_done(blk_get_stats(s->blk), &s->acct);
458 } else {
459 block_acct_failed(blk_get_stats(s->blk), &s->acct);
460 }
461 }
462
463 if (ret >= 0) {
464 while (iocb->j < iocb->qiov->niov) {
465 int j = iocb->j;
466 while (++iocb->i < iocb->qiov->iov[j].iov_len / 8) {
467 int i = iocb->i;
468 uint64_t *buffer = iocb->qiov->iov[j].iov_base;
469
470
471 uint64_t entry = le64_to_cpu(buffer[i]);
472 uint64_t sector = entry & 0x0000ffffffffffffULL;
473 uint16_t count = entry >> 48;
474
475 if (count == 0) {
476 continue;
477 }
478
479 if (!ide_sect_range_ok(s, sector, count)) {
480 block_acct_invalid(blk_get_stats(s->blk), BLOCK_ACCT_UNMAP);
481 iocb->ret = -EINVAL;
482 goto done;
483 }
484
485 block_acct_start(blk_get_stats(s->blk), &s->acct,
486 count << BDRV_SECTOR_BITS, BLOCK_ACCT_UNMAP);
487
488
489 iocb->aiocb = blk_aio_pdiscard(s->blk,
490 sector << BDRV_SECTOR_BITS,
491 count << BDRV_SECTOR_BITS,
492 ide_issue_trim_cb, opaque);
493 return;
494 }
495
496 iocb->j++;
497 iocb->i = -1;
498 }
499 } else {
500 iocb->ret = ret;
501 }
502
503done:
504 iocb->aiocb = NULL;
505 if (iocb->bh) {
506 replay_bh_schedule_event(iocb->bh);
507 }
508}
509
510BlockAIOCB *ide_issue_trim(
511 int64_t offset, QEMUIOVector *qiov,
512 BlockCompletionFunc *cb, void *cb_opaque, void *opaque)
513{
514 IDEState *s = opaque;
515 TrimAIOCB *iocb;
516
517
518 blk_inc_in_flight(s->blk);
519
520 iocb = blk_aio_get(&trim_aiocb_info, s->blk, cb, cb_opaque);
521 iocb->s = s;
522 iocb->bh = qemu_bh_new(ide_trim_bh_cb, iocb);
523 iocb->ret = 0;
524 iocb->qiov = qiov;
525 iocb->i = -1;
526 iocb->j = 0;
527 ide_issue_trim_cb(iocb, 0);
528 return &iocb->common;
529}
530
531void ide_abort_command(IDEState *s)
532{
533 ide_transfer_stop(s);
534 s->status = READY_STAT | ERR_STAT;
535 s->error = ABRT_ERR;
536}
537
538static void ide_set_retry(IDEState *s)
539{
540 s->bus->retry_unit = s->unit;
541 s->bus->retry_sector_num = ide_get_sector(s);
542 s->bus->retry_nsector = s->nsector;
543}
544
545static void ide_clear_retry(IDEState *s)
546{
547 s->bus->retry_unit = -1;
548 s->bus->retry_sector_num = 0;
549 s->bus->retry_nsector = 0;
550}
551
552
553bool ide_transfer_start_norecurse(IDEState *s, uint8_t *buf, int size,
554 EndTransferFunc *end_transfer_func)
555{
556 s->data_ptr = buf;
557 s->data_end = buf + size;
558 ide_set_retry(s);
559 if (!(s->status & ERR_STAT)) {
560 s->status |= DRQ_STAT;
561 }
562 if (!s->bus->dma->ops->pio_transfer) {
563 s->end_transfer_func = end_transfer_func;
564 return false;
565 }
566 s->bus->dma->ops->pio_transfer(s->bus->dma);
567 return true;
568}
569
570void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
571 EndTransferFunc *end_transfer_func)
572{
573 if (ide_transfer_start_norecurse(s, buf, size, end_transfer_func)) {
574 end_transfer_func(s);
575 }
576}
577
578static void ide_cmd_done(IDEState *s)
579{
580 if (s->bus->dma->ops->cmd_done) {
581 s->bus->dma->ops->cmd_done(s->bus->dma);
582 }
583}
584
585static void ide_transfer_halt(IDEState *s)
586{
587 s->end_transfer_func = ide_transfer_stop;
588 s->data_ptr = s->io_buffer;
589 s->data_end = s->io_buffer;
590 s->status &= ~DRQ_STAT;
591}
592
593void ide_transfer_stop(IDEState *s)
594{
595 ide_transfer_halt(s);
596 ide_cmd_done(s);
597}
598
599int64_t ide_get_sector(IDEState *s)
600{
601 int64_t sector_num;
602 if (s->select & (ATA_DEV_LBA)) {
603 if (s->lba48) {
604 sector_num = ((int64_t)s->hob_hcyl << 40) |
605 ((int64_t) s->hob_lcyl << 32) |
606 ((int64_t) s->hob_sector << 24) |
607 ((int64_t) s->hcyl << 16) |
608 ((int64_t) s->lcyl << 8) | s->sector;
609 } else {
610
611 sector_num = ((s->select & (ATA_DEV_LBA_MSB)) << 24) |
612 (s->hcyl << 16) | (s->lcyl << 8) | s->sector;
613 }
614 } else {
615
616 sector_num = ((s->hcyl << 8) | s->lcyl) * s->heads * s->sectors +
617 (s->select & (ATA_DEV_HS)) * s->sectors + (s->sector - 1);
618 }
619
620 return sector_num;
621}
622
623void ide_set_sector(IDEState *s, int64_t sector_num)
624{
625 unsigned int cyl, r;
626 if (s->select & (ATA_DEV_LBA)) {
627 if (s->lba48) {
628 s->sector = sector_num;
629 s->lcyl = sector_num >> 8;
630 s->hcyl = sector_num >> 16;
631 s->hob_sector = sector_num >> 24;
632 s->hob_lcyl = sector_num >> 32;
633 s->hob_hcyl = sector_num >> 40;
634 } else {
635
636 s->select = (s->select & ~(ATA_DEV_LBA_MSB)) |
637 ((sector_num >> 24) & (ATA_DEV_LBA_MSB));
638 s->hcyl = (sector_num >> 16);
639 s->lcyl = (sector_num >> 8);
640 s->sector = (sector_num);
641 }
642 } else {
643
644 cyl = sector_num / (s->heads * s->sectors);
645 r = sector_num % (s->heads * s->sectors);
646 s->hcyl = cyl >> 8;
647 s->lcyl = cyl;
648 s->select = (s->select & ~(ATA_DEV_HS)) |
649 ((r / s->sectors) & (ATA_DEV_HS));
650 s->sector = (r % s->sectors) + 1;
651 }
652}
653
654static void ide_rw_error(IDEState *s) {
655 ide_abort_command(s);
656 ide_set_irq(s->bus);
657}
658
659static void ide_buffered_readv_cb(void *opaque, int ret)
660{
661 IDEBufferedRequest *req = opaque;
662 if (!req->orphaned) {
663 if (!ret) {
664 assert(req->qiov.size == req->original_qiov->size);
665 qemu_iovec_from_buf(req->original_qiov, 0,
666 req->qiov.local_iov.iov_base,
667 req->original_qiov->size);
668 }
669 req->original_cb(req->original_opaque, ret);
670 }
671 QLIST_REMOVE(req, list);
672 qemu_vfree(qemu_iovec_buf(&req->qiov));
673 g_free(req);
674}
675
676#define MAX_BUFFERED_REQS 16
677
678BlockAIOCB *ide_buffered_readv(IDEState *s, int64_t sector_num,
679 QEMUIOVector *iov, int nb_sectors,
680 BlockCompletionFunc *cb, void *opaque)
681{
682 BlockAIOCB *aioreq;
683 IDEBufferedRequest *req;
684 int c = 0;
685
686 QLIST_FOREACH(req, &s->buffered_requests, list) {
687 c++;
688 }
689 if (c > MAX_BUFFERED_REQS) {
690 return blk_abort_aio_request(s->blk, cb, opaque, -EIO);
691 }
692
693 req = g_new0(IDEBufferedRequest, 1);
694 req->original_qiov = iov;
695 req->original_cb = cb;
696 req->original_opaque = opaque;
697 qemu_iovec_init_buf(&req->qiov, blk_blockalign(s->blk, iov->size),
698 iov->size);
699
700 aioreq = blk_aio_preadv(s->blk, sector_num << BDRV_SECTOR_BITS,
701 &req->qiov, 0, ide_buffered_readv_cb, req);
702
703 QLIST_INSERT_HEAD(&s->buffered_requests, req, list);
704 return aioreq;
705}
706
707
708
709
710
711
712void ide_cancel_dma_sync(IDEState *s)
713{
714 IDEBufferedRequest *req;
715
716
717
718
719
720 QLIST_FOREACH(req, &s->buffered_requests, list) {
721 if (!req->orphaned) {
722 trace_ide_cancel_dma_sync_buffered(req->original_cb, req);
723 req->original_cb(req->original_opaque, -ECANCELED);
724 }
725 req->orphaned = true;
726 }
727
728
729
730
731
732
733
734
735
736
737
738
739
740 if (s->bus->dma->aiocb) {
741 trace_ide_cancel_dma_sync_remaining();
742 blk_drain(s->blk);
743 assert(s->bus->dma->aiocb == NULL);
744 }
745}
746
747static void ide_sector_read(IDEState *s);
748
749static void ide_sector_read_cb(void *opaque, int ret)
750{
751 IDEState *s = opaque;
752 int n;
753
754 s->pio_aiocb = NULL;
755 s->status &= ~BUSY_STAT;
756
757 if (ret != 0) {
758 if (ide_handle_rw_error(s, -ret, IDE_RETRY_PIO |
759 IDE_RETRY_READ)) {
760 return;
761 }
762 }
763
764 block_acct_done(blk_get_stats(s->blk), &s->acct);
765
766 n = s->nsector;
767 if (n > s->req_nb_sectors) {
768 n = s->req_nb_sectors;
769 }
770
771 ide_set_sector(s, ide_get_sector(s) + n);
772 s->nsector -= n;
773
774 ide_transfer_start(s, s->io_buffer, n * BDRV_SECTOR_SIZE, ide_sector_read);
775 ide_set_irq(s->bus);
776}
777
778static void ide_sector_read(IDEState *s)
779{
780 int64_t sector_num;
781 int n;
782
783 s->status = READY_STAT | SEEK_STAT;
784 s->error = 0;
785 sector_num = ide_get_sector(s);
786 n = s->nsector;
787
788 if (n == 0) {
789 ide_transfer_stop(s);
790 return;
791 }
792
793 s->status |= BUSY_STAT;
794
795 if (n > s->req_nb_sectors) {
796 n = s->req_nb_sectors;
797 }
798
799 trace_ide_sector_read(sector_num, n);
800
801 if (!ide_sect_range_ok(s, sector_num, n)) {
802 ide_rw_error(s);
803 block_acct_invalid(blk_get_stats(s->blk), BLOCK_ACCT_READ);
804 return;
805 }
806
807 qemu_iovec_init_buf(&s->qiov, s->io_buffer, n * BDRV_SECTOR_SIZE);
808
809 block_acct_start(blk_get_stats(s->blk), &s->acct,
810 n * BDRV_SECTOR_SIZE, BLOCK_ACCT_READ);
811 s->pio_aiocb = ide_buffered_readv(s, sector_num, &s->qiov, n,
812 ide_sector_read_cb, s);
813}
814
815void dma_buf_commit(IDEState *s, uint32_t tx_bytes)
816{
817 if (s->bus->dma->ops->commit_buf) {
818 s->bus->dma->ops->commit_buf(s->bus->dma, tx_bytes);
819 }
820 s->io_buffer_offset += tx_bytes;
821 qemu_sglist_destroy(&s->sg);
822}
823
824void ide_set_inactive(IDEState *s, bool more)
825{
826 s->bus->dma->aiocb = NULL;
827 ide_clear_retry(s);
828 if (s->bus->dma->ops->set_inactive) {
829 s->bus->dma->ops->set_inactive(s->bus->dma, more);
830 }
831 ide_cmd_done(s);
832}
833
834void ide_dma_error(IDEState *s)
835{
836 dma_buf_commit(s, 0);
837 ide_abort_command(s);
838 ide_set_inactive(s, false);
839 ide_set_irq(s->bus);
840}
841
842int ide_handle_rw_error(IDEState *s, int error, int op)
843{
844 bool is_read = (op & IDE_RETRY_READ) != 0;
845 BlockErrorAction action = blk_get_error_action(s->blk, is_read, error);
846
847 if (action == BLOCK_ERROR_ACTION_STOP) {
848 assert(s->bus->retry_unit == s->unit);
849 s->bus->error_status = op;
850 } else if (action == BLOCK_ERROR_ACTION_REPORT) {
851 block_acct_failed(blk_get_stats(s->blk), &s->acct);
852 if (IS_IDE_RETRY_DMA(op)) {
853 ide_dma_error(s);
854 } else if (IS_IDE_RETRY_ATAPI(op)) {
855 ide_atapi_io_error(s, -error);
856 } else {
857 ide_rw_error(s);
858 }
859 }
860 blk_error_action(s->blk, action, is_read, error);
861 return action != BLOCK_ERROR_ACTION_IGNORE;
862}
863
864static void ide_dma_cb(void *opaque, int ret)
865{
866 IDEState *s = opaque;
867 int n;
868 int64_t sector_num;
869 uint64_t offset;
870 bool stay_active = false;
871 int32_t prep_size = 0;
872
873 if (ret == -EINVAL) {
874 ide_dma_error(s);
875 return;
876 }
877
878 if (ret < 0) {
879 if (ide_handle_rw_error(s, -ret, ide_dma_cmd_to_retry(s->dma_cmd))) {
880 s->bus->dma->aiocb = NULL;
881 dma_buf_commit(s, 0);
882 return;
883 }
884 }
885
886 if (s->io_buffer_size > s->nsector * 512) {
887
888
889
890
891 n = s->nsector;
892 stay_active = true;
893 } else {
894 n = s->io_buffer_size >> 9;
895 }
896
897 sector_num = ide_get_sector(s);
898 if (n > 0) {
899 assert(n * 512 == s->sg.size);
900 dma_buf_commit(s, s->sg.size);
901 sector_num += n;
902 ide_set_sector(s, sector_num);
903 s->nsector -= n;
904 }
905
906
907 if (s->nsector == 0) {
908 s->status = READY_STAT | SEEK_STAT;
909 ide_set_irq(s->bus);
910 goto eot;
911 }
912
913
914 n = s->nsector;
915 s->io_buffer_index = 0;
916 s->io_buffer_size = n * 512;
917 prep_size = s->bus->dma->ops->prepare_buf(s->bus->dma, s->io_buffer_size);
918
919 assert(prep_size >= 0 && prep_size <= n * 512);
920
921
922
923
924
925
926 if (prep_size < n * 512) {
927
928
929
930
931 s->status = READY_STAT | SEEK_STAT;
932 dma_buf_commit(s, 0);
933 goto eot;
934 }
935
936 trace_ide_dma_cb(s, sector_num, n, IDE_DMA_CMD_str(s->dma_cmd));
937
938 if ((s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) &&
939 !ide_sect_range_ok(s, sector_num, n)) {
940 ide_dma_error(s);
941 block_acct_invalid(blk_get_stats(s->blk), s->acct.type);
942 return;
943 }
944
945 offset = sector_num << BDRV_SECTOR_BITS;
946 switch (s->dma_cmd) {
947 case IDE_DMA_READ:
948 s->bus->dma->aiocb = dma_blk_read(s->blk, &s->sg, offset,
949 BDRV_SECTOR_SIZE, ide_dma_cb, s);
950 break;
951 case IDE_DMA_WRITE:
952 s->bus->dma->aiocb = dma_blk_write(s->blk, &s->sg, offset,
953 BDRV_SECTOR_SIZE, ide_dma_cb, s);
954 break;
955 case IDE_DMA_TRIM:
956 s->bus->dma->aiocb = dma_blk_io(blk_get_aio_context(s->blk),
957 &s->sg, offset, BDRV_SECTOR_SIZE,
958 ide_issue_trim, s, ide_dma_cb, s,
959 DMA_DIRECTION_TO_DEVICE);
960 break;
961 default:
962 abort();
963 }
964 return;
965
966eot:
967 if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) {
968 block_acct_done(blk_get_stats(s->blk), &s->acct);
969 }
970 ide_set_inactive(s, stay_active);
971}
972
973static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd)
974{
975 s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
976 s->io_buffer_size = 0;
977 s->dma_cmd = dma_cmd;
978
979 switch (dma_cmd) {
980 case IDE_DMA_READ:
981 block_acct_start(blk_get_stats(s->blk), &s->acct,
982 s->nsector * BDRV_SECTOR_SIZE, BLOCK_ACCT_READ);
983 break;
984 case IDE_DMA_WRITE:
985 block_acct_start(blk_get_stats(s->blk), &s->acct,
986 s->nsector * BDRV_SECTOR_SIZE, BLOCK_ACCT_WRITE);
987 break;
988 default:
989 break;
990 }
991
992 ide_start_dma(s, ide_dma_cb);
993}
994
995void ide_start_dma(IDEState *s, BlockCompletionFunc *cb)
996{
997 s->io_buffer_index = 0;
998 ide_set_retry(s);
999 if (s->bus->dma->ops->start_dma) {
1000 s->bus->dma->ops->start_dma(s->bus->dma, s, cb);
1001 }
1002}
1003
1004static void ide_sector_write(IDEState *s);
1005
1006static void ide_sector_write_timer_cb(void *opaque)
1007{
1008 IDEState *s = opaque;
1009 ide_set_irq(s->bus);
1010}
1011
1012static void ide_sector_write_cb(void *opaque, int ret)
1013{
1014 IDEState *s = opaque;
1015 int n;
1016
1017 s->pio_aiocb = NULL;
1018 s->status &= ~BUSY_STAT;
1019
1020 if (ret != 0) {
1021 if (ide_handle_rw_error(s, -ret, IDE_RETRY_PIO)) {
1022 return;
1023 }
1024 }
1025
1026 block_acct_done(blk_get_stats(s->blk), &s->acct);
1027
1028 n = s->nsector;
1029 if (n > s->req_nb_sectors) {
1030 n = s->req_nb_sectors;
1031 }
1032 s->nsector -= n;
1033
1034 ide_set_sector(s, ide_get_sector(s) + n);
1035 if (s->nsector == 0) {
1036
1037 ide_transfer_stop(s);
1038 } else {
1039 int n1 = s->nsector;
1040 if (n1 > s->req_nb_sectors) {
1041 n1 = s->req_nb_sectors;
1042 }
1043 ide_transfer_start(s, s->io_buffer, n1 * BDRV_SECTOR_SIZE,
1044 ide_sector_write);
1045 }
1046
1047 if (win2k_install_hack && ((++s->irq_count % 16) == 0)) {
1048
1049
1050
1051
1052
1053
1054 timer_mod(s->sector_write_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
1055 (NANOSECONDS_PER_SECOND / 1000));
1056 } else {
1057 ide_set_irq(s->bus);
1058 }
1059}
1060
1061static void ide_sector_write(IDEState *s)
1062{
1063 int64_t sector_num;
1064 int n;
1065
1066 s->status = READY_STAT | SEEK_STAT | BUSY_STAT;
1067 sector_num = ide_get_sector(s);
1068
1069 n = s->nsector;
1070 if (n > s->req_nb_sectors) {
1071 n = s->req_nb_sectors;
1072 }
1073
1074 trace_ide_sector_write(sector_num, n);
1075
1076 if (!ide_sect_range_ok(s, sector_num, n)) {
1077 ide_rw_error(s);
1078 block_acct_invalid(blk_get_stats(s->blk), BLOCK_ACCT_WRITE);
1079 return;
1080 }
1081
1082 qemu_iovec_init_buf(&s->qiov, s->io_buffer, n * BDRV_SECTOR_SIZE);
1083
1084 block_acct_start(blk_get_stats(s->blk), &s->acct,
1085 n * BDRV_SECTOR_SIZE, BLOCK_ACCT_WRITE);
1086 s->pio_aiocb = blk_aio_pwritev(s->blk, sector_num << BDRV_SECTOR_BITS,
1087 &s->qiov, 0, ide_sector_write_cb, s);
1088}
1089
1090static void ide_flush_cb(void *opaque, int ret)
1091{
1092 IDEState *s = opaque;
1093
1094 s->pio_aiocb = NULL;
1095
1096 if (ret < 0) {
1097
1098 if (ide_handle_rw_error(s, -ret, IDE_RETRY_FLUSH)) {
1099 return;
1100 }
1101 }
1102
1103 if (s->blk) {
1104 block_acct_done(blk_get_stats(s->blk), &s->acct);
1105 }
1106 s->status = READY_STAT | SEEK_STAT;
1107 ide_cmd_done(s);
1108 ide_set_irq(s->bus);
1109}
1110
1111static void ide_flush_cache(IDEState *s)
1112{
1113 if (s->blk == NULL) {
1114 ide_flush_cb(s, 0);
1115 return;
1116 }
1117
1118 s->status |= BUSY_STAT;
1119 ide_set_retry(s);
1120 block_acct_start(blk_get_stats(s->blk), &s->acct, 0, BLOCK_ACCT_FLUSH);
1121 s->pio_aiocb = blk_aio_flush(s->blk, ide_flush_cb, s);
1122}
1123
1124static void ide_cfata_metadata_inquiry(IDEState *s)
1125{
1126 uint16_t *p;
1127 uint32_t spd;
1128
1129 p = (uint16_t *) s->io_buffer;
1130 memset(p, 0, 0x200);
1131 spd = ((s->mdata_size - 1) >> 9) + 1;
1132
1133 put_le16(p + 0, 0x0001);
1134 put_le16(p + 1, 0x0000);
1135 put_le16(p + 2, s->media_changed);
1136 put_le16(p + 3, s->mdata_size & 0xffff);
1137 put_le16(p + 4, s->mdata_size >> 16);
1138 put_le16(p + 5, spd & 0xffff);
1139 put_le16(p + 6, spd >> 16);
1140}
1141
1142static void ide_cfata_metadata_read(IDEState *s)
1143{
1144 uint16_t *p;
1145
1146 if (((s->hcyl << 16) | s->lcyl) << 9 > s->mdata_size + 2) {
1147 s->status = ERR_STAT;
1148 s->error = ABRT_ERR;
1149 return;
1150 }
1151
1152 p = (uint16_t *) s->io_buffer;
1153 memset(p, 0, 0x200);
1154
1155 put_le16(p + 0, s->media_changed);
1156 memcpy(p + 1, s->mdata_storage + (((s->hcyl << 16) | s->lcyl) << 9),
1157 MIN(MIN(s->mdata_size - (((s->hcyl << 16) | s->lcyl) << 9),
1158 s->nsector << 9), 0x200 - 2));
1159}
1160
1161static void ide_cfata_metadata_write(IDEState *s)
1162{
1163 if (((s->hcyl << 16) | s->lcyl) << 9 > s->mdata_size + 2) {
1164 s->status = ERR_STAT;
1165 s->error = ABRT_ERR;
1166 return;
1167 }
1168
1169 s->media_changed = 0;
1170
1171 memcpy(s->mdata_storage + (((s->hcyl << 16) | s->lcyl) << 9),
1172 s->io_buffer + 2,
1173 MIN(MIN(s->mdata_size - (((s->hcyl << 16) | s->lcyl) << 9),
1174 s->nsector << 9), 0x200 - 2));
1175}
1176
1177
1178static void ide_cd_change_cb(void *opaque, bool load, Error **errp)
1179{
1180 IDEState *s = opaque;
1181 uint64_t nb_sectors;
1182
1183 s->tray_open = !load;
1184 blk_get_geometry(s->blk, &nb_sectors);
1185 s->nb_sectors = nb_sectors;
1186
1187
1188
1189
1190
1191
1192
1193
1194 s->cdrom_changed = 1;
1195 s->events.new_media = true;
1196 s->events.eject_request = false;
1197 ide_set_irq(s->bus);
1198}
1199
1200static void ide_cd_eject_request_cb(void *opaque, bool force)
1201{
1202 IDEState *s = opaque;
1203
1204 s->events.eject_request = true;
1205 if (force) {
1206 s->tray_locked = false;
1207 }
1208 ide_set_irq(s->bus);
1209}
1210
1211static void ide_cmd_lba48_transform(IDEState *s, int lba48)
1212{
1213 s->lba48 = lba48;
1214
1215
1216
1217
1218
1219 if (!s->lba48) {
1220 if (!s->nsector)
1221 s->nsector = 256;
1222 } else {
1223 if (!s->nsector && !s->hob_nsector)
1224 s->nsector = 65536;
1225 else {
1226 int lo = s->nsector;
1227 int hi = s->hob_nsector;
1228
1229 s->nsector = (hi << 8) | lo;
1230 }
1231 }
1232}
1233
1234static void ide_clear_hob(IDEBus *bus)
1235{
1236
1237 bus->cmd &= ~(IDE_CTRL_HOB);
1238}
1239
1240
1241enum ATA_IOPORT_WR {
1242 ATA_IOPORT_WR_DATA = 0,
1243 ATA_IOPORT_WR_FEATURES = 1,
1244 ATA_IOPORT_WR_SECTOR_COUNT = 2,
1245 ATA_IOPORT_WR_SECTOR_NUMBER = 3,
1246 ATA_IOPORT_WR_CYLINDER_LOW = 4,
1247 ATA_IOPORT_WR_CYLINDER_HIGH = 5,
1248 ATA_IOPORT_WR_DEVICE_HEAD = 6,
1249 ATA_IOPORT_WR_COMMAND = 7,
1250 ATA_IOPORT_WR_NUM_REGISTERS,
1251};
1252
1253const char *ATA_IOPORT_WR_lookup[ATA_IOPORT_WR_NUM_REGISTERS] = {
1254 [ATA_IOPORT_WR_DATA] = "Data",
1255 [ATA_IOPORT_WR_FEATURES] = "Features",
1256 [ATA_IOPORT_WR_SECTOR_COUNT] = "Sector Count",
1257 [ATA_IOPORT_WR_SECTOR_NUMBER] = "Sector Number",
1258 [ATA_IOPORT_WR_CYLINDER_LOW] = "Cylinder Low",
1259 [ATA_IOPORT_WR_CYLINDER_HIGH] = "Cylinder High",
1260 [ATA_IOPORT_WR_DEVICE_HEAD] = "Device/Head",
1261 [ATA_IOPORT_WR_COMMAND] = "Command"
1262};
1263
1264void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1265{
1266 IDEBus *bus = opaque;
1267 IDEState *s = idebus_active_if(bus);
1268 int reg_num = addr & 7;
1269
1270 trace_ide_ioport_write(addr, ATA_IOPORT_WR_lookup[reg_num], val, bus, s);
1271
1272
1273 if (reg_num != 7 && (s->status & (BUSY_STAT|DRQ_STAT))) {
1274 return;
1275 }
1276
1277
1278
1279
1280 switch (reg_num) {
1281 case 0:
1282 break;
1283 case ATA_IOPORT_WR_FEATURES:
1284 ide_clear_hob(bus);
1285 bus->ifs[0].hob_feature = bus->ifs[0].feature;
1286 bus->ifs[1].hob_feature = bus->ifs[1].feature;
1287 bus->ifs[0].feature = val;
1288 bus->ifs[1].feature = val;
1289 break;
1290 case ATA_IOPORT_WR_SECTOR_COUNT:
1291 ide_clear_hob(bus);
1292 bus->ifs[0].hob_nsector = bus->ifs[0].nsector;
1293 bus->ifs[1].hob_nsector = bus->ifs[1].nsector;
1294 bus->ifs[0].nsector = val;
1295 bus->ifs[1].nsector = val;
1296 break;
1297 case ATA_IOPORT_WR_SECTOR_NUMBER:
1298 ide_clear_hob(bus);
1299 bus->ifs[0].hob_sector = bus->ifs[0].sector;
1300 bus->ifs[1].hob_sector = bus->ifs[1].sector;
1301 bus->ifs[0].sector = val;
1302 bus->ifs[1].sector = val;
1303 break;
1304 case ATA_IOPORT_WR_CYLINDER_LOW:
1305 ide_clear_hob(bus);
1306 bus->ifs[0].hob_lcyl = bus->ifs[0].lcyl;
1307 bus->ifs[1].hob_lcyl = bus->ifs[1].lcyl;
1308 bus->ifs[0].lcyl = val;
1309 bus->ifs[1].lcyl = val;
1310 break;
1311 case ATA_IOPORT_WR_CYLINDER_HIGH:
1312 ide_clear_hob(bus);
1313 bus->ifs[0].hob_hcyl = bus->ifs[0].hcyl;
1314 bus->ifs[1].hob_hcyl = bus->ifs[1].hcyl;
1315 bus->ifs[0].hcyl = val;
1316 bus->ifs[1].hcyl = val;
1317 break;
1318 case ATA_IOPORT_WR_DEVICE_HEAD:
1319 ide_clear_hob(bus);
1320 bus->ifs[0].select = val | (ATA_DEV_ALWAYS_ON);
1321 bus->ifs[1].select = val | (ATA_DEV_ALWAYS_ON);
1322
1323 bus->unit = (val & (ATA_DEV_SELECT)) ? 1 : 0;
1324 break;
1325 default:
1326 case ATA_IOPORT_WR_COMMAND:
1327 ide_clear_hob(bus);
1328 qemu_irq_lower(bus->irq);
1329 ide_exec_cmd(bus, val);
1330 break;
1331 }
1332}
1333
1334static void ide_reset(IDEState *s)
1335{
1336 trace_ide_reset(s);
1337
1338 if (s->pio_aiocb) {
1339 blk_aio_cancel(s->pio_aiocb);
1340 s->pio_aiocb = NULL;
1341 }
1342
1343 if (s->drive_kind == IDE_CFATA)
1344 s->mult_sectors = 0;
1345 else
1346 s->mult_sectors = MAX_MULT_SECTORS;
1347
1348 s->feature = 0;
1349 s->error = 0;
1350 s->nsector = 0;
1351 s->sector = 0;
1352 s->lcyl = 0;
1353 s->hcyl = 0;
1354
1355
1356 s->hob_feature = 0;
1357 s->hob_sector = 0;
1358 s->hob_nsector = 0;
1359 s->hob_lcyl = 0;
1360 s->hob_hcyl = 0;
1361
1362 s->select = (ATA_DEV_ALWAYS_ON);
1363 s->status = READY_STAT | SEEK_STAT;
1364
1365 s->lba48 = 0;
1366
1367
1368 s->sense_key = 0;
1369 s->asc = 0;
1370 s->cdrom_changed = 0;
1371 s->packet_transfer_size = 0;
1372 s->elementary_transfer_size = 0;
1373 s->io_buffer_index = 0;
1374 s->cd_sector_size = 0;
1375 s->atapi_dma = 0;
1376 s->tray_locked = 0;
1377 s->tray_open = 0;
1378
1379 s->io_buffer_size = 0;
1380 s->req_nb_sectors = 0;
1381
1382 ide_set_signature(s);
1383
1384
1385 s->end_transfer_func = ide_dummy_transfer_stop;
1386 ide_dummy_transfer_stop(s);
1387 s->media_changed = 0;
1388}
1389
1390static bool cmd_nop(IDEState *s, uint8_t cmd)
1391{
1392 return true;
1393}
1394
1395static bool cmd_device_reset(IDEState *s, uint8_t cmd)
1396{
1397
1398 ide_transfer_halt(s);
1399 ide_cancel_dma_sync(s);
1400
1401
1402 ide_reset(s);
1403
1404
1405
1406 s->status = 0x00;
1407
1408
1409 return false;
1410}
1411
1412static bool cmd_data_set_management(IDEState *s, uint8_t cmd)
1413{
1414 switch (s->feature) {
1415 case DSM_TRIM:
1416 if (s->blk) {
1417 ide_sector_start_dma(s, IDE_DMA_TRIM);
1418 return false;
1419 }
1420 break;
1421 }
1422
1423 ide_abort_command(s);
1424 return true;
1425}
1426
1427static bool cmd_identify(IDEState *s, uint8_t cmd)
1428{
1429 if (s->blk && s->drive_kind != IDE_CD) {
1430 if (s->drive_kind != IDE_CFATA) {
1431 ide_identify(s);
1432 } else {
1433 ide_cfata_identify(s);
1434 }
1435 s->status = READY_STAT | SEEK_STAT;
1436 ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
1437 ide_set_irq(s->bus);
1438 return false;
1439 } else {
1440 if (s->drive_kind == IDE_CD) {
1441 ide_set_signature(s);
1442 }
1443 ide_abort_command(s);
1444 }
1445
1446 return true;
1447}
1448
1449static bool cmd_verify(IDEState *s, uint8_t cmd)
1450{
1451 bool lba48 = (cmd == WIN_VERIFY_EXT);
1452
1453
1454 ide_cmd_lba48_transform(s, lba48);
1455
1456 return true;
1457}
1458
1459static bool cmd_set_multiple_mode(IDEState *s, uint8_t cmd)
1460{
1461 if (s->drive_kind == IDE_CFATA && s->nsector == 0) {
1462
1463 s->mult_sectors = 0;
1464 } else if ((s->nsector & 0xff) != 0 &&
1465 ((s->nsector & 0xff) > MAX_MULT_SECTORS ||
1466 (s->nsector & (s->nsector - 1)) != 0)) {
1467 ide_abort_command(s);
1468 } else {
1469 s->mult_sectors = s->nsector & 0xff;
1470 }
1471
1472 return true;
1473}
1474
1475static bool cmd_read_multiple(IDEState *s, uint8_t cmd)
1476{
1477 bool lba48 = (cmd == WIN_MULTREAD_EXT);
1478
1479 if (!s->blk || !s->mult_sectors) {
1480 ide_abort_command(s);
1481 return true;
1482 }
1483
1484 ide_cmd_lba48_transform(s, lba48);
1485 s->req_nb_sectors = s->mult_sectors;
1486 ide_sector_read(s);
1487 return false;
1488}
1489
1490static bool cmd_write_multiple(IDEState *s, uint8_t cmd)
1491{
1492 bool lba48 = (cmd == WIN_MULTWRITE_EXT);
1493 int n;
1494
1495 if (!s->blk || !s->mult_sectors) {
1496 ide_abort_command(s);
1497 return true;
1498 }
1499
1500 ide_cmd_lba48_transform(s, lba48);
1501
1502 s->req_nb_sectors = s->mult_sectors;
1503 n = MIN(s->nsector, s->req_nb_sectors);
1504
1505 s->status = SEEK_STAT | READY_STAT;
1506 ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
1507
1508 s->media_changed = 1;
1509
1510 return false;
1511}
1512
1513static bool cmd_read_pio(IDEState *s, uint8_t cmd)
1514{
1515 bool lba48 = (cmd == WIN_READ_EXT);
1516
1517 if (s->drive_kind == IDE_CD) {
1518 ide_set_signature(s);
1519 ide_abort_command(s);
1520 return true;
1521 }
1522
1523 if (!s->blk) {
1524 ide_abort_command(s);
1525 return true;
1526 }
1527
1528 ide_cmd_lba48_transform(s, lba48);
1529 s->req_nb_sectors = 1;
1530 ide_sector_read(s);
1531
1532 return false;
1533}
1534
1535static bool cmd_write_pio(IDEState *s, uint8_t cmd)
1536{
1537 bool lba48 = (cmd == WIN_WRITE_EXT);
1538
1539 if (!s->blk) {
1540 ide_abort_command(s);
1541 return true;
1542 }
1543
1544 ide_cmd_lba48_transform(s, lba48);
1545
1546 s->req_nb_sectors = 1;
1547 s->status = SEEK_STAT | READY_STAT;
1548 ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
1549
1550 s->media_changed = 1;
1551
1552 return false;
1553}
1554
1555static bool cmd_read_dma(IDEState *s, uint8_t cmd)
1556{
1557 bool lba48 = (cmd == WIN_READDMA_EXT);
1558
1559 if (!s->blk) {
1560 ide_abort_command(s);
1561 return true;
1562 }
1563
1564 ide_cmd_lba48_transform(s, lba48);
1565 ide_sector_start_dma(s, IDE_DMA_READ);
1566
1567 return false;
1568}
1569
1570static bool cmd_write_dma(IDEState *s, uint8_t cmd)
1571{
1572 bool lba48 = (cmd == WIN_WRITEDMA_EXT);
1573
1574 if (!s->blk) {
1575 ide_abort_command(s);
1576 return true;
1577 }
1578
1579 ide_cmd_lba48_transform(s, lba48);
1580 ide_sector_start_dma(s, IDE_DMA_WRITE);
1581
1582 s->media_changed = 1;
1583
1584 return false;
1585}
1586
1587static bool cmd_flush_cache(IDEState *s, uint8_t cmd)
1588{
1589 ide_flush_cache(s);
1590 return false;
1591}
1592
1593static bool cmd_seek(IDEState *s, uint8_t cmd)
1594{
1595
1596 return true;
1597}
1598
1599static bool cmd_read_native_max(IDEState *s, uint8_t cmd)
1600{
1601 bool lba48 = (cmd == WIN_READ_NATIVE_MAX_EXT);
1602
1603
1604 if (s->nb_sectors == 0) {
1605 ide_abort_command(s);
1606 return true;
1607 }
1608
1609 ide_cmd_lba48_transform(s, lba48);
1610 ide_set_sector(s, s->nb_sectors - 1);
1611
1612 return true;
1613}
1614
1615static bool cmd_check_power_mode(IDEState *s, uint8_t cmd)
1616{
1617 s->nsector = 0xff;
1618 return true;
1619}
1620
1621static bool cmd_set_features(IDEState *s, uint8_t cmd)
1622{
1623 uint16_t *identify_data;
1624
1625 if (!s->blk) {
1626 ide_abort_command(s);
1627 return true;
1628 }
1629
1630
1631 switch (s->feature) {
1632 case 0x02:
1633 blk_set_enable_write_cache(s->blk, true);
1634 identify_data = (uint16_t *)s->identify_data;
1635 put_le16(identify_data + 85, (1 << 14) | (1 << 5) | 1);
1636 return true;
1637 case 0x82:
1638 blk_set_enable_write_cache(s->blk, false);
1639 identify_data = (uint16_t *)s->identify_data;
1640 put_le16(identify_data + 85, (1 << 14) | 1);
1641 ide_flush_cache(s);
1642 return false;
1643 case 0xcc:
1644 case 0x66:
1645 case 0xaa:
1646 case 0x55:
1647 case 0x05:
1648 case 0x85:
1649 case 0x69:
1650 case 0x67:
1651 case 0x96:
1652 case 0x9a:
1653 case 0x42:
1654 case 0xc2:
1655 return true;
1656 case 0x03:
1657 {
1658 uint8_t val = s->nsector & 0x07;
1659 identify_data = (uint16_t *)s->identify_data;
1660
1661 switch (s->nsector >> 3) {
1662 case 0x00:
1663 case 0x01:
1664 put_le16(identify_data + 62, 0x07);
1665 put_le16(identify_data + 63, 0x07);
1666 put_le16(identify_data + 88, 0x3f);
1667 break;
1668 case 0x02:
1669 put_le16(identify_data + 62, 0x07 | (1 << (val + 8)));
1670 put_le16(identify_data + 63, 0x07);
1671 put_le16(identify_data + 88, 0x3f);
1672 break;
1673 case 0x04:
1674 put_le16(identify_data + 62, 0x07);
1675 put_le16(identify_data + 63, 0x07 | (1 << (val + 8)));
1676 put_le16(identify_data + 88, 0x3f);
1677 break;
1678 case 0x08:
1679 put_le16(identify_data + 62, 0x07);
1680 put_le16(identify_data + 63, 0x07);
1681 put_le16(identify_data + 88, 0x3f | (1 << (val + 8)));
1682 break;
1683 default:
1684 goto abort_cmd;
1685 }
1686 return true;
1687 }
1688 }
1689
1690abort_cmd:
1691 ide_abort_command(s);
1692 return true;
1693}
1694
1695
1696
1697
1698static bool cmd_identify_packet(IDEState *s, uint8_t cmd)
1699{
1700 ide_atapi_identify(s);
1701 s->status = READY_STAT | SEEK_STAT;
1702 ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
1703 ide_set_irq(s->bus);
1704 return false;
1705}
1706
1707static bool cmd_exec_dev_diagnostic(IDEState *s, uint8_t cmd)
1708{
1709 ide_set_signature(s);
1710
1711 if (s->drive_kind == IDE_CD) {
1712 s->status = 0;
1713
1714
1715 s->error = 0x01;
1716 } else {
1717 s->status = READY_STAT | SEEK_STAT;
1718
1719
1720
1721 s->error = 0x01;
1722 ide_set_irq(s->bus);
1723 }
1724
1725 return false;
1726}
1727
1728static bool cmd_packet(IDEState *s, uint8_t cmd)
1729{
1730
1731 if (s->feature & 0x02) {
1732 ide_abort_command(s);
1733 return true;
1734 }
1735
1736 s->status = READY_STAT | SEEK_STAT;
1737 s->atapi_dma = s->feature & 1;
1738 if (s->atapi_dma) {
1739 s->dma_cmd = IDE_DMA_ATAPI;
1740 }
1741 s->nsector = 1;
1742 ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,
1743 ide_atapi_cmd);
1744 return false;
1745}
1746
1747
1748
1749
1750static bool cmd_cfa_req_ext_error_code(IDEState *s, uint8_t cmd)
1751{
1752 s->error = 0x09;
1753 s->status = READY_STAT | SEEK_STAT;
1754 ide_set_irq(s->bus);
1755
1756 return false;
1757}
1758
1759static bool cmd_cfa_erase_sectors(IDEState *s, uint8_t cmd)
1760{
1761
1762
1763
1764 if (cmd == CFA_WEAR_LEVEL) {
1765 s->nsector = 0;
1766 }
1767
1768 if (cmd == CFA_ERASE_SECTORS) {
1769 s->media_changed = 1;
1770 }
1771
1772 return true;
1773}
1774
1775static bool cmd_cfa_translate_sector(IDEState *s, uint8_t cmd)
1776{
1777 s->status = READY_STAT | SEEK_STAT;
1778
1779 memset(s->io_buffer, 0, 0x200);
1780 s->io_buffer[0x00] = s->hcyl;
1781 s->io_buffer[0x01] = s->lcyl;
1782 s->io_buffer[0x02] = s->select;
1783 s->io_buffer[0x03] = s->sector;
1784 s->io_buffer[0x04] = ide_get_sector(s) >> 16;
1785 s->io_buffer[0x05] = ide_get_sector(s) >> 8;
1786 s->io_buffer[0x06] = ide_get_sector(s) >> 0;
1787 s->io_buffer[0x13] = 0x00;
1788 s->io_buffer[0x18] = 0x00;
1789 s->io_buffer[0x19] = 0x00;
1790 s->io_buffer[0x1a] = 0x01;
1791
1792 ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1793 ide_set_irq(s->bus);
1794
1795 return false;
1796}
1797
1798static bool cmd_cfa_access_metadata_storage(IDEState *s, uint8_t cmd)
1799{
1800 switch (s->feature) {
1801 case 0x02:
1802 ide_cfata_metadata_inquiry(s);
1803 break;
1804 case 0x03:
1805 ide_cfata_metadata_read(s);
1806 break;
1807 case 0x04:
1808 ide_cfata_metadata_write(s);
1809 break;
1810 default:
1811 ide_abort_command(s);
1812 return true;
1813 }
1814
1815 ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1816 s->status = 0x00;
1817 ide_set_irq(s->bus);
1818
1819 return false;
1820}
1821
1822static bool cmd_ibm_sense_condition(IDEState *s, uint8_t cmd)
1823{
1824 switch (s->feature) {
1825 case 0x01:
1826 s->nsector = 0x50;
1827 break;
1828 default:
1829 ide_abort_command(s);
1830 return true;
1831 }
1832
1833 return true;
1834}
1835
1836
1837
1838
1839static bool cmd_smart(IDEState *s, uint8_t cmd)
1840{
1841 int n;
1842
1843 if (s->hcyl != 0xc2 || s->lcyl != 0x4f) {
1844 goto abort_cmd;
1845 }
1846
1847 if (!s->smart_enabled && s->feature != SMART_ENABLE) {
1848 goto abort_cmd;
1849 }
1850
1851 switch (s->feature) {
1852 case SMART_DISABLE:
1853 s->smart_enabled = 0;
1854 return true;
1855
1856 case SMART_ENABLE:
1857 s->smart_enabled = 1;
1858 return true;
1859
1860 case SMART_ATTR_AUTOSAVE:
1861 switch (s->sector) {
1862 case 0x00:
1863 s->smart_autosave = 0;
1864 break;
1865 case 0xf1:
1866 s->smart_autosave = 1;
1867 break;
1868 default:
1869 goto abort_cmd;
1870 }
1871 return true;
1872
1873 case SMART_STATUS:
1874 if (!s->smart_errors) {
1875 s->hcyl = 0xc2;
1876 s->lcyl = 0x4f;
1877 } else {
1878 s->hcyl = 0x2c;
1879 s->lcyl = 0xf4;
1880 }
1881 return true;
1882
1883 case SMART_READ_THRESH:
1884 memset(s->io_buffer, 0, 0x200);
1885 s->io_buffer[0] = 0x01;
1886
1887 for (n = 0; n < ARRAY_SIZE(smart_attributes); n++) {
1888 s->io_buffer[2 + 0 + (n * 12)] = smart_attributes[n][0];
1889 s->io_buffer[2 + 1 + (n * 12)] = smart_attributes[n][11];
1890 }
1891
1892
1893 for (n = 0; n < 511; n++) {
1894 s->io_buffer[511] += s->io_buffer[n];
1895 }
1896 s->io_buffer[511] = 0x100 - s->io_buffer[511];
1897
1898 s->status = READY_STAT | SEEK_STAT;
1899 ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1900 ide_set_irq(s->bus);
1901 return false;
1902
1903 case SMART_READ_DATA:
1904 memset(s->io_buffer, 0, 0x200);
1905 s->io_buffer[0] = 0x01;
1906
1907 for (n = 0; n < ARRAY_SIZE(smart_attributes); n++) {
1908 int i;
1909 for (i = 0; i < 11; i++) {
1910 s->io_buffer[2 + i + (n * 12)] = smart_attributes[n][i];
1911 }
1912 }
1913
1914 s->io_buffer[362] = 0x02 | (s->smart_autosave ? 0x80 : 0x00);
1915 if (s->smart_selftest_count == 0) {
1916 s->io_buffer[363] = 0;
1917 } else {
1918 s->io_buffer[363] =
1919 s->smart_selftest_data[3 +
1920 (s->smart_selftest_count - 1) *
1921 24];
1922 }
1923 s->io_buffer[364] = 0x20;
1924 s->io_buffer[365] = 0x01;
1925
1926 s->io_buffer[367] = (1 << 4 | 1 << 3 | 1);
1927 s->io_buffer[368] = 0x03;
1928 s->io_buffer[369] = 0x00;
1929 s->io_buffer[370] = 0x01;
1930 s->io_buffer[372] = 0x02;
1931 s->io_buffer[373] = 0x36;
1932 s->io_buffer[374] = 0x01;
1933
1934 for (n = 0; n < 511; n++) {
1935 s->io_buffer[511] += s->io_buffer[n];
1936 }
1937 s->io_buffer[511] = 0x100 - s->io_buffer[511];
1938
1939 s->status = READY_STAT | SEEK_STAT;
1940 ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1941 ide_set_irq(s->bus);
1942 return false;
1943
1944 case SMART_READ_LOG:
1945 switch (s->sector) {
1946 case 0x01:
1947 memset(s->io_buffer, 0, 0x200);
1948 s->io_buffer[0] = 0x01;
1949 s->io_buffer[1] = 0x00;
1950 s->io_buffer[452] = s->smart_errors & 0xff;
1951 s->io_buffer[453] = (s->smart_errors & 0xff00) >> 8;
1952
1953 for (n = 0; n < 511; n++) {
1954 s->io_buffer[511] += s->io_buffer[n];
1955 }
1956 s->io_buffer[511] = 0x100 - s->io_buffer[511];
1957 break;
1958 case 0x06:
1959 memset(s->io_buffer, 0, 0x200);
1960 s->io_buffer[0] = 0x01;
1961 if (s->smart_selftest_count == 0) {
1962 s->io_buffer[508] = 0;
1963 } else {
1964 s->io_buffer[508] = s->smart_selftest_count;
1965 for (n = 2; n < 506; n++) {
1966 s->io_buffer[n] = s->smart_selftest_data[n];
1967 }
1968 }
1969
1970 for (n = 0; n < 511; n++) {
1971 s->io_buffer[511] += s->io_buffer[n];
1972 }
1973 s->io_buffer[511] = 0x100 - s->io_buffer[511];
1974 break;
1975 default:
1976 goto abort_cmd;
1977 }
1978 s->status = READY_STAT | SEEK_STAT;
1979 ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1980 ide_set_irq(s->bus);
1981 return false;
1982
1983 case SMART_EXECUTE_OFFLINE:
1984 switch (s->sector) {
1985 case 0:
1986 case 1:
1987 case 2:
1988 s->smart_selftest_count++;
1989 if (s->smart_selftest_count > 21) {
1990 s->smart_selftest_count = 1;
1991 }
1992 n = 2 + (s->smart_selftest_count - 1) * 24;
1993 s->smart_selftest_data[n] = s->sector;
1994 s->smart_selftest_data[n + 1] = 0x00;
1995 s->smart_selftest_data[n + 2] = 0x34;
1996 s->smart_selftest_data[n + 3] = 0x12;
1997 break;
1998 default:
1999 goto abort_cmd;
2000 }
2001 return true;
2002 }
2003
2004abort_cmd:
2005 ide_abort_command(s);
2006 return true;
2007}
2008
2009#define HD_OK (1u << IDE_HD)
2010#define CD_OK (1u << IDE_CD)
2011#define CFA_OK (1u << IDE_CFATA)
2012#define HD_CFA_OK (HD_OK | CFA_OK)
2013#define ALL_OK (HD_OK | CD_OK | CFA_OK)
2014
2015
2016#define SET_DSC (1u << 8)
2017
2018
2019static const struct {
2020
2021 bool (*handler)(IDEState *s, uint8_t cmd);
2022 int flags;
2023} ide_cmd_table[0x100] = {
2024
2025 [CFA_REQ_EXT_ERROR_CODE] = { cmd_cfa_req_ext_error_code, CFA_OK },
2026 [WIN_DSM] = { cmd_data_set_management, HD_CFA_OK },
2027 [WIN_DEVICE_RESET] = { cmd_device_reset, CD_OK },
2028 [WIN_RECAL] = { cmd_nop, HD_CFA_OK | SET_DSC},
2029 [WIN_READ] = { cmd_read_pio, ALL_OK },
2030 [WIN_READ_ONCE] = { cmd_read_pio, HD_CFA_OK },
2031 [WIN_READ_EXT] = { cmd_read_pio, HD_CFA_OK },
2032 [WIN_READDMA_EXT] = { cmd_read_dma, HD_CFA_OK },
2033 [WIN_READ_NATIVE_MAX_EXT] = { cmd_read_native_max, HD_CFA_OK | SET_DSC },
2034 [WIN_MULTREAD_EXT] = { cmd_read_multiple, HD_CFA_OK },
2035 [WIN_WRITE] = { cmd_write_pio, HD_CFA_OK },
2036 [WIN_WRITE_ONCE] = { cmd_write_pio, HD_CFA_OK },
2037 [WIN_WRITE_EXT] = { cmd_write_pio, HD_CFA_OK },
2038 [WIN_WRITEDMA_EXT] = { cmd_write_dma, HD_CFA_OK },
2039 [CFA_WRITE_SECT_WO_ERASE] = { cmd_write_pio, CFA_OK },
2040 [WIN_MULTWRITE_EXT] = { cmd_write_multiple, HD_CFA_OK },
2041 [WIN_WRITE_VERIFY] = { cmd_write_pio, HD_CFA_OK },
2042 [WIN_VERIFY] = { cmd_verify, HD_CFA_OK | SET_DSC },
2043 [WIN_VERIFY_ONCE] = { cmd_verify, HD_CFA_OK | SET_DSC },
2044 [WIN_VERIFY_EXT] = { cmd_verify, HD_CFA_OK | SET_DSC },
2045 [WIN_SEEK] = { cmd_seek, HD_CFA_OK | SET_DSC },
2046 [CFA_TRANSLATE_SECTOR] = { cmd_cfa_translate_sector, CFA_OK },
2047 [WIN_DIAGNOSE] = { cmd_exec_dev_diagnostic, ALL_OK },
2048 [WIN_SPECIFY] = { cmd_nop, HD_CFA_OK | SET_DSC },
2049 [WIN_STANDBYNOW2] = { cmd_nop, HD_CFA_OK },
2050 [WIN_IDLEIMMEDIATE2] = { cmd_nop, HD_CFA_OK },
2051 [WIN_STANDBY2] = { cmd_nop, HD_CFA_OK },
2052 [WIN_SETIDLE2] = { cmd_nop, HD_CFA_OK },
2053 [WIN_CHECKPOWERMODE2] = { cmd_check_power_mode, HD_CFA_OK | SET_DSC },
2054 [WIN_SLEEPNOW2] = { cmd_nop, HD_CFA_OK },
2055 [WIN_PACKETCMD] = { cmd_packet, CD_OK },
2056 [WIN_PIDENTIFY] = { cmd_identify_packet, CD_OK },
2057 [WIN_SMART] = { cmd_smart, HD_CFA_OK | SET_DSC },
2058 [CFA_ACCESS_METADATA_STORAGE] = { cmd_cfa_access_metadata_storage, CFA_OK },
2059 [CFA_ERASE_SECTORS] = { cmd_cfa_erase_sectors, CFA_OK | SET_DSC },
2060 [WIN_MULTREAD] = { cmd_read_multiple, HD_CFA_OK },
2061 [WIN_MULTWRITE] = { cmd_write_multiple, HD_CFA_OK },
2062 [WIN_SETMULT] = { cmd_set_multiple_mode, HD_CFA_OK | SET_DSC },
2063 [WIN_READDMA] = { cmd_read_dma, HD_CFA_OK },
2064 [WIN_READDMA_ONCE] = { cmd_read_dma, HD_CFA_OK },
2065 [WIN_WRITEDMA] = { cmd_write_dma, HD_CFA_OK },
2066 [WIN_WRITEDMA_ONCE] = { cmd_write_dma, HD_CFA_OK },
2067 [CFA_WRITE_MULTI_WO_ERASE] = { cmd_write_multiple, CFA_OK },
2068 [WIN_STANDBYNOW1] = { cmd_nop, HD_CFA_OK },
2069 [WIN_IDLEIMMEDIATE] = { cmd_nop, HD_CFA_OK },
2070 [WIN_STANDBY] = { cmd_nop, HD_CFA_OK },
2071 [WIN_SETIDLE1] = { cmd_nop, HD_CFA_OK },
2072 [WIN_CHECKPOWERMODE1] = { cmd_check_power_mode, HD_CFA_OK | SET_DSC },
2073 [WIN_SLEEPNOW1] = { cmd_nop, HD_CFA_OK },
2074 [WIN_FLUSH_CACHE] = { cmd_flush_cache, ALL_OK },
2075 [WIN_FLUSH_CACHE_EXT] = { cmd_flush_cache, HD_CFA_OK },
2076 [WIN_IDENTIFY] = { cmd_identify, ALL_OK },
2077 [WIN_SETFEATURES] = { cmd_set_features, ALL_OK | SET_DSC },
2078 [IBM_SENSE_CONDITION] = { cmd_ibm_sense_condition, CFA_OK | SET_DSC },
2079 [CFA_WEAR_LEVEL] = { cmd_cfa_erase_sectors, HD_CFA_OK | SET_DSC },
2080 [WIN_READ_NATIVE_MAX] = { cmd_read_native_max, HD_CFA_OK | SET_DSC },
2081};
2082
2083static bool ide_cmd_permitted(IDEState *s, uint32_t cmd)
2084{
2085 return cmd < ARRAY_SIZE(ide_cmd_table)
2086 && (ide_cmd_table[cmd].flags & (1u << s->drive_kind));
2087}
2088
2089void ide_exec_cmd(IDEBus *bus, uint32_t val)
2090{
2091 IDEState *s;
2092 bool complete;
2093
2094 s = idebus_active_if(bus);
2095 trace_ide_exec_cmd(bus, s, val);
2096
2097
2098 if (s != bus->ifs && !s->blk) {
2099 return;
2100 }
2101
2102
2103
2104 if (s->status & (BUSY_STAT|DRQ_STAT)) {
2105 if (val != WIN_DEVICE_RESET || s->drive_kind != IDE_CD) {
2106 return;
2107 }
2108 }
2109
2110 if (!ide_cmd_permitted(s, val)) {
2111 ide_abort_command(s);
2112 ide_set_irq(s->bus);
2113 return;
2114 }
2115
2116 s->status = READY_STAT | BUSY_STAT;
2117 s->error = 0;
2118 s->io_buffer_offset = 0;
2119
2120 complete = ide_cmd_table[val].handler(s, val);
2121 if (complete) {
2122 s->status &= ~BUSY_STAT;
2123 assert(!!s->error == !!(s->status & ERR_STAT));
2124
2125 if ((ide_cmd_table[val].flags & SET_DSC) && !s->error) {
2126 s->status |= SEEK_STAT;
2127 }
2128
2129 ide_cmd_done(s);
2130 ide_set_irq(s->bus);
2131 }
2132}
2133
2134
2135enum ATA_IOPORT_RR {
2136 ATA_IOPORT_RR_DATA = 0,
2137 ATA_IOPORT_RR_ERROR = 1,
2138 ATA_IOPORT_RR_SECTOR_COUNT = 2,
2139 ATA_IOPORT_RR_SECTOR_NUMBER = 3,
2140 ATA_IOPORT_RR_CYLINDER_LOW = 4,
2141 ATA_IOPORT_RR_CYLINDER_HIGH = 5,
2142 ATA_IOPORT_RR_DEVICE_HEAD = 6,
2143 ATA_IOPORT_RR_STATUS = 7,
2144 ATA_IOPORT_RR_NUM_REGISTERS,
2145};
2146
2147const char *ATA_IOPORT_RR_lookup[ATA_IOPORT_RR_NUM_REGISTERS] = {
2148 [ATA_IOPORT_RR_DATA] = "Data",
2149 [ATA_IOPORT_RR_ERROR] = "Error",
2150 [ATA_IOPORT_RR_SECTOR_COUNT] = "Sector Count",
2151 [ATA_IOPORT_RR_SECTOR_NUMBER] = "Sector Number",
2152 [ATA_IOPORT_RR_CYLINDER_LOW] = "Cylinder Low",
2153 [ATA_IOPORT_RR_CYLINDER_HIGH] = "Cylinder High",
2154 [ATA_IOPORT_RR_DEVICE_HEAD] = "Device/Head",
2155 [ATA_IOPORT_RR_STATUS] = "Status"
2156};
2157
2158uint32_t ide_ioport_read(void *opaque, uint32_t addr)
2159{
2160 IDEBus *bus = opaque;
2161 IDEState *s = idebus_active_if(bus);
2162 uint32_t reg_num;
2163 int ret, hob;
2164
2165 reg_num = addr & 7;
2166 hob = bus->cmd & (IDE_CTRL_HOB);
2167 switch (reg_num) {
2168 case ATA_IOPORT_RR_DATA:
2169
2170
2171
2172
2173 ret = ide_data_readw(bus, addr) & 0xff;
2174 break;
2175 case ATA_IOPORT_RR_ERROR:
2176 if ((!bus->ifs[0].blk && !bus->ifs[1].blk) ||
2177 (s != bus->ifs && !s->blk)) {
2178 ret = 0;
2179 } else if (!hob) {
2180 ret = s->error;
2181 } else {
2182 ret = s->hob_feature;
2183 }
2184 break;
2185 case ATA_IOPORT_RR_SECTOR_COUNT:
2186 if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
2187 ret = 0;
2188 } else if (!hob) {
2189 ret = s->nsector & 0xff;
2190 } else {
2191 ret = s->hob_nsector;
2192 }
2193 break;
2194 case ATA_IOPORT_RR_SECTOR_NUMBER:
2195 if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
2196 ret = 0;
2197 } else if (!hob) {
2198 ret = s->sector;
2199 } else {
2200 ret = s->hob_sector;
2201 }
2202 break;
2203 case ATA_IOPORT_RR_CYLINDER_LOW:
2204 if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
2205 ret = 0;
2206 } else if (!hob) {
2207 ret = s->lcyl;
2208 } else {
2209 ret = s->hob_lcyl;
2210 }
2211 break;
2212 case ATA_IOPORT_RR_CYLINDER_HIGH:
2213 if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
2214 ret = 0;
2215 } else if (!hob) {
2216 ret = s->hcyl;
2217 } else {
2218 ret = s->hob_hcyl;
2219 }
2220 break;
2221 case ATA_IOPORT_RR_DEVICE_HEAD:
2222 if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
2223 ret = 0;
2224 } else {
2225 ret = s->select;
2226 }
2227 break;
2228 default:
2229 case ATA_IOPORT_RR_STATUS:
2230 if ((!bus->ifs[0].blk && !bus->ifs[1].blk) ||
2231 (s != bus->ifs && !s->blk)) {
2232 ret = 0;
2233 } else {
2234 ret = s->status;
2235 }
2236 qemu_irq_lower(bus->irq);
2237 break;
2238 }
2239
2240 trace_ide_ioport_read(addr, ATA_IOPORT_RR_lookup[reg_num], ret, bus, s);
2241 return ret;
2242}
2243
2244uint32_t ide_status_read(void *opaque, uint32_t addr)
2245{
2246 IDEBus *bus = opaque;
2247 IDEState *s = idebus_active_if(bus);
2248 int ret;
2249
2250 if ((!bus->ifs[0].blk && !bus->ifs[1].blk) ||
2251 (s != bus->ifs && !s->blk)) {
2252 ret = 0;
2253 } else {
2254 ret = s->status;
2255 }
2256
2257 trace_ide_status_read(addr, ret, bus, s);
2258 return ret;
2259}
2260
2261static void ide_perform_srst(IDEState *s)
2262{
2263 s->status |= BUSY_STAT;
2264
2265
2266 ide_transfer_halt(s);
2267
2268
2269 ide_cancel_dma_sync(s);
2270
2271
2272 ide_reset(s);
2273
2274
2275 cmd_exec_dev_diagnostic(s, WIN_DIAGNOSE);
2276}
2277
2278static void ide_bus_perform_srst(void *opaque)
2279{
2280 IDEBus *bus = opaque;
2281 IDEState *s;
2282 int i;
2283
2284 for (i = 0; i < 2; i++) {
2285 s = &bus->ifs[i];
2286 ide_perform_srst(s);
2287 }
2288
2289 bus->cmd &= ~IDE_CTRL_RESET;
2290}
2291
2292void ide_ctrl_write(void *opaque, uint32_t addr, uint32_t val)
2293{
2294 IDEBus *bus = opaque;
2295 IDEState *s;
2296 int i;
2297
2298 trace_ide_ctrl_write(addr, val, bus);
2299
2300
2301
2302 if (!(bus->cmd & IDE_CTRL_RESET) && (val & IDE_CTRL_RESET)) {
2303 for (i = 0; i < 2; i++) {
2304 s = &bus->ifs[i];
2305 s->status |= BUSY_STAT;
2306 }
2307 replay_bh_schedule_oneshot_event(qemu_get_aio_context(),
2308 ide_bus_perform_srst, bus);
2309 }
2310
2311 bus->cmd = val;
2312}
2313
2314
2315
2316
2317
2318static bool ide_is_pio_out(IDEState *s)
2319{
2320 if (s->end_transfer_func == ide_sector_write ||
2321 s->end_transfer_func == ide_atapi_cmd) {
2322 return false;
2323 } else if (s->end_transfer_func == ide_sector_read ||
2324 s->end_transfer_func == ide_transfer_stop ||
2325 s->end_transfer_func == ide_atapi_cmd_reply_end ||
2326 s->end_transfer_func == ide_dummy_transfer_stop) {
2327 return true;
2328 }
2329
2330 abort();
2331}
2332
2333void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
2334{
2335 IDEBus *bus = opaque;
2336 IDEState *s = idebus_active_if(bus);
2337 uint8_t *p;
2338
2339 trace_ide_data_writew(addr, val, bus, s);
2340
2341
2342
2343 if (!(s->status & DRQ_STAT) || ide_is_pio_out(s)) {
2344 return;
2345 }
2346
2347 p = s->data_ptr;
2348 if (p + 2 > s->data_end) {
2349 return;
2350 }
2351
2352 *(uint16_t *)p = le16_to_cpu(val);
2353 p += 2;
2354 s->data_ptr = p;
2355 if (p >= s->data_end) {
2356 s->status &= ~DRQ_STAT;
2357 s->end_transfer_func(s);
2358 }
2359}
2360
2361uint32_t ide_data_readw(void *opaque, uint32_t addr)
2362{
2363 IDEBus *bus = opaque;
2364 IDEState *s = idebus_active_if(bus);
2365 uint8_t *p;
2366 int ret;
2367
2368
2369
2370 if (!(s->status & DRQ_STAT) || !ide_is_pio_out(s)) {
2371 return 0;
2372 }
2373
2374 p = s->data_ptr;
2375 if (p + 2 > s->data_end) {
2376 return 0;
2377 }
2378
2379 ret = cpu_to_le16(*(uint16_t *)p);
2380 p += 2;
2381 s->data_ptr = p;
2382 if (p >= s->data_end) {
2383 s->status &= ~DRQ_STAT;
2384 s->end_transfer_func(s);
2385 }
2386
2387 trace_ide_data_readw(addr, ret, bus, s);
2388 return ret;
2389}
2390
2391void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
2392{
2393 IDEBus *bus = opaque;
2394 IDEState *s = idebus_active_if(bus);
2395 uint8_t *p;
2396
2397 trace_ide_data_writel(addr, val, bus, s);
2398
2399
2400
2401 if (!(s->status & DRQ_STAT) || ide_is_pio_out(s)) {
2402 return;
2403 }
2404
2405 p = s->data_ptr;
2406 if (p + 4 > s->data_end) {
2407 return;
2408 }
2409
2410 *(uint32_t *)p = le32_to_cpu(val);
2411 p += 4;
2412 s->data_ptr = p;
2413 if (p >= s->data_end) {
2414 s->status &= ~DRQ_STAT;
2415 s->end_transfer_func(s);
2416 }
2417}
2418
2419uint32_t ide_data_readl(void *opaque, uint32_t addr)
2420{
2421 IDEBus *bus = opaque;
2422 IDEState *s = idebus_active_if(bus);
2423 uint8_t *p;
2424 int ret;
2425
2426
2427
2428 if (!(s->status & DRQ_STAT) || !ide_is_pio_out(s)) {
2429 ret = 0;
2430 goto out;
2431 }
2432
2433 p = s->data_ptr;
2434 if (p + 4 > s->data_end) {
2435 return 0;
2436 }
2437
2438 ret = cpu_to_le32(*(uint32_t *)p);
2439 p += 4;
2440 s->data_ptr = p;
2441 if (p >= s->data_end) {
2442 s->status &= ~DRQ_STAT;
2443 s->end_transfer_func(s);
2444 }
2445
2446out:
2447 trace_ide_data_readl(addr, ret, bus, s);
2448 return ret;
2449}
2450
2451static void ide_dummy_transfer_stop(IDEState *s)
2452{
2453 s->data_ptr = s->io_buffer;
2454 s->data_end = s->io_buffer;
2455 s->io_buffer[0] = 0xff;
2456 s->io_buffer[1] = 0xff;
2457 s->io_buffer[2] = 0xff;
2458 s->io_buffer[3] = 0xff;
2459}
2460
2461void ide_bus_reset(IDEBus *bus)
2462{
2463 bus->unit = 0;
2464 bus->cmd = 0;
2465 ide_reset(&bus->ifs[0]);
2466 ide_reset(&bus->ifs[1]);
2467 ide_clear_hob(bus);
2468
2469
2470 if (bus->dma->aiocb) {
2471 trace_ide_bus_reset_aio();
2472 blk_aio_cancel(bus->dma->aiocb);
2473 bus->dma->aiocb = NULL;
2474 }
2475
2476
2477 if (bus->dma->ops->reset) {
2478 bus->dma->ops->reset(bus->dma);
2479 }
2480}
2481
2482static bool ide_cd_is_tray_open(void *opaque)
2483{
2484 return ((IDEState *)opaque)->tray_open;
2485}
2486
2487static bool ide_cd_is_medium_locked(void *opaque)
2488{
2489 return ((IDEState *)opaque)->tray_locked;
2490}
2491
2492static void ide_resize_cb(void *opaque)
2493{
2494 IDEState *s = opaque;
2495 uint64_t nb_sectors;
2496
2497 if (!s->identify_set) {
2498 return;
2499 }
2500
2501 blk_get_geometry(s->blk, &nb_sectors);
2502 s->nb_sectors = nb_sectors;
2503
2504
2505 if (s->drive_kind == IDE_CFATA) {
2506 ide_cfata_identify_size(s);
2507 } else {
2508
2509 assert(s->drive_kind != IDE_CD);
2510 ide_identify_size(s);
2511 }
2512}
2513
2514static const BlockDevOps ide_cd_block_ops = {
2515 .change_media_cb = ide_cd_change_cb,
2516 .eject_request_cb = ide_cd_eject_request_cb,
2517 .is_tray_open = ide_cd_is_tray_open,
2518 .is_medium_locked = ide_cd_is_medium_locked,
2519};
2520
2521static const BlockDevOps ide_hd_block_ops = {
2522 .resize_cb = ide_resize_cb,
2523};
2524
2525int ide_init_drive(IDEState *s, BlockBackend *blk, IDEDriveKind kind,
2526 const char *version, const char *serial, const char *model,
2527 uint64_t wwn,
2528 uint32_t cylinders, uint32_t heads, uint32_t secs,
2529 int chs_trans, Error **errp)
2530{
2531 uint64_t nb_sectors;
2532
2533 s->blk = blk;
2534 s->drive_kind = kind;
2535
2536 blk_get_geometry(blk, &nb_sectors);
2537 s->cylinders = cylinders;
2538 s->heads = heads;
2539 s->sectors = secs;
2540 s->chs_trans = chs_trans;
2541 s->nb_sectors = nb_sectors;
2542 s->wwn = wwn;
2543
2544
2545 s->smart_enabled = 1;
2546 s->smart_autosave = 1;
2547 s->smart_errors = 0;
2548 s->smart_selftest_count = 0;
2549 if (kind == IDE_CD) {
2550 blk_set_dev_ops(blk, &ide_cd_block_ops, s);
2551 } else {
2552 if (!blk_is_inserted(s->blk)) {
2553 error_setg(errp, "Device needs media, but drive is empty");
2554 return -1;
2555 }
2556 if (!blk_is_writable(blk)) {
2557 error_setg(errp, "Can't use a read-only drive");
2558 return -1;
2559 }
2560 blk_set_dev_ops(blk, &ide_hd_block_ops, s);
2561 }
2562 if (serial) {
2563 pstrcpy(s->drive_serial_str, sizeof(s->drive_serial_str), serial);
2564 } else {
2565 snprintf(s->drive_serial_str, sizeof(s->drive_serial_str),
2566 "QM%05d", s->drive_serial);
2567 }
2568 if (model) {
2569 pstrcpy(s->drive_model_str, sizeof(s->drive_model_str), model);
2570 } else {
2571 switch (kind) {
2572 case IDE_CD:
2573 strcpy(s->drive_model_str, "QEMU DVD-ROM");
2574 break;
2575 case IDE_CFATA:
2576 strcpy(s->drive_model_str, "QEMU MICRODRIVE");
2577 break;
2578 default:
2579 strcpy(s->drive_model_str, "QEMU HARDDISK");
2580 break;
2581 }
2582 }
2583
2584 if (version) {
2585 pstrcpy(s->version, sizeof(s->version), version);
2586 } else {
2587 pstrcpy(s->version, sizeof(s->version), qemu_hw_version());
2588 }
2589
2590 ide_reset(s);
2591 blk_iostatus_enable(blk);
2592 return 0;
2593}
2594
2595static void ide_init1(IDEBus *bus, int unit)
2596{
2597 static int drive_serial = 1;
2598 IDEState *s = &bus->ifs[unit];
2599
2600 s->bus = bus;
2601 s->unit = unit;
2602 s->drive_serial = drive_serial++;
2603
2604 s->io_buffer_total_len = IDE_DMA_BUF_SECTORS*512 + 4;
2605 s->io_buffer = qemu_memalign(2048, s->io_buffer_total_len);
2606 memset(s->io_buffer, 0, s->io_buffer_total_len);
2607
2608 s->smart_selftest_data = blk_blockalign(s->blk, 512);
2609 memset(s->smart_selftest_data, 0, 512);
2610
2611 s->sector_write_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
2612 ide_sector_write_timer_cb, s);
2613}
2614
2615static int ide_nop_int(const IDEDMA *dma, bool is_write)
2616{
2617 return 0;
2618}
2619
2620static void ide_nop(const IDEDMA *dma)
2621{
2622}
2623
2624static int32_t ide_nop_int32(const IDEDMA *dma, int32_t l)
2625{
2626 return 0;
2627}
2628
2629static const IDEDMAOps ide_dma_nop_ops = {
2630 .prepare_buf = ide_nop_int32,
2631 .restart_dma = ide_nop,
2632 .rw_buf = ide_nop_int,
2633};
2634
2635static void ide_restart_dma(IDEState *s, enum ide_dma_cmd dma_cmd)
2636{
2637 s->unit = s->bus->retry_unit;
2638 ide_set_sector(s, s->bus->retry_sector_num);
2639 s->nsector = s->bus->retry_nsector;
2640 s->bus->dma->ops->restart_dma(s->bus->dma);
2641 s->io_buffer_size = 0;
2642 s->dma_cmd = dma_cmd;
2643 ide_start_dma(s, ide_dma_cb);
2644}
2645
2646static void ide_restart_bh(void *opaque)
2647{
2648 IDEBus *bus = opaque;
2649 IDEState *s;
2650 bool is_read;
2651 int error_status;
2652
2653 qemu_bh_delete(bus->bh);
2654 bus->bh = NULL;
2655
2656 error_status = bus->error_status;
2657 if (bus->error_status == 0) {
2658 return;
2659 }
2660
2661 s = idebus_active_if(bus);
2662 is_read = (bus->error_status & IDE_RETRY_READ) != 0;
2663
2664
2665
2666
2667 bus->error_status = 0;
2668
2669
2670 if (error_status & IDE_RETRY_HBA) {
2671 if (s->bus->dma->ops->restart) {
2672 s->bus->dma->ops->restart(s->bus->dma);
2673 }
2674 } else if (IS_IDE_RETRY_DMA(error_status)) {
2675 if (error_status & IDE_RETRY_TRIM) {
2676 ide_restart_dma(s, IDE_DMA_TRIM);
2677 } else {
2678 ide_restart_dma(s, is_read ? IDE_DMA_READ : IDE_DMA_WRITE);
2679 }
2680 } else if (IS_IDE_RETRY_PIO(error_status)) {
2681 if (is_read) {
2682 ide_sector_read(s);
2683 } else {
2684 ide_sector_write(s);
2685 }
2686 } else if (error_status & IDE_RETRY_FLUSH) {
2687 ide_flush_cache(s);
2688 } else if (IS_IDE_RETRY_ATAPI(error_status)) {
2689 assert(s->end_transfer_func == ide_atapi_cmd);
2690 ide_atapi_dma_restart(s);
2691 } else {
2692 abort();
2693 }
2694}
2695
2696static void ide_restart_cb(void *opaque, bool running, RunState state)
2697{
2698 IDEBus *bus = opaque;
2699
2700 if (!running)
2701 return;
2702
2703 if (!bus->bh) {
2704 bus->bh = qemu_bh_new(ide_restart_bh, bus);
2705 qemu_bh_schedule(bus->bh);
2706 }
2707}
2708
2709void ide_register_restart_cb(IDEBus *bus)
2710{
2711 if (bus->dma->ops->restart_dma) {
2712 bus->vmstate = qemu_add_vm_change_state_handler(ide_restart_cb, bus);
2713 }
2714}
2715
2716static IDEDMA ide_dma_nop = {
2717 .ops = &ide_dma_nop_ops,
2718 .aiocb = NULL,
2719};
2720
2721void ide_init2(IDEBus *bus, qemu_irq irq)
2722{
2723 int i;
2724
2725 for(i = 0; i < 2; i++) {
2726 ide_init1(bus, i);
2727 ide_reset(&bus->ifs[i]);
2728 }
2729 bus->irq = irq;
2730 bus->dma = &ide_dma_nop;
2731}
2732
2733void ide_exit(IDEState *s)
2734{
2735 timer_free(s->sector_write_timer);
2736 qemu_vfree(s->smart_selftest_data);
2737 qemu_vfree(s->io_buffer);
2738}
2739
2740static bool is_identify_set(void *opaque, int version_id)
2741{
2742 IDEState *s = opaque;
2743
2744 return s->identify_set != 0;
2745}
2746
2747static EndTransferFunc* transfer_end_table[] = {
2748 ide_sector_read,
2749 ide_sector_write,
2750 ide_transfer_stop,
2751 ide_atapi_cmd_reply_end,
2752 ide_atapi_cmd,
2753 ide_dummy_transfer_stop,
2754};
2755
2756static int transfer_end_table_idx(EndTransferFunc *fn)
2757{
2758 int i;
2759
2760 for (i = 0; i < ARRAY_SIZE(transfer_end_table); i++)
2761 if (transfer_end_table[i] == fn)
2762 return i;
2763
2764 return -1;
2765}
2766
2767static int ide_drive_post_load(void *opaque, int version_id)
2768{
2769 IDEState *s = opaque;
2770
2771 if (s->blk && s->identify_set) {
2772 blk_set_enable_write_cache(s->blk, !!(s->identify_data[85] & (1 << 5)));
2773 }
2774 return 0;
2775}
2776
2777static int ide_drive_pio_post_load(void *opaque, int version_id)
2778{
2779 IDEState *s = opaque;
2780
2781 if (s->end_transfer_fn_idx >= ARRAY_SIZE(transfer_end_table)) {
2782 return -EINVAL;
2783 }
2784 s->end_transfer_func = transfer_end_table[s->end_transfer_fn_idx];
2785 s->data_ptr = s->io_buffer + s->cur_io_buffer_offset;
2786 s->data_end = s->data_ptr + s->cur_io_buffer_len;
2787 s->atapi_dma = s->feature & 1;
2788
2789 return 0;
2790}
2791
2792static int ide_drive_pio_pre_save(void *opaque)
2793{
2794 IDEState *s = opaque;
2795 int idx;
2796
2797 s->cur_io_buffer_offset = s->data_ptr - s->io_buffer;
2798 s->cur_io_buffer_len = s->data_end - s->data_ptr;
2799
2800 idx = transfer_end_table_idx(s->end_transfer_func);
2801 if (idx == -1) {
2802 fprintf(stderr, "%s: invalid end_transfer_func for DRQ_STAT\n",
2803 __func__);
2804 s->end_transfer_fn_idx = 2;
2805 } else {
2806 s->end_transfer_fn_idx = idx;
2807 }
2808
2809 return 0;
2810}
2811
2812static bool ide_drive_pio_state_needed(void *opaque)
2813{
2814 IDEState *s = opaque;
2815
2816 return ((s->status & DRQ_STAT) != 0)
2817 || (s->bus->error_status & IDE_RETRY_PIO);
2818}
2819
2820static bool ide_tray_state_needed(void *opaque)
2821{
2822 IDEState *s = opaque;
2823
2824 return s->tray_open || s->tray_locked;
2825}
2826
2827static bool ide_atapi_gesn_needed(void *opaque)
2828{
2829 IDEState *s = opaque;
2830
2831 return s->events.new_media || s->events.eject_request;
2832}
2833
2834static bool ide_error_needed(void *opaque)
2835{
2836 IDEBus *bus = opaque;
2837
2838 return (bus->error_status != 0);
2839}
2840
2841
2842static const VMStateDescription vmstate_ide_atapi_gesn_state = {
2843 .name ="ide_drive/atapi/gesn_state",
2844 .version_id = 1,
2845 .minimum_version_id = 1,
2846 .needed = ide_atapi_gesn_needed,
2847 .fields = (VMStateField[]) {
2848 VMSTATE_BOOL(events.new_media, IDEState),
2849 VMSTATE_BOOL(events.eject_request, IDEState),
2850 VMSTATE_END_OF_LIST()
2851 }
2852};
2853
2854static const VMStateDescription vmstate_ide_tray_state = {
2855 .name = "ide_drive/tray_state",
2856 .version_id = 1,
2857 .minimum_version_id = 1,
2858 .needed = ide_tray_state_needed,
2859 .fields = (VMStateField[]) {
2860 VMSTATE_BOOL(tray_open, IDEState),
2861 VMSTATE_BOOL(tray_locked, IDEState),
2862 VMSTATE_END_OF_LIST()
2863 }
2864};
2865
2866static const VMStateDescription vmstate_ide_drive_pio_state = {
2867 .name = "ide_drive/pio_state",
2868 .version_id = 1,
2869 .minimum_version_id = 1,
2870 .pre_save = ide_drive_pio_pre_save,
2871 .post_load = ide_drive_pio_post_load,
2872 .needed = ide_drive_pio_state_needed,
2873 .fields = (VMStateField[]) {
2874 VMSTATE_INT32(req_nb_sectors, IDEState),
2875 VMSTATE_VARRAY_INT32(io_buffer, IDEState, io_buffer_total_len, 1,
2876 vmstate_info_uint8, uint8_t),
2877 VMSTATE_INT32(cur_io_buffer_offset, IDEState),
2878 VMSTATE_INT32(cur_io_buffer_len, IDEState),
2879 VMSTATE_UINT8(end_transfer_fn_idx, IDEState),
2880 VMSTATE_INT32(elementary_transfer_size, IDEState),
2881 VMSTATE_INT32(packet_transfer_size, IDEState),
2882 VMSTATE_END_OF_LIST()
2883 }
2884};
2885
2886const VMStateDescription vmstate_ide_drive = {
2887 .name = "ide_drive",
2888 .version_id = 3,
2889 .minimum_version_id = 0,
2890 .post_load = ide_drive_post_load,
2891 .fields = (VMStateField[]) {
2892 VMSTATE_INT32(mult_sectors, IDEState),
2893 VMSTATE_INT32(identify_set, IDEState),
2894 VMSTATE_BUFFER_TEST(identify_data, IDEState, is_identify_set),
2895 VMSTATE_UINT8(feature, IDEState),
2896 VMSTATE_UINT8(error, IDEState),
2897 VMSTATE_UINT32(nsector, IDEState),
2898 VMSTATE_UINT8(sector, IDEState),
2899 VMSTATE_UINT8(lcyl, IDEState),
2900 VMSTATE_UINT8(hcyl, IDEState),
2901 VMSTATE_UINT8(hob_feature, IDEState),
2902 VMSTATE_UINT8(hob_sector, IDEState),
2903 VMSTATE_UINT8(hob_nsector, IDEState),
2904 VMSTATE_UINT8(hob_lcyl, IDEState),
2905 VMSTATE_UINT8(hob_hcyl, IDEState),
2906 VMSTATE_UINT8(select, IDEState),
2907 VMSTATE_UINT8(status, IDEState),
2908 VMSTATE_UINT8(lba48, IDEState),
2909 VMSTATE_UINT8(sense_key, IDEState),
2910 VMSTATE_UINT8(asc, IDEState),
2911 VMSTATE_UINT8_V(cdrom_changed, IDEState, 3),
2912 VMSTATE_END_OF_LIST()
2913 },
2914 .subsections = (const VMStateDescription*[]) {
2915 &vmstate_ide_drive_pio_state,
2916 &vmstate_ide_tray_state,
2917 &vmstate_ide_atapi_gesn_state,
2918 NULL
2919 }
2920};
2921
2922static const VMStateDescription vmstate_ide_error_status = {
2923 .name ="ide_bus/error",
2924 .version_id = 2,
2925 .minimum_version_id = 1,
2926 .needed = ide_error_needed,
2927 .fields = (VMStateField[]) {
2928 VMSTATE_INT32(error_status, IDEBus),
2929 VMSTATE_INT64_V(retry_sector_num, IDEBus, 2),
2930 VMSTATE_UINT32_V(retry_nsector, IDEBus, 2),
2931 VMSTATE_UINT8_V(retry_unit, IDEBus, 2),
2932 VMSTATE_END_OF_LIST()
2933 }
2934};
2935
2936const VMStateDescription vmstate_ide_bus = {
2937 .name = "ide_bus",
2938 .version_id = 1,
2939 .minimum_version_id = 1,
2940 .fields = (VMStateField[]) {
2941 VMSTATE_UINT8(cmd, IDEBus),
2942 VMSTATE_UINT8(unit, IDEBus),
2943 VMSTATE_END_OF_LIST()
2944 },
2945 .subsections = (const VMStateDescription*[]) {
2946 &vmstate_ide_error_status,
2947 NULL
2948 }
2949};
2950
2951void ide_drive_get(DriveInfo **hd, int n)
2952{
2953 int i;
2954
2955 for (i = 0; i < n; i++) {
2956 hd[i] = drive_get_by_index(IF_IDE, i);
2957 }
2958}
2959