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