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