[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 1/3] ide id updates
From: |
Jens Axboe |
Subject: |
[Qemu-devel] [PATCH 1/3] ide id updates |
Date: |
Wed, 4 Jan 2006 13:12:57 +0100 |
Hi,
Subject: [PATCH] ide id updates
From: Jens Axboe <address@hidden>
Date: 1136375788 +0100
Some changes to the ata/atapi identify code and default values:
- Store the drive id in the IDEState, so we can reliably set and query
new values. Right now doing things like:
doesn't work, as the IDENTIFY command will re-fill default values
everytime.
- Fill in IORDY, dma timings, and mdma modes.
- Don't set both 1 << 14 and 0x4000 for word 93, it's the same thing.
- Fill in supported/set ata specs
- Implement real setting of transfer mode (sub feature 0x03 of
WIN_SETFEATURES) so we can reflect the transfer mode requested by the
OS.
With this patch, Linux correctly identifies and sets DMA mode in the
drive by default.
---
hw/ide.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 54 insertions(+), 7 deletions(-)
eaa17552cf9891cbc8fc46b826fde10a4d5e07c7
diff --git a/hw/ide.c b/hw/ide.c
index 28ed5ab..8196ace 100644
--- a/hw/ide.c
+++ b/hw/ide.c
@@ -296,6 +296,8 @@ typedef struct IDEState {
int cylinders, heads, sectors;
int64_t nb_sectors;
int mult_sectors;
+ int identify_set;
+ uint16_t identify_data[256];
SetIRQFunc *set_irq;
void *irq_opaque;
int irq;
@@ -414,6 +416,11 @@ static void ide_identify(IDEState *s)
unsigned int oldsize;
char buf[20];
+ if (s->identify_set) {
+ memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
+ return;
+ }
+
memset(s->io_buffer, 0, 512);
p = (uint16_t *)s->io_buffer;
put_le16(p + 0, 0x0040);
@@ -433,10 +440,10 @@ static void ide_identify(IDEState *s)
put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
#endif
put_le16(p + 48, 1); /* dword I/O */
- put_le16(p + 49, 1 << 9 | 1 << 8); /* DMA and LBA supported */
+ put_le16(p + 49, (1 << 11) | (1 << 9) | (1 << 8)); /* DMA and LBA
supported */
put_le16(p + 51, 0x200); /* PIO transfer cycle */
put_le16(p + 52, 0x200); /* DMA transfer cycle */
- put_le16(p + 53, 1 | 1 << 2); /* words 54-58,88 are valid */
+ put_le16(p + 53, 1 | 1 << 1 | 1 << 2); /* words 54-58,64-70,88 are valid */
put_le16(p + 54, s->cylinders);
put_le16(p + 55, s->heads);
put_le16(p + 56, s->sectors);
@@ -447,15 +454,24 @@ static void ide_identify(IDEState *s)
put_le16(p + 59, 0x100 | s->mult_sectors);
put_le16(p + 60, s->nb_sectors);
put_le16(p + 61, s->nb_sectors >> 16);
- put_le16(p + 80, (1 << 1) | (1 << 2));
+ put_le16(p + 63, 0x07); /* mdma0-2 supported */
+ put_le16(p + 65, 120);
+ put_le16(p + 66, 120);
+ put_le16(p + 67, 120);
+ put_le16(p + 68, 120);
+ put_le16(p + 80, 0xf0); /* ata3 -> ata6 supported */
+ put_le16(p + 81, 0x16); /* conforms to ata5 */
put_le16(p + 82, (1 << 14));
put_le16(p + 83, (1 << 14));
put_le16(p + 84, (1 << 14));
put_le16(p + 85, (1 << 14));
put_le16(p + 86, 0);
put_le16(p + 87, (1 << 14));
- put_le16(p + 88, 0x1f | (1 << 13));
- put_le16(p + 93, 1 | (1 << 14) | 0x2000 | 0x4000);
+ put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
+ put_le16(p + 93, 1 | (1 << 14) | 0x2000);
+
+ memcpy(s->identify_data, p, sizeof(s->identify_data));
+ s->identify_set = 1;
}
static void ide_atapi_identify(IDEState *s)
@@ -463,6 +479,11 @@ static void ide_atapi_identify(IDEState
uint16_t *p;
char buf[20];
+ if (s->identify_set) {
+ memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
+ return;
+ }
+
memset(s->io_buffer, 0, 512);
p = (uint16_t *)s->io_buffer;
/* Removable CDROM, 50us response, 12 byte packets */
@@ -483,11 +504,14 @@ static void ide_atapi_identify(IDEState
put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */
put_le16(p + 67, 0x12c); /* minimum PIO cycle time without flow control */
put_le16(p + 68, 0xb4); /* minimum PIO cycle time with IORDY flow control
*/
-
+
put_le16(p + 71, 30); /* in ns */
put_le16(p + 72, 30); /* in ns */
put_le16(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */
+
+ memcpy(s->identify_data, p, sizeof(s->identify_data));
+ s->identify_set = 1;
}
static void ide_set_signature(IDEState *s)
@@ -1601,13 +1625,36 @@ static void ide_ioport_write(void *opaqu
/* XXX: valid for CDROM ? */
switch(s->feature) {
case 0x02: /* write cache enable */
- case 0x03: /* set transfer mode */
case 0x82: /* write cache disable */
case 0xaa: /* read look-ahead enable */
case 0x55: /* read look-ahead disable */
s->status = READY_STAT | SEEK_STAT;
ide_set_irq(s);
break;
+ case 0x03: { /* set transfer mode */
+ uint8_t val = s->nsector & 0x07;
+
+ switch (s->nsector >> 3) {
+ case 0x00: /* pio default */
+ case 0x01: /* pio mode */
+ put_le16(s->identify_data + 63,0x07);
+ put_le16(s->identify_data + 88,0x3f);
+ break;
+ case 0x04: /* mdma mode */
+ put_le16(s->identify_data + 63,0x07 | (1 << (val + 8)));
+ put_le16(s->identify_data + 88,0x3f);
+ break;
+ case 0x08: /* udma mode */
+ put_le16(s->identify_data + 63,0x07);
+ put_le16(s->identify_data + 88,0x3f | (1 << (val + 8)));
+ break;
+ default:
+ goto abort_cmd;
+ }
+ s->status = READY_STAT | SEEK_STAT;
+ ide_set_irq(s);
+ break;
+ }
default:
goto abort_cmd;
}
--
1.0.GIT
--
Jens Axboe
[Qemu-devel] [PATCH 2/3] ide lba48 support, Jens Axboe, 2006/01/04
[Qemu-devel] [PATCH 1/3] ide id updates,
Jens Axboe <=