summaryrefslogtreecommitdiff
path: root/sys/arch/arc/dev/scsi.h
blob: 963617add65ad0227d97c5652e1a015856a4e219 (plain)
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
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
/*	$OpenBSD: scsi.h,v 1.1 1996/06/24 09:07:19 pefo Exp $	*/
/*
 * Copyright (c) 1992, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Ralph Campbell.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	from: @(#)scsi.h	8.1 (Berkeley) 6/10/93
 *      $Id: scsi.h,v 1.1 1996/06/24 09:07:19 pefo Exp $
 *
 * scsi.h --
 *
 *	Common declarations for SCSI command formaters. This file only covers
 *	definitions pertaining to the SCSI common command set that are
 *	common to all SCSI device types (ie disk, tapes, WORM, printers, etc).
 *	Some of the references from the proceedings of the
 *	1984 Mini/Micro Northeast conference might help in understanding SCSI. 
 *
 * from: Header: /sprite/src/kernel/dev/RCS/scsi.h,
 *	v 9.1 90/02/13 23:11:24 jhh Exp  SPRITE (Berkeley)
 * $Id: scsi.h,v 1.1 1996/06/24 09:07:19 pefo Exp $
 */

#ifndef _SCSI_H
#define _SCSI_H

/*
 * "Standard" SCSI Commands.
 * SCSI commands are divided into 8 groups as follows:
 *	Group0	(0x00 - 0x1f).	Basic commands. 6 bytes long
 *	Group1	(0x20 - 0x3f).	Extended command. 10 bytes.
 *	Group2	(0x40 - 0x5f).	Reserved.
 *	Group2	(0x60 - 0x7f).	Reserved.
 *	Group2	(0x80 - 0x9f).	Reserved.
 *	Group2	(0xa0 - 0xbf).	Reserved.
 *	Group6	(0xc0 - 0xdf).	Vendor Unique
 *	Group7	(0xe0 - 0xff).	Vendor Unique
 */

/*
 * Scsi Group0 commands all are 6 bytes and have a format according to 
 * struct ScsiGroup0Cmd.
 */
#define SCSI_TEST_UNIT_READY	0x00
#define SCSI_REZERO_UNIT	0x01
#define SCSI_REWIND		0x01
#define SCSI_REQUEST_SENSE	0x03
#define	SCSI_FORMAT_UNIT	0x04
#define	SCSI_READ_BLOCK_LIMITS	0x05
#define SCSI_REASSIGN_BLOCKS	0x07
#define SCSI_READ		0x08
#define SCSI_WRITE		0x0a
#define SCSI_SEEK		0x0b
#define	SCSI_TRACK_SELECT	0x0b
#define	SCSI_READ_REVERSE	0x0f
#define SCSI_WRITE_EOF		0x10
#define SCSI_SPACE		0x11
#define SCSI_INQUIRY		0x12
#define SCSI_VERIFY		0x13
#define	SCSI_READ_BUFFER	0x14
#define SCSI_MODE_SELECT	0x15
#define	SCSI_RESERVE_UNIT	0x16
#define	SCSI_RELEASE_UNIT	0x17
#define SCSI_COPY		0x18
#define SCSI_ERASE_TAPE		0x19
#define SCSI_MODE_SENSE		0x1a
#define SCSI_START_STOP		0x1b
#define	SCSI_LOAD_UNLOAD	0x1b
#define	SCSI_RECV_DIAG_RESULTS	0x1c
#define SCSI_SEND_DIAGNOSTIC	0x1d
#define SCSI_PREVENT_ALLOW	0x1e

/*
 * Group1 commands are all 10 bytes and have a format according to
 * struct ScsiGroup1Cmd.
 */
#define SCSI_READ_CAPACITY	0x25	
#define	SCSI_READ_EXT		0x28
#define	SCSI_WRITE_EXT		0x2a
#define	SCSI_SEEK_EXT		0x2b
#define	SCSI_WRITE_VERIFY	0x2e
#define	SCSI_VERIFY_EXT		0x2f
#define	SCSI_SEARCH_HIGH	0x30
#define SCSI_SEARCH_EQUAL	0x31
#define	SCSI_SEARCH_LOW		0x32
#define	SCSI_SET_LIMITS		0x33
#define	SCSI_COMPARE		0x39
#define	SCSI_COPY_VERIFY	0x3a

