Commit 944588029809b29c800f081d812153f559ec523a
1 parent
8147cfca
correct DMA and transfer mode reporting (Jens Axboe)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1736 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
54 additions
and
7 deletions
hw/ide.c
| ... | ... | @@ -296,6 +296,8 @@ typedef struct IDEState { |
| 296 | 296 | int cylinders, heads, sectors; |
| 297 | 297 | int64_t nb_sectors; |
| 298 | 298 | int mult_sectors; |
| 299 | + int identify_set; | |
| 300 | + uint16_t identify_data[256]; | |
| 299 | 301 | SetIRQFunc *set_irq; |
| 300 | 302 | void *irq_opaque; |
| 301 | 303 | int irq; |
| ... | ... | @@ -414,6 +416,11 @@ static void ide_identify(IDEState *s) |
| 414 | 416 | unsigned int oldsize; |
| 415 | 417 | char buf[20]; |
| 416 | 418 | |
| 419 | + if (s->identify_set) { | |
| 420 | + memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data)); | |
| 421 | + return; | |
| 422 | + } | |
| 423 | + | |
| 417 | 424 | memset(s->io_buffer, 0, 512); |
| 418 | 425 | p = (uint16_t *)s->io_buffer; |
| 419 | 426 | put_le16(p + 0, 0x0040); |
| ... | ... | @@ -433,10 +440,10 @@ static void ide_identify(IDEState *s) |
| 433 | 440 | put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS); |
| 434 | 441 | #endif |
| 435 | 442 | put_le16(p + 48, 1); /* dword I/O */ |
| 436 | - put_le16(p + 49, 1 << 9 | 1 << 8); /* DMA and LBA supported */ | |
| 443 | + put_le16(p + 49, (1 << 11) | (1 << 9) | (1 << 8)); /* DMA and LBA supported */ | |
| 437 | 444 | put_le16(p + 51, 0x200); /* PIO transfer cycle */ |
| 438 | 445 | put_le16(p + 52, 0x200); /* DMA transfer cycle */ |
| 439 | - put_le16(p + 53, 1 | 1 << 2); /* words 54-58,88 are valid */ | |
| 446 | + put_le16(p + 53, 1 | (1 << 1) | (1 << 2)); /* words 54-58,64-70,88 are valid */ | |
| 440 | 447 | put_le16(p + 54, s->cylinders); |
| 441 | 448 | put_le16(p + 55, s->heads); |
| 442 | 449 | put_le16(p + 56, s->sectors); |
| ... | ... | @@ -447,15 +454,24 @@ static void ide_identify(IDEState *s) |
| 447 | 454 | put_le16(p + 59, 0x100 | s->mult_sectors); |
| 448 | 455 | put_le16(p + 60, s->nb_sectors); |
| 449 | 456 | put_le16(p + 61, s->nb_sectors >> 16); |
| 450 | - put_le16(p + 80, (1 << 1) | (1 << 2)); | |
| 457 | + put_le16(p + 63, 0x07); /* mdma0-2 supported */ | |
| 458 | + put_le16(p + 65, 120); | |
| 459 | + put_le16(p + 66, 120); | |
| 460 | + put_le16(p + 67, 120); | |
| 461 | + put_le16(p + 68, 120); | |
| 462 | + put_le16(p + 80, 0xf0); /* ata3 -> ata6 supported */ | |
| 463 | + put_le16(p + 81, 0x16); /* conforms to ata5 */ | |
| 451 | 464 | put_le16(p + 82, (1 << 14)); |
| 452 | 465 | put_le16(p + 83, (1 << 14)); |
| 453 | 466 | put_le16(p + 84, (1 << 14)); |
| 454 | 467 | put_le16(p + 85, (1 << 14)); |
| 455 | 468 | put_le16(p + 86, 0); |
| 456 | 469 | put_le16(p + 87, (1 << 14)); |
| 457 | - put_le16(p + 88, 0x1f | (1 << 13)); | |
| 458 | - put_le16(p + 93, 1 | (1 << 14) | 0x2000 | 0x4000); | |
| 470 | + put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */ | |
| 471 | + put_le16(p + 93, 1 | (1 << 14) | 0x2000); | |
| 472 | + | |
| 473 | + memcpy(s->identify_data, p, sizeof(s->identify_data)); | |
| 474 | + s->identify_set = 1; | |
| 459 | 475 | } |
| 460 | 476 | |
| 461 | 477 | static void ide_atapi_identify(IDEState *s) |
| ... | ... | @@ -463,6 +479,11 @@ static void ide_atapi_identify(IDEState *s) |
| 463 | 479 | uint16_t *p; |
| 464 | 480 | char buf[20]; |
| 465 | 481 | |
| 482 | + if (s->identify_set) { | |
| 483 | + memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data)); | |
| 484 | + return; | |
| 485 | + } | |
| 486 | + | |
| 466 | 487 | memset(s->io_buffer, 0, 512); |
| 467 | 488 | p = (uint16_t *)s->io_buffer; |
| 468 | 489 | /* Removable CDROM, 50us response, 12 byte packets */ |
| ... | ... | @@ -483,11 +504,14 @@ static void ide_atapi_identify(IDEState *s) |
| 483 | 504 | put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */ |
| 484 | 505 | put_le16(p + 67, 0x12c); /* minimum PIO cycle time without flow control */ |
| 485 | 506 | put_le16(p + 68, 0xb4); /* minimum PIO cycle time with IORDY flow control */ |
| 486 | - | |
| 507 | + | |
| 487 | 508 | put_le16(p + 71, 30); /* in ns */ |
| 488 | 509 | put_le16(p + 72, 30); /* in ns */ |
| 489 | 510 | |
| 490 | 511 | put_le16(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */ |
| 512 | + | |
| 513 | + memcpy(s->identify_data, p, sizeof(s->identify_data)); | |
| 514 | + s->identify_set = 1; | |
| 491 | 515 | } |
| 492 | 516 | |
| 493 | 517 | static void ide_set_signature(IDEState *s) |
| ... | ... | @@ -1601,13 +1625,36 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
| 1601 | 1625 | /* XXX: valid for CDROM ? */ |
| 1602 | 1626 | switch(s->feature) { |
| 1603 | 1627 | case 0x02: /* write cache enable */ |
| 1604 | - case 0x03: /* set transfer mode */ | |
| 1605 | 1628 | case 0x82: /* write cache disable */ |
| 1606 | 1629 | case 0xaa: /* read look-ahead enable */ |
| 1607 | 1630 | case 0x55: /* read look-ahead disable */ |
| 1608 | 1631 | s->status = READY_STAT | SEEK_STAT; |
| 1609 | 1632 | ide_set_irq(s); |
| 1610 | 1633 | break; |
| 1634 | + case 0x03: { /* set transfer mode */ | |
| 1635 | + uint8_t val = s->nsector & 0x07; | |
| 1636 | + | |
| 1637 | + switch (s->nsector >> 3) { | |
| 1638 | + case 0x00: /* pio default */ | |
| 1639 | + case 0x01: /* pio mode */ | |
| 1640 | + put_le16(s->identify_data + 63,0x07); | |
| 1641 | + put_le16(s->identify_data + 88,0x3f); | |
| 1642 | + break; | |
| 1643 | + case 0x04: /* mdma mode */ | |
| 1644 | + put_le16(s->identify_data + 63,0x07 | (1 << (val + 8))); | |
| 1645 | + put_le16(s->identify_data + 88,0x3f); | |
| 1646 | + break; | |
| 1647 | + case 0x08: /* udma mode */ | |
| 1648 | + put_le16(s->identify_data + 63,0x07); | |
| 1649 | + put_le16(s->identify_data + 88,0x3f | (1 << (val + 8))); | |
| 1650 | + break; | |
| 1651 | + default: | |
| 1652 | + goto abort_cmd; | |
| 1653 | + } | |
| 1654 | + s->status = READY_STAT | SEEK_STAT; | |
| 1655 | + ide_set_irq(s); | |
| 1656 | + break; | |
| 1657 | + } | |
| 1611 | 1658 | default: |
| 1612 | 1659 | goto abort_cmd; |
| 1613 | 1660 | } | ... | ... |