aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target/target_core_cdb.c
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2011-07-28 03:07:03 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2011-08-22 15:26:21 -0400
commit706d5860969b3b24d65d9a57bd3bb5e4a1419c08 (patch)
treea6293f322a5327d3c317c09197b33d66e22d010e /drivers/target/target_core_cdb.c
parent16ab8e60a0ebc22cfbe61d84e620457a15f3a0bc (diff)
target: Add WRITE_SAME (10) parsing and refactor passthrough checks
This patch adds initial WRITE_SAME (10) w/ UNMAP=1 support following updates in sbcr26 to allow UNMAP=1 for the non 16 + 32 byte CDB case. It also refactors current pSCSI passthrough passthrough checks into target_check_write_same_discard() ahead of UNMAP=0 w/ write payload support into target_core_iblock.c. This includes the support for handling WRITE_SAME in transport_emulate_control_cdb(), and converts target_emulate_write_same to accept num_blocks directly for WRITE_SAME, WRITE_SAME_16 and WRITE_SAME_32. Reported-by: Eric Seppanen <eric@purestorage.com> Cc: Roland Dreier <roland@purestorage.com> Cc: Christoph Hellwig <hch@lst.de> Signed-off-by: Nicholas Bellinger <nab@risingtidesystems.com>
Diffstat (limited to 'drivers/target/target_core_cdb.c')
-rw-r--r--drivers/target/target_core_cdb.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c
index d095408dbd5f..4c1d3a98e894 100644
--- a/drivers/target/target_core_cdb.c
+++ b/drivers/target/target_core_cdb.c
@@ -1090,24 +1090,17 @@ err:
1090 * Note this is not used for TCM/pSCSI passthrough 1090 * Note this is not used for TCM/pSCSI passthrough
1091 */ 1091 */
1092static int 1092static int
1093target_emulate_write_same(struct se_task *task, int write_same32) 1093target_emulate_write_same(struct se_task *task, u32 num_blocks)
1094{ 1094{
1095 struct se_cmd *cmd = task->task_se_cmd; 1095 struct se_cmd *cmd = task->task_se_cmd;
1096 struct se_device *dev = cmd->se_dev; 1096 struct se_device *dev = cmd->se_dev;
1097 sector_t range; 1097 sector_t range;
1098 sector_t lba = cmd->t_task_lba; 1098 sector_t lba = cmd->t_task_lba;
1099 unsigned int num_blocks;
1100 int ret; 1099 int ret;
1101 /* 1100 /*
1102 * Extract num_blocks from the WRITE_SAME_* CDB. Then use the explict 1101 * Use the explicit range when non zero is supplied, otherwise calculate
1103 * range when non zero is supplied, otherwise calculate the remaining 1102 * the remaining range based on ->get_blocks() - starting LBA.
1104 * range based on ->get_blocks() - starting LBA.
1105 */ 1103 */
1106 if (write_same32)
1107 num_blocks = get_unaligned_be32(&cmd->t_task_cdb[28]);
1108 else
1109 num_blocks = get_unaligned_be32(&cmd->t_task_cdb[10]);
1110
1111 if (num_blocks != 0) 1104 if (num_blocks != 0)
1112 range = num_blocks; 1105 range = num_blocks;
1113 else 1106 else
@@ -1170,13 +1163,23 @@ transport_emulate_control_cdb(struct se_task *task)
1170 } 1163 }
1171 ret = target_emulate_unmap(task); 1164 ret = target_emulate_unmap(task);
1172 break; 1165 break;
1166 case WRITE_SAME:
1167 if (!dev->transport->do_discard) {
1168 pr_err("WRITE_SAME emulation not supported"
1169 " for: %s\n", dev->transport->name);
1170 return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
1171 }
1172 ret = target_emulate_write_same(task,
1173 get_unaligned_be16(&cmd->t_task_cdb[7]));
1174 break;
1173 case WRITE_SAME_16: 1175 case WRITE_SAME_16:
1174 if (!dev->transport->do_discard) { 1176 if (!dev->transport->do_discard) {
1175 pr_err("WRITE_SAME_16 emulation not supported" 1177 pr_err("WRITE_SAME_16 emulation not supported"
1176 " for: %s\n", dev->transport->name); 1178 " for: %s\n", dev->transport->name);
1177 return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; 1179 return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
1178 } 1180 }
1179 ret = target_emulate_write_same(task, 0); 1181 ret = target_emulate_write_same(task,
1182 get_unaligned_be32(&cmd->t_task_cdb[10]));
1180 break; 1183 break;
1181 case VARIABLE_LENGTH_CMD: 1184 case VARIABLE_LENGTH_CMD:
1182 service_action = 1185 service_action =
@@ -1189,7 +1192,8 @@ transport_emulate_control_cdb(struct se_task *task)
1189 dev->transport->name); 1192 dev->transport->name);
1190 return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; 1193 return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
1191 } 1194 }
1192 ret = target_emulate_write_same(task, 1); 1195 ret = target_emulate_write_same(task,
1196 get_unaligned_be32(&cmd->t_task_cdb[28]));
1193 break; 1197 break;
1194 default: 1198 default:
1195 pr_err("Unsupported VARIABLE_LENGTH_CMD SA:" 1199 pr_err("Unsupported VARIABLE_LENGTH_CMD SA:"