qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] ide.c make write cacheing controllable by guest


From: Ian Jackson
Subject: Re: [Qemu-devel] [PATCH] ide.c make write cacheing controllable by guest
Date: Fri, 28 Mar 2008 09:38:59 +0000

Paul Brook writes ("Re: [Qemu-devel] [PATCH] ide.c make write cacheing 
controllable by guest"):
> On Thursday 27 March 2008, Ian Jackson wrote:
> >              case 0xcc: /* reverting to power-on defaults enable */
> >              case 0x66: /* reverting to power-on defaults disable */
> >              case 0x02: /* write cache enable */
> > +                s->write_cache = 1;
> 
> This look wrong.

Oops, that must have been my fault when I ported this feature from
xen-unstable's hg.  Here is a fixed version.

Thanks,
Ian.

diff --git a/hw/ide.c b/hw/ide.c
index b73dba2..0fb58e7 100644
--- a/hw/ide.c
+++ b/hw/ide.c
@@ -383,6 +383,7 @@ typedef struct IDEState {
     PCIDevice *pci_dev;
     struct BMDMAState *bmdma;
     int drive_serial;
+    int write_cache;
     /* ide regs */
     uint8_t feature;
     uint8_t error;
@@ -559,7 +560,8 @@ static void ide_identify(IDEState *s)
     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));
+    /* 14=nop 5=write_cache */
+    put_le16(p + 82, (1 << 14) | (1 << 5));
     /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
     put_le16(p + 83, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
     put_le16(p + 84, (1 << 14));
@@ -965,6 +967,9 @@ static void ide_sector_write(IDEState *s)
     if (n > s->req_nb_sectors)
         n = s->req_nb_sectors;
     ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
+    if (ret == 0 && !s->write_cache) {
+       ret = bdrv_flush(s->bs);
+    }
     if (ret != 0) {
        ide_rw_error(s);
        return;
@@ -1021,6 +1026,13 @@ static void ide_write_dma_cb(void *opaque, int ret)
 
     /* end of transfer ? */
     if (s->nsector == 0) {
+       if (!s->write_cache) {
+           ret = bdrv_flush(s->bs);
+           if (ret != 0) {
+               ide_dma_error(s);
+               return;
+           }
+       }
         s->status = READY_STAT | SEEK_STAT;
         ide_set_irq(s);
     eot:
@@ -2102,8 +2114,6 @@ static void ide_ioport_write(void *opaque, uint32_t addr, 
uint32_t val)
             switch(s->feature) {
             case 0xcc: /* reverting to power-on defaults enable */
             case 0x66: /* reverting to power-on defaults disable */
-            case 0x02: /* write cache enable */
-            case 0x82: /* write cache disable */
             case 0xaa: /* read look-ahead enable */
             case 0x55: /* read look-ahead disable */
             case 0x05: /* set advanced power management mode */
@@ -2117,6 +2127,18 @@ static void ide_ioport_write(void *opaque, uint32_t 
addr, uint32_t val)
                 s->status = READY_STAT | SEEK_STAT;
                 ide_set_irq(s);
                 break;
+            case 0x02: /* write cache enable */
+                s->write_cache = 1;
+                s->status = READY_STAT | SEEK_STAT;
+                ide_set_irq(s);
+                break;
+            case 0x82: /* write cache disable */
+                s->write_cache = 0;
+                ret = bdrv_flush(s->bs);
+               if (ret != 0) goto abort_cmd;
+                s->status = READY_STAT | SEEK_STAT;
+                ide_set_irq(s);
+                break;
             case 0x03: { /* set transfer mode */
                uint8_t val = s->nsector & 0x07;
 
@@ -2629,6 +2651,7 @@ static void ide_init2(IDEState *ide_state,
         s->irq = irq;
         s->sector_write_timer = qemu_new_timer(vm_clock,
                                                ide_sector_write_timer_cb, s);
+       s->write_cache = 0;
         ide_reset(s);
     }
 }
@@ -2657,6 +2680,7 @@ static void ide_save(QEMUFile* f, IDEState *s)
     if (s->identify_set) {
         qemu_put_buffer(f, (const uint8_t *)s->identify_data, 512);
     }
+    qemu_put_8s(f, &s->write_cache);
     qemu_put_8s(f, &s->feature);
     qemu_put_8s(f, &s->error);
     qemu_put_be32s(f, &s->nsector);
@@ -2685,6 +2709,8 @@ static void ide_load(QEMUFile* f, IDEState *s)
     if (s->identify_set) {
         qemu_get_buffer(f, (uint8_t *)s->identify_data, 512);
     }
+    if (version_id >= 2)
+       qemu_get_8s(f, &s->write_cache);
     qemu_get_8s(f, &s->feature);
     qemu_get_8s(f, &s->error);
     qemu_get_be32s(f, &s->nsector);
@@ -3029,7 +3055,7 @@ static int pci_ide_load(QEMUFile* f, void *opaque, int 
version_id)
     PCIIDEState *d = opaque;
     int ret, i;
 
-    if (version_id != 1)
+    if (version_id != 1 && version_id != 2)
         return -EINVAL;
     ret = pci_device_load(&d->dev, f);
     if (ret < 0)
@@ -3105,7 +3131,7 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState 
**hd_table, int devfn,
     ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
     ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
 
-    register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
+    register_savevm("ide", 0, 2, pci_ide_save, pci_ide_load, d);
 }
 
 /* hd_table must contain 4 block drivers */
@@ -3143,7 +3169,7 @@ void pci_piix4_ide_init(PCIBus *bus, BlockDriverState 
**hd_table, int devfn,
     ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
     ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
 
-    register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
+    register_savevm("ide", 0, 2, pci_ide_save, pci_ide_load, d);
 }
 
 /***********************************************************/

reply via email to

[Prev in Thread] Current Thread [Next in Thread]