From: Anthony Liguori <anthony@codemonkey.ws>
To: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH v2 1/3] Stop VM on ENOSPC error.
Date: Thu, 15 Jan 2009 14:39:52 -0600 [thread overview]
Message-ID: <496F9F18.2020302@codemonkey.ws> (raw)
In-Reply-To: <20090115101241.13211.64596.stgit@dhcp-1-237.tlv.redhat.com>
Gleb Natapov wrote:
> And repeat last IDE command after VM restart.
>
> Signed-off-by: Gleb Natapov <gleb@redhat.com>
> ---
>
> hw/ide.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++----
> 1 files changed, 50 insertions(+), 4 deletions(-)
>
> diff --git a/hw/ide.c b/hw/ide.c
> index 7dd41f7..2d2cead 100644
> --- a/hw/ide.c
> +++ b/hw/ide.c
> @@ -457,6 +457,8 @@ static inline int media_is_cd(IDEState *s)
> #define BM_STATUS_DMAING 0x01
> #define BM_STATUS_ERROR 0x02
> #define BM_STATUS_INT 0x04
> +#define BM_STATUS_DMA_RETRY 0x08
> +#define BM_STATUS_PIO_RETRY 0x10
>
> #define BM_CMD_START 0x01
> #define BM_CMD_READ 0x08
> @@ -488,6 +490,8 @@ typedef struct BMDMAState {
> IDEState *ide_if;
> BlockDriverCompletionFunc *dma_cb;
> BlockDriverAIOCB *aiocb;
> + int64_t sector_num;
> + uint32_t nsector;
> } BMDMAState;
>
> typedef struct PCIIDEState {
> @@ -498,6 +502,7 @@ typedef struct PCIIDEState {
> } PCIIDEState;
>
> static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb);
> +static void ide_dma_restart(IDEState *s);
> static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret);
>
> static void padstr(char *str, const char *src, int len)
> @@ -991,8 +996,13 @@ static void ide_sector_write(IDEState *s)
> n = s->req_nb_sectors;
> ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
> if (ret != 0) {
> - ide_rw_error(s);
> - return;
> + if (ret == -ENOSPC) {
> + s->bmdma->ide_if = s;
> + s->bmdma->status |= BM_STATUS_PIO_RETRY;
> + vm_stop(0);
> + } else
> + ide_rw_error(s);
> + return;
> }
>
> s->nsector -= n;
> @@ -1024,6 +1034,20 @@ static void ide_sector_write(IDEState *s)
> }
> }
>
> +static void ide_dma_restart_cb(void *opaque, int running)
> +{
> + BMDMAState *bm = opaque;
> + if (!running)
> + return;
> + if (bm->status & BM_STATUS_DMA_RETRY) {
> + bm->status &= ~BM_STATUS_DMA_RETRY;
> + ide_dma_restart(bm->ide_if);
> + } else if (bm->status & BM_STATUS_PIO_RETRY) {
> + bm->status &= ~BM_STATUS_PIO_RETRY;
> + ide_sector_write(bm->ide_if);
> + }
> +}
> +
> static void ide_write_dma_cb(void *opaque, int ret)
> {
> BMDMAState *bm = opaque;
> @@ -1032,8 +1056,12 @@ static void ide_write_dma_cb(void *opaque, int ret)
> int64_t sector_num;
>
> if (ret < 0) {
> - ide_dma_error(s);
> - return;
> + if (ret == -ENOSPC) {
> + bm->status |= BM_STATUS_DMA_RETRY;
> + vm_stop(0);
> + } else
> + ide_dma_error(s);
> + return;
> }
>
> n = s->io_buffer_size >> 9;
> @@ -2849,11 +2877,24 @@ static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb)
> bm->cur_prd_last = 0;
> bm->cur_prd_addr = 0;
> bm->cur_prd_len = 0;
> + bm->sector_num = ide_get_sector(s);
> + bm->nsector = s->nsector;
> if (bm->status & BM_STATUS_DMAING) {
> bm->dma_cb(bm, 0);
> }
> }
>
> +static void ide_dma_restart(IDEState *s)
> +{
> + BMDMAState *bm = s->bmdma;
> + ide_set_sector(s, bm->sector_num);
> + s->io_buffer_index = 0;
> + s->io_buffer_size = 0;
> + s->nsector = bm->nsector;
> + bm->cur_addr = bm->addr;
> + ide_dma_start(s, bm->dma_cb);
> +}
> +
> static void ide_dma_cancel(BMDMAState *bm)
> {
> if (bm->status & BM_STATUS_DMAING) {
> @@ -3043,6 +3084,7 @@ static void bmdma_map(PCIDevice *pci_dev, int region_num,
> d->ide_if[2 * i].bmdma = bm;
> d->ide_if[2 * i + 1].bmdma = bm;
> bm->pci_dev = (PCIIDEState *)pci_dev;
> + qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm);
>
> register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
>
> @@ -3071,6 +3113,8 @@ static void pci_ide_save(QEMUFile* f, void *opaque)
> qemu_put_8s(f, &bm->cmd);
> qemu_put_8s(f, &bm->status);
> qemu_put_be32s(f, &bm->addr);
> + qemu_put_sbe64s(f, &bm->sector_num);
> + qemu_put_be32s(f, &bm->nsector);
>
If you're adding to the save/restore format, you have to increment the
version number.
Regards,
Anthony Liguori
> /* XXX: if a transfer is pending, we do not save it yet */
> }
>
> @@ -3105,6 +3149,8 @@ static int pci_ide_load(QEMUFile* f, void *opaque, int version_id)
> qemu_get_8s(f, &bm->cmd);
> qemu_get_8s(f, &bm->status);
> qemu_get_be32s(f, &bm->addr);
> + qemu_get_sbe64s(f, &bm->sector_num);
> + qemu_get_be32s(f, &bm->nsector);
> /* XXX: if a transfer is pending, we do not save it yet */
> }
>
>
>
>
>
prev parent reply other threads:[~2009-01-15 20:40 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-01-15 10:12 [Qemu-devel] [PATCH v2 1/3] Stop VM on ENOSPC error Gleb Natapov
2009-01-15 10:12 ` [Qemu-devel] [PATCH v2 2/3] bdrv_write should not stop on partial write Gleb Natapov
2009-01-15 20:44 ` Anthony Liguori
2009-01-15 10:12 ` [Qemu-devel] [PATCH v2 3/3] Return -errno on write failure Gleb Natapov
2009-01-15 20:44 ` Anthony Liguori
2009-01-15 20:39 ` Anthony Liguori [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=496F9F18.2020302@codemonkey.ws \
--to=anthony@codemonkey.ws \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.