Commit 72c7b06cb7e0cfded2678d531c454fcac16c93c3

Authored by aliguori
1 parent 414f0dab

Cancel IDE outstanding IO on device reset (Gleb Natapov)

Cancel AIO in IDE layer on device rest in order to be in deterministic state
during next boot.

Signed-off-by: Gleb Natapov <gleb@qumranet.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5011 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 26 additions and 14 deletions
hw/ide.c
@@ -2844,6 +2844,23 @@ static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb) @@ -2844,6 +2844,23 @@ static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb)
2844 } 2844 }
2845 } 2845 }
2846 2846
  2847 +static void ide_dma_cancel(BMDMAState *bm)
  2848 +{
  2849 + if (bm->status & BM_STATUS_DMAING) {
  2850 + bm->status &= ~BM_STATUS_DMAING;
  2851 + /* cancel DMA request */
  2852 + bm->ide_if = NULL;
  2853 + bm->dma_cb = NULL;
  2854 + if (bm->aiocb) {
  2855 +#ifdef DEBUG_AIO
  2856 + printf("aio_cancel\n");
  2857 +#endif
  2858 + bdrv_aio_cancel(bm->aiocb);
  2859 + bm->aiocb = NULL;
  2860 + }
  2861 + }
  2862 +}
  2863 +
2847 static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val) 2864 static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
2848 { 2865 {
2849 BMDMAState *bm = opaque; 2866 BMDMAState *bm = opaque;
@@ -2852,19 +2869,7 @@ static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val) @@ -2852,19 +2869,7 @@ static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
2852 #endif 2869 #endif
2853 if (!(val & BM_CMD_START)) { 2870 if (!(val & BM_CMD_START)) {
2854 /* XXX: do it better */ 2871 /* XXX: do it better */
2855 - if (bm->status & BM_STATUS_DMAING) {  
2856 - bm->status &= ~BM_STATUS_DMAING;  
2857 - /* cancel DMA request */  
2858 - bm->ide_if = NULL;  
2859 - bm->dma_cb = NULL;  
2860 - if (bm->aiocb) {  
2861 -#ifdef DEBUG_AIO  
2862 - printf("aio_cancel\n");  
2863 -#endif  
2864 - bdrv_aio_cancel(bm->aiocb);  
2865 - bm->aiocb = NULL;  
2866 - }  
2867 - } 2872 + ide_dma_cancel(bm);
2868 bm->cmd = val & 0x09; 2873 bm->cmd = val & 0x09;
2869 } else { 2874 } else {
2870 if (!(bm->status & BM_STATUS_DMAING)) { 2875 if (!(bm->status & BM_STATUS_DMAING)) {
@@ -3188,9 +3193,14 @@ static int pci_ide_load(QEMUFile* f, void *opaque, int version_id) @@ -3188,9 +3193,14 @@ static int pci_ide_load(QEMUFile* f, void *opaque, int version_id)
3188 return 0; 3193 return 0;
3189 } 3194 }
3190 3195
3191 -static void piix3_reset(PCIIDEState *d) 3196 +static void piix3_reset(void *opaque)
3192 { 3197 {
  3198 + PCIIDEState *d = opaque;
3193 uint8_t *pci_conf = d->dev.config; 3199 uint8_t *pci_conf = d->dev.config;
  3200 + int i;
  3201 +
  3202 + for (i = 0; i < 2; i++)
  3203 + ide_dma_cancel(&d->bmdma[i]);
3194 3204
3195 pci_conf[0x04] = 0x00; 3205 pci_conf[0x04] = 0x00;
3196 pci_conf[0x05] = 0x00; 3206 pci_conf[0x05] = 0x00;
@@ -3224,6 +3234,7 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn, @@ -3224,6 +3234,7 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
3224 pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage 3234 pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
3225 pci_conf[0x0e] = 0x00; // header_type 3235 pci_conf[0x0e] = 0x00; // header_type
3226 3236
  3237 + qemu_register_reset(piix3_reset, d);
3227 piix3_reset(d); 3238 piix3_reset(d);
3228 3239
3229 pci_register_io_region((PCIDevice *)d, 4, 0x10, 3240 pci_register_io_region((PCIDevice *)d, 4, 0x10,
@@ -3262,6 +3273,7 @@ void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn, @@ -3262,6 +3273,7 @@ void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
3262 pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage 3273 pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
3263 pci_conf[0x0e] = 0x00; // header_type 3274 pci_conf[0x0e] = 0x00; // header_type
3264 3275
  3276 + qemu_register_reset(piix3_reset, d);
3265 piix3_reset(d); 3277 piix3_reset(d);
3266 3278
3267 pci_register_io_region((PCIDevice *)d, 4, 0x10, 3279 pci_register_io_region((PCIDevice *)d, 4, 0x10,