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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
|
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Copyright 2016 Joyent, Inc.
*/
/*
* Defines for user SCSI commands
*/
#ifndef _SYS_SCSI_IMPL_USCSI_H
#define _SYS_SCSI_IMPL_USCSI_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* definition for user-scsi command structure
*/
struct uscsi_cmd {
int uscsi_flags; /* read, write, etc. see below */
short uscsi_status; /* resulting status */
short uscsi_timeout; /* Command Timeout */
caddr_t uscsi_cdb; /* cdb to send to target */
caddr_t uscsi_bufaddr; /* i/o source/destination */
size_t uscsi_buflen; /* size of i/o to take place */
size_t uscsi_resid; /* resid from i/o operation */
uchar_t uscsi_cdblen; /* # of valid cdb bytes */
uchar_t uscsi_rqlen; /* size of uscsi_rqbuf */
uchar_t uscsi_rqstatus; /* status of request sense cmd */
uchar_t uscsi_rqresid; /* resid of request sense cmd */
caddr_t uscsi_rqbuf; /* request sense buffer */
ulong_t uscsi_path_instance; /* private: hardware path */
};
#if defined(_SYSCALL32)
struct uscsi_cmd32 {
int uscsi_flags; /* read, write, etc. see below */
short uscsi_status; /* resulting status */
short uscsi_timeout; /* Command Timeout */
caddr32_t uscsi_cdb; /* cdb to send to target */
caddr32_t uscsi_bufaddr; /* i/o source/destination */
size32_t uscsi_buflen; /* size of i/o to take place */
size32_t uscsi_resid; /* resid from i/o operation */
uchar_t uscsi_cdblen; /* # of valid cdb bytes */
uchar_t uscsi_rqlen; /* size of uscsi_rqbuf */
uchar_t uscsi_rqstatus; /* status of request sense cmd */
uchar_t uscsi_rqresid; /* resid of request sense cmd */
caddr32_t uscsi_rqbuf; /* request sense buffer */
uint32_t uscsi_path_instance; /* private: hardware path */
};
#define uscsi_cmd32touscsi_cmd(u32, ucmd) \
ucmd->uscsi_flags = u32->uscsi_flags; \
ucmd->uscsi_status = u32->uscsi_status; \
ucmd->uscsi_timeout = u32->uscsi_timeout; \
ucmd->uscsi_cdb = (caddr_t)(uintptr_t)u32->uscsi_cdb; \
ucmd->uscsi_bufaddr = (caddr_t)(uintptr_t)u32->uscsi_bufaddr; \
ucmd->uscsi_buflen = (size_t)u32->uscsi_buflen; \
ucmd->uscsi_resid = (size_t)u32->uscsi_resid; \
ucmd->uscsi_cdblen = u32->uscsi_cdblen; \
ucmd->uscsi_rqlen = u32->uscsi_rqlen; \
ucmd->uscsi_rqstatus = u32->uscsi_rqstatus; \
ucmd->uscsi_rqresid = u32->uscsi_rqresid; \
ucmd->uscsi_rqbuf = (caddr_t)(uintptr_t)u32->uscsi_rqbuf; \
ucmd->uscsi_path_instance = (ulong_t)u32->uscsi_path_instance;
#define uscsi_cmdtouscsi_cmd32(ucmd, u32) \
u32->uscsi_flags = ucmd->uscsi_flags; \
u32->uscsi_status = ucmd->uscsi_status; \
u32->uscsi_timeout = ucmd->uscsi_timeout; \
u32->uscsi_cdb = (caddr32_t)(uintptr_t)ucmd->uscsi_cdb; \
u32->uscsi_bufaddr = (caddr32_t)(uintptr_t)ucmd->uscsi_bufaddr; \
u32->uscsi_buflen = (size32_t)ucmd->uscsi_buflen; \
u32->uscsi_resid = (size32_t)ucmd->uscsi_resid; \
u32->uscsi_cdblen = ucmd->uscsi_cdblen; \
u32->uscsi_rqlen = ucmd->uscsi_rqlen; \
u32->uscsi_rqstatus = ucmd->uscsi_rqstatus; \
u32->uscsi_rqresid = ucmd->uscsi_rqresid; \
u32->uscsi_rqbuf = (caddr32_t)(uintptr_t)ucmd->uscsi_rqbuf; \
u32->uscsi_path_instance = (uint32_t)ucmd->uscsi_path_instance;
#endif /* _SYSCALL32 */
/*
* flags for uscsi_flags field
*/
/*
* generic flags
*/
#define USCSI_SILENT 0x00000001 /* no error messages */
#define USCSI_DIAGNOSE 0x00000002 /* fail if any error occurs */
#define USCSI_ISOLATE 0x00000004 /* isolate from normal commands */
#define USCSI_READ 0x00000008 /* get data from device */
#define USCSI_WRITE 0x00000000 /* send data to device */
#define USCSI_RESET 0x00004000 /* Reset target */
#define USCSI_RESET_TARGET \
USCSI_RESET /* Reset target */
#define USCSI_RESET_ALL 0x00008000 /* Reset all targets */
#define USCSI_RQENABLE 0x00010000 /* Enable Request Sense extensions */
#define USCSI_RENEGOT 0x00020000 /* renegotiate wide/sync on next I/O */
#define USCSI_RESET_LUN 0x00040000 /* Reset logical unit */
#define USCSI_PATH_INSTANCE \
0x00080000 /* use path instance for transport */
/*
* suitable for parallel SCSI bus only
*/
#define USCSI_ASYNC 0x00001000 /* Set bus to asynchronous mode */
#define USCSI_SYNC 0x00002000 /* Set bus to sync mode if possible */
/*
* the following flags should not be used at user level but may
* be used by a scsi target driver for internal commands
*/
/*
* generic flags
*/
#define USCSI_NOINTR 0x00000040 /* No interrupts, NEVER use this flag */
#define USCSI_NOTAG 0x00000100 /* Disable tagged queueing */
#define USCSI_OTAG 0x00000200 /* ORDERED QUEUE tagged cmd */
#define USCSI_HTAG 0x00000400 /* HEAD OF QUEUE tagged cmd */
#define USCSI_HEAD 0x00000800 /* Head of HA queue */
/*
* suitable for parallel SCSI bus only
*/
#define USCSI_NOPARITY 0x00000010 /* run command without parity */
#define USCSI_NODISCON 0x00000020 /* run command without disconnects */
/*
* suitable for FMA module for PM purpose
*/
#define USCSI_PMFAILFAST 0x00100000 /* fail command if device is */
/* in low power */
#define USCSI_RESERVED 0xffe00000 /* Reserved Bits, must be zero */
struct uscsi_rqs {
int rqs_flags; /* see below */
ushort_t rqs_buflen; /* maximum number or bytes to return */
ushort_t rqs_resid; /* untransferred length of RQS data */
caddr_t rqs_bufaddr; /* request sense buffer */
};
#if defined(_SYSCALL32)
struct uscsi_rqs32 {
int rqs_flags; /* see below */
ushort_t rqs_buflen; /* maximum number or bytes to return */
ushort_t rqs_resid; /* untransferred length of RQS data */
caddr32_t rqs_bufaddr; /* request sense buffer */
};
#endif /* _SYSCALL32 */
/*
* uscsi_rqs flags
*/
#define RQS_OVR 0x01 /* RQS data has been overwritten */
#define RQS_VALID 0x02 /* RQS data is valid */
/*
* Structure for USCSIMAXXFER ioctls
*/
typedef uint64_t uscsi_xfer_t;
/*
* User SCSI io control command
*/
#define USCSIIOC (0x04 << 8)
#define USCSICMD (USCSIIOC|201) /* user scsi command */
#define USCSIMAXXFER (USCSIIOC|202) /* get max transfer size */
#ifdef _KERNEL
#include <sys/scsi/scsi_types.h>
struct uscsi_cmd *scsi_uscsi_alloc();
int scsi_uscsi_copyin(intptr_t, int,
struct scsi_address *, struct uscsi_cmd **);
int scsi_uscsi_alloc_and_copyin(intptr_t, int,
struct scsi_address *, struct uscsi_cmd **);
int scsi_uscsi_pktinit(struct uscsi_cmd *, struct scsi_pkt *);
int scsi_uscsi_handle_cmd(dev_t, enum uio_seg,
struct uscsi_cmd *, int (*)(struct buf *),
struct buf *, void *);
int scsi_uscsi_pktfini(struct scsi_pkt *, struct uscsi_cmd *);
int scsi_uscsi_copyout(intptr_t, struct uscsi_cmd *);
void scsi_uscsi_free(struct uscsi_cmd *);
int scsi_uscsi_copyout_and_free(intptr_t, struct uscsi_cmd *);
#endif /* _KERNEL */
#ifdef __cplusplus
}
#endif
#endif /* _SYS_SCSI_IMPL_USCSI_H */
|