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,6 +296,8 @@ typedef struct IDEState {
296 int cylinders, heads, sectors; 296 int cylinders, heads, sectors;
297 int64_t nb_sectors; 297 int64_t nb_sectors;
298 int mult_sectors; 298 int mult_sectors;
  299 + int identify_set;
  300 + uint16_t identify_data[256];
299 SetIRQFunc *set_irq; 301 SetIRQFunc *set_irq;
300 void *irq_opaque; 302 void *irq_opaque;
301 int irq; 303 int irq;
@@ -414,6 +416,11 @@ static void ide_identify(IDEState *s) @@ -414,6 +416,11 @@ static void ide_identify(IDEState *s)
414 unsigned int oldsize; 416 unsigned int oldsize;
415 char buf[20]; 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 memset(s->io_buffer, 0, 512); 424 memset(s->io_buffer, 0, 512);
418 p = (uint16_t *)s->io_buffer; 425 p = (uint16_t *)s->io_buffer;
419 put_le16(p + 0, 0x0040); 426 put_le16(p + 0, 0x0040);
@@ -433,10 +440,10 @@ static void ide_identify(IDEState *s) @@ -433,10 +440,10 @@ static void ide_identify(IDEState *s)
433 put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS); 440 put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
434 #endif 441 #endif
435 put_le16(p + 48, 1); /* dword I/O */ 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 put_le16(p + 51, 0x200); /* PIO transfer cycle */ 444 put_le16(p + 51, 0x200); /* PIO transfer cycle */
438 put_le16(p + 52, 0x200); /* DMA transfer cycle */ 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 put_le16(p + 54, s->cylinders); 447 put_le16(p + 54, s->cylinders);
441 put_le16(p + 55, s->heads); 448 put_le16(p + 55, s->heads);
442 put_le16(p + 56, s->sectors); 449 put_le16(p + 56, s->sectors);
@@ -447,15 +454,24 @@ static void ide_identify(IDEState *s) @@ -447,15 +454,24 @@ static void ide_identify(IDEState *s)
447 put_le16(p + 59, 0x100 | s->mult_sectors); 454 put_le16(p + 59, 0x100 | s->mult_sectors);
448 put_le16(p + 60, s->nb_sectors); 455 put_le16(p + 60, s->nb_sectors);
449 put_le16(p + 61, s->nb_sectors >> 16); 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 put_le16(p + 82, (1 << 14)); 464 put_le16(p + 82, (1 << 14));
452 put_le16(p + 83, (1 << 14)); 465 put_le16(p + 83, (1 << 14));
453 put_le16(p + 84, (1 << 14)); 466 put_le16(p + 84, (1 << 14));
454 put_le16(p + 85, (1 << 14)); 467 put_le16(p + 85, (1 << 14));
455 put_le16(p + 86, 0); 468 put_le16(p + 86, 0);
456 put_le16(p + 87, (1 << 14)); 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 static void ide_atapi_identify(IDEState *s) 477 static void ide_atapi_identify(IDEState *s)
@@ -463,6 +479,11 @@ static void ide_atapi_identify(IDEState *s) @@ -463,6 +479,11 @@ static void ide_atapi_identify(IDEState *s)
463 uint16_t *p; 479 uint16_t *p;
464 char buf[20]; 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 memset(s->io_buffer, 0, 512); 487 memset(s->io_buffer, 0, 512);
467 p = (uint16_t *)s->io_buffer; 488 p = (uint16_t *)s->io_buffer;
468 /* Removable CDROM, 50us response, 12 byte packets */ 489 /* Removable CDROM, 50us response, 12 byte packets */
@@ -483,11 +504,14 @@ static void ide_atapi_identify(IDEState *s) @@ -483,11 +504,14 @@ static void ide_atapi_identify(IDEState *s)
483 put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */ 504 put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */
484 put_le16(p + 67, 0x12c); /* minimum PIO cycle time without flow control */ 505 put_le16(p + 67, 0x12c); /* minimum PIO cycle time without flow control */
485 put_le16(p + 68, 0xb4); /* minimum PIO cycle time with IORDY flow control */ 506 put_le16(p + 68, 0xb4); /* minimum PIO cycle time with IORDY flow control */
486 - 507 +
487 put_le16(p + 71, 30); /* in ns */ 508 put_le16(p + 71, 30); /* in ns */
488 put_le16(p + 72, 30); /* in ns */ 509 put_le16(p + 72, 30); /* in ns */
489 510
490 put_le16(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */ 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 static void ide_set_signature(IDEState *s) 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,13 +1625,36 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1601 /* XXX: valid for CDROM ? */ 1625 /* XXX: valid for CDROM ? */
1602 switch(s->feature) { 1626 switch(s->feature) {
1603 case 0x02: /* write cache enable */ 1627 case 0x02: /* write cache enable */
1604 - case 0x03: /* set transfer mode */  
1605 case 0x82: /* write cache disable */ 1628 case 0x82: /* write cache disable */
1606 case 0xaa: /* read look-ahead enable */ 1629 case 0xaa: /* read look-ahead enable */
1607 case 0x55: /* read look-ahead disable */ 1630 case 0x55: /* read look-ahead disable */
1608 s->status = READY_STAT | SEEK_STAT; 1631 s->status = READY_STAT | SEEK_STAT;
1609 ide_set_irq(s); 1632 ide_set_irq(s);
1610 break; 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 default: 1658 default:
1612 goto abort_cmd; 1659 goto abort_cmd;
1613 } 1660 }