mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-06 17:23:56 -06:00
fdc/i8257: implement verify transfer mode
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>
This commit is contained in:
parent
cfe68ae025
commit
9e58f17270
3 changed files with 31 additions and 51 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue