Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/jnsnow/tags/ide-pull-request' i…
Browse files Browse the repository at this point in the history
…nto staging

# gpg: Signature made Fri 13 Nov 2015 20:16:21 GMT using RSA key ID AAFC390E
# gpg: Good signature from "John Snow (John Huston) <jsnow@redhat.com>"

* remotes/jnsnow/tags/ide-pull-request:
  qtest/ahci: use raw format when qemu-img is absent
  libqos: add qemu-img presence check
  qtest/ahci: always specify image format
  ahci/qtest: don't use tcp sockets for migration tests
  atapi: Prioritize unknown cmd error over BCL error
  atapi: add byte_count_limit helper

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Nov 16, 2015
2 parents 8337c6c + 917158d commit bc7c6c1
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 55 deletions.
38 changes: 23 additions & 15 deletions hw/ide/atapi.c
Expand Up @@ -170,6 +170,17 @@ void ide_atapi_io_error(IDEState *s, int ret)
}
}

static uint16_t atapi_byte_count_limit(IDEState *s)
{
uint16_t bcl;

bcl = s->lcyl | (s->hcyl << 8);
if (bcl == 0xffff) {
return 0xfffe;
}
return bcl;
}

/* The whole ATAPI transfer logic is handled in this function */
void ide_atapi_cmd_reply_end(IDEState *s)
{
Expand Down Expand Up @@ -212,12 +223,10 @@ void ide_atapi_cmd_reply_end(IDEState *s)
} else {
/* a new transfer is needed */
s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
byte_count_limit = s->lcyl | (s->hcyl << 8);
byte_count_limit = atapi_byte_count_limit(s);
#ifdef DEBUG_IDE_ATAPI
printf("byte_count_limit=%d\n", byte_count_limit);
#endif
if (byte_count_limit == 0xffff)
byte_count_limit--;
size = s->packet_transfer_size;
if (size > byte_count_limit) {
/* byte count limit must be even if this case */
Expand Down Expand Up @@ -1186,7 +1195,7 @@ enum {
NONDATA = 0x04,
};

static const struct {
static const struct AtapiCmd {
void (*handler)(IDEState *s, uint8_t *buf);
int flags;
} atapi_cmd_table[0x100] = {
Expand All @@ -1213,9 +1222,9 @@ static const struct {

void ide_atapi_cmd(IDEState *s)
{
uint8_t *buf;
uint8_t *buf = s->io_buffer;
const struct AtapiCmd *cmd = &atapi_cmd_table[s->io_buffer[0]];

buf = s->io_buffer;
#ifdef DEBUG_IDE_ATAPI
{
int i;
Expand All @@ -1226,14 +1235,14 @@ void ide_atapi_cmd(IDEState *s)
printf("\n");
}
#endif

/*
* If there's a UNIT_ATTENTION condition pending, only command flagged with
* ALLOW_UA are allowed to complete. with other commands getting a CHECK
* condition response unless a higher priority status, defined by the drive
* here, is pending.
*/
if (s->sense_key == UNIT_ATTENTION &&
!(atapi_cmd_table[s->io_buffer[0]].flags & ALLOW_UA)) {
if (s->sense_key == UNIT_ATTENTION && !(cmd->flags & ALLOW_UA)) {
ide_atapi_cmd_check_status(s);
return;
}
Expand All @@ -1244,7 +1253,7 @@ void ide_atapi_cmd(IDEState *s)
* GET_EVENT_STATUS_NOTIFICATION to detect such tray open/close
* states rely on this behavior.
*/
if (!(atapi_cmd_table[s->io_buffer[0]].flags & ALLOW_UA) &&
if (!(cmd->flags & ALLOW_UA) &&
!s->tray_open && blk_is_inserted(s->blk) && s->cdrom_changed) {

if (s->cdrom_changed == 1) {
Expand All @@ -1259,7 +1268,7 @@ void ide_atapi_cmd(IDEState *s)
}

/* Report a Not Ready condition if appropriate for the command */
if ((atapi_cmd_table[s->io_buffer[0]].flags & CHECK_READY) &&
if ((cmd->flags & CHECK_READY) &&
(!media_present(s) || !blk_is_inserted(s->blk)))
{
ide_atapi_cmd_error(s, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
Expand All @@ -1270,19 +1279,18 @@ void ide_atapi_cmd(IDEState *s)
* If this is a data-transferring PIO command and BCL is 0,
* we abort at the /ATA/ level, not the ATAPI level.
* See ATA8 ACS3 section 7.17.6.49 and 7.21.5 */
if (!(atapi_cmd_table[s->io_buffer[0]].flags & NONDATA)) {
if (cmd->handler && !(cmd->flags & NONDATA)) {
/* TODO: Check IDENTIFY data word 125 for default BCL (currently 0) */
uint16_t byte_count_limit = s->lcyl | (s->hcyl << 8);
if (!(byte_count_limit || s->atapi_dma)) {
if (!(atapi_byte_count_limit(s) || s->atapi_dma)) {
/* TODO: Move abort back into core.c and make static inline again */
ide_abort_command(s);
return;
}
}

/* Execute the command */
if (atapi_cmd_table[s->io_buffer[0]].handler) {
atapi_cmd_table[s->io_buffer[0]].handler(s, buf);
if (cmd->handler) {
cmd->handler(s, buf);
return;
}

Expand Down

0 comments on commit bc7c6c1

Please sign in to comment.