1 #ifndef SG_PT_H 2 #define SG_PT_H 3 4 /* 5 * Copyright (c) 2005-2014 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 #include <stdint.h> 12 13 #ifdef __cplusplus 14 extern "C" { 15 #endif 16 17 /* This declaration hides the fact that each implementation has its own 18 * structure "derived" (using a C++ term) from this one. It compiles 19 * because 'struct sg_pt_base' is only referenced (by pointer: 'objp') 20 * in this interface. An instance of this structure represents the 21 * context of one SCSI command. */ 22 struct sg_pt_base; 23 24 25 /* The format of the version string is like this: "2.01 20090201". 26 * The leading digit will be incremented if this interface changes 27 * in a way that may impact backward compatibility. */ 28 const char * scsi_pt_version(); 29 30 31 /* Returns >= 0 if successful. If error in Unix returns negated errno. */ 32 int scsi_pt_open_device(const char * device_name, int read_only, int verbose); 33 34 /* Similar to scsi_pt_open_device() but takes Unix style open flags OR-ed 35 * together. Returns valid file descriptor( >= 0 ) if successful, otherwise 36 * returns -1 or a negated errno. 37 * In Win32 O_EXCL translated to equivalent. */ 38 int scsi_pt_open_flags(const char * device_name, int flags, int verbose); 39 40 /* Returns 0 if successful. If error in Unix returns negated errno. */ 41 int scsi_pt_close_device(int device_fd); 42 43 44 /* Creates an object that can be used to issue one or more SCSI commands 45 * (or task management functions). Returns NULL if problem. 46 * Once this object has been created it should be destroyed with 47 * destruct_scsi_pt_obj() when it is no longer needed. */ 48 struct sg_pt_base * construct_scsi_pt_obj(void); 49 50 /* Clear state information held in *objp . This allows this object to be 51 * used to issue more than one SCSI command. */ 52 void clear_scsi_pt_obj(struct sg_pt_base * objp); 53 54 /* Set the CDB (command descriptor block) */ 55 void set_scsi_pt_cdb(struct sg_pt_base * objp, const unsigned char * cdb, 56 int cdb_len); 57 /* Set the sense buffer and the maximum length that it can handle */ 58 void set_scsi_pt_sense(struct sg_pt_base * objp, unsigned char * sense, 59 int max_sense_len); 60 /* Set a pointer and length to be used for data transferred from device */ 61 void set_scsi_pt_data_in(struct sg_pt_base * objp, /* from device */ 62 unsigned char * dxferp, int dxfer_len); 63 /* Set a pointer and length to be used for data transferred to device */ 64 void set_scsi_pt_data_out(struct sg_pt_base * objp, /* to device */ 65 const unsigned char * dxferp, int dxfer_len); 66 /* The following "set_"s implementations may be dummies */ 67 void set_scsi_pt_packet_id(struct sg_pt_base * objp, int pack_id); 68 void set_scsi_pt_tag(struct sg_pt_base * objp, uint64_t tag); 69 void set_scsi_pt_task_management(struct sg_pt_base * objp, int tmf_code); 70 void set_scsi_pt_task_attr(struct sg_pt_base * objp, int attribute, 71 int priority); 72 73 /* Following is a guard which is defined when set_scsi_pt_flags() is 74 * present. Older versions of this library may not have this function. */ 75 #define SCSI_PT_FLAGS_FUNCTION 1 76 /* If neither QUEUE_AT_HEAD nor QUEUE_AT_TAIL are given, or both 77 * are given, use the pass-through default. */ 78 #define SCSI_PT_FLAGS_QUEUE_AT_TAIL 0x10 79 #define SCSI_PT_FLAGS_QUEUE_AT_HEAD 0x20 80 /* Set (potentially OS dependant) flags for pass-through mechanism. 81 * Apart from contradictions, flags can be OR-ed together. */ 82 void set_scsi_pt_flags(struct sg_pt_base * objp, int flags); 83 84 #define SCSI_PT_DO_START_OK 0 85 #define SCSI_PT_DO_BAD_PARAMS 1 86 #define SCSI_PT_DO_TIMEOUT 2 87 /* If OS error prior to or during command submission then returns negated 88 * error value (e.g. Unix '-errno'). This includes interrupted system calls 89 * (e.g. by a signal) in which case -EINTR would be returned. Note that 90 * system call errors also can be fetched with get_scsi_pt_os_err(). 91 * Return 0 if okay (i.e. at the very least: command sent). Positive 92 * return values are errors (see SCSI_PT_DO_* defines). */ 93 int do_scsi_pt(struct sg_pt_base * objp, int fd, int timeout_secs, 94 int verbose); 95 96 #define SCSI_PT_RESULT_GOOD 0 97 #define SCSI_PT_RESULT_STATUS 1 /* other than GOOD and CHECK CONDITION */ 98 #define SCSI_PT_RESULT_SENSE 2 99 #define SCSI_PT_RESULT_TRANSPORT_ERR 3 100 #define SCSI_PT_RESULT_OS_ERR 4 101 /* highest numbered applicable category returned */ 102 int get_scsi_pt_result_category(const struct sg_pt_base * objp); 103 104 /* If not available return 0 */ 105 int get_scsi_pt_resid(const struct sg_pt_base * objp); 106 /* Returns SCSI status value (from device that received the 107 command). */ 108 int get_scsi_pt_status_response(const struct sg_pt_base * objp); 109 /* Actual sense length returned. If sense data is present but 110 actual sense length is not known, return 'max_sense_len' */ 111 int get_scsi_pt_sense_len(const struct sg_pt_base * objp); 112 /* If not available return 0 */ 113 int get_scsi_pt_os_err(const struct sg_pt_base * objp); 114 char * get_scsi_pt_os_err_str(const struct sg_pt_base * objp, int max_b_len, 115 char * b); 116 /* If not available return 0 */ 117 int get_scsi_pt_transport_err(const struct sg_pt_base * objp); 118 char * get_scsi_pt_transport_err_str(const struct sg_pt_base * objp, 119 int max_b_len, char * b); 120 121 /* If not available return -1 */ 122 int get_scsi_pt_duration_ms(const struct sg_pt_base * objp); 123 124 125 /* Should be invoked once per objp after other processing is complete in 126 * order to clean up resources. For ever successful construct_scsi_pt_obj() 127 * call there should be one destruct_scsi_pt_obj(). */ 128 void destruct_scsi_pt_obj(struct sg_pt_base * objp); 129 130 #ifdef SG_LIB_WIN32 131 #define SG_LIB_WIN32_DIRECT 1 132 133 /* Request SPT direct interface when state_direct is 1, state_direct set 134 * to 0 for the SPT indirect interface. Default setting selected by build 135 * (i.e. library compile time) and is usually indirect. */ 136 void scsi_pt_win32_direct(int state_direct); 137 138 /* Returns current SPT interface state, 1 for direct, 0 for indirect */ 139 int scsi_pt_win32_spt_state(void); 140 141 #endif 142 143 #ifdef __cplusplus 144 } 145 #endif 146 147 #endif 148