aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target/target_core_cdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/target/target_core_cdb.c')
-rw-r--r--drivers/target/target_core_cdb.c57
1 files changed, 34 insertions, 23 deletions
diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c
index 8ae09a1bdf74..89ae923c5da6 100644
--- a/drivers/target/target_core_cdb.c
+++ b/drivers/target/target_core_cdb.c
@@ -67,6 +67,7 @@ target_emulate_inquiry_std(struct se_cmd *cmd)
67{ 67{
68 struct se_lun *lun = cmd->se_lun; 68 struct se_lun *lun = cmd->se_lun;
69 struct se_device *dev = cmd->se_dev; 69 struct se_device *dev = cmd->se_dev;
70 struct se_portal_group *tpg = lun->lun_sep->sep_tpg;
70 unsigned char *buf; 71 unsigned char *buf;
71 72
72 /* 73 /*
@@ -81,9 +82,13 @@ target_emulate_inquiry_std(struct se_cmd *cmd)
81 82
82 buf = transport_kmap_first_data_page(cmd); 83 buf = transport_kmap_first_data_page(cmd);
83 84
84 buf[0] = dev->transport->get_device_type(dev); 85 if (dev == tpg->tpg_virt_lun0.lun_se_dev) {
85 if (buf[0] == TYPE_TAPE) 86 buf[0] = 0x3f; /* Not connected */
86 buf[1] = 0x80; 87 } else {
88 buf[0] = dev->transport->get_device_type(dev);
89 if (buf[0] == TYPE_TAPE)
90 buf[1] = 0x80;
91 }
87 buf[2] = dev->transport->get_device_rev(dev); 92 buf[2] = dev->transport->get_device_rev(dev);
88 93
89 /* 94 /*
@@ -915,8 +920,8 @@ target_emulate_modesense(struct se_cmd *cmd, int ten)
915 length += target_modesense_control(dev, &buf[offset+length]); 920 length += target_modesense_control(dev, &buf[offset+length]);
916 break; 921 break;
917 default: 922 default:
918 pr_err("Got Unknown Mode Page: 0x%02x\n", 923 pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n",
919 cdb[2] & 0x3f); 924 cdb[2] & 0x3f, cdb[3]);
920 return PYX_TRANSPORT_UNKNOWN_MODE_PAGE; 925 return PYX_TRANSPORT_UNKNOWN_MODE_PAGE;
921 } 926 }
922 offset += length; 927 offset += length;
@@ -1072,8 +1077,6 @@ target_emulate_unmap(struct se_task *task)
1072 size -= 16; 1077 size -= 16;
1073 } 1078 }
1074 1079
1075 task->task_scsi_status = GOOD;
1076 transport_complete_task(task, 1);
1077err: 1080err:
1078 transport_kunmap_first_data_page(cmd); 1081 transport_kunmap_first_data_page(cmd);
1079 1082
@@ -1085,24 +1088,17 @@ err:
1085 * Note this is not used for TCM/pSCSI passthrough 1088 * Note this is not used for TCM/pSCSI passthrough
1086 */ 1089 */
1087static int 1090static int
1088target_emulate_write_same(struct se_task *task, int write_same32) 1091target_emulate_write_same(struct se_task *task, u32 num_blocks)
1089{ 1092{
1090 struct se_cmd *cmd = task->task_se_cmd; 1093 struct se_cmd *cmd = task->task_se_cmd;
1091 struct se_device *dev = cmd->se_dev; 1094 struct se_device *dev = cmd->se_dev;
1092 sector_t range; 1095 sector_t range;
1093 sector_t lba = cmd->t_task_lba; 1096 sector_t lba = cmd->t_task_lba;
1094 unsigned int num_blocks;
1095 int ret; 1097 int ret;
1096 /* 1098 /*
1097 * Extract num_blocks from the WRITE_SAME_* CDB. Then use the explict 1099 * Use the explicit range when non zero is supplied, otherwise calculate
1098 * range when non zero is supplied, otherwise calculate the remaining 1100 * the remaining range based on ->get_blocks() - starting LBA.
1099 * range based on ->get_blocks() - starting LBA.
1100 */ 1101 */
1101 if (write_same32)
1102 num_blocks = get_unaligned_be32(&cmd->t_task_cdb[28]);
1103 else
1104 num_blocks = get_unaligned_be32(&cmd->t_task_cdb[10]);
1105
1106 if (num_blocks != 0) 1102 if (num_blocks != 0)
1107 range = num_blocks; 1103 range = num_blocks;
1108 else 1104 else
@@ -1117,8 +1113,6 @@ target_emulate_write_same(struct se_task *task, int write_same32)
1117 return ret; 1113 return ret;
1118 } 1114 }
1119 1115
1120 task->task_scsi_status = GOOD;
1121 transport_complete_task(task, 1);
1122 return 0; 1116 return 0;
1123} 1117}
1124 1118
@@ -1165,13 +1159,23 @@ transport_emulate_control_cdb(struct se_task *task)
1165 } 1159 }
1166 ret = target_emulate_unmap(task); 1160 ret = target_emulate_unmap(task);
1167 break; 1161 break;
1162 case WRITE_SAME:
1163 if (!dev->transport->do_discard) {
1164 pr_err("WRITE_SAME emulation not supported"
1165 " for: %s\n", dev->transport->name);
1166 return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
1167 }
1168 ret = target_emulate_write_same(task,
1169 get_unaligned_be16(&cmd->t_task_cdb[7]));
1170 break;
1168 case WRITE_SAME_16: 1171 case WRITE_SAME_16:
1169 if (!dev->transport->do_discard) { 1172 if (!dev->transport->do_discard) {
1170 pr_err("WRITE_SAME_16 emulation not supported" 1173 pr_err("WRITE_SAME_16 emulation not supported"
1171 " for: %s\n", dev->transport->name); 1174 " for: %s\n", dev->transport->name);
1172 return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; 1175 return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
1173 } 1176 }
1174 ret = target_emulate_write_same(task, 0); 1177 ret = target_emulate_write_same(task,
1178 get_unaligned_be32(&cmd->t_task_cdb[10]));
1175 break; 1179 break;
1176 case VARIABLE_LENGTH_CMD: 1180 case VARIABLE_LENGTH_CMD:
1177 service_action = 1181 service_action =
@@ -1184,7 +1188,8 @@ transport_emulate_control_cdb(struct se_task *task)
1184 dev->transport->name); 1188 dev->transport->name);
1185 return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; 1189 return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
1186 } 1190 }
1187 ret = target_emulate_write_same(task, 1); 1191 ret = target_emulate_write_same(task,
1192 get_unaligned_be32(&cmd->t_task_cdb[28]));
1188 break; 1193 break;
1189 default: 1194 default:
1190 pr_err("Unsupported VARIABLE_LENGTH_CMD SA:" 1195 pr_err("Unsupported VARIABLE_LENGTH_CMD SA:"
@@ -1219,8 +1224,14 @@ transport_emulate_control_cdb(struct se_task *task)
1219 1224
1220 if (ret < 0) 1225 if (ret < 0)
1221 return ret; 1226 return ret;
1222 task->task_scsi_status = GOOD; 1227 /*
1223 transport_complete_task(task, 1); 1228 * Handle the successful completion here unless a caller
1229 * has explictly requested an asychronous completion.
1230 */
1231 if (!(cmd->se_cmd_flags & SCF_EMULATE_CDB_ASYNC)) {
1232 task->task_scsi_status = GOOD;
1233 transport_complete_task(task, 1);
1234 }
1224 1235
1225 return PYX_TRANSPORT_SENT_TO_TRANSPORT; 1236 return PYX_TRANSPORT_SENT_TO_TRANSPORT;
1226} 1237}