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