|
@@ -395,6 +395,10 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
|
|
|
if (rc)
|
|
|
return rc;
|
|
|
}
|
|
|
+
|
|
|
+ if (scsi_get_prot_op(sc) != SCSI_PROT_NORMAL)
|
|
|
+ task->protected = true;
|
|
|
+
|
|
|
if (sc->sc_data_direction == DMA_TO_DEVICE) {
|
|
|
unsigned out_len = scsi_out(sc)->length;
|
|
|
struct iscsi_r2t_info *r2t = &task->unsol_r2t;
|
|
@@ -823,6 +827,33 @@ static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
|
|
|
|
|
|
sc->result = (DID_OK << 16) | rhdr->cmd_status;
|
|
|
|
|
|
+ if (task->protected) {
|
|
|
+ sector_t sector;
|
|
|
+ u8 ascq;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Transports that didn't implement check_protection
|
|
|
+ * callback but still published T10-PI support to scsi-mid
|
|
|
+ * deserve this BUG_ON.
|
|
|
+ **/
|
|
|
+ BUG_ON(!session->tt->check_protection);
|
|
|
+
|
|
|
+ ascq = session->tt->check_protection(task, §or);
|
|
|
+ if (ascq) {
|
|
|
+ sc->result = DRIVER_SENSE << 24 |
|
|
|
+ SAM_STAT_CHECK_CONDITION;
|
|
|
+ scsi_build_sense_buffer(1, sc->sense_buffer,
|
|
|
+ ILLEGAL_REQUEST, 0x10, ascq);
|
|
|
+ sc->sense_buffer[7] = 0xc; /* Additional sense length */
|
|
|
+ sc->sense_buffer[8] = 0; /* Information desc type */
|
|
|
+ sc->sense_buffer[9] = 0xa; /* Additional desc length */
|
|
|
+ sc->sense_buffer[10] = 0x80; /* Validity bit */
|
|
|
+
|
|
|
+ put_unaligned_be64(sector, &sc->sense_buffer[12]);
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (rhdr->response != ISCSI_STATUS_CMD_COMPLETED) {
|
|
|
sc->result = DID_ERROR << 16;
|
|
|
goto out;
|
|
@@ -1567,6 +1598,7 @@ static inline struct iscsi_task *iscsi_alloc_task(struct iscsi_conn *conn,
|
|
|
task->have_checked_conn = false;
|
|
|
task->last_timeout = jiffies;
|
|
|
task->last_xfer = jiffies;
|
|
|
+ task->protected = false;
|
|
|
INIT_LIST_HEAD(&task->running);
|
|
|
return task;
|
|
|
}
|