Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. #ifndef _IPXE_SCSI_H
  2. #define _IPXE_SCSI_H
  3. #include <stdint.h>
  4. #include <ipxe/uaccess.h>
  5. #include <ipxe/interface.h>
  6. /** @file
  7. *
  8. * SCSI devices
  9. *
  10. */
  11. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  12. /** Maximum block for READ/WRITE (10) commands */
  13. #define SCSI_MAX_BLOCK_10 0xffffffffULL
  14. /**
  15. * @defgroup scsiops SCSI operation codes
  16. * @{
  17. */
  18. #define SCSI_OPCODE_READ_10 0x28 /**< READ (10) */
  19. #define SCSI_OPCODE_READ_16 0x88 /**< READ (16) */
  20. #define SCSI_OPCODE_WRITE_10 0x2a /**< WRITE (10) */
  21. #define SCSI_OPCODE_WRITE_16 0x8a /**< WRITE (16) */
  22. #define SCSI_OPCODE_READ_CAPACITY_10 0x25 /**< READ CAPACITY (10) */
  23. #define SCSI_OPCODE_SERVICE_ACTION_IN 0x9e /**< SERVICE ACTION IN */
  24. #define SCSI_SERVICE_ACTION_READ_CAPACITY_16 0x10 /**< READ CAPACITY (16) */
  25. #define SCSI_OPCODE_TEST_UNIT_READY 0x00 /**< TEST UNIT READY */
  26. /** @} */
  27. /**
  28. * @defgroup scsiflags SCSI flags
  29. * @{
  30. */
  31. #define SCSI_FL_FUA_NV 0x02 /**< Force unit access to NVS */
  32. #define SCSI_FL_FUA 0x08 /**< Force unit access */
  33. #define SCSI_FL_DPO 0x10 /**< Disable cache page out */
  34. /** @} */
  35. /**
  36. * @defgroup scsicdbs SCSI command data blocks
  37. * @{
  38. */
  39. /** A SCSI "READ (10)" CDB */
  40. struct scsi_cdb_read_10 {
  41. /** Opcode (0x28) */
  42. uint8_t opcode;
  43. /** Flags */
  44. uint8_t flags;
  45. /** Start address
  46. *
  47. * This is a logical block number, in big-endian order.
  48. */
  49. uint32_t lba;
  50. /** Group number */
  51. uint8_t group;
  52. /** Transfer length
  53. *
  54. * This is a logical block count, in big-endian order.
  55. */
  56. uint16_t len;
  57. /** Control byte */
  58. uint8_t control;
  59. } __attribute__ (( packed ));
  60. /** A SCSI "READ (16)" CDB */
  61. struct scsi_cdb_read_16 {
  62. /** Opcode (0x88) */
  63. uint8_t opcode;
  64. /** Flags */
  65. uint8_t flags;
  66. /** Start address
  67. *
  68. * This is a logical block number, in big-endian order.
  69. */
  70. uint64_t lba;
  71. /** Transfer length
  72. *
  73. * This is a logical block count, in big-endian order.
  74. */
  75. uint32_t len;
  76. /** Group number */
  77. uint8_t group;
  78. /** Control byte */
  79. uint8_t control;
  80. } __attribute__ (( packed ));
  81. /** A SCSI "WRITE (10)" CDB */
  82. struct scsi_cdb_write_10 {
  83. /** Opcode (0x2a) */
  84. uint8_t opcode;
  85. /** Flags */
  86. uint8_t flags;
  87. /** Start address
  88. *
  89. * This is a logical block number, in big-endian order.
  90. */
  91. uint32_t lba;
  92. /** Group number */
  93. uint8_t group;
  94. /** Transfer length
  95. *
  96. * This is a logical block count, in big-endian order.
  97. */
  98. uint16_t len;
  99. /** Control byte */
  100. uint8_t control;
  101. } __attribute__ (( packed ));
  102. /** A SCSI "WRITE (16)" CDB */
  103. struct scsi_cdb_write_16 {
  104. /** Opcode (0x8a) */
  105. uint8_t opcode;
  106. /** Flags */
  107. uint8_t flags;
  108. /** Start address
  109. *
  110. * This is a logical block number, in big-endian order.
  111. */
  112. uint64_t lba;
  113. /** Transfer length
  114. *
  115. * This is a logical block count, in big-endian order.
  116. */
  117. uint32_t len;
  118. /** Group number */
  119. uint8_t group;
  120. /** Control byte */
  121. uint8_t control;
  122. } __attribute__ (( packed ));
  123. /** A SCSI "READ CAPACITY (10)" CDB */
  124. struct scsi_cdb_read_capacity_10 {
  125. /** Opcode (0x25) */
  126. uint8_t opcode;
  127. /** Reserved */
  128. uint8_t reserved_a;
  129. /** Logical block address
  130. *
  131. * Applicable only if the PMI bit is set.
  132. */
  133. uint32_t lba;
  134. /** Reserved */
  135. uint8_t reserved_b[3];
  136. /** Control byte */
  137. uint8_t control;
  138. } __attribute__ (( packed ));
  139. /** SCSI "READ CAPACITY (10)" parameter data */
  140. struct scsi_capacity_10 {
  141. /** Maximum logical block number */
  142. uint32_t lba;
  143. /** Block length in bytes */
  144. uint32_t blksize;
  145. } __attribute__ (( packed ));
  146. /** A SCSI "READ CAPACITY (16)" CDB */
  147. struct scsi_cdb_read_capacity_16 {
  148. /** Opcode (0x9e) */
  149. uint8_t opcode;
  150. /** Service action */
  151. uint8_t service_action;
  152. /** Logical block address
  153. *
  154. * Applicable only if the PMI bit is set.
  155. */
  156. uint64_t lba;
  157. /** Transfer length
  158. *
  159. * This is the size of the data-in buffer, in bytes.
  160. */
  161. uint32_t len;
  162. /** Reserved */
  163. uint8_t reserved;
  164. /** Control byte */
  165. uint8_t control;
  166. } __attribute__ (( packed ));
  167. /** SCSI "READ CAPACITY (16)" parameter data */
  168. struct scsi_capacity_16 {
  169. /** Maximum logical block number */
  170. uint64_t lba;
  171. /** Block length in bytes */
  172. uint32_t blksize;
  173. /** Reserved */
  174. uint8_t reserved[20];
  175. } __attribute__ (( packed ));
  176. /** A SCSI "TEST UNIT READY" CDB */
  177. struct scsi_cdb_test_unit_ready {
  178. /** Opcode (0x00) */
  179. uint8_t opcode;
  180. /** Reserved */
  181. uint8_t reserved[4];
  182. /** Control byte */
  183. uint8_t control;
  184. } __attribute__ (( packed ));
  185. /** A SCSI Command Data Block */
  186. union scsi_cdb {
  187. struct scsi_cdb_read_10 read10;
  188. struct scsi_cdb_read_16 read16;
  189. struct scsi_cdb_write_10 write10;
  190. struct scsi_cdb_write_16 write16;
  191. struct scsi_cdb_read_capacity_10 readcap10;
  192. struct scsi_cdb_read_capacity_16 readcap16;
  193. struct scsi_cdb_test_unit_ready testready;
  194. unsigned char bytes[16];
  195. };
  196. /** printf() format for dumping a scsi_cdb */
  197. #define SCSI_CDB_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:" \
  198. "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x"
  199. /** printf() parameters for dumping a scsi_cdb */
  200. #define SCSI_CDB_DATA(cdb) \
  201. (cdb).bytes[0], (cdb).bytes[1], (cdb).bytes[2], (cdb).bytes[3], \
  202. (cdb).bytes[4], (cdb).bytes[5], (cdb).bytes[6], (cdb).bytes[7], \
  203. (cdb).bytes[8], (cdb).bytes[9], (cdb).bytes[10], (cdb).bytes[11], \
  204. (cdb).bytes[12], (cdb).bytes[13], (cdb).bytes[14], (cdb).bytes[15]
  205. /** @} */
  206. /** A SCSI LUN
  207. *
  208. * This is a four-level LUN as specified by SAM-2, in big-endian
  209. * order.
  210. */
  211. struct scsi_lun {
  212. uint16_t u16[4];
  213. } __attribute__ (( packed ));
  214. /** printf() format for dumping a scsi_lun */
  215. #define SCSI_LUN_FORMAT "%04x-%04x-%04x-%04x"
  216. /** printf() parameters for dumping a scsi_lun */
  217. #define SCSI_LUN_DATA(lun) \
  218. ntohs ( (lun).u16[0] ), ntohs ( (lun).u16[1] ), \
  219. ntohs ( (lun).u16[2] ), ntohs ( (lun).u16[3] )
  220. /** A SCSI command information unit */
  221. struct scsi_cmd {
  222. /** LUN */
  223. struct scsi_lun lun;
  224. /** CDB for this command */
  225. union scsi_cdb cdb;
  226. /** Data-out buffer (may be NULL) */
  227. userptr_t data_out;
  228. /** Data-out buffer length
  229. *
  230. * Must be zero if @c data_out is NULL
  231. */
  232. size_t data_out_len;
  233. /** Data-in buffer (may be NULL) */
  234. userptr_t data_in;
  235. /** Data-in buffer length
  236. *
  237. * Must be zero if @c data_in is NULL
  238. */
  239. size_t data_in_len;
  240. };
  241. /** SCSI fixed-format sense data */
  242. struct scsi_sns_fixed {
  243. /** Response code */
  244. uint8_t code;
  245. /** Reserved */
  246. uint8_t reserved;
  247. /** Sense key */
  248. uint8_t key;
  249. /** Information */
  250. uint32_t info;
  251. /** Additional sense length */
  252. uint8_t len;
  253. /** Command-specific information */
  254. uint32_t cs_info;
  255. /** Additional sense code and qualifier */
  256. uint16_t additional;
  257. } __attribute__ (( packed ));
  258. /** SCSI descriptor-format sense data */
  259. struct scsi_sns_descriptor {
  260. /** Response code */
  261. uint8_t code;
  262. /** Sense key */
  263. uint8_t key;
  264. /** Additional sense code and qualifier */
  265. uint16_t additional;
  266. } __attribute__ (( packed ));
  267. /** SCSI sense data */
  268. union scsi_sns {
  269. /** Response code */
  270. uint8_t code;
  271. /** Fixed-format sense data */
  272. struct scsi_sns_fixed fixed;
  273. /** Descriptor-format sense data */
  274. struct scsi_sns_descriptor desc;
  275. };
  276. /** SCSI sense response code mask */
  277. #define SCSI_SENSE_CODE_MASK 0x7f
  278. /** Test if SCSI sense data is in fixed format
  279. *
  280. * @v code Response code
  281. * @ret is_fixed Sense data is in fixed format
  282. */
  283. #define SCSI_SENSE_FIXED( code ) ( ( (code) & 0x7e ) == 0x70 )
  284. /** SCSI sense key mask */
  285. #define SCSI_SENSE_KEY_MASK 0x0f
  286. /** A SCSI response information unit */
  287. struct scsi_rsp {
  288. /** SCSI status code */
  289. uint8_t status;
  290. /** Data overrun (or negative underrun) */
  291. ssize_t overrun;
  292. /** Autosense data (if any)
  293. *
  294. * To minimise code size, this is stored as the first four
  295. * bytes of a descriptor-format sense data block (even if the
  296. * response code indicates fixed-format sense data).
  297. */
  298. struct scsi_sns_descriptor sense;
  299. };
  300. extern int scsi_parse_lun ( const char *lun_string, struct scsi_lun *lun );
  301. extern void scsi_parse_sense ( const void *data, size_t len,
  302. struct scsi_sns_descriptor *sense );
  303. extern int scsi_command ( struct interface *control, struct interface *data,
  304. struct scsi_cmd *command );
  305. #define scsi_command_TYPE( object_type ) \
  306. typeof ( int ( object_type, struct interface *data, \
  307. struct scsi_cmd *command ) )
  308. extern void scsi_response ( struct interface *intf, struct scsi_rsp *response );
  309. #define scsi_response_TYPE( object_type ) \
  310. typeof ( void ( object_type, struct scsi_rsp *response ) )
  311. extern int scsi_open ( struct interface *block, struct interface *scsi,
  312. struct scsi_lun *lun );
  313. #endif /* _IPXE_SCSI_H */