# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Date 1193024674 -32400 # Node ID ceee54c9f9f0a43b3b13b972c49a15ef32f7fc73 # Parent 208908de6975954de268fdbc42db8067f5b64eeb make buffered pio aware of save/load. PATCHNAME: save_load_for_buffered_pio Signed-off-by: Isaku Yamahata diff -r 208908de6975 -r ceee54c9f9f0 tools/ioemu/hw/ide.c --- a/tools/ioemu/hw/ide.c Wed Oct 17 15:29:44 2007 +0900 +++ b/tools/ioemu/hw/ide.c Mon Oct 22 12:44:34 2007 +0900 @@ -431,16 +431,21 @@ buffered_pio_init(void) } static inline void +__buffered_pio_flush(struct pio_buffer *piobuf, IDEState *s, uint32_t pointer) +{ + uint8_t *buf = (uint8_t *)buffered_pio_page + piobuf->page_offset; + memcpy(s->data_ptr, buf, pointer); + s->data_ptr += pointer; +} + +static inline void buffered_pio_flush(struct pio_buffer *piobuf) { IDEState *s = piobuf->opaque; uint32_t pointer = piobuf->pointer; - if (s != NULL && pointer > 0) { - uint8_t *buf = (uint8_t *)buffered_pio_page + piobuf->page_offset; - memcpy(s->data_ptr, buf, pointer); - s->data_ptr += pointer; - } + if (s != NULL && pointer > 0) + __buffered_pio_flush(piobuf, s, pointer); } static inline void @@ -500,6 +505,54 @@ buffered_pio_read(IDEState *s, uint32_t piobuf->pointer = 0; piobuf->data_end = data_end; piobuf->opaque = NULL; +} + +/* + * buffered pio reads are undone. It results in normal pio when the domain + * is restored. + * buffered pio writes are handled before saving domain. + * However currently pci_ide_save/load() just discards a pending transfer. XXX + */ +static void +__handle_buffered_pio(struct pio_buffer *piobuf) +{ + IDEState *s = piobuf->opaque; + uint32_t pointer = piobuf->pointer; + + + if (pointer == 0) + return;/* no buffered pio */ + + if (s != NULL) { + /* written data are pending in pio_buffer. process it */ + __buffered_pio_flush(piobuf, s, pointer); + } else { + /* data are buffered for pio read in pio_buffer. + * undone buffering by buffered_pio_read() + */ + if (pointer > s->data_ptr - s->io_buffer) + pointer = s->data_ptr - s->io_buffer; + s->data_ptr -= pointer; + } + + piobuf->pointer = 0; + piobuf->data_end = 0; + piobuf->opaque = NULL; +} + +void +handle_buffered_pio(void) +{ + struct pio_buffer *p1, *p2; + + if (!buffered_pio_page) + return; + + p1 = &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY]; + p2 = &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY]; + + __handle_buffered_pio(p1); + __handle_buffered_pio(p2); } #else /* !__ia64__ */ diff -r 208908de6975 -r ceee54c9f9f0 tools/ioemu/target-i386-dm/helper2.c --- a/tools/ioemu/target-i386-dm/helper2.c Wed Oct 17 15:29:44 2007 +0900 +++ b/tools/ioemu/target-i386-dm/helper2.c Mon Oct 22 12:44:34 2007 +0900 @@ -635,6 +635,7 @@ int main_loop(void) fprintf(logfile, "device model saving state\n"); /* Pull all outstanding ioreqs through the system */ + handle_buffered_pio(); handle_buffered_io(env); main_loop_wait(1); /* For the select() on events */ diff -r 208908de6975 -r ceee54c9f9f0 tools/ioemu/vl.h --- a/tools/ioemu/vl.h Wed Oct 17 15:29:44 2007 +0900 +++ b/tools/ioemu/vl.h Mon Oct 22 12:44:34 2007 +0900 @@ -1494,8 +1494,11 @@ static inline void xc_domain_shutdown_ho { xc_ia64_save_to_nvram(xc_handle, domid); } + +void handle_buffered_pio(void); #else #define xc_domain_shutdown_hook(xc_handle, domid) do {} while (0) +#define handle_buffered_pio() do {} while (0) #endif #endif /* VL_H */