/* $Copyright:	$
 * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989, 1990 
 * Sequent Computer Systems, Inc.   All rights reserved.
 *  
 * This software is furnished under a license and may be used
 * only in accordance with the terms of that license and with the
 * inclusion of the above copyright notice.   This software may not
 * be provided or otherwise made available to, or used by, any
 * other person.  No title to or ownership of the software is
 * hereby transferred.
 */

/* $Header: scsi.h 1.2 88/10/26 $ */

/*
 * Supported SCSI commands.
 */

/* class 00 commands */
#define	SCSI_TEST		0x00	/* Test unit ready */
#define SCSI_REZERO		0x01	/* Rezero unit */
#define SCSI_RSENSE		0x03	/* Request sense */
#define SCSI_FORMAT		0x04	/* Format unit */
#define SCSI_REASS		0x07	/* Reassign blocks */
#define	SCSI_READ		0x08	/* Read */
#define	SCSI_WRITE		0x0a	/* Write */
#define	SCSI_SEEK		0x0b	/* Seek */
#define SCSI_TRAN		0x0f	/* Translate logical to phys */
#define SCSI_INQUIRY		0x12	/* Do inquiry, note: not 4000 */
#define SCSI_WRITEB		0x13	/* Write buffer */
#define SCSI_READB		0x14	/* Read buffer */
#define SCSI_MODES		0x15	/* Mode select */
#define SCSI_RESRV		0x16	/* Reserve unit, note: not 4000 */
#define SCSI_RELSE		0x17	/* Release unit, note: not 4000 */
#define SCSI_MSENSE		0x1a	/* Mode sense, note: not 4000 */
#define SCSI_STARTOP		0x1b	/* Start/stop unit */
#define		SCSI_START_UNIT		0x01
#define		SCSI_STOP_UNIT		0x00
#define SCSI_RDIAG		0x1c	/* Receive diagnostic */
#define SCSI_SDIAG		0x1d	/* Send diagnostic */
#define		SCSI_SDIAG_REINIT	0x60
#define		SCSI_SDIAG_DUMP_HW	0x61
#define		SCSI_SDIAG_DUMP_RAM	0x62
#define		SCSI_SDIAG_PATCH_HW	0x63
#define		SCSI_SDIAG_PATCH_RAM	0x64
#define		SCSI_SDIAG_SET_RD_ERR	0x65
#define			SCSI_SDIAG_RD_ERR_DEF	0x00
#define			SCSI_SDIAG_RD_ERR_NOC	0x01
#define			SCSI_SDIAG_RD_ERR_RPT	0x02

/* Class 01 commands */
#define SCSI_READC		0x25	/* Read capacity */
#define		SCSI_FULL_CAP		0x00
#define		SCSI_PART_CAP		0x01
#define SCSI_READ_EXTENDED	0x28
#define SCSI_WRITE_EXTENDED	0x2A

/*
 * Unsupported SCSI commands.
 */
#define SCSI_SET_THRESHOLD	0x10
#define SCSI_RD_USAGE_CTRS	0x11
#define SCSI_WRITE_AND_VERIFY	0x2E
#define SCSI_VERIFY		0x2F
#define SCSI_SEARCH_DATA_EQUAL	0x31
#define SCSI_SET_LIMITS		0x33

/*
 * Tape commands
 */
#define SCSI_REWIND		0x01	/* Rewind command */
#define SCSI_RETENTION		0x02	/* Retention a tape */
#define SCSI_WFM		0x10	/* Write a file mark */
#define SCSI_SPACE		0x11	/* Space (default blocks) fwd */
#define 	SCSI_SPACE_BLOCKS	0x00
#define 	SCSI_SPACE_FILEMARKS	0x01
#define 	SCSI_SPACE_SFILEMARKS	0x02
#define 	SCSI_SPACE_ENDOFDATA	0x03

#define	SCSI_FIXED_BLOCKS	0x01
#define SCSI_ERASE_LONG		0x01

#define SCSI_ERASE		0x19	/* Erase a tape */

/*
 * Sizes of data transferred for some standard commands.
 */
#define SIZE_CAP		8	/* #bytes in Read Capacity input data */
#define SIZE_TRANS		8	/* #bytes in Translate input data */
#define SIZE_INQ		4	/* #bytes in Inquiry output data */
#define SIZE_INQ_XTND		36	/* #bytes in extended Inquiry data */
#define SIZE_BDESC		12	/* #bytes in Mode Select block descr. */
#define SIZE_MAXDATA		36	/* #bytes in largest data transfer */

