1 #ifndef SG_LIB_H 2 #define SG_LIB_H 3 4 /* 5 * Copyright (c) 2004-2018 Douglas Gilbert. 6 * All rights reserved. 7 * Use of this source code is governed by a BSD-style 8 * license that can be found in the BSD_LICENSE file. 9 */ 10 11 /* 12 * 13 * On 5th October 2004 a FreeBSD license was added to this file. 14 * The intention is to keep this file and the related sg_lib.c file 15 * as open source and encourage their unencumbered use. 16 * 17 * Current version number is in the sg_lib.c file and can be accessed 18 * with the sg_lib_version() function. 19 */ 20 21 22 /* 23 * This header file contains defines and function declarations that may 24 * be useful to applications that communicate with devices that use a 25 * SCSI command set. These command sets have names like SPC-4, SBC-3, 26 * SSC-3, SES-2 and draft standards defining them can be found at 27 * http://www.t10.org . Virtually all devices in the Linux SCSI subsystem 28 * utilize SCSI command sets. Many devices in other Linux device subsystems 29 * utilize SCSI command sets either natively or via emulation (e.g. a 30 * parallel ATA disk in a USB enclosure). 31 */ 32 33 #include <stdio.h> 34 #include <stdint.h> 35 #include <stdbool.h> 36 37 #ifdef __cplusplus 38 extern "C" { 39 #endif 40 41 /* SCSI Peripheral Device Types (PDT) [5 bit field] */ 42 #define PDT_DISK 0x0 /* direct access block device (disk) */ 43 #define PDT_TAPE 0x1 /* sequential access device (magnetic tape) */ 44 #define PDT_PRINTER 0x2 /* printer device (see SSC-1) */ 45 #define PDT_PROCESSOR 0x3 /* processor device (e.g. SAFTE device) */ 46 #define PDT_WO 0x4 /* write once device (some optical disks) */ 47 #define PDT_MMC 0x5 /* CD/DVD/BD (multi-media) */ 48 #define PDT_SCANNER 0x6 /* obsolete */ 49 #define PDT_OPTICAL 0x7 /* optical memory device (some optical disks) */ 50 #define PDT_MCHANGER 0x8 /* media changer device (e.g. tape robot) */ 51 #define PDT_COMMS 0x9 /* communications device (obsolete) */ 52 #define PDT_SAC 0xc /* storage array controller device */ 53 #define PDT_SES 0xd /* SCSI Enclosure Services (SES) device */ 54 #define PDT_RBC 0xe /* Reduced Block Commands (simplified PDT_DISK) */ 55 #define PDT_OCRW 0xf /* optical card read/write device */ 56 #define PDT_BCC 0x10 /* bridge controller commands */ 57 #define PDT_OSD 0x11 /* Object Storage Device (OSD) */ 58 #define PDT_ADC 0x12 /* Automation/drive commands (ADC) */ 59 #define PDT_SMD 0x13 /* Security Manager Device (SMD) */ 60 #define PDT_ZBC 0x14 /* Zoned Block Commands (ZBC) */ 61 #define PDT_WLUN 0x1e /* Well known logical unit (WLUN) */ 62 #define PDT_UNKNOWN 0x1f /* Unknown or no device type */ 63 64 #ifndef SAM_STAT_GOOD 65 /* The SCSI status codes as found in SAM-4 at www.t10.org */ 66 #define SAM_STAT_GOOD 0x0 67 #define SAM_STAT_CHECK_CONDITION 0x2 68 #define SAM_STAT_CONDITION_MET 0x4 69 #define SAM_STAT_BUSY 0x8 70 #define SAM_STAT_INTERMEDIATE 0x10 /* obsolete in SAM-4 */ 71 #define SAM_STAT_INTERMEDIATE_CONDITION_MET 0x14 /* obsolete in SAM-4 */ 72 #define SAM_STAT_RESERVATION_CONFLICT 0x18 73 #define SAM_STAT_COMMAND_TERMINATED 0x22 /* obsolete in SAM-3 */ 74 #define SAM_STAT_TASK_SET_FULL 0x28 75 #define SAM_STAT_ACA_ACTIVE 0x30 76 #define SAM_STAT_TASK_ABORTED 0x40 77 #endif 78 79 /* The SCSI sense key codes as found in SPC-4 at www.t10.org */ 80 #define SPC_SK_NO_SENSE 0x0 81 #define SPC_SK_RECOVERED_ERROR 0x1 82 #define SPC_SK_NOT_READY 0x2 83 #define SPC_SK_MEDIUM_ERROR 0x3 84 #define SPC_SK_HARDWARE_ERROR 0x4 85 #define SPC_SK_ILLEGAL_REQUEST 0x5 86 #define SPC_SK_UNIT_ATTENTION 0x6 87 #define SPC_SK_DATA_PROTECT 0x7 88 #define SPC_SK_BLANK_CHECK 0x8 89 #define SPC_SK_VENDOR_SPECIFIC 0x9 90 #define SPC_SK_COPY_ABORTED 0xa 91 #define SPC_SK_ABORTED_COMMAND 0xb 92 #define SPC_SK_RESERVED 0xc 93 #define SPC_SK_VOLUME_OVERFLOW 0xd 94 #define SPC_SK_MISCOMPARE 0xe 95 #define SPC_SK_COMPLETED 0xf 96 97 /* Transport protocol identifiers or just Protocol identifiers */ 98 #define TPROTO_FCP 0 99 #define TPROTO_SPI 1 100 #define TPROTO_SSA 2 101 #define TPROTO_1394 3 102 #define TPROTO_SRP 4 /* SCSI over RDMA */ 103 #define TPROTO_ISCSI 5 104 #define TPROTO_SAS 6 105 #define TPROTO_ADT 7 106 #define TPROTO_ATA 8 107 #define TPROTO_UAS 9 /* USB attached SCSI */ 108 #define TPROTO_SOP 0xa /* SCSI over PCIe */ 109 #define TPROTO_PCIE 0xb /* includes NVMe */ 110 #define TPROTO_NONE 0xf 111 112 /* SCSI Feature Sets (sfs) */ 113 #define SCSI_FS_SPC_DISCOVERY_2016 0x1 114 #define SCSI_FS_SBC_BASE_2010 0x102 115 #define SCSI_FS_SBC_BASE_2016 0x101 116 #define SCSI_FS_SBC_BASIC_PROV_2016 0x103 117 #define SCSI_FS_SBC_DRIVE_MAINT_2016 0x104 118 119 /* Often SCSI responses use the highest integer that can fit in a field 120 * to indicate "unbounded" or limit does not apply. Sometimes represented 121 * in output as "-1" for brevity */ 122 #define SG_LIB_UNBOUNDED_16BIT 0xffff 123 #define SG_LIB_UNBOUNDED_32BIT 0xffffffffU 124 #define SG_LIB_UNBOUNDED_64BIT 0xffffffffffffffffULL 125 126 #if (__STDC_VERSION__ >= 199901L) /* C99 or later */ 127 typedef uintptr_t sg_uintptr_t; 128 #else 129 typedef unsigned long sg_uintptr_t; 130 #endif 131 132 133 /* The format of the version string is like this: "2.26 20170906" */ 134 const char * sg_lib_version(); 135 136 /* Returns length of SCSI command given the opcode (first byte). 137 * Yields the wrong answer for variable length commands (opcode=0x7f) 138 * and potentially some vendor specific commands. */ 139 int sg_get_command_size(unsigned char cdb_byte0); 140 141 /* Command name given pointer to the cdb. Certain command names 142 * depend on peripheral type (give 0 or -1 if unknown). Places command 143 * name into buff and will write no more than buff_len bytes. */ 144 void sg_get_command_name(const unsigned char * cdbp, int peri_type, 145 int buff_len, char * buff); 146 147 /* Command name given only the first byte (byte 0) of a cdb and 148 * peripheral type (give 0 or -1 if unknown). */ 149 void sg_get_opcode_name(unsigned char cdb_byte0, int peri_type, int buff_len, 150 char * buff); 151 152 /* Command name given opcode (byte 0), service action and peripheral type. 153 * If no service action give 0, if unknown peripheral type give 0 or -1 . */ 154 void sg_get_opcode_sa_name(unsigned char cdb_byte0, int service_action, 155 int peri_type, int buff_len, char * buff); 156 157 /* Fetch scsi status string. */ 158 void sg_get_scsi_status_str(int scsi_status, int buff_len, char * buff); 159 160 /* This is a slightly stretched SCSI sense "descriptor" format header. 161 * The addition is to allow the 0x70 and 0x71 response codes. The idea 162 * is to place the salient data of both "fixed" and "descriptor" sense 163 * format into one structure to ease application processing. 164 * The original sense buffer should be kept around for those cases 165 * in which more information is required (e.g. the LBA of a MEDIUM ERROR). */ 166 struct sg_scsi_sense_hdr { 167 unsigned char response_code; /* permit: 0x0, 0x70, 0x71, 0x72, 0x73 */ 168 unsigned char sense_key; 169 unsigned char asc; 170 unsigned char ascq; 171 unsigned char byte4; 172 unsigned char byte5; 173 unsigned char byte6; 174 unsigned char additional_length; 175 }; 176 177 /* Maps the salient data from a sense buffer which is in either fixed or 178 * descriptor format into a structure mimicking a descriptor format 179 * header (i.e. the first 8 bytes of sense descriptor format). 180 * If zero response code returns false. Otherwise returns true and if 'sshp' 181 * is non-NULL then zero all fields and then set the appropriate fields in 182 * that structure. sshp::additional_length is always 0 for response 183 * codes 0x70 and 0x71 (fixed format). */ 184 bool sg_scsi_normalize_sense(const unsigned char * sensep, int sense_len, 185 struct sg_scsi_sense_hdr * sshp); 186 187 /* Attempt to find the first SCSI sense data descriptor that matches the 188 * given 'desc_type'. If found return pointer to start of sense data 189 * descriptor; otherwise (including fixed format sense data) returns NULL. */ 190 const unsigned char * sg_scsi_sense_desc_find(const unsigned char * sensep, 191 int sense_len, int desc_type); 192 193 /* Get sense key from sense buffer. If successful returns a sense key value 194 * between 0 and 15. If sense buffer cannot be decode, returns -1 . */ 195 int sg_get_sense_key(const unsigned char * sensep, int sense_len); 196 197 /* Yield string associated with sense_key value. Returns 'buff'. */ 198 char * sg_get_sense_key_str(int sense_key, int buff_len, char * buff); 199 200 /* Yield string associated with ASC/ASCQ values. Returns 'buff'. */ 201 char * sg_get_asc_ascq_str(int asc, int ascq, int buff_len, char * buff); 202 203 /* Returns true if valid bit set, false if valid bit clear. Irrespective the 204 * information field is written out via 'info_outp' (except when it is 205 * NULL). Handles both fixed and descriptor sense formats. */ 206 bool sg_get_sense_info_fld(const unsigned char * sensep, int sb_len, 207 uint64_t * info_outp); 208 209 /* Returns true if fixed format or command specific information descriptor 210 * is found in the descriptor sense; else false. If available the command 211 * specific information field (4 byte integer in fixed format, 8 byte 212 * integer in descriptor format) is written out via 'cmd_spec_outp'. 213 * Handles both fixed and descriptor sense formats. */ 214 bool sg_get_sense_cmd_spec_fld(const unsigned char * sensep, int sb_len, 215 uint64_t * cmd_spec_outp); 216 217 /* Returns true if any of the 3 bits (i.e. FILEMARK, EOM or ILI) are set. 218 * In descriptor format if the stream commands descriptor not found 219 * then returns false. Writes true or false corresponding to these bits to 220 * the last three arguments if they are non-NULL. */ 221 bool sg_get_sense_filemark_eom_ili(const unsigned char * sensep, int sb_len, 222 bool * filemark_p, bool * eom_p, 223 bool * ili_p); 224 225 /* Returns true if SKSV is set and sense key is NO_SENSE or NOT_READY. Also 226 * returns true if progress indication sense data descriptor found. Places 227 * progress field from sense data where progress_outp points. If progress 228 * field is not available returns false. Handles both fixed and descriptor 229 * sense formats. N.B. App should multiply by 100 and divide by 65536 230 * to get percentage completion from given value. */ 231 bool sg_get_sense_progress_fld(const unsigned char * sensep, int sb_len, 232 int * progress_outp); 233 234 /* Closely related to sg_print_sense(). Puts decoded sense data in 'buff'. 235 * Usually multiline with multiple '\n' including one trailing. If 236 * 'raw_sinfo' set appends sense buffer in hex. 'leadin' is string prepended 237 * to each line written to 'buff', NULL treated as "". Returns the number of 238 * bytes written to 'buff' excluding the trailing '\0'. 239 * N.B. prior to sg3_utils v 1.42 'leadin' was only prepended to the first 240 * line output. Also this function returned type void. */ 241 int sg_get_sense_str(const char * leadin, const unsigned char * sense_buffer, 242 int sb_len, bool raw_sinfo, int buff_len, char * buff); 243 244 /* Decode descriptor format sense descriptors (assumes sense buffer is 245 * in descriptor format). 'leadin' is string prepended to each line written 246 * to 'b', NULL treated as "". Returns the number of bytes written to 'b' 247 * excluding the trailing '\0'. */ 248 int sg_get_sense_descriptors_str(const char * leadin, 249 const unsigned char * sense_buffer, 250 int sb_len, int blen, char * b); 251 252 /* Decodes a designation descriptor (e.g. as found in the Device 253 * Identification VPD page (0x83)) into string 'b' whose maximum length is 254 * blen. 'leadin' is string prepended to each line written to 'b', NULL 255 * treated as "". Returns the number of bytes written to 'b' excluding the 256 * trailing '\0'. */ 257 int sg_get_designation_descriptor_str(const char * leadin, 258 const unsigned char * ddp, int dd_len, 259 bool print_assoc, bool do_long, 260 int blen, char * b); 261 262 /* Yield string associated with peripheral device type (pdt). Returns 263 * 'buff'. If 'pdt' out of range yields "bad pdt" string. */ 264 char * sg_get_pdt_str(int pdt, int buff_len, char * buff); 265 266 /* Some lesser used PDTs share a lot in common with a more used PDT. 267 * Examples are PDT_ADC decaying to PDT_TAPE and PDT_ZBC to PDT_DISK. 268 * If such a lesser used 'pdt' is given to this function, then it will 269 * return the more used PDT (i.e. "decays to"); otherwise 'pdt' is returned. 270 * Valid for 'pdt' 0 to 31, for other values returns 0. */ 271 int sg_lib_pdt_decay(int pdt); 272 273 /* Yield string associated with transport protocol identifier (tpi). Returns 274 * 'buff'. If 'tpi' out of range yields "bad tpi" string. */ 275 char * sg_get_trans_proto_str(int tpi, int buff_len, char * buff); 276 277 /* Decode TransportID pointed to by 'bp' of length 'bplen'. Place decoded 278 * string output in 'buff' which is also the return value. Each new line 279 * is prefixed by 'leadin'. If leadin NULL treat as "". */ 280 char * sg_decode_transportid_str(const char * leadin, unsigned char * bp, 281 int bplen, bool only_one, int buff_len, 282 char * buff); 283 284 /* Returns a designator's type string given 'val' (0 to 15 inclusive), 285 * otherwise returns NULL. */ 286 const char * sg_get_desig_type_str(int val); 287 288 /* Returns a designator's code_set string given 'val' (0 to 15 inclusive), 289 * otherwise returns NULL. */ 290 const char * sg_get_desig_code_set_str(int val); 291 292 /* Returns a designator's association string given 'val' (0 to 3 inclusive), 293 * otherwise returns NULL. */ 294 const char * sg_get_desig_assoc_str(int val); 295 296 /* Yield SCSI Feature Set (sfs) string. When 'peri_type' is < -1 (or > 31) 297 * returns pointer to string (same as 'buff') associated with 'sfs_code'. 298 * When 'peri_type' is between -1 (for SPC) and 31 (inclusive) then a match 299 * on both 'sfs_code' and 'peri_type' is required. If 'foundp' is not NULL 300 * then where it points is set to true if a match is found else it is set to 301 * false. If 'buff' is not NULL then in the case of a match a descriptive 302 * string is written to 'buff' while if there is not a not then a string 303 * ending in "Reserved" is written (and may be prefixed with SPC, SBC, SSC 304 * or ZBC). Returns 'buff' (i.e. a pointer value) even if it is NULL. 305 * Example: 306 * char b[64]; 307 * ... 308 * printf("%s\n", sg_get_sfs_str(sfs_code, -2, sizeof(b), b, NULL, 0)); 309 */ 310 const char * sg_get_sfs_str(uint16_t sfs_code, int peri_type, int buff_len, 311 char * buff, bool * foundp, int verbose); 312 313 /* This is a heuristic that takes into account the command bytes and length 314 * to decide whether the presented unstructured sequence of bytes could be 315 * a SCSI command. If so it returns true otherwise false. Vendor specific 316 * SCSI commands (i.e. opcodes from 0xc0 to 0xff), if presented, are assumed 317 * to follow SCSI conventions (i.e. length of 6, 10, 12 or 16 bytes). The 318 * only SCSI commands considered above 16 bytes of length are the Variable 319 * Length Commands (opcode 0x7f) and the XCDB wrapped commands (opcode 0x7e). 320 * Both have an inbuilt length field which can be cross checked with clen. 321 * No NVMe commands (64 bytes long plus some extra added by some OSes) have 322 * opcodes 0x7e or 0x7f yet. ATA is register based but SATA has FIS 323 * structures that are sent across the wire. The 'FIS register' structure is 324 * used to move a command from a SATA host to device, but the ATA 'command' 325 * is not the first byte. So it is harder to say what will happen if a 326 * FIS structure is presented as a SCSI command, hopfully there is a low 327 * probability this function will yield true in that case. */ 328 bool sg_is_scsi_cdb(const uint8_t * cdbp, int clen); 329 330 /* Yield string associated with NVMe command status value in sct_sc. It 331 * expects to decode DW3 bits 27:17 from the completion queue. Bits 27:25 332 * are the Status Code Type (SCT) and bits 24:17 are the Status Code (SC). 333 * Bit 17 in DW3 should be bit 0 in sct_sc. If no status string is found 334 * a string of the form "Reserved [0x<sct_sc_in_hex>]" is generated. 335 * Returns 'buff'. Does nothing if buff_len<=0 or if buff is NULL.*/ 336 char * sg_get_nvme_cmd_status_str(uint16_t sct_sc, int buff_len, char * buff); 337 338 /* Attempts to map NVMe status value ((SCT << 8) | SC) n sct_sc to a SCSI 339 * status, sense_key, asc and ascq tuple. If successful returns true and 340 * writes to non-NULL pointer arguments; otherwise returns false. */ 341 bool sg_nvme_status2scsi(uint16_t sct_sc, uint8_t * status_p, uint8_t * sk_p, 342 uint8_t * asc_p, uint8_t * ascq_p); 343 344 extern FILE * sg_warnings_strm; 345 346 void sg_set_warnings_strm(FILE * warnings_strm); 347 348 /* The following "print" functions send ACSII to 'sg_warnings_strm' file 349 * descriptor (default value is stderr). 'leadin' is string prepended to 350 * each line printed out, NULL treated as "". */ 351 void sg_print_command(const unsigned char * command); 352 void sg_print_scsi_status(int scsi_status); 353 354 /* 'leadin' is string prepended to each line printed out, NULL treated as 355 * "". N.B. prior to sg3_utils v 1.42 'leadin' was only prepended to the 356 * first line printed. */ 357 void sg_print_sense(const char * leadin, const unsigned char * sense_buffer, 358 int sb_len, bool raw_info); 359 360 /* Following examines exit_status and outputs a clear error message to 361 * warnings_strm (usually stderr) if one is known and returns true. 362 * Otherwise it doesn't print anything and returns false. Note that if 363 * exit_status==0 then returns true but prints nothing and if 364 * exit_status<0 ("some error occurred") false is returned. If leadin is 365 * non-NULL is will be printed before error message. */ 366 bool sg_if_can2stderr(const char * leadin, int exit_status); 367 368 /* Utilities can use these exit status values for syntax errors and 369 * file (device node) problems (e.g. not found or permissions). */ 370 #define SG_LIB_SYNTAX_ERROR 1 /* command line syntax problem */ 371 #define SG_LIB_FILE_ERROR 15 /* device or other file problem */ 372 373 /* The sg_err_category_sense() function returns one of the following. 374 * These may be used as exit status values (from a process). Notice that 375 * some of the lower values correspond to SCSI sense key values. */ 376 #define SG_LIB_CAT_CLEAN 0 /* No errors or other information */ 377 /* Value 1 left unused for utilities to use SG_LIB_SYNTAX_ERROR */ 378 #define SG_LIB_CAT_NOT_READY 2 /* sense key, unit stopped? */ 379 /* [sk,asc,ascq: 0x2,*,*] */ 380 #define SG_LIB_CAT_MEDIUM_HARD 3 /* medium or hardware error, blank check */ 381 /* [sk,asc,ascq: 0x3/0x4/0x8,*,*] */ 382 #define SG_LIB_CAT_ILLEGAL_REQ 5 /* Illegal request (other than invalid */ 383 /* opcode): [sk,asc,ascq: 0x5,*,*] */ 384 #define SG_LIB_CAT_UNIT_ATTENTION 6 /* sense key, device state changed */ 385 /* [sk,asc,ascq: 0x6,*,*] */ 386 /* was SG_LIB_CAT_MEDIA_CHANGED earlier [sk,asc,ascq: 0x6,0x28,*] */ 387 #define SG_LIB_CAT_DATA_PROTECT 7 /* sense key, media write protected? */ 388 /* [sk,asc,ascq: 0x7,*,*] */ 389 #define SG_LIB_CAT_INVALID_OP 9 /* (Illegal request,) Invalid opcode: */ 390 /* [sk,asc,ascq: 0x5,0x20,0x0] */ 391 #define SG_LIB_CAT_COPY_ABORTED 10 /* sense key, some data transferred */ 392 /* [sk,asc,ascq: 0xa,*,*] */ 393 #define SG_LIB_CAT_ABORTED_COMMAND 11 /* interpreted from sense buffer */ 394 /* [sk,asc,ascq: 0xb,! 0x10,*] */ 395 #define SG_LIB_CAT_MISCOMPARE 14 /* sense key, probably verify */ 396 /* [sk,asc,ascq: 0xe,*,*] */ 397 #define SG_LIB_CAT_NO_SENSE 20 /* sense data with key of "no sense" */ 398 /* [sk,asc,ascq: 0x0,*,*] */ 399 #define SG_LIB_CAT_RECOVERED 21 /* Successful command after recovered err */ 400 /* [sk,asc,ascq: 0x1,*,*] */ 401 #define SG_LIB_CAT_RES_CONFLICT SAM_STAT_RESERVATION_CONFLICT 402 /* 24: this is a SCSI status, not sense. */ 403 /* It indicates reservation by another */ 404 /* machine blocks this command */ 405 #define SG_LIB_CAT_CONDITION_MET 25 /* SCSI status, not sense key. */ 406 /* Only from PRE-FETCH (SBC-4) */ 407 #define SG_LIB_CAT_BUSY 26 /* SCSI status, not sense. Invites retry */ 408 #define SG_LIB_CAT_TS_FULL 27 /* SCSI status, not sense. Wait then retry */ 409 #define SG_LIB_CAT_ACA_ACTIVE 28 /* SCSI status; ACA seldom used */ 410 #define SG_LIB_CAT_TASK_ABORTED 29 /* SCSI status, this command aborted by? */ 411 #define SG_LIB_CAT_PROTECTION 40 /* subset of aborted command (for PI, DIF) */ 412 /* [sk,asc,ascq: 0xb,0x10,*] */ 413 #define SG_LIB_NVME_STATUS 48 /* NVMe Status Field (SF) other than 0 */ 414 #define SG_LIB_WILD_RESID 49 /* Residual value for data-in transfer of a */ 415 /* SCSI command is nonsensical */ 416 #define SG_LIB_OS_BASE_ERR 50 /* in Linux: values found in: */ 417 /* include/uapi/asm-generic/errno-base.h */ 418 /* Example: ENOMEM reported as 62 (=50+12) */ 419 #define SG_LIB_CAT_MALFORMED 97 /* Response to SCSI command malformed */ 420 #define SG_LIB_CAT_SENSE 98 /* Something else is in the sense buffer */ 421 #define SG_LIB_CAT_OTHER 99 /* Some other error/warning has occurred */ 422 /* (e.g. a transport or driver error) */ 423 424 /* Returns a SG_LIB_CAT_* value. If cannot decode sense_buffer or a less 425 * common sense key then return SG_LIB_CAT_SENSE .*/ 426 int sg_err_category_sense(const unsigned char * sense_buffer, int sb_len); 427 428 /* Here are some additional sense data categories that are not returned 429 * by sg_err_category_sense() but are returned by some related functions. */ 430 #define SG_LIB_CAT_ILLEGAL_REQ_WITH_INFO 17 /* Illegal request (other than */ 431 /* invalid opcode) plus 'info' field: */ 432 /* [sk,asc,ascq: 0x5,*,*] */ 433 #define SG_LIB_CAT_MEDIUM_HARD_WITH_INFO 18 /* medium or hardware error */ 434 /* sense key plus 'info' field: */ 435 /* [sk,asc,ascq: 0x3/0x4,*,*] */ 436 #define SG_LIB_CAT_PROTECTION_WITH_INFO 41 /* aborted command sense key, */ 437 /* protection plus 'info' field: */ 438 /* [sk,asc,ascq: 0xb,0x10,*] */ 439 #define SG_LIB_CAT_TIMEOUT 33 440 441 /* Yield string associated with sense category. Returns 'buff' (or pointer 442 * to "Bad sense category" if 'buff' is NULL). If sense_cat unknown then 443 * yield "Sense category: <sense_cat>" string. */ 444 const char * sg_get_category_sense_str(int sense_cat, int buff_len, 445 char * buff, int verbose); 446 447 448 /* Iterates to next designation descriptor in the device identification 449 * VPD page. The 'initial_desig_desc' should point to start of first 450 * descriptor with 'page_len' being the number of valid bytes in that 451 * and following descriptors. To start, 'off' should point to a negative 452 * value, thereafter it should point to the value yielded by the previous 453 * call. If 0 returned then 'initial_desig_desc + *off' should be a valid 454 * descriptor; returns -1 if normal end condition and -2 for an abnormal 455 * termination. Matches association, designator_type and/or code_set when 456 * any of those values are greater than or equal to zero. */ 457 int sg_vpd_dev_id_iter(const unsigned char * initial_desig_desc, int page_len, 458 int * off, int m_assoc, int m_desig_type, 459 int m_code_set); 460 461 462 /* <<< General purpose (i.e. not SCSI specific) utility functions >>> */ 463 464 /* Always returns valid string even if errnum is wild (or library problem). 465 * If errnum is negative, flip its sign. */ 466 char * safe_strerror(int errnum); 467 468 469 /* Print (to stdout) 'str' of bytes in hex, 16 bytes per line optionally 470 * followed at the right hand side of the line with an ASCII interpretation. 471 * Each line is prefixed with an address, starting at 0 for str[0]..str[15]. 472 * All output numbers are in hex. 'no_ascii' allows for 3 output types: 473 * > 0 each line has address then up to 16 ASCII-hex bytes 474 * = 0 in addition, the bytes are listed in ASCII to the right 475 * < 0 only the ASCII-hex bytes are listed (i.e. without address) 476 */ 477 void dStrHex(const char * str, int len, int no_ascii); 478 479 /* Print (to sg_warnings_strm (stderr)) 'str' of bytes in hex, 16 bytes per 480 * line optionally followed at right by its ASCII interpretation. Same 481 * logic as dStrHex() with different output stream (i.e. stderr). */ 482 void dStrHexErr(const char * str, int len, int no_ascii); 483 484 /* Read 'len' bytes from 'str' and output as ASCII-Hex bytes (space 485 * separated) to 'b' not to exceed 'b_len' characters. Each line 486 * starts with 'leadin' (NULL for no leadin) and there are 16 bytes 487 * per line with an extra space between the 8th and 9th bytes. 'format' 488 * is 0 for repeat in printable ASCII ('.' for non printable chars) to 489 * right of each line; 1 don't (so just output ASCII hex). Returns 490 * number of bytes written to 'b' excluding the trailing '\0'. */ 491 int dStrHexStr(const char * str, int len, const char * leadin, int format, 492 int cb_len, char * cbp); 493 494 /* The following 3 functions are equivalent to dStrHex(), dStrHexErr() and 495 * dStrHexStr() respectively. The difference is the type of the first of 496 * argument: uint8_t instead of char. The name of the argument is changed 497 * to b_str to stress it is a pointer to the start of a binary string. */ 498 void hex2stdout(const uint8_t * b_str, int len, int no_ascii); 499 void hex2stderr(const uint8_t * b_str, int len, int no_ascii); 500 int hex2str(const uint8_t * b_str, int len, const char * leadin, int format, 501 int cb_len, char * cbp); 502 503 /* Returns true when executed on big endian machine; else returns false. 504 * Useful for displaying ATA identify words (which need swapping on a 505 * big endian machine). */ 506 bool sg_is_big_endian(); 507 508 /* Returns true if byte sequence starting at bp with a length of b_len is 509 * all zeros (for sg_all_zeros()) or all 0xff_s (for sg_all_ffs()); 510 * otherwise returns false. If bp is NULL ir b_len <= 0 returns false. */ 511 bool sg_all_zeros(const uint8_t * bp, int b_len); 512 bool sg_all_ffs(const uint8_t * bp, int b_len); 513 514 /* Extract character sequence from ATA words as in the model string 515 * in a IDENTIFY DEVICE response. Returns number of characters 516 * written to 'ochars' before 0 character is found or 'num' words 517 * are processed. */ 518 int sg_ata_get_chars(const uint16_t * word_arr, int start_word, 519 int num_words, bool is_big_endian, char * ochars); 520 521 /* Print (to stdout) 16 bit 'words' in hex, 8 words per line optionally 522 * followed at the right hand side of the line with an ASCII interpretation 523 * (pairs of ASCII characters in big endian order (upper first)). 524 * Each line is prefixed with an address, starting at 0. 525 * All output numbers are in hex. 'no_ascii' allows for 3 output types: 526 * > 0 each line has address then up to 8 ASCII-hex words 527 * = 0 in addition, the words are listed in ASCII pairs to the right 528 * = -1 only the ASCII-hex words are listed (i.e. without address) 529 * = -2 only the ASCII-hex words, formatted for "hdparm --Istdin" 530 * < -2 same as -1 531 * If 'swapb' is true then bytes in each word swapped. Needs to be set 532 * for ATA IDENTIFY DEVICE response on big-endian machines. 533 */ 534 void dWordHex(const uint16_t * words, int num, int no_ascii, bool swapb); 535 536 /* If the number in 'buf' can not be decoded or the multiplier is unknown 537 * then -1 is returned. Accepts a hex prefix (0x or 0X) or a 'h' (or 'H') 538 * suffix. Otherwise a decimal multiplier suffix may be given. Recognised 539 * multipliers: c C *1; w W *2; b B *512; k K KiB *1,024; 540 * KB *1,000; m M MiB *1,048,576; MB *1,000,000; g G GiB *1,073,741,824; 541 * GB *1,000,000,000 and <n>x<m> which multiplies <n> by <m> . Ignore leading 542 * spaces and tabs; accept comma, hyphen, space, tab and hash as terminator. 543 */ 544 int sg_get_num(const char * buf); 545 546 /* If the number in 'buf' can not be decoded then -1 is returned. Accepts a 547 * hex prefix (0x or 0X) or a 'h' (or 'H') suffix; otherwise decimal is 548 * assumed. Does not accept multipliers. Accept a comma (","), hyphen ("-"), 549 * a whitespace or newline as terminator. Only decimal numbers can represent 550 * negative numbers and '-1' must be treated separately. */ 551 int sg_get_num_nomult(const char * buf); 552 553 /* If the number in 'buf' can not be decoded or the multiplier is unknown 554 * then -1LL is returned. Accepts a hex prefix (0x or 0X) or a 'h' (or 'H') 555 * suffix. Otherwise a decimal multiplier suffix may be given. In addition 556 * to supporting the multipliers of sg_get_num(), this function supports: 557 * t T TiB *(2**40); TB *(10**12); p P PiB *(2**50); PB *(10**15) . 558 * Ignore leading spaces and tabs; accept comma, hyphen, space, tab and hash 559 * as terminator. */ 560 int64_t sg_get_llnum(const char * buf); 561 562 /* If the number in 'buf' can not be decoded then -1 is returned. Accepts a 563 * hex prefix (0x or 0X) or a 'h' (or 'H') suffix; otherwise decimal is 564 * assumed. Does not accept multipliers. Accept a comma (","), hyphen ("-"), 565 * a whitespace or newline as terminator. Only decimal numbers can represent 566 * negative numbers and '-1' must be treated separately. */ 567 int64_t sg_get_llnum_nomult(const char * buf); 568 569 /* Returns pointer to heap (or NULL) that is aligned to a align_to byte 570 * boundary. Sends back *buff_to_free pointer in third argument that may be 571 * different from the return value. If it is different then the *buff_to_free 572 * pointer should be freed (rather than the returned value) when the heap is 573 * no longer needed. If align_to is 0 then aligns to OS's page size. Sets all 574 * returned heap to zeros. If num_bytes is 0 then set to page size. */ 575 uint8_t * sg_memalign(uint32_t num_bytes, uint32_t align_to, 576 uint8_t ** buff_to_free, bool vb); 577 578 /* Returns OS page size in bytes. If uncertain returns 4096. */ 579 uint32_t sg_get_page_size(void); 580 581 /* If os_err_num is within bounds then the returned value is 'os_err_num + 582 * SG_LIB_OS_BASE_ERR' otherwise -1 is returned. If os_err_num is 0 then 0 583 * is returned. */ 584 int sg_convert_errno(int os_err_num); 585 586 587 /* <<< Architectural support functions [is there a better place?] >>> */ 588 589 /* Non Unix OSes distinguish between text and binary files. 590 * Set text mode on fd. Does nothing in Unix. Returns negative number on 591 * failure. */ 592 int sg_set_text_mode(int fd); 593 594 /* Set binary mode on fd. Does nothing in Unix. Returns negative number on 595 * failure. */ 596 int sg_set_binary_mode(int fd); 597 598 #ifdef __cplusplus 599 } 600 #endif 601 602 #endif /* SG_LIB_H */ 603