All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jens Axboe <qemu@kernel.dk>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH] ide id updates
Date: Tue, 3 Jan 2006 20:43:55 +0100	[thread overview]
Message-ID: <20060103194354.GZ2772@suse.de> (raw)

Hi,

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:

# hdparm -Xudma2 /dev/hda
# hdparm -i /dev/hda (and check for mode)

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.

Fabrice, let me know if you will merge this. I need to post another
little update for the lba48 support patch (needed a cast for hob filling
in ide_set_sector() to work correctly for really big disks), since I
need to rebase that on top of this patch.

Index: hw/ide.c
===================================================================
RCS file: /sources/qemu/qemu/hw/ide.c,v
retrieving revision 1.38
diff -u -r1.38 ide.c
--- hw/ide.c	6 Aug 2005 09:14:32 -0000	1.38
+++ hw/ide.c	3 Jan 2006 19:35:06 -0000
@@ -296,6 +296,8 @@
     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 @@
     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 @@
     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 @@
         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 @@
     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 @@
     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 @@
             /* 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;
             }

-- 
Jens Axboe

                 reply	other threads:[~2006-01-03 19:43 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20060103194354.GZ2772@suse.de \
    --to=qemu@kernel.dk \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.