1 | /* $NetBSD: scsi_spc.h,v 1.5 2010/02/06 23:13:59 cegger Exp $ */ |
2 | |
3 | /*- |
4 | * Copyright (c) 2005 The NetBSD Foundation, Inc. |
5 | * All rights reserved. |
6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Jason R. Thorpe. |
9 | * |
10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions |
12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. |
15 | * 2. Redistributions in binary form must reproduce the above copyright |
16 | * notice, this list of conditions and the following disclaimer in the |
17 | * documentation and/or other materials provided with the distribution. |
18 | * |
19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ |
31 | |
32 | /* |
33 | * SCSI Primary Commands (SPC) -- |
34 | * Commands for all device types |
35 | */ |
36 | |
37 | /* |
38 | * Largely written by Julian Elischer (julian@tfs.com) |
39 | * for TRW Financial Systems. |
40 | * |
41 | * TRW Financial Systems, in accordance with their agreement with Carnegie |
42 | * Mellon University, makes this software available to CMU to distribute |
43 | * or use in any manner that they see fit as long as this message is kept with |
44 | * the software. For this reason TFS also grants any other persons or |
45 | * organisations permission to use or modify this software. |
46 | * |
47 | * TFS supplies this software to be publicly redistributed |
48 | * on the understanding that TFS is not responsible for the correct |
49 | * functioning of this software in any circumstances. |
50 | * |
51 | * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 |
52 | */ |
53 | |
54 | #ifndef _DEV_SCSIPI_SCSI_SPC_H_ |
55 | #define _DEV_SCSIPI_SCSI_SPC_H_ |
56 | |
57 | /* |
58 | * EXTENDED COPY |
59 | */ |
60 | |
61 | /* |
62 | * INQUIRY |
63 | */ |
64 | |
65 | /* |
66 | * LOG SELECT |
67 | */ |
68 | |
69 | /* |
70 | * LOG SENSE |
71 | */ |
72 | |
73 | /* |
74 | * MODE SELECT |
75 | */ |
76 | |
77 | #define SCSI_MODE_SELECT_6 0x15 |
78 | struct scsi_mode_select_6 { |
79 | uint8_t opcode; |
80 | uint8_t byte2; |
81 | #define SMS_SP 0x01 /* save page */ |
82 | #define SMS_PF 0x10 /* page format (0 = SCSI-1, 1 = SCSI-2) */ |
83 | uint8_t reserved[2]; |
84 | uint8_t length; |
85 | uint8_t control; |
86 | }; |
87 | |
88 | #define SCSI_MODE_SELECT_10 0x55 |
89 | struct scsi_mode_select_10 { |
90 | uint8_t opcode; |
91 | uint8_t byte2; /* see MODE SELECT (6) */ |
92 | uint8_t reserved[5]; |
93 | uint8_t length[2]; |
94 | uint8_t control; |
95 | }; |
96 | |
97 | /* |
98 | * MODE SENSE |
99 | */ |
100 | |
101 | #define SCSI_MODE_SENSE_6 0x1a |
102 | struct scsi_mode_sense_6 { |
103 | uint8_t opcode; |
104 | uint8_t byte2; |
105 | #define SMS_DBD 0x08 /* disable block descriptors */ |
106 | uint8_t page; |
107 | #define SMS_PAGE_MASK 0x3f |
108 | #define SMS_PCTRL_MASK 0xc0 |
109 | #define SMS_PCTRL_CURRENT 0x00 |
110 | #define SMS_PCTRL_CHANGEABLE 0x40 |
111 | #define SMS_PCTRL_DEFAULT 0x80 |
112 | #define SMS_PCTRL_SAVED 0xc0 |
113 | uint8_t reserved; |
114 | uint8_t length; |
115 | uint8_t control; |
116 | }; |
117 | |
118 | #define SCSI_MODE_SENSE_10 0x5a |
119 | struct scsi_mode_sense_10 { |
120 | uint8_t opcode; |
121 | uint8_t byte2; /* see MODE SENSE (6) */ |
122 | #define SMS_LLBAA 0x10 |
123 | uint8_t page; /* See MODE SENSE (6) */ |
124 | uint8_t reserved[4]; |
125 | uint8_t length[2]; |
126 | uint8_t control; |
127 | }; |
128 | |
129 | /* |
130 | * Page code usage: |
131 | * 0x00 Vendor-specific (does not require page format) |
132 | * 0x01 - 0x1f Device-type-specific pages |
133 | * 0x20 - 0x3e Vendor-specific (page format required) |
134 | * 0x3f Return all mode pages |
135 | */ |
136 | #define SMS_PAGE_ALL_PAGES 0x3f |
137 | |
138 | /* |
139 | * Mode parameters are returned in the following format: |
140 | * |
141 | * Mode parameter header |
142 | * Block descriptor(s) [zero or more] |
143 | * Page(s) [zero or more, variable-length] |
144 | */ |
145 | |
146 | struct { |
147 | uint8_t ; |
148 | uint8_t ; |
149 | uint8_t ; |
150 | uint8_t ; /* unused on ATAPI */ |
151 | }; |
152 | |
153 | struct { |
154 | uint8_t [2]; |
155 | uint8_t ; |
156 | uint8_t ; |
157 | uint8_t ; |
158 | #define SMPH_LONGLBA 0x01 |
159 | uint8_t ; |
160 | uint8_t [2]; |
161 | }; |
162 | |
163 | struct scsi_general_block_descriptor { |
164 | uint8_t density; |
165 | uint8_t nblocks[3]; |
166 | uint8_t reserved; |
167 | uint8_t blklen[3]; |
168 | }; |
169 | |
170 | struct scsi_da_block_descriptor { |
171 | uint8_t nblocks[4]; |
172 | uint8_t density; |
173 | uint8_t blklen[3]; |
174 | }; |
175 | |
176 | struct scsi_longlba_block_descriptor { |
177 | uint8_t nblocks[8]; |
178 | uint8_t density; |
179 | uint8_t reserved[3]; |
180 | uint8_t blklen[4]; |
181 | }; |
182 | |
183 | /* |
184 | * Header common to all mode parameter pages. |
185 | */ |
186 | struct { |
187 | uint8_t ; |
188 | #define PGCODE_MASK 0x3f /* page code mask */ |
189 | #define PGCODE_PS 0x80 /* page is saveable */ |
190 | uint8_t ; /* page length (not including header) */ |
191 | }; |
192 | |
193 | /* |
194 | * Control mode page |
195 | */ |
196 | #define SCSI_CONTROL_MODE_PAGE 0x0a |
197 | struct scsi_control_mode_page { |
198 | uint8_t pg_code; /* 0x0a */ |
199 | uint8_t pg_length; /* 0x0a */ |
200 | uint8_t byte3; |
201 | #define SCMP_RLEC 0x01 /* report log exception condition */ |
202 | #define SCMP_GLTSD 0x02 /* global logging target save disable */ |
203 | #define SCMP_TST_mask 0x7 /* task set type */ |
204 | #define SCMP_TST_shift 5 |
205 | #define SCMP_TST_ALL_INIT 0 /* per LU for all initiators */ |
206 | #define SCMP_TST_PER_INIT 1 /* per initiator per LU */ |
207 | uint8_t queue_params; |
208 | #define SCMP_DQue 0x01 /* disable queueing */ |
209 | #define SCMP_QErr_mask 0x3 /* queue error management */ |
210 | #define SCMP_QErr_shift 1 |
211 | #define SCMP_QAM_mask 0xf /* queue algorithm modifier */ |
212 | #define SCMP_QAM_shift 4 |
213 | #define SCMP_QAM_RESTRICTED 0x0 /* restricted reordering allowed */ |
214 | #define SCMP_QAM_UNRESTRICTED 0x1 /* unrestricted reordering allowed */ |
215 | /* 0x2 - 0x7 Reserved */ |
216 | /* 0x8 - 0xf Vendor-specific */ |
217 | uint8_t byte5; |
218 | #define SCMP_EAERP 0x01 |
219 | #define SCMP_UAAERP 0x02 |
220 | #define SCMP_RAERP 0x04 |
221 | #define SCMP_SWP 0x08 |
222 | #define SCMP_RAC 0x40 |
223 | #define SCMP_TAS 0x80 |
224 | uint8_t byte6; |
225 | #define SCMP_AM_mask 0x7 /* autload mode */ |
226 | #define SCMP_AM_FULL 0 |
227 | #define SCMP_AM_AUXMEM 1 |
228 | #define SCMP_AM_NOLOAD 2 |
229 | uint8_t rahp[2]; /* ready aer holdoff period */ |
230 | uint8_t btp[2]; /* busy timeout period */ |
231 | uint8_t estct[2]; /* extended self-test completion time */ |
232 | }; |
233 | |
234 | /* |
235 | * Disconnect-reconnect page |
236 | */ |
237 | #define SCSI_DISCONNECT_RECONNECT_PAGE 0x02 |
238 | struct scsi_disconnect_reconnect_page { |
239 | uint8_t pg_code; /* 0x02 */ |
240 | uint8_t pg_length; /* 0x0e */ |
241 | uint8_t buffer_full_ratio; |
242 | uint8_t buffer_empty_ratio; |
243 | uint8_t bus_inactivity_limit[2]; |
244 | uint8_t disconnect_time_limit[2]; |
245 | uint8_t connect_time_limit[2]; |
246 | uint8_t maximum_burst_size[2]; |
247 | uint8_t flags; |
248 | #define SDRP_DTDC_mask 0x7 /* data transfer disconnect control */ |
249 | #define SDRP_DImm 0x08 |
250 | #define SDRP_FA_mask 0x7 |
251 | #define SDRP_FA_shift 4 |
252 | #define SDRP_EMDP 0x80 |
253 | uint8_t reserved; |
254 | uint8_t first_burst_size[2]; |
255 | }; |
256 | |
257 | /* |
258 | * Informational exceptions control page |
259 | */ |
260 | #define SCSI_INFORMATIONAL_EXCEPTIONS_CONTROL_PAGE 0x1c |
261 | struct scsi_informational_exceptions_control_page { |
262 | uint8_t pg_code; /* 0x1c */ |
263 | uint8_t pg_length; /* 0x0a */ |
264 | uint8_t byte3; |
265 | #define SIECP_LogErr 0x01 |
266 | #define SIECP_TEST 0x04 |
267 | #define SIECP_DExcpt 0x08 |
268 | #define SIECP_EWasc 0x10 |
269 | #define SIECP_EBF 0x20 |
270 | #define SIECP_PERF 0x80 |
271 | uint8_t byte4; |
272 | #define SIECP_MRIE_mask 0xf /* method of reporting |
273 | informational exceptions */ |
274 | #define SIECP_MRIE_NO_REPORTING 0x00 |
275 | #define SIECP_MRIE_ASYNC_EVENT 0x01 |
276 | #define SIECP_MRIE_UNIT_ATN 0x02 |
277 | #define SIECP_MRIE_COND_RECOV_ERR 0x03 |
278 | #define SIECP_MRIE_UNCOND_RECOV_ERR 0x04 |
279 | #define SIECP_MRIE_NO_SENSE 0x05 |
280 | #define SIECP_MRIE_ON_REQUEST 0x06 |
281 | /* 0x07 - 0x0b reserved */ |
282 | /* 0x0c - 0x0f Vendor-specific */ |
283 | uint8_t interval_timer[2]; |
284 | uint8_t report_count[2]; |
285 | }; |
286 | |
287 | /* |
288 | * Power condition page |
289 | */ |
290 | #define SCSI_POWER_CONDITION_PAGE 0x1a |
291 | struct scsi_power_condition_page { |
292 | uint8_t pg_code; /* 0x1a */ |
293 | uint8_t pg_length; /* 0x0a */ |
294 | uint8_t reserved; |
295 | uint8_t byte4; |
296 | #define SPCP_STANDBY 0x01 |
297 | #define SPCP_IDLE 0x02 |
298 | uint8_t idle_timer[2]; /* 100ms increments */ |
299 | uint8_t standby_timer[2]; /* 100ms increments */ |
300 | }; |
301 | |
302 | /* |
303 | * Protocol specific LUN page |
304 | */ |
305 | #define SCSI_PROTOCOL_SPECIFIC_LUN_PAGE 0x18 |
306 | struct scsi_protocol_specific_lun_page { |
307 | uint8_t pg_code; /* 0x18 */ |
308 | uint8_t pg_length; /* variable */ |
309 | uint8_t byte3; |
310 | #define SPSLP_PROTOCOL_mask 0xf |
311 | #define SPSLP_PROTOCOL_FCP 0x00 /* Fibre Channel */ |
312 | #define SPSLP_PROTOCOL_SPI 0x01 /* parallel SCSI */ |
313 | #define SPSLP_PROTOCOL_SSA 0x02 /* SSA-S2P or SSA-S3P */ |
314 | #define SPSLP_PROTOCOL_SBP2 0x03 /* IEEE 1394 */ |
315 | #define SPSLP_PROTOCOL_SRP 0x04 /* SCSI RDMA */ |
316 | #define SPSLP_PROTOCOL_ISCSI 0x05 /* iSCSI */ |
317 | /* protocol specific mode parameters follow */ |
318 | }; |
319 | |
320 | /* |
321 | * Protocol specific port page |
322 | */ |
323 | #define SCSI_PROTOCOL_SPECIFIC_PORT_PAGE 0x19 |
324 | struct scsi_protocol_specific_port_page { |
325 | uint8_t pg_code; /* 0x18 */ |
326 | uint8_t pg_length; /* variable */ |
327 | uint8_t byte3; /* see SCSI PROTOCOL SPECIFIC LUN PAGE */ |
328 | /* protocol specific mode parameters follow */ |
329 | }; |
330 | |
331 | /* |
332 | * PERSISTENT RESERVE IN |
333 | */ |
334 | |
335 | /* |
336 | * PERSISTENT RESERVE OUT |
337 | */ |
338 | |
339 | /* |
340 | * PREVENT ALLOW MEDIUM REMOVAL |
341 | */ |
342 | |
343 | #define SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e |
344 | struct scsi_prevent_allow_medium_removal { |
345 | uint8_t opcode; |
346 | uint8_t byte2; |
347 | uint8_t reserved[2]; |
348 | uint8_t how; |
349 | #define SPAMR_ALLOW 0x00 |
350 | #define SPAMR_PREVENT_DT 0x01 |
351 | #define SPAMR_PREVENT_MC 0x02 |
352 | #define SPAMR_PREVENT_ALL 0x03 |
353 | uint8_t control; |
354 | }; |
355 | |
356 | /* |
357 | * READ BUFFER |
358 | */ |
359 | |
360 | /* |
361 | * RECEIVE COPY RESULTS |
362 | */ |
363 | |
364 | /* |
365 | * RECEIVE DIAGNOSTIC RESULTS |
366 | */ |
367 | |
368 | /* |
369 | * RESERVE / RELEASE |
370 | */ |
371 | |
372 | #define SCSI_RESERVE_6 0x16 |
373 | #define SCSI_RELEASE_6 0x17 |
374 | struct scsi_reserve_release_6 { |
375 | uint8_t opcode; |
376 | uint8_t byte2; |
377 | uint8_t obsolete; |
378 | uint8_t reserved[2]; |
379 | uint8_t control; |
380 | }; |
381 | |
382 | #define SCSI_RESERVE_10 0x56 |
383 | #define SCSI_RELEASE_10 0x57 |
384 | struct scsi_reserve_release_10 { |
385 | uint8_t opcode; |
386 | uint8_t byte2; |
387 | #define SR_LongID 0x02 |
388 | #define SR_3rdPty 0x10 |
389 | uint8_t obsolete; |
390 | uint8_t thirdpartyid; |
391 | uint8_t reserved[3]; |
392 | uint8_t paramlen[2]; |
393 | uint8_t control; |
394 | }; |
395 | |
396 | struct scsi_reserve_release_10_idparam { |
397 | uint8_t thirdpartyid[8]; |
398 | }; |
399 | |
400 | /* |
401 | * REPORT DEVICE IDENTIFIER |
402 | */ |
403 | |
404 | /* |
405 | * REPORT LUNS |
406 | */ |
407 | |
408 | /* |
409 | * REQUEST SENSE |
410 | */ |
411 | |
412 | #define SCSI_REQUEST_SENSE 0x03 |
413 | struct scsi_request_sense { |
414 | uint8_t opcode; |
415 | uint8_t byte2; |
416 | uint8_t reserved[2]; |
417 | uint8_t length; |
418 | uint8_t control; |
419 | }; |
420 | |
421 | struct scsi_sense_data { |
422 | /* 1*/ uint8_t response_code; |
423 | #define SSD_RCODE(x) ((x) & 0x7f) |
424 | #define SSD_RCODE_CURRENT 0x70 |
425 | #define SSD_RCODE_DEFERRED 0x71 |
426 | #define SSD_RCODE_VALID 0x80 |
427 | /* 2*/ uint8_t segment; /* obsolete */ |
428 | /* 3*/ uint8_t flags; |
429 | #define SSD_SENSE_KEY(x) ((x) & 0x0f) |
430 | #define SSD_ILI 0x20 |
431 | #define SSD_EOM 0x40 |
432 | #define SSD_FILEMARK 0x80 |
433 | /* 7*/ uint8_t info[4]; |
434 | /* 8*/ uint8_t ; /* Additional sense length */ |
435 | /*12*/ uint8_t csi[4]; /* Command-specific information */ |
436 | /*13*/ uint8_t asc; /* Additional sense code */ |
437 | /*14*/ uint8_t ascq; /* Additional sense code qualifier */ |
438 | /*15*/ uint8_t fru; /* Field replaceable unit code */ |
439 | union { |
440 | uint8_t sks_bytes[3]; |
441 | |
442 | /* ILLEGAL REQUEST */ |
443 | struct { |
444 | uint8_t byte0; |
445 | #define SSD_SKS_FP_BIT(x) ((x) & 0x7) |
446 | #define SSD_SKS_FP_BPV 0x08 |
447 | #define SSK_SKS_FP_CD 0x40 /* 1=command, 0=data */ |
448 | uint8_t val[2]; |
449 | } field_pointer; |
450 | |
451 | /* RECOVERED ERROR, HARDWARE ERROR, MEDIUM ERROR */ |
452 | struct { |
453 | uint8_t byte0; |
454 | uint8_t val[2]; |
455 | } actual_retry_count; |
456 | |
457 | /* NOT READY, NO SENSE */ |
458 | struct { |
459 | uint8_t byte0; |
460 | uint8_t val[2]; |
461 | } progress_indication; |
462 | |
463 | /* COPY ABORTED */ |
464 | struct { |
465 | uint8_t byte0; |
466 | #define SSD_SKS_SP_BIT(x) ((x) & 0x7) |
467 | #define SSD_SKS_SP_BPV 0x08 |
468 | #define SSD_SKS_SP_SD 0x20 /* 0=param list, 1=segment desc */ |
469 | uint8_t val[2]; |
470 | } segment_pointer; |
471 | /*18*/ } sks; /* Sense-key specific */ |
472 | #define SSD_SKSV 0x80 /* byte0 of sks field */ |
473 | /*32*/ uint8_t [14]; /* really variable length */ |
474 | }; |
475 | |
476 | /* |
477 | * Sense bytes described by the extra_len field start at csi[], and can |
478 | * only continue up to the end of the 32-byte sense structure that we |
479 | * have defined (which might be too short for some cases). |
480 | */ |
481 | #define SSD_ADD_BYTES_LIM(sp) \ |
482 | ((((int)(sp)->extra_len) < (int)sizeof(struct scsi_sense_data) - 8) ? \ |
483 | (sp)->extra_len : sizeof(struct scsi_sense_data) - 8) |
484 | |
485 | #define SKEY_NO_SENSE 0x00 |
486 | #define SKEY_RECOVERED_ERROR 0x01 |
487 | #define SKEY_NOT_READY 0x02 |
488 | #define SKEY_MEDIUM_ERROR 0x03 |
489 | #define SKEY_HARDWARE_ERROR 0x04 |
490 | #define SKEY_ILLEGAL_REQUEST 0x05 |
491 | #define SKEY_UNIT_ATTENTION 0x06 |
492 | #define SKEY_DATA_PROTECT 0x07 |
493 | #define SKEY_BLANK_CHECK 0x08 |
494 | #define SKEY_VENDOR_SPECIFIC 0x09 |
495 | #define SKEY_COPY_ABORTED 0x0a |
496 | #define SKEY_ABORTED_COMMAND 0x0b |
497 | #define SKEY_EQUAL 0x0c /* obsolete */ |
498 | #define SKEY_VOLUME_OVERFLOW 0x0d |
499 | #define SKEY_MISCOMPARE 0x0e |
500 | /* 0x0f reserved */ |
501 | |
502 | /* XXX This is not described in SPC-2. */ |
503 | struct scsi_sense_data_unextended { |
504 | uint8_t response_code; |
505 | uint8_t block[3]; |
506 | }; |
507 | |
508 | /* |
509 | * SEND DIAGNOSTIC |
510 | */ |
511 | |
512 | #define SCSI_SEND_DIAGNOSTIC 0x1d |
513 | struct scsi_send_diagnostic { |
514 | uint8_t opcode; |
515 | uint8_t byte2; |
516 | #define SSD_UnitOffL 0x01 |
517 | #define SSD_DevOffL 0x02 |
518 | #define SSD_SelfTest 0x04 /* standard self-test */ |
519 | #define SSD_PF 0x10 /* results in page format */ |
520 | #define SSD_CODE(x) ((x) << 5) |
521 | /* |
522 | * Codes: |
523 | * |
524 | * 0 This value shall be used when the SelfTest bit is |
525 | * set to one or if the SEND DIAGNOSTIC command is not |
526 | * invoking one of the other self-test functions such |
527 | * as enclosure services or the Translate Address page. |
528 | * |
529 | * 1 Background short self-test. Parameter length is 0. |
530 | * |
531 | * 2 Background extended self-test. Parameter length is 0. |
532 | * |
533 | * 4 Abort background self-test. Parameter length is 0. |
534 | * |
535 | * 5 Foreground short self-test. Parameter length is 0. |
536 | * |
537 | * 6 Foreground extended self-test. Parameter length is 0. |
538 | */ |
539 | uint8_t reserved; |
540 | uint8_t paramlen[2]; |
541 | uint8_t control; |
542 | }; |
543 | |
544 | /* |
545 | * SET DEVICE IDENTIFIER |
546 | */ |
547 | |
548 | /* |
549 | * TEST UNIT READY |
550 | */ |
551 | |
552 | #define SCSI_TEST_UNIT_READY 0x00 |
553 | struct scsi_test_unit_ready { |
554 | uint8_t opcode; |
555 | uint8_t byte2; |
556 | uint8_t reserved[3]; |
557 | uint8_t control; |
558 | }; |
559 | |
560 | /* |
561 | * WRITE BUFFER |
562 | */ |
563 | |
564 | #endif /* _DEV_SCSIPI_SCSI_SPC_H_ */ |
565 | |