#define SCSI_CMD6SZ		6	/* SCSI command length */
#define SCSI_CMD10SZ		10	/* SCSI command length */
#define SCSI_CMD12SZ		12	/* SCSI command length */

/*
 * Structure for SCSI mode select command  (non-CCS devices).
 */
#define SCSI_MODES_ILEN		22	/* Bytes in data block */
#define SCSI_MODES_DLEN		8	/* Length of extent decriptor list */

struct  scsi_modes {
			/* Command list */
	unchar	m_type;			/* Command type */
	unchar	m_unit;			/* Upper 3 bits are unit */
	unchar	m_pad1[2];		/* Reserved */
	unchar	m_ilen;			/* Length of info passed */
	unchar	m_cont;			/* Control byte */
			/* Parameter list */
	unchar	m_pad2[3];		/* Reserved */
	unchar	m_dlen;			/* Length of descript list */
			/* Extent descripter list */
	unchar	m_density;		/* Density code */
	unchar	m_pad3[4];		/* Reserved */
	unchar	m_bsize[3];		/* Block size */
			/* Drive parameter list */
	unchar	m_fcode;		/* Format code */
	unchar	m_cyls[2];		/* Cylinder count */
	unchar	m_heads;		/* Data head count */
	unchar	m_rwcc[2];		/* Reduced write current cylinder */
	unchar	m_wpc[2];		/* Write precompensation cylinder */
	char	m_lzone;		/* Landing zone position */
	unchar	m_srate;		/* Step pulse output rate code */
};

/* 
 * Structures for SCSI format command (non-CCS devices).
 */

struct dlist {				/* Defect list entries */
	unchar	d_cyls[3];		/* Cyl of defect */
	unchar	d_heads;		/* Head nbr */
	unchar	d_bytes[4];		/* Bytes from index */
};

#define FORMAT_BUF	1024		/* Max bytes for Format Data */
#define MAX_DEFECTS	(FORMAT_BUF / sizeof(struct dlist))

struct	scsi_fmt {
			/* Command list */
	unchar	f_type;			/* Command type */
	unchar	f_misc;			/* 3 bit unit, data flag,
					 * complete list bits */
	unchar	f_data;			/* Data pattern */
	unchar	f_ileave[2];		/* Interleave */
	unchar	f_pad1;			/* Reserved */
			/* Defect list */
	unchar	f_full;			/* Full or cyl flag: cyl not on 4000 */
	unchar	f_spares;		/* Number spares/cyl: not on 4000 */
	unchar	f_dlen[2];		/* Length of defect list blocks */
	struct dlist dlist[MAX_DEFECTS]; /* Blocks of defect list */
};

/*
 * scsi_fmt.f_misc flags
 */
#define FMT_BBL_DATA		0x10	/* Bbl data exists */
#define FMT_CMPLT		0x08	/* Bbl data is complete */
#define FMT_USER_FMT		0x04	/* Use user-supplied fmt data */
#define FMT_DATA		0x02	/* Use user-supplied data pattern */
#define FMT_ALL		(FMT_BBL_DATA | FMT_CMPLT | FMT_USER_FMT | FMT_DATA)

/*
 * scsi_fmt.f_data
 */
#define FMT_PAT			0x6D	/* Worst winchester data */

/*
 * scsi_fmt.f_full flags
 */
#define	FMT_FULL		0x00	/* Complete drive */
#define	FMT_CYL			0x01	/* Single cylinder: not on 4000 */

/*
 * scsi_fmt.f_code
 */
#define FMT_FCODE		0x01	/* Must be 1 */

/*
 * Numbering for the SCSI stand alone device drivers' 
 * major numbers and numbering macros.
 *
 * UNIT: Unit number, must be in the range of 0-8191 inclusive.
 * 	bits 0-2: unit number on the hardware (up to 8)
 *	bits 3-5: controller select (target adapter) (up to 8)
 *	bits 6-8: drive  type (up to 8), index into configuration table 
 *	bits 9-11: SCSI board number
 *
 * OFFSET: In the case of disk, if in the range of 0-7, 
 *	indexes into partition table, otherwise it is the 
 *	actual block offset.  In the case of tape, it is 
 *	the file number to space to upon opening the device
 *	(starting at zero).
 */

/*
 * Unit number macros.
 */