/*
 * Control byte flags for Group0 and Group1 commands.
 *
 * SCSI_CTRL_LINK - This is used to prevent a bus free phase between commands.
 *	If the command terminates successfully, a SCSI_LINKED_CMD_COMPLETE
 *	message is returned instead of the normal SCSI_COMMAND_COMPLETE message. *	The last command in a chain should not have this bit set
 *	(and consequently gets a normal SCSI_COMMAND_COMPLETE message).
 * SCSI_CTRL_LINK_FLAG - This bit should only set when SCSI_CTRL_LINK is set and
 *	causes a SCSI_LINKED_FLAGED_CMD_COMPLETE to be returned instead of
 *	a SCSI_LINKED_CMD_COMPLETE.
 */
#define SCSI_CTRL_LINK		0x01	/* Link commands (no bus free phase) */
#define SCSI_CTRL_LINK_INTR	0x02	/* Interrupt after linked command */

/*
 * The standard group0 6-byte SCSI control block.  Note that the 
 * fields between highAddr and blockCount inclusive are command dependent.
 * The definitions Addr and BlockCount cover most of the commands we will
 * use.
 */
typedef struct ScsiGroup0Cmd {
	u_char	command;		/* command code, defined below.  The
					 * upper three bits of this are zero
					 * to indicate the control block is
					 * only 6 bytes long */
#if BYTE_ORDER == BIG_ENDIAN
	u_char	unitNumber	:3;	/* Logical Unit (LUN) to which to
					 * pass the command.  The device
					 * has already been selected using
					 * the "targetID" bit. */
	u_char	highAddr	:5;	/* High bits of address */
#else
	u_char	highAddr	:5;	/* High bits of address */
	u_char	unitNumber	:3;	/* Logical Unit (LUN) to which to
					 * pass the command.  The device
					 * has already been selected using
					 * the "targetID" bit. */
#endif
	u_char	midAddr;		/* Middle bits of address */
	u_char	lowAddr;		/* Low bits of address */
	u_char	blockCount;		/* Blocks to transfer */
	u_char	control;		/* See flags for common bits */
} ScsiGroup0Cmd;

/*
 * Format of a SCSI_START_STOP command. This is a group 0 command, but
 * the command contents are different.
 */
typedef struct ScsiStartStopCmd {
#if BYTE_ORDER == BIG_ENDIAN
	u_char	command;		/* command code, defined below.  The
					 * upper three bits of this are zero
					 * to indicate the control block is
					 * only 6 bytes long */
	u_char	unitNumber	:3;	/* Logical Unit (LUN) to which to
					 * pass the command.  The device
					 * has already been selected using
					 * the "targetID" bit. */
	u_char	pad1		:4;	/* Reserved */
	u_char	immed		:1;	/* Immediate status bit */
	u_char	pad2;			/* Reserved */
	u_char	pad3;			/* Reserved */
	u_char	pad4		:6;	/* Reserved */
	u_char	loadEject	:1;	/* Load or eject medium */
	u_char	start		:1;	/* Start or stop medium */
	u_char	control;		/* See flags for common bits */
#else
	u_char	command;		/* command code, defined below.  The
					 * upper three bits of this are zero
					 * to indicate the control block is
					 * only 6 bytes long */
	u_char	immed		:1;	/* Immediate status bit */
	u_char	pad1		:4;	/* Reserved */
	u_char	unitNumber	:3;	/* Logical Unit (LUN) to which to
					 * pass the command.  The device
					 * has already been selected using
					 * the "targetID" bit. */
	u_char	pad2;			/* Reserved */
	u_char	pad3;			/* Reserved */
	u_char	start		:1;	/* Start or stop medium */
	u_char	loadEject	:1;	/* Load or eject medium */
	u_char	pad4		:6;	/* Reserved */
	u_char	control;		/* See flags for common bits */
#endif
} ScsiStartStopCmd;

