From: <vl...@us...> - 2006-12-14 15:52:22
|
Revision: 55 http://svn.sourceforge.net/scst/?rev=55&view=rev Author: vlnb Date: 2006-12-14 07:52:16 -0800 (Thu, 14 Dec 2006) Log Message: ----------- Reorganized getting CDB info (scst_get_cdb_info()) to make it more peformance effective. Mostly done by Ming Zhang. Modified Paths: -------------- trunk/scst/src/scst_cdbprobe.h trunk/scst/src/scst_lib.c Modified: trunk/scst/src/scst_cdbprobe.h =================================================================== --- trunk/scst/src/scst_cdbprobe.h 2006-12-14 15:42:11 UTC (rev 54) +++ trunk/scst/src/scst_cdbprobe.h 2006-12-14 15:52:16 UTC (rev 55) @@ -20,8 +20,18 @@ #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); + /* +=====================================-============-======- | Command name | Operation | Type | @@ -68,14 +78,15 @@ 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 @@ * || | | || | * || | | || | * 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))) Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2006-12-14 15:42:11 UTC (rev 54) +++ trunk/scst/src/scst_lib.c 2006-12-14 15:52:16 UTC (rev 55) @@ -1472,6 +1472,51 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |