1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
|
/* $OpenBSD: scsi_disk.h,v 1.35 2015/06/07 19:13:27 krw Exp $ */
/* $NetBSD: scsi_disk.h,v 1.10 1996/07/05 16:19:05 christos Exp $ */
/*
* SCSI interface description
*/
/*
* Some lines of this file come from a file of the name "scsi.h"
* distributed by OSF as part of mach2.5,
* so the following disclaimer has been kept.
*
* Copyright 1990 by Open Software Foundation,
* Grenoble, FRANCE
*
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation, and that the name of OSF or Open Software
* Foundation not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior
* permission.
*
* OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
* IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Largely written by Julian Elischer (julian@tfs.com)
* for TRW Financial Systems.
*
* TRW Financial Systems, in accordance with their agreement with Carnegie
* Mellon University, makes this software available to CMU to distribute
* or use in any manner that they see fit as long as this message is kept with
* the software. For this reason TFS also grants any other persons or
* organisations permission to use or modify this software.
*
* TFS supplies this software to be publicly redistributed
* on the understanding that TFS is not responsible for the correct
* functioning of this software in any circumstances.
*
* Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
*/
/*
* SCSI command format
*/
#ifndef _SCSI_SCSI_DISK_H
#define _SCSI_SCSI_DISK_H 1
/*
* XXX Is this also used by ATAPI?
*/
#define FORMAT_UNIT 0x04
struct scsi_format_unit {
u_int8_t opcode;
u_int8_t flags;
#define SFU_DLF_MASK 0x07
#define SFU_CMPLST 0x08
#define SFU_FMTDATA 0x10
u_int8_t vendor_specific;
u_int8_t interleave[2];
u_int8_t control;
};
/*
* If the FmtData bit is set, a FORMAT UNIT parameter list is transferred
* to the target during the DATA OUT phase. The parameter list includes
*
* Defect list header
* Initialization pattern descriptor (if any)
* Defect descriptor(s) (if any)
*/
struct scsi_format_unit_defect_list_header {
u_int8_t reserved;
u_int8_t flags;
#define DLH_VS 0x01 /* vendor specific */
#define DLH_IMMED 0x02 /* immediate return */
#define DLH_DSP 0x04 /* disable saving parameters */
#define DLH_IP 0x08 /* initialization pattern */
#define DLH_STPF 0x10 /* stop format */
#define DLH_DCRT 0x20 /* disable certification */
#define DLH_DPRY 0x40 /* disable primary */
#define DLH_FOV 0x80 /* format options valid */
u_int8_t defect_lst_len[2];
};
/*
* See Table 117 of the SCSI-2 specification for a description of
* the IP modifier.
*/
struct scsi_initialization_pattern_descriptor {
u_int8_t ip_modifier;
u_int8_t pattern_type;
#define IP_TYPE_DEFAULT 0x01
#define IP_TYPE_REPEAT 0x01
/* 0x02 -> 0x7f: reserved */
/* 0x80 -> 0xff: vendor-specific */
u_int8_t pattern_length[2];
#if 0
u_int8_t pattern[...];
#endif
};
/*
* Defect desciptors. These are used as the defect lists in the FORMAT UNIT
* and READ DEFECT DATA commands, and as the translate page of the
* SEND DIAGNOSTIC and RECEIVE DIAGNOSTIC RESULTS commands.
*/
/* Block format */
struct scsi_defect_descriptor_bf {
u_int8_t block_address[4];
};
/* Bytes from index format */
struct scsi_defect_descriptor_bfif {
u_int8_t cylinder[2];
u_int8_t head;
u_int8_t bytes_from_index[2];
};
/* Physical sector format */
struct scsi_defect_descriptor_psf {
u_int8_t cylinder[2];
u_int8_t head;
u_int8_t sector[2];
};
struct scsi_reassign_blocks {
u_int8_t opcode;
u_int8_t byte2;
u_int8_t unused[3];
u_int8_t control;
};
/*
* XXX Is this also used by ATAPI?
*/
#define REZERO_UNIT 0x01
struct scsi_rezero_unit {
u_int8_t opcode;
u_int8_t byte2;
u_int8_t reserved[3];
u_int8_t control;
};
struct scsi_rw {
u_int8_t opcode;
u_int8_t addr[3];
#define SRW_TOPADDR 0x1F /* only 5 bits here */
u_int8_t length;
u_int8_t control;
};
struct scsi_rw_big {
u_int8_t opcode;
u_int8_t byte2;
#define SRWB_RELADDR 0x01
u_int8_t addr[4];
u_int8_t reserved;
u_int8_t length[2];
u_int8_t control;
};
struct scsi_rw_12 {
u_int8_t opcode;
u_int8_t byte2;
u_int8_t addr[4];
u_int8_t length[4];
u_int8_t reserved;
u_int8_t control;
};
struct scsi_rw_16 {
u_int8_t opcode;
u_int8_t byte2;
u_int8_t addr[8];
u_int8_t length[4];
u_int8_t reserved;
u_int8_t control;
};
struct scsi_write_same_10 {
u_int8_t opcode;
u_int8_t flags;
#define WRITE_SAME_F_LBDATA (1 << 1)
#define WRITE_SAME_F_PBDATA (1 << 2)
u_int8_t lba[4];
u_int8_t group_number;
u_int8_t length[2];
u_int8_t control;
};
struct scsi_write_same_16 {
u_int8_t opcode;
u_int8_t flags;
/* includes WRITE SAME 10 flags */
#define WRITE_SAME_F_UNMAP (1 << 3)
#define WRITE_SAME_F_ANCHOR (1 << 4)
u_int8_t lba[8];
u_int8_t length[4];
u_int8_t group_number;
u_int8_t control;
};
struct scsi_unmap {
u_int8_t opcode;
u_int8_t anchor;
u_int8_t _reserved[4];
u_int8_t group_number;
u_int8_t list_len[2];
u_int8_t control;
};
struct scsi_unmap_data {
u_int8_t data_length[2];
u_int8_t desc_length[2];
u_int8_t _reserved[4];
/* followed by struct scsi_unmap_desc */
};
struct scsi_unmap_desc {
u_int8_t logical_addr[8];
u_int8_t logical_blocks[4];
u_int8_t _reserved[4];
};
struct scsi_read_capacity {
u_int8_t opcode;
u_int8_t byte2;
u_int8_t addr[4];
u_int8_t unused[3];
u_int8_t control;
};
struct scsi_read_capacity_16 {
u_int8_t opcode;
u_int8_t byte2;
#define SRC16_SERVICE_ACTION 0x10
u_int8_t addr[8];
u_int8_t length[4];
u_int8_t reserved;
u_int8_t control;
};
struct scsi_start_stop {
u_int8_t opcode;
u_int8_t byte2;
u_int8_t unused[2];
u_int8_t how;
#define SSS_STOP 0x00
#define SSS_START 0x01
#define SSS_LOEJ 0x02
u_int8_t control;
};
/*
* XXX Does ATAPI have an equivalent?
*/
struct scsi_synchronize_cache {
u_int8_t opcode;
u_int8_t flags;
#define SSC_RELADR 0x01
#define SSC_IMMED 0x02
u_int8_t addr[4];
u_int8_t reserved;
u_int8_t length[2];
u_int8_t control;
};
/*
* Disk specific opcodes
*/
#define REASSIGN_BLOCKS 0x07
#define READ_COMMAND 0x08
#define WRITE_COMMAND 0x0a
#define READ_CAPACITY 0x25
#define READ_CAPACITY_16 0x9e
#define READ_BIG 0x28
#define WRITE_BIG 0x2a
#define READ_12 0xa8
#define WRITE_12 0xaa
#define READ_16 0x88
#define WRITE_16 0x8a
#define SYNCHRONIZE_CACHE 0x35
#define WRITE_SAME_10 0x41
#define WRITE_SAME_16 0x93
#define UNMAP 0x42
struct scsi_read_cap_data {
u_int8_t addr[4];
u_int8_t length[4];
};
struct scsi_read_cap_data_16 {
u_int8_t addr[8];
u_int8_t length[4];
u_int8_t p_type_prot;
u_int8_t logical_per_phys;
u_int8_t lowest_aligned[2];
#define READ_CAP_16_TPE 0x8000
#define READ_CAP_16_TPRZ 0x4000
u_int8_t reserved[16];
};
struct scsi_reassign_blocks_data {
u_int8_t reserved[2];
u_int8_t length[2];
struct {
u_int8_t dlbaddr[4];
} defect_descriptor[1];
};
/* Only the lower 6 bits of the pg_code field are used for page #. */
#define DISK_PGCODE(pg, n) ((pg) != NULL) && (((pg)->pg_code & 0x3f) == n)
#define PAGE_DISK_FORMAT 3
#define PAGE_RIGID_GEOMETRY 4
#define PAGE_FLEX_GEOMETRY 5
#define PAGE_REDUCED_GEOMETRY 6
#define PAGE_CACHING_MODE 8
struct page_disk_format {
u_int8_t pg_code; /* page code (should be 3) */
u_int8_t pg_length; /* page length (should be 0x16) */
u_int8_t trk_z[2]; /* tracks per zone */
u_int8_t alt_sec[2]; /* alternate sectors per zone */
u_int8_t alt_trk_z[2]; /* alternate tracks per zone */
u_int8_t alt_trk_v[2]; /* alternate tracks per volume */
u_int8_t ph_sec_t[2]; /* physical sectors per track */
u_int8_t bytes_s[2]; /* bytes per sector */
u_int8_t interleave[2]; /* interleave */
u_int8_t trk_skew[2]; /* track skew factor */
u_int8_t cyl_skew[2]; /* cylinder skew */
u_int8_t flags; /* various */
#define DISK_FMT_SURF 0x10
#define DISK_FMT_RMB 0x20
#define DISK_FMT_HSEC 0x40
#define DISK_FMT_SSEC 0x80
u_int8_t reserved1;
u_int8_t reserved2;
u_int8_t reserved3;
};
struct page_rigid_geometry {
u_int8_t pg_code; /* page code (should be 4) */
u_int8_t pg_length; /* page length (should be 0x12 or 0x16) */
u_int8_t ncyl[3]; /* number of cylinders */
u_int8_t nheads; /* number of heads */
u_int8_t st_cyl_wp[3]; /* starting cyl., write precomp */
u_int8_t st_cyl_rwc[3]; /* starting cyl., red. write cur */
u_int8_t driv_step[2]; /* drive step rate */
u_int8_t land_zone[3]; /* landing zone cylinder */
u_int8_t sp_sync_ctl; /* spindle synch control */
#define SPINDLE_SYNCH_MASK 0x03 /* mask of valid bits */
#define SPINDLE_SYNCH_NONE 0x00 /* synch disabled or not supported */
#define SPINDLE_SYNCH_SLAVE 0x01 /* disk is a slave */
#define SPINDLE_SYNCH_MASTER 0x02 /* disk is a master */
#define SPINDLE_SYNCH_MCONTROL 0x03 /* disk is a master control */
u_int8_t rot_offset; /* rotational offset (for spindle synch) */
u_int8_t reserved1;
u_int8_t rpm[2]; /* media rotation speed */
u_int8_t reserved2;
u_int8_t reserved3;
};
struct page_flex_geometry {
u_int8_t pg_code; /* page code (should be 5) */
u_int8_t pg_length; /* page length (should be 0x1a or 0x1e) */
u_int8_t xfr_rate[2];
u_int8_t nheads; /* number of heads */
u_int8_t ph_sec_tr; /* physical sectors per track */
u_int8_t bytes_s[2]; /* bytes per sector */
u_int8_t ncyl[2]; /* number of cylinders */
u_int8_t st_cyl_wp[2]; /* start cyl., write precomp */
u_int8_t st_cyl_rwc[2]; /* start cyl., red. write cur */
u_int8_t driv_step[2]; /* drive step rate */
u_int8_t driv_step_w; /* drive step pulse width */
u_int8_t head_settle[2];/* head settle delay */
u_int8_t motor_on; /* motor on delay */
u_int8_t motor_off; /* motor off delay */
u_int8_t flags; /* various flags */
#define MOTOR_ON 0x20 /* motor on (pin 16)? */
#define START_AT_SECTOR_1 0x40 /* start at sector 1 */
#define READY_VALID 0x20 /* RDY (pin 34) valid */
u_int8_t step_p_cyl; /* step pulses per cylinder */
u_int8_t write_pre; /* write precompensation */
u_int8_t head_load; /* head load delay */
u_int8_t head_unload; /* head unload delay */
u_int8_t pin_34_2; /* pin 34 (6) pin 2 (7/11) definition */
u_int8_t pin_4_1; /* pin 4 (8/9) pin 1 (13) definition */
u_int8_t rpm[2]; /* media rotation speed */
u_int8_t reserved1;
u_int8_t reserved2;
};
struct page_reduced_geometry {
u_int8_t pg_code; /* page code (should be 6) */
u_int8_t pg_length; /* page length (should be 0x0B) */
u_int8_t wcd; /* bit 0 = write cache disable */
u_int8_t bytes_s[2]; /* bytes per sector */
u_int8_t sectors[5]; /* total number of sectors */
u_int8_t pow_perf; /* power/performance level */
u_int8_t flags; /* various */
#define LOCK_DISABLED 0x1
#define FORMAT_DISABLED 0x2
#define WRITE_DISABLED 0x4
#define READ_DISABLED 0x8
u_int8_t reserved;
};
struct page_caching_mode {
u_int8_t pg_code; /* page code (should be 8) */
u_int8_t pg_length; /* page length (should be 0x12) */
u_int8_t flags;
#define PG_CACHE_FL_RCD (1<<0)
#define PG_CACHE_FL_MF (1<<1)
#define PG_CACHE_FL_WCE (1<<2)
#define PG_CACHE_FL_SIZE (1<<3)
#define PG_CACHE_FL_DISC (1<<4)
#define PG_CACHE_FL_CAP (1<<5)
#define PG_CACHE_FL_ABPF (1<<6)
#define PG_CACHE_FL_IC (1<<7)
u_int8_t priority;
#define PG_CACHE_PRI_DEMAND(_f) ((_f) & 0x0f)
#define PG_CACHE_PRI_WRITE(_f) (((_f) >> 4) & 0x0f)
u_int8_t dis_prefetch_tl[2];
u_int8_t min_prefetch[2];
u_int8_t max_prefetch[2];
u_int8_t max_prefetch_ceil[2];
};
#define SI_PG_DISK_LIMITS 0xb0 /* block limits */
#define SI_PG_DISK_INFO 0xb1 /* device charateristics */
#define SI_PG_DISK_THIN 0xb2 /* thin provisioning */
struct scsi_vpd_disk_limits {
struct scsi_vpd_hdr hdr;
#define SI_PG_DISK_LIMITS_LEN 0x10
#define SI_PG_DISK_LIMITS_LEN_THIN 0x3c
u_int8_t _reserved1[1];
u_int8_t max_comp_wr_len;
u_int8_t optimal_xfer_granularity[2];
u_int8_t max_xfer_len[4];
u_int8_t optimal_xfer[4];
u_int8_t max_xd_prefetch_len[4];
u_int8_t max_unmap_lba_count[4];
u_int8_t max_unmap_desc_count[4];
u_int8_t optimal_unmap_granularity[4];
u_int8_t unmap_granularity_align[4];
#define SI_PG_DISK_LIMITS_UGAVALID (1U << 31)
u_int8_t _reserved2[28];
};
struct scsi_vpd_disk_info {
struct scsi_vpd_hdr hdr;
u_int8_t rpm[2];
#define VPD_DISK_INFO_RPM_UNDEF 0x0000
#define VPD_DISK_INFO_RPM_NONE 0x0001
u_int8_t _reserved1[1];
u_int8_t form_factor;
#define VPD_DISK_INFO_FORM_MASK 0xf
#define VPD_DISK_INFO_FORM_UNDEF 0x0
#define VPD_DISK_INFO_FORM_5_25 0x1
#define VPD_DISK_INFO_FORM_3_5 0x2
#define VPD_DISK_INFO_FORM_2_5 0x3
#define VPD_DISK_INFO_FORM_1_8 0x4
#define VPD_DISK_INFO_FORM_LT_1_8 0x5
u_int8_t _reserved2[56];
};
struct scsi_vpd_disk_thin {
struct scsi_vpd_hdr hdr;
u_int8_t threshold_exponent;
u_int8_t flags;
#define VPD_DISK_THIN_DP (1 << 0) /* descriptor present */
#define VPD_DISK_THIN_ANC_SUP (0x7 << 1)
#define VPD_DISK_THIN_ANC_SUP_NO (0x0 << 1)
#define VPD_DISK_THIN_ANC_SUP_YES (0x1 << 1)
#define VPD_DISK_THIN_TPWS (1 << 6) /* WRITE SAME 16 */
#define VPD_DISK_THIN_TPU (1 << 7) /* UNMAP */
u_int8_t _reserved1[2];
/* followed by a designation descriptor if DP is set */
};
#endif /* _SCSI_SCSI_DISK_H */
|