From: John Snow <jsnow@redhat.com>
To: Peter Maydell <peter.maydell@linaro.org>, qemu-devel@nongnu.org
Cc: "Michael S. Tsirkin" <mst@redhat.com>,
"Mark Cave-Ayland" <mark.cave-ayland@ilande.co.uk>,
"Sven Schnelle" <svens@stackframe.org>,
qemu-block@nongnu.org, "Helge Deller" <deller@gmx.de>,
"Hervé Poussineau" <hpoussin@reactos.org>,
"Aleksandar Rikalo" <aleksandar.rikalo@rt-rk.com>,
"Richard Henderson" <rth@twiddle.net>,
"Philippe Mathieu-Daudé" <philmd@redhat.com>,
"Artyom Tarasenko" <atar4qemu@gmail.com>,
"Laurent Vivier" <lvivier@redhat.com>,
"Thomas Huth" <thuth@redhat.com>,
"Eduardo Habkost" <ehabkost@redhat.com>,
"John Snow" <jsnow@redhat.com>,
"David Gibson" <david@gibson.dropbear.id.au>,
"Kevin Wolf" <kwolf@redhat.com>, "Max Reitz" <mreitz@redhat.com>,
qemu-ppc@nongnu.org,
"Aleksandar Markovic" <amarkovic@wavecomp.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Aurelien Jarno" <aurelien@aurel32.net>
Subject: [PULL 1/2] fdc/i8257: implement verify transfer mode
Date: Tue, 24 Mar 2020 15:55:22 -0400 [thread overview]
Message-ID: <20200324195523.19779-2-jsnow@redhat.com> (raw)
In-Reply-To: <20200324195523.19779-1-jsnow@redhat.com>
From: Sven Schnelle <svens@stackframe.org>
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>
Reviewed-by: Hervé Poussineau <hpoussin@reactos.org>
Signed-off-by: John Snow <jsnow@redhat.com>
---
include/hw/isa/isa.h | 1 -
hw/block/fdc.c | 61 +++++++++++++-------------------------------
hw/dma/i8257.c | 20 ++++++++++-----
3 files changed, 31 insertions(+), 51 deletions(-)
diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h
index e9ac1f1205..59a4d4b50a 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);
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 22e954e0dc..33bc9e2f92 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -1714,53 +1714,28 @@ static void fdctrl_start_transfer(FDCtrl *fdctrl, int direction)
}
fdctrl->eot = fdctrl->fifo[6];
if (fdctrl->dor & FD_DOR_DMAEN) {
- IsaDmaTransferMode dma_mode;
+ /* DMA transfer is enabled. */
IsaDmaClass *k = ISADMA_GET_CLASS(fdctrl->dma);
- bool dma_mode_ok;
- /* DMA transfer are enabled. Check if DMA channel is well programmed */
- 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]) *
+
+ FLOPPY_DPRINTF("direction=%d (%d - %d)\n",
+ direction, (128 << fdctrl->fifo[5]) *
(cur_drv->last_sect - ks + 1), fdctrl->data_len);
- switch (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;
- }
- 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 ef15c06d77..1b3435ab58 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;
device_class_set_props(dc, 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;
--
2.21.1
next prev parent reply other threads:[~2020-03-24 19:57 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-24 19:55 [PULL 0/2] Ide patches John Snow
2020-03-24 19:55 ` John Snow [this message]
2020-03-24 19:55 ` [PULL 2/2] hw/ide/sii3112: Use qdev gpio rather than qemu_allocate_irqs() John Snow
2020-03-24 21:06 ` [PULL 0/2] Ide patches 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=20200324195523.19779-2-jsnow@redhat.com \
--to=jsnow@redhat.com \
--cc=aleksandar.rikalo@rt-rk.com \
--cc=amarkovic@wavecomp.com \
--cc=atar4qemu@gmail.com \
--cc=aurelien@aurel32.net \
--cc=david@gibson.dropbear.id.au \
--cc=deller@gmx.de \
--cc=ehabkost@redhat.com \
--cc=hpoussin@reactos.org \
--cc=kwolf@redhat.com \
--cc=lvivier@redhat.com \
--cc=mark.cave-ayland@ilande.co.uk \
--cc=mreitz@redhat.com \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=philmd@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
--cc=rth@twiddle.net \
--cc=svens@stackframe.org \
--cc=thuth@redhat.com \
/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).