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 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 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,
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 | BUSY_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 s->pio_aiocb = blk_aio_flush(s->blk, ide_flush_cb, s);
1067}
1068
1069static void ide_cfata_metadata_inquiry(IDEState *s)
1070{
1071 uint16_t *p;
1072 uint32_t spd;
1073
1074 p = (uint16_t *) s->io_buffer;
1075 memset(p, 0, 0x200);
1076 spd = ((s->mdata_size - 1) >> 9) + 1;
1077
1078 put_le16(p + 0, 0x0001);
1079 put_le16(p + 1, 0x0000);
1080 put_le16(p + 2, s->media_changed);
1081 put_le16(p + 3, s->mdata_size & 0xffff);
1082 put_le16(p + 4, s->mdata_size >> 16);
1083 put_le16(p + 5, spd & 0xffff);
1084 put_le16(p + 6, spd >> 16);
1085}
1086
1087static void ide_cfata_metadata_read(IDEState *s)
1088{
1089 uint16_t *p;
1090
1091 if (((s->hcyl << 16) | s->lcyl) << 9 > s->mdata_size + 2) {
1092 s->status = ERR_STAT;
1093 s->error = ABRT_ERR;
1094 return;
1095 }
1096
1097 p = (uint16_t *) s->io_buffer;
1098 memset(p, 0, 0x200);
1099
1100 put_le16(p + 0, s->media_changed);
1101 memcpy(p + 1, s->mdata_storage + (((s->hcyl << 16) | s->lcyl) << 9),
1102 MIN(MIN(s->mdata_size - (((s->hcyl << 16) | s->lcyl) << 9),
1103 s->nsector << 9), 0x200 - 2));
1104}
1105
1106static void ide_cfata_metadata_write(IDEState *s)
1107{
1108 if (((s->hcyl << 16) | s->lcyl) << 9 > s->mdata_size + 2) {
1109 s->status = ERR_STAT;
1110 s->error = ABRT_ERR;
1111 return;
1112 }
1113
1114 s->media_changed = 0;
1115
1116 memcpy(s->mdata_storage + (((s->hcyl << 16) | s->lcyl) << 9),
1117 s->io_buffer + 2,
1118 MIN(MIN(s->mdata_size - (((s->hcyl << 16) | s->lcyl) << 9),
1119 s->nsector << 9), 0x200 - 2));
1120}
1121
1122
1123static void ide_cd_change_cb(void *opaque, bool load)
1124{
1125 IDEState *s = opaque;
1126 uint64_t nb_sectors;
1127
1128 s->tray_open = !load;
1129 blk_get_geometry(s->blk, &nb_sectors);
1130 s->nb_sectors = nb_sectors;
1131
1132
1133
1134
1135
1136
1137
1138
1139 s->cdrom_changed = 1;
1140 s->events.new_media = true;
1141 s->events.eject_request = false;
1142 ide_set_irq(s->bus);
1143}
1144
1145static void ide_cd_eject_request_cb(void *opaque, bool force)
1146{
1147 IDEState *s = opaque;
1148
1149 s->events.eject_request = true;
1150 if (force) {
1151 s->tray_locked = false;
1152 }
1153 ide_set_irq(s->bus);
1154}
1155
1156static void ide_cmd_lba48_transform(IDEState *s, int lba48)
1157{
1158 s->lba48 = lba48;
1159
1160
1161
1162
1163
1164 if (!s->lba48) {
1165 if (!s->nsector)
1166 s->nsector = 256;
1167 } else {
1168 if (!s->nsector && !s->hob_nsector)
1169 s->nsector = 65536;
1170 else {
1171 int lo = s->nsector;
1172 int hi = s->hob_nsector;
1173
1174 s->nsector = (hi << 8) | lo;
1175 }
1176 }
1177}
1178
1179static void ide_clear_hob(IDEBus *bus)
1180{
1181
1182 bus->ifs[0].select &= ~(1 << 7);
1183 bus->ifs[1].select &= ~(1 << 7);
1184}
1185
1186void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1187{
1188 IDEBus *bus = opaque;
1189
1190#ifdef DEBUG_IDE
1191 printf("IDE: write addr=0x%x val=0x%02x\n", addr, val);
1192#endif
1193
1194 addr &= 7;
1195
1196
1197 if (addr != 7 && (idebus_active_if(bus)->status & (BUSY_STAT|DRQ_STAT)))
1198 return;
1199
1200 switch(addr) {
1201 case 0:
1202 break;
1203 case 1:
1204 ide_clear_hob(bus);
1205
1206 bus->ifs[0].hob_feature = bus->ifs[0].feature;
1207 bus->ifs[1].hob_feature = bus->ifs[1].feature;
1208 bus->ifs[0].feature = val;
1209 bus->ifs[1].feature = val;
1210 break;
1211 case 2:
1212 ide_clear_hob(bus);
1213 bus->ifs[0].hob_nsector = bus->ifs[0].nsector;
1214 bus->ifs[1].hob_nsector = bus->ifs[1].nsector;
1215 bus->ifs[0].nsector = val;
1216 bus->ifs[1].nsector = val;
1217 break;
1218 case 3:
1219 ide_clear_hob(bus);
1220 bus->ifs[0].hob_sector = bus->ifs[0].sector;
1221 bus->ifs[1].hob_sector = bus->ifs[1].sector;
1222 bus->ifs[0].sector = val;
1223 bus->ifs[1].sector = val;
1224 break;
1225 case 4:
1226 ide_clear_hob(bus);
1227 bus->ifs[0].hob_lcyl = bus->ifs[0].lcyl;
1228 bus->ifs[1].hob_lcyl = bus->ifs[1].lcyl;
1229 bus->ifs[0].lcyl = val;
1230 bus->ifs[1].lcyl = val;
1231 break;
1232 case 5:
1233 ide_clear_hob(bus);
1234 bus->ifs[0].hob_hcyl = bus->ifs[0].hcyl;
1235 bus->ifs[1].hob_hcyl = bus->ifs[1].hcyl;
1236 bus->ifs[0].hcyl = val;
1237 bus->ifs[1].hcyl = val;
1238 break;
1239 case 6:
1240
1241 bus->ifs[0].select = (val & ~0x10) | 0xa0;
1242 bus->ifs[1].select = (val | 0x10) | 0xa0;
1243
1244 bus->unit = (val >> 4) & 1;
1245 break;
1246 default:
1247 case 7:
1248
1249 ide_exec_cmd(bus, val);
1250 break;
1251 }
1252}
1253
1254static void ide_reset(IDEState *s)
1255{
1256#ifdef DEBUG_IDE
1257 printf("ide: reset\n");
1258#endif
1259
1260 if (s->pio_aiocb) {
1261 blk_aio_cancel(s->pio_aiocb);
1262 s->pio_aiocb = NULL;
1263 }
1264
1265 if (s->drive_kind == IDE_CFATA)
1266 s->mult_sectors = 0;
1267 else
1268 s->mult_sectors = MAX_MULT_SECTORS;
1269
1270 s->feature = 0;
1271 s->error = 0;
1272 s->nsector = 0;
1273 s->sector = 0;
1274 s->lcyl = 0;
1275 s->hcyl = 0;
1276
1277
1278 s->hob_feature = 0;
1279 s->hob_sector = 0;
1280 s->hob_nsector = 0;
1281 s->hob_lcyl = 0;
1282 s->hob_hcyl = 0;
1283
1284 s->select = 0xa0;
1285 s->status = READY_STAT | SEEK_STAT;
1286
1287 s->lba48 = 0;
1288
1289
1290 s->sense_key = 0;
1291 s->asc = 0;
1292 s->cdrom_changed = 0;
1293 s->packet_transfer_size = 0;
1294 s->elementary_transfer_size = 0;
1295 s->io_buffer_index = 0;
1296 s->cd_sector_size = 0;
1297 s->atapi_dma = 0;
1298 s->tray_locked = 0;
1299 s->tray_open = 0;
1300
1301 s->io_buffer_size = 0;
1302 s->req_nb_sectors = 0;
1303
1304 ide_set_signature(s);
1305
1306
1307 s->end_transfer_func = ide_dummy_transfer_stop;
1308 ide_dummy_transfer_stop(s);
1309 s->media_changed = 0;
1310}
1311
1312static bool cmd_nop(IDEState *s, uint8_t cmd)
1313{
1314 return true;
1315}
1316
1317static bool cmd_device_reset(IDEState *s, uint8_t cmd)
1318{
1319
1320 ide_transfer_cancel(s);
1321 ide_cancel_dma_sync(s);
1322
1323
1324 ide_reset(s);
1325
1326
1327
1328 s->status = 0x00;
1329
1330
1331 return false;
1332}
1333
1334static bool cmd_data_set_management(IDEState *s, uint8_t cmd)
1335{
1336 switch (s->feature) {
1337 case DSM_TRIM:
1338 if (s->blk) {
1339 ide_sector_start_dma(s, IDE_DMA_TRIM);
1340 return false;
1341 }
1342 break;
1343 }
1344
1345 ide_abort_command(s);
1346 return true;
1347}
1348
1349static bool cmd_identify(IDEState *s, uint8_t cmd)
1350{
1351 if (s->blk && s->drive_kind != IDE_CD) {
1352 if (s->drive_kind != IDE_CFATA) {
1353 ide_identify(s);
1354 } else {
1355 ide_cfata_identify(s);
1356 }
1357 s->status = READY_STAT | SEEK_STAT;
1358 ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
1359 ide_set_irq(s->bus);
1360 return false;
1361 } else {
1362 if (s->drive_kind == IDE_CD) {
1363 ide_set_signature(s);
1364 }
1365 ide_abort_command(s);
1366 }
1367
1368 return true;
1369}
1370
1371static bool cmd_verify(IDEState *s, uint8_t cmd)
1372{
1373 bool lba48 = (cmd == WIN_VERIFY_EXT);
1374
1375
1376 ide_cmd_lba48_transform(s, lba48);
1377
1378 return true;
1379}
1380
1381static bool cmd_set_multiple_mode(IDEState *s, uint8_t cmd)
1382{
1383 if (s->drive_kind == IDE_CFATA && s->nsector == 0) {
1384
1385 s->mult_sectors = 0;
1386 } else if ((s->nsector & 0xff) != 0 &&
1387 ((s->nsector & 0xff) > MAX_MULT_SECTORS ||
1388 (s->nsector & (s->nsector - 1)) != 0)) {
1389 ide_abort_command(s);
1390 } else {
1391 s->mult_sectors = s->nsector & 0xff;
1392 }
1393
1394 return true;
1395}
1396
1397static bool cmd_read_multiple(IDEState *s, uint8_t cmd)
1398{
1399 bool lba48 = (cmd == WIN_MULTREAD_EXT);
1400
1401 if (!s->blk || !s->mult_sectors) {
1402 ide_abort_command(s);
1403 return true;
1404 }
1405
1406 ide_cmd_lba48_transform(s, lba48);
1407 s->req_nb_sectors = s->mult_sectors;
1408 ide_sector_read(s);
1409 return false;
1410}
1411
1412static bool cmd_write_multiple(IDEState *s, uint8_t cmd)
1413{
1414 bool lba48 = (cmd == WIN_MULTWRITE_EXT);
1415 int n;
1416
1417 if (!s->blk || !s->mult_sectors) {
1418 ide_abort_command(s);
1419 return true;
1420 }
1421
1422 ide_cmd_lba48_transform(s, lba48);
1423
1424 s->req_nb_sectors = s->mult_sectors;
1425 n = MIN(s->nsector, s->req_nb_sectors);
1426
1427 s->status = SEEK_STAT | READY_STAT;
1428 ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
1429
1430 s->media_changed = 1;
1431
1432 return false;
1433}
1434
1435static bool cmd_read_pio(IDEState *s, uint8_t cmd)
1436{
1437 bool lba48 = (cmd == WIN_READ_EXT);
1438
1439 if (s->drive_kind == IDE_CD) {
1440 ide_set_signature(s);
1441 ide_abort_command(s);
1442 return true;
1443 }
1444
1445 if (!s->blk) {
1446 ide_abort_command(s);
1447 return true;
1448 }
1449
1450 ide_cmd_lba48_transform(s, lba48);
1451 s->req_nb_sectors = 1;
1452 ide_sector_read(s);
1453
1454 return false;
1455}
1456
1457static bool cmd_write_pio(IDEState *s, uint8_t cmd)
1458{
1459 bool lba48 = (cmd == WIN_WRITE_EXT);
1460
1461 if (!s->blk) {
1462 ide_abort_command(s);
1463 return true;
1464 }
1465
1466 ide_cmd_lba48_transform(s, lba48);
1467
1468 s->req_nb_sectors = 1;
1469 s->status = SEEK_STAT | READY_STAT;
1470 ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
1471
1472 s->media_changed = 1;
1473
1474 return false;
1475}
1476
1477static bool cmd_read_dma(IDEState *s, uint8_t cmd)
1478{
1479 bool lba48 = (cmd == WIN_READDMA_EXT);
1480
1481 if (!s->blk) {
1482 ide_abort_command(s);
1483 return true;
1484 }
1485
1486 ide_cmd_lba48_transform(s, lba48);
1487 ide_sector_start_dma(s, IDE_DMA_READ);
1488
1489 return false;
1490}
1491
1492static bool cmd_write_dma(IDEState *s, uint8_t cmd)
1493{
1494 bool lba48 = (cmd == WIN_WRITEDMA_EXT);
1495
1496 if (!s->blk) {
1497 ide_abort_command(s);
1498 return true;
1499 }
1500
1501 ide_cmd_lba48_transform(s, lba48);
1502 ide_sector_start_dma(s, IDE_DMA_WRITE);
1503
1504 s->media_changed = 1;
1505
1506 return false;
1507}
1508
1509static bool cmd_flush_cache(IDEState *s, uint8_t cmd)
1510{
1511 ide_flush_cache(s);
1512 return false;
1513}
1514
1515static bool cmd_seek(IDEState *s, uint8_t cmd)
1516{
1517
1518 return true;
1519}
1520
1521static bool cmd_read_native_max(IDEState *s, uint8_t cmd)
1522{
1523 bool lba48 = (cmd == WIN_READ_NATIVE_MAX_EXT);
1524
1525
1526 if (s->nb_sectors == 0) {
1527 ide_abort_command(s);
1528 return true;
1529 }
1530
1531 ide_cmd_lba48_transform(s, lba48);
1532 ide_set_sector(s, s->nb_sectors - 1);
1533
1534 return true;
1535}
1536
1537static bool cmd_check_power_mode(IDEState *s, uint8_t cmd)
1538{
1539 s->nsector = 0xff;
1540 return true;
1541}
1542
1543static bool cmd_set_features(IDEState *s, uint8_t cmd)
1544{
1545 uint16_t *identify_data;
1546
1547 if (!s->blk) {
1548 ide_abort_command(s);
1549 return true;
1550 }
1551
1552
1553 switch (s->feature) {
1554 case 0x02:
1555 blk_set_enable_write_cache(s->blk, true);
1556 identify_data = (uint16_t *)s->identify_data;
1557 put_le16(identify_data + 85, (1 << 14) | (1 << 5) | 1);
1558 return true;
1559 case 0x82:
1560 blk_set_enable_write_cache(s->blk, false);
1561 identify_data = (uint16_t *)s->identify_data;
1562 put_le16(identify_data + 85, (1 << 14) | 1);
1563 ide_flush_cache(s);
1564 return false;
1565 case 0xcc:
1566 case 0x66:
1567 case 0xaa:
1568 case 0x55:
1569 case 0x05:
1570 case 0x85:
1571 case 0x69:
1572 case 0x67:
1573 case 0x96:
1574 case 0x9a:
1575 case 0x42:
1576 case 0xc2:
1577 return true;
1578 case 0x03:
1579 {
1580 uint8_t val = s->nsector & 0x07;
1581 identify_data = (uint16_t *)s->identify_data;
1582
1583 switch (s->nsector >> 3) {
1584 case 0x00:
1585 case 0x01:
1586 put_le16(identify_data + 62, 0x07);
1587 put_le16(identify_data + 63, 0x07);
1588 put_le16(identify_data + 88, 0x3f);
1589 break;
1590 case 0x02:
1591 put_le16(identify_data + 62, 0x07 | (1 << (val + 8)));
1592 put_le16(identify_data + 63, 0x07);
1593 put_le16(identify_data + 88, 0x3f);
1594 break;
1595 case 0x04:
1596 put_le16(identify_data + 62, 0x07);
1597 put_le16(identify_data + 63, 0x07 | (1 << (val + 8)));
1598 put_le16(identify_data + 88, 0x3f);
1599 break;
1600 case 0x08:
1601 put_le16(identify_data + 62, 0x07);
1602 put_le16(identify_data + 63, 0x07);
1603 put_le16(identify_data + 88, 0x3f | (1 << (val + 8)));
1604 break;
1605 default:
1606 goto abort_cmd;
1607 }
1608 return true;
1609 }
1610 }
1611
1612abort_cmd:
1613 ide_abort_command(s);
1614 return true;
1615}
1616
1617
1618
1619
1620static bool cmd_identify_packet(IDEState *s, uint8_t cmd)
1621{
1622 ide_atapi_identify(s);
1623 s->status = READY_STAT | SEEK_STAT;
1624 ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
1625 ide_set_irq(s->bus);
1626 return false;
1627}
1628
1629static bool cmd_exec_dev_diagnostic(IDEState *s, uint8_t cmd)
1630{
1631 ide_set_signature(s);
1632
1633 if (s->drive_kind == IDE_CD) {
1634 s->status = 0;
1635
1636
1637 s->error = 0x01;
1638 } else {
1639 s->status = READY_STAT | SEEK_STAT;
1640
1641
1642
1643 s->error = 0x01;
1644 ide_set_irq(s->bus);
1645 }
1646
1647 return false;
1648}
1649
1650static bool cmd_packet(IDEState *s, uint8_t cmd)
1651{
1652
1653 if (s->feature & 0x02) {
1654 ide_abort_command(s);
1655 return true;
1656 }
1657
1658 s->status = READY_STAT | SEEK_STAT;
1659 s->atapi_dma = s->feature & 1;
1660 if (s->atapi_dma) {
1661 s->dma_cmd = IDE_DMA_ATAPI;
1662 }
1663 s->nsector = 1;
1664 ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,
1665 ide_atapi_cmd);
1666 return false;
1667}
1668
1669
1670
1671
1672static bool cmd_cfa_req_ext_error_code(IDEState *s, uint8_t cmd)
1673{
1674 s->error = 0x09;
1675 s->status = READY_STAT | SEEK_STAT;
1676 ide_set_irq(s->bus);
1677
1678 return false;
1679}
1680
1681static bool cmd_cfa_erase_sectors(IDEState *s, uint8_t cmd)
1682{
1683
1684
1685
1686 if (cmd == CFA_WEAR_LEVEL) {
1687 s->nsector = 0;
1688 }
1689
1690 if (cmd == CFA_ERASE_SECTORS) {
1691 s->media_changed = 1;
1692 }
1693
1694 return true;
1695}
1696
1697static bool cmd_cfa_translate_sector(IDEState *s, uint8_t cmd)
1698{
1699 s->status = READY_STAT | SEEK_STAT;
1700
1701 memset(s->io_buffer, 0, 0x200);
1702 s->io_buffer[0x00] = s->hcyl;
1703 s->io_buffer[0x01] = s->lcyl;
1704 s->io_buffer[0x02] = s->select;
1705 s->io_buffer[0x03] = s->sector;
1706 s->io_buffer[0x04] = ide_get_sector(s) >> 16;
1707 s->io_buffer[0x05] = ide_get_sector(s) >> 8;
1708 s->io_buffer[0x06] = ide_get_sector(s) >> 0;
1709 s->io_buffer[0x13] = 0x00;
1710 s->io_buffer[0x18] = 0x00;
1711 s->io_buffer[0x19] = 0x00;
1712 s->io_buffer[0x1a] = 0x01;
1713
1714 ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1715 ide_set_irq(s->bus);
1716
1717 return false;
1718}
1719
1720static bool cmd_cfa_access_metadata_storage(IDEState *s, uint8_t cmd)
1721{
1722 switch (s->feature) {
1723 case 0x02:
1724 ide_cfata_metadata_inquiry(s);
1725 break;
1726 case 0x03:
1727 ide_cfata_metadata_read(s);
1728 break;
1729 case 0x04:
1730 ide_cfata_metadata_write(s);
1731 break;
1732 default:
1733 ide_abort_command(s);
1734 return true;
1735 }
1736
1737 ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1738 s->status = 0x00;
1739 ide_set_irq(s->bus);
1740
1741 return false;
1742}
1743
1744static bool cmd_ibm_sense_condition(IDEState *s, uint8_t cmd)
1745{
1746 switch (s->feature) {
1747 case 0x01:
1748 s->nsector = 0x50;
1749 break;
1750 default:
1751 ide_abort_command(s);
1752 return true;
1753 }
1754
1755 return true;
1756}
1757
1758
1759
1760
1761static bool cmd_smart(IDEState *s, uint8_t cmd)
1762{
1763 int n;
1764
1765 if (s->hcyl != 0xc2 || s->lcyl != 0x4f) {
1766 goto abort_cmd;
1767 }
1768
1769 if (!s->smart_enabled && s->feature != SMART_ENABLE) {
1770 goto abort_cmd;
1771 }
1772
1773 switch (s->feature) {
1774 case SMART_DISABLE:
1775 s->smart_enabled = 0;
1776 return true;
1777
1778 case SMART_ENABLE:
1779 s->smart_enabled = 1;
1780 return true;
1781
1782 case SMART_ATTR_AUTOSAVE:
1783 switch (s->sector) {
1784 case 0x00:
1785 s->smart_autosave = 0;
1786 break;
1787 case 0xf1:
1788 s->smart_autosave = 1;
1789 break;
1790 default:
1791 goto abort_cmd;
1792 }
1793 return true;
1794
1795 case SMART_STATUS:
1796 if (!s->smart_errors) {
1797 s->hcyl = 0xc2;
1798 s->lcyl = 0x4f;
1799 } else {
1800 s->hcyl = 0x2c;
1801 s->lcyl = 0xf4;
1802 }
1803 return true;
1804
1805 case SMART_READ_THRESH:
1806 memset(s->io_buffer, 0, 0x200);
1807 s->io_buffer[0] = 0x01;
1808
1809 for (n = 0; n < ARRAY_SIZE(smart_attributes); n++) {
1810 s->io_buffer[2 + 0 + (n * 12)] = smart_attributes[n][0];
1811 s->io_buffer[2 + 1 + (n * 12)] = smart_attributes[n][11];
1812 }
1813
1814
1815 for (n = 0; n < 511; n++) {
1816 s->io_buffer[511] += s->io_buffer[n];
1817 }
1818 s->io_buffer[511] = 0x100 - s->io_buffer[511];
1819
1820 s->status = READY_STAT | SEEK_STAT;
1821 ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1822 ide_set_irq(s->bus);
1823 return false;
1824
1825 case SMART_READ_DATA:
1826 memset(s->io_buffer, 0, 0x200);
1827 s->io_buffer[0] = 0x01;
1828
1829 for (n = 0; n < ARRAY_SIZE(smart_attributes); n++) {
1830 int i;
1831 for (i = 0; i < 11; i++) {
1832 s->io_buffer[2 + i + (n * 12)] = smart_attributes[n][i];
1833 }
1834 }
1835
1836 s->io_buffer[362] = 0x02 | (s->smart_autosave ? 0x80 : 0x00);
1837 if (s->smart_selftest_count == 0) {
1838 s->io_buffer[363] = 0;
1839 } else {
1840 s->io_buffer[363] =
1841 s->smart_selftest_data[3 +
1842 (s->smart_selftest_count - 1) *
1843 24];
1844 }
1845 s->io_buffer[364] = 0x20;
1846 s->io_buffer[365] = 0x01;
1847
1848 s->io_buffer[367] = (1 << 4 | 1 << 3 | 1);
1849 s->io_buffer[368] = 0x03;
1850 s->io_buffer[369] = 0x00;
1851 s->io_buffer[370] = 0x01;
1852 s->io_buffer[372] = 0x02;
1853 s->io_buffer[373] = 0x36;
1854 s->io_buffer[374] = 0x01;
1855
1856 for (n = 0; n < 511; n++) {
1857 s->io_buffer[511] += s->io_buffer[n];
1858 }
1859 s->io_buffer[511] = 0x100 - s->io_buffer[511];
1860
1861 s->status = READY_STAT | SEEK_STAT;
1862 ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1863 ide_set_irq(s->bus);
1864 return false;
1865
1866 case SMART_READ_LOG:
1867 switch (s->sector) {
1868 case 0x01:
1869 memset(s->io_buffer, 0, 0x200);
1870 s->io_buffer[0] = 0x01;
1871 s->io_buffer[1] = 0x00;
1872 s->io_buffer[452] = s->smart_errors & 0xff;
1873 s->io_buffer[453] = (s->smart_errors & 0xff00) >> 8;
1874
1875 for (n = 0; n < 511; n++) {
1876 s->io_buffer[511] += s->io_buffer[n];
1877 }
1878 s->io_buffer[511] = 0x100 - s->io_buffer[511];
1879 break;
1880 case 0x06:
1881 memset(s->io_buffer, 0, 0x200);
1882 s->io_buffer[0] = 0x01;
1883 if (s->smart_selftest_count == 0) {
1884 s->io_buffer[508] = 0;
1885 } else {
1886 s->io_buffer[508] = s->smart_selftest_count;
1887 for (n = 2; n < 506; n++) {
1888 s->io_buffer[n] = s->smart_selftest_data[n];
1889 }
1890 }
1891
1892 for (n = 0; n < 511; n++) {
1893 s->io_buffer[511] += s->io_buffer[n];
1894 }
1895 s->io_buffer[511] = 0x100 - s->io_buffer[511];
1896 break;
1897 default:
1898 goto abort_cmd;
1899 }
1900 s->status = READY_STAT | SEEK_STAT;
1901 ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1902 ide_set_irq(s->bus);
1903 return false;
1904
1905 case SMART_EXECUTE_OFFLINE:
1906 switch (s->sector) {
1907 case 0:
1908 case 1:
1909 case 2:
1910 s->smart_selftest_count++;
1911 if (s->smart_selftest_count > 21) {
1912 s->smart_selftest_count = 1;
1913 }
1914 n = 2 + (s->smart_selftest_count - 1) * 24;
1915 s->smart_selftest_data[n] = s->sector;
1916 s->smart_selftest_data[n + 1] = 0x00;
1917 s->smart_selftest_data[n + 2] = 0x34;
1918 s->smart_selftest_data[n + 3] = 0x12;
1919 break;
1920 default:
1921 goto abort_cmd;
1922 }
1923 return true;
1924 }
1925
1926abort_cmd:
1927 ide_abort_command(s);
1928 return true;
1929}
1930
1931#define HD_OK (1u << IDE_HD)
1932#define CD_OK (1u << IDE_CD)
1933#define CFA_OK (1u << IDE_CFATA)
1934#define HD_CFA_OK (HD_OK | CFA_OK)
1935#define ALL_OK (HD_OK | CD_OK | CFA_OK)
1936
1937
1938#define SET_DSC (1u << 8)
1939
1940
1941static const struct {
1942
1943 bool (*handler)(IDEState *s, uint8_t cmd);
1944 int flags;
1945} ide_cmd_table[0x100] = {
1946
1947 [CFA_REQ_EXT_ERROR_CODE] = { cmd_cfa_req_ext_error_code, CFA_OK },
1948 [WIN_DSM] = { cmd_data_set_management, HD_CFA_OK },
1949 [WIN_DEVICE_RESET] = { cmd_device_reset, CD_OK },
1950 [WIN_RECAL] = { cmd_nop, HD_CFA_OK | SET_DSC},
1951 [WIN_READ] = { cmd_read_pio, ALL_OK },
1952 [WIN_READ_ONCE] = { cmd_read_pio, HD_CFA_OK },
1953 [WIN_READ_EXT] = { cmd_read_pio, HD_CFA_OK },
1954 [WIN_READDMA_EXT] = { cmd_read_dma, HD_CFA_OK },
1955 [WIN_READ_NATIVE_MAX_EXT] = { cmd_read_native_max, HD_CFA_OK | SET_DSC },
1956 [WIN_MULTREAD_EXT] = { cmd_read_multiple, HD_CFA_OK },
1957 [WIN_WRITE] = { cmd_write_pio, HD_CFA_OK },
1958 [WIN_WRITE_ONCE] = { cmd_write_pio, HD_CFA_OK },
1959 [WIN_WRITE_EXT] = { cmd_write_pio, HD_CFA_OK },
1960 [WIN_WRITEDMA_EXT] = { cmd_write_dma, HD_CFA_OK },
1961 [CFA_WRITE_SECT_WO_ERASE] = { cmd_write_pio, CFA_OK },
1962 [WIN_MULTWRITE_EXT] = { cmd_write_multiple, HD_CFA_OK },
1963 [WIN_WRITE_VERIFY] = { cmd_write_pio, HD_CFA_OK },
1964 [WIN_VERIFY] = { cmd_verify, HD_CFA_OK | SET_DSC },
1965 [WIN_VERIFY_ONCE] = { cmd_verify, HD_CFA_OK | SET_DSC },
1966 [WIN_VERIFY_EXT] = { cmd_verify, HD_CFA_OK | SET_DSC },
1967 [WIN_SEEK] = { cmd_seek, HD_CFA_OK | SET_DSC },
1968 [CFA_TRANSLATE_SECTOR] = { cmd_cfa_translate_sector, CFA_OK },
1969 [WIN_DIAGNOSE] = { cmd_exec_dev_diagnostic, ALL_OK },
1970 [WIN_SPECIFY] = { cmd_nop, HD_CFA_OK | SET_DSC },
1971 [WIN_STANDBYNOW2] = { cmd_nop, HD_CFA_OK },
1972 [WIN_IDLEIMMEDIATE2] = { cmd_nop, HD_CFA_OK },
1973 [WIN_STANDBY2] = { cmd_nop, HD_CFA_OK },
1974 [WIN_SETIDLE2] = { cmd_nop, HD_CFA_OK },
1975 [WIN_CHECKPOWERMODE2] = { cmd_check_power_mode, HD_CFA_OK | SET_DSC },
1976 [WIN_SLEEPNOW2] = { cmd_nop, HD_CFA_OK },
1977 [WIN_PACKETCMD] = { cmd_packet, CD_OK },
1978 [WIN_PIDENTIFY] = { cmd_identify_packet, CD_OK },
1979 [WIN_SMART] = { cmd_smart, HD_CFA_OK | SET_DSC },
1980 [CFA_ACCESS_METADATA_STORAGE] = { cmd_cfa_access_metadata_storage, CFA_OK },
1981 [CFA_ERASE_SECTORS] = { cmd_cfa_erase_sectors, CFA_OK | SET_DSC },
1982 [WIN_MULTREAD] = { cmd_read_multiple, HD_CFA_OK },
1983 [WIN_MULTWRITE] = { cmd_write_multiple, HD_CFA_OK },
1984 [WIN_SETMULT] = { cmd_set_multiple_mode, HD_CFA_OK | SET_DSC },
1985 [WIN_READDMA] = { cmd_read_dma, HD_CFA_OK },
1986 [WIN_READDMA_ONCE] = { cmd_read_dma, HD_CFA_OK },
1987 [WIN_WRITEDMA] = { cmd_write_dma, HD_CFA_OK },
1988 [WIN_WRITEDMA_ONCE] = { cmd_write_dma, HD_CFA_OK },
1989 [CFA_WRITE_MULTI_WO_ERASE] = { cmd_write_multiple, CFA_OK },
1990 [WIN_STANDBYNOW1] = { cmd_nop, HD_CFA_OK },
1991 [WIN_IDLEIMMEDIATE] = { cmd_nop, HD_CFA_OK },
1992 [WIN_STANDBY] = { cmd_nop, HD_CFA_OK },
1993 [WIN_SETIDLE1] = { cmd_nop, HD_CFA_OK },
1994 [WIN_CHECKPOWERMODE1] = { cmd_check_power_mode, HD_CFA_OK | SET_DSC },
1995 [WIN_SLEEPNOW1] = { cmd_nop, HD_CFA_OK },
1996 [WIN_FLUSH_CACHE] = { cmd_flush_cache, ALL_OK },
1997 [WIN_FLUSH_CACHE_EXT] = { cmd_flush_cache, HD_CFA_OK },
1998 [WIN_IDENTIFY] = { cmd_identify, ALL_OK },
1999 [WIN_SETFEATURES] = { cmd_set_features, ALL_OK | SET_DSC },
2000 [IBM_SENSE_CONDITION] = { cmd_ibm_sense_condition, CFA_OK | SET_DSC },
2001 [CFA_WEAR_LEVEL] = { cmd_cfa_erase_sectors, HD_CFA_OK | SET_DSC },
2002 [WIN_READ_NATIVE_MAX] = { cmd_read_native_max, HD_CFA_OK | SET_DSC },
2003};
2004
2005static bool ide_cmd_permitted(IDEState *s, uint32_t cmd)
2006{
2007 return cmd < ARRAY_SIZE(ide_cmd_table)
2008 && (ide_cmd_table[cmd].flags & (1u << s->drive_kind));
2009}
2010
2011void ide_exec_cmd(IDEBus *bus, uint32_t val)
2012{
2013 IDEState *s;
2014 bool complete;
2015
2016#if defined(DEBUG_IDE)
2017 printf("ide: CMD=%02x\n", val);
2018#endif
2019 s = idebus_active_if(bus);
2020
2021 if (s != bus->ifs && !s->blk) {
2022 return;
2023 }
2024
2025
2026
2027 if (s->status & (BUSY_STAT|DRQ_STAT)) {
2028 if (val != WIN_DEVICE_RESET || s->drive_kind != IDE_CD) {
2029 return;
2030 }
2031 }
2032
2033 if (!ide_cmd_permitted(s, val)) {
2034 ide_abort_command(s);
2035 ide_set_irq(s->bus);
2036 return;
2037 }
2038
2039 s->status = READY_STAT | BUSY_STAT;
2040 s->error = 0;
2041 s->io_buffer_offset = 0;
2042
2043 complete = ide_cmd_table[val].handler(s, val);
2044 if (complete) {
2045 s->status &= ~BUSY_STAT;
2046 assert(!!s->error == !!(s->status & ERR_STAT));
2047
2048 if ((ide_cmd_table[val].flags & SET_DSC) && !s->error) {
2049 s->status |= SEEK_STAT;
2050 }
2051
2052 ide_cmd_done(s);
2053 ide_set_irq(s->bus);
2054 }
2055}
2056
2057uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
2058{
2059 IDEBus *bus = opaque;
2060 IDEState *s = idebus_active_if(bus);
2061 uint32_t addr;
2062 int ret, hob;
2063
2064 addr = addr1 & 7;
2065
2066
2067 hob = 0;
2068 switch(addr) {
2069 case 0:
2070 ret = 0xff;
2071 break;
2072 case 1:
2073 if ((!bus->ifs[0].blk && !bus->ifs[1].blk) ||
2074 (s != bus->ifs && !s->blk)) {
2075 ret = 0;
2076 } else if (!hob) {
2077 ret = s->error;
2078 } else {
2079 ret = s->hob_feature;
2080 }
2081 break;
2082 case 2:
2083 if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
2084 ret = 0;
2085 } else if (!hob) {
2086 ret = s->nsector & 0xff;
2087 } else {
2088 ret = s->hob_nsector;
2089 }
2090 break;
2091 case 3:
2092 if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
2093 ret = 0;
2094 } else if (!hob) {
2095 ret = s->sector;
2096 } else {
2097 ret = s->hob_sector;
2098 }
2099 break;
2100 case 4:
2101 if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
2102 ret = 0;
2103 } else if (!hob) {
2104 ret = s->lcyl;
2105 } else {
2106 ret = s->hob_lcyl;
2107 }
2108 break;
2109 case 5:
2110 if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
2111 ret = 0;
2112 } else if (!hob) {
2113 ret = s->hcyl;
2114 } else {
2115 ret = s->hob_hcyl;
2116 }
2117 break;
2118 case 6:
2119 if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
2120 ret = 0;
2121 } else {
2122 ret = s->select;
2123 }
2124 break;
2125 default:
2126 case 7:
2127 if ((!bus->ifs[0].blk && !bus->ifs[1].blk) ||
2128 (s != bus->ifs && !s->blk)) {
2129 ret = 0;
2130 } else {
2131 ret = s->status;
2132 }
2133 qemu_irq_lower(bus->irq);
2134 break;
2135 }
2136#ifdef DEBUG_IDE
2137 printf("ide: read addr=0x%x val=%02x\n", addr1, ret);
2138#endif
2139 return ret;
2140}
2141
2142uint32_t ide_status_read(void *opaque, uint32_t addr)
2143{
2144 IDEBus *bus = opaque;
2145 IDEState *s = idebus_active_if(bus);
2146 int ret;
2147
2148 if ((!bus->ifs[0].blk && !bus->ifs[1].blk) ||
2149 (s != bus->ifs && !s->blk)) {
2150 ret = 0;
2151 } else {
2152 ret = s->status;
2153 }
2154#ifdef DEBUG_IDE
2155 printf("ide: read status addr=0x%x val=%02x\n", addr, ret);
2156#endif
2157 return ret;
2158}
2159
2160void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
2161{
2162 IDEBus *bus = opaque;
2163 IDEState *s;
2164 int i;
2165
2166#ifdef DEBUG_IDE
2167 printf("ide: write control addr=0x%x val=%02x\n", addr, val);
2168#endif
2169
2170 if (!(bus->cmd & IDE_CMD_RESET) &&
2171 (val & IDE_CMD_RESET)) {
2172
2173 for(i = 0;i < 2; i++) {
2174 s = &bus->ifs[i];
2175 s->status = BUSY_STAT | SEEK_STAT;
2176 s->error = 0x01;
2177 }
2178 } else 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 if (s->drive_kind == IDE_CD)
2184 s->status = 0x00;
2185 else
2186 s->status = READY_STAT | SEEK_STAT;
2187 ide_set_signature(s);
2188 }
2189 }
2190
2191 bus->cmd = val;
2192}
2193
2194
2195
2196
2197
2198static bool ide_is_pio_out(IDEState *s)
2199{
2200 if (s->end_transfer_func == ide_sector_write ||
2201 s->end_transfer_func == ide_atapi_cmd) {
2202 return false;
2203 } else if (s->end_transfer_func == ide_sector_read ||
2204 s->end_transfer_func == ide_transfer_stop ||
2205 s->end_transfer_func == ide_atapi_cmd_reply_end ||
2206 s->end_transfer_func == ide_dummy_transfer_stop) {
2207 return true;
2208 }
2209
2210 abort();
2211}
2212
2213void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
2214{
2215 IDEBus *bus = opaque;
2216 IDEState *s = idebus_active_if(bus);
2217 uint8_t *p;
2218
2219
2220
2221 if (!(s->status & DRQ_STAT) || ide_is_pio_out(s)) {
2222 return;
2223 }
2224
2225 p = s->data_ptr;
2226 if (p + 2 > s->data_end) {
2227 return;
2228 }
2229
2230 *(uint16_t *)p = le16_to_cpu(val);
2231 p += 2;
2232 s->data_ptr = p;
2233 if (p >= s->data_end) {
2234 s->status &= ~DRQ_STAT;
2235 s->end_transfer_func(s);
2236 }
2237}
2238
2239uint32_t ide_data_readw(void *opaque, uint32_t addr)
2240{
2241 IDEBus *bus = opaque;
2242 IDEState *s = idebus_active_if(bus);
2243 uint8_t *p;
2244 int ret;
2245
2246
2247
2248 if (!(s->status & DRQ_STAT) || !ide_is_pio_out(s)) {
2249 return 0;
2250 }
2251
2252 p = s->data_ptr;
2253 if (p + 2 > s->data_end) {
2254 return 0;
2255 }
2256
2257 ret = cpu_to_le16(*(uint16_t *)p);
2258 p += 2;
2259 s->data_ptr = p;
2260 if (p >= s->data_end) {
2261 s->status &= ~DRQ_STAT;
2262 s->end_transfer_func(s);
2263 }
2264 return ret;
2265}
2266
2267void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
2268{
2269 IDEBus *bus = opaque;
2270 IDEState *s = idebus_active_if(bus);
2271 uint8_t *p;
2272
2273
2274
2275 if (!(s->status & DRQ_STAT) || ide_is_pio_out(s)) {
2276 return;
2277 }
2278
2279 p = s->data_ptr;
2280 if (p + 4 > s->data_end) {
2281 return;
2282 }
2283
2284 *(uint32_t *)p = le32_to_cpu(val);
2285 p += 4;
2286 s->data_ptr = p;
2287 if (p >= s->data_end) {
2288 s->status &= ~DRQ_STAT;
2289 s->end_transfer_func(s);
2290 }
2291}
2292
2293uint32_t ide_data_readl(void *opaque, uint32_t addr)
2294{
2295 IDEBus *bus = opaque;
2296 IDEState *s = idebus_active_if(bus);
2297 uint8_t *p;
2298 int ret;
2299
2300
2301
2302 if (!(s->status & DRQ_STAT) || !ide_is_pio_out(s)) {
2303 return 0;
2304 }
2305
2306 p = s->data_ptr;
2307 if (p + 4 > s->data_end) {
2308 return 0;
2309 }
2310
2311 ret = cpu_to_le32(*(uint32_t *)p);
2312 p += 4;
2313 s->data_ptr = p;
2314 if (p >= s->data_end) {
2315 s->status &= ~DRQ_STAT;
2316 s->end_transfer_func(s);
2317 }
2318 return ret;
2319}
2320
2321static void ide_dummy_transfer_stop(IDEState *s)
2322{
2323 s->data_ptr = s->io_buffer;
2324 s->data_end = s->io_buffer;
2325 s->io_buffer[0] = 0xff;
2326 s->io_buffer[1] = 0xff;
2327 s->io_buffer[2] = 0xff;
2328 s->io_buffer[3] = 0xff;
2329}
2330
2331void ide_bus_reset(IDEBus *bus)
2332{
2333 bus->unit = 0;
2334 bus->cmd = 0;
2335 ide_reset(&bus->ifs[0]);
2336 ide_reset(&bus->ifs[1]);
2337 ide_clear_hob(bus);
2338
2339
2340 if (bus->dma->aiocb) {
2341#ifdef DEBUG_AIO
2342 printf("aio_cancel\n");
2343#endif
2344 blk_aio_cancel(bus->dma->aiocb);
2345 bus->dma->aiocb = NULL;
2346 }
2347
2348
2349 if (bus->dma->ops->reset) {
2350 bus->dma->ops->reset(bus->dma);
2351 }
2352}
2353
2354static bool ide_cd_is_tray_open(void *opaque)
2355{
2356 return ((IDEState *)opaque)->tray_open;
2357}
2358
2359static bool ide_cd_is_medium_locked(void *opaque)
2360{
2361 return ((IDEState *)opaque)->tray_locked;
2362}
2363
2364static void ide_resize_cb(void *opaque)
2365{
2366 IDEState *s = opaque;
2367 uint64_t nb_sectors;
2368
2369 if (!s->identify_set) {
2370 return;
2371 }
2372
2373 blk_get_geometry(s->blk, &nb_sectors);
2374 s->nb_sectors = nb_sectors;
2375
2376
2377 if (s->drive_kind == IDE_CFATA) {
2378 ide_cfata_identify_size(s);
2379 } else {
2380
2381 assert(s->drive_kind != IDE_CD);
2382 ide_identify_size(s);
2383 }
2384}
2385
2386static const BlockDevOps ide_cd_block_ops = {
2387 .change_media_cb = ide_cd_change_cb,
2388 .eject_request_cb = ide_cd_eject_request_cb,
2389 .is_tray_open = ide_cd_is_tray_open,
2390 .is_medium_locked = ide_cd_is_medium_locked,
2391};
2392
2393static const BlockDevOps ide_hd_block_ops = {
2394 .resize_cb = ide_resize_cb,
2395};
2396
2397int ide_init_drive(IDEState *s, BlockBackend *blk, IDEDriveKind kind,
2398 const char *version, const char *serial, const char *model,
2399 uint64_t wwn,
2400 uint32_t cylinders, uint32_t heads, uint32_t secs,
2401 int chs_trans)
2402{
2403 uint64_t nb_sectors;
2404
2405 s->blk = blk;
2406 s->drive_kind = kind;
2407
2408 blk_get_geometry(blk, &nb_sectors);
2409 s->cylinders = cylinders;
2410 s->heads = heads;
2411 s->sectors = secs;
2412 s->chs_trans = chs_trans;
2413 s->nb_sectors = nb_sectors;
2414 s->wwn = wwn;
2415
2416
2417 s->smart_enabled = 1;
2418 s->smart_autosave = 1;
2419 s->smart_errors = 0;
2420 s->smart_selftest_count = 0;
2421 if (kind == IDE_CD) {
2422 blk_set_dev_ops(blk, &ide_cd_block_ops, s);
2423 blk_set_guest_block_size(blk, 2048);
2424 } else {
2425 if (!blk_is_inserted(s->blk)) {
2426 error_report("Device needs media, but drive is empty");
2427 return -1;
2428 }
2429 if (blk_is_read_only(blk)) {
2430 error_report("Can't use a read-only drive");
2431 return -1;
2432 }
2433 blk_set_dev_ops(blk, &ide_hd_block_ops, s);
2434 }
2435 if (serial) {
2436 pstrcpy(s->drive_serial_str, sizeof(s->drive_serial_str), serial);
2437 } else {
2438 snprintf(s->drive_serial_str, sizeof(s->drive_serial_str),
2439 "QM%05d", s->drive_serial);
2440 }
2441 if (model) {
2442 pstrcpy(s->drive_model_str, sizeof(s->drive_model_str), model);
2443 } else {
2444 switch (kind) {
2445 case IDE_CD:
2446 strcpy(s->drive_model_str, "QEMU DVD-ROM");
2447 break;
2448 case IDE_CFATA:
2449 strcpy(s->drive_model_str, "QEMU MICRODRIVE");
2450 break;
2451 default:
2452 strcpy(s->drive_model_str, "QEMU HARDDISK");
2453 break;
2454 }
2455 }
2456
2457 if (version) {
2458 pstrcpy(s->version, sizeof(s->version), version);
2459 } else {
2460 pstrcpy(s->version, sizeof(s->version), qemu_hw_version());
2461 }
2462
2463 ide_reset(s);
2464 blk_iostatus_enable(blk);
2465 return 0;
2466}
2467
2468static void ide_init1(IDEBus *bus, int unit)
2469{
2470 static int drive_serial = 1;
2471 IDEState *s = &bus->ifs[unit];
2472
2473 s->bus = bus;
2474 s->unit = unit;
2475 s->drive_serial = drive_serial++;
2476
2477 s->io_buffer_total_len = IDE_DMA_BUF_SECTORS*512 + 4;
2478 s->io_buffer = qemu_memalign(2048, s->io_buffer_total_len);
2479 memset(s->io_buffer, 0, s->io_buffer_total_len);
2480
2481 s->smart_selftest_data = blk_blockalign(s->blk, 512);
2482 memset(s->smart_selftest_data, 0, 512);
2483
2484 s->sector_write_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
2485 ide_sector_write_timer_cb, s);
2486}
2487
2488static int ide_nop_int(IDEDMA *dma, int x)
2489{
2490 return 0;
2491}
2492
2493static void ide_nop(IDEDMA *dma)
2494{
2495}
2496
2497static int32_t ide_nop_int32(IDEDMA *dma, int32_t l)
2498{
2499 return 0;
2500}
2501
2502static const IDEDMAOps ide_dma_nop_ops = {
2503 .prepare_buf = ide_nop_int32,
2504 .restart_dma = ide_nop,
2505 .rw_buf = ide_nop_int,
2506};
2507
2508static void ide_restart_dma(IDEState *s, enum ide_dma_cmd dma_cmd)
2509{
2510 s->unit = s->bus->retry_unit;
2511 ide_set_sector(s, s->bus->retry_sector_num);
2512 s->nsector = s->bus->retry_nsector;
2513 s->bus->dma->ops->restart_dma(s->bus->dma);
2514 s->io_buffer_size = 0;
2515 s->dma_cmd = dma_cmd;
2516 ide_start_dma(s, ide_dma_cb);
2517}
2518
2519static void ide_restart_bh(void *opaque)
2520{
2521 IDEBus *bus = opaque;
2522 IDEState *s;
2523 bool is_read;
2524 int error_status;
2525
2526 qemu_bh_delete(bus->bh);
2527 bus->bh = NULL;
2528
2529 error_status = bus->error_status;
2530 if (bus->error_status == 0) {
2531 return;
2532 }
2533
2534 s = idebus_active_if(bus);
2535 is_read = (bus->error_status & IDE_RETRY_READ) != 0;
2536
2537
2538
2539
2540 bus->error_status = 0;
2541
2542
2543 if (error_status & IDE_RETRY_HBA) {
2544 if (s->bus->dma->ops->restart) {
2545 s->bus->dma->ops->restart(s->bus->dma);
2546 }
2547 } else if (IS_IDE_RETRY_DMA(error_status)) {
2548 if (error_status & IDE_RETRY_TRIM) {
2549 ide_restart_dma(s, IDE_DMA_TRIM);
2550 } else {
2551 ide_restart_dma(s, is_read ? IDE_DMA_READ : IDE_DMA_WRITE);
2552 }
2553 } else if (IS_IDE_RETRY_PIO(error_status)) {
2554 if (is_read) {
2555 ide_sector_read(s);
2556 } else {
2557 ide_sector_write(s);
2558 }
2559 } else if (error_status & IDE_RETRY_FLUSH) {
2560 ide_flush_cache(s);
2561 } else if (IS_IDE_RETRY_ATAPI(error_status)) {
2562 assert(s->end_transfer_func == ide_atapi_cmd);
2563 ide_atapi_dma_restart(s);
2564 } else {
2565 abort();
2566 }
2567}
2568
2569static void ide_restart_cb(void *opaque, int running, RunState state)
2570{
2571 IDEBus *bus = opaque;
2572
2573 if (!running)
2574 return;
2575
2576 if (!bus->bh) {
2577 bus->bh = qemu_bh_new(ide_restart_bh, bus);
2578 qemu_bh_schedule(bus->bh);
2579 }
2580}
2581
2582void ide_register_restart_cb(IDEBus *bus)
2583{
2584 if (bus->dma->ops->restart_dma) {
2585 qemu_add_vm_change_state_handler(ide_restart_cb, bus);
2586 }
2587}
2588
2589static IDEDMA ide_dma_nop = {
2590 .ops = &ide_dma_nop_ops,
2591 .aiocb = NULL,
2592};
2593
2594void ide_init2(IDEBus *bus, qemu_irq irq)
2595{
2596 int i;
2597
2598 for(i = 0; i < 2; i++) {
2599 ide_init1(bus, i);
2600 ide_reset(&bus->ifs[i]);
2601 }
2602 bus->irq = irq;
2603 bus->dma = &ide_dma_nop;
2604}
2605
2606static const MemoryRegionPortio ide_portio_list[] = {
2607 { 0, 8, 1, .read = ide_ioport_read, .write = ide_ioport_write },
2608 { 0, 1, 2, .read = ide_data_readw, .write = ide_data_writew },
2609 { 0, 1, 4, .read = ide_data_readl, .write = ide_data_writel },
2610 PORTIO_END_OF_LIST(),
2611};
2612
2613static const MemoryRegionPortio ide_portio2_list[] = {
2614 { 0, 1, 1, .read = ide_status_read, .write = ide_cmd_write },
2615 PORTIO_END_OF_LIST(),
2616};
2617
2618void ide_init_ioport(IDEBus *bus, ISADevice *dev, int iobase, int iobase2)
2619{
2620
2621
2622 isa_register_portio_list(dev, iobase, ide_portio_list, bus, "ide");
2623
2624 if (iobase2) {
2625 isa_register_portio_list(dev, iobase2, ide_portio2_list, bus, "ide");
2626 }
2627}
2628
2629static bool is_identify_set(void *opaque, int version_id)
2630{
2631 IDEState *s = opaque;
2632
2633 return s->identify_set != 0;
2634}
2635
2636static EndTransferFunc* transfer_end_table[] = {
2637 ide_sector_read,
2638 ide_sector_write,
2639 ide_transfer_stop,
2640 ide_atapi_cmd_reply_end,
2641 ide_atapi_cmd,
2642 ide_dummy_transfer_stop,
2643};
2644
2645static int transfer_end_table_idx(EndTransferFunc *fn)
2646{
2647 int i;
2648
2649 for (i = 0; i < ARRAY_SIZE(transfer_end_table); i++)
2650 if (transfer_end_table[i] == fn)
2651 return i;
2652
2653 return -1;
2654}
2655
2656static int ide_drive_post_load(void *opaque, int version_id)
2657{
2658 IDEState *s = opaque;
2659
2660 if (s->blk && s->identify_set) {
2661 blk_set_enable_write_cache(s->blk, !!(s->identify_data[85] & (1 << 5)));
2662 }
2663 return 0;
2664}
2665
2666static int ide_drive_pio_post_load(void *opaque, int version_id)
2667{
2668 IDEState *s = opaque;
2669
2670 if (s->end_transfer_fn_idx >= ARRAY_SIZE(transfer_end_table)) {
2671 return -EINVAL;
2672 }
2673 s->end_transfer_func = transfer_end_table[s->end_transfer_fn_idx];
2674 s->data_ptr = s->io_buffer + s->cur_io_buffer_offset;
2675 s->data_end = s->data_ptr + s->cur_io_buffer_len;
2676 s->atapi_dma = s->feature & 1;
2677
2678 return 0;
2679}
2680
2681static void ide_drive_pio_pre_save(void *opaque)
2682{
2683 IDEState *s = opaque;
2684 int idx;
2685
2686 s->cur_io_buffer_offset = s->data_ptr - s->io_buffer;
2687 s->cur_io_buffer_len = s->data_end - s->data_ptr;
2688
2689 idx = transfer_end_table_idx(s->end_transfer_func);
2690 if (idx == -1) {
2691 fprintf(stderr, "%s: invalid end_transfer_func for DRQ_STAT\n",
2692 __func__);
2693 s->end_transfer_fn_idx = 2;
2694 } else {
2695 s->end_transfer_fn_idx = idx;
2696 }
2697}
2698
2699static bool ide_drive_pio_state_needed(void *opaque)
2700{
2701 IDEState *s = opaque;
2702
2703 return ((s->status & DRQ_STAT) != 0)
2704 || (s->bus->error_status & IDE_RETRY_PIO);
2705}
2706
2707static bool ide_tray_state_needed(void *opaque)
2708{
2709 IDEState *s = opaque;
2710
2711 return s->tray_open || s->tray_locked;
2712}
2713
2714static bool ide_atapi_gesn_needed(void *opaque)
2715{
2716 IDEState *s = opaque;
2717
2718 return s->events.new_media || s->events.eject_request;
2719}
2720
2721static bool ide_error_needed(void *opaque)
2722{
2723 IDEBus *bus = opaque;
2724
2725 return (bus->error_status != 0);
2726}
2727
2728
2729static const VMStateDescription vmstate_ide_atapi_gesn_state = {
2730 .name ="ide_drive/atapi/gesn_state",
2731 .version_id = 1,
2732 .minimum_version_id = 1,
2733 .needed = ide_atapi_gesn_needed,
2734 .fields = (VMStateField[]) {
2735 VMSTATE_BOOL(events.new_media, IDEState),
2736 VMSTATE_BOOL(events.eject_request, IDEState),
2737 VMSTATE_END_OF_LIST()
2738 }
2739};
2740
2741static const VMStateDescription vmstate_ide_tray_state = {
2742 .name = "ide_drive/tray_state",
2743 .version_id = 1,
2744 .minimum_version_id = 1,
2745 .needed = ide_tray_state_needed,
2746 .fields = (VMStateField[]) {
2747 VMSTATE_BOOL(tray_open, IDEState),
2748 VMSTATE_BOOL(tray_locked, IDEState),
2749 VMSTATE_END_OF_LIST()
2750 }
2751};
2752
2753static const VMStateDescription vmstate_ide_drive_pio_state = {
2754 .name = "ide_drive/pio_state",
2755 .version_id = 1,
2756 .minimum_version_id = 1,
2757 .pre_save = ide_drive_pio_pre_save,
2758 .post_load = ide_drive_pio_post_load,
2759 .needed = ide_drive_pio_state_needed,
2760 .fields = (VMStateField[]) {
2761 VMSTATE_INT32(req_nb_sectors, IDEState),
2762 VMSTATE_VARRAY_INT32(io_buffer, IDEState, io_buffer_total_len, 1,
2763 vmstate_info_uint8, uint8_t),
2764 VMSTATE_INT32(cur_io_buffer_offset, IDEState),
2765 VMSTATE_INT32(cur_io_buffer_len, IDEState),
2766 VMSTATE_UINT8(end_transfer_fn_idx, IDEState),
2767 VMSTATE_INT32(elementary_transfer_size, IDEState),
2768 VMSTATE_INT32(packet_transfer_size, IDEState),
2769 VMSTATE_END_OF_LIST()
2770 }
2771};
2772
2773const VMStateDescription vmstate_ide_drive = {
2774 .name = "ide_drive",
2775 .version_id = 3,
2776 .minimum_version_id = 0,
2777 .post_load = ide_drive_post_load,
2778 .fields = (VMStateField[]) {
2779 VMSTATE_INT32(mult_sectors, IDEState),
2780 VMSTATE_INT32(identify_set, IDEState),
2781 VMSTATE_BUFFER_TEST(identify_data, IDEState, is_identify_set),
2782 VMSTATE_UINT8(feature, IDEState),
2783 VMSTATE_UINT8(error, IDEState),
2784 VMSTATE_UINT32(nsector, IDEState),
2785 VMSTATE_UINT8(sector, IDEState),
2786 VMSTATE_UINT8(lcyl, IDEState),
2787 VMSTATE_UINT8(hcyl, IDEState),
2788 VMSTATE_UINT8(hob_feature, IDEState),
2789 VMSTATE_UINT8(hob_sector, IDEState),
2790 VMSTATE_UINT8(hob_nsector, IDEState),
2791 VMSTATE_UINT8(hob_lcyl, IDEState),
2792 VMSTATE_UINT8(hob_hcyl, IDEState),
2793 VMSTATE_UINT8(select, IDEState),
2794 VMSTATE_UINT8(status, IDEState),
2795 VMSTATE_UINT8(lba48, IDEState),
2796 VMSTATE_UINT8(sense_key, IDEState),
2797 VMSTATE_UINT8(asc, IDEState),
2798 VMSTATE_UINT8_V(cdrom_changed, IDEState, 3),
2799 VMSTATE_END_OF_LIST()
2800 },
2801 .subsections = (const VMStateDescription*[]) {
2802 &vmstate_ide_drive_pio_state,
2803 &vmstate_ide_tray_state,
2804 &vmstate_ide_atapi_gesn_state,
2805 NULL
2806 }
2807};
2808
2809static const VMStateDescription vmstate_ide_error_status = {
2810 .name ="ide_bus/error",
2811 .version_id = 2,
2812 .minimum_version_id = 1,
2813 .needed = ide_error_needed,
2814 .fields = (VMStateField[]) {
2815 VMSTATE_INT32(error_status, IDEBus),
2816 VMSTATE_INT64_V(retry_sector_num, IDEBus, 2),
2817 VMSTATE_UINT32_V(retry_nsector, IDEBus, 2),
2818 VMSTATE_UINT8_V(retry_unit, IDEBus, 2),
2819 VMSTATE_END_OF_LIST()
2820 }
2821};
2822
2823const VMStateDescription vmstate_ide_bus = {
2824 .name = "ide_bus",
2825 .version_id = 1,
2826 .minimum_version_id = 1,
2827 .fields = (VMStateField[]) {
2828 VMSTATE_UINT8(cmd, IDEBus),
2829 VMSTATE_UINT8(unit, IDEBus),
2830 VMSTATE_END_OF_LIST()
2831 },
2832 .subsections = (const VMStateDescription*[]) {
2833 &vmstate_ide_error_status,
2834 NULL
2835 }
2836};
2837
2838void ide_drive_get(DriveInfo **hd, int n)
2839{
2840 int i;
2841 int highest_bus = drive_get_max_bus(IF_IDE) + 1;
2842 int max_devs = drive_get_max_devs(IF_IDE);
2843 int n_buses = max_devs ? (n / max_devs) : n;
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853 if (highest_bus > n_buses) {
2854 error_report("Too many IDE buses defined (%d > %d)",
2855 highest_bus, n_buses);
2856 exit(1);
2857 }
2858
2859 for (i = 0; i < n; i++) {
2860 hd[i] = drive_get_by_index(IF_IDE, i);
2861 }
2862}
2863