Reorganized getting CDB info (scst_get_cdb_info()) to make it more

peformance effective. Mostly done by Ming Zhang.


git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@55 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2006-12-14 15:52:16 +00:00
parent 426e0474e0
commit d01eacc4d2
2 changed files with 298 additions and 345 deletions

View File

@@ -20,7 +20,17 @@
#ifndef __SCST_CDBPROBE_H
#define __SCST_CDBPROBE_H
#define SCST_BLOCK_LIMIT_LEN 6
/* get_trans_len_x extract x bytes from cdb as length starting from off */
static uint32_t get_trans_len_1(const uint8_t *cdb, uint8_t off);
static uint32_t get_trans_len_2(const uint8_t *cdb, uint8_t off);
static uint32_t get_trans_len_3(const uint8_t *cdb, uint8_t off);
static uint32_t get_trans_len_4(const uint8_t *cdb, uint8_t off);
/* for special commands */
static uint32_t get_trans_len_block_limit(const uint8_t *cdb, uint8_t off);
static uint32_t get_trans_len_read_capacity(const uint8_t *cdb, uint8_t off);
static uint32_t get_trans_len_single(const uint8_t *cdb, uint8_t off);
static uint32_t get_trans_len_none(const uint8_t *cdb, uint8_t off);
/*
+=====================================-============-======-
@@ -68,14 +78,15 @@ struct scst_sdbops
uint8_t direction; /* init --> target: SCST_DATA_WRITE
* target --> init: SCST_DATA_READ
*/
uint8_t size_field_len; /* how many bytes using for data */
uint8_t fixed; /* opcode -- have fixed variable bit ??? */
uint8_t flag1; /* Note 1 */
uint8_t flag2;
};
uint8_t flags; /* opcode -- various flags */
uint8_t off; /* length offset in cdb */
uint32_t (*get_trans_len)(const uint8_t *cdb, uint8_t off) __attribute__ ((aligned));
} __attribute__((packed));
static int scst_scsi_op_list[256];
#define FLAG_NONE 0
static const struct scst_sdbops scst_scsi_op_table[] = {
/*
* +-------------------> TYPE_IS_DISK (0)
@@ -94,413 +105,406 @@ static const struct scst_sdbops scst_scsi_op_table[] = {
* || | | || |
* || | | || |
* 0123456789ABCDEF ---> TYPE_IS_???? */
/* 6-bytes length CDB */
{0x00, "MMMMMMMMMMMMMMMM", "TEST UNIT READY",
SCST_DATA_NONE, 0, SCST_SMALL_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_SMALL_TIMEOUT, 0, get_trans_len_none},
{0x01, " M ", "REWIND",
SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
{0x01, "O V OO OO ", "REZERO UNIT",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x02, "VVVVVV V ", "REQUEST BLOCK ADDR",
SCST_DATA_NONE, 0, SCST_SMALL_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_SMALL_TIMEOUT, 0, get_trans_len_none},
{0x03, "MMMMMMMMMMMMMMMM", "REQUEST SENSE",
SCST_DATA_READ, 1, SCST_SMALL_TIMEOUT, 0, 0},
SCST_DATA_READ, SCST_SMALL_TIMEOUT, 4, get_trans_len_1},
{0x04, "M O O ", "FORMAT UNIT",
SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0}, /*-*/
SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
{0x04, " O ", "FORMAT",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x05, "VMVVVV V ", "READ BLOCK LIMITS",
SCST_DATA_READ, 1, SCST_SMALL_TIMEOUT, 0, 0},
SCST_DATA_READ, SCST_SMALL_TIMEOUT, 0, get_trans_len_block_limit},
{0x06, "VVVVVV V ", "",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x07, " O ", "INITIALIZE ELEMENT STATUS",
SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
{0x07, "OVV O OV ", "REASSIGN BLOCKS",
SCST_DATA_NONE, 0, 0, 0, 0}, /*-*/
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x08, "O ", "READ(6)",
SCST_DATA_READ, 1, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0},
SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED, 4, get_trans_len_1},
{0x08, " MV OO OV ", "READ(6)",
SCST_DATA_READ, 3, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0},
SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED, 2, get_trans_len_3},
{0x08, " M ", "GET MESSAGE(6)",
SCST_DATA_READ, 3, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 2, get_trans_len_3},
{0x08, " O ", "RECEIVE",
SCST_DATA_READ, 3, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 2, get_trans_len_3},
{0x09, "VVVVVV V ", "",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x0A, "O ", "WRITE(6)",
SCST_DATA_WRITE, 1, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0},
SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 4, get_trans_len_1},
{0x0A, " M O OV ", "WRITE(6)",
SCST_DATA_WRITE, 3, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0},
SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 2, get_trans_len_3},
{0x0A, " M ", "PRINT",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x0A, " M ", "SEND MESSAGE(6)",
SCST_DATA_WRITE, 3, 0, 0, 0},
SCST_DATA_WRITE, FLAG_NONE, 2, get_trans_len_3},
{0x0A, " M ", "SEND(6)",
SCST_DATA_WRITE, 3, 0, 0, 0},
SCST_DATA_WRITE, FLAG_NONE, 2, get_trans_len_3},
{0x0B, "O OO OV ", "SEEK(6)",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x0B, " ", "TRACK SELECT",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x0B, " O ", "SLEW AND PRINT",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x0C, "VVVVVV V ", "SEEK BLOCK",
SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
{0x0D, "VVVVVV V ", "PARTITION",
SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
{0x0E, "VVVVVV V ", "",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x0F, "VOVVVV V ", "READ REVERSE",
SCST_DATA_READ, 3, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0},
SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED, 2, get_trans_len_3},
{0x10, "VM V V ", "WRITE FILEMARKS",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x10, " O O ", "SYNCHRONIZE BUFFER",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x11, "VMVVVV ", "SPACE",
SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
{0x12, "MMMMMMMMMMMMMMMM", "INQUIRY",
SCST_DATA_READ, 1, SCST_SMALL_TIMEOUT, 0, 0},
SCST_DATA_READ, SCST_SMALL_TIMEOUT, 4, get_trans_len_1},
{0x13, "VOVVVV ", "VERIFY(6)",
SCST_DATA_WRITE, 3, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0},
SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 2, get_trans_len_3},
{0x14, "VOOVVV ", "RECOVER BUFFERED DATA",
SCST_DATA_READ, 3, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0},
SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED, 2, get_trans_len_3},
{0x15, "OMOOOOOOOOOOOOOO", "MODE SELECT(6)",
SCST_DATA_WRITE, 1, 0, 0, 0}, /*N6! */
SCST_DATA_WRITE, FLAG_NONE, 4, get_trans_len_1},
{0x16, "MMMMMMMMMMMMMMMM", "RESERVE",
SCST_DATA_NONE, 0, SCST_SMALL_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_SMALL_TIMEOUT, 0, get_trans_len_none},
{0x17, "MMMMMMMMMMMMMMMM", "RELEASE",
SCST_DATA_NONE, 0, SCST_SMALL_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_SMALL_TIMEOUT, 0, get_trans_len_none},
{0x18, "OOOOOOOO ", "COPY",
SCST_DATA_WRITE, 1, SCST_LONG_TIMEOUT, 0, 0}, /*N5! */
SCST_DATA_WRITE, SCST_LONG_TIMEOUT, 2, get_trans_len_3},
{0x19, "VMVVVV ", "ERASE",
SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
{0x1A, "OMOOOOOOOOOOOOOO", "MODE SENSE(6)",
SCST_DATA_READ, 1, SCST_SMALL_TIMEOUT, 0, 0},
SCST_DATA_READ, SCST_SMALL_TIMEOUT, 4, get_trans_len_1},
{0x1B, " O ", "SCAN",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x1B, " O ", "LOAD UNLOAD",
SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
{0x1B, " O ", "STOP PRINT",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x1B, "O OO O O ", "STOP START UNIT",
SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
{0x1C, "OOOOOOOOOOOOOOOO", "RECEIVE DIAGNOSTIC RESULTS",
SCST_DATA_READ, 1, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 4, get_trans_len_1},
{0x1D, "MMMMMMMMMMMMMMMM", "SEND DIAGNOSTIC",
SCST_DATA_WRITE, 1, 0, 0, 0},
SCST_DATA_WRITE, FLAG_NONE, 4, get_trans_len_1},
{0x1E, "OOOOOOOOOOOOOOOO", "PREVENT ALLOW MEDIUM REMOVAL",
SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
{0x1F, " O ", "PORT STATUS",
SCST_DATA_NONE, 0, 0, 0, 0},
/* 10-bytes length CDB */
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
/* 10-bytes length CDB */
{0x20, "V VV V ", "",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x21, "V VV V ", "",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x22, "V VV V ", "",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x23, "V VV V ", "READ FORMAT CAPACITY",
SCST_DATA_READ, 2, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
{0x24, "V VVM ", "SET WINDOW",
SCST_DATA_WRITE, 3, 0, 0, 0}, /*-*/
SCST_DATA_WRITE, FLAG_NONE, 6, get_trans_len_3},
{0x25, "M MM M ", "READ CAPACITY",
SCST_DATA_READ, 0, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 0, get_trans_len_read_capacity},
{0x25, " O ", "GET WINDOW",
SCST_DATA_READ, 3, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 6, get_trans_len_3},
{0x26, "V VV ", "",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x27, "V VV ", "",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x28, "M MMMM ", "READ(10)",
SCST_DATA_READ, 2, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0},
SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED, 7, get_trans_len_2},
{0x28, " O ", "GET MESSAGE(10)",
SCST_DATA_READ, 2, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
{0x29, "V VV O ", "READ GENERATION",
SCST_DATA_READ, 1, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 8, get_trans_len_1},
{0x2A, "O MO M ", "WRITE(10)",
SCST_DATA_WRITE, 2, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0},
SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 7, get_trans_len_2},
{0x2A, " O ", "SEND MESSAGE(10)",
SCST_DATA_WRITE, 2, 0, 0, 0},
SCST_DATA_WRITE, FLAG_NONE, 7, get_trans_len_2},
{0x2A, " O ", "SEND(10)",
SCST_DATA_WRITE, 2, 0, 0, 0},
SCST_DATA_WRITE, FLAG_NONE, 7, get_trans_len_2},
{0x2B, " O ", "LOCATE",
SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
{0x2B, " O ", "POSITION TO ELEMENT",
SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
{0x2B, "O OO O ", "SEEK(10)",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x2C, "V O O ", "ERASE(10)",
SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
{0x2D, "V O O ", "READ UPDATED BLOCK",
SCST_DATA_READ, 1, 0, 0, 0}, /*N2! */
SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED, 0, get_trans_len_single},
{0x2E, "O OO O ", "WRITE AND VERIFY(10)",
SCST_DATA_WRITE, 2, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0},
SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 7, get_trans_len_2},
{0x2F, "O OO O ", "VERIFY(10)",
SCST_DATA_WRITE, 2, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0},
/*-*/
SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 7, get_trans_len_2},
/*
{0x30, "O OO O ", "SEARCH DATA HIGH(10)",
SCST_DATA_NONE, 0, SCST_UNKNOWN_LENGTH, 1, 0}, /*-*/
SCST_DATA_NONE, SCST_UNKNOWN_LENGTH, 0, get_trans_len_none},
{0x31, " O ", "OBJECT POSITION",
SCST_DATA_NONE, 0, SCST_UNKNOWN_LENGTH, 1, 0}, /*N1! */
SCST_DATA_NONE, SCST_UNKNOWN_LENGTH, 0, get_trans_len_none},
{0x31, "O OO O ", "SEARCH DATA EQUAL(10)",
SCST_DATA_NONE, 0, SCST_UNKNOWN_LENGTH, 1, 0}, /*-*/
SCST_DATA_NONE, SCST_UNKNOWN_LENGTH, 0, get_trans_len_none},
{0x32, "O OO O ", "SEARCH DATA LOW(10)",
SCST_DATA_NONE, 0, SCST_UNKNOWN_LENGTH, 1, 0}, /*-*/
SCST_DATA_NONE, SCST_UNKNOWN_LENGTH, 0, get_trans_len_none},
*/
{0x33, "O OO O ", "SET LIMITS(10)",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x34, " O ", "READ POSITION",
SCST_DATA_READ, 1, SCST_SMALL_TIMEOUT, 0, 0}, /*N4! */
SCST_DATA_READ, SCST_SMALL_TIMEOUT, 7, get_trans_len_2},
{0x34, " O ", "GET DATA BUFFER STATUS",
SCST_DATA_READ, 2, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
{0x34, "O OO O ", "PRE-FETCH",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x35, "O OO O ", "SYNCHRONIZE CACHE",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x36, "O OO O ", "LOCK UNLOCK CACHE",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x37, "O O ", "READ DEFECT DATA(10)",
SCST_DATA_READ, 1, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 8, get_trans_len_1},
{0x38, " O O ", "MEDIUM SCAN",
SCST_DATA_READ, 1, 0, 0, 0}, /*-*/
SCST_DATA_READ, FLAG_NONE, 8, get_trans_len_1},
{0x39, "OOOOOOOO ", "COMPARE",
SCST_DATA_WRITE, 1, 0, 0, 0}, /*N3! */
SCST_DATA_WRITE, FLAG_NONE, 3, get_trans_len_3},
{0x3A, "OOOOOOOO ", "COPY AND VERIFY",
SCST_DATA_WRITE, 1, 0, 0, 0}, /*N3!? */
SCST_DATA_WRITE, FLAG_NONE, 3, get_trans_len_3},
{0x3B, "OOOOOOOOOOOOOOOO", "WRITE BUFFER",
SCST_DATA_WRITE, 3, SCST_SMALL_TIMEOUT, 0, 0},
SCST_DATA_WRITE, SCST_SMALL_TIMEOUT, 6, get_trans_len_3},
{0x3C, "OOOOOOOOOOOOOOOO", "READ BUFFER",
SCST_DATA_READ, 3, SCST_SMALL_TIMEOUT, 0, 0},
SCST_DATA_READ, SCST_SMALL_TIMEOUT, 6, get_trans_len_3},
{0x3D, " O O ", "UPDATE BLOCK",
SCST_DATA_WRITE, 1, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0}, /*N2! */
SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 0, get_trans_len_single},
{0x3E, "O OO O ", "READ LONG",
SCST_DATA_READ, 1, 0, 0, 0}, /*N6! */
SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
{0x3F, "O O O ", "WRITE LONG",
SCST_DATA_WRITE, 1, 0, 0, 0}, /*N6! */
SCST_DATA_WRITE, FLAG_NONE, 7, get_trans_len_2},
{0x40, "OOOOOOOOOO ", "CHANGE DEFINITION",
SCST_DATA_WRITE, 1, SCST_SMALL_TIMEOUT, 0, 0},
SCST_DATA_WRITE, SCST_SMALL_TIMEOUT, 8, get_trans_len_1},
{0x41, "O O ", "WRITE SAME",
SCST_DATA_WRITE, 0, SCST_UNKNOWN_LENGTH, 1, 0}, /*N2! */
SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 0, get_trans_len_single},
{0x42, " O ", "READ SUB-CHANNEL",
SCST_DATA_READ, 2, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
{0x43, " O ", "READ TOC/PMA/ATIP",
SCST_DATA_READ, 2, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
{0x44, " O ", "READ HEADER",
SCST_DATA_READ, 2, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
{0x45, " O ", "PLAY AUDIO(10)",
SCST_DATA_READ, 2, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0}, /*N8! */
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x46, " O ", "GET CONFIGURATION",
SCST_DATA_READ, 2, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
{0x47, " O ", "PLAY AUDIO MSF",
SCST_DATA_READ, 0, SCST_UNKNOWN_LENGTH, 1, 0}, /*? */
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x48, " O ", "PLAY AUDIO TRACK INDEX",
SCST_DATA_READ, 0, SCST_UNKNOWN_LENGTH, 1, 0}, /*? */
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x49, " O ", "PLAY TRACK RELATIVE(10)",
SCST_DATA_READ, 2, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0}, /*N8! */
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x4A, " O ", "GET EVENT STATUS NOTIFICATION",
SCST_DATA_READ, 2, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
{0x4B, " O ", "PAUSE/RESUME",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x4C, "OOOOOOOOOOOOOOOO", "LOG SELECT",
SCST_DATA_WRITE, 2, SCST_SMALL_TIMEOUT, 0, 0}, /*N6! */
SCST_DATA_WRITE, SCST_SMALL_TIMEOUT, 7, get_trans_len_2},
{0x4D, "OOOOOOOOOOOOOOOO", "LOG SENSE",
SCST_DATA_READ, 2, SCST_SMALL_TIMEOUT, 0, 0}, /*N6! */
SCST_DATA_READ, SCST_SMALL_TIMEOUT, 7, get_trans_len_2},
{0x4E, " O ", "STOP PLAY/SCAN",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x4F, " ", "",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x50, " ", "XDWRITE",
SCST_DATA_NONE, 0, 0, 0, 0}, /*-*/
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x51, " O ", "READ DISC INFORMATION",
SCST_DATA_READ, 2, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
{0x51, " ", "XPWRITE",
SCST_DATA_NONE, 0, 0, 0, 0}, /*-*/
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x52, " O ", "READ TRACK INFORMATION",
SCST_DATA_READ, 2, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
{0x53, " O ", "RESERVE TRACK",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x54, " O ", "SEND OPC INFORMATION",
SCST_DATA_WRITE, 2, 0, 0, 0},
SCST_DATA_WRITE, FLAG_NONE, 7, get_trans_len_2},
{0x55, "OOOOOOOOOOOOOOOO", "MODE SELECT(10)",
SCST_DATA_WRITE, 2, 0, 0, 0},
SCST_DATA_WRITE, FLAG_NONE, 7, get_trans_len_2},
{0x56, "OOOOOOOOOOOOOOOO", "RESERVE(10)",
SCST_DATA_NONE, 0, SCST_SMALL_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_SMALL_TIMEOUT, 0, get_trans_len_none},
{0x57, "OOOOOOOOOOOOOOOO", "RELEASE(10)",
SCST_DATA_NONE, 0, SCST_SMALL_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_SMALL_TIMEOUT, 0, get_trans_len_none},
{0x58, " O ", "REPAIR TRACK",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x59, " ", "",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x5A, "OOOOOOOOOOOOOOOO", "MODE SENSE(10)",
SCST_DATA_READ, 2, SCST_SMALL_TIMEOUT, 0, 0},
SCST_DATA_READ, SCST_SMALL_TIMEOUT, 7, get_trans_len_2},
{0x5B, " O ", "CLOSE TRACK/SESSION",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x5C, " O ", "READ BUFFER CAPACITY",
SCST_DATA_READ, 2, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_2},
{0x5D, " O ", "SEND CUE SHEET",
SCST_DATA_WRITE, 3, 0, 0, 0},
SCST_DATA_WRITE, FLAG_NONE, 6, get_trans_len_3},
{0x5E, " ", "PERSISTENT_RESERV_IN",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x5F, " ", "PERSISTENT_RESERV_OUT",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
/* 16-bytes length CDB */
{0x80, "O OO O ", "XDWRITE EXTENDED",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x80, " M ", "WRITE FILEMARKS",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x81, "O OO O ", "REBUILD",
SCST_DATA_WRITE, 4, 0, 0, 0},
SCST_DATA_WRITE, FLAG_NONE, 10, get_trans_len_4},
{0x82, "O OO O ", "REGENERATE",
SCST_DATA_WRITE, 4, 0, 0, 0},
SCST_DATA_WRITE, FLAG_NONE, 10, get_trans_len_4},
{0x83, "OOOOOOOOOOOOOOOO", "EXTENDED COPY",
SCST_DATA_WRITE, 4, 0, 0, 0},
SCST_DATA_WRITE, FLAG_NONE, 10, get_trans_len_4},
{0x84, "OOOOOOOOOOOOOOOO", "RECEIVE COPY RESULT",
SCST_DATA_WRITE, 4, 0, 0, 0},
SCST_DATA_WRITE, FLAG_NONE, 10, get_trans_len_4},
{0x86, "OOOOOOOOOO ", "ACCESS CONTROL IN",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x87, "OOOOOOOOOO ", "ACCESS CONTROL OUT",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x88, "M MMMM ", "READ(16)",
SCST_DATA_READ, 4, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0},
SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED, 10, get_trans_len_4},
{0x8A, "O OO O ", "WRITE(16)",
SCST_DATA_WRITE, 4, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0},
SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 10, get_trans_len_4},
{0x8C, "OOOOOOOOOO ", "READ ATTRIBUTE",
SCST_DATA_READ, 4, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 10, get_trans_len_4},
{0x8D, "OOOOOOOOOO ", "WRITE ATTRIBUTE",
SCST_DATA_WRITE, 4, 0, 0, 0},
SCST_DATA_WRITE, FLAG_NONE, 10, get_trans_len_4},
{0x8E, "O OO O ", "WRITE AND VERIFY(16)",
SCST_DATA_WRITE, 4, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0},
/*-*/
SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 10, get_trans_len_4},
{0x8F, "O OO O ", "VERIFY(16)",
SCST_DATA_WRITE, 4, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0}, /*? */
SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 10, get_trans_len_4},
{0x90, "O OO O ", "PRE-FETCH(16)",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x91, "O OO O ", "SYNCHRONIZE CACHE(16)",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x91, " M ", "SPACE(16)",
SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
{0x92, "O OO O ", "LOCK UNLOCK CACHE(16)",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x92, " O ", "LOCATE(16)",
SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
{0x93, "O O ", "WRITE SAME(16)",
SCST_DATA_WRITE, 4, SCST_UNKNOWN_LENGTH, 1, 0}, /*N2! */
SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 10, get_trans_len_4},
{0x93, " M ", "ERASE(16)",
SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
{0x9E, "O ", "SERVICE ACTION IN",
SCST_DATA_READ, 0, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 0, get_trans_len_none},
/* 12-bytes length CDB */
{0xA0, "VVVVVVVVVV M ", "REPORT LUN",
SCST_DATA_READ, 4, SCST_SMALL_TIMEOUT, 0, 0}, /*N7! */
SCST_DATA_READ, SCST_SMALL_TIMEOUT, 6, get_trans_len_4},
{0xA1, " O ", "BLANK",
SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
{0xA2, " ", "",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0xA3, " O ", "SEND KEY",
SCST_DATA_WRITE, 2, 0, 0, 0},
SCST_DATA_WRITE, FLAG_NONE, 8, get_trans_len_2},
{0xA3, "OOOOO OOOO ", "REPORT DEVICE IDENTIDIER",
SCST_DATA_READ, 4, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 6, get_trans_len_4},
{0xA3, " M ", "MAINTENANCE(IN)",
SCST_DATA_READ, 4, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 6, get_trans_len_4},
{0xA4, " O ", "REPORT KEY",
SCST_DATA_READ, 2, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 8, get_trans_len_2},
{0xA4, " O ", "MAINTENANCE(OUT)",
SCST_DATA_WRITE, 4, 0, 0, 0},
SCST_DATA_WRITE, FLAG_NONE, 6, get_trans_len_4},
{0xA5, " M ", "MOVE MEDIUM",
SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
{0xA5, " O ", "PLAY AUDIO(12)",
SCST_DATA_READ, 4, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0}, /*N8! */
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0xA6, " O O ", "EXCHANGE/LOAD/UNLOAD MEDIUM",
SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
{0xA7, " O ", "SET READ AHEAD",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0xA8, " O ", "GET MESSAGE(12)",
SCST_DATA_READ, 4, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 6, get_trans_len_4},
{0xA8, "O OO O ", "READ(12)",
SCST_DATA_READ, 4, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0},
SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED, 6, get_trans_len_4},
{0xA9, " O ", "PLAY TRACK RELATIVE(12)",
SCST_DATA_READ, 4, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0}, /*N8*! */
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0xAA, "O OO O ", "WRITE(12)",
SCST_DATA_WRITE, 4, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0},
SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 6, get_trans_len_4},
{0xAA, " O ", "SEND MESSAGE(12)",
SCST_DATA_WRITE, 4, 0, 0, 0},
SCST_DATA_WRITE, FLAG_NONE, 6, get_trans_len_4},
{0xAB, " ", "",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0xAC, " O ", "ERASE(12)",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0xAC, " O ", "GET PERFORMANCE",
SCST_DATA_READ, 0, SCST_UNKNOWN_LENGTH, 1, 0},
SCST_DATA_READ, SCST_UNKNOWN_LENGTH, 0, get_trans_len_none},
{0xAD, " O ", "READ DVD STRUCTURE",
SCST_DATA_READ, 2, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 8, get_trans_len_2},
{0xAE, "O OO O ", "WRITE AND VERIFY(12)",
SCST_DATA_WRITE, 4, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0},
/*-*/
SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 6, get_trans_len_4},
{0xAF, "O OO O ", "VERIFY(12)",
SCST_DATA_WRITE, 4, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0}, /*? */
SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 6, get_trans_len_4},
/* No need to support at all.
{0xB0, " OO O ", "SEARCH DATA HIGH(12)",
SCST_DATA_WRITE, 1, 0, 0, 0}, /*N9! */
SCST_DATA_WRITE, FLAG_NONE, 9, get_trans_len_1},
{0xB1, " OO O ", "SEARCH DATA EQUAL(12)",
SCST_DATA_WRITE, 1, 0, 0, 0}, /*N9! */
SCST_DATA_WRITE, FLAG_NONE, 9, get_trans_len_1},
{0xB2, " OO O ", "SEARCH DATA LOW(12)",
SCST_DATA_WRITE, 1, 0, 0, 0}, /*N9! */
SCST_DATA_WRITE, FLAG_NONE, 9, get_trans_len_1},
*/
{0xB3, " OO O ", "SET LIMITS(12)",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0xB4, " ", "",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0xB5, " O ", "REQUEST VOLUME ELEMENT ADDRESS",
SCST_DATA_READ, 1, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 9, get_trans_len_1},
{0xB6, " O ", "SEND VOLUME TAG",
SCST_DATA_WRITE, 1, 0, 0, 0},
SCST_DATA_WRITE, FLAG_NONE, 9, get_trans_len_1},
{0xB6, " O ", "SET STREAMING",
SCST_DATA_WRITE, 0, 0, 0, 0},
SCST_DATA_WRITE, FLAG_NONE, 0, get_trans_len_none},
{0xB7, " O ", "READ DEFECT DATA(12)",
SCST_DATA_READ, 1, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 9, get_trans_len_1},
{0xB8, " O ", "READ ELEMENT STATUS",
SCST_DATA_READ, 3, 0, 0, 0}, /*N10 */
SCST_DATA_READ, FLAG_NONE, 7, get_trans_len_3},
{0xB9, " O ", "READ CD MSF",
SCST_DATA_READ, 0, SCST_UNKNOWN_LENGTH, 1, 0},
SCST_DATA_READ, SCST_UNKNOWN_LENGTH, 0, get_trans_len_none},
{0xBA, " O ", "SCAN",
SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0},
SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
{0xBA, " O ", "REDUNDANCY GROUP(IN)",
SCST_DATA_READ, 4, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 6, get_trans_len_4},
{0xBB, " O ", "SET SPEED",
SCST_DATA_NONE, 0, 0, 0, 0},
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0xBB, " O ", "REDUNDANCY GROUP(OUT)",
SCST_DATA_WRITE, 4, 0, 0, 0},
SCST_DATA_WRITE, FLAG_NONE, 6, get_trans_len_4},
{0xBC, " O ", "SPARE(IN)",
SCST_DATA_READ, 4, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 6, get_trans_len_4},
{0xBD, " O ", "MECHANISM STATUS",
SCST_DATA_READ, 2, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 8, get_trans_len_2},
{0xBD, " O ", "SPARE(OUT)",
SCST_DATA_WRITE, 4, 0, 0, 0},
SCST_DATA_WRITE, FLAG_NONE, 6, get_trans_len_4},
{0xBE, " O ", "READ CD",
SCST_DATA_READ, 4, SCST_TRANSFER_LEN_TYPE_FIXED, 0, 0},
SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED, 6, get_trans_len_3},
{0xBE, " O ", "VOLUME SET(IN)",
SCST_DATA_READ, 4, 0, 0, 0},
SCST_DATA_READ, FLAG_NONE, 6, get_trans_len_4},
{0xBF, " O ", "SEND DVD STRUCTUE",
SCST_DATA_WRITE, 2, 0, 0, 0},
SCST_DATA_WRITE, FLAG_NONE, 8, get_trans_len_2},
{0xBF, " O ", "VOLUME SET(OUT)",
SCST_DATA_WRITE, 4, 0, 0, 0},
SCST_DATA_WRITE, FLAG_NONE, 6, get_trans_len_4},
{0xE7, " V ", "INIT ELEMENT STATUS WRANGE",
SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0}
SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none}
};
/* Notes:
N1. - Unknown data len
N2. - Read/Write 1 block data
N3. - SCSI-2 1 byte len, SCSI-3 may be upto 3 bytes AND other location
N4. - Answer 20-bytes block.
N5. - CDB get param list len
N6. - len is bytes only
N7. - SCSI-3 Report Lun?
N8. - fixed length audio mode blocks for CD/DVD use MODE SENSE
N9. - 14-BYTES header + (n * patterns) full length variable
N10. - SCSI-2 use 1byte, mt.c (SCSI-3)? use 3 bytes
Unknown op's:
#define SCSIOP_XDWRITE_EXTENDED 0x80
#define SCSIOP_REBUILD 0x81
#define SCSIOP_EA 0xea
#define WRITE_LONG_2 0xea
Unknown op's:
#define SCSIOP_XDWRITE_EXTENDED 0x80
#define SCSIOP_REBUILD 0x81
#define SCSIOP_EA 0xea
#define WRITE_LONG_2 0xea
*/
#define SCST_CDB_TBL_SIZE ((sizeof(scst_scsi_op_table)/sizeof(struct scst_sdbops)))

View File

@@ -1472,6 +1472,51 @@ int scst_get_cdb_len(const uint8_t *cdb)
return SCST_GET_CDB_LEN(cdb[0]);
}
/* get_trans_len_x extract x bytes from cdb as length starting from off */
static uint32_t get_trans_len_1(const uint8_t *cdb, uint8_t off)
{
return (*(cdb + off));
}
static uint32_t get_trans_len_2(const uint8_t *cdb, uint8_t off)
{
return be16_to_cpu(*((uint16_t *)(cdb + off)));
}
static uint32_t get_trans_len_3(const uint8_t *cdb, uint8_t off)
{
const uint8_t *p = cdb + off;
return ((*p) << 16) + (*(p + 1) << 8) + *(p + 2);
}
static uint32_t get_trans_len_4(const uint8_t *cdb, uint8_t off)
{
return be32_to_cpu(*((uint32_t *)(cdb + off)));
}
/* for special commands */
static uint32_t get_trans_len_block_limit(const uint8_t *cdb, uint8_t off)
{
return 6;
}
static uint32_t get_trans_len_read_capacity(const uint8_t *cdb, uint8_t off)
{
return 8;
}
static uint32_t get_trans_len_single(const uint8_t *cdb, uint8_t off)
{
return 1;
}
static uint32_t get_trans_len_none(const uint8_t *cdb, uint8_t off)
{
return 0;
}
int scst_get_cdb_info(const uint8_t *cdb_p, int dev_type,
struct scst_info_cdb *info_p)
{
@@ -1481,12 +1526,9 @@ int scst_get_cdb_info(const uint8_t *cdb_p, int dev_type,
TRACE_ENTRY();
memset(info_p, 0, sizeof(*info_p));
info_p->direction = SCST_DATA_NONE;
info_p->op_name = "NOOP";
op = *cdb_p; /* get clear opcode */
TRACE(TRACE_SCSI, "opcode=%02x, cdblen=%d bytes, tblsize=%zd, "
TRACE_DBG("opcode=%02x, cdblen=%d bytes, tblsize=%zd, "
"dev_type=%d", op, SCST_GET_CDB_LEN(op), SCST_CDB_TBL_SIZE,
dev_type);
@@ -1494,8 +1536,7 @@ int scst_get_cdb_info(const uint8_t *cdb_p, int dev_type,
while (i < SCST_CDB_TBL_SIZE && scst_scsi_op_table[i].ops == op) {
if (scst_scsi_op_table[i].devkey[dev_type] != SCST_CDB_NOTSUPP) {
ptr = &scst_scsi_op_table[i];
#if 0
TRACE(TRACE_SCSI, "op = 0x%02x+'%c%c%c%c%c%c%c%c%c%c'+<%s>",
TRACE_DBG("op = 0x%02x+'%c%c%c%c%c%c%c%c%c%c'+<%s>",
ptr->ops, ptr->devkey[0], /* disk */
ptr->devkey[1], /* tape */
ptr->devkey[2], /* printer */
@@ -1507,13 +1548,10 @@ int scst_get_cdb_info(const uint8_t *cdb_p, int dev_type,
ptr->devkey[8], /* changer */
ptr->devkey[9], /* commdev */
ptr->op_name);
TRACE(TRACE_SCSI,
"direction=%d size_field_len=%d fixed=%d flag1=%d flag2=%d",
TRACE_DBG("direction=%d flags=%d off=%d",
ptr->direction,
ptr->size_field_len,
ptr->fixed, ptr->flag1, ptr->flag2);
#endif
ptr->flags,
ptr->off);
break;
}
i++;
@@ -1529,135 +1567,24 @@ int scst_get_cdb_info(const uint8_t *cdb_p, int dev_type,
info_p->cdb_len = SCST_GET_CDB_LEN(op);
info_p->op_name = ptr->op_name;
/* 1. direction */
info_p->direction = ptr->direction;
if (info_p->direction == SCST_DATA_NONE)
goto out;
info_p->flags = ptr->flags;
info_p->transfer_len = (*ptr->get_trans_len)(cdb_p, ptr->off);
/* 2. flags */
info_p->flags = ptr->fixed;
/*
* CDB length needed, because we must know offsets:
* 1) for 6-bytes CDB len = 1 byte or 3 bytes(if real transfer exist)
* 2) for 10-bytes CDB len = 1 byte or 2 bytes(0x24,0x25 = 3)
* 3) for 12-bytes CDB len = 1 byte or 4 bytes
*/
/* 3. transfer_len */
if (SCST_GET_CDB_LEN(op) == 6) {
if (ptr->size_field_len == 3) {
/* length = 3 bytes */
info_p->transfer_len = (((*(cdb_p + 2)) & 0xff) << 16) +
(((*(cdb_p + 3)) & 0xff) << 8) +
((*(cdb_p + 4)) & 0xff);
info_p->transfer_len &= 0xffffff;
} else if (ptr->size_field_len == 1) {
/*
* Warning!!! CDB 'READ BLOCK LIMITS'
* always returns 6-byte block with limits
* info_p->transfer_len = (int)(*(cdb_p + 4));
*/
info_p->transfer_len = ((op == READ_BLOCK_LIMITS) ?
SCST_BLOCK_LIMIT_LEN :
*(cdb_p + 4)) & 0xff;
}
} else if (SCST_GET_CDB_LEN(op) == 10) {
if (ptr->size_field_len == 3)
/*
* SET window usees 3 bytes length SET/GET WINDOW
* if ((uint8_t)ptr->ops == 0x24 || 0x25)
*/
{
info_p->transfer_len = (((*(cdb_p + 6)) & 0xff) << 16) +
(((*(cdb_p + 7)) & 0xff) << 8) +
((*(cdb_p + 8)) & 0xff);
info_p->transfer_len &= 0xffffff;
} else if (ptr->size_field_len == 2) {
info_p->transfer_len = (((*(cdb_p + 7)) & 0xff) << 8) +
((*(cdb_p + 8)) & 0xff);
info_p->transfer_len &= 0xffff;
} else if (ptr->size_field_len == 1) {
info_p->transfer_len = (*(cdb_p + 8));
/* opcode = READ-WRITE UPDATED BLOCK */
if ((ptr->ops == UPDATE_BLOCK) ||
(ptr->ops == WRITE_SAME)) {
/* the opcode always returns 1 block */
info_p->flags |= SCST_TRANSFER_LEN_TYPE_FIXED;
info_p->transfer_len = 1;
}
if ((ptr->ops == COMPARE) || (ptr->ops == COPY_VERIFY)) {
/* ese other place in CDB [3,4],5 */
info_p->transfer_len = (*(cdb_p + 5));
}
info_p->transfer_len &= 0xff;
}
} else if (SCST_GET_CDB_LEN(op) == 12) {
if (ptr->size_field_len == 4) {
info_p->transfer_len = (((*(cdb_p + 6)) & 0xff) << 24) +
(((*(cdb_p + 7)) & 0xff) << 16) +
(((*(cdb_p + 8)) & 0xff) << 8) +
((*(cdb_p + 9)) & 0xff);
info_p->transfer_len &= 0xffffffff;
} else if (ptr->size_field_len == 3) {
info_p->transfer_len = (((*(cdb_p + 7)) & 0xff) << 16) +
(((*(cdb_p + 8)) & 0xff) << 8) +
((*(cdb_p + 9)) & 0xff);
info_p->transfer_len &= 0xffffff;
} else if (ptr->size_field_len == 2) {
info_p->transfer_len = (((*(cdb_p + 8)) & 0xff) << 8) +
((*(cdb_p + 9)) & 0xff);
info_p->transfer_len &= 0xffff;
} else {
if (ptr->size_field_len == 1) {
info_p->transfer_len = (*(cdb_p + 9));
info_p->transfer_len &= 0xff;
}
}
} else if (SCST_GET_CDB_LEN(op) == 16) {
if (ptr->size_field_len == 4) {
info_p->transfer_len =
(((*(cdb_p + 10)) & 0xff) << 24) +
(((*(cdb_p + 11)) & 0xff) << 16) +
(((*(cdb_p + 12)) & 0xff) << 8) +
((*(cdb_p + 13)) & 0xff);
}
}
if (!info_p->transfer_len) {
#ifdef EXTRACHECKS
if (unlikely((info_p->transfer_len == 0) &&
(info_p->direction != SCST_DATA_NONE))) {
TRACE_DBG("Warning! transfer_len 0, direction %d change on %d",
info_p->direction, SCST_DATA_NONE);
info_p->direction = SCST_DATA_NONE;
}
#endif
out:
TRACE_EXIT();
return res;
}
void scst_scsi_op_list_init(void)
{
int i;
uint8_t op = 0xff;
TRACE_ENTRY();
for (i = 0; i < 256; i++)
scst_scsi_op_list[i] = SCST_CDB_TBL_SIZE;
for (i = 0; i < SCST_CDB_TBL_SIZE; i++) {
if (scst_scsi_op_table[i].ops != op) {
op = scst_scsi_op_table[i].ops;
scst_scsi_op_list[op] = i;
}
}
TRACE_EXIT();
return;
}
/*
* Routine to extract a lun number from an 8-byte LUN structure
* in network byte order (BE).
@@ -2234,6 +2161,28 @@ void scst_inc_expected_sn_unblock(struct scst_tgt_dev *tgt_dev,
return;
}
void __init scst_scsi_op_list_init(void)
{
int i;
uint8_t op = 0xff;
TRACE_ENTRY();
for (i = 0; i < 256; i++)
scst_scsi_op_list[i] = SCST_CDB_TBL_SIZE;
for (i = 0; i < SCST_CDB_TBL_SIZE; i++) {
if (scst_scsi_op_table[i].ops != op) {
op = scst_scsi_op_table[i].ops;
scst_scsi_op_list[op] = i;
}
}
TRACE_EXIT();
return;
}
#ifdef DEBUG
/* Original taken from the XFS code */
unsigned long scst_random(void)