Commit 944588029809b29c800f081d812153f559ec523a

Authored by bellard
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 }
... ...