Replace the is_read flag with a dma_cmd flag to allow the dma and restart logic to handler other commands like TRIM.
Signed-off-by: Christoph Hellwig <h...@lst.de> Index: qemu/hw/ide/core.c =================================================================== --- qemu.orig/hw/ide/core.c 2011-05-18 20:24:04.318125593 +0200 +++ qemu/hw/ide/core.c 2011-05-18 20:30:20.855172933 +0200 @@ -473,7 +473,7 @@ handle_rw_error: if (ret < 0) { int op = BM_STATUS_DMA_RETRY; - if (s->is_read) + if (s->dma_cmd == IDE_DMA_READ) op |= BM_STATUS_RETRY_READ; if (ide_handle_rw_error(s, -ret, op)) { return; @@ -483,7 +483,7 @@ handle_rw_error: n = s->io_buffer_size >> 9; sector_num = ide_get_sector(s); if (n > 0) { - dma_buf_commit(s, s->is_read); + dma_buf_commit(s, ide_cmd_is_read(s)); sector_num += n; ide_set_sector(s, sector_num); s->nsector -= n; @@ -500,20 +500,23 @@ handle_rw_error: n = s->nsector; s->io_buffer_index = 0; s->io_buffer_size = n * 512; - if (s->bus->dma->ops->prepare_buf(s->bus->dma, s->is_read) == 0) + if (s->bus->dma->ops->prepare_buf(s->bus->dma, ide_cmd_is_read(s)) == 0) goto eot; #ifdef DEBUG_AIO - printf("ide_dma_cb: sector_num=%" PRId64 " n=%d, is_read=%d\n", - sector_num, n, s->is_read); + printf("ide_dma_cb: sector_num=%" PRId64 " n=%d, cmd_cmd=%d\n", + sector_num, n, s->dma_cmd); #endif - if (s->is_read) { + switch (s->dma_cmd) { + case IDE_DMA_READ: s->bus->dma->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num, ide_dma_cb, s); - } else { + break; + case IDE_DMA_WRITE: s->bus->dma->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num, ide_dma_cb, s); + break; } if (!s->bus->dma->aiocb) { @@ -527,12 +530,12 @@ eot: ide_set_inactive(s); } -static void ide_sector_start_dma(IDEState *s, int is_read) +static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd) { s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT; s->io_buffer_index = 0; s->io_buffer_size = 0; - s->is_read = is_read; + s->dma_cmd = dma_cmd; s->bus->dma->ops->start_dma(s->bus->dma, s, ide_dma_cb); } @@ -915,7 +918,7 @@ void ide_exec_cmd(IDEBus *bus, uint32_t if (!s->bs) goto abort_cmd; ide_cmd_lba48_transform(s, lba48); - ide_sector_start_dma(s, 1); + ide_sector_start_dma(s, IDE_DMA_READ); break; case WIN_WRITEDMA_EXT: lba48 = 1; @@ -924,7 +927,7 @@ void ide_exec_cmd(IDEBus *bus, uint32_t if (!s->bs) goto abort_cmd; ide_cmd_lba48_transform(s, lba48); - ide_sector_start_dma(s, 0); + ide_sector_start_dma(s, IDE_DMA_WRITE); s->media_changed = 1; break; case WIN_READ_NATIVE_MAX_EXT: Index: qemu/hw/ide/internal.h =================================================================== --- qemu.orig/hw/ide/internal.h 2011-05-18 20:24:04.334126497 +0200 +++ qemu/hw/ide/internal.h 2011-05-18 20:28:17.133626100 +0200 @@ -379,6 +379,14 @@ struct unreported_events { bool new_media; }; +enum ide_dma_cmd { + IDE_DMA_READ, + IDE_DMA_WRITE, +}; + +#define ide_cmd_is_read(s) \ + ((s)->dma_cmd == IDE_DMA_READ) + /* NOTE: IDEState represents in fact one drive */ struct IDEState { IDEBus *bus; @@ -446,7 +454,7 @@ struct IDEState { uint32_t mdata_size; uint8_t *mdata_storage; int media_changed; - int is_read; + enum ide_dma_cmd dma_cmd; /* SMART */ uint8_t smart_enabled; uint8_t smart_autosave; Index: qemu/hw/ide/macio.c =================================================================== --- qemu.orig/hw/ide/macio.c 2011-05-18 20:24:04.346126902 +0200 +++ qemu/hw/ide/macio.c 2011-05-18 20:28:17.145627191 +0200 @@ -145,12 +145,17 @@ static void pmac_ide_transfer_cb(void *o io->addr += io->len; io->len = 0; - if (s->is_read) + switch (s->dma_cmd) { + case IDE_DMA_READ: m->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num, pmac_ide_transfer_cb, io); - else + break; + case IDE_DMA_WRITE: m->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num, pmac_ide_transfer_cb, io); + break; + } + if (!m->aiocb) pmac_ide_transfer_cb(io, -1); } Index: qemu/hw/ide/pci.c =================================================================== --- qemu.orig/hw/ide/pci.c 2011-05-18 20:24:04.362126865 +0200 +++ qemu/hw/ide/pci.c 2011-05-18 20:28:17.153625872 +0200 @@ -169,7 +169,7 @@ static int bmdma_set_inactive(IDEDMA *dm return 0; } -static void bmdma_restart_dma(BMDMAState *bm, int is_read) +static void bmdma_restart_dma(BMDMAState *bm, enum ide_dma_cmd dma_cmd) { IDEState *s = bmdma_active_if(bm); @@ -177,7 +177,7 @@ static void bmdma_restart_dma(BMDMAState s->io_buffer_index = 0; s->io_buffer_size = 0; s->nsector = bm->nsector; - s->is_read = is_read; + s->dma_cmd = dma_cmd; bm->cur_addr = bm->addr; bm->dma_cb = ide_dma_cb; bmdma_start_dma(&bm->dma, s, bm->dma_cb); @@ -195,7 +195,7 @@ static void bmdma_restart_bh(void *opaqu if (bm->status & BM_STATUS_DMA_RETRY) { bm->status &= ~(BM_STATUS_DMA_RETRY | BM_STATUS_RETRY_READ); - bmdma_restart_dma(bm, is_read); + bmdma_restart_dma(bm, is_read ? IDE_DMA_READ : IDE_DMA_WRITE); } else if (bm->status & BM_STATUS_PIO_RETRY) { bm->status &= ~(BM_STATUS_PIO_RETRY | BM_STATUS_RETRY_READ); if (is_read) {