Remove building with NOCRYPTO option
[minix3.git] / minix / drivers / usb / usb_storage / scsi.c
blob128039f8b57ca72b45fd1e2a5de8f9e5f1e7a504
1 /*
2 * SCSI commands related implementation
3 */
5 #include <minix/blockdriver.h> /* SECTOR_SIZE */
7 #include <assert.h>
8 #include <string.h> /* strncpy */
10 #include "common.h"
11 #include "scsi.h"
13 /*---------------------------*
14 * declared functions *
15 *---------------------------*/
16 /* To work correctly cbw->CBWCB must be zeroed before calling these: */
17 static int create_inquiry_scsi_cmd(mass_storage_cbw *);
18 static int create_test_scsi_cmd(mass_storage_cbw *);
19 static int create_read_capacity_scsi_cmd(mass_storage_cbw *);
20 static int create_write_scsi_cmd(mass_storage_cbw *, scsi_transfer *);
21 static int create_read_scsi_cmd(mass_storage_cbw *, scsi_transfer *);
22 static int create_mode_sense_scsi_cmd(mass_storage_cbw *);
23 static int create_request_sense_scsi_cmd(mass_storage_cbw *);
25 /*---------------------------*
26 * defined functions *
27 *---------------------------*/
28 /*===========================================================================*
29 * create_scsi_cmd *
30 *===========================================================================*/
31 int
32 create_scsi_cmd(mass_storage_cbw * cbw, int cmd, scsi_transfer * info)
34 MASS_DEBUG_DUMP;
36 assert(NULL != cbw);
38 switch (cmd) {
39 case SCSI_INQUIRY:
40 return create_inquiry_scsi_cmd(cbw);
41 case SCSI_TEST_UNIT_READY:
42 return create_test_scsi_cmd(cbw);
43 case SCSI_READ_CAPACITY:
44 return create_read_capacity_scsi_cmd(cbw);
45 case SCSI_WRITE:
46 return create_write_scsi_cmd(cbw, info);
47 case SCSI_READ:
48 return create_read_scsi_cmd(cbw, info);
49 case SCSI_MODE_SENSE:
50 return create_mode_sense_scsi_cmd(cbw);
51 case SCSI_REQUEST_SENSE:
52 return create_request_sense_scsi_cmd(cbw);
53 default:
54 MASS_MSG("Invalid SCSI command!");
55 return EXIT_FAILURE;
60 /*===========================================================================*
61 * create_inquiry_scsi_cmd *
62 *===========================================================================*/
63 static int
64 create_inquiry_scsi_cmd(mass_storage_cbw * cbw)
66 MASS_DEBUG_DUMP;
68 cbw->dCBWDataTransferLength = SCSI_INQUIRY_DATA_LEN;
69 cbw->bCBWFlags = CBW_FLAGS_IN;
70 cbw->bCDBLength = SCSI_INQUIRY_CMD_LEN;
72 SCSI_SET_INQUIRY_OP_CODE(cbw->CBWCB);
73 SCSI_SET_INQUIRY_PAGE_CODE(cbw->CBWCB, 0);
74 SCSI_SET_INQUIRY_ALLOC_LEN(cbw->CBWCB, SCSI_INQUIRY_DATA_LEN);
76 return EXIT_SUCCESS;
80 /*===========================================================================*
81 * create_test_scsi_cmd *
82 *===========================================================================*/
83 static int
84 create_test_scsi_cmd(mass_storage_cbw * cbw)
86 MASS_DEBUG_DUMP;
88 cbw->bCDBLength = SCSI_TEST_CMD_LEN;
90 SCSI_SET_TEST_OP_CODE(cbw->CBWCB);
92 return EXIT_SUCCESS;
96 /*===========================================================================*
97 * create_read_capacity_scsi_cmd *
98 *===========================================================================*/
99 static int
100 create_read_capacity_scsi_cmd(mass_storage_cbw * cbw)
102 MASS_DEBUG_DUMP;
104 cbw->dCBWDataTransferLength = SCSI_READ_CAPACITY_DATA_LEN;
105 cbw->bCBWFlags = CBW_FLAGS_IN;
106 cbw->bCDBLength = SCSI_READ_CAPACITY_CMD_LEN;
108 SCSI_SET_READ_CAPACITY_OP_CODE(cbw->CBWCB);
109 SCSI_SET_READ_CAPACITY_LBA(cbw->CBWCB, 0x00);
111 return EXIT_SUCCESS;
115 /*===========================================================================*
116 * create_write_scsi_cmd *
117 *===========================================================================*/
118 static int
119 create_write_scsi_cmd(mass_storage_cbw * cbw, scsi_transfer * info)
121 MASS_DEBUG_DUMP;
123 assert(NULL != info);
124 assert(0 == (info->length % SECTOR_SIZE));
126 cbw->dCBWDataTransferLength = info->length;
127 cbw->bCBWFlags = CBW_FLAGS_OUT;
128 cbw->bCDBLength = SCSI_WRITE_CMD_LEN;
130 SCSI_SET_WRITE_OP_CODE(cbw->CBWCB);
131 SCSI_SET_WRITE_LBA(cbw->CBWCB, info->lba);
132 SCSI_SET_WRITE_BLEN(cbw->CBWCB, info->length / SECTOR_SIZE);
134 return EXIT_SUCCESS;
138 /*===========================================================================*
139 * create_read_scsi_cmd *
140 *===========================================================================*/
141 static int
142 create_read_scsi_cmd(mass_storage_cbw * cbw, scsi_transfer * info)
144 MASS_DEBUG_DUMP;
146 assert(NULL != info);
147 assert(0 == (info->length % SECTOR_SIZE));
149 cbw->dCBWDataTransferLength = info->length;
150 cbw->bCBWFlags = CBW_FLAGS_IN;
151 cbw->bCDBLength = SCSI_READ_CMD_LEN;
153 SCSI_SET_READ_OP_CODE(cbw->CBWCB);
154 SCSI_SET_READ_LBA(cbw->CBWCB, info->lba);
155 SCSI_SET_READ_BLEN(cbw->CBWCB, info->length / SECTOR_SIZE);
157 return EXIT_SUCCESS;
161 /*===========================================================================*
162 * create_mode_sense_scsi_cmd *
163 *===========================================================================*/
164 static int
165 create_mode_sense_scsi_cmd(mass_storage_cbw * cbw)
167 MASS_DEBUG_DUMP;
169 cbw->dCBWDataTransferLength = SCSI_MODE_SENSE_FLEX_DATA_LEN;
170 cbw->bCBWFlags = CBW_FLAGS_IN;
171 cbw->bCDBLength = SCSI_MODE_SENSE_CMD_LEN;
173 SCSI_SET_MODE_SENSE_OP_CODE(cbw->CBWCB);
174 SCSI_SET_MODE_SENSE_PAGE_CODE(cbw->CBWCB,
175 SCSI_MODE_SENSE_FLEXIBLE_DISK_PAGE);
177 return EXIT_SUCCESS;
181 /*===========================================================================*
182 * create_request_sense_scsi_cmd *
183 *===========================================================================*/
184 static int
185 create_request_sense_scsi_cmd(mass_storage_cbw * cbw)
187 MASS_DEBUG_DUMP;
189 cbw->dCBWDataTransferLength = SCSI_REQUEST_SENSE_DATA_LEN;
190 cbw->bCBWFlags = CBW_FLAGS_IN;
191 cbw->bCDBLength = SCSI_REQUEST_SENSE_CMD_LEN;
193 SCSI_SET_REQUEST_SENSE_OP_CODE(cbw->CBWCB);
194 SCSI_SET_REQUEST_SENSE_ALLOC(cbw->CBWCB, SCSI_REQUEST_SENSE_DATA_LEN);
196 return EXIT_SUCCESS;
200 /*===========================================================================*
201 * check_inquiry_reply *
202 *===========================================================================*/
204 check_inquiry_reply(uint8_t * scsi_reply)
206 char vendor_name[SCSI_INQUIRY_VENDOR_NAME_LEN + 1];
207 char product_name[SCSI_INQUIRY_PRODUCT_NAME_LEN + 1];
209 MASS_DEBUG_DUMP;
211 /* Stop condition for printing as strncpy() does not add it */
212 vendor_name[SCSI_INQUIRY_VENDOR_NAME_LEN] = '\0';
213 product_name[SCSI_INQUIRY_PRODUCT_NAME_LEN] = '\0';
215 if (SCSI_GET_INQUIRY_PERIPH_QUALIF(scsi_reply)) {
216 MASS_MSG("Device not connected");
217 return EXIT_FAILURE;
220 strncpy(vendor_name, SCSI_GET_INQUIRY_VENDOR_NAME(scsi_reply),
221 SCSI_INQUIRY_VENDOR_NAME_LEN);
222 strncpy(product_name, SCSI_GET_INQUIRY_PRODUCT_NAME(scsi_reply),
223 SCSI_INQUIRY_PRODUCT_NAME_LEN);
225 MASS_DEBUG_MSG("Vendor name: %s", vendor_name);
226 MASS_DEBUG_MSG("Product name %s", product_name);
228 return EXIT_SUCCESS;
232 /*===========================================================================*
233 * check_read_capacity_reply *
234 *===========================================================================*/
236 check_read_capacity_reply(uint8_t * scsi_reply, uint32_t * lba, uint32_t * blen)
238 MASS_DEBUG_DUMP;
240 *lba = SCSI_GET_READ_CAPACITY_LBA(scsi_reply);
241 *blen = SCSI_GET_READ_CAPACITY_BLEN(scsi_reply);
243 return EXIT_SUCCESS;
247 /*===========================================================================*
248 * check_mode_sense_reply *
249 *===========================================================================*/
251 check_mode_sense_reply(uint8_t * scsi_reply, unsigned * cyl,
252 unsigned * head, unsigned * sect)
254 MASS_DEBUG_DUMP;
256 *cyl = SCSI_GET_MODE_SENSE_CYLINDERS(scsi_reply);
257 *head = SCSI_GET_MODE_SENSE_HEADS(scsi_reply);
258 *sect = SCSI_GET_MODE_SENSE_SECTORS(scsi_reply);
260 return EXIT_SUCCESS;
264 /*===========================================================================*
265 * check_csw *
266 *===========================================================================*/
268 check_csw(mass_storage_csw * csw, unsigned int tag)
270 MASS_DEBUG_DUMP;
272 if (csw->dCSWTag != tag) {
273 MASS_MSG("CSW tag mismatch!");
274 return EXIT_FAILURE;
277 if (CSW_SIGNATURE != csw->dCSWSignature) {
278 MASS_MSG("CSW signature mismatch!");
279 return EXIT_FAILURE;
282 if (CSW_STATUS_GOOD != csw->bCSWStatus) {
283 MASS_MSG("CSW status error (0x%02X)!", csw->bCSWStatus);
284 return EXIT_FAILURE;
287 return EXIT_SUCCESS;