* THE SOFTWARE.
*/
#include "qemu-common.h"
-#ifndef QEMU_IMG
#include "qemu-timer.h"
-#include "exec-all.h"
-#endif
#include "block_int.h"
#include <assert.h>
+#include <windows.h>
#include <winioctl.h>
+//#define WIN32_AIO
+
#define FTYPE_FILE 0
#define FTYPE_CD 1
#define FTYPE_HARDDISK 2
} else {
create_flags = OPEN_EXISTING;
}
-#ifdef QEMU_IMG
- overlapped = FILE_ATTRIBUTE_NORMAL;
-#else
+#ifdef WIN32_AIO
overlapped = FILE_FLAG_OVERLAPPED;
+#else
+ overlapped = FILE_ATTRIBUTE_NORMAL;
#endif
+ if ((flags & BDRV_O_NOCACHE))
+ overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
+ else if (!(flags & BDRV_O_CACHE_WB))
+ overlapped |= FILE_FLAG_WRITE_THROUGH;
s->hfile = CreateFile(filename, access_flags,
FILE_SHARE_READ, NULL,
create_flags, overlapped, NULL);
return 0;
}
-static int raw_pread(BlockDriverState *bs, int64_t offset,
- uint8_t *buf, int count)
+static int raw_read(BlockDriverState *bs, int64_t sector_num,
+ uint8_t *buf, int nb_sectors)
{
BDRVRawState *s = bs->opaque;
OVERLAPPED ov;
DWORD ret_count;
int ret;
+ int64_t offset = sector_num * 512;
+ int count = nb_sectors * 512;
memset(&ov, 0, sizeof(ov));
ov.Offset = offset;
ov.OffsetHigh = offset >> 32;
ret = ReadFile(s->hfile, buf, count, &ret_count, &ov);
if (!ret) {
+#ifdef WIN32_AIO
ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE);
if (!ret)
return -EIO;
else
+#endif
return ret_count;
}
+ if (ret_count == count)
+ ret_count = 0;
return ret_count;
}
-static int raw_pwrite(BlockDriverState *bs, int64_t offset,
- const uint8_t *buf, int count)
+static int raw_write(BlockDriverState *bs, int64_t sector_num,
+ const uint8_t *buf, int nb_sectors)
{
BDRVRawState *s = bs->opaque;
OVERLAPPED ov;
DWORD ret_count;
int ret;
+ int64_t offset = sector_num * 512;
+ int count = nb_sectors * 512;
memset(&ov, 0, sizeof(ov));
ov.Offset = offset;
ov.OffsetHigh = offset >> 32;
ret = WriteFile(s->hfile, buf, count, &ret_count, &ov);
if (!ret) {
+#ifdef WIN32_AIO
ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE);
if (!ret)
return -EIO;
else
+#endif
return ret_count;
}
+ if (ret_count == count)
+ ret_count = 0;
return ret_count;
}
-#if 0
-#ifndef QEMU_IMG
+#ifdef WIN32_AIO
static void raw_aio_cb(void *opaque)
{
RawAIOCB *acb = opaque;
acb->common.cb(acb->common.opaque, 0);
}
}
-#endif
static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
int64_t sector_num, uint8_t *buf, int nb_sectors,
acb->ov.OffsetHigh = offset >> 32;
acb->ov.hEvent = acb->hEvent;
acb->count = nb_sectors * 512;
-#ifndef QEMU_IMG
qemu_add_wait_object(acb->ov.hEvent, raw_aio_cb, acb);
-#endif
return acb;
}
qemu_aio_release(acb);
return NULL;
}
-#ifdef QEMU_IMG
qemu_aio_release(acb);
-#endif
return (BlockDriverAIOCB *)acb;
}
qemu_aio_release(acb);
return NULL;
}
-#ifdef QEMU_IMG
qemu_aio_release(acb);
-#endif
return (BlockDriverAIOCB *)acb;
}
static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
{
-#ifndef QEMU_IMG
RawAIOCB *acb = (RawAIOCB *)blockacb;
BlockDriverState *bs = acb->common.bs;
BDRVRawState *s = bs->opaque;
/* XXX: if more than one async I/O it is not correct */
CancelIo(s->hfile);
qemu_aio_release(acb);
-#endif
}
-#endif /* #if 0 */
+#endif /* #if WIN32_AIO */
static void raw_flush(BlockDriverState *bs)
{
return 0;
}
-void qemu_aio_init(void)
-{
-}
-
-void qemu_aio_poll(void)
-{
-}
-
-void qemu_aio_flush(void)
-{
-}
-
-void qemu_aio_wait_start(void)
-{
-}
-
-void qemu_aio_wait(void)
-{
-#ifndef QEMU_IMG
- qemu_bh_poll();
-#endif
-}
-
-void qemu_aio_wait_end(void)
-{
-}
-
BlockDriver bdrv_raw = {
"raw",
sizeof(BDRVRawState),
raw_create,
raw_flush,
-#if 0
+#ifdef WIN32_AIO
.bdrv_aio_read = raw_aio_read,
.bdrv_aio_write = raw_aio_write,
.bdrv_aio_cancel = raw_aio_cancel,
.aiocb_size = sizeof(RawAIOCB);
#endif
- .protocol_name = "file",
- .bdrv_pread = raw_pread,
- .bdrv_pwrite = raw_pwrite,
+ .bdrv_read = raw_read,
+ .bdrv_write = raw_write,
.bdrv_truncate = raw_truncate,
.bdrv_getlength = raw_getlength,
};
}
create_flags = OPEN_EXISTING;
-#ifdef QEMU_IMG
- overlapped = FILE_ATTRIBUTE_NORMAL;
-#else
+#ifdef WIN32_AIO
overlapped = FILE_FLAG_OVERLAPPED;
+#else
+ overlapped = FILE_ATTRIBUTE_NORMAL;
#endif
+ if ((flags & BDRV_O_NOCACHE))
+ overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
+ else if (!(flags & BDRV_O_CACHE_WB))
+ overlapped |= FILE_FLAG_WRITE_THROUGH;
s->hfile = CreateFile(filename, access_flags,
FILE_SHARE_READ, NULL,
create_flags, overlapped, NULL);
#endif
BlockDriver bdrv_host_device = {
- "host_device",
- sizeof(BDRVRawState),
- NULL, /* no probe for protocols */
- hdev_open,
- NULL,
- NULL,
- raw_close,
- NULL,
- raw_flush,
-
-#if 0
- .bdrv_aio_read = raw_aio_read,
- .bdrv_aio_write = raw_aio_write,
- .bdrv_aio_cancel = raw_aio_cancel,
- .aiocb_size = sizeof(RawAIOCB);
+ .format_name = "host_device",
+ .instance_size = sizeof(BDRVRawState),
+ .bdrv_open = hdev_open,
+ .bdrv_close = raw_close,
+ .bdrv_flush = raw_flush,
+
+#ifdef WIN32_AIO
+ .bdrv_aio_read = raw_aio_read,
+ .bdrv_aio_write = raw_aio_write,
+ .bdrv_aio_cancel = raw_aio_cancel,
+ .aiocb_size = sizeof(RawAIOCB);
#endif
- .bdrv_pread = raw_pread,
- .bdrv_pwrite = raw_pwrite,
- .bdrv_getlength = raw_getlength,
+ .bdrv_read = raw_read,
+ .bdrv_write = raw_write,
+ .bdrv_getlength = raw_getlength,
};