154878Storek /* 2*63144Sbostic * Copyright (c) 1992, 1993 3*63144Sbostic * The Regents of the University of California. All rights reserved. 454878Storek * 554878Storek * This software was developed by the Computer Systems Engineering group 654878Storek * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 754878Storek * contributed to Berkeley. 854878Storek * 955559Storek * All advertising materials mentioning features or use of this software 1055559Storek * must display the following acknowledgement: 1155559Storek * This product includes software developed by the University of 1255559Storek * California, Lawrence Berkeley Laboratories. 1355559Storek * 1454878Storek * %sccs.include.redist.c% 1554878Storek * 16*63144Sbostic * @(#)scsi.h 8.1 (Berkeley) 06/10/93 1754878Storek * 1857753Storek * from: $Header: scsi.h,v 1.5 93/02/01 19:19:15 torek Exp $ (LBL) 1954878Storek */ 2054878Storek 2154878Storek /* 2254878Storek * Machine independent SCSI defintions. 2354878Storek */ 2454878Storek 2554878Storek /* 2654878Storek * Mostly-generic command descriptor blocks (6 and 10 bytes). 2754878Storek * Note that no SCSI command uses the 12 byte variety, hence it 2854878Storek * is not defined here. 2954878Storek */ 3054878Storek struct scsi_cdb6 { 3154878Storek u_char cdb_cmd, /* command code */ 3254878Storek cdb_lun_lbah, /* logical unit number, & lba (MSB) */ 3354878Storek cdb_lbam, /* logical block address */ 3454878Storek cdb_lbal, /* logical block address (LSB) */ 3554878Storek cdb_len, /* transfer length */ 3654878Storek cdb_ctrl; /* control byte */ 3754878Storek }; 3854878Storek 3954878Storek struct scsi_cdb10 { 4054878Storek u_char cdb_cmd, /* command code */ 4154878Storek cdb_lun_rel, /* logical unit number, rsvd, & reladr flag */ 4254878Storek cdb_lbah, /* logical block address (MSB) */ 4354878Storek cdb_lbahm, /* logical block address (high middle byte) */ 4454878Storek cdb_lbalm, /* logical block address (low middle byte) */ 4554878Storek cdb_lbal, /* logical block address (LSB) */ 4654878Storek cdb_xxx, /* reserved */ 4754878Storek cdb_lenh, /* transfer length (MSB) */ 4854878Storek cdb_lenl, /* transfer length (LSB) */ 4954878Storek cdb_ctrl; /* control byte */ 5054878Storek }; 5154878Storek 5254878Storek /* 5354878Storek * SCSI `generic' cdb. 5454878Storek * The length of the cdb is implicit in the first byte (see scsivar.h). 5554878Storek * This is 16 bytes, rather than 10 or 12, just to help out alignment. 5654878Storek */ 5754878Storek struct scsi_cdb { 5854878Storek u_char cdb_bytes[16]; /* up to 16 bytes of command */ 5954878Storek }; 6054878Storek #define CDB6(cdb) ((struct scsi_cdb6 *)&(cdb)->cdb_bytes[0]) 6154878Storek #define CDB10(cdb) ((struct scsi_cdb10 *)&(cdb)->cdb_bytes[0]) 6254878Storek 6354878Storek /* 6454878Storek * SCSI command (cdb_cmd/cdb_bytes[0]) byte definitions. Only those 6554878Storek * that are common across all devices are actually defined here. 6654878Storek * (The SCSI standard defines six groups of devices: direct access, 6754878Storek * sequential access, printer, processor, WORM direct access, and 6854878Storek * ROM direct access. DADs and SADs are basically `disk' and `tape'; 6954878Storek * printers and processors are obvious; and WORMs and ROMs are really 7054878Storek * just disks that are missing one or two operations. A few commands 7154878Storek * are required of all devices; these are defined here, and the others 7254878Storek * are defined in separate headers.) 7354878Storek * 7454878Storek * Letter flags in parentheses in the comment column indicate: 7554878Storek * M = mandatory (command is implemented on all SCSI devices) 7654878Storek * E = extended (command implemented if SCSI device does extended SCSI) 7754878Storek * O = optional 7854878Storek * R = reserved to future SCSI standard 7954878Storek * V = vendor unique 8054878Storek * * = depends on device type 8154878Storek * 8254878Storek * Note that SCSI commands are broken into 8 `groups' given by bits 7..5. 8354878Storek * Group 0 is 6-byte commands, 1 is 10-byte commands, and 5 is 12-byte 8454878Storek * commands (of which none exist); groups 6 and 7 are vendor unique. 8554878Storek * Commands are normally just treated as a simple 8-bit number, 8654878Storek * but the size of the associated cdb is implied by the group. 8754878Storek */ 8854878Storek /* group 0 */ 8954878Storek #define CMD_TEST_UNIT_READY 0x00 /* (O) test unit ready */ 9054878Storek /* 0x01 (*) */ 9154878Storek /* 0x02 (V) */ 9254878Storek #define CMD_REQUEST_SENSE 0x03 /* (M) request sense */ 9354878Storek /* 0x04..0x05 (*) */ 9454878Storek /* 0x06 (V) */ 9554878Storek /* 0x07..0x08 (*) */ 9654878Storek /* 0x09 (V) */ 9754878Storek /* 0x0a..0x0b (*) */ 9854878Storek /* 0x0c..0x0e (V) */ 9954878Storek /* 0x0f..0x11 (*) */ 10054878Storek #define CMD_INQUIRY 0x12 /* (E) inquiry */ 10154878Storek /* 0x13..0x17 (*) */ 10254878Storek #define CMD_COPY 0x18 /* (O) copy */ 10354878Storek /* 0x19..0x1b (*) */ 10454878Storek #define CMD_RECEIVE_DIAG 0x1c /* (O) receive diagnostic results */ 10554878Storek #define CMD_SEND_DIAG 0x1d /* (O) send diagnostic */ 10654878Storek /* 0x1e (*) */ 10754878Storek /* 0x1f (R) */ 10854878Storek /* group 1 */ 10954878Storek /* 0x20..0x24 (V) */ 11054878Storek /* 0x25 (*) */ 11154878Storek /* 0x26..0x27 (V) */ 11254878Storek /* 0x28 (*) */ 11354878Storek /* 0x29 (V) */ 11454878Storek /* 0x2a..0x2b (*) */ 11554878Storek /* 0x2c..0x2d (V) */ 11654878Storek /* 0x2e..0x33 (*) */ 11754878Storek /* 0x34..0x37 (R) */ 11854878Storek #define CMD_COMPARE 0x38 /* (O) compare */ 11954878Storek #define CMD_COMPARE_VERIFY 0x39 /* (O) compare and verify */ 12054878Storek /* 0x3a..0x3f (R) */ 12154878Storek /* group 2 (40-5f) reserved */ 12254878Storek /* group 3 (60-7f) reserved */ 12354878Storek /* group 4 (80-9f) reserved */ 12454878Storek /* group 5 (a0-bf) reserved */ 12554878Storek /* group 6 (c0-df) vendor unique */ 12654878Storek /* group 7 (e0-ff) vendor unique */ 12754878Storek 12854878Storek /* 12954878Storek * SCSI control byte. 13054878Storek * Bits 7 and 6 are vendor unique; bits 5, 4, 3, and 2 are reserved. 13154878Storek * Bit 1 may be 1 only if bit 0 is 1; if so, it tells the target to 13254878Storek * send a LINKED COMMAND COMPLETE (WITH FLAG) message. If not, but 13354878Storek * bit 0 is set, this tells the target to send a LINKED COMMAND COMPLETE 13454878Storek * message. 13554878Storek */ 13654878Storek #define CTRL_VU_MASK 0xc0 /* vendor unique */ 13754878Storek #define CTRL_RSVD 0x3c /* reserved, must be zero */ 13854878Storek #define CTRL_LCCF 0x02 /* send LCCF if sending LCC */ 13954878Storek #define CTRL_LINK 0x01 /* linked command */ 14054878Storek 14154878Storek /* 14254878Storek * Generic sense: regular and extended. 14354878Storek * A sense operation returned an extended sense iff the error class 14454878Storek * is 7. The format is vendor unique unless the error code is 0. 14554878Storek * The regular and extended formats are completely different; we 14654878Storek * define macros to obtain values from them. 14754878Storek */ 14854878Storek struct scsi_sense { 14954878Storek u_char sn_vcc; /* valid bit, error class, & error code */ 15054878Storek u_char sn_var[7]; /* bytes 1-3, or 1-7; variant formats */ 15154878Storek u_char sn_addl[32-8]; /* additional sense data, if extended */ 15254878Storek }; 15354878Storek 15454878Storek #define SENSE_ECLASS(sn) (((sn)->sn_vcc >> 4) & 7) 15554878Storek #define SENSE_ECODE(sn) ((sn)->sn_vcc & 0xf) 15654878Storek #define SENSE_ISXSENSE(sn) (SENSE_ECLASS(sn) == 7) 15754878Storek 15854878Storek /* for non-extended sense (`r'egular or `r'estricted sense) */ 15954878Storek #define RSENSE_LVALID(sn) ((sn)->sn_vcc & 0x80) 16054878Storek #define RSENSE_VU(sn) ((sn)->sn_var[0] >> 5) 16154878Storek #define RSENSE_LBA(sn) \ 16254878Storek ((((sn)->sn_var[0] & 0x1f) << 16) | ((sn)->sn_var[1] << 8) | (sn)->sn_var[2]) 16354878Storek 16454878Storek /* for extended sense */ 16554878Storek #define XSENSE_ISSTD(sn) (SENSE_ECODE(sn) == 0) 16654878Storek /* if not standard, cannot interpret it at all */ 16754878Storek #define XSENSE_IVALID(sn) ((sn)->sn_vcc & 0x80) 16854878Storek #define XSENSE_SEG(sn) ((sn)->sn_var[0]) 16954878Storek #define XSENSE_FM(sn) ((sn)->sn_var[1] & 0x80) /* filemark */ 17054878Storek #define XSENSE_EOM(sn) ((sn)->sn_var[1] & 0x40) /* end of media */ 17154878Storek #define XSENSE_ILI(sn) ((sn)->sn_var[1] & 0x20) /* incor length ind */ 17254878Storek #define XSENSE_KEY(sn) ((sn)->sn_var[1] & 0x0f) /* sense key */ 17354878Storek #define XSENSE_INFO(sn) \ 17454878Storek (((sn)->sn_var[2] << 24) | ((sn)->sn_var[3] << 16) | \ 17554878Storek ((sn)->sn_var[4] << 8) | (sn)->sn_var[5]) 17654878Storek #define XSENSE_ADDL(sn) ((sn)->sn_var[6]) /* add'l sense len */ 17754878Storek 17854878Storek /* 17954878Storek * SCSI INQUIRY data: general, and ANSI versions 1 and 2 18054878Storek * (including common command set). 18154878Storek */ 18254878Storek struct scsi_inquiry { 18354878Storek u_char si_type; /* peripheral device type (below) */ 18454878Storek u_char si_qual; /* qualifier (see below) */ 18554878Storek u_char si_version; /* version (see below) */ 18654878Storek u_char si_v2info; /* scsi version 2 stuff (see below) */ 18754878Storek u_char si_len; /* additional length */ 18854878Storek u_char si_more[252-5]; /* actually si_len bytes */ 18954878Storek }; 19054878Storek struct scsi_inq_ansi { 19154878Storek u_char si_type; /* peripheral qualifier and device type */ 19254878Storek u_char si_qual; /* RMB and device type qualifier */ 19354878Storek u_char si_version; /* ISO, ECMA and ANSI-approved versions */ 19454878Storek u_char si_v2info; /* ? */ 19554878Storek u_char si_len; /* addition length */ 19654878Storek char si_xxx1[2]; /* reserved */ 19754878Storek char si_flags; /* (see below) */ 19854878Storek char si_vendor[8]; /* vendor (blank padded) */ 19954878Storek char si_product[16]; /* product (blank padded) */ 20054878Storek char si_rev[4]; /* revision (blank padded) */ 20154878Storek 20254878Storek /* scsi version 2 stuff follows */ 20354878Storek char si_vend1[20]; /* vendor specific */ 20454878Storek char si_xxx2[40]; /* reserved */ 20554878Storek char si_vend2[252-96]; /* vendor specific parameters */ 20654878Storek }; 20754878Storek 20854878Storek /* peripheral device types */ 20954878Storek #define TYPE_QUAL_MASK 0xe0 /* peripheral qualifer mask */ 21054878Storek #define TYPE_TYPE_MASK 0x1f /* peripheral device type mask */ 21154878Storek #define TYPE_QUAL_NORM 0x00 /* device is normal */ 21254878Storek #define TYPE_QUAL_NOTCONN 0x20 /* not connected */ 21354878Storek #define TYPE_QUAL_XXX 0x40 /* reserved */ 21454878Storek #define TYPE_QUAL_NOLUN 0x60 /* logical unit not supported */ 21554878Storek #define TYPE_QUAL_VT4 0x80 /* vendor specific type 4 */ 21654878Storek #define TYPE_QUAL_VT5 0xa0 /* vendor specific type 5 */ 21754878Storek #define TYPE_QUAL_VT6 0xc0 /* vendor specific type 6 */ 21854878Storek #define TYPE_QUAL_VT7 0xe0 /* vendor specific type 7 */ 21954878Storek 22054878Storek #define TYPE_DAD 0x00 /* direct access device (disk) */ 22154878Storek #define TYPE_SAD 0x01 /* sequential access device (tape) */ 22254878Storek #define TYPE_PRINTER 0x02 /* printer */ 22354878Storek #define TYPE_PROCESSOR 0x03 /* processor */ 22454878Storek #define TYPE_WORM 0x04 /* WORM disk */ 22554878Storek #define TYPE_ROM 0x05 /* CD-ROM disk */ 22654878Storek #define TYPE_SCANNER 0x06 /* scanner */ 22754878Storek #define TYPE_MO 0x07 /* magneto-optical */ 22854878Storek #define TYPE_JUKEBOX 0x08 /* medium changer */ 22954878Storek #define TYPE_LAN 0x09 /* communications device */ 23054878Storek #define TYPE_NP 0x1f /* unknown or no device */ 23154878Storek 23254878Storek /* qualifiers */ 23354878Storek #define QUAL_RMB 0x80 /* removable medium bit */ 23454878Storek #define QUAL_MASK 0x7f /* mask for `user' bits */ 23554878Storek 23654878Storek /* version (shifts and masks for subfields) */ 23754878Storek #define VER_ISO_SHIFT 6 /* ISO version: top 2 bits */ 23854878Storek #define VER_ISO_MASK 3 23954878Storek #define VER_ECMA_SHIFT 3 /* ECMA version: middle 3 bits */ 24054878Storek #define VER_ECMA_MASK 7 24154878Storek #define VER_ANSI_SHIFT 0 /* ANSI version: bottom 3 bits */ 24254878Storek #define VER_ANSI_MASK 7 24354878Storek 24454878Storek /* v2 info */ 24554878Storek #define V2INFO_AENC 0x80 /* device can accept AEN data */ 24654878Storek #define V2INFO_TRMIOP 0x40 /* supports TERMINATE I/O PROC msg */ 24754878Storek #define V2INFO_XXX 0x30 /* reserved */ 24854878Storek #define V2INFO_RDF_MASK 0x0f /* response data format mask */ 24954878Storek #define V2INFO_RDF_SCSI1 0x00 /* SCSI-1 standard INQUIRY data */ 25054878Storek #define V2INFO_RDF_CCS 0x01 /* common command set INQUIRY data */ 25154878Storek #define V2INFO_RDF_SCSI2 0x02 /* SCSI-2 standard INQUIRY data */ 25254878Storek 25354878Storek /* flags */ 25454878Storek #define V2FLAG_RELADR 0x80 /* supports relative addressing */ 25554878Storek #define V2FLAG_WBUS32 0x40 /* supports 32 bit data xfer */ 25654878Storek #define V2FLAG_WBUS16 0x20 /* supports 32 bit data xfer */ 25754878Storek #define V2FLAG_SYNC 0x10 /* supports synchronous data xfer */ 25854878Storek #define V2FLAG_LINKED 0x08 /* supports linked commands */ 25954878Storek #define V2FLAG_XXX 0x04 /* reserved */ 26054878Storek #define V2FLAG_CMDQUE 0x02 /* supports tagged command queueing */ 26154878Storek #define V2FLAG_SOFTRESET 0x01 /* RST causes soft reset */ 26254878Storek 26354878Storek /* 26454878Storek * SCSI message codes bytes. The `command complete' code is required; 26554878Storek * all others are optional. `Identify' is a flag bit, not a code (thus 26654878Storek * codes are actually at most 7 bits). 26754878Storek */ 26854878Storek #define MSG_IDENTIFY 0x80 /* flag => this is an identify msg */ 26954878Storek #define MSG_IDENTIFY_DR 0x40 /* IDENTIFY: flag => discon/resel ok */ 27054878Storek #define MSG_IDENTIFY_RSVD 0x38 /* IDENTIFY: these bits are reserved */ 27154878Storek #define MSG_IDENTIFY_LUN 0x07 /* IDENTIFY: these bits give LUN */ 27254878Storek 27354878Storek #define MSG_CMD_COMPLETE 0x00 /* command complete */ 27454878Storek #define MSG_EXT_MESSAGE 0x01 /* extended message */ 27554878Storek #define MSG_SAVE_DATA_PTR 0x02 /* save data pointer */ 27654878Storek #define MSG_RESTORE_PTR 0x03 /* restore pointers */ 27754878Storek #define MSG_DISCONNECT 0x04 /* disconnect */ 27854878Storek #define MSG_INIT_DETECT_ERROR 0x05 /* initiator detected error */ 27954878Storek #define MSG_ABORT 0x06 /* abort */ 28054878Storek #define MSG_REJECT 0x07 /* message reject */ 28154878Storek #define MSG_NOOP 0x08 /* no operation */ 28254878Storek #define MSG_PARITY_ERROR 0x09 /* message parity error */ 28354878Storek #define MSG_LCC 0x0a /* linked command complete */ 28454878Storek #define MSG_LCCF 0x0b /* linked command complete (w/ flag) */ 28554878Storek #define MSG_BUS_DEVICE_RESET 0x0c /* bus device reset */ 28654878Storek #define MSG_ABORT_TAG 0x0d /* abort tagged msg */ 28754878Storek #define MSG_CLEAR_QUEUE 0x0e /* clear queue */ 28854878Storek #define MSG_INITIATE_RECOVERY 0x0f /* initiate recovery */ 28954878Storek #define MSG_RELEASE_RECOVERY 0x10 /* release recovery */ 29054878Storek #define MSG_TERMINATE_PROCESS 0x11 /* ? */ 29154878Storek #define MSG_SIMPLE_Q_TAG 0x20 /* ? */ 29254878Storek #define MSG_HEAD_Q_TAG 0x21 /* ? */ 29354878Storek #define MSG_ORDERED_Q_TAG 0x22 /* ? */ 29454878Storek #define MSG_IGNORE_WIDE_RESID 0x23 /* ? */ 29554878Storek 29654878Storek /* 29754878Storek * SCSI extended message format. 29854878Storek */ 29954878Storek struct scsi_xmsg { 30054878Storek u_char xm_xmsg, /* value 1, i.e., SMSG_EXT_MESSAGE */ 30154878Storek xm_len, /* length of this extended message */ 30254878Storek xm_code, /* actual code */ 30354878Storek xm_args[253]; /* actualy xm_len-1 bytes */ 30454878Storek }; 30554878Storek 30654878Storek /* 30754878Storek * SCSI extended message codes. 30854878Storek */ 30954878Storek #define XMSG_MDP 0x00 /* modify data pointer */ 31054878Storek #define XMSG_SDTR 0x01 /* synchronous data transfer request */ 31154878Storek #define XMSG_XID 0x02 /* extended identify */ 31254878Storek 31354878Storek /* 31454878Storek * SCSI status byte values. Bits 6, 5, and 0 are Vendor Unique. 31554878Storek */ 31654878Storek #define STS_EXT 0x80 /* flag => extended status valid */ 31754878Storek #define STS_MASK 0x1e /* mask for non-VU bits */ 31854878Storek #define STS_VU 0x61 /* mask for Vendor Unique bits */ 31954878Storek 32054878Storek #define STS_GOOD 0x00 /* success, command done */ 32154878Storek #define STS_CHECKCOND 0x02 /* check condition (do a REQ SENSE) */ 32254878Storek #define STS_CONDMET 0x04 /* condition met (search succeeded) */ 32354878Storek /* 0x06 reserved */ 32454878Storek #define STS_BUSY 0x08 /* busy */ 32554878Storek /* 0x0a reserved */ 32654878Storek /* 0x0c reserved */ 32754878Storek /* 0x0e reserved */ 32854878Storek #define STS_INTERMED 0x10 /* succeeded, doing linked cmd */ 32954878Storek /* 0x12 reserved */ 33054878Storek #define STS_INTERMED_CONDMET 0x14 /* condition met, doing linked cmd */ 33154878Storek /* 0x16 reserved */ 33254878Storek #define STS_RESERV_CONFLICT 0x18 /* reservation conflict */ 33354878Storek /* 0x1a reserved */ 33454878Storek /* 0x1c reserved */ 33554878Storek /* 0x1e reserved */ 336