[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] Replace bdrv_* to bdrv_aio_* functions in pio mode
From: |
Li Zhi Hui |
Subject: |
[Qemu-devel] [PATCH] Replace bdrv_* to bdrv_aio_* functions in pio mode in fdc.c. |
Date: |
Fri, 23 Mar 2012 15:07:20 +0800 |
Replace bdrv_* to bdrv_aio_* functions in pio mode in fdc.c.
Signed-off-by: Li Zhi Hui <address@hidden>
---
hw/fdc.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 90 insertions(+), 27 deletions(-)
diff --git a/hw/fdc.c b/hw/fdc.c
index a0236b7..5e855fd 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -1301,12 +1301,42 @@ static int fdctrl_transfer_handler (void *opaque, int
nchan,
return len;
}
+enum {
+ FD_DATA_IDLE,
+ FD_DATA_WORKING,
+ FD_DATA_FIN,
+};
+
+int data_status[MAX_FD];
+
+static void fdctrl_read_pio_cb(void *opaque, int ret)
+{
+ FDCtrl *fdctrl = opaque;
+ FDrive *cur_drv;
+
+ if (ret < 0) {
+ cur_drv = get_cur_drv(fdctrl);
+ FLOPPY_DPRINTF("error getting sector %d\n",
+ fd_sector(cur_drv));
+ /* Sure, image size is too small... */
+ memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
+ data_status[fdctrl->cur_drv] = FD_DATA_IDLE;
+ goto end;
+ }
+ data_status[fdctrl->cur_drv] = FD_DATA_FIN;
+
+end:
+ return;
+}
+
/* Data register : 0x05 */
static uint32_t fdctrl_read_data(FDCtrl *fdctrl)
{
FDrive *cur_drv;
uint32_t retval = 0;
int pos;
+ QEMUIOVector qiov;
+ struct iovec iov;
cur_drv = get_cur_drv(fdctrl);
fdctrl->dsr &= ~FD_DSR_PWRDOWN;
@@ -1318,17 +1348,30 @@ static uint32_t fdctrl_read_data(FDCtrl *fdctrl)
if (fdctrl->msr & FD_MSR_NONDMA) {
pos %= FD_SECTOR_LEN;
if (pos == 0) {
- if (fdctrl->data_pos != 0)
- if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) {
- FLOPPY_DPRINTF("error seeking to next sector %d\n",
- fd_sector(cur_drv));
- return 0;
+ switch (data_status[fdctrl->cur_drv]) {
+ case FD_DATA_IDLE:
+ if (fdctrl->data_pos != 0) {
+ if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) {
+ FLOPPY_DPRINTF("error seeking to next sector %d\n",
+ fd_sector(cur_drv));
+ goto end;
+ }
}
- if (bdrv_read(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) <
0) {
- FLOPPY_DPRINTF("error getting sector %d\n",
- fd_sector(cur_drv));
- /* Sure, image size is too small... */
- memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
+ iov.iov_base = fdctrl->fifo;
+ iov.iov_len = FD_SECTOR_LEN;
+ qemu_iovec_init_external(&qiov, &iov, 1);
+ bdrv_aio_readv(cur_drv->bs, fd_sector(cur_drv),
+ &qiov, 1, fdctrl_read_pio_cb, fdctrl);
+ data_status[fdctrl->cur_drv] = FD_DATA_WORKING;
+ goto end;
+ case FD_DATA_WORKING:
+ goto end;
+ case FD_DATA_FIN:
+ data_status[fdctrl->cur_drv] = FD_DATA_IDLE;
+ break;
+ default:
+ data_status[fdctrl->cur_drv] = FD_DATA_IDLE;
+ goto end;
}
}
}
@@ -1347,6 +1390,7 @@ static uint32_t fdctrl_read_data(FDCtrl *fdctrl)
}
FLOPPY_DPRINTF("data register: 0x%02x\n", retval);
+end:
return retval;
}
@@ -1759,10 +1803,38 @@ static const struct {
/* Associate command to an index in the 'handlers' array */
static uint8_t command_to_handler[256];
+static void fdctrl_write_pio_cb(void *opaque, int ret)
+{
+ FDCtrl *fdctrl = opaque;
+ FDrive *cur_drv;
+
+ cur_drv = get_cur_drv(fdctrl);
+ if (ret < 0) {
+ FLOPPY_ERROR("writing sector %d\n", fd_sector(cur_drv));
+ goto end;
+ }
+ if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) {
+ FLOPPY_DPRINTF("error seeking to next sector %d\n",
+ fd_sector(cur_drv));
+ goto end;
+ }
+ /* Switch from transfer mode to status mode
+ * then from status mode to command mode
+ */
+ if (fdctrl->data_pos == fdctrl->data_len) {
+ fdctrl_stop_transfer(fdctrl, FD_SR0_SEEK, 0x00, 0x00);
+ }
+
+end:
+ return;
+}
+
static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value)
{
FDrive *cur_drv;
int pos;
+ QEMUIOVector qiov;
+ struct iovec iov;
/* Reset mode */
if (!(fdctrl->dor & FD_DOR_nRESET)) {
@@ -1780,25 +1852,16 @@ static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t
value)
pos = fdctrl->data_pos++;
pos %= FD_SECTOR_LEN;
fdctrl->fifo[pos] = value;
- if (pos == FD_SECTOR_LEN - 1 ||
- fdctrl->data_pos == fdctrl->data_len) {
+ if ((pos == FD_SECTOR_LEN - 1) ||
+ (fdctrl->data_pos == fdctrl->data_len)) {
cur_drv = get_cur_drv(fdctrl);
- if (bdrv_write(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) <
0) {
- FLOPPY_ERROR("writing sector %d\n", fd_sector(cur_drv));
- return;
- }
- if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) {
- FLOPPY_DPRINTF("error seeking to next sector %d\n",
- fd_sector(cur_drv));
- return;
- }
+ iov.iov_base = fdctrl->fifo;
+ iov.iov_len = FD_SECTOR_LEN;
+ qemu_iovec_init_external(&qiov, &iov, 1);
+ bdrv_aio_writev(cur_drv->bs, fd_sector(cur_drv),
+ &qiov, 1, fdctrl_write_pio_cb, fdctrl);
+ return;
}
- /* Switch from transfer mode to status mode
- * then from status mode to command mode
- */
- if (fdctrl->data_pos == fdctrl->data_len)
- fdctrl_stop_transfer(fdctrl, FD_SR0_SEEK, 0x00, 0x00);
- return;
}
if (fdctrl->data_pos == 0) {
/* Command */
--
1.7.4.1
- [Qemu-devel] [PATCH] Replace bdrv_* to bdrv_aio_* functions in pio mode in fdc.c.,
Li Zhi Hui <=