1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2023-02-25     GuEe-GUI     the first version
9  */
10 
11 #ifndef __SCSI_H__
12 #define __SCSI_H__
13 
14 #include <rthw.h>
15 #include <rtthread.h>
16 #include <drivers/byteorder.h>
17 
18 #define RT_SCSI_LUN_SHIFT       5
19 
20 rt_packed(struct rt_scsi_unknow
21 {
22     rt_uint8_t opcode;
23 });
24 
25 rt_packed(struct rt_scsi_test_unit_ready
26 {
27     rt_uint8_t opcode;
28     rt_uint8_t reserved[4];
29     rt_uint8_t control;
30     rt_uint8_t pad[6];      /* To be ATAPI compatible */
31 });
32 
33 rt_packed(struct rt_scsi_inquiry
34 {
35     rt_uint8_t opcode;
36     rt_uint8_t config;      /* 7-2 Reserved, 1 Obsolete Formerly CMDDT, 0 EVPD */
37     rt_uint8_t page;        /* Page code if EVPD=1 */
38     rt_uint8_t reserved;
39     rt_uint8_t alloc_length;
40     rt_uint8_t control;
41     rt_uint8_t pad[6];      /* To be ATAPI compatible */
42 });
43 
44 rt_packed(struct rt_scsi_inquiry_data
45 {
46 #define RT_SCSI_DEVTYPE_MASK  31
47     rt_uint8_t devtype;
48 #define RT_SCSI_REMOVABLE_BIT 7
49     rt_uint8_t rmb;
50     rt_uint8_t reserved[2];
51     rt_uint8_t length;
52     rt_uint8_t reserved1[3];
53     char vendor[8];
54     char prodid[16];
55     char prodrev[4];
56 });
57 
58 rt_packed(struct rt_scsi_request_sense
59 {
60     rt_uint8_t opcode;
61     rt_uint8_t config;      /* 7-2 Reserved, 1 Obsolete, 0 SP */
62     rt_uint8_t reserved[2];
63     rt_uint8_t alloc_length;
64     rt_uint8_t control;
65     rt_uint8_t pad[6];      /* To be ATAPI compatible */
66 });
67 
68 rt_packed(struct rt_scsi_request_sense_data
69 {
70     rt_uint8_t error_code;  /* 7 Valid, 6-0 Err. code */
71     rt_uint8_t segment_number;
72     rt_uint8_t sense_key;   /* 7 FileMark, 6 EndOfMedia, 5 ILI, 4-0 sense key */
73     rt_be32_t information;
74     rt_uint8_t additional_sense_length;
75     rt_be32_t cmd_specific_info;
76     rt_uint8_t additional_sense_code;
77     rt_uint8_t additional_sense_code_qualifier;
78     rt_uint8_t field_replaceable_unit_code;
79     rt_uint8_t sense_key_specific[3];
80 });
81 
82 rt_packed(struct rt_scsi_read_capacity10
83 {
84     rt_uint8_t opcode;
85     rt_uint8_t config;              /* 7-1 Reserved, 0 Obsolete */
86     rt_be32_t logical_block_addr;   /* only if PMI=1 */
87     rt_uint8_t reserved[2];
88     rt_uint8_t pmi;
89     rt_uint8_t control;
90     rt_be16_t pad;                  /* To be ATAPI compatible */
91 });
92 
93 rt_packed(struct rt_scsi_read_capacity10_data
94 {
95     rt_be32_t last_block;
96     rt_be32_t block_size;
97 });
98 
99 rt_packed(struct rt_scsi_read_capacity16
100 {
101     rt_uint8_t opcode;
102     rt_uint8_t config;              /* 7-5 Reserved, 4-0 SERVICE ACTION 0x10 */
103     rt_be64_t logical_block_addr;   /* only if PMI=1 */
104     rt_be32_t alloc_len;
105     rt_uint8_t pmi;
106     rt_uint8_t control;
107 });
108 
109 rt_packed(struct rt_scsi_read_capacity16_data
110 {
111     rt_be64_t last_block;
112     rt_be32_t block_size;
113     rt_uint8_t pad[20];
114 });
115 
116 rt_packed(struct rt_scsi_read10
117 {
118     rt_uint8_t opcode;
119     rt_uint8_t config;      /* 7-5 RDPROTECT, 4 DPO, 3 FUA, 2 RARC, 1 Obsolete, 0 Obsolete */
120     rt_be32_t lba;
121     rt_uint8_t reserved;
122     rt_be16_t size;
123     rt_uint8_t reserved2;
124     rt_be16_t pad;
125 });
126 
127 rt_packed(struct rt_scsi_read12
128 {
129     rt_uint8_t opcode;
130     rt_uint8_t config;      /* 7-5 RDPROTECT, 4 DPO, 3 FUA, 2 RARC, 1 Obsolete, 0 Obsolete */
131     rt_be32_t lba;
132     rt_be32_t size;
133     rt_uint8_t reserved;
134     rt_uint8_t control;
135 });
136 
137 rt_packed(struct rt_scsi_read16
138 {
139     rt_uint8_t opcode;
140     rt_uint8_t config;      /* 7-5 RDPROTECT, 4 DPO, 3 FUA, 2 RARC, 1 Obsolete, 0 DLD2 */
141     rt_be64_t lba;
142     rt_be32_t size;
143     rt_uint8_t reserved;
144     rt_uint8_t control;
145 });
146 
147 rt_packed(struct rt_scsi_write10
148 {
149     rt_uint8_t opcode;
150     rt_uint8_t config;      /* 7-5 WRPROTECT, 4 DPO, 3 FUA, 2 Reserved, 1 Obsolete, 0 Obsolete */
151     rt_be32_t lba;
152     rt_uint8_t reserved;
153     rt_be16_t size;
154     rt_uint8_t reserved2;
155     rt_be16_t pad;
156 });
157 
158 rt_packed(struct rt_scsi_write12
159 {
160     rt_uint8_t opcode;
161     rt_uint8_t config;      /* 7-5 WRPROTECT, 4 DPO, 3 FUA, 2 Reserved, 1 Obsolete, 0 Obsolete */
162     rt_be32_t lba;
163     rt_be32_t size;
164     rt_uint8_t reserved;
165     rt_uint8_t control;
166 });
167 
168 rt_packed(struct rt_scsi_write16
169 {
170     rt_uint8_t opcode;
171     rt_uint8_t config;      /* 7-5 WRPROTECT, 4 DPO, 3 FUA, 2 Reserved, 1 Obsolete, 0 DLD2 */
172     rt_be64_t lba;
173     rt_be32_t size;
174     rt_uint8_t reserved;
175     rt_uint8_t control;
176 });
177 
178 rt_packed(struct rt_scsi_synchronize_cache10
179 {
180     rt_uint8_t opcode;
181     rt_uint8_t config;      /* 7-3 Reserved, 2 Obsolete, 1 IMMED, 0 Obsolete */
182     rt_be32_t lba;
183     rt_uint8_t reserved;
184     rt_be16_t size;
185     rt_uint8_t control;
186 });
187 
188 rt_packed(struct rt_scsi_synchronize_cache16
189 {
190     rt_uint8_t opcode;
191     rt_uint8_t config;      /* 7-3 Reserved, 2 Obsolete, 1 IMMED, 0 Obsolete */
192     rt_be64_t lba;
193     rt_be32_t size;
194     rt_uint8_t reserved;
195     rt_uint8_t control;
196 });
197 
198 #define RT_SCSI_UNMAP_SHIFT     3
199 
200 rt_packed(struct rt_scsi_write_same10
201 {
202     rt_uint8_t opcode;
203     rt_uint8_t config;      /* 7-5 WRPROTECT, 4 ANCHOR, 3 UNMAP, 2 Obsolete, 1 Obsolete, 0 Obsolete */
204     rt_be32_t lba;
205     rt_uint8_t reserved;
206     rt_be16_t size;
207     rt_uint8_t control;
208 });
209 
210 rt_packed(struct rt_scsi_write_same16
211 {
212     rt_uint8_t opcode;
213     rt_uint8_t config;      /* 7-5 WRPROTECT, 4 ANCHOR, 3 UNMAP, 2 Obsolete, 1 Obsolete, 0 NDOB */
214     rt_be64_t lba;
215     rt_be32_t size;
216     rt_uint8_t reserved;
217     rt_uint8_t control;
218 });
219 
220 #define RT_SCSI_PF_SHIFT        4
221 #define RT_SCSI_RTD_SHIFT       1
222 #define RT_SCSI_SP_SHIFT        0
223 
224 rt_packed(struct rt_scsi_mode_select6
225 {
226     rt_uint8_t opcode;
227     rt_uint8_t config;      /* 7-5 Reserved, 4 PF, 3-2 Reserved, 1 RTD, 0 SP */
228     rt_uint8_t reserved[2];
229     rt_uint8_t param_list_len;
230     rt_uint8_t control;
231 });
232 
233 rt_packed(struct rt_scsi_mode_select10
234 {
235     rt_uint8_t opcode;
236     rt_uint8_t config;      /* 7-5 Reserved, 4 PF, 3-1 Reserved, 0 SP */
237     rt_uint8_t reserved[5];
238     rt_be16_t param_list_len;
239     rt_uint8_t control;
240 });
241 
242 struct rt_scsi_mode_select_data
243 {
244     rt_uint32_t length;
245     rt_uint16_t block_descriptor_length;
246     rt_uint8_t medium_type;
247     rt_uint8_t device_specific;
248     rt_uint8_t header_length;
249     rt_uint8_t longlba:1;
250 };
251 
252 #define RT_SCSI_DBD_SHIFT       3
253 #define RT_SCSI_LLBAA_SHIFT     4
254 #define RT_SCSI_PC_SHIFT        6
255 #define RT_SCSI_PAGE_CODE_SHIFT 0
256 
257 rt_packed(struct rt_scsi_mode_sense6
258 {
259     rt_uint8_t opcode;
260     rt_uint8_t config;      /* 7-4 Reserved, 3 DBD, 2-0 Reserved */
261     rt_uint8_t page_control_code;
262     rt_uint8_t subpage_code;
263     rt_uint8_t allocation_len;
264     rt_uint8_t control;
265 });
266 
267 rt_packed(struct rt_scsi_mode_sense10
268 {
269     rt_uint8_t opcode;
270     rt_uint8_t config;      /* 7-5 Reserved, 4 LLBAA, 3 DBD, 2-0 Reserved */
271     rt_uint8_t page_control_code;
272     rt_uint8_t subpage_code;
273     rt_uint8_t reserved[3];
274     rt_be16_t allocation_len;
275     rt_uint8_t control;
276 });
277 
278 #define RT_SCSI_CMD_TEST_UNIT_READY     0x00
279 #define RT_SCSI_CMD_REQUEST_SENSE       0x03
280 #define RT_SCSI_CMD_INQUIRY             0x12
281 #define RT_SCSI_CMD_MODE_SELECT         0x15
282 #define RT_SCSI_CMD_MODE_SENSE          0x1a
283 #define RT_SCSI_CMD_READ_CAPACITY10     0x25
284 #define RT_SCSI_CMD_READ10              0x28
285 #define RT_SCSI_CMD_WRITE10             0x2a
286 #define RT_SCSI_CMD_SYNCHRONIZE_CACHE10 0x35
287 #define RT_SCSI_CMD_WRITE_SAME10        0x41
288 #define RT_SCSI_CMD_MODE_SELECT10       0x55
289 #define RT_SCSI_CMD_MODE_SENSE10        0x5a
290 #define RT_SCSI_CMD_READ16              0x88
291 #define RT_SCSI_CMD_WRITE16             0x8a
292 #define RT_SCSI_CMD_SYNCHRONIZE_CACHE16 0x91
293 #define RT_SCSI_CMD_WRITE_SAME16        0x93
294 #define RT_SCSI_CMD_READ_CAPACITY16     0x9e
295 #define RT_SCSI_CMD_READ12              0xa8
296 #define RT_SCSI_CMD_WRITE12             0xaa
297 
298 struct rt_scsi_cmd
299 {
300     union
301     {
302         struct rt_scsi_unknow unknow;
303         struct rt_scsi_test_unit_ready test_unit_ready;
304         struct rt_scsi_inquiry inquiry;
305         struct rt_scsi_request_sense request_sense;
306         struct rt_scsi_read_capacity10 read_capacity10;
307         struct rt_scsi_read_capacity16 read_capacity16;
308         struct rt_scsi_read10 read10;
309         struct rt_scsi_read12 read12;
310         struct rt_scsi_read16 read16;
311         struct rt_scsi_write10 write10;
312         struct rt_scsi_write12 write12;
313         struct rt_scsi_write16 write16;
314         struct rt_scsi_synchronize_cache10 synchronize_cache10;
315         struct rt_scsi_synchronize_cache16 synchronize_cache16;
316         struct rt_scsi_write_same10 write_same10;
317         struct rt_scsi_write_same16 write_same16;
318         struct rt_scsi_mode_select6 mode_select6;
319         struct rt_scsi_mode_select10 mode_select10;
320         struct rt_scsi_mode_sense6 mode_sense6;
321         struct rt_scsi_mode_sense10 mode_sense10;
322     } op;
323     rt_size_t op_size;
324 
325     union
326     {
327         struct
328         {
329             struct rt_scsi_inquiry_data inquiry;
330             struct rt_scsi_request_sense_data request_sense;
331             struct rt_scsi_read_capacity10_data read_capacity10;
332             struct rt_scsi_read_capacity16_data read_capacity16;
333         };
334         struct
335         {
336             void *ptr;
337             rt_size_t size;
338         };
339     } data;
340 };
341 
342 enum
343 {
344     SCSI_DEVICE_TYPE_DIRECT                     = 0x00, /* DiskPeripheral (GenDisk) */
345     SCSI_DEVICE_TYPE_SEQUENTIAL                 = 0x01, /* TapePeripheral */
346     SCSI_DEVICE_TYPE_PRINTER                    = 0x02, /* PrinterPeripheral (GenPrinter) */
347     SCSI_DEVICE_TYPE_PROCESSOR                  = 0x03, /* OtherPeripheral */
348     SCSI_DEVICE_TYPE_WRITE_ONCE_READ_MULTIPLE   = 0x04, /* WormPeripheral (GenWorm) */
349     SCSI_DEVICE_TYPE_CDROM                      = 0x05, /* CdRomPeripheral (GenCdRom) */
350     SCSI_DEVICE_TYPE_SCANNER                    = 0x06, /* ScannerPeripheral (GenScanner) */
351     SCSI_DEVICE_TYPE_OPTICAL                    = 0x07, /* OpticalDiskPeripheral (GenOptical) */
352     SCSI_DEVICE_TYPE_MEDIUM_CHANGER             = 0x08, /* MediumChangerPeripheral (ScsiChanger) */
353     SCSI_DEVICE_TYPE_COMMUNICATION              = 0x09, /* CommunicationsPeripheral (ScsiNet) */
354     SCSI_DEVICE_TYPE_ASC_PREPRESS_GRAPHICS10    = 0x0a, /* ASCPrePressGraphicsPeripheral (ScsiASCIT8) */
355     SCSI_DEVICE_TYPE_ASC_PREPRESS_GRAPHICS11    = 0x0b, /* ASCPrePressGraphicsPeripheral (ScsiASCIT8) */
356     SCSI_DEVICE_TYPE_ARRAY                      = 0x0c, /* ArrayPeripheral (ScsiArray) */
357     SCSI_DEVICE_TYPE_ENCLOSURE                  = 0x0d, /* EnclosurePeripheral (ScsiEnclosure) */
358     SCSI_DEVICE_TYPE_RBC                        = 0x0e, /* RBCPeripheral (ScsiRBC) */
359     SCSI_DEVICE_TYPE_CARDREADER                 = 0x0f, /* CardReaderPeripheral (ScsiCardReader) */
360     SCSI_DEVICE_TYPE_BRIDGE                     = 0x10, /* BridgePeripheral (ScsiBridge) */
361     SCSI_DEVICE_TYPE_OTHER                      = 0x11, /* OtherPeripheral (ScsiOther) */
362     SCSI_DEVICE_TYPE_MAX,
363 };
364 
365 struct rt_scsi_ops;
366 
367 struct rt_scsi_host
368 {
369     struct rt_device *dev;
370 
371     const struct rt_scsi_ops *ops;
372 
373     rt_size_t max_id;
374     rt_size_t max_lun;
375 
376     rt_list_t lun_nodes;
377 };
378 
379 struct rt_scsi_device
380 {
381     struct rt_scsi_host *host;
382 
383     rt_list_t list;
384 
385     rt_size_t id;
386     rt_size_t lun;
387     rt_uint32_t devtype;
388     rt_uint32_t removable;
389     rt_size_t last_block;
390     rt_size_t block_size;
391 
392     void *priv;
393 };
394 
395 struct rt_scsi_ops
396 {
397     rt_err_t (*reset)(struct rt_scsi_device *sdev);
398     rt_err_t (*transfer)(struct rt_scsi_device *sdev, struct rt_scsi_cmd *cmd);
399 };
400 
401 rt_err_t rt_scsi_host_register(struct rt_scsi_host *scsi);
402 rt_err_t rt_scsi_host_unregister(struct rt_scsi_host *scsi);
403 
rt_scsi_cmd_is_write(struct rt_scsi_cmd * cmd)404 rt_inline rt_bool_t rt_scsi_cmd_is_write(struct rt_scsi_cmd *cmd)
405 {
406     return cmd->op.write10.opcode == RT_SCSI_CMD_WRITE10 ||
407             cmd->op.write12.opcode == RT_SCSI_CMD_WRITE16 ||
408             cmd->op.write16.opcode == RT_SCSI_CMD_WRITE12;
409 }
410 
411 rt_err_t rt_scsi_request_sense(struct rt_scsi_device *sdev,
412         struct rt_scsi_request_sense_data *out_data);
413 
414 rt_err_t rt_scsi_test_unit_ready(struct rt_scsi_device *sdev);
415 rt_err_t rt_scsi_inquiry(struct rt_scsi_device *sdev,
416         struct rt_scsi_inquiry_data *out_data);
417 
418 rt_err_t rt_scsi_read_capacity10(struct rt_scsi_device *sdev,
419         struct rt_scsi_read_capacity10_data *out_data);
420 rt_err_t rt_scsi_read_capacity16(struct rt_scsi_device *sdev,
421         struct rt_scsi_read_capacity16_data *out_data);
422 
423 rt_err_t rt_scsi_read10(struct rt_scsi_device *sdev,
424         rt_off_t lba, void *buffer, rt_size_t size);
425 rt_err_t rt_scsi_read12(struct rt_scsi_device *sdev,
426         rt_off_t lba, void *buffer, rt_size_t size);
427 rt_err_t rt_scsi_read16(struct rt_scsi_device *sdev,
428         rt_off_t lba, void *buffer, rt_size_t size);
429 
430 rt_err_t rt_scsi_write10(struct rt_scsi_device *sdev,
431         rt_off_t lba, const void *buffer, rt_size_t size);
432 rt_err_t rt_scsi_write12(struct rt_scsi_device *sdev,
433         rt_off_t lba, const void *buffer, rt_size_t size);
434 rt_err_t rt_scsi_write16(struct rt_scsi_device *sdev,
435         rt_off_t lba, const void *buffer, rt_size_t size);
436 
437 rt_err_t rt_scsi_synchronize_cache10(struct rt_scsi_device *sdev,
438         rt_off_t lba, rt_size_t size);
439 rt_err_t rt_scsi_synchronize_cache16(struct rt_scsi_device *sdev,
440         rt_off_t lba, rt_size_t size);
441 
442 rt_err_t rt_scsi_write_same10(struct rt_scsi_device *sdev,
443         rt_off_t lba, rt_size_t size);
444 rt_err_t rt_scsi_write_same16(struct rt_scsi_device *sdev,
445         rt_off_t lba, rt_size_t size);
446 
447 rt_err_t rt_scsi_mode_select6(struct rt_scsi_device *sdev,
448         rt_uint8_t pf, rt_uint8_t sp, void *buffer, rt_size_t size,
449         struct rt_scsi_mode_select_data *data);
450 rt_err_t rt_scsi_mode_select10(struct rt_scsi_device *sdev,
451         rt_uint8_t pf, rt_uint8_t sp, void *buffer, rt_size_t size,
452         struct rt_scsi_mode_select_data *data);
453 
454 rt_err_t rt_scsi_mode_sense6(struct rt_scsi_device *sdev,
455         rt_uint8_t dbd, rt_uint8_t modepage, rt_uint8_t subpage, void *buffer, rt_size_t size,
456         struct rt_scsi_mode_select_data *data);
457 rt_err_t rt_scsi_mode_sense10(struct rt_scsi_device *sdev,
458         rt_uint8_t dbd, rt_uint8_t modepage, rt_uint8_t subpage, void *buffer, rt_size_t size,
459         struct rt_scsi_mode_select_data *data);
460 
461 #endif /* __SCSI_H__ */
462