From f9f963e0fbba98d7ece75287c40d0c1b249dc9b4 Mon Sep 17 00:00:00 2001 From: John Snow Date: Wed, 25 Feb 2015 18:06:37 -0500 Subject: libqos/ahci: add ahci command helpers ahci_command_set_flags: Set additional flags in the command header. ahci_command_clr_flags: Clear flags from the command header. ahci_command_set_offset: Change the IO sector from 0. ahci_command_adjust: Adjust many values simultaneously. To be used to adjust the command header if the default values/guesses were incorrect or undesirable. Signed-off-by: John Snow Message-id: 1424905602-24715-4-git-send-email-jsnow@redhat.com Signed-off-by: Stefan Hajnoczi [ kwolf: Fixed conflicting prototype for ahci_command_adjust() ] Signed-off-by: Kevin Wolf --- tests/libqos/ahci.c | 42 ++++++++++++++++++++++++++++++++++++++++++ tests/libqos/ahci.h | 5 +++++ 2 files changed, 47 insertions(+) (limited to 'tests/libqos') diff --git a/tests/libqos/ahci.c b/tests/libqos/ahci.c index 9dc505ce0a..b0f39a5e32 100644 --- a/tests/libqos/ahci.c +++ b/tests/libqos/ahci.c @@ -713,6 +713,40 @@ void ahci_command_free(AHCICommand *cmd) g_free(cmd); } +void ahci_command_set_flags(AHCICommand *cmd, uint16_t cmdh_flags) +{ + cmd->header.flags |= cmdh_flags; +} + +void ahci_command_clr_flags(AHCICommand *cmd, uint16_t cmdh_flags) +{ + cmd->header.flags &= ~cmdh_flags; +} + +void ahci_command_set_offset(AHCICommand *cmd, uint64_t lba_sect) +{ + RegH2DFIS *fis = &(cmd->fis); + if (cmd->props->lba28) { + g_assert_cmphex(lba_sect, <=, 0xFFFFFFF); + } else if (cmd->props->lba48) { + g_assert_cmphex(lba_sect, <=, 0xFFFFFFFFFFFF); + } else { + /* Can't set offset if we don't know the format. */ + g_assert_not_reached(); + } + + /* LBA28 uses the low nibble of the device/control register for LBA24:27 */ + fis->lba_lo[0] = (lba_sect & 0xFF); + fis->lba_lo[1] = (lba_sect >> 8) & 0xFF; + fis->lba_lo[2] = (lba_sect >> 16) & 0xFF; + if (cmd->props->lba28) { + fis->device = (fis->device & 0xF0) || (lba_sect >> 24) & 0x0F; + } + fis->lba_hi[0] = (lba_sect >> 24) & 0xFF; + fis->lba_hi[1] = (lba_sect >> 32) & 0xFF; + fis->lba_hi[2] = (lba_sect >> 40) & 0xFF; +} + void ahci_command_set_buffer(AHCICommand *cmd, uint64_t buffer) { cmd->buffer = buffer; @@ -740,6 +774,14 @@ void ahci_command_set_prd_size(AHCICommand *cmd, unsigned prd_size) ahci_command_set_sizes(cmd, cmd->xbytes, prd_size); } +void ahci_command_adjust(AHCICommand *cmd, uint64_t offset, uint64_t buffer, + uint64_t xbytes, unsigned prd_size) +{ + ahci_command_set_sizes(cmd, xbytes, prd_size); + ahci_command_set_buffer(cmd, buffer); + ahci_command_set_offset(cmd, offset); +} + void ahci_command_commit(AHCIQState *ahci, AHCICommand *cmd, uint8_t port) { uint16_t i, prdtl; diff --git a/tests/libqos/ahci.h b/tests/libqos/ahci.h index 39b99d3658..888545d5a2 100644 --- a/tests/libqos/ahci.h +++ b/tests/libqos/ahci.h @@ -537,11 +537,16 @@ void ahci_command_verify(AHCIQState *ahci, AHCICommand *cmd); void ahci_command_free(AHCICommand *cmd); /* Command adjustments */ +void ahci_command_set_flags(AHCICommand *cmd, uint16_t cmdh_flags); +void ahci_command_clr_flags(AHCICommand *cmd, uint16_t cmdh_flags); +void ahci_command_set_offset(AHCICommand *cmd, uint64_t lba_sect); void ahci_command_set_buffer(AHCICommand *cmd, uint64_t buffer); void ahci_command_set_size(AHCICommand *cmd, uint64_t xbytes); void ahci_command_set_prd_size(AHCICommand *cmd, unsigned prd_size); void ahci_command_set_sizes(AHCICommand *cmd, uint64_t xbytes, unsigned prd_size); +void ahci_command_adjust(AHCICommand *cmd, uint64_t lba_sect, uint64_t gbuffer, + uint64_t xbytes, unsigned prd_size); /* Command Misc */ uint8_t ahci_command_slot(AHCICommand *cmd); -- cgit v1.2.1