/*
 * The standard group1 10-byte SCSI control block.  Note that the 
 * fields between highAddr and blockCount inclusive are command dependent.
 * The definitions Addr and BlockCount cover most of the commands we will
 * use.
 */
typedef struct ScsiGroup1Cmd {
	u_char	command;		/* command code, defined below.  The
					 * upper three bits of this are zero
					 * to indicate the control block is
					 * only 6 bytes long */
#if BYTE_ORDER == BIG_ENDIAN
	u_char	unitNumber	:3;	/* Logical Unit (LUN) to which to
					 * pass the command.  The device
					 * has already been selected using
					 * the "targetID" bit. */
	u_char	pad1		:5;	/* Reserved */
#else
	u_char	pad1		:5;	/* Reserved */
	u_char	unitNumber	:3;	/* Logical Unit (LUN) to which to
					 * pass the command.  The device
					 * has already been selected using
					 * the "targetID" bit. */
#endif
	u_char	highAddr;		/* High bits of address */
	u_char	midHighAddr;		/* Middle high bits of address */
	u_char	midLowAddr;		/* Middle low bits of address */
	u_char	lowAddr;		/* Low bits of address */
	u_char	pad2;			/* Reserved */
	u_char	highBlockCount;	/* High bits of blocks to transfer */
	u_char	lowBlockCount;	/* Low bits of blocks to transfer */
	u_char	control;		/* See flags for common bits */
} ScsiGroup1Cmd;

/*
 * SCSI status completion information.
 * This is returned by the device when a command completes. 
 */
#define	SCSI_STATUS_CHECKCOND	0x02	/* Check Condition (ie., read sense) */
#define	SCSI_STATUS_CONDMET	0x04	/* Condition Met (ie., search worked) */
#define	SCSI_STATUS_BUSY	0x08
#define	SCSI_STATUS_INTERMED	0x10	/* Intermediate status sent */
#define	SCSI_STATUS_EXT		0x80	/* Extended status valid */

/*
 * Sense information provided after some errors.  This is divided into
 * two kinds, classes 0-6, and class 7.  This is 30 bytes big to allow
 * for the drive specific sense bytes that follow the standard 4 byte header.
 *
 * For extended sense, this buffer may be cast into another type.  Also
 * The actual size of the sense data returned is used to detect what
 * kind of tape drive is out there.  Kludgy, but true.
 */
typedef struct ScsiClass0Sense {
#if BYTE_ORDER == BIG_ENDIAN
	u_char	valid		:1;	/* Sense data is valid */
	u_char	error		:7;	/* 3 bits class and 4 bits code */
#else
	u_char	error		:7;	/* 3 bits class and 4 bits code */
	u_char	valid		:1;	/* Sense data is valid */
#endif
	u_char	highAddr;		/* High byte of block address */
	u_char	midAddr;		/* Middle byte of block address */
	u_char	lowAddr;		/* Low byte of block address */
	u_char	sense[26];		/* Target specific sense data */
} ScsiClass0Sense;

/*
 * Definitions for errors in the sense data.  The error field is specified
 * as a 3 bit class and 4 bit code, but it is easier to treat it as a
 * single 7 bit field.
 */
#define SCSI_NO_SENSE_DATA		0x00
#define SCSI_NOT_READY			0x04
#define SCSI_NOT_LOADED			0x09
#define SCSI_INSUF_CAPACITY		0x0a
#define SCSI_HARD_DATA_ERROR		0x11
#define SCSI_WRITE_PROTECT		0x17
#define SCSI_CORRECTABLE_ERROR		0x18
#define SCSI_FILE_MARK			0x1c
#define SCSI_INVALID_COMMAND		0x20
#define SCSI_UNIT_ATTENTION		0x30
#define SCSI_END_OF_MEDIA		0x34

/*
 * The standard "extended" sense data returned by SCSI devices.  This
 * has an error field of 0x70, for a "class 7" error.
 */
