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