1488570ebSJim Harris /* SPDX-License-Identifier: BSD-3-Clause 2bd4ac74eSDaniel Verkamp * Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>. 3a6dbe372Spaul luse * Copyright (C) 2016 Intel Corporation. 4bd4ac74eSDaniel Verkamp * All rights reserved. 5bd4ac74eSDaniel Verkamp */ 6bd4ac74eSDaniel Verkamp 7bd4ac74eSDaniel Verkamp #ifndef SPDK_SCSI_INTERNAL_H 8bd4ac74eSDaniel Verkamp #define SPDK_SCSI_INTERNAL_H 9bd4ac74eSDaniel Verkamp 10b961d9ccSBen Walker #include "spdk/stdinc.h" 11bd4ac74eSDaniel Verkamp 12bd4ac74eSDaniel Verkamp #include "spdk/bdev.h" 13bd4ac74eSDaniel Verkamp #include "spdk/scsi.h" 14bd4ac74eSDaniel Verkamp #include "spdk/scsi_spec.h" 15bd4ac74eSDaniel Verkamp #include "spdk/trace.h" 168697bce7SShuhei Matsumoto #include "spdk/dif.h" 17bd4ac74eSDaniel Verkamp 184e8e97c8STomasz Zawadzki #include "spdk/log.h" 19d27b24c9SDaniel Verkamp 205e877275SShuhei Matsumoto #define SPDK_SCSI_DEV_MAX_LUN 256 215e877275SShuhei Matsumoto 22bd4ac74eSDaniel Verkamp enum { 23bd4ac74eSDaniel Verkamp SPDK_SCSI_TASK_UNKNOWN = -1, 24bd4ac74eSDaniel Verkamp SPDK_SCSI_TASK_COMPLETE, 25bd4ac74eSDaniel Verkamp SPDK_SCSI_TASK_PENDING, 26bd4ac74eSDaniel Verkamp }; 27bd4ac74eSDaniel Verkamp 282990f869SDaniel Verkamp struct spdk_scsi_port { 290e5b81b3SShuhei Matsumoto uint8_t is_used; 302990f869SDaniel Verkamp uint64_t id; 312990f869SDaniel Verkamp uint16_t index; 3238dfce04SChangpeng Liu uint16_t transport_id_len; 3338dfce04SChangpeng Liu char transport_id[SPDK_SCSI_MAX_TRANSPORT_ID_LENGTH]; 342990f869SDaniel Verkamp char name[SPDK_SCSI_PORT_MAX_NAME_LENGTH]; 352990f869SDaniel Verkamp }; 362990f869SDaniel Verkamp 37d0d19eb8SChangpeng Liu /* Registrant with I_T nextus */ 38d0d19eb8SChangpeng Liu struct spdk_scsi_pr_registrant { 39d0d19eb8SChangpeng Liu uint64_t rkey; 40d0d19eb8SChangpeng Liu uint16_t relative_target_port_id; 41d0d19eb8SChangpeng Liu uint16_t transport_id_len; 42d0d19eb8SChangpeng Liu char transport_id[SPDK_SCSI_MAX_TRANSPORT_ID_LENGTH]; 43d0d19eb8SChangpeng Liu char initiator_port_name[SPDK_SCSI_PORT_MAX_NAME_LENGTH]; 44d0d19eb8SChangpeng Liu char target_port_name[SPDK_SCSI_PORT_MAX_NAME_LENGTH]; 45d0d19eb8SChangpeng Liu struct spdk_scsi_port *initiator_port; 46d0d19eb8SChangpeng Liu struct spdk_scsi_port *target_port; 47d0d19eb8SChangpeng Liu TAILQ_ENTRY(spdk_scsi_pr_registrant) link; 48d0d19eb8SChangpeng Liu }; 49d0d19eb8SChangpeng Liu 506b6a3ff9SChangpeng Liu #define SCSI_SPC2_RESERVE 0x00000001U 516b6a3ff9SChangpeng Liu 52d0d19eb8SChangpeng Liu /* Reservation with LU_SCOPE */ 53d0d19eb8SChangpeng Liu struct spdk_scsi_pr_reservation { 546b6a3ff9SChangpeng Liu uint32_t flags; 55d0d19eb8SChangpeng Liu struct spdk_scsi_pr_registrant *holder; 56d0d19eb8SChangpeng Liu enum spdk_scsi_pr_type_code rtype; 57d0d19eb8SChangpeng Liu uint64_t crkey; 58d0d19eb8SChangpeng Liu }; 59d0d19eb8SChangpeng Liu 60a3738d90SDaniel Verkamp struct spdk_scsi_dev { 61a3738d90SDaniel Verkamp int id; 62a3738d90SDaniel Verkamp int is_allocated; 6385a61ea6SPawel Wodkowski bool removed; 6456d8b785SShuhei Matsumoto spdk_scsi_dev_destruct_cb_t remove_cb; 6556d8b785SShuhei Matsumoto void *remove_ctx; 66a3738d90SDaniel Verkamp 67c013db36SShuhei Matsumoto char name[SPDK_SCSI_DEV_MAX_NAME + 1]; 68a3738d90SDaniel Verkamp 694265fc50SShuhei Matsumoto TAILQ_HEAD(, spdk_scsi_lun) luns; 70a3738d90SDaniel Verkamp 71a3738d90SDaniel Verkamp int num_ports; 72a3738d90SDaniel Verkamp struct spdk_scsi_port port[SPDK_SCSI_DEV_MAX_PORTS]; 735e132b6bSTomasz Zawadzki 745e132b6bSTomasz Zawadzki uint8_t protocol_id; 75a3738d90SDaniel Verkamp }; 76a3738d90SDaniel Verkamp 779470d65eSShuhei Matsumoto struct spdk_scsi_lun_desc { 78c740e569SShuhei Matsumoto struct spdk_scsi_lun *lun; 799470d65eSShuhei Matsumoto spdk_scsi_lun_remove_cb_t hotremove_cb; 80c740e569SShuhei Matsumoto void *hotremove_ctx; 819470d65eSShuhei Matsumoto TAILQ_ENTRY(spdk_scsi_lun_desc) link; 82c740e569SShuhei Matsumoto }; 83c740e569SShuhei Matsumoto 8412965bb6SDaniel Verkamp struct spdk_scsi_lun { 8512965bb6SDaniel Verkamp /** LUN id for this logical unit. */ 8612965bb6SDaniel Verkamp int id; 8712965bb6SDaniel Verkamp 88*05faf8e7Szhenwei pi /** The LUN is removed */ 89*05faf8e7Szhenwei pi bool removed; 90*05faf8e7Szhenwei pi 91*05faf8e7Szhenwei pi /** The LUN is resizing */ 92*05faf8e7Szhenwei pi bool resizing; 93*05faf8e7Szhenwei pi 9412965bb6SDaniel Verkamp /** Pointer to the SCSI device containing this LUN. */ 9512965bb6SDaniel Verkamp struct spdk_scsi_dev *dev; 9612965bb6SDaniel Verkamp 97dd06e98dSJim Harris /** The bdev associated with this LUN. */ 9812965bb6SDaniel Verkamp struct spdk_bdev *bdev; 9912965bb6SDaniel Verkamp 10057d174ffSJim Harris /** Descriptor for opened block device. */ 10157d174ffSJim Harris struct spdk_bdev_desc *bdev_desc; 10257d174ffSJim Harris 1037cef60b6SShuhei Matsumoto /** The thread which opens this LUN. */ 1047cef60b6SShuhei Matsumoto struct spdk_thread *thread; 1057cef60b6SShuhei Matsumoto 106dd06e98dSJim Harris /** I/O channel for the bdev associated with this LUN. */ 10712965bb6SDaniel Verkamp struct spdk_io_channel *io_channel; 10812965bb6SDaniel Verkamp 10912965bb6SDaniel Verkamp /** Poller to release the resource of the lun when it is hot removed */ 110edf92482SShuhei Matsumoto struct spdk_poller *hotremove_poller; 11112965bb6SDaniel Verkamp 11272343bcfSDariusz Stojaczyk /** Callback to be fired when LUN removal is first triggered. */ 11372343bcfSDariusz Stojaczyk void (*hotremove_cb)(const struct spdk_scsi_lun *lun, void *arg); 11472343bcfSDariusz Stojaczyk 11572343bcfSDariusz Stojaczyk /** Argument for hotremove_cb */ 11672343bcfSDariusz Stojaczyk void *hotremove_ctx; 11772343bcfSDariusz Stojaczyk 1185029fe14SLi Feng /** Callback to be fired when the bdev size of related LUN has changed. */ 1195029fe14SLi Feng void (*resize_cb)(const struct spdk_scsi_lun *, void *); 1205029fe14SLi Feng 1215029fe14SLi Feng /** Argument for resize_cb */ 1225029fe14SLi Feng void *resize_ctx; 1235029fe14SLi Feng 124c740e569SShuhei Matsumoto /** List of open descriptors for this LUN. */ 1259470d65eSShuhei Matsumoto TAILQ_HEAD(, spdk_scsi_lun_desc) open_descs; 126c740e569SShuhei Matsumoto 127b409bf40SShuhei Matsumoto /** submitted tasks */ 128c740e569SShuhei Matsumoto TAILQ_HEAD(tasks, spdk_scsi_task) tasks; 1296dd09113SShuhei Matsumoto 130b409bf40SShuhei Matsumoto /** pending tasks */ 131b409bf40SShuhei Matsumoto TAILQ_HEAD(pending_tasks, spdk_scsi_task) pending_tasks; 132b409bf40SShuhei Matsumoto 1336dd09113SShuhei Matsumoto /** submitted management tasks */ 1346dd09113SShuhei Matsumoto TAILQ_HEAD(mgmt_tasks, spdk_scsi_task) mgmt_tasks; 1356dd09113SShuhei Matsumoto 1366dd09113SShuhei Matsumoto /** pending management tasks */ 1376dd09113SShuhei Matsumoto TAILQ_HEAD(pending_mgmt_tasks, spdk_scsi_task) pending_mgmt_tasks; 1386dd09113SShuhei Matsumoto 139d0e3f624SShuhei Matsumoto /** poller to check completion of tasks prior to reset */ 140d0e3f624SShuhei Matsumoto struct spdk_poller *reset_poller; 1414265fc50SShuhei Matsumoto 1424265fc50SShuhei Matsumoto /** A structure to connect LUNs in a list. */ 1434265fc50SShuhei Matsumoto TAILQ_ENTRY(spdk_scsi_lun) tailq; 1446b7e9d0aSGangCao 145*05faf8e7Szhenwei pi /** The reference number for this LUN, thus we can correctly free the io_channel */ 146*05faf8e7Szhenwei pi uint32_t ref; 147a91b02b2Szhenwei pi 148a91b02b2Szhenwei pi /** Persistent Reservation Generation */ 149a91b02b2Szhenwei pi uint32_t pr_generation; 150a91b02b2Szhenwei pi /** Registrant head for I_T nexus */ 151a91b02b2Szhenwei pi TAILQ_HEAD(, spdk_scsi_pr_registrant) reg_head; 152a91b02b2Szhenwei pi /** Reservation for the LUN */ 153a91b02b2Szhenwei pi struct spdk_scsi_pr_reservation reservation; 154a91b02b2Szhenwei pi /** Reservation holder for SPC2 RESERVE(6) and RESERVE(10) */ 155a91b02b2Szhenwei pi struct spdk_scsi_pr_registrant scsi2_holder; 15612965bb6SDaniel Verkamp }; 15712965bb6SDaniel Verkamp 158ab808d2bSShuhei Matsumoto struct spdk_scsi_lun *scsi_lun_construct(const char *bdev_name, 1595029fe14SLi Feng void (*resize_cb)(const struct spdk_scsi_lun *, void *), 1605029fe14SLi Feng void *resize_ctx, 16172343bcfSDariusz Stojaczyk void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), 16272343bcfSDariusz Stojaczyk void *hotremove_ctx); 16318dec401SShuhei Matsumoto void scsi_lun_destruct(struct spdk_scsi_lun *lun); 164bd4ac74eSDaniel Verkamp 16518dec401SShuhei Matsumoto void scsi_lun_execute_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task); 16618dec401SShuhei Matsumoto void scsi_lun_execute_mgmt_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task); 16718dec401SShuhei Matsumoto bool scsi_lun_has_pending_mgmt_tasks(const struct spdk_scsi_lun *lun, 168f9583f2cSShuhei Matsumoto const struct spdk_scsi_port *initiator_port); 16918dec401SShuhei Matsumoto void scsi_lun_complete_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task); 17018dec401SShuhei Matsumoto void scsi_lun_complete_reset_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task); 17118dec401SShuhei Matsumoto bool scsi_lun_has_pending_tasks(const struct spdk_scsi_lun *lun, 172f9583f2cSShuhei Matsumoto const struct spdk_scsi_port *initiator_port); 17318dec401SShuhei Matsumoto int scsi_lun_allocate_io_channel(struct spdk_scsi_lun *lun); 17418dec401SShuhei Matsumoto void scsi_lun_free_io_channel(struct spdk_scsi_lun *lun); 175bd4ac74eSDaniel Verkamp 17618dec401SShuhei Matsumoto struct spdk_scsi_dev *scsi_dev_get_list(void); 177bd4ac74eSDaniel Verkamp 17818dec401SShuhei Matsumoto int scsi_port_construct(struct spdk_scsi_port *port, uint64_t id, 1792990f869SDaniel Verkamp uint16_t index, const char *name); 18018dec401SShuhei Matsumoto void scsi_port_destruct(struct spdk_scsi_port *port); 1812990f869SDaniel Verkamp 18218dec401SShuhei Matsumoto int bdev_scsi_execute(struct spdk_scsi_task *task); 18318dec401SShuhei Matsumoto void bdev_scsi_reset(struct spdk_scsi_task *task); 184bd4ac74eSDaniel Verkamp 18518dec401SShuhei Matsumoto bool bdev_scsi_get_dif_ctx(struct spdk_bdev *bdev, struct spdk_scsi_task *task, 1868697bce7SShuhei Matsumoto struct spdk_dif_ctx *dif_ctx); 1878697bce7SShuhei Matsumoto 18818dec401SShuhei Matsumoto int scsi_pr_out(struct spdk_scsi_task *task, uint8_t *cdb, uint8_t *data, uint16_t data_len); 18918dec401SShuhei Matsumoto int scsi_pr_in(struct spdk_scsi_task *task, uint8_t *cdb, uint8_t *data, uint16_t data_len); 19018dec401SShuhei Matsumoto int scsi_pr_check(struct spdk_scsi_task *task); 191d0d19eb8SChangpeng Liu 1926b6a3ff9SChangpeng Liu int scsi2_reserve(struct spdk_scsi_task *task, uint8_t *cdb); 1936b6a3ff9SChangpeng Liu int scsi2_release(struct spdk_scsi_task *task); 1946b6a3ff9SChangpeng Liu int scsi2_reserve_check(struct spdk_scsi_task *task); 1956b6a3ff9SChangpeng Liu 196bd4ac74eSDaniel Verkamp #endif /* SPDK_SCSI_INTERNAL_H */ 197