PCIDevice *pci_dev;
struct BMDMAState *bmdma;
int drive_serial;
+ int write_cache;
/* ide regs */
uint8_t feature;
uint8_t error;
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));
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;
/* 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:
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;
+ 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 0xaa: /* read look-ahead enable */
case 0x55: /* read look-ahead disable */
case 0x05: /* set advanced power management mode */
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);
}
}