blob: 1ab2f6ef11da0da29f899b6dc7b400dc0dee6104 [file] [log] [blame]
/*
* scst_pres.c
*
* Copyright (C) 2009 - 2010 Alexey Obitotskiy <alexeyo1@open-e.com>
* Copyright (C) 2009 - 2010 Open-E, Inc.
* Copyright (C) 2009 - 2018 Vladislav Bolkhovitin <vst@vlnb.net>
*
* 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 <linux/delay.h>
#ifdef INSIDE_KERNEL_TREE
#include <scst/scst_debug.h>
#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);
uint32_t 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_ */