TESTS: simple support for READDEFECTDATA10/12

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
This commit is contained in:
Ronnie Sahlberg
2016-09-22 22:43:16 -07:00
parent 01a8e22207
commit 39001203b7
14 changed files with 409 additions and 1 deletions

View File

@@ -799,6 +799,18 @@ iscsi_readcapacity16_task(struct iscsi_context *iscsi, int lun,
iscsi_command_cb cb,
void *private_data);
EXTERN struct scsi_task *
iscsi_readdefectdata10_task(struct iscsi_context *iscsi, int lun,
int req_plist, int req_glist,
int defect_list_format, uint16_t alloc_len,
iscsi_command_cb cb, void *private_data);
EXTERN struct scsi_task *
iscsi_readdefectdata12_task(struct iscsi_context *iscsi, int lun,
int req_plist, int req_glist,
int defect_list_format,
uint32_t address_descriptor_index,
uint32_t alloc_len,
iscsi_command_cb cb, void *private_data);
EXTERN struct scsi_task *
iscsi_sanitize_task(struct iscsi_context *iscsi, int lun,
int immed, int ause, int sa, int param_len,
struct iscsi_data *data,
@@ -1291,6 +1303,17 @@ iscsi_readcapacity10_sync(struct iscsi_context *iscsi, int lun, int lba,
EXTERN struct scsi_task *
iscsi_readcapacity16_sync(struct iscsi_context *iscsi, int lun);
EXTERN struct scsi_task *
iscsi_readdefectdata10_sync(struct iscsi_context *iscsi, int lun,
int req_plist, int req_glist,
int defect_list_format, uint16_t alloc_len);
EXTERN struct scsi_task *
iscsi_readdefectdata12_sync(struct iscsi_context *iscsi, int lun,
int req_plist, int req_glist,
int defect_list_format,
uint32_t address_descriptor_index,
uint32_t alloc_len);
EXTERN struct scsi_task *
iscsi_get_lba_status_sync(struct iscsi_context *iscsi, int lun, uint64_t starting_lba, uint32_t alloc_len);

View File

@@ -46,6 +46,7 @@ enum scsi_opcode {
SCSI_OPCODE_VERIFY10 = 0x2F,
SCSI_OPCODE_PREFETCH10 = 0x34,
SCSI_OPCODE_SYNCHRONIZECACHE10 = 0x35,
SCSI_OPCODE_READ_DEFECT_DATA10 = 0x37,
SCSI_OPCODE_WRITE_SAME10 = 0x41,
SCSI_OPCODE_UNMAP = 0x42,
SCSI_OPCODE_READTOC = 0x43,
@@ -72,7 +73,8 @@ enum scsi_opcode {
SCSI_OPCODE_READ12 = 0xA8,
SCSI_OPCODE_WRITE12 = 0xAA,
SCSI_OPCODE_WRITE_VERIFY12 = 0xAE,
SCSI_OPCODE_VERIFY12 = 0xAF
SCSI_OPCODE_VERIFY12 = 0xAF,
SCSI_OPCODE_READ_DEFECT_DATA12 = 0xB7
};
enum scsi_persistent_in_sa {
@@ -1119,6 +1121,8 @@ EXTERN struct scsi_task *scsi_cdb_read10(uint32_t lba, uint32_t xferlen, int blo
EXTERN struct scsi_task *scsi_cdb_read12(uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number);
EXTERN struct scsi_task *scsi_cdb_read16(uint64_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number);
EXTERN struct scsi_task *scsi_cdb_readcapacity16(void);
EXTERN struct scsi_task *scsi_cdb_readdefectdata10(int req_plist, int req_glist, int defect_list_format, uint16_t alloc_len);
EXTERN struct scsi_task *scsi_cdb_readdefectdata12(int req_plist, int req_glist, int defect_list_format, uint32_t address_descriptor_index, uint32_t alloc_len);
EXTERN struct scsi_task *scsi_cdb_report_supported_opcodes(int rctd, int options, enum scsi_opcode opcode, int sa, uint32_t alloc_len);
EXTERN struct scsi_task *scsi_cdb_serviceactionin16(enum scsi_service_action_in sa, uint32_t xferlen);
EXTERN struct scsi_task *scsi_cdb_startstopunit(int immed, int pcm, int pc, int no_flush, int loej, int start);

View File

@@ -718,6 +718,57 @@ iscsi_readcapacity16_task(struct iscsi_context *iscsi, int lun,
return task;
}
struct scsi_task *
iscsi_readdefectdata10_task(struct iscsi_context *iscsi, int lun,
int req_plist, int req_glist,
int defect_list_format, uint16_t alloc_len,
iscsi_command_cb cb, void *private_data)
{
struct scsi_task *task;
task = scsi_cdb_readdefectdata10(req_plist, req_glist,
defect_list_format, alloc_len);
if (task == NULL) {
iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
"readdefectdata10 cdb.");
return NULL;
}
if (iscsi_scsi_command_async(iscsi, lun, task, cb,
NULL, private_data) != 0) {
scsi_free_scsi_task(task);
return NULL;
}
return task;
}
struct scsi_task *
iscsi_readdefectdata12_task(struct iscsi_context *iscsi, int lun,
int req_plist, int req_glist,
int defect_list_format,
uint32_t address_descriptor_index,
uint32_t alloc_len,
iscsi_command_cb cb, void *private_data)
{
struct scsi_task *task;
task = scsi_cdb_readdefectdata12(req_plist, req_glist,
defect_list_format,
address_descriptor_index, alloc_len);
if (task == NULL) {
iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
"readdefectdata12 cdb.");
return NULL;
}
if (iscsi_scsi_command_async(iscsi, lun, task, cb,
NULL, private_data) != 0) {
scsi_free_scsi_task(task);
return NULL;
}
return task;
}
struct scsi_task *
iscsi_get_lba_status_task(struct iscsi_context *iscsi, int lun,
uint64_t starting_lba, uint32_t alloc_len,

View File

@@ -69,6 +69,10 @@ iscsi_readcapacity10_sync
iscsi_readcapacity10_task
iscsi_readcapacity16_sync
iscsi_readcapacity16_task
iscsi_readdefectdata10_sync
iscsi_readdefectdata10_task
iscsi_readdefectdata12_sync
iscsi_readdefectdata12_task
iscsi_readtoc_sync
iscsi_readtoc_task
iscsi_reserve6_sync
@@ -212,6 +216,8 @@ scsi_cdb_read16
scsi_cdb_read6
scsi_cdb_readcapacity10
scsi_cdb_readcapacity16
scsi_cdb_readdefectdata10
scsi_cdb_readdefectdata12
scsi_cdb_readtoc
scsi_cdb_receive_copy_results
scsi_cdb_reserve6

View File

@@ -67,6 +67,10 @@ iscsi_readcapacity10_sync
iscsi_readcapacity10_task
iscsi_readcapacity16_sync
iscsi_readcapacity16_task
iscsi_readdefectdata10_sync
iscsi_readdefectdata10_task
iscsi_readdefectdata12_sync
iscsi_readdefectdata12_task
iscsi_readtoc_sync
iscsi_readtoc_task
iscsi_reserve6_sync
@@ -210,6 +214,8 @@ scsi_cdb_read16
scsi_cdb_read6
scsi_cdb_readcapacity10
scsi_cdb_readcapacity16
scsi_cdb_readdefectdata10
scsi_cdb_readdefectdata12
scsi_cdb_readtoc
scsi_cdb_receive_copy_results
scsi_cdb_reserve6

View File

@@ -536,6 +536,75 @@ scsi_cdb_readcapacity10(int lba, int pmi)
return task;
}
/*
* READDEFECTDATA10
*/
struct scsi_task *
scsi_cdb_readdefectdata10(int req_plist, int req_glist, int defect_list_format,
uint16_t alloc_len)
{
struct scsi_task *task;
task = malloc(sizeof(struct scsi_task));
if (task == NULL) {
return NULL;
}
memset(task, 0, sizeof(struct scsi_task));
task->cdb[0] = SCSI_OPCODE_READ_DEFECT_DATA10;
if (req_plist) {
task->cdb[2] |= 0x10;
}
if (req_glist) {
task->cdb[2] |= 0x08;
}
task->cdb[2] |= (defect_list_format & 0x07);
scsi_set_uint16(&task->cdb[7], alloc_len);
task->cdb_size = 10;
task->xfer_dir = SCSI_XFER_READ;
task->expxferlen = alloc_len;
return task;
}
/*
* READDEFECTDATA12
*/
struct scsi_task *
scsi_cdb_readdefectdata12(int req_plist, int req_glist, int defect_list_format,
uint32_t address_descriptor_index, uint32_t alloc_len)
{
struct scsi_task *task;
task = malloc(sizeof(struct scsi_task));
if (task == NULL) {
return NULL;
}
memset(task, 0, sizeof(struct scsi_task));
task->cdb[0] = SCSI_OPCODE_READ_DEFECT_DATA12;
if (req_plist) {
task->cdb[2] |= 0x10;
}
if (req_glist) {
task->cdb[2] |= 0x08;
}
task->cdb[2] |= (defect_list_format & 0x07);
scsi_set_uint32(&task->cdb[2], address_descriptor_index);
scsi_set_uint32(&task->cdb[6], alloc_len);
task->cdb_size = 12;
task->xfer_dir = SCSI_XFER_READ;
task->expxferlen = alloc_len;
return task;
}
/*
* READTOC
*/

View File

@@ -614,6 +614,55 @@ iscsi_readcapacity16_sync(struct iscsi_context *iscsi, int lun)
return state.task;
}
struct scsi_task *
iscsi_readdefectdata10_sync(struct iscsi_context *iscsi, int lun,
int req_plist, int req_glist,
int defect_list_format, uint16_t alloc_len)
{
struct iscsi_sync_state state;
memset(&state, 0, sizeof(state));
if (iscsi_readdefectdata10_task(iscsi, lun,
req_plist, req_glist,
defect_list_format, alloc_len,
scsi_sync_cb, &state) == NULL) {
iscsi_set_error(iscsi,
"Failed to send ReadDefectData10 command");
return NULL;
}
event_loop(iscsi, &state);
return state.task;
}
struct scsi_task *
iscsi_readdefectdata12_sync(struct iscsi_context *iscsi, int lun,
int req_plist, int req_glist,
int defect_list_format,
uint32_t address_descriptor_index,
uint32_t alloc_len)
{
struct iscsi_sync_state state;
memset(&state, 0, sizeof(state));
if (iscsi_readdefectdata12_task(iscsi, lun,
req_plist, req_glist,
defect_list_format,
address_descriptor_index, alloc_len,
scsi_sync_cb, &state) == NULL) {
iscsi_set_error(iscsi,
"Failed to send ReadDefectData12 command");
return NULL;
}
event_loop(iscsi, &state);
return state.task;
}
struct scsi_task *
iscsi_sanitize_sync(struct iscsi_context *iscsi, int lun,
int immed, int ause, int sa, int param_len,

View File

@@ -104,6 +104,8 @@ iscsi_test_cu_SOURCES = iscsi-test-cu.c \
test_readcapacity16_protection.c \
test_readcapacity16_simple.c \
test_readcapacity16_support.c \
test_readdefectdata10_simple.c \
test_readdefectdata12_simple.c \
test_readonly_sbc.c \
test_receive_copy_results_copy_status.c \
test_receive_copy_results_op_params.c \

View File

@@ -2008,6 +2008,70 @@ readcapacity16(struct scsi_device *sdev, struct scsi_task **out_task, int alloc_
return ret;
}
int
readdefectdata10(struct scsi_device *sdev, struct scsi_task **out_task,
int req_plist, int req_glist,
int defect_list_format, uint16_t alloc_len,
int status, enum scsi_sense_key key, int *ascq, int num_ascq)
{
struct scsi_task *task;
int ret;
logging(LOG_VERBOSE, "Send READDEFECTDATA10 (Expecting %s)"
" req_plist:%d req_glist:%d format:%d",
scsi_status_str(status),
req_plist, req_glist, defect_list_format);
task = scsi_cdb_readdefectdata10(req_plist, req_glist,
defect_list_format, alloc_len);
assert(task != NULL);
task = send_scsi_command(sdev, task, NULL);
ret = check_result("READDEFECTDATA10", sdev, task,
status, key, ascq, num_ascq);
if (out_task) {
*out_task = task;
} else if (task) {
scsi_free_scsi_task(task);
}
return ret;
}
int
readdefectdata12(struct scsi_device *sdev, struct scsi_task **out_task,
int req_plist, int req_glist,
int defect_list_format,
uint32_t address_descriptor_index,
uint32_t alloc_len,
int status, enum scsi_sense_key key, int *ascq, int num_ascq)
{
struct scsi_task *task;
int ret;
logging(LOG_VERBOSE, "Send READDEFECTDATA12 (Expecting %s)"
" req_plist:%d req_glist:%d format:%d",
scsi_status_str(status),
req_plist, req_glist, defect_list_format);
task = scsi_cdb_readdefectdata12(req_plist, req_glist,
defect_list_format,
address_descriptor_index,
alloc_len);
assert(task != NULL);
task = send_scsi_command(sdev, task, NULL);
ret = check_result("READDEFECTDATA12", sdev, task,
status, key, ascq, num_ascq);
if (out_task) {
*out_task = task;
} else if (task) {
scsi_free_scsi_task(task);
}
return ret;
}
int
release6(struct scsi_device *sdev)
{

View File

@@ -389,6 +389,34 @@ do { \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define READDEFECTDATA10(...) \
do { \
int _r; \
_r = readdefectdata10(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] READDEFECTDATA10 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"READDEFECTDATA10. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define READDEFECTDATA12(...) \
do { \
int _r; \
_r = readdefectdata12(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] READDEFECTDATA12 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"READDEFECTDATA12. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define RECEIVE_COPY_RESULTS(...) \
do { \
int _r; \
@@ -833,6 +861,18 @@ int read12(struct scsi_device *sdev, struct scsi_task **task, uint32_t lba, uint
int read16(struct scsi_device *sdev, struct scsi_task **task, uint64_t lba, uint32_t datalen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int readcapacity10(struct scsi_device *sdev, struct scsi_task **task, uint32_t lba, int pmi, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int readcapacity16(struct scsi_device *sdev, struct scsi_task **task, int alloc_len, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int readdefectdata10(struct scsi_device *sdev, struct scsi_task **task,
int req_plist, int req_glist,
int defect_list_format, uint16_t alloc_len,
int status, enum scsi_sense_key key,
int *ascq, int num_ascq);
int readdefectdata12(struct scsi_device *sdev, struct scsi_task **task,
int req_plist, int req_glist,
int defect_list_format,
uint32_t address_descriptor_index,
uint32_t alloc_len,
int status, enum scsi_sense_key key,
int *ascq, int num_ascq);
int report_supported_opcodes(struct scsi_device *sdev, struct scsi_task **save_task, int rctd, int options, int opcode, int sa, int alloc_len, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int release6(struct scsi_device *sdev);
int reserve6(struct scsi_device *sdev);

View File

@@ -265,6 +265,16 @@ static CU_TestInfo tests_readcapacity16[] = {
CU_TEST_INFO_NULL
};
static CU_TestInfo tests_readdefectdata10[] = {
{ (char *)"Simple", test_readdefectdata10_simple },
CU_TEST_INFO_NULL
};
static CU_TestInfo tests_readdefectdata12[] = {
{ (char *)"Simple", test_readdefectdata12_simple },
CU_TEST_INFO_NULL
};
static CU_TestInfo tests_readonly[] = {
{ (char *)"ReadOnlySBC", test_readonly_sbc },
CU_TEST_INFO_NULL
@@ -516,6 +526,8 @@ static libiscsi_suite_info scsi_suites[] = {
{ "Read16", NON_PGR_FUNCS, tests_read16 },
{ "ReadCapacity10", NON_PGR_FUNCS, tests_readcapacity10 },
{ "ReadCapacity16", NON_PGR_FUNCS, tests_readcapacity16 },
{ "ReadDefectData10", NON_PGR_FUNCS, tests_readdefectdata10 },
{ "ReadDefectData12", NON_PGR_FUNCS, tests_readdefectdata12 },
{ "ReadOnly", NON_PGR_FUNCS, tests_readonly },
{ "ReceiveCopyResults", NON_PGR_FUNCS, tests_receive_copy_results },
{ "ReportSupportedOpcodes", NON_PGR_FUNCS,
@@ -611,6 +623,8 @@ static libiscsi_suite_info all_suites[] = {
{ "Read16", NON_PGR_FUNCS, tests_read16 },
{ "ReadCapacity10", NON_PGR_FUNCS, tests_readcapacity10 },
{ "ReadCapacity16", NON_PGR_FUNCS, tests_readcapacity16 },
{ "ReadDefectData10", NON_PGR_FUNCS, tests_readdefectdata10 },
{ "ReadDefectData12", NON_PGR_FUNCS, tests_readdefectdata12 },
{ "ReadOnly", NON_PGR_FUNCS, tests_readonly },
{ "ReceiveCopyResults", NON_PGR_FUNCS, tests_receive_copy_results },
{ "ReportSupportedOpcodes", NON_PGR_FUNCS,
@@ -654,6 +668,8 @@ static libiscsi_suite_info linux_suites[] = {
{ "Read16", NON_PGR_FUNCS, tests_read16 },
{ "ReadCapacity10", NON_PGR_FUNCS, tests_readcapacity10 },
{ "ReadCapacity16", NON_PGR_FUNCS, tests_readcapacity16 },
{ "ReadDefectData10", NON_PGR_FUNCS, tests_readdefectdata10 },
{ "ReadDefectData12", NON_PGR_FUNCS, tests_readdefectdata12 },
{ "ReadOnly", NON_PGR_FUNCS, tests_readonly },
{ "ReportSupportedOpcodes", NON_PGR_FUNCS,
tests_report_supported_opcodes },

View File

@@ -170,6 +170,10 @@ void test_readcapacity16_protection(void);
void test_readcapacity16_simple(void);
void test_readcapacity16_support(void);
void test_readdefectdata10_simple(void);
void test_readdefectdata12_simple(void);
void test_readonly_sbc(void);
void test_receive_copy_results_copy_status(void);

View File

@@ -0,0 +1,37 @@
/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */
/*
Copyright (C) 2013 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <CUnit/CUnit.h>
#include "iscsi.h"
#include "scsi-lowlevel.h"
#include "iscsi-support.h"
#include "iscsi-test-cu.h"
void
test_readdefectdata10_simple(void)
{
logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test basic READDEFECTDATA10");
READDEFECTDATA10(sd, NULL, 0, 0, 0, 32,
EXPECT_STATUS_GOOD);
}

View File

@@ -0,0 +1,37 @@
/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */
/*
Copyright (C) 2013 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <CUnit/CUnit.h>
#include "iscsi.h"
#include "scsi-lowlevel.h"
#include "iscsi-support.h"
#include "iscsi-test-cu.h"
void
test_readdefectdata12_simple(void)
{
logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test basic READDEFECTDATA12");
READDEFECTDATA12(sd, NULL, 0, 0, 0, 0, 32,
EXPECT_STATUS_GOOD);
}