Revision ed487bb1

b/hw/ide/core.c
2650 2650
        s->unit = i;
2651 2651
        s->drive_serial = drive_serial++;
2652 2652
        s->io_buffer = qemu_blockalign(s->bs, IDE_DMA_BUF_SECTORS*512 + 4);
2653
        s->io_buffer_total_len = IDE_DMA_BUF_SECTORS*512 + 4;
2653 2654
        s->smart_selftest_data = qemu_blockalign(s->bs, 512);
2654 2655
        s->sector_write_timer = qemu_new_timer(vm_clock,
2655 2656
                                               ide_sector_write_timer_cb, s);
......
2684 2685
    return s->identify_set != 0;
2685 2686
}
2686 2687

  
2688
static EndTransferFunc* transfer_end_table[] = {
2689
        ide_sector_read,
2690
        ide_sector_write,
2691
        ide_transfer_stop,
2692
        ide_atapi_cmd_reply_end,
2693
        ide_atapi_cmd,
2694
};
2695

  
2696
static int transfer_end_table_idx(EndTransferFunc *fn)
2697
{
2698
    int i;
2699

  
2700
    for (i = 0; i < ARRAY_SIZE(transfer_end_table); i++)
2701
        if (transfer_end_table[i] == fn)
2702
            return i;
2703

  
2704
    return -1;
2705
}
2706

  
2687 2707
static int ide_drive_post_load(void *opaque, int version_id)
2688 2708
{
2689 2709
    IDEState *s = opaque;
......
2694 2714
            s->cdrom_changed = 1;
2695 2715
        }
2696 2716
    }
2717

  
2718
    if (s->cur_io_buffer_len) {
2719
        s->end_transfer_func = transfer_end_table[s->end_transfer_fn_idx];
2720
        s->data_ptr = s->io_buffer + s->cur_io_buffer_offset;
2721
        s->data_end = s->data_ptr + s->cur_io_buffer_len;
2722
    }
2723
        
2697 2724
    return 0;
2698 2725
}
2699 2726

  
2727
static void ide_drive_pre_save(void *opaque)
2728
{
2729
    IDEState *s = opaque;
2730

  
2731
    s->cur_io_buffer_len = 0;
2732

  
2733
    if (!(s->status & DRQ_STAT))
2734
        return;
2735

  
2736
    s->cur_io_buffer_offset = s->data_ptr - s->io_buffer;
2737
    s->cur_io_buffer_len = s->data_end - s->data_ptr;
2738

  
2739
    s->end_transfer_fn_idx = transfer_end_table_idx(s->end_transfer_func);
2740
    if (s->end_transfer_fn_idx == -1) {
2741
        fprintf(stderr, "%s: invalid end_transfer_func for DRQ_STAT\n",
2742
                        __func__);
2743
        s->end_transfer_fn_idx = 2;
2744
    }
2745
}
2746

  
2700 2747
const VMStateDescription vmstate_ide_drive = {
2701 2748
    .name = "ide_drive",
2702
    .version_id = 3,
2749
    .version_id = 4,
2703 2750
    .minimum_version_id = 0,
2704 2751
    .minimum_version_id_old = 0,
2752
    .pre_save = ide_drive_pre_save,
2705 2753
    .post_load = ide_drive_post_load,
2706 2754
    .fields      = (VMStateField []) {
2707 2755
        VMSTATE_INT32(mult_sectors, IDEState),
......
2724 2772
        VMSTATE_UINT8(sense_key, IDEState),
2725 2773
        VMSTATE_UINT8(asc, IDEState),
2726 2774
        VMSTATE_UINT8_V(cdrom_changed, IDEState, 3),
2727
        /* XXX: if a transfer is pending, we do not save it yet */
2775
        VMSTATE_INT32_V(req_nb_sectors, IDEState, 4),
2776
        VMSTATE_VARRAY_INT32(io_buffer, IDEState, io_buffer_total_len, 4,
2777
			     vmstate_info_uint8, uint8_t),
2778
        VMSTATE_INT32_V(cur_io_buffer_offset, IDEState, 4),
2779
        VMSTATE_INT32_V(cur_io_buffer_len, IDEState, 4),
2780
        VMSTATE_UINT8_V(end_transfer_fn_idx, IDEState, 4),
2781
        VMSTATE_INT32_V(elementary_transfer_size, IDEState, 4),
2782
        VMSTATE_INT32_V(packet_transfer_size, IDEState, 4),
2728 2783
        VMSTATE_END_OF_LIST()
2729 2784
    }
2730 2785
};
b/hw/ide/internal.h
419 419
    uint8_t *data_ptr;
420 420
    uint8_t *data_end;
421 421
    uint8_t *io_buffer;
422
    /* PIO save/restore */
423
    int32_t io_buffer_total_len;
424
    int cur_io_buffer_offset;
425
    int cur_io_buffer_len;
426
    uint8_t end_transfer_fn_idx;
422 427
    QEMUTimer *sector_write_timer; /* only used for win2k install hack */
423 428
    uint32_t irq_count; /* counts IRQs when using win2k install hack */
424 429
    /* CF-ATA extended error */

Also available in: Unified diff