typedef struct ScsiClass7Sense {
#if BYTE_ORDER == BIG_ENDIAN
	u_char	valid		:1;	/* Sense data is valid */
	u_char	error7		:7;	/* == 0x70 */
	u_char	pad1;			/* Also "segment number" for copy */
	u_char	fileMark	:1;	/* File mark on device */
	u_char	endOfMedia	:1;	/* End of media reached */
	u_char	badBlockLen	:1;	/* Block length mis-match (Exabyte) */
	u_char	pad2		:1;
	u_char	key		:4;	/* Sense keys defined below */
	u_char	info1;			/* Information byte 1 */
	u_char	info2;			/* Information byte 2 */
	u_char	info3;			/* Information byte 3 */
	u_char	info4;			/* Information byte 4 */
	u_char	length;			/* Number of additional info bytes */
#else
	u_char	error7		:7;	/* == 0x70 */
	u_char	valid		:1;	/* Sense data is valid */
	u_char	pad1;			/* Also "segment number" for copy */
	u_char	key		:4;	/* Sense keys defined below */
	u_char	pad2		:1;
	u_char	badBlockLen	:1;	/* Block length mis-match (Exabyte) */
	u_char	endOfMedia	:1;	/* End of media reached */
	u_char	fileMark	:1;	/* File mark on device */
	u_char	info1;			/* Information byte 1 */
	u_char	info2;			/* Information byte 2 */
	u_char	info3;			/* Information byte 3 */
	u_char	info4;			/* Information byte 4 */
	u_char	length;			/* Number of additional info bytes */
#endif
} ScsiClass7Sense;			/* 8 Bytes */

/*
 * Key values for standardized sense class 7. 
 */
#define SCSI_CLASS7_NO_SENSE		0
#define SCSI_CLASS7_RECOVERABLE		1
#define SCSI_CLASS7_NOT_READY		2
#define SCSI_CLASS7_MEDIA_ERROR		3
#define SCSI_CLASS7_HARDWARE_ERROR	4
#define SCSI_CLASS7_ILLEGAL_REQUEST	5

/*
 * These seem to have different meanings to different vendors....
 */
#define SCSI_CLASS7_MEDIA_CHANGE	6
#define SCSI_CLASS7_UNIT_ATTN		6

#define SCSI_CLASS7_WRITE_PROTECT	7
#define SCSI_CLASS7_BLANK_CHECK		8
#define SCSI_CLASS7_VENDOR		9
#define SCSI_CLASS7_POWER_UP_FAILURE	10
#define SCSI_CLASS7_ABORT		11
#define SCSI_CLASS7_EQUAL		12
#define SCSI_CLASS7_OVERFLOW		13
#define SCSI_CLASS7_RESERVED_14		14
#define SCSI_CLASS7_RESERVED_15		15

/*
 * Data return by the SCSI inquiry command. 
 */
typedef struct ScsiInquiryData {
#if BYTE_ORDER == BIG_ENDIAN
	u_char	type;		/* Peripheral Device type. See below. */
	u_char	rmb:1;		/* Removable Medium bit. */
	u_char	qualifier:7;	/* Device type qualifier. */
	u_char	version;	/* Version info. */
	u_char	reserved:4;	/* reserved. */
	u_char	format:4;	/* Response format. */
	u_char	length;		/* length of data returned. */
	u_char	reserved2[2];	/* Reserved */
	u_char	flags;		/* SCSI II flags (see below) */
	u_char	vendorID[8];	/* Vendor ID (ASCII) */
	u_char	productID[16];	/* Product ID (ASCII) */
	u_char	revLevel[4];	/* Revision level (ASCII) */
	u_char	revData[8];	/* Revision data (ASCII) */
#else
	u_char	type;		/* Peripheral Device type. See below. */
	u_char	qualifier:7;	/* Device type qualifier. */
	u_char	rmb:1;		/* Removable Medium bit. */
	u_char	version;	/* Version info. */
	u_char	format:4;	/* Response format. */
	u_char	reserved:4;	/* reserved. */
	u_char	length;		/* length of data returned. */
	u_char	reserved2[2];	/* Reserved */
	u_char	flags;		/* SCSI II flags (see below) */
	u_char	vendorID[8];	/* Vendor ID (ASCII) */
	u_char	productID[16];	/* Product ID (ASCII) */
	u_char	revLevel[4];	/* Revision level (ASCII) */
	u_char	revData[8];	/* Revision data (ASCII) */
#endif
} ScsiInquiryData;

