diff --git a/doc/scst_user_spec.sgml b/doc/scst_user_spec.sgml
index fa455c9f5..2e65eb8bd 100644
--- a/doc/scst_user_spec.sgml
+++ b/doc/scst_user_spec.sgml
@@ -10,7 +10,7 @@ SCST user space device handler module interface descrition
Vladislav Bolkhovitin
-Version 2.1.0
+Version 3.0.0
@@ -380,6 +380,7 @@ struct scst_user_scsi_cmd_reply_parse
uint8_t queue_type;
uint8_t data_direction;
uint16_t cdb_len;
+ aligned_i64 lba;
uint32_t op_flags;
int32_t data_len;
int32_t bufflen;
@@ -401,13 +402,17 @@ where:
- sg_cnt;
}
+/* Returns cmd's LBA */
+static inline int64_t scst_cmd_get_lba(struct scst_cmd *cmd)
+{
+ return cmd->lba;
+}
+
/*
* Returns cmd's data buffer length.
*
@@ -3116,11 +3127,20 @@ static inline int scst_cmd_get_sg_cnt(struct scst_cmd *cmd)
* this function is not recommended, use scst_get_buf_*()
* family of functions instead.
*/
-static inline unsigned int scst_cmd_get_bufflen(struct scst_cmd *cmd)
+static inline int scst_cmd_get_bufflen(struct scst_cmd *cmd)
{
return cmd->bufflen;
}
+/*
+ * Returns cmd's data_len. See the corresponding field's description in
+ * struct scst_cmd above.
+ */
+static inline int scst_cmd_get_data_len(struct scst_cmd *cmd)
+{
+ return cmd->data_len;
+}
+
/*
* Returns pointer to cmd's bidirectional in (WRITE) SG data buffer.
*
@@ -3514,6 +3534,9 @@ static inline unsigned int scst_get_active_cmd_count(struct scst_cmd *cmd)
return (unsigned int)-1;
}
+int scst_set_cdb_lba(struct scst_cmd *cmd, int64_t len);
+int scst_set_cdb_transf_len(struct scst_cmd *cmd, int len);
+
/*
* Get/Set function for mgmt cmd's target private data
*/
diff --git a/scst/include/scst_const.h b/scst/include/scst_const.h
index a46c59c38..159b2d59d 100644
--- a/scst/include/scst_const.h
+++ b/scst/include/scst_const.h
@@ -183,8 +183,9 @@ enum scst_cdb_flags {
SCST_TRANSFER_LEN_TYPE_FIXED = 0x0001,
SCST_SMALL_TIMEOUT = 0x0002,
SCST_LONG_TIMEOUT = 0x0004,
- SCST_UNKNOWN_LENGTH = 0x0008,
- SCST_INFO_VALID = 0x0010, /* must be single bit */
+ SCST_UNKNOWN_LBA = 0x0008,
+ SCST_UNKNOWN_LENGTH = 0x0010,
+ SCST_INFO_VALID = 0x0020, /* must be single bit */
SCST_IMPLICIT_HQ = 0x0040,
SCST_SKIP_UA = 0x0080,
SCST_WRITE_MEDIUM = 0x0100,
diff --git a/scst/include/scst_user.h b/scst/include/scst_user.h
index 92a2e270d..b19bf33e3 100644
--- a/scst/include/scst_user.h
+++ b/scst/include/scst_user.h
@@ -60,6 +60,10 @@
#define aligned_u64 uint64_t __attribute__((aligned(8)))
#endif
+#ifndef aligned_i64
+#define aligned_i64 int64_t __attribute__((aligned(8)))
+#endif
+
/*************************************************************
** Private ucmd states
*************************************************************/
@@ -125,8 +129,11 @@ struct scst_user_scsi_cmd_parse {
uint8_t cdb[SCST_MAX_CDB_SIZE];
uint16_t cdb_len;
+ aligned_i64 lba;
+
int32_t timeout;
int32_t bufflen;
+ int32_t data_len;
int32_t out_bufflen;
uint32_t op_flags;
@@ -162,6 +169,8 @@ struct scst_user_scsi_cmd_exec {
uint8_t cdb[SCST_MAX_CDB_SIZE];
uint16_t cdb_len;
+ aligned_i64 lba;
+
int32_t data_len;
int32_t bufflen;
int32_t alloc_len;
@@ -225,6 +234,7 @@ struct scst_user_scsi_cmd_reply_parse {
uint8_t queue_type;
uint8_t data_direction;
uint16_t cdb_len;
+ aligned_i64 lba;
uint32_t op_flags;
int32_t data_len;
int32_t bufflen;
diff --git a/scst/src/dev_handlers/scst_disk.c b/scst/src/dev_handlers/scst_disk.c
index 81cd80e1f..ea06b001a 100644
--- a/scst/src/dev_handlers/scst_disk.c
+++ b/scst/src/dev_handlers/scst_disk.c
@@ -368,110 +368,16 @@ struct disk_work {
struct completion disk_work_cmpl;
int result;
unsigned int left;
- uint64_t save_lba;
- unsigned int save_len;
+ int64_t save_lba;
+ int save_len;
struct scatterlist *save_sg;
int save_sg_cnt;
};
-static int disk_cdb_get_transfer_data(const uint8_t *cdb,
- uint64_t *out_lba, unsigned int *out_length)
-{
- int res;
- uint64_t lba;
- unsigned int len;
-
- TRACE_ENTRY();
-
- switch (cdb[0]) {
- case WRITE_6:
- case READ_6:
- lba = get_unaligned_be16(&cdb[2]);
- len = cdb[4];
- break;
- case WRITE_10:
- case READ_10:
- case WRITE_VERIFY:
- lba = get_unaligned_be32(&cdb[2]);
- len = get_unaligned_be16(&cdb[7]);
- break;
- case WRITE_12:
- case READ_12:
- case WRITE_VERIFY_12:
- lba = get_unaligned_be32(&cdb[2]);
- len = get_unaligned_be32(&cdb[6]);
- break;
- case WRITE_16:
- case READ_16:
- case WRITE_VERIFY_16:
- lba = get_unaligned_be64(&cdb[2]);
- len = get_unaligned_be32(&cdb[10]);
- break;
- default:
- res = -EINVAL;
- goto out;
- }
-
- res = 0;
- *out_lba = lba;
- *out_length = len;
-
- TRACE_DBG("LBA %lld, length %d", (unsigned long long)lba, len);
-
-out:
- TRACE_EXIT_RES(res);
- return res;
-}
-
-static int disk_cdb_set_transfer_data(uint8_t *cdb,
- uint64_t lba, unsigned int len)
-{
- int res;
-
- TRACE_ENTRY();
-
- switch (cdb[0]) {
- case WRITE_6:
- case READ_6:
- put_unaligned_be16(lba, &cdb[2]);
- cdb[4] = len;
- break;
- case WRITE_10:
- case READ_10:
- case WRITE_VERIFY:
- put_unaligned_be32(lba, &cdb[2]);
- put_unaligned_be16(len, &cdb[7]);
- break;
- case WRITE_12:
- case READ_12:
- case WRITE_VERIFY_12:
- put_unaligned_be32(lba, &cdb[2]);
- put_unaligned_be32(len, &cdb[6]);
- break;
- case WRITE_16:
- case READ_16:
- case WRITE_VERIFY_16:
- put_unaligned_be64(lba, &cdb[2]);
- put_unaligned_be32(len, &cdb[10]);
- break;
- default:
- res = -EINVAL;
- goto out;
- }
-
- res = 0;
-
- TRACE_DBG("LBA %lld, length %d", (unsigned long long)lba, len);
- TRACE_BUFFER("New CDB", cdb, SCST_MAX_CDB_SIZE);
-
-out:
- TRACE_EXIT_RES(res);
- return res;
-}
-
static void disk_restore_sg(struct disk_work *work)
{
- disk_cdb_set_transfer_data(work->cmd->cdb, work->save_lba, work->save_len);
+ scst_set_cdb_lba(work->cmd, work->save_lba);
+ scst_set_cdb_transf_len(work->cmd, work->save_len);
work->cmd->sg = work->save_sg;
work->cmd->sg_cnt = work->save_sg_cnt;
return;
@@ -546,7 +452,7 @@ static int disk_exec(struct scst_cmd *cmd)
goto split;
}
- if (likely(cmd->sg_cnt <= sg_tablesize)) {
+ if (cmd->sg_cnt <= sg_tablesize) {
res = SCST_EXEC_NOT_COMPLETED;
goto out;
}
@@ -564,10 +470,10 @@ split:
work.cmd = cmd;
work.save_sg = cmd->sg;
work.save_sg_cnt = cmd->sg_cnt;
- rc = disk_cdb_get_transfer_data(cmd->cdb, &work.save_lba,
- &work.save_len);
- if (rc != 0)
- goto out_error;
+ work.save_lba = cmd->lba;
+ work.save_len = cmd->bufflen;
+
+ EXTRACHECKS_BUG_ON(work.save_len < 0);
cmd->status = 0;
cmd->msg_status = 0;
@@ -617,8 +523,8 @@ split:
(cur_len >= max_sectors)) {
TRACE_DBG("%s", "Execing...");
- disk_cdb_set_transfer_data(cmd->cdb,
- work.save_lba + offset, cur_len);
+ scst_set_cdb_lba(work.cmd, work.save_lba + offset);
+ scst_set_cdb_transf_len(work.cmd, cur_len);
cmd->sg = start_sg;
cmd->sg_cnt = cur_sg_cnt;
diff --git a/scst/src/dev_handlers/scst_user.c b/scst/src/dev_handlers/scst_user.c
index 5a9260176..8b54285a8 100644
--- a/scst/src/dev_handlers/scst_user.c
+++ b/scst/src/dev_handlers/scst_user.c
@@ -808,7 +808,9 @@ static int dev_user_parse(struct scst_cmd *cmd)
min_t(int, SCST_MAX_CDB_SIZE, cmd->cdb_len));
ucmd->user_cmd.parse_cmd.cdb_len = cmd->cdb_len;
ucmd->user_cmd.parse_cmd.timeout = cmd->timeout / HZ;
+ ucmd->user_cmd.parse_cmd.lba = cmd->lba;
ucmd->user_cmd.parse_cmd.bufflen = cmd->bufflen;
+ ucmd->user_cmd.parse_cmd.data_len = cmd->data_len;
ucmd->user_cmd.parse_cmd.out_bufflen = cmd->out_bufflen;
ucmd->user_cmd.parse_cmd.queue_type = cmd->queue_type;
ucmd->user_cmd.parse_cmd.data_direction = cmd->data_direction;
@@ -913,9 +915,9 @@ static int dev_user_exec(struct scst_cmd *cmd)
TRACE_ENTRY();
- TRACE_DBG("Preparing EXEC for user space (ucmd=%p, h=%d, "
+ TRACE_DBG("Preparing EXEC for user space (ucmd=%p, h=%d, lba %lld, "
"bufflen %d, data_len %d, ubuff %lx)", ucmd, ucmd->h,
- cmd->bufflen, cmd->data_len, ucmd->ubuff);
+ (long long)cmd->lba, cmd->bufflen, cmd->data_len, ucmd->ubuff);
if (cmd->data_direction & SCST_DATA_WRITE)
dev_user_flush_dcache(ucmd);
@@ -929,6 +931,7 @@ static int dev_user_exec(struct scst_cmd *cmd)
memcpy(ucmd->user_cmd.exec_cmd.cdb, cmd->cdb,
min_t(int, SCST_MAX_CDB_SIZE, cmd->cdb_len));
ucmd->user_cmd.exec_cmd.cdb_len = cmd->cdb_len;
+ ucmd->user_cmd.exec_cmd.lba = cmd->lba;
ucmd->user_cmd.exec_cmd.bufflen = cmd->bufflen;
ucmd->user_cmd.exec_cmd.data_len = cmd->data_len;
ucmd->user_cmd.exec_cmd.pbuf = ucmd->ubuff;
@@ -1299,7 +1302,7 @@ static int dev_user_process_reply_parse(struct scst_user_cmd *ucmd,
goto out_inval;
if (unlikely((preply->bufflen < 0) || (preply->out_bufflen < 0) ||
- (preply->data_len < 0)))
+ (preply->data_len < 0) || (preply->lba < 0)))
goto out_inval;
if (unlikely(preply->cdb_len > cmd->cdb_len))
@@ -1308,14 +1311,15 @@ static int dev_user_process_reply_parse(struct scst_user_cmd *ucmd,
if (!(preply->op_flags & SCST_INFO_VALID))
goto out_inval;
- TRACE_DBG("ucmd %p, queue_type %x, data_direction, %x, bufflen %d, "
- "data_len %d, pbuf %llx, cdb_len %d, op_flags %x", ucmd,
- preply->queue_type, preply->data_direction, preply->bufflen,
- preply->data_len, reply->alloc_reply.pbuf, preply->cdb_len,
- preply->op_flags);
+ TRACE_DBG("ucmd %p, queue_type %x, data_direction, %x, lba %lld, "
+ "bufflen %d, data_len %d, pbuf %llx, cdb_len %d, op_flags %x",
+ ucmd, preply->queue_type, preply->data_direction,
+ (long long)preply->lba, preply->bufflen, preply->data_len,
+ reply->alloc_reply.pbuf, preply->cdb_len, preply->op_flags);
cmd->queue_type = preply->queue_type;
cmd->data_direction = preply->data_direction;
+ cmd->lba = preply->lba;
cmd->bufflen = preply->bufflen;
cmd->out_bufflen = preply->out_bufflen;
cmd->data_len = preply->data_len;
diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c
index 2993daca7..818e60dd9 100644
--- a/scst/src/dev_handlers/scst_vdisk.c
+++ b/scst/src/dev_handlers/scst_vdisk.c
@@ -191,9 +191,7 @@ struct vdisk_cmd_params {
int iv_count;
struct iovec small_iv[4];
struct scst_cmd *cmd;
- uint64_t lba_start;
loff_t loff;
- loff_t data_len;
int fua;
bool use_zero_copy;
};
@@ -974,7 +972,7 @@ static enum compl_status_e vdisk_synchronize_cache(struct vdisk_cmd_params *p)
const uint8_t *cdb = cmd->cdb;
struct scst_device *dev = cmd->dev;
const loff_t loff = p->loff;
- const loff_t data_len = p->data_len;
+ int data_len = scst_cmd_get_data_len(cmd);
int immed = cdb[1] & 0x2;
enum compl_status_e res;
@@ -985,6 +983,12 @@ static enum compl_status_e vdisk_synchronize_cache(struct vdisk_cmd_params *p)
(long long unsigned int)loff,
(long long unsigned int)data_len, immed);
+ if (data_len == 0) {
+ struct scst_vdisk_dev *virt_dev = dev->dh_priv;
+ data_len = virt_dev->file_size -
+ ((loff_t)scst_cmd_get_lba(cmd) << virt_dev->block_shift);
+ }
+
if (immed) {
scst_cmd_get(cmd); /* to protect dev */
cmd->completed = 1;
@@ -1116,13 +1120,13 @@ static const vdisk_op_fn nullio_ops[256] = {
};
/*
- * Compute p->lba_start, p->loff, p->data_len and p->fua.
+ * Compute p->loff and p->fua.
* Returns true for success or false otherwise and set error in the commeand.
*/
static bool vdisk_parse_offset(struct vdisk_cmd_params *p, struct scst_cmd *cmd)
{
- uint64_t lba_start = 0;
- loff_t data_len = 0;
+ uint64_t lba_start;
+ int data_len;
uint8_t *cdb = cmd->cdb;
int opcode = cdb[0];
loff_t loff;
@@ -1133,6 +1137,14 @@ static bool vdisk_parse_offset(struct vdisk_cmd_params *p, struct scst_cmd *cmd)
TRACE_ENTRY();
+ if (unlikely(!(cmd->op_flags & SCST_INFO_VALID))) {
+ PRINT_ERROR("Unknown opcode 0x%02x", cmd->cdb[0]);
+ scst_set_cmd_error(cmd,
+ SCST_LOAD_SENSE(scst_sense_invalid_opcode));
+ res = false;
+ goto out;
+ }
+
p->cmd = cmd;
cmd->status = 0;
@@ -1151,55 +1163,8 @@ static bool vdisk_parse_offset(struct vdisk_cmd_params *p, struct scst_cmd *cmd)
break;
}
- switch (opcode) {
- case READ_6:
- case WRITE_6:
- lba_start = get_unaligned_be24(&cdb[1]) & 0x1f0000U;
- data_len = cmd->bufflen;
- use_zero_copy = true;
- break;
- case READ_10:
- case READ_12:
- case WRITE_10:
- case WRITE_12:
- case WRITE_VERIFY:
- case WRITE_VERIFY_12:
- lba_start = get_unaligned_be32(&cdb[2]);
- data_len = cmd->bufflen;
- use_zero_copy = true;
- break;
- case READ_16:
- case WRITE_16:
- case WRITE_VERIFY_16:
- lba_start = get_unaligned_be64(&cdb[2]);
- data_len = cmd->bufflen;
- use_zero_copy = true;
- break;
- case VERIFY:
- lba_start = get_unaligned_be32(&cdb[2]);
- data_len = get_unaligned_be16(&cdb[7]) << virt_dev->block_shift;
- use_zero_copy = true;
- break;
- case VERIFY_12:
- lba_start = get_unaligned_be32(&cdb[2]);
- data_len = get_unaligned_be32(&cdb[6]) << virt_dev->block_shift;
- use_zero_copy = true;
- break;
- case VERIFY_16:
- lba_start = get_unaligned_be64(&cdb[2]);
- data_len = get_unaligned_be32(&cdb[10]) << virt_dev->block_shift;
- use_zero_copy = true;
- break;
- case SYNCHRONIZE_CACHE:
- lba_start = get_unaligned_be32(&cdb[2]);
- data_len = get_unaligned_be16(&cdb[7]) << virt_dev->block_shift;
- if (data_len == 0)
- data_len = virt_dev->file_size -
- ((loff_t)lba_start << virt_dev->block_shift);
- break;
- }
-
- p->use_zero_copy = use_zero_copy && virt_dev->zero_copy;
+ lba_start = scst_cmd_get_lba(cmd);
+ data_len = scst_cmd_get_data_len(cmd);
loff = (loff_t)lba_start << virt_dev->block_shift;
TRACE_DBG("cmd %p, lba_start %lld, loff %lld, data_len %lld", cmd,
@@ -1209,7 +1174,7 @@ static bool vdisk_parse_offset(struct vdisk_cmd_params *p, struct scst_cmd *cmd)
if (unlikely(loff < 0) || unlikely(data_len < 0) ||
unlikely((loff + data_len) > virt_dev->file_size)) {
PRINT_INFO("Access beyond the end of the device "
- "(%lld of %lld, len %lld)",
+ "(%lld of %lld, data len %lld)",
(long long unsigned int)loff,
(long long unsigned int)virt_dev->file_size,
(long long unsigned int)data_len);
@@ -1219,6 +1184,15 @@ static bool vdisk_parse_offset(struct vdisk_cmd_params *p, struct scst_cmd *cmd)
goto out;
}
+ switch (opcode) {
+ case READ_6:
+ case READ_10:
+ case READ_12:
+ case READ_16:
+ use_zero_copy = true;
+ break;
+ }
+
switch (opcode) {
case WRITE_10:
case WRITE_12:
@@ -1232,10 +1206,9 @@ static bool vdisk_parse_offset(struct vdisk_cmd_params *p, struct scst_cmd *cmd)
break;
}
- p->lba_start = lba_start;
- p->data_len = data_len;
p->loff = loff;
p->fua = fua;
+ p->use_zero_copy = use_zero_copy && virt_dev->zero_copy;
res = true;
@@ -3545,7 +3518,7 @@ restart:
out_sync:
/* O_SYNC flag is used for WT devices */
if (p->fua)
- vdisk_fsync(p, loff, p->data_len, cmd->dev,
+ vdisk_fsync(p, loff, scst_cmd_get_data_len(cmd), cmd->dev,
scst_cmd_get_gfp_flags(cmd), cmd);
out:
TRACE_EXIT();
@@ -3638,7 +3611,7 @@ static void blockio_endio(struct bio *bio, int error)
static void blockio_exec_rw(struct vdisk_cmd_params *p, bool write, bool fua)
{
struct scst_cmd *cmd = p->cmd;
- u64 lba_start = p->lba_start;
+ u64 lba_start = scst_cmd_get_lba(cmd);
struct scst_vdisk_dev *virt_dev = cmd->dev->dh_priv;
struct block_device *bdev = virt_dev->bdev;
struct request_queue *q = bdev_get_queue(bdev);
@@ -3831,12 +3804,13 @@ static enum compl_status_e fileio_exec_verify(struct vdisk_cmd_params *p)
struct scst_vdisk_dev *virt_dev = cmd->dev->dh_priv;
struct file *fd = virt_dev->fd;
uint8_t *mem_verify = NULL;
+ int data_len = scst_cmd_get_data_len(cmd);
TRACE_ENTRY();
sBUG_ON(virt_dev->blockio);
- if (vdisk_fsync(p, loff, cmd->bufflen, cmd->dev,
+ if (vdisk_fsync(p, loff, data_len, cmd->dev,
scst_cmd_get_gfp_flags(cmd), cmd) != 0)
goto out;
@@ -3849,8 +3823,8 @@ static enum compl_status_e fileio_exec_verify(struct vdisk_cmd_params *p)
*/
compare = scst_cmd_get_data_direction(cmd) == SCST_DATA_WRITE;
- TRACE_DBG("VERIFY with BYTCHK=%d at offset %lld and with len = %lld\n",
- compare, loff, p->data_len);
+ TRACE_DBG("VERIFY with BYTCHK=%d at offset %lld and len %d\n",
+ compare, loff, data_len);
/* SEEK */
old_fs = get_fs();
@@ -3875,17 +3849,15 @@ static enum compl_status_e fileio_exec_verify(struct vdisk_cmd_params *p)
if (mem_verify == NULL) {
PRINT_ERROR("Unable to allocate memory %d for verify",
LEN_MEM);
- scst_set_cmd_error(cmd,
- SCST_LOAD_SENSE(scst_sense_hardw_error));
+ scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
goto out_set_fs;
}
if (compare) {
length = scst_get_buf_first(cmd, &address);
address_sav = address;
- } else {
- length = p->data_len;
- }
+ } else
+ length = data_len;
while (length > 0) {
len_mem = (length > LEN_MEM) ? LEN_MEM : length;
diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c
index bae3fcf71..730da8a4b 100644
--- a/scst/src/scst_lib.c
+++ b/scst/src/scst_lib.c
@@ -67,31 +67,64 @@ static int strncasecmp(const char *s1, const char *s2, size_t n)
}
#endif
-/* get_trans_len_x extract x bytes from cdb as length starting from off */
-static int get_trans_len_1(struct scst_cmd *cmd, uint8_t off);
-static int get_trans_len_1_256(struct scst_cmd *cmd, uint8_t off);
-static int get_trans_len_2(struct scst_cmd *cmd, uint8_t off);
-static int get_trans_len_3(struct scst_cmd *cmd, uint8_t off);
-static int get_trans_len_4(struct scst_cmd *cmd, uint8_t off);
+struct scst_sdbops;
-static int get_bidi_trans_len_2(struct scst_cmd *cmd, uint8_t off);
-
-/* for special commands */
-static int get_trans_len_fmt(struct scst_cmd *cmd, uint8_t off);
-static int get_verify_trans_len_2(struct scst_cmd *cmd, uint8_t off);
-static int get_verify_trans_len_3(struct scst_cmd *cmd, uint8_t off);
-static int get_verify_trans_len_4(struct scst_cmd *cmd, uint8_t off);
-static int get_trans_len_block_limit(struct scst_cmd *cmd, uint8_t off);
-static int get_trans_len_read_capacity(struct scst_cmd *cmd, uint8_t off);
-static int get_trans_len_serv_act_in(struct scst_cmd *cmd, uint8_t off);
-static int get_trans_len_single(struct scst_cmd *cmd, uint8_t off);
-static int get_trans_len_none(struct scst_cmd *cmd, uint8_t off);
-static int get_trans_len_read_pos(struct scst_cmd *cmd, uint8_t off);
-static int get_trans_cdb_len_10(struct scst_cmd *cmd, uint8_t off);
-static int get_trans_len_prevent_allow_medium_removal(struct scst_cmd *cmd,
- uint8_t off);
-static int get_trans_len_3_read_elem_stat(struct scst_cmd *cmd, uint8_t off);
-static int get_trans_len_start_stop(struct scst_cmd *cmd, uint8_t off);
+static int get_cdb_info_len_10(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_block_limit(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_read_capacity(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_serv_act_in(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_single(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_read_pos(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_prevent_allow_medium_removal(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_start_stop(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_len_3_read_elem_stat(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_len_2(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_fmt(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+ static int get_cdb_info_verify6(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_verify10(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_verify12(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_verify16(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_len_1(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_lba_2_len_1_256(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_bidi_lba_4_len_2(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_len_3(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_len_4(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_none(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_lba_2_none(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_lba_4_len_2(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_lba_4_none(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_lba_4_len_2(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_lba_4_len_4(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_lba_8_len_4(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
+static int get_cdb_info_lba_8_none(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops);
/*
+=====================================-============-======-
@@ -134,13 +167,17 @@ struct scst_sdbops {
* type_reserv devkey[E]
* type_reserv devkey[F]
*/
- const char *op_name; /* SCSI-2 op codes full name */
- uint8_t direction; /* init --> target: SCST_DATA_WRITE
- * target --> init: SCST_DATA_READ
- */
- uint32_t flags; /* opcode -- various flags */
- uint8_t off; /* length offset in cdb */
- int (*get_trans_len)(struct scst_cmd *cmd, uint8_t off);
+ uint8_t info_lba_off; /* LBA offset in cdb */
+ uint8_t info_lba_len; /* LBA length in cdb */
+ uint8_t info_len_off; /* length offset in cdb */
+ uint8_t info_len_len; /* length length in cdb */
+ uint8_t info_data_direction; /* init --> target: SCST_DATA_WRITE
+ * target --> init: SCST_DATA_READ
+ * target <--> init: SCST_DATA_READ|SCST_DATA_WRITE
+ */
+ uint32_t info_op_flags; /* various flags of this opcode */
+ const char *info_op_name;/* op code SCSI full name */
+ int (*get_cdb_info)(struct scst_cmd *cmd, const struct scst_sdbops *sdbops);
};
static int scst_scsi_op_list[256];
@@ -149,532 +186,1057 @@ static int scst_scsi_op_list[256];
static const struct scst_sdbops scst_scsi_op_table[] = {
/*
- * +-------------------> TYPE_IS_DISK (0)
- * |
- * |+------------------> TYPE_IS_TAPE (1)
- * ||
- * || +----------------> TYPE_IS_PROCESSOR (3)
- * || |
- * || | +--------------> TYPE_IS_CDROM (5)
- * || | |
- * || | | +------------> TYPE_IS_MOD (7)
- * || | | |
- * || | | |+-----------> TYPE_IS_CHANGER (8)
- * || | | ||
- * || | | || +-------> TYPE_IS_RAID (C)
- * || | | || |
- * || | | || |
- * 0123456789ABCDEF ---> TYPE_IS_???? */
+ * +-------------------> TYPE_IS_DISK (0)
+ * |
+ * |+------------------> TYPE_IS_TAPE (1)
+ * ||
+ * || +----------------> TYPE_IS_PROCESSOR (3)
+ * || |
+ * || | +--------------> TYPE_IS_CDROM (5)
+ * || | |
+ * || | | +------------> TYPE_IS_MOD (7)
+ * || | | |
+ * || | | |+-----------> TYPE_IS_CHANGER (8)
+ * || | | ||
+ * || | | || +-------> TYPE_IS_RAID (C)
+ * || | | || |
+ * || | | || |
+ * 0123456789ABCDEF ---> TYPE_IS_???? */
/* 6-bytes length CDB */
- {0x00, "MMMMMMMMMMMMMMMM", "TEST UNIT READY",
- /* let's be HQ to don't look dead under high load */
- SCST_DATA_NONE, SCST_SMALL_TIMEOUT|SCST_IMPLICIT_HQ|
- SCST_REG_RESERVE_ALLOWED|
- SCST_WRITE_EXCL_ALLOWED|
+ {.ops = 0x00, .devkey = "MMMMMMMMMMMMMMMM",
+ .info_op_name = "TEST UNIT READY",
+ .info_data_direction = SCST_DATA_NONE,
+ /* Let's be HQ to don't look dead under high load */
+ .info_op_flags = SCST_SMALL_TIMEOUT|SCST_IMPLICIT_HQ|
+ SCST_REG_RESERVE_ALLOWED|SCST_WRITE_EXCL_ALLOWED|
#ifdef CONFIG_SCST_TEST_IO_IN_SIRQ
SCST_TEST_IO_IN_SIRQ_ALLOWED|
#endif
SCST_EXCL_ACCESS_ALLOWED,
- 0, get_trans_len_none},
- {0x01, " M ", "REWIND",
- SCST_DATA_NONE, SCST_LONG_TIMEOUT|SCST_WRITE_EXCL_ALLOWED,
- 0, get_trans_len_none},
- {0x01, "O V OO OO ", "REZERO UNIT",
- SCST_DATA_NONE, SCST_WRITE_EXCL_ALLOWED,
- 0, get_trans_len_none},
- {0x02, "VVVVVV V ", "REQUEST BLOCK ADDR",
- SCST_DATA_NONE, SCST_SMALL_TIMEOUT, 0, get_trans_len_none},
- {0x03, "MMMMMMMMMMMMMMMM", "REQUEST SENSE",
- SCST_DATA_READ, SCST_SMALL_TIMEOUT|SCST_SKIP_UA|SCST_LOCAL_CMD|
- SCST_REG_RESERVE_ALLOWED|
- SCST_WRITE_EXCL_ALLOWED|
- SCST_EXCL_ACCESS_ALLOWED,
- 4, get_trans_len_1},
- {0x04, "M O O ", "FORMAT UNIT",
- SCST_DATA_NONE, SCST_LONG_TIMEOUT|SCST_WRITE_MEDIUM,
- 0, get_trans_len_fmt},
- {0x04, " O ", "FORMAT",
- SCST_DATA_NONE, SCST_WRITE_MEDIUM, 0, get_trans_len_none},
- {0x05, "VMVVVV V ", "READ BLOCK LIMITS",
- SCST_DATA_READ, SCST_SMALL_TIMEOUT|
- SCST_REG_RESERVE_ALLOWED|
- SCST_WRITE_EXCL_ALLOWED|
- SCST_EXCL_ACCESS_ALLOWED,
- 0, get_trans_len_block_limit},
- {0x07, " O ", "INITIALIZE ELEMENT STATUS",
- SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
- {0x07, "OVV O OV ", "REASSIGN BLOCKS",
- SCST_DATA_NONE, SCST_WRITE_MEDIUM, 0, get_trans_len_none},
- {0x08, "O ", "READ(6)",
- SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED|
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x01, .devkey = " M ",
+ .info_op_name = "REWIND",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_LONG_TIMEOUT|SCST_WRITE_EXCL_ALLOWED,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x03, .devkey = "MMMMMMMMMMMMMMMM",
+ .info_op_name = "REQUEST SENSE",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_SMALL_TIMEOUT|SCST_SKIP_UA|SCST_LOCAL_CMD|
+ SCST_REG_RESERVE_ALLOWED| SCST_WRITE_EXCL_ALLOWED|
+ SCST_EXCL_ACCESS_ALLOWED,
+ .info_len_off = 4, .info_len_len = 1,
+ .get_cdb_info = get_cdb_info_len_1},
+ {.ops = 0x04, .devkey = "M O O ",
+ .info_op_name = "FORMAT UNIT",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_LONG_TIMEOUT|SCST_WRITE_MEDIUM,
+ .get_cdb_info = get_cdb_info_fmt},
+ {.ops = 0x04, .devkey = " O ",
+ .info_op_name = "FORMAT",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_WRITE_MEDIUM,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x05, .devkey = "VMVVVV V ",
+ .info_op_name = "READ BLOCK LIMITS",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_SMALL_TIMEOUT|SCST_REG_RESERVE_ALLOWED|
+ SCST_WRITE_EXCL_ALLOWED|SCST_EXCL_ACCESS_ALLOWED,
+ .get_cdb_info = get_cdb_info_block_limit},
+ {.ops = 0x07, .devkey = " O ",
+ .info_op_name = "INITIALIZE ELEMENT STATUS",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_LONG_TIMEOUT,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x07, .devkey = "OVV O OV ",
+ .info_op_name = "REASSIGN BLOCKS",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_WRITE_MEDIUM,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x08, .devkey = "O ",
+ .info_op_name = "READ(6)",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|
#ifdef CONFIG_SCST_TEST_IO_IN_SIRQ
SCST_TEST_IO_IN_SIRQ_ALLOWED|
#endif
SCST_WRITE_EXCL_ALLOWED,
- 4, get_trans_len_1_256},
- {0x08, " MV OO OV ", "READ(6)",
- SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED|
+ .info_lba_off = 2, .info_lba_len = 2,
+ .info_len_off = 4, .info_len_len = 1,
+ .get_cdb_info = get_cdb_info_lba_2_len_1_256},
+ {.ops = 0x08, .devkey = " MV OO OV ",
+ .info_op_name = "READ(6)",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|
SCST_WRITE_EXCL_ALLOWED,
- 2, get_trans_len_3},
- {0x08, " M ", "GET MESSAGE(6)",
- SCST_DATA_READ, FLAG_NONE, 2, get_trans_len_3},
- {0x08, " O ", "RECEIVE",
- SCST_DATA_READ, FLAG_NONE, 2, get_trans_len_3},
- {0x0A, "O ", "WRITE(6)",
- SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED|
+ .info_len_off = 2, .info_len_len = 3,
+ .get_cdb_info = get_cdb_info_len_3},
+ {.ops = 0x08, .devkey = " M ",
+ .info_op_name = "GET MESSAGE(6)",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 2, .info_len_len = 3,
+ .get_cdb_info = get_cdb_info_len_3},
+ {.ops = 0x08, .devkey = " O ",
+ .info_op_name = "RECEIVE",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 2, .info_len_len = 3,
+ .get_cdb_info = get_cdb_info_len_3},
+ {.ops = 0x0A, .devkey = "O ",
+ .info_op_name = "WRITE(6)",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|
#ifdef CONFIG_SCST_TEST_IO_IN_SIRQ
SCST_TEST_IO_IN_SIRQ_ALLOWED|
#endif
SCST_WRITE_MEDIUM,
- 4, get_trans_len_1_256},
- {0x0A, " M O OV ", "WRITE(6)",
- SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM,
- 2, get_trans_len_3},
- {0x0A, " M ", "PRINT",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0x0A, " M ", "SEND MESSAGE(6)",
- SCST_DATA_WRITE, FLAG_NONE, 2, get_trans_len_3},
- {0x0A, " M ", "SEND(6)",
- SCST_DATA_WRITE, FLAG_NONE, 2, get_trans_len_3},
- {0x0B, "O OO OV ", "SEEK(6)",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0x0B, " ", "TRACK SELECT",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0x0B, " O ", "SLEW AND PRINT",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0x0C, "VVVVVV V ", "SEEK BLOCK",
- SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
- {0x0D, "VVVVVV V ", "PARTITION",
- SCST_DATA_NONE, SCST_LONG_TIMEOUT|SCST_WRITE_MEDIUM,
- 0, get_trans_len_none},
- {0x0F, "VOVVVV V ", "READ REVERSE",
- SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED|
+ .info_lba_off = 2, .info_lba_len = 2,
+ .info_len_off = 4, .info_len_len = 1,
+ .get_cdb_info = get_cdb_info_lba_2_len_1_256},
+ {.ops = 0x0A, .devkey = " M O OV ",
+ .info_op_name = "WRITE(6)",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM,
+ .info_len_off = 2, .info_len_len = 3,
+ .get_cdb_info = get_cdb_info_len_3},
+ {.ops = 0x0A, .devkey = " M ",
+ .info_op_name = "PRINT",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x0A, .devkey = " M ",
+ .info_op_name = "SEND MESSAGE(6)",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 2, .info_len_len = 3,
+ .get_cdb_info = get_cdb_info_len_3},
+ {.ops = 0x0A, .devkey = " M ",
+ .info_op_name = "SEND(6)",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 2, .info_len_len = 3,
+ .get_cdb_info = get_cdb_info_len_3},
+ {.ops = 0x0B, .devkey = "O OO OV ",
+ .info_op_name = "SEEK(6)",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .info_lba_off = 2, .info_lba_len = 2,
+ .get_cdb_info = get_cdb_info_lba_2_none},
+ {.ops = 0x0B, .devkey = " O ",
+ .info_op_name = "SLEW AND PRINT",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x0C, .devkey = " VVVVV V ",
+ .info_op_name = "SEEK BLOCK",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_LONG_TIMEOUT,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x0D, .devkey = " VVVVV V ",
+ .info_op_name = "PARTITION",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_LONG_TIMEOUT|SCST_WRITE_MEDIUM,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x0F, .devkey = " OVVVV V ",
+ .info_op_name = "READ REVERSE",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|
SCST_WRITE_EXCL_ALLOWED,
- 2, get_trans_len_3},
- {0x10, "VM V V ", "WRITE FILEMARKS",
- SCST_DATA_NONE, SCST_WRITE_MEDIUM, 0, get_trans_len_none},
- {0x10, " O O ", "SYNCHRONIZE BUFFER",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0x11, "VMVVVV ", "SPACE",
- SCST_DATA_NONE, SCST_LONG_TIMEOUT|
+ .info_len_off = 12, .info_len_len = 3,
+ .get_cdb_info = get_cdb_info_len_3},
+ {.ops = 0x10, .devkey = " M V V ",
+ .info_op_name = "WRITE FILEMARKS",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_WRITE_MEDIUM,
+ .info_len_off = 2, .info_len_len = 3,
+ .get_cdb_info = get_cdb_info_len_3},
+ {.ops = 0x10, .devkey = " O O ",
+ .info_op_name = "SYNCHRONIZE BUFFER",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x11, .devkey = "VMVVVV ",
+ .info_op_name = "SPACE",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_LONG_TIMEOUT|
SCST_WRITE_EXCL_ALLOWED,
- 0, get_trans_len_none},
- {0x12, "MMMMMMMMMMMMMMMM", "INQUIRY",
- SCST_DATA_READ, SCST_SMALL_TIMEOUT|SCST_IMPLICIT_HQ|SCST_SKIP_UA|
- SCST_REG_RESERVE_ALLOWED|
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x12, .devkey = "MMMMMMMMMMMMMMMM",
+ .info_op_name = "INQUIRY",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_SMALL_TIMEOUT|SCST_IMPLICIT_HQ|SCST_SKIP_UA|
+ SCST_REG_RESERVE_ALLOWED| SCST_WRITE_EXCL_ALLOWED|
+ SCST_EXCL_ACCESS_ALLOWED,
+ .info_len_off = 3, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x13, .devkey = " O ",
+ .info_op_name = "VERIFY(6)",
+ .info_data_direction = SCST_DATA_UNKNOWN,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_EXCL_ALLOWED,
+ .info_len_off = 2, .info_len_len = 3,
+ .get_cdb_info = get_cdb_info_verify6},
+ {.ops = 0x14, .devkey = " OOVVV ",
+ .info_op_name = "RECOVER BUFFERED DATA",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_EXCL_ALLOWED,
+ .info_len_off = 2, .info_len_len = 3,
+ .get_cdb_info = get_cdb_info_len_3},
+ {.ops = 0x15, .devkey = "OMOOOOOOOOOOOOOO",
+ .info_op_name = "MODE SELECT(6)",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_STRICTLY_SERIALIZED,
+ .info_len_off = 4, .info_len_len = 1,
+ .get_cdb_info = get_cdb_info_len_1},
+ {.ops = 0x16, .devkey = "MMMMMMMMMMMMMMMM",
+ .info_op_name = "RESERVE",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_SMALL_TIMEOUT|SCST_LOCAL_CMD|SCST_SERIALIZED|
SCST_WRITE_EXCL_ALLOWED|SCST_EXCL_ACCESS_ALLOWED,
- 3, get_trans_len_2},
- {0x13, " O ", "VERIFY(6)",
- SCST_DATA_UNKNOWN, SCST_TRANSFER_LEN_TYPE_FIXED|
- SCST_WRITE_EXCL_ALLOWED,
- 2, get_verify_trans_len_3},
- {0x14, "VOOVVV ", "RECOVER BUFFERED DATA",
- SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED|
- SCST_WRITE_EXCL_ALLOWED,
- 2, get_trans_len_3},
- {0x15, "OMOOOOOOOOOOOOOO", "MODE SELECT(6)",
- SCST_DATA_WRITE, SCST_STRICTLY_SERIALIZED, 4, get_trans_len_1},
- {0x16, "MMMMMMMMMMMMMMMM", "RESERVE",
- SCST_DATA_NONE, SCST_SMALL_TIMEOUT|SCST_LOCAL_CMD|SCST_SERIALIZED|
- SCST_WRITE_EXCL_ALLOWED|SCST_EXCL_ACCESS_ALLOWED,
- 0, get_trans_len_none},
- {0x17, "MMMMMMMMMMMMMMMM", "RELEASE",
- SCST_DATA_NONE, SCST_SMALL_TIMEOUT|SCST_LOCAL_CMD|SCST_SERIALIZED|
- SCST_REG_RESERVE_ALLOWED|
- SCST_WRITE_EXCL_ALLOWED|SCST_EXCL_ACCESS_ALLOWED,
- 0, get_trans_len_none},
- {0x18, "OOOOOOOO ", "COPY",
- SCST_DATA_WRITE, SCST_LONG_TIMEOUT, 2, get_trans_len_3},
- {0x19, "VMVVVV ", "ERASE",
- SCST_DATA_NONE, SCST_LONG_TIMEOUT|SCST_WRITE_MEDIUM,
- 0, get_trans_len_none},
- {0x1A, "OMOOOOOOOOOOOOOO", "MODE SENSE(6)",
- SCST_DATA_READ, SCST_SMALL_TIMEOUT, 4, get_trans_len_1},
- {0x1B, " O ", "SCAN",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0x1B, " O ", "LOAD UNLOAD",
- SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
- {0x1B, " O ", "STOP PRINT",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0x1B, "O OO O O ", "START STOP UNIT",
- SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_start_stop},
- {0x1C, "OOOOOOOOOOOOOOOO", "RECEIVE DIAGNOSTIC RESULTS",
- SCST_DATA_READ, FLAG_NONE, 3, get_trans_len_2},
- {0x1D, "MMMMMMMMMMMMMMMM", "SEND DIAGNOSTIC",
- SCST_DATA_WRITE, FLAG_NONE, 4, get_trans_len_1},
- {0x1E, "OOOOOOOOOOOOOOOO", "PREVENT ALLOW MEDIUM REMOVAL",
- SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0,
- get_trans_len_prevent_allow_medium_removal},
- {0x1F, " O ", "PORT STATUS",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x17, .devkey = "MMMMMMMMMMMMMMMM",
+ .info_op_name = "RELEASE",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_SMALL_TIMEOUT|SCST_LOCAL_CMD|SCST_SERIALIZED|
+ SCST_REG_RESERVE_ALLOWED|SCST_WRITE_EXCL_ALLOWED|
+ SCST_EXCL_ACCESS_ALLOWED,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x19, .devkey = " MVVVV ",
+ .info_op_name = "ERASE",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_LONG_TIMEOUT|SCST_WRITE_MEDIUM,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x1A, .devkey = "OMOOOOOOOOOOOOOO",
+ .info_op_name = "MODE SENSE(6)",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_SMALL_TIMEOUT,
+ .info_len_off = 4, .info_len_len = 1,
+ .get_cdb_info = get_cdb_info_len_1},
+ {.ops = 0x1B, .devkey = " O ",
+ .info_op_name = "SCAN",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x1B, .devkey = " O ",
+ .info_op_name = "LOAD UNLOAD",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_LONG_TIMEOUT,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x1B, .devkey = " O ",
+ .info_op_name = "STOP PRINT",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x1B, .devkey = "O OO O O ",
+ .info_op_name = "START STOP UNIT",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_LONG_TIMEOUT,
+ .get_cdb_info = get_cdb_info_start_stop},
+ {.ops = 0x1C, .devkey = "OOOOOOOOOOOOOOOO",
+ .info_op_name = "RECEIVE DIAGNOSTIC RESULTS",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 3, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x1D, .devkey = "MMMMMMMMMMMMMMMM",
+ .info_op_name = "SEND DIAGNOSTIC",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 3, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x1E, .devkey = "OOOOOOOOOOOOOOOO",
+ .info_op_name = "PREVENT ALLOW MEDIUM REMOVAL",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_LONG_TIMEOUT,
+ .get_cdb_info = get_cdb_info_prevent_allow_medium_removal},
+ {.ops = 0x1F, .devkey = " O ",
+ .info_op_name = "PORT STATUS",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .get_cdb_info = get_cdb_info_none},
/* 10-bytes length CDB */
- {0x23, "V VV V ", "READ FORMAT CAPACITY",
- SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
- {0x24, " VVM ", "SET WINDOW",
- SCST_DATA_WRITE, FLAG_NONE, 6, get_trans_len_3},
- {0x25, "M MM M ", "READ CAPACITY",
- SCST_DATA_READ, SCST_IMPLICIT_HQ|
- SCST_REG_RESERVE_ALLOWED|
- SCST_WRITE_EXCL_ALLOWED|
- SCST_EXCL_ACCESS_ALLOWED,
- 0, get_trans_len_read_capacity},
- {0x25, " O ", "GET WINDOW",
- SCST_DATA_READ, FLAG_NONE, 6, get_trans_len_3},
- {0x28, "M MMMM ", "READ(10)",
- SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED|
+ {.ops = 0x23, .devkey = "V VV V ",
+ .info_op_name = "READ FORMAT CAPACITY",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x24, .devkey = " VVM ",
+ .info_op_name = "SET WINDOW",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 6, .info_len_len = 3,
+ .get_cdb_info = get_cdb_info_len_3},
+ {.ops = 0x25, .devkey = "M MM M ",
+ .info_op_name = "READ CAPACITY",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_IMPLICIT_HQ|SCST_REG_RESERVE_ALLOWED|
+ SCST_WRITE_EXCL_ALLOWED|SCST_EXCL_ACCESS_ALLOWED,
+ .get_cdb_info = get_cdb_info_read_capacity},
+ {.ops = 0x25, .devkey = " O ",
+ .info_op_name = "GET WINDOW",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 6, .info_len_len = 3,
+ .get_cdb_info = get_cdb_info_len_3},
+ {.ops = 0x28, .devkey = "M MMMM ",
+ .info_op_name = "READ(10)",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|
#ifdef CONFIG_SCST_TEST_IO_IN_SIRQ
SCST_TEST_IO_IN_SIRQ_ALLOWED|
#endif
SCST_WRITE_EXCL_ALLOWED,
- 7, get_trans_len_2},
- {0x28, " O ", "GET MESSAGE(10)",
- SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
- {0x29, "V VV O ", "READ GENERATION",
- SCST_DATA_READ, FLAG_NONE, 8, get_trans_len_1},
- {0x2A, "O MO M ", "WRITE(10)",
- SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED|
+ .info_lba_off = 2, .info_lba_len = 4,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_lba_4_len_2},
+ {.ops = 0x28, .devkey = " O ",
+ .info_op_name = "GET MESSAGE(10)",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x29, .devkey = "V VV O ",
+ .info_op_name = "READ GENERATION",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 8, .info_len_len = 1,
+ .get_cdb_info = get_cdb_info_len_1},
+ {.ops = 0x2A, .devkey = "O MO M ",
+ .info_op_name = "WRITE(10)",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|
#ifdef CONFIG_SCST_TEST_IO_IN_SIRQ
SCST_TEST_IO_IN_SIRQ_ALLOWED|
#endif
SCST_WRITE_MEDIUM,
- 7, get_trans_len_2},
- {0x2A, " O ", "SEND MESSAGE(10)",
- SCST_DATA_WRITE, FLAG_NONE, 7, get_trans_len_2},
- {0x2A, " O ", "SEND(10)",
- SCST_DATA_WRITE, FLAG_NONE, 7, get_trans_len_2},
- {0x2B, " O ", "LOCATE",
- SCST_DATA_NONE, SCST_LONG_TIMEOUT|
- SCST_WRITE_EXCL_ALLOWED,
- 0, get_trans_len_none},
- {0x2B, " O ", "POSITION TO ELEMENT",
- SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
- {0x2B, "O OO O ", "SEEK(10)",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0x2C, "V O O ", "ERASE(10)",
- SCST_DATA_NONE, SCST_LONG_TIMEOUT|SCST_WRITE_MEDIUM,
- 0, get_trans_len_none},
- {0x2D, "V O O ", "READ UPDATED BLOCK",
- SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED, 0, get_trans_len_single},
- {0x2E, "O OO O ", "WRITE AND VERIFY(10)",
- SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM,
- 7, get_trans_len_2},
- {0x2F, "O OO O ", "VERIFY(10)",
- SCST_DATA_UNKNOWN, SCST_TRANSFER_LEN_TYPE_FIXED|
- SCST_WRITE_EXCL_ALLOWED,
- 7, get_verify_trans_len_2},
- {0x33, "O OO O ", "SET LIMITS(10)",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0x34, " O ", "READ POSITION",
- SCST_DATA_READ, SCST_SMALL_TIMEOUT|
- SCST_WRITE_EXCL_ALLOWED,
- 7, get_trans_len_read_pos},
- {0x34, " O ", "GET DATA BUFFER STATUS",
- SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
- {0x34, "O OO O ", "PRE-FETCH",
- SCST_DATA_NONE, SCST_WRITE_EXCL_ALLOWED,
- 0, get_trans_len_none},
- {0x35, "O OO O ", "SYNCHRONIZE CACHE",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0x36, "O OO O ", "LOCK UNLOCK CACHE",
- SCST_DATA_NONE, SCST_WRITE_EXCL_ALLOWED,
- 0, get_trans_len_none},
- {0x37, "O O ", "READ DEFECT DATA(10)",
- SCST_DATA_READ, SCST_WRITE_EXCL_ALLOWED,
- 8, get_trans_len_1},
- {0x37, " O ", "INIT ELEMENT STATUS WRANGE",
- SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
- {0x38, " O O ", "MEDIUM SCAN",
- SCST_DATA_READ, FLAG_NONE, 8, get_trans_len_1},
- {0x39, "OOOOOOOO ", "COMPARE",
- SCST_DATA_WRITE, FLAG_NONE, 3, get_trans_len_3},
- {0x3A, "OOOOOOOO ", "COPY AND VERIFY",
- SCST_DATA_WRITE, FLAG_NONE, 3, get_trans_len_3},
- {0x3B, "OOOOOOOOOOOOOOOO", "WRITE BUFFER",
- SCST_DATA_WRITE, SCST_SMALL_TIMEOUT, 6, get_trans_len_3},
- {0x3C, "OOOOOOOOOOOOOOOO", "READ BUFFER",
- SCST_DATA_READ, SCST_SMALL_TIMEOUT, 6, get_trans_len_3},
- {0x3D, " O O ", "UPDATE BLOCK",
- SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED,
- 0, get_trans_len_single},
- {0x3E, "O OO O ", "READ LONG",
- SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
- {0x3F, "O O O ", "WRITE LONG",
- SCST_DATA_WRITE, SCST_WRITE_MEDIUM, 7, get_trans_len_2},
- {0x40, "OOOOOOOOOO ", "CHANGE DEFINITION",
- SCST_DATA_WRITE, SCST_SMALL_TIMEOUT, 8, get_trans_len_1},
- {0x41, "O O ", "WRITE SAME",
- SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM,
- 0, get_trans_len_single},
- {0x42, " O ", "READ SUB-CHANNEL",
- SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
- {0x42, "O ", "UNMAP",
- SCST_DATA_WRITE, SCST_WRITE_MEDIUM, 7, get_trans_len_2},
- {0x43, " O ", "READ TOC/PMA/ATIP",
- SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
- {0x44, " M ", "REPORT DENSITY SUPPORT",
- SCST_DATA_READ, SCST_REG_RESERVE_ALLOWED|
- SCST_WRITE_EXCL_ALLOWED|
- SCST_EXCL_ACCESS_ALLOWED,
- 7, get_trans_len_2},
- {0x44, " O ", "READ HEADER",
- SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
- {0x45, " O ", "PLAY AUDIO(10)",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0x46, " O ", "GET CONFIGURATION",
- SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
- {0x47, " O ", "PLAY AUDIO MSF",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0x48, " O ", "PLAY AUDIO TRACK INDEX",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0x49, " O ", "PLAY TRACK RELATIVE(10)",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0x4A, " O ", "GET EVENT STATUS NOTIFICATION",
- SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
- {0x4B, " O ", "PAUSE/RESUME",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0x4C, "OOOOOOOOOOOOOOOO", "LOG SELECT",
- SCST_DATA_WRITE, SCST_STRICTLY_SERIALIZED, 7, get_trans_len_2},
- {0x4D, "OOOOOOOOOOOOOOOO", "LOG SENSE",
- SCST_DATA_READ, SCST_SMALL_TIMEOUT|
- SCST_REG_RESERVE_ALLOWED|
- SCST_WRITE_EXCL_ALLOWED|
- SCST_EXCL_ACCESS_ALLOWED,
- 7, get_trans_len_2},
- {0x4E, " O ", "STOP PLAY/SCAN",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0x50, " ", "XDWRITE",
- SCST_DATA_NONE, SCST_WRITE_MEDIUM, 0, get_trans_len_none},
- {0x51, " O ", "READ DISC INFORMATION",
- SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
- {0x51, " ", "XPWRITE",
- SCST_DATA_NONE, SCST_WRITE_MEDIUM, 0, get_trans_len_none},
- {0x52, " O ", "READ TRACK INFORMATION",
- SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
- {0x53, "O ", "XDWRITEREAD(10)",
- SCST_DATA_READ|SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED|
- SCST_WRITE_MEDIUM,
- 7, get_bidi_trans_len_2},
- {0x53, " O ", "RESERVE TRACK",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0x54, " O ", "SEND OPC INFORMATION",
- SCST_DATA_WRITE, FLAG_NONE, 7, get_trans_len_2},
- {0x55, "OOOOOOOOOOOOOOOO", "MODE SELECT(10)",
- SCST_DATA_WRITE, SCST_STRICTLY_SERIALIZED, 7, get_trans_len_2},
- {0x56, "OOOOOOOOOOOOOOOO", "RESERVE(10)",
- SCST_DATA_NONE, SCST_SMALL_TIMEOUT|SCST_LOCAL_CMD|SCST_SERIALIZED|
- SCST_WRITE_EXCL_ALLOWED|SCST_EXCL_ACCESS_ALLOWED,
- 0, get_trans_len_none},
- {0x57, "OOOOOOOOOOOOOOOO", "RELEASE(10)",
- SCST_DATA_NONE, SCST_SMALL_TIMEOUT|SCST_LOCAL_CMD|SCST_SERIALIZED|
- SCST_REG_RESERVE_ALLOWED|
- SCST_WRITE_EXCL_ALLOWED|SCST_EXCL_ACCESS_ALLOWED,
- 0, get_trans_len_none},
- {0x58, " O ", "REPAIR TRACK",
- SCST_DATA_NONE, SCST_WRITE_MEDIUM, 0, get_trans_len_none},
- {0x5A, "OOOOOOOOOOOOOOOO", "MODE SENSE(10)",
- SCST_DATA_READ, SCST_SMALL_TIMEOUT, 7, get_trans_len_2},
- {0x5B, " O ", "CLOSE TRACK/SESSION",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0x5C, " O ", "READ BUFFER CAPACITY",
- SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
- {0x5D, " O ", "SEND CUE SHEET",
- SCST_DATA_WRITE, FLAG_NONE, 6, get_trans_len_3},
- {0x5E, "OOOOO OOOO ", "PERSISTENT RESERVE IN",
- SCST_DATA_READ, SCST_SMALL_TIMEOUT|
- SCST_LOCAL_CMD|SCST_SERIALIZED|
- SCST_WRITE_EXCL_ALLOWED|
- SCST_EXCL_ACCESS_ALLOWED,
- 5, get_trans_len_4},
- {0x5F, "OOOOO OOOO ", "PERSISTENT RESERVE OUT",
- SCST_DATA_WRITE, SCST_SMALL_TIMEOUT|
- SCST_LOCAL_CMD|SCST_SERIALIZED|
- SCST_WRITE_EXCL_ALLOWED|
- SCST_EXCL_ACCESS_ALLOWED,
- 5, get_trans_len_4},
+ .info_lba_off = 2, .info_lba_len = 4,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_lba_4_len_2},
+ {.ops = 0x2A, .devkey = " O ",
+ .info_op_name = "SEND MESSAGE(10)",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x2A, .devkey = " O ",
+ .info_op_name = "SEND(10)",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x2B, .devkey = " O ",
+ .info_op_name = "LOCATE",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_LONG_TIMEOUT|SCST_WRITE_EXCL_ALLOWED,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x2B, .devkey = " O ",
+ .info_op_name = "POSITION TO ELEMENT",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_LONG_TIMEOUT,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x2B, .devkey = "O OO O ",
+ .info_op_name = "SEEK(10)",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .info_lba_off = 2, .info_lba_len = 4,
+ .get_cdb_info = get_cdb_info_lba_4_none},
+ {.ops = 0x2C, .devkey = "V O O ",
+ .info_op_name = "ERASE(10)",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_LONG_TIMEOUT|SCST_WRITE_MEDIUM,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x2D, .devkey = "V O O ",
+ .info_op_name = "READ UPDATED BLOCK",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED,
+ .get_cdb_info = get_cdb_info_single},
+ {.ops = 0x2E, .devkey = "O OO O ",
+ .info_op_name = "WRITE AND VERIFY(10)",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM,
+ .info_lba_off = 2, .info_lba_len = 4,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_lba_4_len_2},
+ {.ops = 0x2F, .devkey = "O OO O ",
+ .info_op_name = "VERIFY(10)",
+ .info_data_direction = SCST_DATA_UNKNOWN,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_EXCL_ALLOWED,
+ .info_lba_off = 2, .info_lba_len = 4,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_verify10},
+ {.ops = 0x33, .devkey = " OO O ",
+ .info_op_name = "SET LIMITS(10)",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x34, .devkey = " O ",
+ .info_op_name = "READ POSITION",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_SMALL_TIMEOUT|SCST_WRITE_EXCL_ALLOWED,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_read_pos},
+ {.ops = 0x34, .devkey = " O ",
+ .info_op_name = "GET DATA BUFFER STATUS",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x34, .devkey = "O OO O ",
+ .info_op_name = "PRE-FETCH",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_WRITE_EXCL_ALLOWED,
+ .info_lba_off = 2, .info_lba_len = 4,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_lba_4_none},
+ {.ops = 0x35, .devkey = "O OO O ",
+ .info_op_name = "SYNCHRONIZE CACHE(10)",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .info_lba_off = 2, .info_lba_len = 4,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_lba_4_none},
+ {.ops = 0x36, .devkey = "O OO O ",
+ .info_op_name = "LOCK UNLOCK CACHE",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_WRITE_EXCL_ALLOWED,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x37, .devkey = "O O ",
+ .info_op_name = "READ DEFECT DATA(10)",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_WRITE_EXCL_ALLOWED,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x37, .devkey = " O ",
+ .info_op_name = "INIT ELEMENT STATUS WRANGE",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_LONG_TIMEOUT,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x38, .devkey = " O O ",
+ .info_op_name = "MEDIUM SCAN",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 8, .info_len_len = 1,
+ .get_cdb_info = get_cdb_info_len_1},
+ {.ops = 0x3B, .devkey = "OOOOOOOOOOOOOOOO",
+ .info_op_name = "WRITE BUFFER",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_SMALL_TIMEOUT,
+ .info_len_off = 5, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x3C, .devkey = "OOOOOOOOOOOOOOOO",
+ .info_op_name = "READ BUFFER",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_SMALL_TIMEOUT,
+ .info_len_off = 5, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x3D, .devkey = " O O ",
+ .info_op_name = "UPDATE BLOCK",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED,
+ .get_cdb_info = get_cdb_info_single},
+ {.ops = 0x3E, .devkey = "O OO O ",
+ .info_op_name = "READ LONG",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_lba_off = 2, .info_lba_len = 4,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_lba_4_len_2},
+ {.ops = 0x3F, .devkey = "O O O ",
+ .info_op_name = "WRITE LONG",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_WRITE_MEDIUM,
+ .info_lba_off = 2, .info_lba_len = 4,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_lba_4_len_2},
+ {.ops = 0x40, .devkey = "OOOOOOOOOO ",
+ .info_op_name = "CHANGE DEFINITION",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_SMALL_TIMEOUT,
+ .info_len_off = 8, .info_len_len = 1,
+ .get_cdb_info = get_cdb_info_len_1},
+ {.ops = 0x41, .devkey = "O O ",
+ .info_op_name = "WRITE SAME(10)",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM,
+ .info_lba_off = 2, .info_lba_len = 4,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_lba_4_len_2},
+ {.ops = 0x42, .devkey = " O ",
+ .info_op_name = "READ SUB-CHANNEL",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x42, .devkey = "O ",
+ .info_op_name = "UNMAP",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_WRITE_MEDIUM,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x43, .devkey = " O ",
+ .info_op_name = "READ TOC/PMA/ATIP",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x44, .devkey = " M ",
+ .info_op_name = "REPORT DENSITY SUPPORT",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_REG_RESERVE_ALLOWED|SCST_WRITE_EXCL_ALLOWED|
+ SCST_EXCL_ACCESS_ALLOWED,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x44, .devkey = " O ",
+ .info_op_name = "READ HEADER",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x45, .devkey = " O ",
+ .info_op_name = "PLAY AUDIO(10)",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x46, .devkey = " O ",
+ .info_op_name = "GET CONFIGURATION",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x47, .devkey = " O ",
+ .info_op_name = "PLAY AUDIO MSF",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x48, .devkey = " O ",
+ .info_op_name = "PLAY AUDIO TRACK INDEX",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x49, .devkey = " O ",
+ .info_op_name = "PLAY TRACK RELATIVE(10)",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x4A, .devkey = " O ",
+ .info_op_name = "GET EVENT STATUS NOTIFICATION",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x4B, .devkey = " O ",
+ .info_op_name = "PAUSE/RESUME",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x4C, .devkey = "OOOOOOOOOOOOOOOO",
+ .info_op_name = "LOG SELECT",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_STRICTLY_SERIALIZED,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x4D, .devkey = "OOOOOOOOOOOOOOOO",
+ .info_op_name = "LOG SENSE",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_SMALL_TIMEOUT|SCST_REG_RESERVE_ALLOWED|
+ SCST_WRITE_EXCL_ALLOWED|SCST_EXCL_ACCESS_ALLOWED,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x4E, .devkey = " O ",
+ .info_op_name = "STOP PLAY/SCAN",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x50, .devkey = "O ",
+ .info_op_name = "XDWRITE(10)",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_WRITE_MEDIUM,
+ .info_lba_off = 2, .info_lba_len = 4,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_lba_4_len_2},
+ {.ops = 0x51, .devkey = " O ",
+ .info_op_name = "READ DISC INFORMATION",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x51, .devkey = "O ",
+ .info_op_name = "XPWRITE",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_WRITE_MEDIUM,
+ .info_lba_off = 2, .info_lba_len = 4,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_lba_4_len_2},
+ {.ops = 0x52, .devkey = " O ",
+ .info_op_name = "READ TRACK INFORMATION",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x53, .devkey = "O ",
+ .info_op_name = "XDWRITEREAD(10)",
+ .info_data_direction = SCST_DATA_BIDI,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM,
+ .info_lba_off = 2, .info_lba_len = 4,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_bidi_lba_4_len_2},
+ {.ops = 0x53, .devkey = " O ",
+ .info_op_name = "RESERVE TRACK",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x54, .devkey = " O ",
+ .info_op_name = "SEND OPC INFORMATION",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x55, .devkey = "OOOOOOOOOOOOOOOO",
+ .info_op_name = "MODE SELECT(10)",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_STRICTLY_SERIALIZED,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x56, .devkey = "OOOOOOOOOOOOOOOO",
+ .info_op_name = "RESERVE(10)",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_SMALL_TIMEOUT|SCST_LOCAL_CMD|SCST_SERIALIZED|
+ SCST_WRITE_EXCL_ALLOWED|SCST_EXCL_ACCESS_ALLOWED,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x57, .devkey = "OOOOOOOOOOOOOOOO",
+ .info_op_name = "RELEASE(10)",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_SMALL_TIMEOUT|SCST_LOCAL_CMD|SCST_SERIALIZED|
+ SCST_REG_RESERVE_ALLOWED|SCST_WRITE_EXCL_ALLOWED|
+ SCST_EXCL_ACCESS_ALLOWED,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x58, .devkey = " O ",
+ .info_op_name = "REPAIR TRACK",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_WRITE_MEDIUM,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x5A, .devkey = "OOOOOOOOOOOOOOOO",
+ .info_op_name = "MODE SENSE(10)",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_SMALL_TIMEOUT,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x5B, .devkey = " O ",
+ .info_op_name = "CLOSE TRACK/SESSION",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x5C, .devkey = " O ",
+ .info_op_name = "READ BUFFER CAPACITY",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 7, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0x5D, .devkey = " O ",
+ .info_op_name = "SEND CUE SHEET",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 6, .info_len_len = 3,
+ .get_cdb_info = get_cdb_info_len_3},
+ {.ops = 0x5E, .devkey = "OOOOO OOOO ",
+ .info_op_name = "PERSISTENT RESERVE IN",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_SMALL_TIMEOUT|SCST_LOCAL_CMD|SCST_SERIALIZED|
+ SCST_WRITE_EXCL_ALLOWED|SCST_EXCL_ACCESS_ALLOWED,
+ .info_len_off = 5, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_len_4},
+ {.ops = 0x5F, .devkey = "OOOOO OOOO ",
+ .info_op_name = "PERSISTENT RESERVE OUT",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_SMALL_TIMEOUT|SCST_LOCAL_CMD|SCST_SERIALIZED|
+ SCST_WRITE_EXCL_ALLOWED|SCST_EXCL_ACCESS_ALLOWED,
+ .info_len_off = 5, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_len_4},
/* 16-bytes length CDB */
- {0x80, "O OO O ", "XDWRITE EXTENDED",
- SCST_DATA_NONE, SCST_WRITE_MEDIUM, 0, get_trans_len_none},
- {0x80, " M ", "WRITE FILEMARKS",
- SCST_DATA_NONE, SCST_WRITE_MEDIUM, 0, get_trans_len_none},
- {0x81, "O OO O ", "REBUILD",
- SCST_DATA_WRITE, SCST_WRITE_MEDIUM, 10, get_trans_len_4},
- {0x82, "O OO O ", "REGENERATE",
- SCST_DATA_WRITE, SCST_WRITE_MEDIUM, 10, get_trans_len_4},
- {0x83, "OOOOOOOOOOOOOOOO", "EXTENDED COPY",
- SCST_DATA_WRITE, SCST_WRITE_MEDIUM, 10, get_trans_len_4},
- {0x84, "OOOOOOOOOOOOOOOO", "RECEIVE COPY RESULT",
- SCST_DATA_WRITE, FLAG_NONE, 10, get_trans_len_4},
- {0x86, "OOOOOOOOOO ", "ACCESS CONTROL IN",
- SCST_DATA_NONE, SCST_REG_RESERVE_ALLOWED|
- SCST_WRITE_EXCL_ALLOWED|
- SCST_EXCL_ACCESS_ALLOWED,
- 0, get_trans_len_none},
- {0x87, "OOOOOOOOOO ", "ACCESS CONTROL OUT",
- SCST_DATA_NONE, SCST_REG_RESERVE_ALLOWED|
- SCST_WRITE_EXCL_ALLOWED|
- SCST_EXCL_ACCESS_ALLOWED,
- 0, get_trans_len_none},
- {0x88, "M MMMM ", "READ(16)",
- SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED|
+ {.ops = 0x80, .devkey = " O ",
+ .info_op_name = "WRITE FILEMARKS",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_WRITE_MEDIUM,
+ .info_len_off = 12, .info_len_len = 3,
+ .get_cdb_info = get_cdb_info_len_3},
+ {.ops = 0x81, .devkey = "O OO O ",
+ .info_op_name = "REBUILD",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_WRITE_MEDIUM,
+ .info_len_off = 10, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_len_4},
+ {.ops = 0x82, .devkey = "O OO O ",
+ .info_op_name = "REGENERATE",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_WRITE_MEDIUM,
+ .info_len_off = 10, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_len_4},
+ {.ops = 0x83, .devkey = "OOOOOOOOOOOOOOOO",
+ .info_op_name = "EXTENDED COPY",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_WRITE_MEDIUM,
+ .info_len_off = 10, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_len_4},
+ {.ops = 0x84, .devkey = "OOOOOOOOOOOOOOOO",
+ .info_op_name = "RECEIVE COPY RESULT",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 10, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_len_4},
+ {.ops = 0x86, .devkey = "OOOOOOOOOO ",
+ .info_op_name = "ACCESS CONTROL IN",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_REG_RESERVE_ALLOWED|SCST_WRITE_EXCL_ALLOWED|
+ SCST_EXCL_ACCESS_ALLOWED,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x87, .devkey = "OOOOOOOOOO ",
+ .info_op_name = "ACCESS CONTROL OUT",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_REG_RESERVE_ALLOWED|SCST_WRITE_EXCL_ALLOWED|
+ SCST_EXCL_ACCESS_ALLOWED,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x88, .devkey = "M MMMM ",
+ .info_op_name = "READ(16)",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|
#ifdef CONFIG_SCST_TEST_IO_IN_SIRQ
SCST_TEST_IO_IN_SIRQ_ALLOWED|
#endif
SCST_WRITE_EXCL_ALLOWED,
- 10, get_trans_len_4},
- {0x8A, "O OO O ", "WRITE(16)",
- SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED|
+ .info_lba_off = 2, .info_lba_len = 8,
+ .info_len_off = 10, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_lba_8_len_4},
+ {.ops = 0x8A, .devkey = "O OO O ",
+ .info_op_name = "WRITE(16)",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|
#ifdef CONFIG_SCST_TEST_IO_IN_SIRQ
SCST_TEST_IO_IN_SIRQ_ALLOWED|
#endif
SCST_WRITE_MEDIUM,
- 10, get_trans_len_4},
- {0x8C, "OOOOOOOOOO ", "READ ATTRIBUTE",
- SCST_DATA_READ, FLAG_NONE, 10, get_trans_len_4},
- {0x8D, "OOOOOOOOOO ", "WRITE ATTRIBUTE",
- SCST_DATA_WRITE, SCST_WRITE_MEDIUM, 10, get_trans_len_4},
- {0x8E, "O OO O ", "WRITE AND VERIFY(16)",
- SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM,
- 10, get_trans_len_4},
- {0x8F, "O OO O ", "VERIFY(16)",
- SCST_DATA_UNKNOWN, SCST_TRANSFER_LEN_TYPE_FIXED|
- SCST_WRITE_EXCL_ALLOWED,
- 10, get_verify_trans_len_4},
- {0x90, "O OO O ", "PRE-FETCH(16)",
- SCST_DATA_NONE, SCST_WRITE_EXCL_ALLOWED,
- 0, get_trans_len_none},
- {0x91, "O OO O ", "SYNCHRONIZE CACHE(16)",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0x91, " M ", "SPACE(16)",
- SCST_DATA_NONE, SCST_LONG_TIMEOUT|
- SCST_WRITE_EXCL_ALLOWED,
- 0, get_trans_len_none},
- {0x92, "O OO O ", "LOCK UNLOCK CACHE(16)",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0x92, " O ", "LOCATE(16)",
- SCST_DATA_NONE, SCST_LONG_TIMEOUT|
- SCST_WRITE_EXCL_ALLOWED,
- 0, get_trans_len_none},
- {0x93, "O O ", "WRITE SAME(16)",
- SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM,
- 10, get_trans_len_4},
- {0x93, " M ", "ERASE(16)",
- SCST_DATA_NONE, SCST_LONG_TIMEOUT|SCST_WRITE_MEDIUM,
- 0, get_trans_len_none},
- {0x9E, "O ", "SERVICE ACTION IN",
- SCST_DATA_READ, FLAG_NONE, 0, get_trans_len_serv_act_in},
+ .info_lba_off = 2, .info_lba_len = 8,
+ .info_len_off = 10, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_lba_8_len_4},
+ {.ops = 0x8C, .devkey = " OOOOOOOOO ",
+ .info_op_name = "READ ATTRIBUTE",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 10, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_len_4},
+ {.ops = 0x8D, .devkey = " OOOOOOOOO ",
+ .info_op_name = "WRITE ATTRIBUTE",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_WRITE_MEDIUM,
+ .info_len_off = 10, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_len_4},
+ {.ops = 0x8E, .devkey = "O OO O ",
+ .info_op_name = "WRITE AND VERIFY(16)",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM,
+ .info_lba_off = 2, .info_lba_len = 8,
+ .info_len_off = 10, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_lba_8_len_4},
+ {.ops = 0x8F, .devkey = "O OO O ",
+ .info_op_name = "VERIFY(16)",
+ .info_data_direction = SCST_DATA_UNKNOWN,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_EXCL_ALLOWED,
+ .info_lba_off = 2, .info_lba_len = 8,
+ .info_len_off = 10, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_verify16},
+ {.ops = 0x90, .devkey = "O OO O ",
+ .info_op_name = "PRE-FETCH(16)",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_WRITE_EXCL_ALLOWED,
+ .info_lba_off = 2, .info_lba_len = 8,
+ .get_cdb_info = get_cdb_info_lba_8_none},
+ {.ops = 0x91, .devkey = "O OO O ",
+ .info_op_name = "SYNCHRONIZE CACHE(16)",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .info_lba_off = 2, .info_lba_len = 8,
+ .info_len_off = 10, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_lba_8_none},
+ {.ops = 0x91, .devkey = " M ",
+ .info_op_name = "SPACE(16)",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_LONG_TIMEOUT|SCST_WRITE_EXCL_ALLOWED,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x92, .devkey = "O OO O ",
+ .info_op_name = "LOCK UNLOCK CACHE(16)",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x92, .devkey = " O ",
+ .info_op_name = "LOCATE(16)",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_LONG_TIMEOUT|SCST_WRITE_EXCL_ALLOWED,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x93, .devkey = "O O ",
+ .info_op_name = "WRITE SAME(16)",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM,
+ .info_lba_off = 2, .info_lba_len = 8,
+ .info_len_off = 10, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_lba_8_len_4},
+ {.ops = 0x93, .devkey = " M ",
+ .info_op_name = "ERASE(16)",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_LONG_TIMEOUT|SCST_WRITE_MEDIUM,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0x9E, .devkey = "O ",
+ .info_op_name = "SERVICE ACTION IN",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .get_cdb_info = get_cdb_info_serv_act_in},
/* 12-bytes length CDB */
- {0xA0, "VVVVVVVVVV M ", "REPORT LUNS",
- SCST_DATA_READ, SCST_SMALL_TIMEOUT|SCST_IMPLICIT_HQ|SCST_SKIP_UA|
+ {.ops = 0xA0, .devkey = "VVVVVVVVVV M ",
+ .info_op_name = "REPORT LUNS",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_SMALL_TIMEOUT|SCST_IMPLICIT_HQ|SCST_SKIP_UA|
SCST_FULLY_LOCAL_CMD|SCST_LOCAL_CMD|
SCST_REG_RESERVE_ALLOWED|
SCST_WRITE_EXCL_ALLOWED|SCST_EXCL_ACCESS_ALLOWED,
- 6, get_trans_len_4},
- {0xA1, " O ", "BLANK",
- SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
- {0xA3, " O ", "SEND KEY",
- SCST_DATA_WRITE, FLAG_NONE, 8, get_trans_len_2},
- {0xA3, "OOOOO OOOO ", "REPORT DEVICE IDENTIDIER",
- SCST_DATA_READ, SCST_REG_RESERVE_ALLOWED|
- SCST_WRITE_EXCL_ALLOWED|SCST_EXCL_ACCESS_ALLOWED,
- 6, get_trans_len_4},
- {0xA3, " M ", "MAINTENANCE(IN)",
- SCST_DATA_READ, FLAG_NONE, 6, get_trans_len_4},
- {0xA4, " O ", "REPORT KEY",
- SCST_DATA_READ, FLAG_NONE, 8, get_trans_len_2},
- {0xA4, " O ", "MAINTENANCE(OUT)",
- SCST_DATA_WRITE, FLAG_NONE, 6, get_trans_len_4},
- {0xA5, " M ", "MOVE MEDIUM",
- SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
- {0xA5, " O ", "PLAY AUDIO(12)",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0xA6, " O O ", "EXCHANGE/LOAD/UNLOAD MEDIUM",
- SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
- {0xA7, " O ", "SET READ AHEAD",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0xA8, " O ", "GET MESSAGE(12)",
- SCST_DATA_READ, FLAG_NONE, 6, get_trans_len_4},
- {0xA8, "O OO O ", "READ(12)",
- SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED|
+ .info_len_off = 6, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_len_4},
+ {.ops = 0xA1, .devkey = " O ",
+ .info_op_name = "BLANK",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_LONG_TIMEOUT,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0xA3, .devkey = " O ",
+ .info_op_name = "SEND KEY",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 8, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0xA3, .devkey = "OOOOO OOOO ",
+ .info_op_name = "REPORT DEVICE IDENTIDIER",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_REG_RESERVE_ALLOWED|SCST_WRITE_EXCL_ALLOWED|
+ SCST_EXCL_ACCESS_ALLOWED,
+ .info_len_off = 6, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0xA3, .devkey = " M ",
+ .info_op_name = "MAINTENANCE(IN)",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 6, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_len_4},
+ {.ops = 0xA4, .devkey = " O ",
+ .info_op_name = "REPORT KEY",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 8, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0xA4, .devkey = " O ",
+ .info_op_name = "MAINTENANCE(OUT)",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 6, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_len_4},
+ {.ops = 0xA5, .devkey = " M ",
+ .info_op_name = "MOVE MEDIUM",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_LONG_TIMEOUT,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0xA5, .devkey = " O ",
+ .info_op_name = "PLAY AUDIO(12)",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0xA6, .devkey = " O O ",
+ .info_op_name = "EXCHANGE/LOAD/UNLOAD MEDIUM",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_LONG_TIMEOUT,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0xA7, .devkey = " O ",
+ .info_op_name = "SET READ AHEAD",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0xA8, .devkey = " O ",
+ .info_op_name = "GET MESSAGE(12)",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 6, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_len_4},
+ {.ops = 0xA8, .devkey = "O OO O ",
+ .info_op_name = "READ(12)",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|
#ifdef CONFIG_SCST_TEST_IO_IN_SIRQ
SCST_TEST_IO_IN_SIRQ_ALLOWED|
#endif
SCST_WRITE_EXCL_ALLOWED,
- 6, get_trans_len_4},
- {0xA9, " O ", "PLAY TRACK RELATIVE(12)",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0xAA, "O OO O ", "WRITE(12)",
- SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED|
+ .info_lba_off = 2, .info_lba_len = 4,
+ .info_len_off = 6, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_lba_4_len_4},
+ {.ops = 0xA9, .devkey = " O ",
+ .info_op_name = "PLAY TRACK RELATIVE(12)",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0xAA, .devkey = "O OO O ",
+ .info_op_name = "WRITE(12)",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|
#ifdef CONFIG_SCST_TEST_IO_IN_SIRQ
SCST_TEST_IO_IN_SIRQ_ALLOWED|
#endif
SCST_WRITE_MEDIUM,
- 6, get_trans_len_4},
- {0xAA, " O ", "SEND MESSAGE(12)",
- SCST_DATA_WRITE, FLAG_NONE, 6, get_trans_len_4},
- {0xAC, " O ", "ERASE(12)",
- SCST_DATA_NONE, SCST_WRITE_MEDIUM, 0, get_trans_len_none},
- {0xAC, " M ", "GET PERFORMANCE",
- SCST_DATA_READ, SCST_UNKNOWN_LENGTH, 0, get_trans_len_none},
- {0xAD, " O ", "READ DVD STRUCTURE",
- SCST_DATA_READ, FLAG_NONE, 8, get_trans_len_2},
- {0xAE, "O OO O ", "WRITE AND VERIFY(12)",
- SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM,
- 6, get_trans_len_4},
- {0xAF, "O OO O ", "VERIFY(12)",
- SCST_DATA_UNKNOWN, SCST_TRANSFER_LEN_TYPE_FIXED|
- SCST_WRITE_EXCL_ALLOWED,
- 6, get_verify_trans_len_4},
-#if 0 /* No need to support at all */
- {0xB0, " OO O ", "SEARCH DATA HIGH(12)",
- SCST_DATA_WRITE, FLAG_NONE, 9, get_trans_len_1},
- {0xB1, " OO O ", "SEARCH DATA EQUAL(12)",
- SCST_DATA_WRITE, FLAG_NONE, 9, get_trans_len_1},
- {0xB2, " OO O ", "SEARCH DATA LOW(12)",
- SCST_DATA_WRITE, FLAG_NONE, 9, get_trans_len_1},
-#endif
- {0xB3, " OO O ", "SET LIMITS(12)",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0xB5, " O ", "REQUEST VOLUME ELEMENT ADDRESS",
- SCST_DATA_READ, FLAG_NONE, 9, get_trans_len_1},
- {0xB6, " O ", "SEND VOLUME TAG",
- SCST_DATA_WRITE, FLAG_NONE, 9, get_trans_len_1},
- {0xB6, " M ", "SET STREAMING",
- SCST_DATA_WRITE, FLAG_NONE, 9, get_trans_len_2},
- {0xB7, " O ", "READ DEFECT DATA(12)",
- SCST_DATA_READ, SCST_WRITE_EXCL_ALLOWED,
- 9, get_trans_len_1},
- {0xB8, " O ", "READ ELEMENT STATUS",
- SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_3_read_elem_stat},
- {0xB9, " O ", "READ CD MSF",
- SCST_DATA_READ, SCST_UNKNOWN_LENGTH, 0, get_trans_len_none},
- {0xBA, " O ", "SCAN",
- SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
- {0xBA, " O ", "REDUNDANCY GROUP(IN)",
- SCST_DATA_READ, FLAG_NONE, 6, get_trans_len_4},
- {0xBB, " O ", "SET SPEED",
- SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
- {0xBB, " O ", "REDUNDANCY GROUP(OUT)",
- SCST_DATA_WRITE, FLAG_NONE, 6, get_trans_len_4},
- {0xBC, " O ", "SPARE(IN)",
- SCST_DATA_READ, FLAG_NONE, 6, get_trans_len_4},
- {0xBD, " O ", "MECHANISM STATUS",
- SCST_DATA_READ, FLAG_NONE, 8, get_trans_len_2},
- {0xBD, " O ", "SPARE(OUT)",
- SCST_DATA_WRITE, FLAG_NONE, 6, get_trans_len_4},
- {0xBE, " O ", "READ CD",
- SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED, 6, get_trans_len_3},
- {0xBE, " O ", "VOLUME SET(IN)",
- SCST_DATA_READ, FLAG_NONE, 6, get_trans_len_4},
- {0xBF, " O ", "SEND DVD STRUCTUE",
- SCST_DATA_WRITE, FLAG_NONE, 8, get_trans_len_2},
- {0xBF, " O ", "VOLUME SET(OUT)",
- SCST_DATA_WRITE, FLAG_NONE, 6, get_trans_len_4},
- {0xE7, " V ", "INIT ELEMENT STATUS WRANGE",
- SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_cdb_len_10}
+ .info_lba_off = 2, .info_lba_len = 4,
+ .info_len_off = 6, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_lba_4_len_4},
+ {.ops = 0xAA, .devkey = " O ",
+ .info_op_name = "SEND MESSAGE(12)",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 6, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_len_4},
+ {.ops = 0xAC, .devkey = " O ",
+ .info_op_name = "ERASE(12)",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_WRITE_MEDIUM,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0xAC, .devkey = " M ",
+ .info_op_name = "GET PERFORMANCE",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_UNKNOWN_LENGTH,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0xAD, .devkey = " O ",
+ .info_op_name = "READ DVD STRUCTURE",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 8, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0xAE, .devkey = "O OO O ",
+ .info_op_name = "WRITE AND VERIFY(12)",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM,
+ .info_lba_off = 2, .info_lba_len = 4,
+ .info_len_off = 6, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_lba_4_len_4},
+ {.ops = 0xAF, .devkey = "O OO O ",
+ .info_op_name = "VERIFY(12)",
+ .info_data_direction = SCST_DATA_UNKNOWN,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_EXCL_ALLOWED,
+ .info_lba_off = 2, .info_lba_len = 4,
+ .info_len_off = 6, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_verify12},
+ {.ops = 0xB3, .devkey = " OO O ",
+ .info_op_name = "SET LIMITS(12)",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0xB5, .devkey = " O ",
+ .info_op_name = "REQUEST VOLUME ELEMENT ADDRESS",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 9, .info_len_len = 1,
+ .get_cdb_info = get_cdb_info_len_1},
+ {.ops = 0xB6, .devkey = " O ",
+ .info_op_name = "SEND VOLUME TAG",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 9, .info_len_len = 1,
+ .get_cdb_info = get_cdb_info_len_1},
+ {.ops = 0xB6, .devkey = " M ",
+ .info_op_name = "SET STREAMING",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 9, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0xB7, .devkey = " O ",
+ .info_op_name = "READ DEFECT DATA(12)",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_WRITE_EXCL_ALLOWED,
+ .info_len_off = 9, .info_len_len = 1,
+ .get_cdb_info = get_cdb_info_len_1},
+ {.ops = 0xB8, .devkey = " O ",
+ .info_op_name = "READ ELEMENT STATUS",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 7, .info_len_len = 3,
+ .get_cdb_info = get_cdb_info_len_3_read_elem_stat},
+ {.ops = 0xB9, .devkey = " O ",
+ .info_op_name = "READ CD MSF",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_UNKNOWN_LENGTH,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0xBA, .devkey = " O ",
+ .info_op_name = "SCAN",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_LONG_TIMEOUT,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0xBA, .devkey = " O ",
+ .info_op_name = "REDUNDANCY GROUP(IN)",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 6, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_len_4},
+ {.ops = 0xBB, .devkey = " O ",
+ .info_op_name = "SET SPEED",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = FLAG_NONE,
+ .get_cdb_info = get_cdb_info_none},
+ {.ops = 0xBB, .devkey = " O ",
+ .info_op_name = "REDUNDANCY GROUP(OUT)",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 6, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_len_4},
+ {.ops = 0xBC, .devkey = " O ",
+ .info_op_name = "SPARE(IN)",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 6, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_len_4},
+ {.ops = 0xBD, .devkey = " O ",
+ .info_op_name = "MECHANISM STATUS",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 8, .info_len_len = 2,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0xBD, .devkey = " O ",
+ .info_op_name = "SPARE(OUT)",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 6, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_len_4},
+ {.ops = 0xBE, .devkey = " O ",
+ .info_op_name = "READ CD",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED,
+ .info_len_off = 6, .info_len_len = 3,
+ .get_cdb_info = get_cdb_info_len_3},
+ {.ops = 0xBE, .devkey = " O ",
+ .info_op_name = "VOLUME SET(IN)",
+ .info_data_direction = SCST_DATA_READ,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 6, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_len_4},
+ {.ops = 0xBF, .devkey = " O ",
+ .info_op_name = "SEND DVD STRUCTUE",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 8, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_len_2},
+ {.ops = 0xBF, .devkey = " O ",
+ .info_op_name = "VOLUME SET(OUT)",
+ .info_data_direction = SCST_DATA_WRITE,
+ .info_op_flags = FLAG_NONE,
+ .info_len_off = 6, .info_len_len = 4,
+ .get_cdb_info = get_cdb_info_len_4},
+ {.ops = 0xE7, .devkey = " V ",
+ .info_op_name = "INIT ELEMENT STATUS WRANGE",
+ .info_data_direction = SCST_DATA_NONE,
+ .info_op_flags = SCST_LONG_TIMEOUT,
+ .get_cdb_info = get_cdb_info_len_10}
};
#define SCST_CDB_TBL_SIZE ((int)ARRAY_SIZE(scst_scsi_op_table))
@@ -4188,7 +4750,7 @@ struct scst_cmd *scst_alloc_cmd(const uint8_t *cdb,
cmd->queue_type = SCST_CMD_QUEUE_SIMPLE;
cmd->timeout = SCST_DEFAULT_TIMEOUT;
cmd->retries = 0;
- cmd->data_len = -1;
+ cmd->data_len = SCST_DEF_DATA_LEN;
cmd->is_send_status = 1;
cmd->resp_data_len = -1;
cmd->write_sg = &cmd->sg;
@@ -4999,28 +5561,34 @@ static const int SCST_CDB_LENGTH[8] = { 6, 10, 10, 0, 16, 12, 0, 0 };
#define SCST_CDB_GROUP(opcode) ((opcode >> 5) & 0x7)
#define SCST_GET_CDB_LEN(opcode) SCST_CDB_LENGTH[SCST_CDB_GROUP(opcode)]
-/* get_trans_len_x extract x bytes from cdb as length starting from off */
-
-static int get_trans_cdb_len_10(struct scst_cmd *cmd, uint8_t off)
+static int get_cdb_info_len_10(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
{
cmd->cdb_len = 10;
- cmd->bufflen = 0;
+ /* It supposed to be already zeroed */
+ EXTRACHECKS_BUG_ON(cmd->bufflen != 0);
+ cmd->data_len = cmd->bufflen;
return 0;
}
-static int get_trans_len_block_limit(struct scst_cmd *cmd, uint8_t off)
+static int get_cdb_info_block_limit(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
{
cmd->bufflen = 6;
+ cmd->data_len = cmd->bufflen;
return 0;
}
-static int get_trans_len_read_capacity(struct scst_cmd *cmd, uint8_t off)
+static int get_cdb_info_read_capacity(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
{
cmd->bufflen = 8;
+ cmd->data_len = cmd->bufflen;
return 0;
}
-static int get_trans_len_serv_act_in(struct scst_cmd *cmd, uint8_t off)
+static int get_cdb_info_serv_act_in(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
{
int res = 0;
@@ -5029,26 +5597,33 @@ static int get_trans_len_serv_act_in(struct scst_cmd *cmd, uint8_t off)
if ((cmd->cdb[1] & 0x1f) == SAI_READ_CAPACITY_16) {
cmd->op_name = "READ CAPACITY(16)";
cmd->bufflen = get_unaligned_be32(&cmd->cdb[10]);
- cmd->op_flags |= SCST_IMPLICIT_HQ | SCST_REG_RESERVE_ALLOWED |
- SCST_WRITE_EXCL_ALLOWED | SCST_EXCL_ACCESS_ALLOWED;
+ cmd->op_flags |= SCST_IMPLICIT_HQ |
+ SCST_REG_RESERVE_ALLOWED |
+ SCST_WRITE_EXCL_ALLOWED |
+ SCST_EXCL_ACCESS_ALLOWED;
} else
cmd->op_flags |= SCST_UNKNOWN_LENGTH;
+ cmd->data_len = cmd->bufflen;
+
TRACE_EXIT_RES(res);
return res;
}
-static int get_trans_len_single(struct scst_cmd *cmd, uint8_t off)
+static int get_cdb_info_single(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
{
cmd->bufflen = 1;
+ cmd->data_len = cmd->bufflen;
return 0;
}
-static int get_trans_len_read_pos(struct scst_cmd *cmd, uint8_t off)
+static int get_cdb_info_read_pos(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
{
int res = 0;
- cmd->bufflen = get_unaligned_be16(cmd->cdb + off);
+ cmd->bufflen = get_unaligned_be16(cmd->cdb + sdbops->info_len_off);
switch (cmd->cdb[1] & 0x1f) {
case 0:
@@ -5080,6 +5655,8 @@ static int get_trans_len_read_pos(struct scst_cmd *cmd, uint8_t off)
goto out_inval;
}
+ cmd->data_len = cmd->bufflen;
+
out:
return res;
@@ -5090,8 +5667,8 @@ out_inval:
goto out;
}
-static int get_trans_len_prevent_allow_medium_removal(struct scst_cmd *cmd,
- uint8_t off)
+static int get_cdb_info_prevent_allow_medium_removal(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
{
if ((cmd->cdb[4] & 3) == 0)
cmd->op_flags |= SCST_REG_RESERVE_ALLOWED |
@@ -5099,7 +5676,8 @@ static int get_trans_len_prevent_allow_medium_removal(struct scst_cmd *cmd,
return 0;
}
-static int get_trans_len_start_stop(struct scst_cmd *cmd, uint8_t off)
+static int get_cdb_info_start_stop(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
{
if ((cmd->cdb[4] & 0xF1) == 0x1)
cmd->op_flags |= SCST_REG_RESERVE_ALLOWED |
@@ -5107,9 +5685,11 @@ static int get_trans_len_start_stop(struct scst_cmd *cmd, uint8_t off)
return 0;
}
-static int get_trans_len_3_read_elem_stat(struct scst_cmd *cmd, uint8_t off)
+static int get_cdb_info_len_3_read_elem_stat(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
{
- cmd->bufflen = get_unaligned_be24(cmd->cdb + off);
+ cmd->bufflen = get_unaligned_be24(cmd->cdb + sdbops->info_len_off);
+ cmd->data_len = cmd->bufflen;
if ((cmd->cdb[6] & 0x2) == 0x2)
cmd->op_flags |= SCST_REG_RESERVE_ALLOWED |
@@ -5117,77 +5697,101 @@ static int get_trans_len_3_read_elem_stat(struct scst_cmd *cmd, uint8_t off)
return 0;
}
-static int get_bidi_trans_len_2(struct scst_cmd *cmd, uint8_t off)
+static int get_cdb_info_bidi_lba_4_len_2(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
{
- cmd->bufflen = get_unaligned_be16(cmd->cdb + off);
+ cmd->lba = get_unaligned_be32(cmd->cdb + sdbops->info_lba_off);
+ cmd->bufflen = get_unaligned_be16(cmd->cdb + sdbops->info_len_off);
+ cmd->data_len = cmd->bufflen;
cmd->out_bufflen = cmd->bufflen;
return 0;
}
-static int get_trans_len_fmt(struct scst_cmd *cmd, uint8_t off)
+static int get_cdb_info_fmt(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
{
if (cmd->cdb[1] & 0x10/*FMTDATA*/) {
cmd->data_direction = SCST_DATA_WRITE;
cmd->op_flags |= SCST_UNKNOWN_LENGTH;
}
-
return 0;
}
-/*
- * get_verify_trans_len_2() - Compute transport len and dir for SCSI VERIFY.
- *
- * Whether a data-out buffer is associated with a SCSI VERIFY command depends on
- * the BYTCHK bit in that command. Check that bit and compute the data out
- * buffer length and the data transfer direction.
- */
-static int get_verify_trans_len_2(struct scst_cmd *cmd, uint8_t off)
+static int get_cdb_info_verify10(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
{
+ cmd->lba = get_unaligned_be32(cmd->cdb + sdbops->info_lba_off);
if (cmd->cdb[1] & BYTCHK) {
- cmd->bufflen = get_unaligned_be16(cmd->cdb + off);
+ cmd->bufflen = get_unaligned_be16(cmd->cdb + sdbops->info_len_off);
+ cmd->data_len = cmd->bufflen;
cmd->data_direction = SCST_DATA_WRITE;
} else {
cmd->bufflen = 0;
+ cmd->data_len = get_unaligned_be16(cmd->cdb + sdbops->info_len_off);
cmd->data_direction = SCST_DATA_NONE;
}
-
return 0;
}
-static int get_verify_trans_len_3(struct scst_cmd *cmd, uint8_t off)
+static int get_cdb_info_verify6(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
{
if (cmd->cdb[1] & BYTCHK) {
- cmd->bufflen = get_unaligned_be24(cmd->cdb + off);
+ cmd->bufflen = get_unaligned_be24(cmd->cdb + sdbops->info_len_off);
+ cmd->data_len = cmd->bufflen;
cmd->data_direction = SCST_DATA_WRITE;
} else {
cmd->bufflen = 0;
+ cmd->data_len = get_unaligned_be24(cmd->cdb + sdbops->info_len_off);
cmd->data_direction = SCST_DATA_NONE;
}
-
return 0;
}
-static int get_verify_trans_len_4(struct scst_cmd *cmd, uint8_t off)
+static int get_cdb_info_verify12(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
{
+ cmd->lba = get_unaligned_be32(cmd->cdb + sdbops->info_lba_off);
if (cmd->cdb[1] & BYTCHK) {
- cmd->bufflen = get_unaligned_be32(cmd->cdb + off);
+ cmd->bufflen = get_unaligned_be32(cmd->cdb + sdbops->info_len_off);
+ cmd->data_len = cmd->bufflen;
cmd->data_direction = SCST_DATA_WRITE;
} else {
cmd->bufflen = 0;
+ cmd->data_len = get_unaligned_be32(cmd->cdb + sdbops->info_len_off);
cmd->data_direction = SCST_DATA_NONE;
}
-
return 0;
}
-static int get_trans_len_1(struct scst_cmd *cmd, uint8_t off)
+static int get_cdb_info_verify16(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
{
- cmd->bufflen = (u32)cmd->cdb[off];
+ cmd->lba = get_unaligned_be64(cmd->cdb + sdbops->info_lba_off);
+ if (cmd->cdb[1] & BYTCHK) {
+ cmd->bufflen = get_unaligned_be32(cmd->cdb + sdbops->info_len_off);
+ cmd->data_len = cmd->bufflen;
+ cmd->data_direction = SCST_DATA_WRITE;
+ } else {
+ cmd->bufflen = 0;
+ cmd->data_len = get_unaligned_be32(cmd->cdb + sdbops->info_len_off);
+ cmd->data_direction = SCST_DATA_NONE;
+ }
return 0;
}
-static int get_trans_len_1_256(struct scst_cmd *cmd, uint8_t off)
+static int get_cdb_info_len_1(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
{
+ cmd->bufflen = (u32)cmd->cdb[sdbops->info_len_off];
+ cmd->data_len = cmd->bufflen;
+ return 0;
+}
+
+static int get_cdb_info_lba_2_len_1_256(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
+{
+ cmd->lba = get_unaligned_be16(cmd->cdb + sdbops->info_lba_off);
/*
* From the READ(6) specification: a TRANSFER LENGTH field set to zero
* specifies that 256 logical blocks shall be read.
@@ -5199,35 +5803,101 @@ static int get_trans_len_1_256(struct scst_cmd *cmd, uint8_t off)
* is reduced modulo the largest value that can be represented by the
* resulting type.
*/
- cmd->bufflen = (u8)(cmd->cdb[off] - 1) + 1;
+ cmd->bufflen = (u8)(cmd->cdb[sdbops->info_len_off] - 1) + 1;
+ cmd->data_len = cmd->bufflen;
return 0;
}
-static int get_trans_len_2(struct scst_cmd *cmd, uint8_t off)
+static int get_cdb_info_len_2(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
{
- cmd->bufflen = get_unaligned_be16(cmd->cdb + off);
+ cmd->bufflen = get_unaligned_be16(cmd->cdb + sdbops->info_len_off);
+ cmd->data_len = cmd->bufflen;
return 0;
}
-static int get_trans_len_3(struct scst_cmd *cmd, uint8_t off)
+static int get_cdb_info_len_3(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
{
- cmd->bufflen = get_unaligned_be24(cmd->cdb + off);
-
+ cmd->bufflen = get_unaligned_be24(cmd->cdb + sdbops->info_len_off);
+ cmd->data_len = cmd->bufflen;
return 0;
}
-static int get_trans_len_4(struct scst_cmd *cmd, uint8_t off)
+static int get_cdb_info_len_4(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
{
- cmd->bufflen = get_unaligned_be32(cmd->cdb + off);
+ cmd->bufflen = get_unaligned_be32(cmd->cdb + sdbops->info_len_off);
+ cmd->data_len = cmd->bufflen;
return 0;
}
-static int get_trans_len_none(struct scst_cmd *cmd, uint8_t off)
+static int get_cdb_info_none(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
{
- cmd->bufflen = 0;
+ /* All supposed to be already zeroed, except data_len, which is -1 */
+ EXTRACHECKS_BUG_ON(cmd->lba != 0);
+ EXTRACHECKS_BUG_ON(cmd->bufflen != 0);
+ cmd->data_len = cmd->bufflen;
return 0;
}
+static int get_cdb_info_lba_2_none(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
+{
+ cmd->lba = get_unaligned_be16(cmd->cdb + sdbops->info_lba_off);
+ /* It supposed to be already zeroed */
+ EXTRACHECKS_BUG_ON(cmd->bufflen != 0);
+ cmd->data_len = cmd->bufflen;
+ return 0;
+}
+
+static int get_cdb_info_lba_4_none(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
+{
+ cmd->lba = get_unaligned_be32(cmd->cdb + sdbops->info_lba_off);
+ /* It supposed to be already zeroed */
+ EXTRACHECKS_BUG_ON(cmd->bufflen != 0);
+ cmd->data_len = cmd->bufflen;
+ return 0;
+}
+
+static int get_cdb_info_lba_8_none(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
+{
+ cmd->lba = get_unaligned_be64(cmd->cdb + sdbops->info_lba_off);
+ /* It supposed to be already zeroed */
+ EXTRACHECKS_BUG_ON(cmd->bufflen != 0);
+ cmd->data_len = cmd->bufflen;
+ return 0;
+}
+
+static int get_cdb_info_lba_4_len_2(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
+{
+ cmd->lba = get_unaligned_be32(cmd->cdb + sdbops->info_lba_off);
+ cmd->bufflen = get_unaligned_be16(cmd->cdb + sdbops->info_len_off);
+ cmd->data_len = cmd->bufflen;
+ return 0;
+}
+
+static int get_cdb_info_lba_4_len_4(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
+{
+ cmd->lba = get_unaligned_be32(cmd->cdb + sdbops->info_lba_off);
+ cmd->bufflen = get_unaligned_be32(cmd->cdb + sdbops->info_len_off);
+ cmd->data_len = cmd->bufflen;
+ return 0;
+}
+
+static int get_cdb_info_lba_8_len_4(struct scst_cmd *cmd,
+ const struct scst_sdbops *sdbops)
+{
+ cmd->lba = get_unaligned_be64(cmd->cdb + sdbops->info_lba_off);
+ cmd->bufflen = get_unaligned_be32(cmd->cdb + sdbops->info_len_off);
+ cmd->data_len = cmd->bufflen;
+ return 0;
+}
/**
* scst_get_cdb_info() - fill various info about the command's CDB
@@ -5250,9 +5920,8 @@ int scst_get_cdb_info(struct scst_cmd *cmd)
op = cmd->cdb[0]; /* get clear opcode */
- TRACE_DBG("opcode=%02x, cdblen=%d bytes, tblsize=%d, "
- "dev_type=%d", op, SCST_GET_CDB_LEN(op), SCST_CDB_TBL_SIZE,
- dev_type);
+ TRACE_DBG("opcode=%02x, cdblen=%d bytes, dev_type=%d", op,
+ SCST_GET_CDB_LEN(op), dev_type);
i = scst_scsi_op_list[op];
while (i < SCST_CDB_TBL_SIZE && scst_scsi_op_table[i].ops == op) {
@@ -5269,11 +5938,12 @@ int scst_get_cdb_info(struct scst_cmd *cmd)
ptr->devkey[7], /* worm */
ptr->devkey[8], /* changer */
ptr->devkey[9], /* commdev */
- ptr->op_name);
- TRACE_DBG("direction=%d flags=%d off=%d",
- ptr->direction,
- ptr->flags,
- ptr->off);
+ ptr->info_op_name);
+ TRACE_DBG("data direction %d, op flags 0x%x, lba off %d, "
+ "lba len %d, len off %d, len len %d",
+ ptr->info_data_direction, ptr->info_op_flags,
+ ptr->info_lba_off, ptr->info_lba_len,
+ ptr->info_len_off, ptr->info_len_len);
break;
}
i++;
@@ -5288,10 +5958,14 @@ int scst_get_cdb_info(struct scst_cmd *cmd)
}
cmd->cdb_len = SCST_GET_CDB_LEN(op);
- cmd->op_name = ptr->op_name;
- cmd->data_direction = ptr->direction;
- cmd->op_flags = ptr->flags | SCST_INFO_VALID;
- res = (*ptr->get_trans_len)(cmd, ptr->off);
+ cmd->op_name = ptr->info_op_name;
+ cmd->data_direction = ptr->info_data_direction;
+ cmd->op_flags = ptr->info_op_flags | SCST_INFO_VALID;
+ cmd->lba_off = ptr->info_lba_off;
+ cmd->lba_len = ptr->info_lba_len;
+ cmd->len_off = ptr->info_len_off;
+ cmd->len_len = ptr->info_len_len;
+ res = (*ptr->get_cdb_info)(cmd, ptr);
out:
TRACE_EXIT_RES(res);
@@ -5423,25 +6097,6 @@ int scst_sbc_generic_parse(struct scst_cmd *cmd,
* therefore change them only if necessary
*/
- TRACE_DBG("op_name <%s> direct %d flags %d transfer_len %d",
- cmd->op_name, cmd->data_direction, cmd->op_flags, cmd->bufflen);
-
- switch (cmd->cdb[0]) {
- case VERIFY:
- case VERIFY_12:
- case VERIFY_16:
- if ((cmd->cdb[1] & BYTCHK) == 0) {
- cmd->data_len = cmd->bufflen << get_block_shift(cmd);
- cmd->bufflen = 0;
- goto set_timeout;
- } else
- cmd->data_len = 0;
- break;
- default:
- /* It's all good */
- break;
- }
-
if (cmd->op_flags & SCST_TRANSFER_LEN_TYPE_FIXED) {
int block_shift = get_block_shift(cmd);
/*
@@ -5449,10 +6104,10 @@ int scst_sbc_generic_parse(struct scst_cmd *cmd,
* called, when there are existing commands.
*/
cmd->bufflen = cmd->bufflen << block_shift;
+ cmd->data_len = cmd->data_len << block_shift;
cmd->out_bufflen = cmd->out_bufflen << block_shift;
}
-set_timeout:
if ((cmd->op_flags & (SCST_SMALL_TIMEOUT | SCST_LONG_TIMEOUT)) == 0)
cmd->timeout = SCST_GENERIC_DISK_REG_TIMEOUT;
else if (cmd->op_flags & SCST_SMALL_TIMEOUT)
@@ -5485,33 +6140,15 @@ int scst_cdrom_generic_parse(struct scst_cmd *cmd,
* therefore change them only if necessary
*/
- TRACE_DBG("op_name <%s> direct %d flags %d transfer_len %d",
- cmd->op_name, cmd->data_direction, cmd->op_flags, cmd->bufflen);
-
cmd->cdb[1] &= 0x1f;
- switch (cmd->cdb[0]) {
- case VERIFY:
- case VERIFY_12:
- case VERIFY_16:
- if ((cmd->cdb[1] & BYTCHK) == 0) {
- cmd->data_len = cmd->bufflen << get_block_shift(cmd);
- cmd->bufflen = 0;
- goto set_timeout;
- }
- break;
- default:
- /* It's all good */
- break;
- }
-
if (cmd->op_flags & SCST_TRANSFER_LEN_TYPE_FIXED) {
int block_shift = get_block_shift(cmd);
cmd->bufflen = cmd->bufflen << block_shift;
+ cmd->data_len = cmd->data_len << block_shift;
cmd->out_bufflen = cmd->out_bufflen << block_shift;
}
-set_timeout:
if ((cmd->op_flags & (SCST_SMALL_TIMEOUT | SCST_LONG_TIMEOUT)) == 0)
cmd->timeout = SCST_GENERIC_CDROM_REG_TIMEOUT;
else if (cmd->op_flags & SCST_SMALL_TIMEOUT)
@@ -5544,33 +6181,15 @@ int scst_modisk_generic_parse(struct scst_cmd *cmd,
* therefore change them only if necessary
*/
- TRACE_DBG("op_name <%s> direct %d flags %d transfer_len %d",
- cmd->op_name, cmd->data_direction, cmd->op_flags, cmd->bufflen);
-
cmd->cdb[1] &= 0x1f;
- switch (cmd->cdb[0]) {
- case VERIFY:
- case VERIFY_12:
- case VERIFY_16:
- if ((cmd->cdb[1] & BYTCHK) == 0) {
- cmd->data_len = cmd->bufflen << get_block_shift(cmd);
- cmd->bufflen = 0;
- goto set_timeout;
- }
- break;
- default:
- /* It's all good */
- break;
- }
-
if (cmd->op_flags & SCST_TRANSFER_LEN_TYPE_FIXED) {
int block_shift = get_block_shift(cmd);
cmd->bufflen = cmd->bufflen << block_shift;
+ cmd->data_len = cmd->data_len << block_shift;
cmd->out_bufflen = cmd->out_bufflen << block_shift;
}
-set_timeout:
if ((cmd->op_flags & (SCST_SMALL_TIMEOUT | SCST_LONG_TIMEOUT)) == 0)
cmd->timeout = SCST_GENERIC_MODISK_REG_TIMEOUT;
else if (cmd->op_flags & SCST_SMALL_TIMEOUT)
@@ -5603,9 +6222,6 @@ int scst_tape_generic_parse(struct scst_cmd *cmd,
* therefore change them only if necessary
*/
- TRACE_DBG("op_name <%s> direct %d flags %d transfer_len %d",
- cmd->op_name, cmd->data_direction, cmd->op_flags, cmd->bufflen);
-
if (cmd->cdb[0] == READ_POSITION) {
int tclp = cmd->cdb[1] & 4;
int long_bit = cmd->cdb[1] & 2;
@@ -5619,11 +6235,13 @@ int scst_tape_generic_parse(struct scst_cmd *cmd,
cmd->bufflen = 0;
cmd->data_direction = SCST_DATA_NONE;
}
+ cmd->data_len = cmd->bufflen;
}
if (cmd->op_flags & SCST_TRANSFER_LEN_TYPE_FIXED & cmd->cdb[1]) {
int block_size = get_block_size(cmd);
cmd->bufflen = cmd->bufflen * block_size;
+ cmd->data_len = cmd->data_len * block_size;
cmd->out_bufflen = cmd->out_bufflen * block_size;
}
@@ -5650,8 +6268,6 @@ static int scst_null_parse(struct scst_cmd *cmd)
* therefore change them only if necessary
*/
- TRACE_DBG("op_name <%s> direct %d flags %d transfer_len %d",
- cmd->op_name, cmd->data_direction, cmd->op_flags, cmd->bufflen);
#if 0
switch (cmd->cdb[0]) {
default:
@@ -5659,6 +6275,7 @@ static int scst_null_parse(struct scst_cmd *cmd)
break;
}
#endif
+
TRACE_DBG("res %d bufflen %d direct %d",
res, cmd->bufflen, cmd->data_direction);
@@ -5749,7 +6366,7 @@ int scst_block_generic_dev_done(struct scst_cmd *cmd,
* therefore change them only if necessary
*/
- if ((status == SAM_STAT_GOOD) || (status == SAM_STAT_CONDITION_MET)) {
+ if (likely((status == SAM_STAT_GOOD)) || (status == SAM_STAT_CONDITION_MET)) {
switch (opcode) {
case READ_CAPACITY:
{
@@ -5812,7 +6429,7 @@ int scst_tape_generic_dev_done(struct scst_cmd *cmd,
* therefore change them only if necessary
*/
- if (cmd->status != SAM_STAT_GOOD)
+ if (unlikely(cmd->status != SAM_STAT_GOOD))
goto out;
switch (opcode) {
@@ -5864,6 +6481,158 @@ out:
}
EXPORT_SYMBOL_GPL(scst_tape_generic_dev_done);
+typedef void (*scst_set_cdb_lba_fn_t)(struct scst_cmd *cmd, int64_t lba);
+
+static void scst_set_cdb_lba1(struct scst_cmd *cmd, int64_t lba)
+{
+ TRACE_ENTRY();
+
+ cmd->cdb[cmd->lba_off] = lba;
+
+ TRACE_EXIT();
+ return;
+}
+
+static void scst_set_cdb_lba2(struct scst_cmd *cmd, int64_t lba)
+{
+ TRACE_ENTRY();
+
+ put_unaligned_be16(lba, &cmd->cdb[cmd->lba_off]);
+
+ TRACE_EXIT();
+ return;
+}
+
+static void scst_set_cdb_lba3(struct scst_cmd *cmd, int64_t lba)
+{
+ TRACE_ENTRY();
+
+ put_unaligned_be24(lba, &cmd->cdb[cmd->lba_off]);
+
+ TRACE_EXIT();
+ return;
+}
+
+static void scst_set_cdb_lba4(struct scst_cmd *cmd, int64_t lba)
+{
+ TRACE_ENTRY();
+
+ put_unaligned_be32(lba, &cmd->cdb[cmd->lba_off]);
+
+ TRACE_EXIT();
+ return;
+}
+
+static void scst_set_cdb_lba8(struct scst_cmd *cmd, int64_t lba)
+{
+ TRACE_ENTRY();
+
+ put_unaligned_be64(lba, &cmd->cdb[cmd->lba_off]);
+
+ TRACE_EXIT();
+ return;
+}
+
+static const scst_set_cdb_lba_fn_t scst_set_cdb_lba_fns[9] = {
+ [1] = scst_set_cdb_lba1,
+ [2] = scst_set_cdb_lba2,
+ [3] = scst_set_cdb_lba3,
+ [4] = scst_set_cdb_lba4,
+ [8] = scst_set_cdb_lba8,
+};
+
+int scst_set_cdb_lba(struct scst_cmd *cmd, int64_t lba)
+{
+ int res;
+
+ TRACE_ENTRY();
+
+ scst_set_cdb_lba_fns[cmd->lba_len](cmd, lba);
+ res = 0;
+
+ TRACE_DBG("cmd %p, new LBA %lld", cmd, (unsigned long long)lba);
+
+ TRACE_EXIT_RES(res);
+ return res;
+}
+EXPORT_SYMBOL_GPL(scst_set_cdb_lba);
+
+typedef void (*scst_set_cdb_transf_len_fn_t)(struct scst_cmd *cmd, int len);
+
+static void scst_set_cdb_transf_len1(struct scst_cmd *cmd, int len)
+{
+ TRACE_ENTRY();
+
+ cmd->cdb[cmd->len_off] = len;
+
+ TRACE_EXIT();
+ return;
+}
+
+static void scst_set_cdb_transf_len2(struct scst_cmd *cmd, int len)
+{
+ TRACE_ENTRY();
+
+ put_unaligned_be16(len, &cmd->cdb[cmd->len_off]);
+
+ TRACE_EXIT();
+ return;
+}
+
+static void scst_set_cdb_transf_len3(struct scst_cmd *cmd, int len)
+{
+ TRACE_ENTRY();
+
+ put_unaligned_be24(len, &cmd->cdb[cmd->len_off]);
+
+ TRACE_EXIT();
+ return;
+}
+
+static void scst_set_cdb_transf_len4(struct scst_cmd *cmd, int len)
+{
+ TRACE_ENTRY();
+
+ put_unaligned_be32(len, &cmd->cdb[cmd->len_off]);
+
+ TRACE_EXIT();
+ return;
+}
+
+static void scst_set_cdb_transf_len8(struct scst_cmd *cmd, int len)
+{
+ TRACE_ENTRY();
+
+ put_unaligned_be64(len, &cmd->cdb[cmd->len_off]);
+
+ TRACE_EXIT();
+ return;
+}
+
+static const scst_set_cdb_transf_len_fn_t scst_set_cdb_transf_len_fns[9] = {
+ [1] = scst_set_cdb_transf_len1,
+ [2] = scst_set_cdb_transf_len2,
+ [3] = scst_set_cdb_transf_len3,
+ [4] = scst_set_cdb_transf_len4,
+ [8] = scst_set_cdb_transf_len8,
+};
+
+int scst_set_cdb_transf_len(struct scst_cmd *cmd, int len)
+{
+ int res;
+
+ TRACE_ENTRY();
+
+ scst_set_cdb_transf_len_fns[cmd->len_len](cmd, len);
+ res = 0;
+
+ TRACE_DBG("cmd %p, new len %d", cmd, len);
+
+ TRACE_EXIT_RES(res);
+ return res;
+}
+EXPORT_SYMBOL_GPL(scst_set_cdb_transf_len);
+
static void scst_check_internal_sense(struct scst_device *dev, int result,
uint8_t *sense, int sense_len)
{
@@ -6953,6 +7722,8 @@ static void __init scst_scsi_op_list_init(void)
TRACE_ENTRY();
+ TRACE_DBG("tblsize=%d", SCST_CDB_TBL_SIZE);
+
for (i = 0; i < 256; i++)
scst_scsi_op_list[i] = SCST_CDB_TBL_SIZE;
@@ -6963,6 +7734,9 @@ static void __init scst_scsi_op_list_init(void)
}
}
+ TRACE_BUFFER("scst_scsi_op_list", scst_scsi_op_list,
+ sizeof(scst_scsi_op_list));
+
TRACE_EXIT();
return;
}
diff --git a/scst/src/scst_priv.h b/scst/src/scst_priv.h
index 56f6fdaed..a554c20c1 100644
--- a/scst/src/scst_priv.h
+++ b/scst/src/scst_priv.h
@@ -109,6 +109,8 @@ extern unsigned long scst_trace_flag;
#define SCST_TGT_RETRY_TIMEOUT (3/2*HZ)
+#define SCST_DEF_DATA_LEN -1
+
extern struct mutex scst_mutex2;
extern int scst_threads;
diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c
index c15bea593..b6947265b 100644
--- a/scst/src/scst_targ.c
+++ b/scst/src/scst_targ.c
@@ -505,14 +505,14 @@ int scst_pre_parse(struct scst_cmd *cmd)
cmd->queue_type == SCST_CMD_QUEUE_ORDERED));
#endif
-
TRACE_DBG("op_name <%s> (cmd %p), direction=%d "
- "(expected %d, set %s), bufflen=%d, out_bufflen=%d (expected "
- "len %d, out expected len %d), flags=0x%x", cmd->op_name, cmd,
- cmd->data_direction, cmd->expected_data_direction,
+ "(expected %d, set %s), bufflen=%d, data_len %d, out_bufflen=%d "
+ "(expected len %d, out expected len %d), flags=0x%x", cmd->op_name,
+ cmd, cmd->data_direction, cmd->expected_data_direction,
scst_cmd_is_expected_set(cmd) ? "yes" : "no",
- cmd->bufflen, cmd->out_bufflen, cmd->expected_transfer_len,
- cmd->expected_out_transfer_len, cmd->op_flags);
+ cmd->bufflen, cmd->data_len, cmd->out_bufflen,
+ cmd->expected_transfer_len, cmd->expected_out_transfer_len,
+ cmd->op_flags);
res = 0;
@@ -611,6 +611,7 @@ static int scst_parse_cmd(struct scst_cmd *cmd)
cmd->expected_out_transfer_len);
cmd->data_direction = cmd->expected_data_direction;
cmd->bufflen = cmd->expected_transfer_len;
+ cmd->data_len = cmd->bufflen;
cmd->out_bufflen = cmd->expected_out_transfer_len;
} else {
PRINT_ERROR("Unknown opcode 0x%02x for %s and "
@@ -649,14 +650,6 @@ static int scst_parse_cmd(struct scst_cmd *cmd)
EXTRACHECKS_BUG_ON(cmd->cdb_len == 0);
- TRACE(TRACE_SCSI, "op_name <%s> (cmd %p), direction=%d "
- "(expected %d, set %s), bufflen=%d, out_bufflen=%d, (expected "
- "len %d, out expected len %d), flags=%x", cmd->op_name, cmd,
- cmd->data_direction, cmd->expected_data_direction,
- scst_cmd_is_expected_set(cmd) ? "yes" : "no",
- cmd->bufflen, cmd->out_bufflen, cmd->expected_transfer_len,
- cmd->expected_out_transfer_len, cmd->op_flags);
-
if (unlikely((cmd->op_flags & SCST_UNKNOWN_LENGTH) != 0)) {
if (scst_cmd_is_expected_set(cmd)) {
/*
@@ -669,6 +662,7 @@ static int scst_parse_cmd(struct scst_cmd *cmd)
*/
cmd->bufflen = min(cmd->expected_transfer_len,
15*1024*1024);
+ cmd->data_len = cmd->bufflen;
if (cmd->data_direction == SCST_DATA_BIDI)
cmd->out_bufflen = min(cmd->expected_out_transfer_len,
15*1024*1024);
@@ -741,6 +735,7 @@ static int scst_parse_cmd(struct scst_cmd *cmd)
cmd->cdb, cmd->cdb_len);
cmd->data_direction = cmd->expected_data_direction;
cmd->bufflen = cmd->expected_transfer_len;
+ cmd->data_len = cmd->bufflen;
cmd->out_bufflen = cmd->expected_out_transfer_len;
cmd->resid_possible = 1;
}
@@ -799,10 +794,14 @@ static int scst_parse_cmd(struct scst_cmd *cmd)
goto out_hw_error;
}
-set_res:
- if (cmd->data_len == -1)
- cmd->data_len = cmd->bufflen;
+ if (unlikely(cmd->op_flags & SCST_UNKNOWN_LBA)) {
+ PRINT_ERROR("Unknown LBA (opcode 0x%x, handler %s, "
+ "target %s)", cmd->cdb[0], devt->name, cmd->tgtt->name);
+ PRINT_BUFFER("Failed CDB", cmd->cdb, cmd->cdb_len);
+ goto out_hw_error;
+ }
+set_res:
if (cmd->bufflen == 0) {
/*
* According to SPC bufflen 0 for data transfer commands isn't
@@ -811,6 +810,15 @@ set_res:
cmd->data_direction = SCST_DATA_NONE;
}
+ TRACE(TRACE_SCSI, "op_name <%s> (cmd %p), direction=%d "
+ "(expected %d, set %s), bufflen=%d, data len %d, out_bufflen=%d, "
+ "(expected len %d, out expected len %d), flags=0x%x, lba=%lld",
+ cmd->op_name, cmd, cmd->data_direction, cmd->expected_data_direction,
+ scst_cmd_is_expected_set(cmd) ? "yes" : "no",
+ cmd->bufflen, cmd->data_len, cmd->out_bufflen,
+ cmd->expected_transfer_len, cmd->expected_out_transfer_len,
+ cmd->op_flags, (unsigned long long)cmd->lba);
+
#ifdef CONFIG_SCST_EXTRACHECKS
switch (state) {
case SCST_CMD_STATE_PREPARE_SPACE:
@@ -871,6 +879,23 @@ set_res:
#endif
out:
+#ifdef CONFIG_SCST_EXTRACHECKS
+ /*
+ * At this point either data_len must be initialized, or cmd
+ * completed (with an error).
+ */
+ if (unlikely((cmd->data_len == SCST_DEF_DATA_LEN)) &&
+ (!cmd->completed || ((cmd->state <= SCST_CMD_STATE_REAL_EXEC) &&
+ (cmd->state != SCST_CMD_STATE_PREPROCESSING_DONE)))) {
+ PRINT_CRIT_ERROR("Not initialized data_len for going to "
+ "execute command (cmd %p, data_len %d, completed %d, "
+ "state %d)", cmd, cmd->data_len, cmd->completed,
+ cmd->state);
+ WARN_ON(1);
+ goto out_hw_error;
+ }
+#endif
+
TRACE_EXIT_HRES(res);
return res;
@@ -950,8 +975,8 @@ static int scst_prepare_space(struct scst_cmd *cmd)
goto out;
}
- TRACE_DBG("Calling dev handler %s (%p) alloc_data_buf(%p)",
- devt->name, devt, cmd);
+ TRACE_DBG("Calling dev handler's %s alloc_data_buf(%p)",
+ devt->name, cmd);
scst_set_cur_start(cmd);
state = devt->alloc_data_buf(cmd);
/*
@@ -2701,6 +2726,8 @@ static int scst_pre_exec_checks(struct scst_cmd *cmd)
TRACE_ENTRY();
+ EXTRACHECKS_BUG_ON(cmd->data_len == SCST_DEF_DATA_LEN);
+
rc = __scst_check_local_events(cmd, false);
if (unlikely(rc != 0))
goto out_done;
diff --git a/usr/fileio/common.c b/usr/fileio/common.c
index 5c3ae9150..412399327 100644
--- a/usr/fileio/common.c
+++ b/usr/fileio/common.c
@@ -123,6 +123,7 @@ static int do_parse(struct vdisk_cmd *vcmd)
reply->queue_type = cmd->queue_type;
reply->data_direction = cmd->expected_data_direction;
+ reply->lba = cmd->lba;
reply->data_len = cmd->expected_transfer_len;
reply->bufflen = cmd->expected_transfer_len;
reply->out_bufflen = cmd->expected_out_transfer_len;
@@ -177,8 +178,8 @@ static int do_exec(struct vdisk_cmd *vcmd)
struct vdisk_dev *dev = vcmd->dev;
struct scst_user_scsi_cmd_exec *cmd = &vcmd->cmd->exec_cmd;
struct scst_user_scsi_cmd_reply_exec *reply = &vcmd->reply->exec_reply;
- uint64_t lba_start = 0;
- loff_t data_len = 0;
+ uint64_t lba_start = cmd->lba;
+ loff_t data_len = cmd->data_len;
uint8_t *cdb = cmd->cdb;
int opcode = cdb[0];
loff_t loff;
@@ -241,55 +242,6 @@ static int do_exec(struct vdisk_cmd *vcmd)
if (cmd->data_direction & SCST_DATA_READ)
reply->resp_data_len = cmd->bufflen;
- switch (opcode) {
- case READ_6:
- case WRITE_6:
- lba_start = (((cdb[1] & 0x1f) << (BYTE * 2)) +
- (cdb[2] << (BYTE * 1)) +
- (cdb[3] << (BYTE * 0)));
- data_len = cmd->bufflen;
- break;
- case READ_10:
- case READ_12:
- case WRITE_10:
- case WRITE_12:
- case VERIFY:
- case WRITE_VERIFY:
- case WRITE_VERIFY_12:
- case VERIFY_12:
- lba_start |= ((uint64_t)cdb[2]) << 24;
- lba_start |= ((uint64_t)cdb[3]) << 16;
- lba_start |= ((uint64_t)cdb[4]) << 8;
- lba_start |= ((uint64_t)cdb[5]);
- data_len = cmd->bufflen;
- break;
- case SYNCHRONIZE_CACHE:
- lba_start |= ((uint64_t)cdb[2]) << 24;
- lba_start |= ((uint64_t)cdb[3]) << 16;
- lba_start |= ((uint64_t)cdb[4]) << 8;
- lba_start |= ((uint64_t)cdb[5]);
- data_len = ((cdb[7] << (BYTE * 1)) + (cdb[8] << (BYTE * 0)))
- << dev->block_shift;
- if (data_len == 0)
- data_len = dev->file_size -
- ((loff_t)lba_start << dev->block_shift);
- break;
- case READ_16:
- case WRITE_16:
- case WRITE_VERIFY_16:
- case VERIFY_16:
- lba_start |= ((uint64_t)cdb[2]) << 56;
- lba_start |= ((uint64_t)cdb[3]) << 48;
- lba_start |= ((uint64_t)cdb[4]) << 40;
- lba_start |= ((uint64_t)cdb[5]) << 32;
- lba_start |= ((uint64_t)cdb[6]) << 24;
- lba_start |= ((uint64_t)cdb[7]) << 16;
- lba_start |= ((uint64_t)cdb[8]) << 8;
- lba_start |= ((uint64_t)cdb[9]);
- data_len = cmd->bufflen;
- break;
- }
-
loff = (loff_t)lba_start << dev->block_shift;
TRACE_DBG("cmd %d, buf %"PRIx64", lba_start %"PRId64", loff %"PRId64
", data_len %"PRId64, vcmd->cmd->cmd_h, cmd->pbuf, lba_start,
@@ -381,6 +333,9 @@ static int do_exec(struct vdisk_cmd *vcmd)
case SYNCHRONIZE_CACHE:
{
int immed = cdb[1] & 0x2;
+ if (data_len == 0)
+ data_len = dev->file_size -
+ ((loff_t)lba_start << dev->block_shift);
TRACE(TRACE_ORDER, "SYNCHRONIZE_CACHE: "
"loff=%"PRId64", data_len=%"PRId64", immed=%d",
(uint64_t)loff, (uint64_t)data_len, immed);
@@ -1658,7 +1613,7 @@ static void exec_verify(struct vdisk_cmd *vcmd, loff_t loff)
struct scst_user_scsi_cmd_reply_exec *reply = &vcmd->reply->exec_reply;
loff_t err;
int length = cmd->bufflen;
- uint8_t *address = (uint8_t*)(unsigned long)cmd->pbuf;
+ uint8_t *address = (uint8_t *)(unsigned long)cmd->pbuf;
int compare;
int fd = vcmd->fd;
uint8_t mem_verify[128*1024];