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