blob: 734125045a4a1b51527c8ab76ab0b71c8585b848 [file] [log] [blame]
Jaegeuk Kim5cc1f382016-05-27 14:20:43 -07001/*
2 * This file is copied from libzbc.
3 *
4 * Copyright (C) 2009-2014, HGST, Inc. All rights reserved.
5 *
6 * This software is distributed under the terms of the BSD 2-clause license,
7 * "as is," without technical support, and WITHOUT ANY WARRANTY, without
8 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
9 * PURPOSE. You should have received a copy of the BSD 2-clause license along
10 * with libzbc. If not, see <http://opensource.org/licenses/BSD-2-Clause>.
11 *
12 * Author: Damien Le Moal (damien.lemoal@hgst.com)
13 * Christophe Louargant (christophe.louargant@hgst.com)
14 */
15
16#ifndef __LIBZBC_SG_H__
17#define __LIBZBC_SG_H__
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <unistd.h>
22#include <string.h>
23#include <errno.h>
24#include <fcntl.h>
25#include <inttypes.h>
Alexander Martinz8ca5ed62016-11-25 17:06:10 +010026#ifdef __linux__
Jaegeuk Kim5cc1f382016-05-27 14:20:43 -070027#include <linux/types.h>
Alexander Martinz8ca5ed62016-11-25 17:06:10 +010028#endif
Jaegeuk Kim5cc1f382016-05-27 14:20:43 -070029#include <sys/types.h>
30#include <sys/ioctl.h>
Alexander Martinz8ca5ed62016-11-25 17:06:10 +010031#ifdef __linux__
Jaegeuk Kim5cc1f382016-05-27 14:20:43 -070032#include <scsi/scsi.h>
33#include <scsi/sg.h>
Alexander Martinz8ca5ed62016-11-25 17:06:10 +010034#else
35#include "scsi/scsi.h"
36#include "scsi/sg.h"
37#endif
Jaegeuk Kim5cc1f382016-05-27 14:20:43 -070038
39#define zbc_error(format, args...) \
40 fprintf(stderr, "[ERROR] " format, ##args)
41
42/**
43 * SG SCSI command names.
44 */
45enum {
46
47 ZBC_SG_TEST_UNIT_READY = 0,
48 ZBC_SG_INQUIRY,
49 ZBC_SG_READ_CAPACITY,
50 ZBC_SG_READ,
51 ZBC_SG_WRITE,
52 ZBC_SG_SYNC_CACHE,
53 ZBC_SG_REPORT_ZONES,
54 ZBC_SG_OPEN_ZONE,
55 ZBC_SG_CLOSE_ZONE,
56 ZBC_SG_FINISH_ZONE,
57 ZBC_SG_RESET_WRITE_POINTER,
58 ZBC_SG_SET_ZONES,
59 ZBC_SG_SET_WRITE_POINTER,
60 ZBC_SG_ATA12,
61 ZBC_SG_ATA16,
62
63 ZBC_SG_CMD_NUM,
64};
65
66/**
67 * Test unit ready command definition.
68 */
69#define ZBC_SG_TEST_UNIT_READY_CDB_OPCODE 0x00
70#define ZBC_SG_TEST_UNIT_READY_CDB_LENGTH 6
71#define ZBC_ZONE_DESCRIPTOR_LENGTH 64
72
73/**
74 * Number of bytes in the buffer before the first Zone Descriptor.
75 */
76#define ZBC_ZONE_DESCRIPTOR_OFFSET 64
77
78/**
79 * Inquiry command definition.
80 */
81#define ZBC_SG_INQUIRY_CDB_OPCODE 0x12
82#define ZBC_SG_INQUIRY_CDB_LENGTH 6
83#define ZBC_SG_INQUIRY_REPLY_LEN 96
84#define ZBC_SG_INQUIRY_REPLY_LEN_VPD_PAGE_B1 64
85#define ZBC_SG_INQUIRY_REPLY_LEN_VPD_PAGE_B6 64
86
87/**
88 * Read capacity command definition.
89 */
90#define ZBC_SG_READ_CAPACITY_CDB_OPCODE 0x9E
91#define ZBC_SG_READ_CAPACITY_CDB_SA 0x10
92#define ZBC_SG_READ_CAPACITY_CDB_LENGTH 16
93#define ZBC_SG_READ_CAPACITY_REPLY_LEN 32
94
95/**
96 * Read command definition.
97 */
98#define ZBC_SG_READ_CDB_OPCODE 0x88
99#define ZBC_SG_READ_CDB_LENGTH 16
100
101/**
102 * Write command definition.
103 */
104#define ZBC_SG_WRITE_CDB_OPCODE 0x8A
105#define ZBC_SG_WRITE_CDB_LENGTH 16
106
107/**
108 * Sync cache command definition.
109 */
110#define ZBC_SG_SYNC_CACHE_CDB_OPCODE 0x91
111#define ZBC_SG_SYNC_CACHE_CDB_LENGTH 16
112
113/**
114 * Report zones command definition.
115 */
116#define ZBC_SG_REPORT_ZONES_CDB_OPCODE 0x95
117#define ZBC_SG_REPORT_ZONES_CDB_SA 0x00
118#define ZBC_SG_REPORT_ZONES_CDB_LENGTH 16
119
120/**
121 * Open zone command definition.
122 */
123#define ZBC_SG_OPEN_ZONE_CDB_OPCODE 0x94
124#define ZBC_SG_OPEN_ZONE_CDB_SA 0x03
125#define ZBC_SG_OPEN_ZONE_CDB_LENGTH 16
126
127/**
128 * Close zone command definition.
129 */
130#define ZBC_SG_CLOSE_ZONE_CDB_OPCODE 0x94
131#define ZBC_SG_CLOSE_ZONE_CDB_SA 0x01
132#define ZBC_SG_CLOSE_ZONE_CDB_LENGTH 16
133
134/**
135 * Finish zone command definition.
136 */
137#define ZBC_SG_FINISH_ZONE_CDB_OPCODE 0x94
138#define ZBC_SG_FINISH_ZONE_CDB_SA 0x02
139#define ZBC_SG_FINISH_ZONE_CDB_LENGTH 16
140
141/**
142 * Reset write pointer command definition.
143 */
144#define ZBC_SG_RESET_WRITE_POINTER_CDB_OPCODE 0x94
145#define ZBC_SG_RESET_WRITE_POINTER_CDB_SA 0x04
146#define ZBC_SG_RESET_WRITE_POINTER_CDB_LENGTH 16
147
148/**
149 * Set zones command definition.
150 */
151#define ZBC_SG_SET_ZONES_CDB_OPCODE 0x9F
152#define ZBC_SG_SET_ZONES_CDB_SA 0x15
153#define ZBC_SG_SET_ZONES_CDB_LENGTH 16
154
155/**
156 * Set write pointer command definition.
157 */
158#define ZBC_SG_SET_WRITE_POINTER_CDB_OPCODE 0x9F
159#define ZBC_SG_SET_WRITE_POINTER_CDB_SA 0x16
160#define ZBC_SG_SET_WRITE_POINTER_CDB_LENGTH 16
161
162/**
163 * ATA pass through 12.
164 */
165#define ZBC_SG_ATA12_CDB_OPCODE 0xA1
166#define ZBC_SG_ATA12_CDB_LENGTH 12
167
168/**
169 * ATA pass through 16.
170 */
171#define ZBC_SG_ATA16_CDB_OPCODE 0x85
172#define ZBC_SG_ATA16_CDB_LENGTH 16
173
174/**
175 * Command sense buffer maximum length.
176 */
177#define ZBC_SG_SENSE_MAX_LENGTH 64
178
179/**
180 * Maximum command CDB length.
181 */
182#define ZBC_SG_CDB_MAX_LENGTH 16
183
184/**
185 * Status codes.
186 */
187#define ZBC_SG_CHECK_CONDITION 0x02
188
189/**
190 * Host status codes.
191 */
192#define ZBC_SG_DID_OK 0x00 /* No error */
193#define ZBC_SG_DID_NO_CONNECT 0x01 /* Couldn't connect before timeout period */
194#define ZBC_SG_DID_BUS_BUSY 0x02 /* BUS stayed busy through time out period */
195#define ZBC_SG_DID_TIME_OUT 0x03 /* Timed out for other reason */
196#define ZBC_SG_DID_BAD_TARGET 0x04 /* Bad target, device not responding? */
197#define ZBC_SG_DID_ABORT 0x05 /* Told to abort for some other reason. */
198#define ZBC_SG_DID_PARITY 0x06 /* Parity error. */
199#define ZBC_SG_DID_ERROR 0x07 /* Internal error detected in the host adapter. */
200#define ZBC_SG_DID_RESET 0x08 /* The SCSI bus (or this device) has been reset. */
201#define ZBC_SG_DID_BAD_INTR 0x09 /* Got an unexpected interrupt */
202#define ZBC_SG_DID_PASSTHROUGH 0x0a /* Forced command past mid-layer. */
203#define ZBC_SG_DID_SOFT_ERROR 0x0b /* The low level driver wants a retry. */
204
205/**
206 * Driver status codes.
207 */
208#define ZBC_SG_DRIVER_OK 0x00
209#define ZBC_SG_DRIVER_BUSY 0x01
210#define ZBC_SG_DRIVER_SOFT 0x02
211#define ZBC_SG_DRIVER_MEDIA 0x03
212#define ZBC_SG_DRIVER_ERROR 0x04
213#define ZBC_SG_DRIVER_INVALID 0x05
214#define ZBC_SG_DRIVER_TIMEOUT 0x06
215#define ZBC_SG_DRIVER_HARD 0x07
216#define ZBC_SG_DRIVER_SENSE 0x08
217#define ZBC_SG_DRIVER_STATUS_MASK 0x0f
218
219/**
220 * Driver status code flags ('or'ed with code)
221 */
222#define ZBC_SG_DRIVER_SUGGEST_RETRY 0x10
223#define ZBC_SG_DRIVER_SUGGEST_ABORT 0x20
224#define ZBC_SG_DRIVER_SUGGEST_REMAP 0x30
225#define ZBC_SG_DRIVER_SUGGEST_DIE 0x40
226#define ZBC_SG_DRIVER_SUGGEST_SENSE 0x80
227#define ZBC_SG_DRIVER_FLAGS_MASK 0xf0
228
229/***** Type definitions *****/
230
231/**
232 * SG command descriptor. Used to process SCSI commands.
233 */
234typedef struct zbc_sg_cmd {
235
236 int code;
237
238 int cdb_opcode;
239 int cdb_sa;
240 size_t cdb_sz;
241 uint8_t cdb[ZBC_SG_CDB_MAX_LENGTH];
242
243 size_t sense_bufsz;
244 uint8_t sense_buf[ZBC_SG_SENSE_MAX_LENGTH];
245
246 int out_buf_needfree;
247 size_t out_bufsz;
248 uint8_t *out_buf;
249
250 sg_io_hdr_t io_hdr;
251
252} zbc_sg_cmd_t;
253
254/**
255 * Zone descriptor.
256 */
257struct zbc_zone {
258
259 uint64_t zbz_length;
260 uint64_t zbz_start;
261 uint64_t zbz_write_pointer;
262
263 uint8_t zbz_type;
264 uint8_t zbz_condition;
265 uint8_t zbz_flags;
266
267 uint8_t __pad[5];
268
269};
270typedef struct zbc_zone zbc_zone_t;
271
272#define ZBC_FORCE_ATA_RW 0x40000000
273#define zbc_open_flags(f) ((f) & ~ZBC_FORCE_ATA_RW)
274
275/**
276 * Zone type.
277 */
278enum zbc_zone_type {
279 ZBC_ZT_CONVENTIONAL = 0x01,
280 ZBC_ZT_SEQUENTIAL_REQ = 0x02,
281 ZBC_ZT_SEQUENTIAL_PREF = 0x03,
282};
283#define zbc_zone_type(z) ((int)(z)->zbz_type)
284
285#define zbc_zone_conventional(z) ((z)->zbz_type == ZBC_ZT_CONVENTIONAL)
286static inline const char *zbc_zone_type_str(enum zbc_zone_type type)
287{
288 switch( type ) {
289 case ZBC_ZT_CONVENTIONAL:
290 return( "Conventional" );
291 case ZBC_ZT_SEQUENTIAL_REQ:
292 return( "Sequential-write-required" );
293 case ZBC_ZT_SEQUENTIAL_PREF:
294 return( "Sequential-write-preferred" );
295 }
296 return( "Unknown-type" );
297}
298
299/**
300 * Zone condition.
301 */
302enum zbc_zone_condition {
303 ZBC_ZC_NOT_WP = 0x00,
304 ZBC_ZC_EMPTY = 0x01,
305 ZBC_ZC_IMP_OPEN = 0x02,
306 ZBC_ZC_EXP_OPEN = 0x03,
307 ZBC_ZC_CLOSED = 0x04,
308 ZBC_ZC_RDONLY = 0x0d,
309 ZBC_ZC_FULL = 0x0e,
310 ZBC_ZC_OFFLINE = 0x0f,
311};
312
313/**
314 * zbc_zone_cond_str - returns a string describing a zone condition.
315 * @zone: (IN) ZBC_ZC_NOT_WP, ZBC_ZC_EMPTY, ZBC_ZC_IMP_OPEN, ZBC_ZC_EXP_OPEN,
316 * ZBC_ZC_CLOSED, ZBC_ZC_RDONLY, ZBC_ZC_FULL or ZBC_ZC_OFFLINE
317 *
318 * Returns a string describing a zone condition.
319 */
320static inline const char *zbc_zone_condition_str(enum zbc_zone_condition cond)
321{
322 switch( cond ) {
323 case ZBC_ZC_NOT_WP:
324 return "Not-write-pointer";
325 case ZBC_ZC_EMPTY:
326 return "Empty";
327 case ZBC_ZC_IMP_OPEN:
328 return "Implicit-open";
329 case ZBC_ZC_EXP_OPEN:
330 return "Explicit-open";
331 case ZBC_ZC_CLOSED:
332 return "Closed";
333 case ZBC_ZC_RDONLY:
334 return "Read-only";
335 case ZBC_ZC_FULL:
336 return "Full";
337 case ZBC_ZC_OFFLINE:
338 return "Offline";
339 }
340 return "Unknown-cond";
341}
342
343#define zbc_zone_condition(z) ((int)(z)->zbz_condition)
344#define zbc_zone_start_lba(z) ((unsigned long long)((z)->zbz_start))
345#define zbc_zone_length(z) ((unsigned long long)((z)->zbz_length))
346#define zbc_zone_wp_lba(z) ((unsigned long long)((z)->zbz_write_pointer))
347
348/**
349 * Zone flags: need reset, and non-seq write.
350 */
351enum zbc_zone_flags {
352 ZBC_ZF_NEED_RESET = 0x0001,
353 ZBC_ZF_NON_SEQ = 0x0002,
354};
355#define zbc_zone_need_reset(z) (((z)->zbz_flags & ZBC_ZF_NEED_RESET) != 0)
356#define zbc_zone_non_seq(z) (((z)->zbz_flags & ZBC_ZF_NON_SEQ) != 0)
357
358#define zbc_sg_cmd_driver_status(cmd) ((cmd)->io_hdr.driver_status & ZBC_SG_DRIVER_STATUS_MASK)
359#define zbc_sg_cmd_driver_flags(cmd) ((cmd)->io_hdr.driver_status & ZBC_SG_DRIVER_FLAGS_MASK)
360
361union converter {
362 uint8_t val_buf[8];
363 uint16_t val16;
364 uint32_t val32;
365 uint64_t val64;
366};
367
368#endif /* __LIBZBC_SG_H__ */