aboutsummaryrefslogtreecommitdiff
path: root/tests/libqos
diff options
context:
space:
mode:
authorJohn Snow <jsnow@redhat.com>2016-11-14 11:15:54 -0500
committerJohn Snow <jsnow@redhat.com>2016-11-14 11:15:54 -0500
commitebde93bf9a13f2e0a853eac8fb4f33c9ecd74baf (patch)
tree8b0b8b3eda42422c98cc6e6bdf9d53483aaca40f /tests/libqos
parent53c05e6c20509adcff40fe1c7a02210354fe53f7 (diff)
ahci-test: test atapi read_cd with bcl, nb_sectors = 0
Commit 9ef2e93f introduced the concept of tagging ATAPI commands as NONDATA, but this introduced a regression for certain commands better described as CONDDATA. read_cd is such a command that both requires a non-zero BCL if a transfer size is set, but is perfectly content to accept a zero BCL if the transfer size is 0. This test adds a regression test for the case where BCL and nb_sectors are both 0. Flesh out the CDROM tests by: (1) Allowing the test to specify a BCL (2) Allowing the buffer comparison test to compare a 0-size buffer (3) Fix the BCL specification in libqos (It is LE, not BE) (4) Add a nice human-readable message for future SCSI command additions Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Message-id: 1477970211-25754-4-git-send-email-jsnow@redhat.com [Line length edit --js] Signed-off-by: John Snow <jsnow@redhat.com>
Diffstat (limited to 'tests/libqos')
-rw-r--r--tests/libqos/ahci.c28
-rw-r--r--tests/libqos/ahci.h17
2 files changed, 31 insertions, 14 deletions
diff --git a/tests/libqos/ahci.c b/tests/libqos/ahci.c
index 5180d65279..0e9354bf13 100644
--- a/tests/libqos/ahci.c
+++ b/tests/libqos/ahci.c
@@ -633,7 +633,8 @@ void ahci_exec(AHCIQState *ahci, uint8_t port,
/* Command creation */
if (opts->atapi) {
- cmd = ahci_atapi_command_create(op);
+ uint16_t bcl = opts->set_bcl ? opts->bcl : ATAPI_SECTOR_SIZE;
+ cmd = ahci_atapi_command_create(op, bcl);
if (opts->atapi_dma) {
ahci_command_enable_atapi_dma(cmd);
}
@@ -864,16 +865,12 @@ AHCICommand *ahci_command_create(uint8_t command_name)
return cmd;
}
-AHCICommand *ahci_atapi_command_create(uint8_t scsi_cmd)
+AHCICommand *ahci_atapi_command_create(uint8_t scsi_cmd, uint16_t bcl)
{
AHCICommand *cmd = ahci_command_create(CMD_PACKET);
cmd->atapi_cmd = g_malloc0(16);
cmd->atapi_cmd[0] = scsi_cmd;
- /* ATAPI needs a PIO transfer chunk size set inside of the LBA registers.
- * The block/sector size is a natural default. */
- cmd->fis.lba_lo[1] = ATAPI_SECTOR_SIZE >> 8 & 0xFF;
- cmd->fis.lba_lo[2] = ATAPI_SECTOR_SIZE & 0xFF;
-
+ stw_le_p(&cmd->fis.lba_lo[1], bcl);
return cmd;
}
@@ -901,12 +898,17 @@ static void ahci_atapi_command_set_offset(AHCICommand *cmd, uint64_t lba)
switch (cbd[0]) {
case CMD_ATAPI_READ_10:
+ case CMD_ATAPI_READ_CD:
g_assert_cmpuint(lba, <=, UINT32_MAX);
stl_be_p(&cbd[2], lba);
break;
default:
/* SCSI doesn't have uniform packet formats,
* so you have to add support for it manually. Sorry! */
+ fprintf(stderr, "The Libqos AHCI driver does not support the "
+ "set_offset operation for ATAPI command 0x%02x, "
+ "please add support.\n",
+ cbd[0]);
g_assert_not_reached();
}
}
@@ -951,6 +953,7 @@ static void ahci_atapi_set_size(AHCICommand *cmd, uint64_t xbytes)
{
unsigned char *cbd = cmd->atapi_cmd;
uint64_t nsectors = xbytes / 2048;
+ uint32_t tmp;
g_assert(cbd);
switch (cbd[0]) {
@@ -958,9 +961,20 @@ static void ahci_atapi_set_size(AHCICommand *cmd, uint64_t xbytes)
g_assert_cmpuint(nsectors, <=, UINT16_MAX);
stw_be_p(&cbd[7], nsectors);
break;
+ case CMD_ATAPI_READ_CD:
+ /* 24bit BE store */
+ g_assert_cmpuint(nsectors, <, 1ULL << 24);
+ tmp = nsectors;
+ cbd[6] = (tmp & 0xFF0000) >> 16;
+ cbd[7] = (tmp & 0xFF00) >> 8;
+ cbd[8] = (tmp & 0xFF);
+ break;
default:
/* SCSI doesn't have uniform packet formats,
* so you have to add support for it manually. Sorry! */
+ fprintf(stderr, "The Libqos AHCI driver does not support the set_size "
+ "operation for ATAPI command 0x%02x, please add support.\n",
+ cbd[0]);
g_assert_not_reached();
}
}
diff --git a/tests/libqos/ahci.h b/tests/libqos/ahci.h
index caaafe3fdf..f144fab37a 100644
--- a/tests/libqos/ahci.h
+++ b/tests/libqos/ahci.h
@@ -288,6 +288,7 @@ enum {
/* ATAPI Commands */
enum {
CMD_ATAPI_READ_10 = 0x28,
+ CMD_ATAPI_READ_CD = 0xbe,
};
/* AHCI Command Header Flags & Masks*/
@@ -462,12 +463,14 @@ typedef struct AHCICommand AHCICommand;
/* Options to ahci_exec */
typedef struct AHCIOpts {
- size_t size;
- unsigned prd_size;
- uint64_t lba;
- uint64_t buffer;
- bool atapi;
- bool atapi_dma;
+ size_t size; /* Size of transfer */
+ unsigned prd_size; /* Size per-each PRD */
+ bool set_bcl; /* Override the default BCL of ATAPI_SECTOR_SIZE */
+ unsigned bcl; /* Byte Count Limit, for ATAPI PIO */
+ uint64_t lba; /* Starting LBA offset */
+ uint64_t buffer; /* Pointer to source or destination guest buffer */
+ bool atapi; /* ATAPI command? */
+ bool atapi_dma; /* Use DMA for ATAPI? */
bool error;
int (*pre_cb)(AHCIQState*, AHCICommand*, const struct AHCIOpts *);
int (*mid_cb)(AHCIQState*, AHCICommand*, const struct AHCIOpts *);
@@ -599,7 +602,7 @@ void ahci_exec(AHCIQState *ahci, uint8_t port,
/* Command: Fine-grained lifecycle */
AHCICommand *ahci_command_create(uint8_t command_name);
-AHCICommand *ahci_atapi_command_create(uint8_t scsi_cmd);
+AHCICommand *ahci_atapi_command_create(uint8_t scsi_cmd, uint16_t bcl);
void ahci_command_commit(AHCIQState *ahci, AHCICommand *cmd, uint8_t port);
void ahci_command_issue(AHCIQState *ahci, AHCICommand *cmd);
void ahci_command_issue_async(AHCIQState *ahci, AHCICommand *cmd);