From 8dc8632aa7bf1de7a56daea56a7011cbfff76678 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Wed, 26 Jun 2013 17:36:19 -0700 Subject: target: Add (obsolete) checking for PMI/LBA fields in READ CAPACITY(10) The SBC-2 specification of READ CAPACITY(10) has PMI and LOGICAL BLOCK ADDRESS fields in the CDB; in SBC-3 these fields are simply listed as obsolete. However, SBC-2 also has the language If the PMI bit is set to zero and the LOGICAL BLOCK ADDRESS field is not set to zero, the device server shall terminate the command with CHECK CONDITION status with the sense key set to ILLEGAL REQUEST and the additional sense code set to INVALID FIELD IN CDB. and in fact at least the Windows SCSI compliance test checks this behavior. Since no one following SBC-3 is going to set these fields, we might as well include the check from SBC-2 and pass this test. Signed-off-by: Roland Dreier Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_sbc.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index ee0cb9d9692..8a462773d0c 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c @@ -38,11 +38,27 @@ static sense_reason_t sbc_emulate_readcapacity(struct se_cmd *cmd) { struct se_device *dev = cmd->se_dev; + unsigned char *cdb = cmd->t_task_cdb; unsigned long long blocks_long = dev->transport->get_blocks(dev); unsigned char *rbuf; unsigned char buf[8]; u32 blocks; + /* + * SBC-2 says: + * If the PMI bit is set to zero and the LOGICAL BLOCK + * ADDRESS field is not set to zero, the device server shall + * terminate the command with CHECK CONDITION status with + * the sense key set to ILLEGAL REQUEST and the additional + * sense code set to INVALID FIELD IN CDB. + * + * In SBC-3, these fields are obsolete, but some SCSI + * compliance tests actually check this, so we might as well + * follow SBC-2. + */ + if (!(cdb[8] & 1) && !!(cdb[2] | cdb[3] | cdb[4] | cdb[5])) + return TCM_INVALID_CDB_FIELD; + if (blocks_long >= 0x00000000ffffffff) blocks = 0xffffffff; else -- cgit v1.2.3-70-g09d2