9d5952dad8a5fe6b103ca3b7c84eecbfb4d9db53
[people/dverkamp/gpxe.git] / src / include / gpxe / scsi.h
1 #ifndef _GPXE_SCSI_H
2 #define _GPXE_SCSI_H
3
4 #include <stdint.h>
5 #include <gpxe/blockdev.h>
6 #include <gpxe/uaccess.h>
7
8 /** @file
9  *
10  * SCSI devices
11  *
12  */
13
14 /**
15  * @defgroup scsiops SCSI operation codes
16  * @{
17  */
18
19 #define SCSI_OPCODE_READ_10             0x28    /**< READ (10) */
20 #define SCSI_OPCODE_READ_16             0x88    /**< READ (16) */
21 #define SCSI_OPCODE_WRITE_10            0x2a    /**< WRITE (10) */
22 #define SCSI_OPCODE_WRITE_16            0x8a    /**< WRITE (16) */
23 #define SCSI_OPCODE_READ_CAPACITY_10    0x25    /**< READ CAPACITY (10) */
24 #define SCSI_OPCODE_SERVICE_ACTION_IN   0x9e    /**< SERVICE ACTION IN */
25 #define SCSI_SERVICE_ACTION_READ_CAPACITY_16 0x10 /**< READ CAPACITY (16) */
26
27 /** @} */
28
29 /**
30  * @defgroup scsiflags SCSI flags
31  * @{
32  */
33
34 #define SCSI_FL_FUA_NV          0x02    /**< Force unit access to NVS */
35 #define SCSI_FL_FUA             0x08    /**< Force unit access */
36 #define SCSI_FL_DPO             0x10    /**< Disable cache page out */
37
38 /** @} */
39
40 /**
41  * @defgroup scsicdbs SCSI command data blocks
42  * @{
43  */
44
45 /** A SCSI "READ (10)" CDB */
46 struct scsi_cdb_read_10 {
47         /** Opcode (0x28) */
48         uint8_t opcode;
49         /** Flags */
50         uint8_t flags;
51         /** Start address
52          *
53          * This is a logical block number, in big-endian order.
54          */
55         uint32_t lba;
56         /** Group number */
57         uint8_t group;
58         /** Transfer length
59          *
60          * This is a logical block count, in big-endian order.
61          */
62         uint16_t len;
63         /** Control byte */
64         uint8_t control;
65 } __attribute__ (( packed ));
66
67 /** A SCSI "READ (16)" CDB */
68 struct scsi_cdb_read_16 {
69         /** Opcode (0x88) */
70         uint8_t opcode;
71         /** Flags */
72         uint8_t flags;
73         /** Start address
74          *
75          * This is a logical block number, in big-endian order.
76          */
77         uint64_t lba;
78         /** Transfer length
79          *
80          * This is a logical block count, in big-endian order.
81          */
82         uint32_t len;
83         /** Group number */
84         uint8_t group;
85         /** Control byte */
86         uint8_t control;
87 } __attribute__ (( packed ));
88
89 /** A SCSI "WRITE (10)" CDB */
90 struct scsi_cdb_write_10 {
91         /** Opcode (0x2a) */
92         uint8_t opcode;
93         /** Flags */
94         uint8_t flags;
95         /** Start address
96          *
97          * This is a logical block number, in big-endian order.
98          */
99         uint32_t lba;
100         /** Group number */
101         uint8_t group;
102         /** Transfer length
103          *
104          * This is a logical block count, in big-endian order.
105          */
106         uint16_t len;
107         /** Control byte */
108         uint8_t control;
109 } __attribute__ (( packed ));
110
111 /** A SCSI "WRITE (16)" CDB */
112 struct scsi_cdb_write_16 {
113         /** Opcode (0x8a) */
114         uint8_t opcode;
115         /** Flags */
116         uint8_t flags;
117         /** Start address
118          *
119          * This is a logical block number, in big-endian order.
120          */
121         uint64_t lba;
122         /** Transfer length
123          *
124          * This is a logical block count, in big-endian order.
125          */
126         uint32_t len;
127         /** Group number */
128         uint8_t group;
129         /** Control byte */
130         uint8_t control;
131 } __attribute__ (( packed ));
132
133 /** A SCSI "READ CAPACITY (10)" CDB */
134 struct scsi_cdb_read_capacity_10 {
135         /** Opcode (0x25) */
136         uint8_t opcode;
137         /** Reserved */
138         uint8_t reserved_a;
139         /** Logical block address
140          *
141          * Applicable only if the PMI bit is set.
142          */
143         uint32_t lba;
144         /** Reserved */
145         uint8_t reserved_b[3];
146         /** Control byte */
147         uint8_t control;        
148 } __attribute__ (( packed ));
149
150 /** SCSI "READ CAPACITY (10)" parameter data */
151 struct scsi_capacity_10 {
152         /** Maximum logical block number */
153         uint32_t lba;
154         /** Block length in bytes */
155         uint32_t blksize;
156 } __attribute__ (( packed ));
157
158 /** A SCSI "READ CAPACITY (16)" CDB */
159 struct scsi_cdb_read_capacity_16 {
160         /** Opcode (0x9e) */
161         uint8_t opcode;
162         /** Service action */
163         uint8_t service_action;
164         /** Logical block address
165          *
166          * Applicable only if the PMI bit is set.
167          */
168         uint64_t lba;
169         /** Transfer length
170          *
171          * This is the size of the data-in buffer, in bytes.
172          */
173         uint32_t len;
174         /** Reserved */
175         uint8_t reserved;
176         /** Control byte */
177         uint8_t control;
178 } __attribute__ (( packed ));
179
180 /** SCSI "READ CAPACITY (16)" parameter data */
181 struct scsi_capacity_16 {
182         /** Maximum logical block number */
183         uint64_t lba;
184         /** Block length in bytes */
185         uint32_t blksize;
186         /** Reserved */
187         uint8_t reserved[20];
188 } __attribute__ (( packed ));
189
190 /** A SCSI Command Data Block */
191 union scsi_cdb {
192         struct scsi_cdb_read_10 read10;
193         struct scsi_cdb_read_16 read16;
194         struct scsi_cdb_write_10 write10;
195         struct scsi_cdb_write_16 write16;
196         struct scsi_cdb_read_capacity_10 readcap10;
197         struct scsi_cdb_read_capacity_16 readcap16;
198         unsigned char bytes[16];
199 };
200
201 /** printf() format for dumping a scsi_cdb */
202 #define SCSI_CDB_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:" \
203                         "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x"
204
205 /** printf() parameters for dumping a scsi_cdb */
206 #define SCSI_CDB_DATA(cdb)                                                \
207         (cdb).bytes[0], (cdb).bytes[1], (cdb).bytes[2], (cdb).bytes[3],   \
208         (cdb).bytes[4], (cdb).bytes[5], (cdb).bytes[6], (cdb).bytes[7],   \
209         (cdb).bytes[8], (cdb).bytes[9], (cdb).bytes[10], (cdb).bytes[11], \
210         (cdb).bytes[12], (cdb).bytes[13], (cdb).bytes[14], (cdb).bytes[15]
211
212 /** @} */
213
214 /** A SCSI command */
215 struct scsi_command {
216         /** CDB for this command */
217         union scsi_cdb cdb;
218         /** Data-out buffer (may be NULL) */
219         userptr_t data_out;
220         /** Data-out buffer length
221          *
222          * Must be zero if @c data_out is NULL
223          */
224         size_t data_out_len;
225         /** Data-in buffer (may be NULL) */
226         userptr_t data_in;
227         /** Data-in buffer length
228          *
229          * Must be zero if @c data_in is NULL
230          */
231         size_t data_in_len;
232         /** SCSI statua code */
233         uint8_t status;
234         /** SCSI sense response code */
235         uint8_t sense_response;
236 };
237
238 /** A SCSI device */
239 struct scsi_device {
240         /** Block device interface */
241         struct block_device blockdev;
242         /** Logical unit number (LUN)
243          *
244          * This is a four-level LUN as specified by SAM-2, in
245          * big-endian order.
246          */
247         uint64_t lun;
248         /**
249          * Issue SCSI command
250          *
251          * @v scsi              SCSI device
252          * @v command           SCSI command
253          * @ret rc              Return status code
254          *
255          * Note that a successful return status code indicates only
256          * that the SCSI command completed.  The caller must check the
257          * status field in the command structure to see if, for
258          * example, the device returned CHECK CONDITION or some other
259          * non-success status code.
260          */
261         int ( * command ) ( struct scsi_device *scsi,
262                             struct scsi_command *command );
263 };
264
265 extern int init_scsidev ( struct scsi_device *scsi );
266
267 #endif /* _GPXE_SCSI_H */