From: "Hervé Poussineau" <hpoussin@reactos.org>
To: Sven Schnelle <svens@stackframe.org>, John Snow <jsnow@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>,
"open list:Floppy" <qemu-block@nongnu.org>,
"Michael S. Tsirkin" <mst@redhat.com>,
"open list:All patches CC here" <qemu-devel@nongnu.org>,
Max Reitz <mreitz@redhat.com>,
Paolo Bonzini <pbonzini@redhat.com>
Subject: Re: [PATCH v2] fdc/i8257: implement verify transfer mode
Date: Fri, 1 Nov 2019 11:54:03 +0100 [thread overview]
Message-ID: <2531480a-e678-9a8e-13c8-1d7dc8acaa7e@reactos.org> (raw)
In-Reply-To: <20191030082827.10010-1-svens@stackframe.org>
Le 30/10/2019 à 09:28, Sven Schnelle a écrit :
> While working on the Tulip driver i tried to write some Teledisk images to
> a floppy image which didn't work. Turned out that Teledisk checks the written
> data by issuing a READ command to the FDC but running the DMA controller
> in VERIFY mode. As we ignored the DMA request in that case, the DMA transfer
> never finished, and Teledisk reported an error.
>
> The i8257 spec says about verify transfers:
>
> 3) DMA verify, which does not actually involve the transfer of data. When an
> 8257 channel is in the DMA verify mode, it will respond the same as described
> for transfer operations, except that no memory or I/O read/write control signals
> will be generated.
>
> Hervé proposed to remove all the dma_mode_ok stuff from fdc to have a more
> clear boundary between DMA and FDC, so this patch also does that.
>
> Suggested-by: Hervé Poussineau <hpoussin@reactos.org>
> Signed-off-by: Sven Schnelle <svens@stackframe.org>
> ---
> hw/block/fdc.c | 39 +++++++++++++++------------------------
> hw/dma/i8257.c | 20 +++++++++++++-------
> include/hw/isa/isa.h | 1 -
> 3 files changed, 28 insertions(+), 32 deletions(-)
>
> diff --git a/hw/block/fdc.c b/hw/block/fdc.c
> index ac5d31e8c1..18fd22bfb7 100644
> --- a/hw/block/fdc.c
> +++ b/hw/block/fdc.c
> @@ -1716,9 +1716,8 @@ static void fdctrl_start_transfer(FDCtrl *fdctrl, int direction)
> if (fdctrl->dor & FD_DOR_DMAEN) {
> IsaDmaTransferMode dma_mode;
You need to remove this dma_mode variable because you don't set it anymore.
> IsaDmaClass *k = ISADMA_GET_CLASS(fdctrl->dma);
> - bool dma_mode_ok;
> +
> /* DMA transfer are enabled. Check if DMA channel is well programmed */
Second part of this comment should be removed.
> - dma_mode = k->get_transfer_mode(fdctrl->dma, fdctrl->dma_chann);
> FLOPPY_DPRINTF("dma_mode=%d direction=%d (%d - %d)\n",
> dma_mode, direction,
> (128 << fdctrl->fifo[5]) *
You need to remove dma_mode variable from printf statement, as you removed the variable.
> @@ -1727,40 +1726,32 @@ static void fdctrl_start_transfer(FDCtrl *fdctrl, int direction)
> case FD_DIR_SCANE:
> case FD_DIR_SCANL:
> case FD_DIR_SCANH:
> - dma_mode_ok = (dma_mode == ISADMA_TRANSFER_VERIFY);
> break;
> case FD_DIR_WRITE:
> - dma_mode_ok = (dma_mode == ISADMA_TRANSFER_WRITE);
> break;
> case FD_DIR_READ:
> - dma_mode_ok = (dma_mode == ISADMA_TRANSFER_READ);
> break;
> case FD_DIR_VERIFY:
> - dma_mode_ok = true;
> break;
> default:
> - dma_mode_ok = false;
> break;
> }
Now that you have removed the dma_mode_ok instructions, you have a switch where all cases do nothing.
Please completly remove the switch statement.
> - if (dma_mode_ok) {
> - /* No access is allowed until DMA transfer has completed */
> - fdctrl->msr &= ~FD_MSR_RQM;
> - if (direction != FD_DIR_VERIFY) {
> - /* Now, we just have to wait for the DMA controller to
> - * recall us...
> - */
> - k->hold_DREQ(fdctrl->dma, fdctrl->dma_chann);
> - k->schedule(fdctrl->dma);
> - } else {
> - /* Start transfer */
> - fdctrl_transfer_handler(fdctrl, fdctrl->dma_chann, 0,
> - fdctrl->data_len);
> - }
> - return;
> +
> + /* No access is allowed until DMA transfer has completed */
> + fdctrl->msr &= ~FD_MSR_RQM;
> + if (direction != FD_DIR_VERIFY) {
> + /*
> + * Now, we just have to wait for the DMA controller to
> + * recall us...
> + */
> + k->hold_DREQ(fdctrl->dma, fdctrl->dma_chann);
> + k->schedule(fdctrl->dma);
> } else {
> - FLOPPY_DPRINTF("bad dma_mode=%d direction=%d\n", dma_mode,
> - direction);
> + /* Start transfer */
> + fdctrl_transfer_handler(fdctrl, fdctrl->dma_chann, 0,
> + fdctrl->data_len);
> }
> + return;
> }
> FLOPPY_DPRINTF("start non-DMA transfer\n");
> fdctrl->msr |= FD_MSR_NONDMA | FD_MSR_RQM;
> diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c
> index 792f617eb4..85dad3d391 100644
> --- a/hw/dma/i8257.c
> +++ b/hw/dma/i8257.c
> @@ -292,12 +292,6 @@ static uint64_t i8257_read_cont(void *opaque, hwaddr nport, unsigned size)
> return val;
> }
>
> -static IsaDmaTransferMode i8257_dma_get_transfer_mode(IsaDma *obj, int nchan)
> -{
> - I8257State *d = I8257(obj);
> - return (d->regs[nchan & 3].mode >> 2) & 3;
> -}
> -
> static bool i8257_dma_has_autoinitialization(IsaDma *obj, int nchan)
> {
> I8257State *d = I8257(obj);
> @@ -400,6 +394,11 @@ static void i8257_dma_register_channel(IsaDma *obj, int nchan,
> r->opaque = opaque;
> }
>
> +static bool i8257_is_verify_transfer(I8257Regs *r)
> +{
> + return (r->mode & 0x0c) == 0;
> +}
> +
> static int i8257_dma_read_memory(IsaDma *obj, int nchan, void *buf, int pos,
> int len)
> {
> @@ -407,6 +406,10 @@ static int i8257_dma_read_memory(IsaDma *obj, int nchan, void *buf, int pos,
> I8257Regs *r = &d->regs[nchan & 3];
> hwaddr addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR];
>
> + if (i8257_is_verify_transfer(r)) {
> + return len;
> + }
> +
> if (r->mode & 0x20) {
> int i;
> uint8_t *p = buf;
> @@ -431,6 +434,10 @@ static int i8257_dma_write_memory(IsaDma *obj, int nchan, void *buf, int pos,
> I8257Regs *r = &s->regs[nchan & 3];
> hwaddr addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR];
>
> + if (i8257_is_verify_transfer(r)) {
> + return len;
> + }
> +
> if (r->mode & 0x20) {
> int i;
> uint8_t *p = buf;
> @@ -597,7 +604,6 @@ static void i8257_class_init(ObjectClass *klass, void *data)
> dc->vmsd = &vmstate_i8257;
> dc->props = i8257_properties;
>
> - idc->get_transfer_mode = i8257_dma_get_transfer_mode;
> idc->has_autoinitialization = i8257_dma_has_autoinitialization;
> idc->read_memory = i8257_dma_read_memory;
> idc->write_memory = i8257_dma_write_memory;
> diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h
> index 018ada4f6f..f516e253c5 100644
> --- a/include/hw/isa/isa.h
> +++ b/include/hw/isa/isa.h
> @@ -56,7 +56,6 @@ typedef int (*IsaDmaTransferHandler)(void *opaque, int nchan, int pos,
> typedef struct IsaDmaClass {
> InterfaceClass parent;
>
> - IsaDmaTransferMode (*get_transfer_mode)(IsaDma *obj, int nchan);
> bool (*has_autoinitialization)(IsaDma *obj, int nchan);
> int (*read_memory)(IsaDma *obj, int nchan, void *buf, int pos, int len);
> int (*write_memory)(IsaDma *obj, int nchan, void *buf, int pos, int len);
>
Otherwise, the i8257.c parts look good. This might fix some other devices (except fdc) which might use VERIFY mode.
Hervé
next prev parent reply other threads:[~2019-11-01 10:55 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-30 8:28 [PATCH v2] fdc/i8257: implement verify transfer mode Sven Schnelle
2019-11-01 10:54 ` Hervé Poussineau [this message]
2019-11-01 12:33 ` John Snow
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=2531480a-e678-9a8e-13c8-1d7dc8acaa7e@reactos.org \
--to=hpoussin@reactos.org \
--cc=jsnow@redhat.com \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=svens@stackframe.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).