/*
 * The SCSI Peripheral type ID codes as return by the SCSI_INQUIRY command.
 *
 * SCSI_DISK_TYPE - Direct Access Device.
 * SCSI_TAPE_TYPE - Sequential Access Device.
 * SCSI_PRINTER_TYPE - Printer Device.
 * SCSI_HOST_TYPE - Processor Device.
 * SCSI_WORM_TYPE - Write-Once Read-Multiple Device.
 * SCSI_ROM_TYPE - Read-Only Direct Access Device.
 * SCSI_SCANNER_TYPE - Scanner device.
 * SCSI_OPTICAL_MEM_TYPE - Optical memory device.
 * SCSI_MEDIUM_CHANGER_TYPE - Medium changer device.
 * SCSI_COMMUNICATIONS_TYPE - Communications device.
 * SCSI_NODEVICE_TYPE - Logical Unit not present or implemented.
 *
 * Note that codes 0xa-0x7e are reserved and 0x80-0xff are vendor unique.
 */
#define	SCSI_DISK_TYPE			0
#define	SCSI_TAPE_TYPE			1
#define	SCSI_PRINTER_TYPE		2
#define	SCSI_HOST_TYPE			3
#define	SCSI_WORM_TYPE			4
#define	SCSI_ROM_TYPE			5
#define	SCSI_SCANNER_TYPE		6
#define	SCSI_OPTICAL_MEM_TYPE		7
#define	SCSI_MEDIUM_CHANGER_TYPE	8
#define	SCSI_COMMUNICATIONS_TYPE	9
#define	SCSI_NODEVICE_TYPE		0x7f

/*
 * The SCSI I & II inquiry flags.
 *
 * SCSI_REL_ADR - Relative addressing supported.
 * SCSI_WIDE_32 - 32 bit wide SCSI bus transfers supported.
 * SCSI_WIDE_16 - 16 bit wide SCSI bus transfers supported.
 * SCSI_SYNC - Synchronous data transfers supported.
 * SCSI_LINKED - Linked commands supported.
 * SCSI_CMD_QUEUE - Tagged command queuing supported.
 * SCSI_SOFT_RESET - Soft RESET alternative suported.
 */
#define SCSI_REL_ADR		0x80
#define SCSI_WIDE_32		0x40
#define SCSI_WIDE_16		0x20
#define SCSI_SYNC		0x10
#define SCSI_LINKED		0x08
#define SCSI_CMD_QUEUE		0x02
#define SCSI_SOFT_RESET		0x01

/*
 * Standard header for SCSI_MODE_SENSE and SCSI_MODE_SELECT commands for tapes.
 */
typedef struct ScsiTapeModeSelectHdr {
	u_char	len;		/* length */
	u_char	media;		/* media type */
#if BYTE_ORDER == BIG_ENDIAN
	u_char	writeprot:1;	/* Write protected media */
	u_char	bufferedMode:3;	/* Type of buffer to be done. */
	u_char	speed:4;	/* Drive speed. */
#else
	u_char	speed:4;	/* Drive speed. */
	u_char	bufferedMode:3;	/* Type of buffer to be done. */
	u_char	writeprot:1;	/* Write protected media */
#endif
	u_char	length;		/* Block descriptor length. */
	u_char	density;	/* tape density code */
	u_char	blocks_2;	/* number of blocks (MSB) */
	u_char	blocks_1;	/* number of blocks */
	u_char	blocks_0;	/* number of blocks (LSB) */
	u_char	reserved;	/* */
	u_char	block_size2;	/* Tape block size (MSB) */
	u_char	block_size1;	/* Tape block size */
	u_char	block_size0;	/* Tape block size (LSB) */
	u_char	vendor[6];	/* vendor specific data */
} ScsiTapeModeSelectHdr;

