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 80 : iscsi_task_put(struct spdk_iscsi_task *task) 82 : { 83 80 : spdk_scsi_task_put(&task->scsi); 84 80 : } 85 : 86 : static inline struct spdk_iscsi_pdu * 87 77 : iscsi_task_get_pdu(struct spdk_iscsi_task *task) 88 : { 89 77 : return task->pdu; 90 : } 91 : 92 : static inline void 93 48 : iscsi_task_set_pdu(struct spdk_iscsi_task *task, struct spdk_iscsi_pdu *pdu) 94 : { 95 48 : task->pdu = pdu; 96 48 : } 97 : 98 : static inline struct iscsi_bhs * 99 23 : iscsi_task_get_bhs(struct spdk_iscsi_task *task) 100 : { 101 23 : return &iscsi_task_get_pdu(task)->bhs; 102 : } 103 : 104 : static inline void 105 23 : iscsi_task_associate_pdu(struct spdk_iscsi_task *task, struct spdk_iscsi_pdu *pdu) 106 : { 107 23 : iscsi_task_set_pdu(task, pdu); 108 23 : pdu->ref++; 109 23 : } 110 : 111 : static inline void 112 1 : iscsi_task_disassociate_pdu(struct spdk_iscsi_task *task) 113 : { 114 1 : if (iscsi_task_get_pdu(task)) { 115 1 : iscsi_put_pdu(iscsi_task_get_pdu(task)); 116 1 : iscsi_task_set_pdu(task, NULL); 117 : } 118 1 : } 119 : 120 : static inline int 121 9 : iscsi_task_is_immediate(struct spdk_iscsi_task *task) 122 : { 123 : struct iscsi_bhs_scsi_req *scsi_req; 124 : 125 9 : scsi_req = (struct iscsi_bhs_scsi_req *)iscsi_task_get_bhs(task); 126 9 : return (scsi_req->immediate == 1); 127 : } 128 : 129 : static inline int 130 14 : iscsi_task_is_read(struct spdk_iscsi_task *task) 131 : { 132 : struct iscsi_bhs_scsi_req *scsi_req; 133 : 134 14 : scsi_req = (struct iscsi_bhs_scsi_req *)iscsi_task_get_bhs(task); 135 14 : 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 92 : iscsi_task_from_scsi_task(struct spdk_scsi_task *task) 144 : { 145 92 : return SPDK_CONTAINEROF(task, struct spdk_iscsi_task, scsi); 146 : } 147 : 148 : static inline struct spdk_iscsi_task * 149 36 : iscsi_task_get_primary(struct spdk_iscsi_task *task) 150 : { 151 36 : if (task->parent) { 152 21 : return task->parent; 153 : } else { 154 15 : return task; 155 : } 156 : } 157 : 158 : static inline void 159 18 : iscsi_task_set_mobj(struct spdk_iscsi_task *task, struct spdk_mobj *mobj) 160 : { 161 18 : task->mobj = mobj; 162 18 : } 163 : 164 : static inline struct spdk_mobj * 165 12 : iscsi_task_get_mobj(struct spdk_iscsi_task *task) 166 : { 167 12 : return task->mobj; 168 : } 169 : 170 : #endif /* SPDK_ISCSI_TASK_H */