-
Notifications
You must be signed in to change notification settings - Fork 148
/
libtcmu_common.h
205 lines (177 loc) · 6.81 KB
/
libtcmu_common.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/*
* Copyright (c) 2014 Red Hat, Inc.
*
* This file is licensed to you under your choice of the GNU Lesser
* General Public License, version 2.1 or any later version (LGPLv2.1 or
* later), or the Apache License 2.0.
*/
/*
* APIs for both libtcmu users and tcmu-runner plugins to use.
*/
#ifndef __LIBTCMU_COMMON_H
#define __LIBTCMU_COMMON_H
#include <stdbool.h>
#include <pthread.h>
#ifdef __cplusplus
extern "C" {
#endif
struct tcmu_device;
struct tgt_port;
struct tcmulib_cmd;
/*
* TCMU return status codes
*/
enum {
TCMU_STS_ASYNC_HANDLED = -2,
TCMU_STS_NOT_HANDLED = -1,
TCMU_STS_OK = 0,
TCMU_STS_NO_RESOURCE,
/* handler has setup sense. */
TCMU_STS_PASSTHROUGH_ERR,
TCMU_STS_BUSY,
TCMU_STS_WR_ERR,
TCMU_STS_RD_ERR,
TCMU_STS_MISCOMPARE,
TCMU_STS_INVALID_CMD,
TCMU_STS_INVALID_CDB,
TCMU_STS_INVALID_PARAM_LIST,
TCMU_STS_INVALID_PARAM_LIST_LEN,
TCMU_STS_TIMEOUT,
TCMU_STS_FENCED,
TCMU_STS_HW_ERR,
TCMU_STS_RANGE,
TCMU_STS_FRMT_IN_PROGRESS,
TCMU_STS_CAPACITY_CHANGED,
TCMU_STS_NOTSUPP_SAVE_PARAMS,
TCMU_STS_WR_ERR_INCOMPAT_FRMT,
TCMU_STS_TRANSITION,
TCMU_STS_IMPL_TRANSITION_ERR,
TCMU_STS_EXPL_TRANSITION_ERR,
TCMU_STS_NO_LOCK_HOLDERS,
/* xcopy specific errors */
TCMU_STS_NOTSUPP_SEG_DESC_TYPE,
TCMU_STS_NOTSUPP_TGT_DESC_TYPE,
TCMU_STS_CP_TGT_DEV_NOTCONN,
TCMU_STS_INVALID_CP_TGT_DEV_TYPE,
TCMU_STS_TOO_MANY_SEG_DESC,
TCMU_STS_TOO_MANY_TGT_DESC,
};
#define TCMU_THREAD_NAME_LEN 16
#define SENSE_BUFFERSIZE 96
#define CFGFS_ROOT "/sys/kernel/config/target"
#define CFGFS_CORE CFGFS_ROOT"/core"
#define CFGFS_TARGET_MOD "/sys/module/target_core_user"
#define CFGFS_MOD_PARAM CFGFS_TARGET_MOD"/parameters"
#define max(a, b) ({ \
__typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
(void) (&_a == &_b); \
_a < _b ? _b : _a; })
#define min(a, b) ({ \
__typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
(void) (&_a == &_b); \
_a < _b ? _a : _b; })
#define round_up(a, b) ({ \
__typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
((_a + (_b - 1)) / _b) * _b; })
#define round_down(a, b) ({ \
__typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
(_a - (_a % _b)); })
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
struct tcmulib_cmd {
uint16_t cmd_id;
uint8_t *cdb;
struct iovec *iovec;
size_t iov_cnt;
uint8_t sense_buf[SENSE_BUFFERSIZE];
void *hm_private;
};
/* Set/Get methods for the opaque tcmu_device */
void *tcmu_dev_get_private(struct tcmu_device *dev);
void tcmu_dev_set_private(struct tcmu_device *dev, void *priv);
const char *tcmu_dev_get_uio_name(struct tcmu_device *dev);
void tcmu_set_thread_name(const char *prefix, struct tcmu_device *dev);
int tcmu_dev_get_fd(struct tcmu_device *dev);
char *tcmu_dev_get_memory_info(struct tcmu_device *dev, void **base,
size_t *len, off_t *offset);
char *tcmu_dev_get_cfgstring(struct tcmu_device *dev);
void tcmu_dev_set_num_lbas(struct tcmu_device *dev, uint64_t num_lbas);
uint64_t tcmu_dev_get_num_lbas(struct tcmu_device *dev);
void tcmu_dev_set_block_size(struct tcmu_device *dev, uint32_t block_size);
uint32_t tcmu_dev_get_block_size(struct tcmu_device *dev);
uint64_t tcmu_lba_to_byte(struct tcmu_device *dev, uint64_t lba);
uint64_t tcmu_byte_to_lba(struct tcmu_device *dev, uint64_t byte);
void tcmu_dev_set_max_xfer_len(struct tcmu_device *dev, uint32_t len);
uint32_t tcmu_dev_get_max_xfer_len(struct tcmu_device *dev);
void tcmu_dev_set_opt_xcopy_rw_len(struct tcmu_device *dev, uint32_t len);
uint32_t tcmu_dev_get_opt_xcopy_rw_len(struct tcmu_device *dev);
void tcmu_dev_set_max_unmap_len(struct tcmu_device *dev, uint32_t len);
uint32_t tcmu_dev_get_max_unmap_len(struct tcmu_device *dev);
void tcmu_dev_set_opt_unmap_gran(struct tcmu_device *dev, uint32_t len,
bool split);
uint32_t tcmu_dev_get_opt_unmap_gran(struct tcmu_device *dev);
void tcmu_dev_set_unmap_gran_align(struct tcmu_device *dev, uint32_t len);
uint32_t tcmu_dev_get_unmap_gran_align(struct tcmu_device *dev);
void tcmu_dev_set_write_cache_enabled(struct tcmu_device *dev, bool enabled);
bool tcmu_dev_get_write_cache_enabled(struct tcmu_device *dev);
void tcmu_dev_set_solid_state_media(struct tcmu_device *dev, bool solid_state);
bool tcmu_dev_get_solid_state_media(struct tcmu_device *dev);
void tcmu_dev_set_unmap_enabled(struct tcmu_device *dev, bool enabled);
bool tcmu_dev_get_unmap_enabled(struct tcmu_device *dev);
void tcmu_dev_set_write_protect_enabled(struct tcmu_device *dev, bool enabled);
bool tcmu_dev_get_write_protect_enabled(struct tcmu_device *dev);
struct tcmulib_handler *tcmu_dev_get_handler(struct tcmu_device *dev);
void tcmu_dev_flush_ring(struct tcmu_device *dev);
bool tcmu_dev_oooc_supported(struct tcmu_device* dev);
/* Set/Get methods for interacting with configfs */
char *tcmu_cfgfs_get_str(const char *path);
int tcmu_cfgfs_set_str(const char *path, const char *val, int val_len);
int tcmu_cfgfs_get_int(const char *path);
int tcmu_cfgfs_set_u32(const char *path, uint32_t val);
int tcmu_cfgfs_dev_get_attr_int(struct tcmu_device *dev, const char *name);
int tcmu_cfgfs_dev_exec_action(struct tcmu_device *dev, const char *name,
uint32_t val);
int tcmu_cfgfs_dev_set_ctrl_u64(struct tcmu_device *dev, const char *key,
uint64_t val);
uint64_t tcmu_cfgfs_dev_get_info_u64(struct tcmu_device *dev, const char *name,
int *fn_ret);
char *tcmu_cfgfs_dev_get_wwn(struct tcmu_device *dev);
int tcmu_cfgfs_mod_param_set_u32(const char *name, uint32_t val);
/* Helper routines for processing commands */
/* SCSI CDB processing */
int tcmu_cdb_get_length(uint8_t *cdb);
uint64_t tcmu_cdb_get_lba(uint8_t *cdb);
uint32_t tcmu_cdb_get_xfer_length(uint8_t *cdb);
void tcmu_cdb_print_info(struct tcmu_device *dev, const struct tcmulib_cmd *cmd,
const char *info);
uint64_t tcmu_cdb_to_byte(struct tcmu_device *dev, uint8_t *cdb);
/* iovec processing */
off_t tcmu_iovec_compare(void *mem, struct iovec *iovec, size_t size);
size_t tcmu_iovec_seek(struct iovec *iovec, size_t count);
void tcmu_iovec_zero(struct iovec *iovec, size_t iov_cnt);
bool tcmu_iovec_zeroed(struct iovec *iovec, size_t iov_cnt);
size_t tcmu_iovec_length(struct iovec *iovec, size_t iov_cnt);
/* memory mangement */
size_t tcmu_memcpy_into_iovec(struct iovec *iovec, size_t iov_cnt, void *src,
size_t len);
size_t tcmu_memcpy_from_iovec(void *dest, size_t len, struct iovec *iovec,
size_t iov_cnt);
/* tcmulib_cmd processing */
void tcmu_cmd_seek(struct tcmulib_cmd *cmd, size_t count);
/* SCSI Sense */
int tcmu_sense_set_data(uint8_t *sense_buf, uint8_t key, uint16_t asc_ascq);
void tcmu_sense_set_info(uint8_t *sense_buf, uint32_t info);
void tcmu_sense_set_key_specific_info(uint8_t *sense_buf, uint16_t info);
void __tcmu_sense_set_data(uint8_t *sense_buf, uint8_t key, uint16_t asc_ascq);
/*
* Misc
*/
void tcmu_thread_cancel(pthread_t thread);
extern __thread int __tcmu_is_ework_thread;
#ifdef __cplusplus
}
#endif
#endif