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_SCSI_INTERNAL_H 8 #define SPDK_SCSI_INTERNAL_H 9 10 #include "spdk/stdinc.h" 11 12 #include "spdk/bdev.h" 13 #include "spdk/scsi.h" 14 #include "spdk/scsi_spec.h" 15 #include "spdk/trace.h" 16 #include "spdk/dif.h" 17 18 #include "spdk/log.h" 19 20 #define SPDK_SCSI_DEV_MAX_LUN 256 21 22 enum { 23 SPDK_SCSI_TASK_UNKNOWN = -1, 24 SPDK_SCSI_TASK_COMPLETE, 25 SPDK_SCSI_TASK_PENDING, 26 }; 27 28 struct spdk_scsi_port { 29 uint8_t is_used; 30 uint64_t id; 31 uint16_t index; 32 uint16_t transport_id_len; 33 char transport_id[SPDK_SCSI_MAX_TRANSPORT_ID_LENGTH]; 34 char name[SPDK_SCSI_PORT_MAX_NAME_LENGTH]; 35 }; 36 37 /* Registrant with I_T nextus */ 38 struct spdk_scsi_pr_registrant { 39 uint64_t rkey; 40 uint16_t relative_target_port_id; 41 uint16_t transport_id_len; 42 char transport_id[SPDK_SCSI_MAX_TRANSPORT_ID_LENGTH]; 43 char initiator_port_name[SPDK_SCSI_PORT_MAX_NAME_LENGTH]; 44 char target_port_name[SPDK_SCSI_PORT_MAX_NAME_LENGTH]; 45 struct spdk_scsi_port *initiator_port; 46 struct spdk_scsi_port *target_port; 47 TAILQ_ENTRY(spdk_scsi_pr_registrant) link; 48 }; 49 50 #define SCSI_SPC2_RESERVE 0x00000001U 51 52 /* Reservation with LU_SCOPE */ 53 struct spdk_scsi_pr_reservation { 54 uint32_t flags; 55 struct spdk_scsi_pr_registrant *holder; 56 enum spdk_scsi_pr_type_code rtype; 57 uint64_t crkey; 58 }; 59 60 struct spdk_scsi_dev { 61 int id; 62 int is_allocated; 63 bool removed; 64 spdk_scsi_dev_destruct_cb_t remove_cb; 65 void *remove_ctx; 66 67 char name[SPDK_SCSI_DEV_MAX_NAME + 1]; 68 69 TAILQ_HEAD(, spdk_scsi_lun) luns; 70 71 int num_ports; 72 struct spdk_scsi_port port[SPDK_SCSI_DEV_MAX_PORTS]; 73 74 uint8_t protocol_id; 75 }; 76 77 struct spdk_scsi_lun_desc { 78 struct spdk_scsi_lun *lun; 79 spdk_scsi_lun_remove_cb_t hotremove_cb; 80 void *hotremove_ctx; 81 TAILQ_ENTRY(spdk_scsi_lun_desc) link; 82 }; 83 84 struct spdk_scsi_lun { 85 /** LUN id for this logical unit. */ 86 int id; 87 88 /** Pointer to the SCSI device containing this LUN. */ 89 struct spdk_scsi_dev *dev; 90 91 /** The bdev associated with this LUN. */ 92 struct spdk_bdev *bdev; 93 94 /** Descriptor for opened block device. */ 95 struct spdk_bdev_desc *bdev_desc; 96 97 /** The thread which opens this LUN. */ 98 struct spdk_thread *thread; 99 100 /** I/O channel for the bdev associated with this LUN. */ 101 struct spdk_io_channel *io_channel; 102 103 /** The reference number for this LUN, thus we can correctly free the io_channel */ 104 uint32_t ref; 105 106 /** Poller to release the resource of the lun when it is hot removed */ 107 struct spdk_poller *hotremove_poller; 108 109 /** The LUN is removed */ 110 bool removed; 111 112 /** Callback to be fired when LUN removal is first triggered. */ 113 void (*hotremove_cb)(const struct spdk_scsi_lun *lun, void *arg); 114 115 /** Argument for hotremove_cb */ 116 void *hotremove_ctx; 117 118 /** Callback to be fired when the bdev size of related LUN has changed. */ 119 void (*resize_cb)(const struct spdk_scsi_lun *, void *); 120 121 /** Argument for resize_cb */ 122 void *resize_ctx; 123 124 /** Registrant head for I_T nexus */ 125 TAILQ_HEAD(, spdk_scsi_pr_registrant) reg_head; 126 /** Persistent Reservation Generation */ 127 uint32_t pr_generation; 128 /** Reservation for the LUN */ 129 struct spdk_scsi_pr_reservation reservation; 130 /** Reservation holder for SPC2 RESERVE(6) and RESERVE(10) */ 131 struct spdk_scsi_pr_registrant scsi2_holder; 132 133 /** List of open descriptors for this LUN. */ 134 TAILQ_HEAD(, spdk_scsi_lun_desc) open_descs; 135 136 /** submitted tasks */ 137 TAILQ_HEAD(tasks, spdk_scsi_task) tasks; 138 139 /** pending tasks */ 140 TAILQ_HEAD(pending_tasks, spdk_scsi_task) pending_tasks; 141 142 /** submitted management tasks */ 143 TAILQ_HEAD(mgmt_tasks, spdk_scsi_task) mgmt_tasks; 144 145 /** pending management tasks */ 146 TAILQ_HEAD(pending_mgmt_tasks, spdk_scsi_task) pending_mgmt_tasks; 147 148 /** poller to check completion of tasks prior to reset */ 149 struct spdk_poller *reset_poller; 150 151 /** A structure to connect LUNs in a list. */ 152 TAILQ_ENTRY(spdk_scsi_lun) tailq; 153 154 /** The LUN is resizing */ 155 bool resizing; 156 }; 157 158 struct spdk_scsi_lun *scsi_lun_construct(const char *bdev_name, 159 void (*resize_cb)(const struct spdk_scsi_lun *, void *), 160 void *resize_ctx, 161 void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), 162 void *hotremove_ctx); 163 void scsi_lun_destruct(struct spdk_scsi_lun *lun); 164 165 void scsi_lun_execute_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task); 166 void scsi_lun_execute_mgmt_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task); 167 bool scsi_lun_has_pending_mgmt_tasks(const struct spdk_scsi_lun *lun, 168 const struct spdk_scsi_port *initiator_port); 169 void scsi_lun_complete_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task); 170 void scsi_lun_complete_reset_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task); 171 bool scsi_lun_has_pending_tasks(const struct spdk_scsi_lun *lun, 172 const struct spdk_scsi_port *initiator_port); 173 int scsi_lun_allocate_io_channel(struct spdk_scsi_lun *lun); 174 void scsi_lun_free_io_channel(struct spdk_scsi_lun *lun); 175 176 struct spdk_scsi_dev *scsi_dev_get_list(void); 177 178 int scsi_port_construct(struct spdk_scsi_port *port, uint64_t id, 179 uint16_t index, const char *name); 180 void scsi_port_destruct(struct spdk_scsi_port *port); 181 182 int bdev_scsi_execute(struct spdk_scsi_task *task); 183 void bdev_scsi_reset(struct spdk_scsi_task *task); 184 185 bool bdev_scsi_get_dif_ctx(struct spdk_bdev *bdev, struct spdk_scsi_task *task, 186 struct spdk_dif_ctx *dif_ctx); 187 188 int scsi_pr_out(struct spdk_scsi_task *task, uint8_t *cdb, uint8_t *data, uint16_t data_len); 189 int scsi_pr_in(struct spdk_scsi_task *task, uint8_t *cdb, uint8_t *data, uint16_t data_len); 190 int scsi_pr_check(struct spdk_scsi_task *task); 191 192 int scsi2_reserve(struct spdk_scsi_task *task, uint8_t *cdb); 193 int scsi2_release(struct spdk_scsi_task *task); 194 int scsi2_reserve_check(struct spdk_scsi_task *task); 195 196 #endif /* SPDK_SCSI_INTERNAL_H */ 197