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