#define SCSI_UNIT(x)	(((x)>>0)&7)
#define	SCSI_TARGET(x)	(((x)>>3)&7)
#define SCSI_TYPE(x)	(((x)>>6)&7)
#define SCSI_BOARD(x)	(((x)>>9)&7)
#define SCSI_DEVNO(x)	 (SCSI_TARGET((x))<<3) + (SCSI_UNIT((x))) 

/*
 * SCSI command termination status byte macros.
 */
#define SCSI_GOOD(status) (((status) & 0x1E) == 0)
#define	SCSI_CHECK_CONDITION(status) (((status) & 0x1E) == 0x2)
#define	SCSI_CONDITION_MET(status) (((status) & 0x1E) == 0x4)
#define	SCSI_BUSY(status)	(((status) & 0x1E) == 0x8)
#define SCSI_INTERMEDIATE(status)	(((status) & 0x1E) == 0x10)
#define	SCSI_RES_CONFLICT(status)	(((status) & 0x1E) == 0x18)	

/*
 * Inquiry command returned data.
 */
struct scinq {
	unchar sc_devtype;		/* Type SCSI device */
	unchar sc_qualif;		/* Dev type qualifier */
	unchar sc_version;		/* SCSI spec version */
	unchar sc_reserved;
	unchar sc_vlength;		/* Length of vendor unique data */
};

/*
 * Defines for scinq.sc_devtype.
 */
#define	INQ_DIRECT		0x00	/* Direct-access device */
#define INQ_SEQ			0x01	/* Sequential access device */
#define INQ_PRINT		0x02	/* Printer device */
#define INQ_PROC		0x03	/* Processor device */
#define INQ_WRONCE		0x04	/* Write-once read multiple times */
#define INQ_READONLY		0x05	/* Read only medium device */
#define INQ_NOTFOUND		0x7F	/* Logical device not found */

/*
 * Defines for scinq.sc_qualif.
 */
#define	INQ_REMOVABLE		0x80	/* Has removable media */

/*
 * Minimum structure for request sense data.
 */
struct scrsense {
	unchar	rs_error;		/* Error code and valid bit */
	unchar	rs_seg;			/* Segment Number */
	unchar	rs_key;			/* Filemark,EOM,ILI, and Sense Key */
	unchar	rs_info[4];		/* Information bytes */
	unchar	rs_addlen;		/* Additional length in bytes */
};

/*
 * Defines for scrsense.rs_error.
 */
#define	RS_VALID		0x80	/* Bit indicates error code is valid */
#define	RS_ERRCODE		0x7f	/* Mask for error code */
#define	RS_CURERR		0x70	/* Current error */
#define	RS_DEFERR		0x71	/* Deferred error */
#define	RS_VENDERR		0x7f	/* Vendor unique error code */
#define RS_CLASS_EXTEND		0x70	/* Extended class of error codes */

/*
 * Defines for scrsense.rs_key.
 */
#define	RS_FILEMARK		0x80	/* Filemark has just been read */
#define	RS_EOM			0x40	/* End of media encountered */
#define	RS_ILI			0x20	/* Incorrect block length indicator */
#define	RS_RES			0x10	/* Reserved for future use */
#define	RS_KEY			0x0f	/* Mask for Sense Key codes */

/*
 * Sense Key codes for scrsense.rs_key & RS_KEY.
 */
#define	RS_NOSENSE		0x00	/* No Sense information available */
#define	RS_RECERR		0x01	/* Recovered from error */
#define	RS_NOTRDY		0x02	/* Addressed unit not accessible */
#define	RS_MEDERR		0x03	/* Error in medium encountered */
#define	RS_HRDERR		0x04	/* Target detects hardware failure */
#define	RS_ILLREQ		0x05	/* Illegal request */
#define	RS_UNITATTN		0x06	/* Media changed or target reset */
#define	RS_PROTECT		0x07	/* Media protected against operation */
#define	RS_BLANK		0x08	/* Blank check medium error */
#define	RS_VENDUNIQ		0x09	/* Vendor unique code */
#define	RS_CPABORT		0x0a	/* Copy command aborted */
#define	RS_ABORT		0x0a	/* Command aborted */
#define	RS_EQUAL		0x0c	/* Search data found equal comparison */
#define	RS_OVFLOW		0x0d	/* Volume overflow */
#define	RS_MISCMP		0x0e	/* Source and media data mis-compare */
#define	RS_RESKEY		0x0f	/* Reserved for future use */


