1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>. 3 * Copyright (C) 2016 Intel Corporation. 4 * All rights reserved. 5 */ 6 7 #ifndef SPDK_ISCSI_TASK_H 8 #define SPDK_ISCSI_TASK_H 9 10 #include "iscsi/iscsi.h" 11 #include "spdk/scsi.h" 12 #include "spdk/util.h" 13 14 struct spdk_iscsi_task { 15 struct spdk_scsi_task scsi; 16 17 struct spdk_iscsi_task *parent; 18 19 struct spdk_iscsi_conn *conn; 20 struct spdk_iscsi_pdu *pdu; 21 struct spdk_mobj *mobj; 22 uint32_t outstanding_r2t; 23 24 uint32_t desired_data_transfer_length; 25 26 /* Only valid for Read/Write */ 27 uint32_t bytes_completed; 28 29 uint32_t data_out_cnt; 30 31 /* 32 * Tracks the current offset of large read or write io. 33 */ 34 uint32_t current_data_offset; 35 36 /* 37 * next_expected_r2t_offset is used when we receive 38 * the DataOUT PDU. 39 */ 40 uint32_t next_expected_r2t_offset; 41 42 /* 43 * Tracks the length of the R2T that is in progress. 44 * Used to check that an R2T burst does not exceed 45 * MaxBurstLength. 46 */ 47 uint32_t current_r2t_length; 48 49 /* 50 * next_r2t_offset is used when we are sending the 51 * R2T packet to keep track of next offset of r2t. 52 */ 53 uint32_t next_r2t_offset; 54 uint32_t R2TSN; 55 uint32_t r2t_datasn; /* record next datasn for a r2tsn */ 56 uint32_t acked_r2tsn; /* next r2tsn to be acked */ 57 uint32_t datain_datasn; 58 uint32_t acked_data_sn; /* next expected datain datasn */ 59 uint32_t ttt; 60 bool is_r2t_active; 61 62 uint32_t tag; 63 64 /** 65 * Record the lun id just in case the lun is invalid, 66 * which will happen when hot removing the lun. 67 */ 68 int lun_id; 69 70 struct spdk_poller *mgmt_poller; 71 72 TAILQ_ENTRY(spdk_iscsi_task) link; 73 74 TAILQ_HEAD(subtask_list, spdk_iscsi_task) subtask_list; 75 TAILQ_ENTRY(spdk_iscsi_task) subtask_link; 76 bool is_queued; /* is queued in scsi layer for handling */ 77 }; 78 79 static inline void 80 iscsi_task_put(struct spdk_iscsi_task *task) 81 { 82 spdk_scsi_task_put(&task->scsi); 83 } 84 85 static inline struct spdk_iscsi_pdu * 86 iscsi_task_get_pdu(struct spdk_iscsi_task *task) 87 { 88 return task->pdu; 89 } 90 91 static inline void 92 iscsi_task_set_pdu(struct spdk_iscsi_task *task, struct spdk_iscsi_pdu *pdu) 93 { 94 task->pdu = pdu; 95 } 96 97 static inline struct iscsi_bhs * 98 iscsi_task_get_bhs(struct spdk_iscsi_task *task) 99 { 100 return &iscsi_task_get_pdu(task)->bhs; 101 } 102 103 static inline void 104 iscsi_task_associate_pdu(struct spdk_iscsi_task *task, struct spdk_iscsi_pdu *pdu) 105 { 106 iscsi_task_set_pdu(task, pdu); 107 pdu->ref++; 108 } 109 110 static inline void 111 iscsi_task_disassociate_pdu(struct spdk_iscsi_task *task) 112 { 113 if (iscsi_task_get_pdu(task)) { 114 iscsi_put_pdu(iscsi_task_get_pdu(task)); 115 iscsi_task_set_pdu(task, NULL); 116 } 117 } 118 119 static inline int 120 iscsi_task_is_immediate(struct spdk_iscsi_task *task) 121 { 122 struct iscsi_bhs_scsi_req *scsi_req; 123 124 scsi_req = (struct iscsi_bhs_scsi_req *)iscsi_task_get_bhs(task); 125 return (scsi_req->immediate == 1); 126 } 127 128 static inline int 129 iscsi_task_is_read(struct spdk_iscsi_task *task) 130 { 131 struct iscsi_bhs_scsi_req *scsi_req; 132 133 scsi_req = (struct iscsi_bhs_scsi_req *)iscsi_task_get_bhs(task); 134 return (scsi_req->read_bit == 1); 135 } 136 137 struct spdk_iscsi_task *iscsi_task_get(struct spdk_iscsi_conn *conn, 138 struct spdk_iscsi_task *parent, 139 spdk_scsi_task_cpl cpl_fn); 140 141 static inline struct spdk_iscsi_task * 142 iscsi_task_from_scsi_task(struct spdk_scsi_task *task) 143 { 144 return SPDK_CONTAINEROF(task, struct spdk_iscsi_task, scsi); 145 } 146 147 static inline struct spdk_iscsi_task * 148 iscsi_task_get_primary(struct spdk_iscsi_task *task) 149 { 150 if (task->parent) { 151 return task->parent; 152 } else { 153 return task; 154 } 155 } 156 157 static inline void 158 iscsi_task_set_mobj(struct spdk_iscsi_task *task, struct spdk_mobj *mobj) 159 { 160 task->mobj = mobj; 161 } 162 163 static inline struct spdk_mobj * 164 iscsi_task_get_mobj(struct spdk_iscsi_task *task) 165 { 166 return task->mobj; 167 } 168 169 #endif /* SPDK_ISCSI_TASK_H */ 170