d5620ef80732e6b17e569d57ea3b62443dac5f3d
[people/xl0/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 /**
9  * @defgroup scsiops SCSI operation codes
10  * @{
11  */
12
13 #define SCSI_OPCODE_READ_16             0x88    /**< READ (16) */
14 #define SCSI_OPCODE_WRITE_16            0x8a    /**< WRITE (16) */
15 #define SCSI_OPCODE_READ_CAPACITY_10    0x25    /**< READ CAPACITY (10) */
16 #define SCSI_OPCODE_SERVICE_ACTION_IN   0x9e    /**< SERVICE ACTION IN */
17 #define SCSI_SERVICE_ACTION_READ_CAPACITY_16 0x10 /**< READ CAPACITY (16) */
18
19 /** @} */
20
21 /**
22  * @defgroup scsiflags SCSI flags
23  * @{
24  */
25
26 #define SCSI_FL_FUA_NV          0x02    /**< Force unit access to NVS */
27 #define SCSI_FL_FUA             0x08    /**< Force unit access */
28 #define SCSI_FL_DPO             0x10    /**< Disable cache page out */
29
30 /** @} */
31
32 /**
33  * @defgroup scsicdbs SCSI command data blocks
34  * @{
35  */
36
37 /** A SCSI "READ (16)" CDB */
38 struct scsi_cdb_read_16 {
39         /** Opcode (0x88) */
40         uint8_t opcode;
41         /** Flags */
42         uint8_t flags;
43         /** Start address
44          *
45          * This is a logical block number, in big-endian order.
46          */
47         uint64_t lba;
48         /** Transfer length
49          *
50          * This is a logical block count, in big-endian order.
51          */
52         uint32_t len;
53         /** Group number */
54         uint8_t group;
55         /** Control byte */
56         uint8_t control;
57 } __attribute__ (( packed ));
58
59 /** A SCSI "WRITE (16)" CDB */
60 struct scsi_cdb_write_16 {
61         /** Opcode (0x8a) */
62         uint8_t opcode;
63         /** Flags */
64         uint8_t flags;
65         /** Start address
66          *
67          * This is a logical block number, in big-endian order.
68          */
69         uint64_t lba;
70         /** Transfer length
71          *
72          * This is a logical block count, in big-endian order.
73          */
74         uint32_t len;
75         /** Group number */
76         uint8_t group;
77         /** Control byte */
78         uint8_t control;
79 } __attribute__ (( packed ));
80
81 /** A SCSI "READ CAPACITY (10)" CDB */
82 struct scsi_cdb_read_capacity_10 {
83         /** Opcode (0x25) */
84         uint8_t opcode;
85         /** Reserved */
86         uint8_t reserved_a;
87         /** Logical block address
88          *
89          * Applicable only if the PMI bit is set.
90          */
91         uint32_t lba;
92         /** Reserved */
93         uint8_t reserved_b[3];
94         /** Control byte */
95         uint8_t control;        
96 } __attribute__ (( packed ));
97
98 /** SCSI "READ CAPACITY (10)" parameter data */
99 struct scsi_capacity_10 {
100         /** Maximum logical block number */
101         uint32_t lba;
102         /** Block length in bytes */
103         uint32_t blksize;
104 } __attribute__ (( packed ));
105
106 /** A SCSI "READ CAPACITY (16)" CDB */
107 struct scsi_cdb_read_capacity_16 {
108         /** Opcode (0x9e) */
109         uint8_t opcode;
110         /** Service action */
111         uint8_t service_action;
112         /** Logical block address
113          *
114          * Applicable only if the PMI bit is set.
115          */
116         uint64_t lba;
117         /** Transfer length
118          *
119          * This is the size of the data-in buffer, in bytes.
120          */
121         uint32_t len;
122         /** Reserved */
123         uint8_t reserved;
124         /** Control byte */
125         uint8_t control;
126 } __attribute__ (( packed ));
127
128 /** SCSI "READ CAPACITY (16)" parameter data */
129 struct scsi_capacity_16 {
130         /** Maximum logical block number */
131         uint64_t lba;
132         /** Block length in bytes */
133         uint32_t blksize;
134         /** Reserved */
135         uint8_t reserved[20];
136 } __attribute__ (( packed ));
137
138 /** A SCSI Command Data Block */
139 union scsi_cdb {
140         struct scsi_cdb_read_16 read16;
141         struct scsi_cdb_write_16 write16;
142         struct scsi_cdb_read_capacity_10 readcap10;
143         struct scsi_cdb_read_capacity_16 readcap16;
144         char bytes[16];
145 };
146
147 /** @} */
148
149 /** A SCSI command */
150 struct scsi_command {
151         /** CDB for this command */
152         union scsi_cdb cdb;
153         /** Data-out buffer (may be NULL) */
154         userptr_t data_out;
155         /** Data-out buffer length
156          *
157          * Must be zero if @c data_out is NULL
158          */
159         size_t data_out_len;
160         /** Data-in buffer (may be NULL) */
161         userptr_t data_in;
162         /** Data-in buffer length
163          *
164          * Must be zero if @c data_in is NULL
165          */
166         size_t data_in_len;
167         /** SCSI statua code */
168         uint8_t status;
169         /** SCSI sense response code */
170         uint8_t sense_response;
171 };
172
173 /** A SCSI device */
174 struct scsi_device {
175         /** Block device interface */
176         struct block_device blockdev;
177         /** Logical unit number (LUN)
178          *
179          * This is a four-level LUN as specified by SAM-2, in
180          * big-endian order.
181          */
182         uint64_t lun;
183         /**
184          * Issue SCSI command
185          *
186          * @v scsi              SCSI device
187          * @v command           SCSI command
188          * @ret rc              Return status code
189          *
190          * Note that a successful return status code indicates only
191          * that the SCSI command completed.  The caller must check the
192          * status field in the command structure to see if, for
193          * example, the device returned CHECK CONDITION or some other
194          * non-success status code.
195          */
196         int ( * command ) ( struct scsi_device *scsi,
197                             struct scsi_command *command );
198 };
199
200 extern int init_scsidev ( struct scsi_device *scsi );
201
202 #endif /* _GPXE_SCSI_H */