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