xref: /original-bsd/sys/pmax/dev/scsi.h (revision b4971bb3)
1 /*
2  * Copyright (c) 1992 Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Ralph Campbell.
7  *
8  * %sccs.include.redist.c%
9  *
10  *	@(#)scsi.h	7.4 (Berkeley) 05/09/93
11  *
12  * scsi.h --
13  *
14  *	Common declarations for SCSI command formaters. This file only covers
15  *	definitions pertaining to the SCSI common command set that are
16  *	common to all SCSI device types (ie disk, tapes, WORM, printers, etc).
17  *	Some of the references from the proceedings of the
18  *	1984 Mini/Micro Northeast conference might help in understanding SCSI.
19  *
20  * from: $Header: /sprite/src/kernel/dev/RCS/scsi.h,
21  *	v 9.1 90/02/13 23:11:24 jhh Exp $ SPRITE (Berkeley)
22  */
23 
24 #ifndef _SCSI_H
25 #define _SCSI_H
26 
27 /*
28  * "Standard" SCSI Commands.
29  * SCSI commands are divided into 8 groups as follows:
30  *	Group0	(0x00 - 0x1f).	Basic commands. 6 bytes long
31  *	Group1	(0x20 - 0x3f).	Extended command. 10 bytes.
32  *	Group2	(0x40 - 0x5f).	Reserved.
33  *	Group2	(0x60 - 0x7f).	Reserved.
34  *	Group2	(0x80 - 0x9f).	Reserved.
35  *	Group2	(0xa0 - 0xbf).	Reserved.
36  *	Group6	(0xc0 - 0xdf).	Vendor Unique
37  *	Group7	(0xe0 - 0xff).	Vendor Unique
38  */
39 
40 /*
41  * Scsi Group0 commands all are 6 bytes and have a format according to
42  * struct ScsiGroup0Cmd.
43  */
44 #define SCSI_TEST_UNIT_READY	0x00
45 #define SCSI_REZERO_UNIT	0x01
46 #define SCSI_REWIND		0x01
47 #define SCSI_REQUEST_SENSE	0x03
48 #define	SCSI_FORMAT_UNIT	0x04
49 #define	SCSI_READ_BLOCK_LIMITS	0x05
50 #define SCSI_REASSIGN_BLOCKS	0x07
51 #define SCSI_READ		0x08
52 #define SCSI_WRITE		0x0a
53 #define SCSI_SEEK		0x0b
54 #define	SCSI_TRACK_SELECT	0x0b
55 #define	SCSI_READ_REVERSE	0x0f
56 #define SCSI_WRITE_EOF		0x10
57 #define SCSI_SPACE		0x11
58 #define SCSI_INQUIRY		0x12
59 #define SCSI_VERIFY		0x13
60 #define	SCSI_READ_BUFFER	0x14
61 #define SCSI_MODE_SELECT	0x15
62 #define	SCSI_RESERVE_UNIT	0x16
63 #define	SCSI_RELEASE_UNIT	0x17
64 #define SCSI_COPY		0x18
65 #define SCSI_ERASE_TAPE		0x19
66 #define SCSI_MODE_SENSE		0x1a
67 #define SCSI_START_STOP		0x1b
68 #define	SCSI_LOAD_UNLOAD	0x1b
69 #define	SCSI_RECV_DIAG_RESULTS	0x1c
70 #define SCSI_SEND_DIAGNOSTIC	0x1d
71 #define SCSI_PREVENT_ALLOW	0x1e
72 
73 /*
74  * Group1 commands are all 10 bytes and have a format according to
75  * struct ScsiGroup1Cmd.
76  */
77 #define SCSI_READ_CAPACITY	0x25
78 #define	SCSI_READ_EXT		0x28
79 #define	SCSI_WRITE_EXT		0x2a
80 #define	SCSI_SEEK_EXT		0x2b
81 #define	SCSI_WRITE_VERIFY	0x2e
82 #define	SCSI_VERIFY_EXT		0x2f
83 #define	SCSI_SEARCH_HIGH	0x30
84 #define SCSI_SEARCH_EQUAL	0x31
85 #define	SCSI_SEARCH_LOW		0x32
86 #define	SCSI_SET_LIMITS		0x33
87 #define	SCSI_COMPARE		0x39
88 #define	SCSI_COPY_VERIFY	0x3a
89 
90 /*
91  * Control byte flags for Group0 and Group1 commands.
92  *
93  * SCSI_CTRL_LINK - This is used to prevent a bus free phase between commands.
94  *	If the command terminates successfully, a SCSI_LINKED_CMD_COMPLETE
95  *	message is returned instead of the normal SCSI_COMMAND_COMPLETE message. *	The last command in a chain should not have this bit set
96  *	(and consequently gets a normal SCSI_COMMAND_COMPLETE message).
97  * SCSI_CTRL_LINK_FLAG - This bit should only set when SCSI_CTRL_LINK is set and
98  *	causes a SCSI_LINKED_FLAGED_CMD_COMPLETE to be returned instead of
99  *	a SCSI_LINKED_CMD_COMPLETE.
100  */
101 #define SCSI_CTRL_LINK		0x01	/* Link commands (no bus free phase) */
102 #define SCSI_CTRL_LINK_INTR	0x02	/* Interrupt after linked command */
103 
104 /*
105  * The standard group0 6-byte SCSI control block.  Note that the
106  * fields between highAddr and blockCount inclusive are command dependent.
107  * The definitions Addr and BlockCount cover most of the commands we will
108  * use.
109  */
110 typedef struct ScsiGroup0Cmd {
111 	u_char	command;		/* command code, defined below.  The
112 					 * upper three bits of this are zero
113 					 * to indicate the control block is
114 					 * only 6 bytes long */
115 #if BYTE_ORDER == BIG_ENDIAN
116 	u_char	unitNumber	:3;	/* Logical Unit (LUN) to which to
117 					 * pass the command.  The device
118 					 * has already been selected using
119 					 * the "targetID" bit. */
120 	u_char	highAddr	:5;	/* High bits of address */
121 #else
122 	u_char	highAddr	:5;	/* High bits of address */
123 	u_char	unitNumber	:3;	/* Logical Unit (LUN) to which to
124 					 * pass the command.  The device
125 					 * has already been selected using
126 					 * the "targetID" bit. */
127 #endif
128 	u_char	midAddr;		/* Middle bits of address */
129 	u_char	lowAddr;		/* Low bits of address */
130 	u_char	blockCount;		/* Blocks to transfer */
131 	u_char	control;		/* See flags for common bits */
132 } ScsiGroup0Cmd;
133 
134 /*
135  * Format of a SCSI_START_STOP command. This is a group 0 command, but
136  * the command contents are different.
137  */
138 typedef struct ScsiStartStopCmd {
139 #if BYTE_ORDER == BIG_ENDIAN
140 	u_char	command;		/* command code, defined below.  The
141 					 * upper three bits of this are zero
142 					 * to indicate the control block is
143 					 * only 6 bytes long */
144 	u_char	unitNumber	:3;	/* Logical Unit (LUN) to which to
145 					 * pass the command.  The device
146 					 * has already been selected using
147 					 * the "targetID" bit. */
148 	u_char	pad1		:4;	/* Reserved */
149 	u_char	immed		:1;	/* Immediate status bit */
150 	u_char	pad2;			/* Reserved */
151 	u_char	pad3;			/* Reserved */
152 	u_char	pad4		:6;	/* Reserved */
153 	u_char	loadEject	:1;	/* Load or eject medium */
154 	u_char	start		:1;	/* Start or stop medium */
155 	u_char	control;		/* See flags for common bits */
156 #else
157 	u_char	command;		/* command code, defined below.  The
158 					 * upper three bits of this are zero
159 					 * to indicate the control block is
160 					 * only 6 bytes long */
161 	u_char	immed		:1;	/* Immediate status bit */
162 	u_char	pad1		:4;	/* Reserved */
163 	u_char	unitNumber	:3;	/* Logical Unit (LUN) to which to
164 					 * pass the command.  The device
165 					 * has already been selected using
166 					 * the "targetID" bit. */
167 	u_char	pad2;			/* Reserved */
168 	u_char	pad3;			/* Reserved */
169 	u_char	start		:1;	/* Start or stop medium */
170 	u_char	loadEject	:1;	/* Load or eject medium */
171 	u_char	pad4		:6;	/* Reserved */
172 	u_char	control;		/* See flags for common bits */
173 #endif
174 } ScsiStartStopCmd;
175 
176 /*
177  * The standard group1 10-byte SCSI control block.  Note that the
178  * fields between highAddr and blockCount inclusive are command dependent.
179  * The definitions Addr and BlockCount cover most of the commands we will
180  * use.
181  */
182 typedef struct ScsiGroup1Cmd {
183 	u_char	command;		/* command code, defined below.  The
184 					 * upper three bits of this are zero
185 					 * to indicate the control block is
186 					 * only 6 bytes long */
187 #if BYTE_ORDER == BIG_ENDIAN
188 	u_char	unitNumber	:3;	/* Logical Unit (LUN) to which to
189 					 * pass the command.  The device
190 					 * has already been selected using
191 					 * the "targetID" bit. */
192 	u_char	pad1		:5;	/* Reserved */
193 #else
194 	u_char	pad1		:5;	/* Reserved */
195 	u_char	unitNumber	:3;	/* Logical Unit (LUN) to which to
196 					 * pass the command.  The device
197 					 * has already been selected using
198 					 * the "targetID" bit. */
199 #endif
200 	u_char	highAddr;		/* High bits of address */
201 	u_char	midHighAddr;		/* Middle high bits of address */
202 	u_char	midLowAddr;		/* Middle low bits of address */
203 	u_char	lowAddr;		/* Low bits of address */
204 	u_char	pad2;			/* Reserved */
205 	u_char	highBlockCount;	/* High bits of blocks to transfer */
206 	u_char	lowBlockCount;	/* Low bits of blocks to transfer */
207 	u_char	control;		/* See flags for common bits */
208 } ScsiGroup1Cmd;
209 
210 /*
211  * SCSI status completion information.
212  * This is returned by the device when a command completes.
213  */
214 #define	SCSI_STATUS_CHECKCOND	0x02	/* Check Condition (ie., read sense) */
215 #define	SCSI_STATUS_CONDMET	0x04	/* Condition Met (ie., search worked) */
216 #define	SCSI_STATUS_BUSY	0x08
217 #define	SCSI_STATUS_INTERMED	0x10	/* Intermediate status sent */
218 #define	SCSI_STATUS_EXT		0x80	/* Extended status valid */
219 
220 /*
221  * Sense information provided after some errors.  This is divided into
222  * two kinds, classes 0-6, and class 7.  This is 30 bytes big to allow
223  * for the drive specific sense bytes that follow the standard 4 byte header.
224  *
225  * For extended sense, this buffer may be cast into another type.  Also
226  * The actual size of the sense data returned is used to detect what
227  * kind of tape drive is out there.  Kludgy, but true.
228  */
229 typedef struct ScsiClass0Sense {
230 #if BYTE_ORDER == BIG_ENDIAN
231 	u_char	valid		:1;	/* Sense data is valid */
232 	u_char	error		:7;	/* 3 bits class and 4 bits code */
233 #else
234 	u_char	error		:7;	/* 3 bits class and 4 bits code */
235 	u_char	valid		:1;	/* Sense data is valid */
236 #endif
237 	u_char	highAddr;		/* High byte of block address */
238 	u_char	midAddr;		/* Middle byte of block address */
239 	u_char	lowAddr;		/* Low byte of block address */
240 	u_char	sense[26];		/* Target specific sense data */
241 } ScsiClass0Sense;
242 
243 /*
244  * Definitions for errors in the sense data.  The error field is specified
245  * as a 3 bit class and 4 bit code, but it is easier to treat it as a
246  * single 7 bit field.
247  */
248 #define SCSI_NO_SENSE_DATA		0x00
249 #define SCSI_NOT_READY			0x04
250 #define SCSI_NOT_LOADED			0x09
251 #define SCSI_INSUF_CAPACITY		0x0a
252 #define SCSI_HARD_DATA_ERROR		0x11
253 #define SCSI_WRITE_PROTECT		0x17
254 #define SCSI_CORRECTABLE_ERROR		0x18
255 #define SCSI_FILE_MARK			0x1c
256 #define SCSI_INVALID_COMMAND		0x20
257 #define SCSI_UNIT_ATTENTION		0x30
258 #define SCSI_END_OF_MEDIA		0x34
259 
260 /*
261  * The standard "extended" sense data returned by SCSI devices.  This
262  * has an error field of 0x70, for a "class 7" error.
263  */
264 typedef struct ScsiClass7Sense {
265 #if BYTE_ORDER == BIG_ENDIAN
266 	u_char	valid		:1;	/* Sense data is valid */
267 	u_char	error7		:7;	/* == 0x70 */
268 	u_char	pad1;			/* Also "segment number" for copy */
269 	u_char	fileMark	:1;	/* File mark on device */
270 	u_char	endOfMedia	:1;	/* End of media reached */
271 	u_char	badBlockLen	:1;	/* Block length mis-match (Exabyte) */
272 	u_char	pad2		:1;
273 	u_char	key		:4;	/* Sense keys defined below */
274 	u_char	info1;			/* Information byte 1 */
275 	u_char	info2;			/* Information byte 2 */
276 	u_char	info3;			/* Information byte 3 */
277 	u_char	info4;			/* Information byte 4 */
278 	u_char	length;			/* Number of additional info bytes */
279 #else
280 	u_char	error7		:7;	/* == 0x70 */
281 	u_char	valid		:1;	/* Sense data is valid */
282 	u_char	pad1;			/* Also "segment number" for copy */
283 	u_char	key		:4;	/* Sense keys defined below */
284 	u_char	pad2		:1;
285 	u_char	badBlockLen	:1;	/* Block length mis-match (Exabyte) */
286 	u_char	endOfMedia	:1;	/* End of media reached */
287 	u_char	fileMark	:1;	/* File mark on device */
288 	u_char	info1;			/* Information byte 1 */
289 	u_char	info2;			/* Information byte 2 */
290 	u_char	info3;			/* Information byte 3 */
291 	u_char	info4;			/* Information byte 4 */
292 	u_char	length;			/* Number of additional info bytes */
293 #endif
294 } ScsiClass7Sense;			/* 8 Bytes */
295 
296 /*
297  * Key values for standardized sense class 7.
298  */
299 #define SCSI_CLASS7_NO_SENSE		0
300 #define SCSI_CLASS7_RECOVERABLE		1
301 #define SCSI_CLASS7_NOT_READY		2
302 #define SCSI_CLASS7_MEDIA_ERROR		3
303 #define SCSI_CLASS7_HARDWARE_ERROR	4
304 #define SCSI_CLASS7_ILLEGAL_REQUEST	5
305 
306 /*
307  * These seem to have different meanings to different vendors....
308  */
309 #define SCSI_CLASS7_MEDIA_CHANGE	6
310 #define SCSI_CLASS7_UNIT_ATTN		6
311 
312 #define SCSI_CLASS7_WRITE_PROTECT	7
313 #define SCSI_CLASS7_BLANK_CHECK		8
314 #define SCSI_CLASS7_VENDOR		9
315 #define SCSI_CLASS7_POWER_UP_FAILURE	10
316 #define SCSI_CLASS7_ABORT		11
317 #define SCSI_CLASS7_EQUAL		12
318 #define SCSI_CLASS7_OVERFLOW		13
319 #define SCSI_CLASS7_RESERVED_14		14
320 #define SCSI_CLASS7_RESERVED_15		15
321 
322 /*
323  * Data return by the SCSI inquiry command.
324  */
325 typedef struct ScsiInquiryData {
326 #if BYTE_ORDER == BIG_ENDIAN
327 	u_char	type;		/* Peripheral Device type. See below. */
328 	u_char	rmb:1;		/* Removable Medium bit. */
329 	u_char	qualifier:7;	/* Device type qualifier. */
330 	u_char	version;	/* Version info. */
331 	u_char	reserved:4;	/* reserved. */
332 	u_char	format:4;	/* Response format. */
333 	u_char	length;		/* length of data returned. */
334 	u_char	reserved2[2];	/* Reserved */
335 	u_char	flags;		/* SCSI II flags (see below) */
336 	u_char	vendorID[8];	/* Vendor ID (ASCII) */
337 	u_char	productID[16];	/* Product ID (ASCII) */
338 	u_char	revLevel[4];	/* Revision level (ASCII) */
339 	u_char	revData[8];	/* Revision data (ASCII) */
340 #else
341 	u_char	type;		/* Peripheral Device type. See below. */
342 	u_char	qualifier:7;	/* Device type qualifier. */
343 	u_char	rmb:1;		/* Removable Medium bit. */
344 	u_char	version;	/* Version info. */
345 	u_char	format:4;	/* Response format. */
346 	u_char	reserved:4;	/* reserved. */
347 	u_char	length;		/* length of data returned. */
348 	u_char	reserved2[2];	/* Reserved */
349 	u_char	flags;		/* SCSI II flags (see below) */
350 	u_char	vendorID[8];	/* Vendor ID (ASCII) */
351 	u_char	productID[16];	/* Product ID (ASCII) */
352 	u_char	revLevel[4];	/* Revision level (ASCII) */
353 	u_char	revData[8];	/* Revision data (ASCII) */
354 #endif
355 } ScsiInquiryData;
356 
357 /*
358  * The SCSI Peripheral type ID codes as return by the SCSI_INQUIRY command.
359  *
360  * SCSI_DISK_TYPE - Direct Access Device.
361  * SCSI_TAPE_TYPE - Sequential Access Device.
362  * SCSI_PRINTER_TYPE - Printer Device.
363  * SCSI_HOST_TYPE - Processor Device.
364  * SCSI_WORM_TYPE - Write-Once Read-Multiple Device.
365  * SCSI_ROM_TYPE - Read-Only Direct Access Device.
366  * SCSI_SCANNER_TYPE - Scanner device.
367  * SCSI_OPTICAL_MEM_TYPE - Optical memory device.
368  * SCSI_MEDIUM_CHANGER_TYPE - Medium changer device.
369  * SCSI_COMMUNICATIONS_TYPE - Communications device.
370  * SCSI_NODEVICE_TYPE - Logical Unit not present or implemented.
371  *
372  * Note that codes 0xa-0x7e are reserved and 0x80-0xff are vendor unique.
373  */
374 #define	SCSI_DISK_TYPE			0
375 #define	SCSI_TAPE_TYPE			1
376 #define	SCSI_PRINTER_TYPE		2
377 #define	SCSI_HOST_TYPE			3
378 #define	SCSI_WORM_TYPE			4
379 #define	SCSI_ROM_TYPE			5
380 #define	SCSI_SCANNER_TYPE		6
381 #define	SCSI_OPTICAL_MEM_TYPE		7
382 #define	SCSI_MEDIUM_CHANGER_TYPE	8
383 #define	SCSI_COMMUNICATIONS_TYPE	9
384 #define	SCSI_NODEVICE_TYPE		0x7f
385 
386 /*
387  * The SCSI I & II inquiry flags.
388  *
389  * SCSI_REL_ADR - Relative addressing supported.
390  * SCSI_WIDE_32 - 32 bit wide SCSI bus transfers supported.
391  * SCSI_WIDE_16 - 16 bit wide SCSI bus transfers supported.
392  * SCSI_SYNC - Synchronous data transfers supported.
393  * SCSI_LINKED - Linked commands supported.
394  * SCSI_CMD_QUEUE - Tagged command queuing supported.
395  * SCSI_SOFT_RESET - Soft RESET alternative suported.
396  */
397 #define SCSI_REL_ADR		0x80
398 #define SCSI_WIDE_32		0x40
399 #define SCSI_WIDE_16		0x20
400 #define SCSI_SYNC		0x10
401 #define SCSI_LINKED		0x08
402 #define SCSI_CMD_QUEUE		0x02
403 #define SCSI_SOFT_RESET		0x01
404 
405 /*
406  * Standard header for SCSI_MODE_SENSE and SCSI_MODE_SELECT commands for tapes.
407  */
408 typedef struct ScsiTapeModeSelectHdr {
409 	u_char	len;		/* length */
410 	u_char	media;		/* media type */
411 #if BYTE_ORDER == BIG_ENDIAN
412 	u_char	writeprot:1;	/* Write protected media */
413 	u_char	bufferedMode:3;	/* Type of buffer to be done. */
414 	u_char	speed:4;	/* Drive speed. */
415 #else
416 	u_char	speed:4;	/* Drive speed. */
417 	u_char	bufferedMode:3;	/* Type of buffer to be done. */
418 	u_char	writeprot:1;	/* Write protected media */
419 #endif
420 	u_char	length;		/* Block descriptor length. */
421 	u_char	density;	/* tape density code */
422 	u_char	blocks_2;	/* number of blocks (MSB) */
423 	u_char	blocks_1;	/* number of blocks */
424 	u_char	blocks_0;	/* number of blocks (LSB) */
425 	u_char	reserved;	/* */
426 	u_char	block_size2;	/* Tape block size (MSB) */
427 	u_char	block_size1;	/* Tape block size */
428 	u_char	block_size0;	/* Tape block size (LSB) */
429 	u_char	vendor[6];	/* vendor specific data */
430 } ScsiTapeModeSelectHdr;
431 
432 /*
433  * Definitions of SCSI messages.
434  *
435  * SCSI_COMMAND_COMPLETE - After a command has completed, successfully
436  *	or not, this is returned to the host from the target.
437  *
438  * SCSI_EXTENDED_MSG - Indicates that a multi-byte message is being sent.
439  *
440  * The following messages are used with connect/disconnect:
441  * SCSI_SAVE_DATA_POINTER - Sent from target to host to request saving
442  *	of current DMA address and count.  Indicates a pending dis-connect.
443  * SCSI_RESTORE_POINTER - Sent from the target to the host to request
444  *	restoring pointers saved before a disconnect
445  * SCSI_DISCONNECT - Sent from the target to the host to disconnect.
446  * SCSI_ABORT - Sent from the host to the target to abort current request.
447  * SCSI_MESSAGE_REJECT -  Indicates receipt, by either host or target, of
448  *	an unimplemented message.
449  * SCSI_NO_OP - Sent from host to target if it has no real message to send.
450  * SCSI_MESSAGE_PARITY_ERROR - Sent from host to target on message parity error
451  * SCSI_BUS_RESET - Sent from host to target to reset all current I/O
452  *
453  * SCSI_IDENTIFY - The low order two bits of this message type indicate
454  *	the Logical Unit of the Target which is requesting a reconnect.
455  * SCSI_DIS_REC_IDENTIFY - Sent from the host to a target to indicate
456  *	is supports connect/dis-connect
457  *
458  */
459 #define SCSI_COMMAND_COMPLETE		0x00
460 #define SCSI_EXTENDED_MSG		0x01
461 #define SCSI_SAVE_DATA_POINTER		0x02
462 #define SCSI_RESTORE_POINTERS		0x03
463 #define SCSI_DISCONNECT			0x04
464 #define SCSI_ABORT			0x06
465 #define SCSI_MESSAGE_REJECT		0x07
466 #define SCSI_NO_OP			0x08
467 #define SCSI_MESSAGE_PARITY_ERROR	0x09
468 #define SCSI_LINKED_CMD_COMPLETE	0x0A
469 #define SCSI_LINKED_FLAGED_CMD_COMPLETE	0x0B
470 #define SCSI_BUS_RESET			0x0C
471 
472 #define SCSI_IDENTIFY			0x80
473 #define SCSI_DIS_REC_IDENTIFY		0xc0
474 
475 /*
476  * Extended message types (2nd byte of SCSI_EXTENDED_MSG).
477  */
478 #define SCSI_MODIFY_DATA_PTR		0x00
479 #define SCSI_SYNCHRONOUS_XFER		0x01
480 #define SCSI_EXTENDED_IDENTIFY		0x02 /* only in SCSI I */
481 #define SCSI_WIDE_XFER			0x03
482 
483 /*
484  * Driver ioctl's for various scsi operations.
485  */
486 #ifndef _IOCTL_
487 #include <sys/ioctl.h>
488 #endif
489 
490 /*
491  * Control for SCSI "format" mode.
492  *
493  * "Format" mode allows a privileged process to issue direct SCSI
494  * commands to a drive (it is intended primarily to allow on-line
495  * formatting).  SDIOCSFORMAT with a non-zero arg will put the drive
496  * into format mode; a zero arg will take it out.  When in format
497  * mode, only the process that issued the SDIOCFORMAT can read or
498  * write the drive.
499  *
500  * In format mode, process is expected to
501  *	- do SDIOCSCSICOMMAND to supply cdb for next SCSI op
502  *	- do read or write as appropriate for cdb
503  *	- if i/o error, optionally do SDIOCSENSE to get completion
504  *	  status and sense data from last scsi operation.
505  */
506 
507 struct scsi_fmt_cdb {
508 	int	len;		/* cdb length (in bytes) */
509 	u_char	cdb[28];	/* cdb to use on next read/write */
510 };
511 
512 struct scsi_fmt_sense {
513 	u_int	status;		/* completion status of last op */
514 	u_char	sense[32];	/* sense data (if any) from last op */
515 };
516 
517 #define	SDIOCSFORMAT		_IOW('S', 0x1, int)
518 #define	SDIOCGFORMAT		_IOR('S', 0x2, int)
519 #define	SDIOCSCSICOMMAND	_IOW('S', 0x3, struct scsi_fmt_cdb)
520 #define	SDIOCSENSE		_IOR('S', 0x4, struct scsi_fmt_sense)
521 
522 #ifdef KERNEL
523 /*
524  * Routines.
525  */
526 extern void scsiGroup0Cmd();
527 extern void scsiGroup1Cmd();
528 #endif /* KERNEL */
529 
530 #endif /* _SCSI_H */
531