/* * scst_pres.c * * Copyright (C) 2009 - 2010 Alexey Obitotskiy * Copyright (C) 2009 - 2010 Open-E, Inc. * Copyright (C) 2009 - 2018 Vladislav Bolkhovitin * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, version 2 * of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #ifndef SCST_PRES_H_ #define SCST_PRES_H_ #include #ifdef INSIDE_KERNEL_TREE #include #else #include "scst_debug.h" #endif /* PERSISTENT RESERVE OUT service action code */ #define PR_REGISTER 0x00 #define PR_RESERVE 0x01 #define PR_RELEASE 0x02 #define PR_CLEAR 0x03 #define PR_PREEMPT 0x04 #define PR_PREEMPT_AND_ABORT 0x05 #define PR_REGISTER_AND_IGNORE 0x06 #define PR_REGISTER_AND_MOVE 0x07 /* PERSISTENT RESERVE IN service action code */ #define PR_READ_KEYS 0x00 #define PR_READ_RESERVATION 0x01 #define PR_REPORT_CAPS 0x02 #define PR_READ_FULL_STATUS 0x03 /* Persistent reservation TYPE field */ #define TYPE_UNSPECIFIED (-1) #define TYPE_WRITE_EXCLUSIVE 0x01 #define TYPE_EXCLUSIVE_ACCESS 0x03 #define TYPE_WRITE_EXCLUSIVE_REGONLY 0x05 #define TYPE_EXCLUSIVE_ACCESS_REGONLY 0x06 #define TYPE_WRITE_EXCLUSIVE_ALL_REG 0x07 #define TYPE_EXCLUSIVE_ACCESS_ALL_REG 0x08 /* Persistent reservation SCOPE field */ #define SCOPE_LU 0x00 static inline bool scst_pr_type_valid(uint8_t type) { switch (type) { case TYPE_WRITE_EXCLUSIVE: case TYPE_EXCLUSIVE_ACCESS: case TYPE_WRITE_EXCLUSIVE_REGONLY: case TYPE_EXCLUSIVE_ACCESS_REGONLY: case TYPE_WRITE_EXCLUSIVE_ALL_REG: case TYPE_EXCLUSIVE_ACCESS_ALL_REG: return true; default: return false; } } static inline void scst_pr_read_lock(struct scst_device *dev) { mutex_lock(&dev->dev_pr_mutex); } static inline void scst_pr_read_unlock(struct scst_device *dev) { mutex_unlock(&dev->dev_pr_mutex); } static inline void lockdep_assert_pr_read_lock_held(struct scst_device *dev) { lockdep_assert_held(&dev->dev_pr_mutex); } static inline void scst_pr_write_lock(struct scst_device *dev) { mutex_lock(&dev->dev_pr_mutex); } static inline void scst_pr_write_unlock(struct scst_device *dev) { mutex_unlock(&dev->dev_pr_mutex); } static inline void lockdep_assert_pr_write_lock_held(struct scst_device *dev) { lockdep_assert_held(&dev->dev_pr_mutex); } int scst_pr_set_file_name(struct scst_device *dev, char **prev, const char *fmt, ...) __printf(3, 4); int scst_pr_init_dev(struct scst_device *dev); void scst_pr_clear_dev(struct scst_device *dev); int scst_pr_init_tgt_dev(struct scst_tgt_dev *tgt_dev); void scst_pr_clear_tgt_dev(struct scst_tgt_dev *tgt_dev); bool scst_pr_crh_case(struct scst_cmd *cmd); bool scst_pr_is_cmd_allowed(struct scst_cmd *cmd); void scst_pr_register(struct scst_cmd *cmd, uint8_t *buffer, int buffer_size); void scst_pr_register_and_ignore(struct scst_cmd *cmd, uint8_t *buffer, int buffer_size); void scst_pr_register_and_move(struct scst_cmd *cmd, uint8_t *buffer, int buffer_size); void scst_pr_reserve(struct scst_cmd *cmd, uint8_t *buffer, int buffer_size); void scst_pr_release(struct scst_cmd *cmd, uint8_t *buffer, int buffer_size); void scst_pr_clear(struct scst_cmd *cmd, uint8_t *buffer, int buffer_size); void scst_pr_preempt(struct scst_cmd *cmd, uint8_t *buffer, int buffer_size); void scst_pr_preempt_and_abort(struct scst_cmd *cmd, uint8_t *buffer, int buffer_size); void scst_pr_read_keys(struct scst_cmd *cmd, uint8_t *buffer, int buffer_size); void scst_pr_read_reservation(struct scst_cmd *cmd, uint8_t *buffer, int buffer_size); void scst_pr_report_caps(struct scst_cmd *cmd, uint8_t *buffer, int buffer_size); void scst_pr_read_full_status(struct scst_cmd *cmd, uint8_t *buffer, int buffer_size); int scst_tid_size(const uint8_t *tid); bool tid_equal(const uint8_t *tid_a, const uint8_t *tid_b); struct scst_dev_registrant *scst_pr_find_reg(struct scst_device *dev, const uint8_t *transport_id, const uint16_t rel_tgt_id); struct scst_dev_registrant *scst_pr_add_registrant(struct scst_device *dev, const uint8_t *transport_id, const uint16_t rel_tgt_id, __be64 key, bool dev_lock_locked); void scst_pr_remove_registrant(struct scst_device *dev, struct scst_dev_registrant *reg); void scst_pr_set_holder(struct scst_device *dev, struct scst_dev_registrant *holder, uint8_t scope, uint8_t type); void scst_pr_clear_holder(struct scst_device *dev); void scst_pr_sync_device_file(struct scst_device *dev); #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) void scst_pr_dump_prs(struct scst_device *dev, bool force); #else static inline void scst_pr_dump_prs(struct scst_device *dev, bool force) {} #endif #endif /* SCST_PRES_H_ */