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