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