/*
 * Definitions of SCSI messages.
 *
 * SCSI_COMMAND_COMPLETE - After a command has completed, successfully
 *	or not, this is returned to the host from the target.
 *
 * SCSI_EXTENDED_MSG - Indicates that a multi-byte message is being sent.
 *
 * The following messages are used with connect/disconnect:
 * SCSI_SAVE_DATA_POINTER - Sent from target to host to request saving
 *	of current DMA address and count.  Indicates a pending dis-connect.
 * SCSI_RESTORE_POINTER - Sent from the target to the host to request
 *	restoring pointers saved before a disconnect
 * SCSI_DISCONNECT - Sent from the target to the host to disconnect.
 * SCSI_ABORT - Sent from the host to the target to abort current request.
 * SCSI_MESSAGE_REJECT -  Indicates receipt, by either host or target, of
 *	an unimplemented message.
 * SCSI_NO_OP - Sent from host to target if it has no real message to send.
 * SCSI_MESSAGE_PARITY_ERROR - Sent from host to target on message parity error
 * SCSI_BUS_RESET - Sent from host to target to reset all current I/O
 *
 * SCSI_IDENTIFY - The low order two bits of this message type indicate
 *	the Logical Unit of the Target which is requesting a reconnect.
 * SCSI_DIS_REC_IDENTIFY - Sent from the host to a target to indicate
 *	is supports connect/dis-connect
 *	
 */
#define SCSI_COMMAND_COMPLETE		0x00
#define SCSI_EXTENDED_MSG		0x01
#define SCSI_SAVE_DATA_POINTER		0x02
#define SCSI_RESTORE_POINTERS		0x03
#define SCSI_DISCONNECT			0x04
#define SCSI_ABORT			0x06
#define SCSI_MESSAGE_REJECT		0x07
#define SCSI_NO_OP			0x08
#define SCSI_MESSAGE_PARITY_ERROR	0x09
#define SCSI_LINKED_CMD_COMPLETE	0x0A
#define SCSI_LINKED_FLAGED_CMD_COMPLETE	0x0B
#define SCSI_BUS_RESET			0x0C

#define SCSI_IDENTIFY			0x80
#define SCSI_DIS_REC_IDENTIFY		0xc0

/*
 * Extended message types (2nd byte of SCSI_EXTENDED_MSG).
 */
#define SCSI_MODIFY_DATA_PTR		0x00
#define SCSI_SYNCHRONOUS_XFER		0x01
#define SCSI_EXTENDED_IDENTIFY		0x02 /* only in SCSI I */
#define SCSI_WIDE_XFER			0x03

/*
 * Driver ioctl's for various scsi operations.
 */
#ifndef _IOCTL_
#include <sys/ioctl.h>
#endif

/*
 * Control for SCSI "format" mode.
 *
 * "Format" mode allows a privileged process to issue direct SCSI
 * commands to a drive (it is intended primarily to allow on-line
 * formatting).  SDIOCSFORMAT with a non-zero arg will put the drive
 * into format mode; a zero arg will take it out.  When in format
 * mode, only the process that issued the SDIOCFORMAT can read or
 * write the drive.
 *
 * In format mode, process is expected to
 *	- do SDIOCSCSICOMMAND to supply cdb for next SCSI op
 *	- do read or write as appropriate for cdb
 *	- if i/o error, optionally do SDIOCSENSE to get completion
 *	  status and sense data from last scsi operation.
 */

struct scsi_fmt_cdb {
	int	len;		/* cdb length (in bytes) */
	u_char	cdb[28];	/* cdb to use on next read/write */
};

struct scsi_fmt_sense {
	u_int	status;		/* completion status of last op */
	u_char	sense[32];	/* sense data (if any) from last op */
};

#define	SDIOCSFORMAT		_IOW('S', 0x1, int)
#define	SDIOCGFORMAT		_IOR('S', 0x2, int)
#define	SDIOCSCSICOMMAND	_IOW('S', 0x3, struct scsi_fmt_cdb)
#define	SDIOCSENSE		_IOR('S', 0x4, struct scsi_fmt_sense)

#ifdef _KERNEL
/*
 * Routines.
 */
extern void scsiGroup0Cmd();
extern void scsiGroup1Cmd();
#endif /* _KERNEL */

#endif /* _SCSI_H */