scsi.h 14 KB

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