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