1/*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License as
4 * published by the Free Software Foundation; either version 2 of
5 * the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
15 * MA 02111-1307 USA
16 */
17#ifndef SG_PT_H
18#define SG_PT_H
19
20/*
21 * Copyright (c) 2005-2007 Douglas Gilbert.
22 * All rights reserved.
23 *
24 * Redistribution and use in source and binary forms, with or without
25 * modification, are permitted provided that the following conditions
26 * are met:
27 * 1. Redistributions of source code must retain the above copyright
28 *    notice, this list of conditions and the following disclaimer.
29 * 2. Redistributions in binary form must reproduce the above copyright
30 *    notice, this list of conditions and the following disclaimer in the
31 *    documentation and/or other materials provided with the distribution.
32 * 3. The name of the author may not be used to endorse or promote products
33 *    derived from this software without specific prior written permission.
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
36 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
39 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
41 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
43 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45 * SUCH DAMAGE.
46 *
47 */
48
49#ifdef __cplusplus
50extern "C" {
51#endif
52
53/* This declaration hides the fact that each implementation has its own
54   structure "derived" (using a C++ term) from this one. It compiles
55   because 'struct sg_pt_base' is only referenced (by pointer: 'objp')
56   in this interface. An instance of this structure represents the
57   context of one SCSI command. */
58struct sg_pt_base;
59
60
61
62/* Returns >= 0 if successful. If error in Unix returns negated errno. */
63extern int scsi_pt_open_device(const char * device_name, int read_only,
64                               int verbose);
65
66/* Returns 0 if successful. If error in Unix returns negated errno. */
67extern int scsi_pt_close_device(int device_fd);
68
69
70/* Create one struct sg_pt_base object per SCSI command issued */
71extern struct sg_pt_base * construct_scsi_pt_obj(void);
72
73/* Only invoke once per objp */
74extern void set_scsi_pt_cdb(struct sg_pt_base * objp,
75                            const unsigned char * cdb, int cdb_len);
76/* Only invoke once per objp. Zeroes given 'sense' buffer. */
77extern void set_scsi_pt_sense(struct sg_pt_base * objp, unsigned char * sense,
78                              int max_sense_len);
79/* Invoke at most once per objp */
80extern void set_scsi_pt_data_in(struct sg_pt_base * objp,   /* from device */
81                                unsigned char * dxferp, int dxfer_len);
82/* Invoke at most once per objp */
83extern void set_scsi_pt_data_out(struct sg_pt_base * objp,    /* to device */
84                                 const unsigned char * dxferp, int dxfer_len);
85/* The following "set_"s implementations may be dummies */
86extern void set_scsi_pt_packet_id(struct sg_pt_base * objp, int pack_id);
87extern void set_scsi_pt_tag(struct sg_pt_base * objp, unsigned long long tag);
88extern void set_scsi_pt_task_management(struct sg_pt_base * objp,
89                                        int tmf_code);
90extern void set_scsi_pt_task_attr(struct sg_pt_base * objp, int attribute,
91                                  int priority);
92
93#define SCSI_PT_DO_START_OK 0
94#define SCSI_PT_DO_BAD_PARAMS 1
95#define SCSI_PT_DO_TIMEOUT 2
96/* If OS start error, negated error value (e.g. Unix '-errno') returned,
97   return 0 if okay (i.e. at the very least: command sent). Positive
98   return values are errors (see SCSI_PT_DO_* defines). */
99extern int do_scsi_pt(struct sg_pt_base * objp, int fd, int timeout_secs,
100                      int verbose);
101
102#define SCSI_PT_RESULT_GOOD 0
103#define SCSI_PT_RESULT_STATUS 1 /* other than GOOD and CHECK CONDITION */
104#define SCSI_PT_RESULT_SENSE 2
105#define SCSI_PT_RESULT_TRANSPORT_ERR 3
106#define SCSI_PT_RESULT_OS_ERR 4
107/* highest numbered applicable category returned */
108extern int get_scsi_pt_result_category(const struct sg_pt_base * objp);
109
110/* If not available return 0 */
111extern int get_scsi_pt_resid(const struct sg_pt_base * objp);
112/* Returns SCSI status value (from device that received the
113   command). */
114extern int get_scsi_pt_status_response(const struct sg_pt_base * objp);
115/* Actual sense length returned. If sense data is present but
116   actual sense length is not known, return 'max_sense_len' */
117extern int get_scsi_pt_sense_len(const struct sg_pt_base * objp);
118/* If not available return 0 */
119extern int get_scsi_pt_os_err(const struct sg_pt_base * objp);
120extern char * get_scsi_pt_os_err_str(const struct sg_pt_base * objp,
121                                     int max_b_len, char * b);
122/* If not available return 0 */
123extern int get_scsi_pt_transport_err(const struct sg_pt_base * objp);
124extern char * get_scsi_pt_transport_err_str(const struct sg_pt_base * objp,
125                                            int max_b_len, char * b);
126
127/* If not available return -1 */
128extern int get_scsi_pt_duration_ms(const struct sg_pt_base * objp);
129
130
131/* Should be invoked once per objp after other processing is complete in
132   order to clean up resources. For ever successful construct_scsi_pt_obj()
133   call there should be one destruct_scsi_pt_obj().  */
134extern void destruct_scsi_pt_obj(struct sg_pt_base * objp);
135
136#ifdef __cplusplus
137}
138#endif
139
140#endif
141