From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:54550) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SDy9T-00043Y-Bh for qemu-devel@nongnu.org; Sat, 31 Mar 2012 09:15:35 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SDy9O-0005GI-Vz for qemu-devel@nongnu.org; Sat, 31 Mar 2012 09:15:30 -0400 Received: from e28smtp06.in.ibm.com ([122.248.162.6]:54036) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SDy9O-0005G0-3i for qemu-devel@nongnu.org; Sat, 31 Mar 2012 09:15:26 -0400 Received: from /spool/local by e28smtp06.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Sat, 31 Mar 2012 18:45:17 +0530 Received: from d28av02.in.ibm.com (d28av02.in.ibm.com [9.184.220.64]) by d28relay04.in.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q2VDFDWa4276394 for ; Sat, 31 Mar 2012 18:45:14 +0530 Received: from d28av02.in.ibm.com (loopback [127.0.0.1]) by d28av02.in.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id q2VIjoVs025727 for ; Sun, 1 Apr 2012 04:45:50 +1000 From: Li Zhi Hui Date: Sat, 31 Mar 2012 21:15:10 +0800 Message-Id: <1333199710-9061-1-git-send-email-zhihuili@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH v2] Replace bdrv_* to bdrv_aio_* functions in pio mode in fdc.c. List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Li Zhi Hui Replace bdrv_* to bdrv_aio_* functions in pio mode in fdc.c. Signed-off-by: Li Zhi Hui --- hw/fdc.c | 123 +++++++++++++++++++++++++++++++++++++++++++++----------------- 1 files changed, 89 insertions(+), 34 deletions(-) diff --git a/hw/fdc.c b/hw/fdc.c index a0236b7..0d178d2 100644 --- a/hw/fdc.c +++ b/hw/fdc.c @@ -230,6 +230,8 @@ static uint32_t fdctrl_read_data(FDCtrl *fdctrl); static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value); static uint32_t fdctrl_read_dir(FDCtrl *fdctrl); static void fdctrl_write_ccr(FDCtrl *fdctrl, uint32_t value); +static void fdctrl_read_pio_cb(void *opaque, int ret); +static void fdctrl_write_pio_cb(void *opaque, int ret); enum { FD_DIR_WRITE = 0, @@ -429,6 +431,8 @@ struct FDCtrl { /* Timers state */ uint8_t timer0; uint8_t timer1; + QEMUIOVector qiov; + struct iovec iov; }; typedef struct FDCtrlSysBus { @@ -443,6 +447,9 @@ typedef struct FDCtrlISABus { int32_t bootindexB; } FDCtrlISABus; +/* Associate command to an index in the 'handlers' array */ +static uint8_t command_to_handler[256]; + static uint32_t fdctrl_read (void *opaque, uint32_t reg) { FDCtrl *fdctrl = opaque; @@ -1164,6 +1171,16 @@ static void fdctrl_start_transfer(FDCtrl *fdctrl, int direction) fdctrl->msr |= FD_MSR_NONDMA; if (direction != FD_DIR_WRITE) fdctrl->msr |= FD_MSR_DIO; + + if (0 == command_to_handler[fdctrl->fifo[0] & 0xff]) { + fdctrl->msr &= ~FD_MSR_RQM; + fdctrl->iov.iov_base = fdctrl->fifo; + fdctrl->iov.iov_len = FD_SECTOR_LEN; + qemu_iovec_init_external(&fdctrl->qiov, &fdctrl->iov, 1); + bdrv_aio_readv(cur_drv->bs, fd_sector(cur_drv), + &fdctrl->qiov, 1, fdctrl_read_pio_cb, fdctrl); + } + /* IO based transfer: calculate len */ fdctrl_raise_irq(fdctrl, 0x00); @@ -1301,6 +1318,23 @@ static int fdctrl_transfer_handler (void *opaque, int nchan, return len; } +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); + return; + } + + fdctrl->msr |= FD_MSR_RQM; + return; +} /* Data register : 0x05 */ static uint32_t fdctrl_read_data(FDCtrl *fdctrl) { @@ -1315,23 +1349,7 @@ static uint32_t fdctrl_read_data(FDCtrl *fdctrl) return 0; } pos = fdctrl->data_pos; - 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; - } - 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); - } - } - } + pos %= FD_SECTOR_LEN; retval = fdctrl->fifo[pos]; if (++fdctrl->data_pos == fdctrl->data_len) { fdctrl->data_pos = 0; @@ -1344,9 +1362,27 @@ static uint32_t fdctrl_read_data(FDCtrl *fdctrl) fdctrl_reset_fifo(fdctrl); fdctrl_reset_irq(fdctrl); } + goto end; } - FLOPPY_DPRINTF("data register: 0x%02x\n", retval); + if (fdctrl->msr & FD_MSR_NONDMA) { + if (pos + 1 == FD_SECTOR_LEN) { + if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) { + FLOPPY_DPRINTF("error seeking to next sector %d\n", + fd_sector(cur_drv)); + return 0; + } + fdctrl->msr &= ~FD_MSR_RQM; + fdctrl->iov.iov_base = fdctrl->fifo; + fdctrl->iov.iov_len = FD_SECTOR_LEN; + qemu_iovec_init_external(&fdctrl->qiov, &fdctrl->iov, 1); + bdrv_aio_readv(cur_drv->bs, fd_sector(cur_drv), + &fdctrl->qiov, 1, fdctrl_read_pio_cb, fdctrl); + } + } + +end: + FLOPPY_DPRINTF("data register: 0x%02x\n", retval); return retval; } @@ -1756,8 +1792,34 @@ static const struct { { FD_CMD_WRITE, 0x1f, "WRITE (BeOS)", 8, fdctrl_start_transfer, FD_DIR_WRITE }, /* not in specification ; BeOS 4.5 bug */ { 0, 0, "unknown", 0, fdctrl_unimplemented }, /* default handler */ }; -/* 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)); + return; + } + if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) { + FLOPPY_DPRINTF("error seeking to next sector %d\n", + fd_sector(cur_drv)); + return; + } + + fdctrl->msr |= FD_MSR_RQM; + + /* 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; +} static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value) { @@ -1783,21 +1845,14 @@ static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value) 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; - } + + fdctrl->msr &= ~FD_MSR_RQM; + fdctrl->iov.iov_base = fdctrl->fifo; + fdctrl->iov.iov_len = FD_SECTOR_LEN; + qemu_iovec_init_external(&fdctrl->qiov, &fdctrl->iov, 1); + bdrv_aio_writev(cur_drv->bs, fd_sector(cur_drv), + &fdctrl->qiov, 1, fdctrl_write_pio_cb, fdctrl); } - /* 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) { -- 1.7.4.1