mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-07 01:33:56 -06:00
ide: really restart pending and in-flight atapi dma
Restart of ATAPI DMA used to be unreachable, because the request to do so wasn't indicated in bus->error_status due to the lack of spare bits, and ide_restart_bh() would return early doing nothing. This patch makes use of the observation that not all bit combinations were possible in ->error_status. In particular, IDE_RETRY_READ only made sense together with IDE_RETRY_DMA or IDE_RETRY_PIO. This allows to re-use IDE_RETRY_READ alone as an indicator of ATAPI DMA restart request. To makes things more uniform, ATAPI DMA gets its own value for ->dma_cmd. As a means against confusion, macros are added to test the state of ->error_status. The patch fixes the restart of both in-flight and pending ATAPI DMA, following the scheme similar to that of IDE DMA. [Including a fixup patch: Message-id: 1460465594-15777-1-git-send-email-pbutsykin@virtuozzo.com --js] Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com> Signed-off-by: Denis V. Lunev <den@openvz.org> Reviewed-by: Roman Kagan <rkagan@virtuozzo.com> Reviewed-by: John Snow <jsnow@redhat.com> Message-id: 1459924806-306-4-git-send-email-den@openvz.org Signed-off-by: John Snow <jsnow@redhat.com>
This commit is contained in:
parent
9a41826f38
commit
502356eeeb
4 changed files with 43 additions and 22 deletions
|
@ -57,7 +57,6 @@ static const int smart_attributes[][12] = {
|
|||
{ 190, 0x03, 0x00, 0x45, 0x45, 0x1f, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x32},
|
||||
};
|
||||
|
||||
static int ide_handle_rw_error(IDEState *s, int error, int op);
|
||||
static void ide_dummy_transfer_stop(IDEState *s);
|
||||
|
||||
static void padstr(char *str, const char *src, int len)
|
||||
|
@ -773,7 +772,7 @@ void ide_dma_error(IDEState *s)
|
|||
ide_set_irq(s->bus);
|
||||
}
|
||||
|
||||
static int ide_handle_rw_error(IDEState *s, int error, int op)
|
||||
int ide_handle_rw_error(IDEState *s, int error, int op)
|
||||
{
|
||||
bool is_read = (op & IDE_RETRY_READ) != 0;
|
||||
BlockErrorAction action = blk_get_error_action(s->blk, is_read, error);
|
||||
|
@ -783,8 +782,10 @@ static int ide_handle_rw_error(IDEState *s, int error, int op)
|
|||
s->bus->error_status = op;
|
||||
} else if (action == BLOCK_ERROR_ACTION_REPORT) {
|
||||
block_acct_failed(blk_get_stats(s->blk), &s->acct);
|
||||
if (op & IDE_RETRY_DMA) {
|
||||
if (IS_IDE_RETRY_DMA(op)) {
|
||||
ide_dma_error(s);
|
||||
} else if (IS_IDE_RETRY_ATAPI(op)) {
|
||||
ide_atapi_io_error(s, -error);
|
||||
} else {
|
||||
ide_rw_error(s);
|
||||
}
|
||||
|
@ -872,6 +873,8 @@ static void ide_dma_cb(void *opaque, int ret)
|
|||
ide_issue_trim, ide_dma_cb, s,
|
||||
DMA_DIRECTION_TO_DEVICE);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
return;
|
||||
|
||||
|
@ -1634,6 +1637,9 @@ static bool cmd_packet(IDEState *s, uint8_t cmd)
|
|||
|
||||
s->status = READY_STAT | SEEK_STAT;
|
||||
s->atapi_dma = s->feature & 1;
|
||||
if (s->atapi_dma) {
|
||||
s->dma_cmd = IDE_DMA_ATAPI;
|
||||
}
|
||||
s->nsector = 1;
|
||||
ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,
|
||||
ide_atapi_cmd);
|
||||
|
@ -2518,15 +2524,13 @@ static void ide_restart_bh(void *opaque)
|
|||
if (s->bus->dma->ops->restart) {
|
||||
s->bus->dma->ops->restart(s->bus->dma);
|
||||
}
|
||||
}
|
||||
|
||||
if (error_status & IDE_RETRY_DMA) {
|
||||
} else if (IS_IDE_RETRY_DMA(error_status)) {
|
||||
if (error_status & IDE_RETRY_TRIM) {
|
||||
ide_restart_dma(s, IDE_DMA_TRIM);
|
||||
} else {
|
||||
ide_restart_dma(s, is_read ? IDE_DMA_READ : IDE_DMA_WRITE);
|
||||
}
|
||||
} else if (error_status & IDE_RETRY_PIO) {
|
||||
} else if (IS_IDE_RETRY_PIO(error_status)) {
|
||||
if (is_read) {
|
||||
ide_sector_read(s);
|
||||
} else {
|
||||
|
@ -2534,15 +2538,11 @@ static void ide_restart_bh(void *opaque)
|
|||
}
|
||||
} else if (error_status & IDE_RETRY_FLUSH) {
|
||||
ide_flush_cache(s);
|
||||
} else if (IS_IDE_RETRY_ATAPI(error_status)) {
|
||||
assert(s->end_transfer_func == ide_atapi_cmd);
|
||||
ide_atapi_dma_restart(s);
|
||||
} else {
|
||||
/*
|
||||
* We've not got any bits to tell us about ATAPI - but
|
||||
* we do have the end_transfer_func that tells us what
|
||||
* we're trying to do.
|
||||
*/
|
||||
if (s->end_transfer_func == ide_atapi_cmd) {
|
||||
ide_atapi_dma_restart(s);
|
||||
}
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue