diff -rbu qemu.orig/hw/ide.c qemu/hw/ide.c --- qemu.orig/hw/ide.c 2004-12-02 23:20:21.000000000 +0300 +++ qemu/hw/ide.c 2004-12-17 14:06:15.000000000 +0300 @@ -332,8 +332,12 @@ uint8_t *data_ptr; uint8_t *data_end; uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4]; + int ide_set_irq_from_timer; } IDEState; +volatile int ide_set_irq_from_timer; +static IDEState *IDEStates[4]; + #define BM_STATUS_DMAING 0x01 #define BM_STATUS_ERROR 0x02 #define BM_STATUS_INT 0x04 @@ -512,6 +516,21 @@ } } +void make_ide_set_irq(void) +{ + int i; + IDEState *s; + + ide_set_irq_from_timer--; + for(i = 0; (s=IDEStates[i]) != NULL; i++) { + if(s->ide_set_irq_from_timer) { + s->ide_set_irq_from_timer--; + ide_set_irq(s); + break; + } + } +} + /* prepare data transfer and tell what to do after */ static void ide_transfer_start(IDEState *s, uint8_t *buf, int size, EndTransferFunc *end_transfer_func) @@ -667,7 +686,11 @@ ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write); } ide_set_sector(s, sector_num + n); + if(s->ide_set_irq_from_timer) { + ide_set_irq_from_timer++; + } else { ide_set_irq(s); + } } static int ide_write_dma_cb(IDEState *s, @@ -1511,6 +1534,7 @@ s->error = 0; s->status = SEEK_STAT | READY_STAT; s->req_nb_sectors = 1; + s->ide_set_irq_from_timer = 1; ide_transfer_start(s, s->io_buffer, 512, ide_sector_write); break; case WIN_MULTREAD: @@ -1528,6 +1552,7 @@ n = s->nsector; if (n > s->req_nb_sectors) n = s->req_nb_sectors; + s->ide_set_irq_from_timer = 1; ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write); break; case WIN_READDMA: @@ -1883,6 +1908,7 @@ for(i = 0; i < 2; i++) { s = ide_state + i; + IDEStates[drive_serial-1] = s; if (i == 0) s->bs = hd0; else diff -rbu qemu.orig/vl.c qemu/vl.c --- qemu.orig/vl.c 2004-12-13 01:20:04.000000000 +0300 +++ qemu/vl.c 2004-12-17 12:41:16.000000000 +0300 @@ -911,7 +911,7 @@ /* timer signal */ sigfillset(&act.sa_mask); - act.sa_flags = 0; + act.sa_flags = SA_RESTART; #if defined (TARGET_I386) && defined(USE_CODE_COPY) act.sa_flags |= SA_ONSTACK; #endif @@ -2403,7 +2403,12 @@ int n, max_size; #endif int ret; + /* ide.c hack */ + extern volatile int ide_set_irq_from_timer; + extern void make_ide_set_irq(void); + if(ide_set_irq_from_timer) + make_ide_set_irq(); #ifdef _WIN32 if (timeout > 0) Sleep(timeout); @@ -2449,8 +2454,6 @@ n = read(ioh->fd, buf, ioh->max_size); if (n >= 0) { ioh->fd_read(ioh->opaque, buf, n); - } else if (errno != EAGAIN) { - ioh->fd_read(ioh->opaque, NULL, -errno); } } }