Home | History | Annotate | Line # | Download | only in mscp
      1  1.9    abs /*	$NetBSD: mscp.h,v 1.9 2012/07/10 22:30:23 abs Exp $	*/
      2  1.1  ragge 
      3  1.1  ragge /*
      4  1.1  ragge  * Copyright (c) 1988 Regents of the University of California.
      5  1.1  ragge  * All rights reserved.
      6  1.1  ragge  *
      7  1.1  ragge  * This code is derived from software contributed to Berkeley by
      8  1.1  ragge  * Chris Torek.
      9  1.1  ragge  *
     10  1.1  ragge  * Redistribution and use in source and binary forms, with or without
     11  1.1  ragge  * modification, are permitted provided that the following conditions
     12  1.1  ragge  * are met:
     13  1.1  ragge  * 1. Redistributions of source code must retain the above copyright
     14  1.1  ragge  *    notice, this list of conditions and the following disclaimer.
     15  1.1  ragge  * 2. Redistributions in binary form must reproduce the above copyright
     16  1.1  ragge  *    notice, this list of conditions and the following disclaimer in the
     17  1.1  ragge  *    documentation and/or other materials provided with the distribution.
     18  1.7    agc  * 3. Neither the name of the University nor the names of its contributors
     19  1.1  ragge  *    may be used to endorse or promote products derived from this software
     20  1.1  ragge  *    without specific prior written permission.
     21  1.1  ragge  *
     22  1.1  ragge  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     23  1.1  ragge  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24  1.1  ragge  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25  1.1  ragge  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     26  1.1  ragge  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27  1.1  ragge  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     28  1.1  ragge  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29  1.1  ragge  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30  1.1  ragge  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31  1.1  ragge  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32  1.1  ragge  * SUCH DAMAGE.
     33  1.1  ragge  *
     34  1.1  ragge  *	@(#)mscp.h	7.5 (Berkeley) 6/28/90
     35  1.1  ragge  */
     36  1.1  ragge 
     37  1.1  ragge /*
     38  1.1  ragge  * Definitions for the Mass Storage Control Protocol
     39  1.1  ragge  * I WISH I KNEW WHAT MORE OF THESE WERE.  IT SURE WOULD BE NICE
     40  1.1  ragge  * IF DEC SOLD DOCUMENTATION FOR THEIR OWN CONTROLLERS.
     41  1.1  ragge  */
     42  1.1  ragge 
     43  1.9    abs #define MSCP_MAX_UNIT	4095
     44  1.9    abs 
     45  1.1  ragge /*
     46  1.1  ragge  * Control message opcodes
     47  1.1  ragge  */
     48  1.4  ragge #define M_OP_ABORT	0x01	/* Abort command */
     49  1.4  ragge #define M_OP_GETCMDST	0x02	/* Get command status command */
     50  1.4  ragge #define M_OP_GETUNITST	0x03	/* Get unit status command */
     51  1.4  ragge #define M_OP_SETCTLRC	0x04	/* Set controller characteristics command */
     52  1.4  ragge #define M_OP_SEREX	0x07	/* Serious exception end message */
     53  1.4  ragge #define M_OP_AVAILABLE	0x08	/* Available command */
     54  1.4  ragge #define M_OP_ONLINE	0x09	/* Online command */
     55  1.4  ragge #define M_OP_SETUNITC	0x0a	/* Set unit characteristics command */
     56  1.4  ragge #define M_OP_DTACCPATH	0x0b	/* Determine access paths command */
     57  1.4  ragge #define M_OP_ACCESS	0x10	/* Access command */
     58  1.4  ragge #define M_OP_COMPCD	0x11	/* Compare controller data command */
     59  1.4  ragge #define M_OP_ERASE	0x12	/* Erase command */
     60  1.4  ragge #define M_OP_FLUSH	0x13	/* Flush command */
     61  1.4  ragge #define M_OP_REPLACE	0x14	/* Replace command */
     62  1.4  ragge #define M_OP_COMPHD	0x20	/* Compare host data command */
     63  1.4  ragge #define M_OP_READ	0x21	/* Read command */
     64  1.4  ragge #define M_OP_WRITE	0x22	/* Write command */
     65  1.4  ragge #define M_OP_WRITM	0x24	/* Write mark command */
     66  1.4  ragge #define M_OP_POS	0x25	/* Positioning command */
     67  1.4  ragge #define M_OP_AVAILATTN	0x40	/* Available attention message */
     68  1.4  ragge #define M_OP_DUPUNIT	0x41	/* Duplicate unit number attention message */
     69  1.4  ragge #define M_OP_ACCPATH	0x42	/* Access path attention message */
     70  1.4  ragge #define M_OP_END	0x80	/* End message flag */
     71  1.1  ragge 
     72  1.1  ragge 
     73  1.1  ragge /*
     74  1.1  ragge  * Generic command modifiers
     75  1.1  ragge  */
     76  1.4  ragge #define M_MD_EXPRS	0x8000	/* Express request */
     77  1.4  ragge #define M_MD_COMP	0x4000	/* Compare */
     78  1.4  ragge #define M_MD_CLSEX	0x2000	/* Clear serious exception */
     79  1.4  ragge #define M_MD_ERROR	0x1000	/* Force error */
     80  1.4  ragge #define M_MD_SCCHH	0x0800	/* Suppress caching (high speed) */
     81  1.4  ragge #define M_MD_SCCHL	0x0400	/* Suppress caching (low speed) */
     82  1.4  ragge #define M_MD_SECOR	0x0200	/* Suppress error correction */
     83  1.4  ragge #define M_MD_SEREC	0x0100	/* Suppress error recovery */
     84  1.4  ragge #define M_MD_SSHDW	0x0080	/* Suppress shadowing */
     85  1.4  ragge #define M_MD_WBKNV	0x0040	/* Write back (non-volatile) */
     86  1.4  ragge #define M_MD_WBKVL	0x0020	/* Write back (volatile) */
     87  1.4  ragge #define M_MD_WRSEQ	0x0010	/* Write shadow set one unit at a time */
     88  1.1  ragge 
     89  1.1  ragge /*
     90  1.2  ragge  * tape command modifiers
     91  1.2  ragge  */
     92  1.4  ragge #define M_MD_IMMEDIATE	0x0040	/* Immediate completion */
     93  1.4  ragge #define M_MD_UNLOAD	0x0010	/* Unload tape */
     94  1.4  ragge #define M_MD_REVERSE	0x0008	/* Reverse action */
     95  1.4  ragge #define M_MD_OBJCOUNT	0x0004	/* Object count */
     96  1.4  ragge #define M_MD_REWIND	0x0002	/* Rewind */
     97  1.2  ragge 
     98  1.2  ragge /*
     99  1.1  ragge  * AVAILABLE command modifiers
    100  1.1  ragge  */
    101  1.4  ragge #define M_AVM_ALLCD	0x0002	/* All class drivers */
    102  1.4  ragge #define M_AVM_SPINDOWN	0x0001	/* Spin down */
    103  1.1  ragge 
    104  1.1  ragge /*
    105  1.1  ragge  * FLUSH command modifiers
    106  1.1  ragge  */
    107  1.4  ragge #define M_FLM_FLUSHENU	0x0001	/* Flush entire unit */
    108  1.4  ragge #define M_FLM_VOLATILE	0x0002	/* Volatile only */
    109  1.1  ragge 
    110  1.1  ragge /*
    111  1.1  ragge  * GET UNIT STATUS command modifiers
    112  1.1  ragge  */
    113  1.4  ragge #define M_GUM_NEXTUNIT	0x0001	/* Next unit */
    114  1.1  ragge 
    115  1.1  ragge /*
    116  1.1  ragge  * ONLINE command modifiers
    117  1.1  ragge  */
    118  1.4  ragge #define M_OLM_RIP	0x0001	/* Allow self destruction */
    119  1.4  ragge #define M_OLM_IGNMF	0x0002	/* Ignore media format error */
    120  1.1  ragge 
    121  1.1  ragge /*
    122  1.1  ragge  * ONLINE and SET UNIT CHARACTERISTICS command modifiers
    123  1.1  ragge  */
    124  1.4  ragge #define M_OSM_ALTERHI	0x0020	/* Alter host identifier */
    125  1.4  ragge #define M_OSM_SHADOWSP	0x0010	/* Shadow unit specified */
    126  1.4  ragge #define M_OSM_CLEARWBL	0x0008	/* Clear write-back data lost */
    127  1.4  ragge #define M_OSM_SETWRPROT 0x0004	/* Set write protect */
    128  1.1  ragge 
    129  1.1  ragge /*
    130  1.1  ragge  * REPLACE command modifiers
    131  1.1  ragge  */
    132  1.4  ragge #define M_RPM_PRIMARY	0x0001	/* Primary replacement block */
    133  1.1  ragge 
    134  1.1  ragge /*
    135  1.1  ragge  * End message flags
    136  1.1  ragge  */
    137  1.4  ragge #define M_EF_BBLKR	0x80	/* Bad block reported */
    138  1.4  ragge #define M_EF_BBLKU	0x40	/* Bad block unreported */
    139  1.4  ragge #define M_EF_ERLOG	0x20	/* Error log generated */
    140  1.4  ragge #define M_EF_SEREX	0x10	/* Serious exception */
    141  1.4  ragge #define M_EF_EOT	0x08	/* at end-of-tape */
    142  1.4  ragge #define M_EF_POSLOST	0x04	/* position lost */
    143  1.1  ragge 
    144  1.1  ragge /*
    145  1.1  ragge  * Controller flags
    146  1.1  ragge  */
    147  1.4  ragge #define M_CF_ATTN	0x80	/* Enable attention messages */
    148  1.4  ragge #define M_CF_MISC	0x40	/* Enable miscellaneous error log messages */
    149  1.4  ragge #define M_CF_OTHER	0x20	/* Enable other host's error log messages */
    150  1.4  ragge #define M_CF_THIS	0x10	/* Enable this host's error log messages */
    151  1.4  ragge #define M_CF_MLTHS	0x04	/* Multi-host */
    152  1.4  ragge #define M_CF_SHADW	0x02	/* Shadowing */
    153  1.4  ragge #define M_CF_576	0x01	/* 576 byte sectors */
    154  1.1  ragge 
    155  1.1  ragge /*
    156  1.1  ragge  * Unit flags
    157  1.1  ragge  */
    158  1.4  ragge #define M_UF_REPLC	0x8000	/* Controller initiated bad block replacement */
    159  1.4  ragge #define M_UF_INACT	0x4000	/* Inactive shadow set unit */
    160  1.4  ragge #define M_UF_WRTPH	0x2000	/* Write protect (hardware) */
    161  1.4  ragge #define M_UF_WRTPS	0x1000	/* Write protect (software or volume) */
    162  1.4  ragge #define M_UF_SCCHH	0x8000	/* Suppress caching (high speed) */
    163  1.4  ragge #define M_UF_SCCHL	0x4000	/* Suppress caching (low speed) */
    164  1.4  ragge #define M_UF_RMVBL	0x0080	/* Removable media */
    165  1.4  ragge #define M_UF_WBKNV	0x0040	/* Write back (non-volatile) */
    166  1.4  ragge #define M_UF_576	0x0004	/* 576 byte sectors */
    167  1.4  ragge #define M_UF_CMPWR	0x0002	/* Compare writes */
    168  1.4  ragge #define M_UF_CMPRD	0x0001	/* Compare reads */
    169  1.1  ragge 
    170  1.1  ragge /*
    171  1.1  ragge  * Error Log message format codes
    172  1.1  ragge  */
    173  1.4  ragge #define M_FM_CTLRERR	0x00	/* Controller error */
    174  1.4  ragge #define M_FM_BUSADDR	0x01	/* Host memory access error */
    175  1.4  ragge #define M_FM_DISKTRN	0x02	/* Disk transfer error */
    176  1.4  ragge #define M_FM_SDI	0x03	/* SDI error */
    177  1.4  ragge #define M_FM_SMLDSK	0x04	/* Small disk error */
    178  1.4  ragge #define M_FM_TAPETRN	0x05	/* Tape transfer error */
    179  1.4  ragge #define M_FM_STIERR	0x06	/* STI communication or command failure */
    180  1.4  ragge #define M_FM_STIDEL	0x07	/* STI drive error log */
    181  1.4  ragge #define M_FM_STIFEL	0x08	/* STI formatter error log */
    182  1.1  ragge 
    183  1.1  ragge /*
    184  1.1  ragge  * Error Log message flags
    185  1.1  ragge  */
    186  1.4  ragge #define M_LF_SUCC	0x80	/* Operation successful */
    187  1.4  ragge #define M_LF_CONT	0x40	/* Operation continuing */
    188  1.4  ragge #define M_LF_SQNRS	0x01	/* Sequence number reset */
    189  1.1  ragge 
    190  1.1  ragge /*
    191  1.1  ragge  * Status codes
    192  1.1  ragge  */
    193  1.4  ragge #define M_ST_MASK	0x1f	/* Status code mask */
    194  1.4  ragge #define M_ST_SUCCESS	0x00	/* Success */
    195  1.4  ragge #define M_ST_INVALCMD	0x01	/* Invalid command */
    196  1.4  ragge #define M_ST_ABORTED	0x02	/* Command aborted */
    197  1.4  ragge #define M_ST_OFFLINE	0x03	/* Unit offline */
    198  1.4  ragge #define M_ST_AVAILABLE	0x04	/* Unit available */
    199  1.4  ragge #define M_ST_MFMTERR	0x05	/* Media format error */
    200  1.4  ragge #define M_ST_WRPROT	0x06	/* Write protected */
    201  1.4  ragge #define M_ST_COMPERR	0x07	/* Compare error */
    202  1.4  ragge #define M_ST_DATAERR	0x08	/* Data error */
    203  1.4  ragge #define M_ST_HOSTBUFERR 0x09	/* Host buffer access error */
    204  1.4  ragge #define M_ST_CTLRERR	0x0a	/* Controller error */
    205  1.4  ragge #define M_ST_DRIVEERR	0x0b	/* Drive error */
    206  1.4  ragge #define M_ST_FORMATTERR 0x0c	/* Formatter error */
    207  1.4  ragge #define M_ST_BOT	0x0d	/* Beginning-of-tape */
    208  1.4  ragge #define M_ST_TAPEMARK	0x0e	/* Tape mark encountered */
    209  1.4  ragge #define M_ST_RDTRUNC	0x10	/* Record data truncated */
    210  1.4  ragge #define M_ST_DIAG	0x1f	/* Message from an internal diagnostic */
    211  1.1  ragge 
    212  1.1  ragge /*
    213  1.1  ragge  * Subcodes of M_ST_OFFLINE
    214  1.1  ragge  */
    215  1.4  ragge #define M_OFFLINE_UNKNOWN	(0 << 5) /* unknown or on other ctlr */
    216  1.4  ragge #define M_OFFLINE_UNMOUNTED	(1 << 5) /* unmounted or RUN/STOP at STOP */
    217  1.4  ragge #define M_OFFLINE_INOPERATIVE	(2 << 5) /* inoperative? */
    218  1.4  ragge #define M_OFFLINE_DUPLICATE	(4 << 5) /* duplicate unit number */
    219  1.4  ragge #define M_OFFLINE_INDIAGNOSTIC	(8 << 5) /* disabled by FS or diagnostic */
    220  1.1  ragge 
    221  1.1  ragge /*
    222  1.1  ragge  * An MSCP packet begins with a header giving the length of
    223  1.1  ragge  * the entire packet (including the header itself)(?), two bytes
    224  1.1  ragge  * of device specific data, and the a whole bunch of variants
    225  1.1  ragge  * depending on message type.
    226  1.1  ragge  *
    227  1.1  ragge  * N.B.:  In most cases we distinguish between a `command' and
    228  1.1  ragge  * an `end' variant as well.  The command variant is that which
    229  1.1  ragge  * is given to the controller; the `end' variant is its response.
    230  1.1  ragge  */
    231  1.1  ragge 
    232  1.1  ragge /*
    233  1.1  ragge  * Generic sequential message variant (command and response).
    234  1.1  ragge  */
    235  1.1  ragge struct mscpv_seq {
    236  1.1  ragge 	long	seq_bytecount;		/* byte count */
    237  1.4  ragge #define seq_rbn		seq_bytecount	/* aka RBN (replace) */
    238  1.4  ragge #define seq_outref	seq_bytecount	/* aka outref (abort/get cmd status) */
    239  1.1  ragge 	long	seq_buffer;		/* buffer descriptor */
    240  1.1  ragge 	long	seq_mapbase;		/* page map (first PTE) phys address */
    241  1.4  ragge 	long	seq_xxx1;	/* ? */ /* unused */
    242  1.1  ragge 	long	seq_lbn;		/* logical block number */
    243  1.4  ragge 	long	seq_xxx2;	/* ? */ /* unused */
    244  1.1  ragge 	long	*seq_addr;		/* pointer to cmd descriptor */
    245  1.1  ragge 	long	seq_software[4];	/* reserved to software; unused */
    246  1.1  ragge };
    247  1.1  ragge 
    248  1.1  ragge /*
    249  1.1  ragge  * Set Controller Characteristics command variant
    250  1.1  ragge  */
    251  1.1  ragge struct mscpv_sccc {
    252  1.4  ragge 	u_short sccc_version;		/* MSCP version number */
    253  1.4  ragge 	u_short sccc_ctlrflags;		/* controller flags */
    254  1.4  ragge 	u_short sccc_hosttimo;		/* host timeout */
    255  1.4  ragge 	u_short sccc_usefrac;		/* use fraction */
    256  1.1  ragge 	long	sccc_time;		/* time and date */
    257  1.2  ragge 	long	sccc_time1;		/* it's a quad field */
    258  1.1  ragge 	long	sccc_errlgfl;	/* ? */
    259  1.1  ragge 	short	sccc_xxx2;	/* ? */
    260  1.1  ragge 	short	sccc_copyspd;	/* ? */
    261  1.1  ragge };
    262  1.1  ragge 
    263  1.1  ragge /*
    264  1.1  ragge  * Set Controller Characteristics end variant
    265  1.1  ragge  */
    266  1.1  ragge struct mscpv_scce {
    267  1.4  ragge 	u_short scce_version;		/* MSCP version number */
    268  1.4  ragge 	u_short scce_ctlrflags;		/* controller flags */
    269  1.4  ragge 	u_short scce_ctlrtimo;		/* controller timeout */
    270  1.4  ragge 	u_short scce_ctlrcmdl;		/* ??? */
    271  1.1  ragge 	quad_t	scce_ctlrid;		/* controller ID */
    272  1.1  ragge 	long	scce_xxx[3];	/* ? */
    273  1.1  ragge 	long	scce_volser;		/* volume serial number */
    274  1.1  ragge };
    275  1.1  ragge 
    276  1.1  ragge /*
    277  1.1  ragge  * On Line command variant
    278  1.1  ragge  */
    279  1.1  ragge struct mscpv_onlc {
    280  1.1  ragge 	long	onlc_xxx1[4];	/* ? */
    281  1.1  ragge 	long	onlc_errlgfl;		/* error log flag? */
    282  1.1  ragge 	short	onlc_xxx2;	/* ? */
    283  1.1  ragge 	short	onlc_copyspd;		/* copy speed? */
    284  1.1  ragge };
    285  1.1  ragge 
    286  1.1  ragge /*
    287  1.1  ragge  * On Line end variant
    288  1.1  ragge  */
    289  1.1  ragge struct mscpv_onle {
    290  1.1  ragge 	long	onle_xxx1[3];	/* ? */
    291  1.4  ragge /*???*/ short	onle_xxx2;	/* ? */
    292  1.1  ragge 	u_char	onle_drivetype;		/* drive type index (same in guse) */
    293  1.1  ragge 	char	onle_xxx3;	/* ? */
    294  1.1  ragge 	long	onle_mediaid;		/* media type id (same in guse) */
    295  1.1  ragge 	long	onle_xxx4;	/* ? */
    296  1.1  ragge 	long	onle_unitsize;		/* unit size in sectors */
    297  1.1  ragge 	long	onle_volser;		/* volume serial number */
    298  1.1  ragge };
    299  1.1  ragge 
    300  1.1  ragge /*
    301  1.1  ragge  * Get Unit Status end variant (and Avail Attn?)
    302  1.1  ragge  */
    303  1.1  ragge struct mscpv_guse {
    304  1.4  ragge 	u_short guse_multunit;		/* multi-unit code */
    305  1.4  ragge 	u_short guse_unitflags;		/* unit flags */
    306  1.1  ragge 	long	guse_hostid;		/* host id */
    307  1.1  ragge 	long	guse_unitid0;	/*???*/
    308  1.1  ragge 	short	guse_unitid1;	/*???*/
    309  1.1  ragge 	u_char	guse_drivetype;		/* drive type index */
    310  1.1  ragge 	u_char	guse_unitid2;	/*???*/
    311  1.1  ragge 	long	guse_mediaid;		/* media type id (encoded) */
    312  1.1  ragge 	short	guse_shadowunit;	/* shadow unit */
    313  1.1  ragge 	short	guse_shadowstat;	/* shadow status */
    314  1.4  ragge 	u_short guse_nspt;		/* sectors per track */
    315  1.4  ragge 	u_short guse_group;		/* track group size */
    316  1.4  ragge 	u_short guse_ngpc;		/* groups per cylinder */
    317  1.4  ragge 	u_short guse_xxx;		/* reserved */
    318  1.4  ragge 	u_short guse_rctsize;		/* RCT size (sectors) */
    319  1.1  ragge 	u_char	guse_nrpt;		/* RBNs per track */
    320  1.1  ragge 	u_char	guse_nrct;		/* number of RCTs */
    321  1.1  ragge };
    322  1.1  ragge 
    323  1.1  ragge /*
    324  1.1  ragge  * Macros to break up and build media IDs.  An ID encodes the port
    325  1.1  ragge  * type in the top 10 bits, and the drive type in the remaining 22.
    326  1.1  ragge  * The 10 bits, and 15 of the 22, are in groups of 5, with the value
    327  1.1  ragge  * 0 representing space and values 1..26 representing A..Z.  The low
    328  1.4  ragge  * 7 bits represent a number in 0..127.	 Hence an RA81 on a UDA50
    329  1.4  ragge  * is <D><U><R><A>< >81, or 0x25641051.	 This encoding scheme is known
    330  1.1  ragge  * in part in uda.c.
    331  1.1  ragge  *
    332  1.1  ragge  * The casts below are just to make pcc generate better code.
    333  1.1  ragge  */
    334  1.4  ragge #define MSCP_MEDIA_PORT(id)	(((long)(id) >> 22) & 0x3ff)	/* port */
    335  1.4  ragge #define MSCP_MEDIA_DRIVE(id)	((long)(id) & 0x003fffff)	/* drive */
    336  1.5  ragge #define MSCP_MID_ECH(n, id)	(((int)(id) >> ((n) * 5 + 7)) & 0x1f)
    337  1.4  ragge #define MSCP_MID_CHAR(n, id) \
    338  1.1  ragge 	(MSCP_MID_ECH(n, id) ? MSCP_MID_ECH(n, id) + '@' : ' ')
    339  1.4  ragge #define MSCP_MID_NUM(id)	((id) & 0x7f)
    340  1.1  ragge /* for, e.g., RA81 */
    341  1.4  ragge #define MSCP_MKDRIVE2(a, b, n) \
    342  1.1  ragge 	(((a) - '@') << 17 | ((b) - '@') << 12 | (n))
    343  1.1  ragge /* for, e.g., RRD50 */
    344  1.4  ragge #define MSCP_MKDRIVE3(a, b, c, n) \
    345  1.1  ragge 	(((a) - '@') << 17 | ((b) - '@') << 12 | ((c) - '@') << 7 | (n))
    346  1.1  ragge 
    347  1.1  ragge /*
    348  1.1  ragge  * Error datagram variant.
    349  1.1  ragge  */
    350  1.1  ragge struct mscpv_erd {
    351  1.1  ragge 	quad_t	erd_ctlrid;		/* controller ID */
    352  1.1  ragge 	u_char	erd_ctlrsoftware;	/* controller software version */
    353  1.1  ragge 	u_char	erd_ctlrhardware;	/* controller hardware version */
    354  1.4  ragge 	u_short erd_multiunit;		/* multi-unit code (?) */
    355  1.1  ragge 	union {
    356  1.1  ragge 		u_long	un_busaddr;	/* bus address, if mem access err */
    357  1.1  ragge 		quad_t	un_unitid;	/* unit id, otherwise */
    358  1.1  ragge 	} erd_un1;
    359  1.4  ragge #define erd_busaddr	erd_un1.un_busaddr
    360  1.4  ragge #define erd_unitid	erd_un1.un_unitid
    361  1.1  ragge 	u_char	erd_unitsoftware;	/* unit software version */
    362  1.1  ragge 	u_char	erd_unithardware;	/* unit hardware version */
    363  1.1  ragge 	union {
    364  1.1  ragge 		u_char	un_b[2];	/* level, retry (if disk xfer err) */
    365  1.4  ragge 		u_short un_s;		/* cylinder (if small disk error) */
    366  1.1  ragge 	} erd_un2;
    367  1.4  ragge #define erd_level	erd_un2.un_b[0]
    368  1.4  ragge #define erd_retry	erd_un2.un_b[1]
    369  1.4  ragge #define erd_sdecyl	erd_un2.un_s
    370  1.1  ragge 	long	erd_volser;		/* volume serial number */
    371  1.1  ragge 	u_long	erd_hdr;		/* `header' (block number) */
    372  1.1  ragge 	u_char	erd_sdistat[12];	/* SDI status information (?) */
    373  1.1  ragge };
    374  1.1  ragge 
    375  1.1  ragge /*
    376  1.1  ragge  * I am making brash assumptions about the first four bytes of all
    377  1.1  ragge  * MSCP packets.  These appear to be true for both UDA50s and TMSCP
    378  1.4  ragge  * devices (TU81, TA81, TK50).	DEC claim that these four bytes are
    379  1.1  ragge  * not part of MSCP itself, yet at least the length is necessary
    380  1.1  ragge  * for, e.g., error checking.
    381  1.1  ragge  */
    382  1.1  ragge struct mscp {
    383  1.4  ragge 	u_short mscp_msglen;		/* length in bytes */
    384  1.1  ragge 	u_char	mscp_msgtc;		/* type (high 4 bits) and credits */
    385  1.1  ragge 	u_char	mscp_vcid;		/* virtual circuit ID */
    386  1.1  ragge 	long	mscp_cmdref;		/* command reference number */
    387  1.4  ragge 	u_short mscp_unit;		/* unit number */
    388  1.4  ragge 	u_short mscp_seqnum;		/* sequence number */
    389  1.1  ragge 	u_char	mscp_opcode;		/* opcode */
    390  1.4  ragge #define mscp_format	mscp_opcode	/* aka format (datagrams) */
    391  1.1  ragge 	u_char	mscp_flags;		/* flags */
    392  1.4  ragge 	u_short mscp_modifier;		/* modifier (commands) */
    393  1.4  ragge #define mscp_status	mscp_modifier	/* aka status (ends) */
    394  1.4  ragge #define mscp_event	mscp_modifier	/* aka event (datagrams) */
    395  1.1  ragge 	union {
    396  1.1  ragge 		struct	mscpv_seq un_seq;	/* generic sequential msg */
    397  1.1  ragge 		struct	mscpv_sccc un_sccc;	/* SCC command */
    398  1.1  ragge 		struct	mscpv_scce un_scce;	/* SCC end */
    399  1.1  ragge 		struct	mscpv_onlc un_onlc;	/* on line command */
    400  1.1  ragge 		struct	mscpv_onle un_onle;	/* on line end */
    401  1.1  ragge 		struct	mscpv_guse un_guse;	/* get unit status */
    402  1.1  ragge 		struct	mscpv_erd un_erd;	/* error datagram */
    403  1.1  ragge 	} mscp_un;
    404  1.4  ragge /*???*/ long	mscp_xxx;		/* pad to 64 bytes */
    405  1.1  ragge };
    406  1.1  ragge 
    407  1.1  ragge /*
    408  1.1  ragge  * Define message length according to the DEC specifications by dropping
    409  1.1  ragge  * the four byte header.
    410  1.1  ragge  */
    411  1.4  ragge #define MSCP_MSGLEN	(sizeof (struct mscp) - 4)
    412  1.1  ragge 
    413  1.1  ragge /*
    414  1.1  ragge  * Shorthand
    415  1.1  ragge  */
    416  1.1  ragge 
    417  1.1  ragge /*
    418  1.1  ragge  * Generic packet
    419  1.1  ragge  */
    420  1.4  ragge #define mscp_seq	mscp_un.un_seq
    421  1.1  ragge 
    422  1.1  ragge /*
    423  1.1  ragge  * Set Controller Characteristics packet
    424  1.1  ragge  */
    425  1.4  ragge #define mscp_sccc	mscp_un.un_sccc
    426  1.1  ragge 
    427  1.1  ragge /*
    428  1.1  ragge  * Set Controller Characteristics end packet
    429  1.1  ragge  */
    430  1.4  ragge #define mscp_scce	mscp_un.un_scce
    431  1.1  ragge 
    432  1.1  ragge /*
    433  1.1  ragge  * Online / Set Unit Characteristics command packet
    434  1.1  ragge  */
    435  1.4  ragge #define mscp_onlc	mscp_un.un_onlc
    436  1.1  ragge 
    437  1.1  ragge /*
    438  1.1  ragge  * Online end packet
    439  1.1  ragge  */
    440  1.4  ragge #define mscp_onle	mscp_un.un_onle
    441  1.1  ragge 
    442  1.1  ragge /*
    443  1.1  ragge  * Get Unit Status end packet
    444  1.1  ragge  */
    445  1.4  ragge #define mscp_guse	mscp_un.un_guse
    446  1.1  ragge 
    447  1.1  ragge /*
    448  1.1  ragge  * MSCP Error Log packet
    449  1.1  ragge  */
    450  1.4  ragge #define mscp_erd	mscp_un.un_erd
    451  1.1  ragge 
    452  1.1  ragge /*
    453  1.1  ragge  * MSCP seq_addr field actually belongs to overall packet.
    454  1.1  ragge  */
    455  1.4  ragge #define mscp_addr	mscp_seq.seq_addr
    456  1.1  ragge 
    457  1.1  ragge /*
    458  1.1  ragge  * Macros to break up mscp_msgtc, and types.
    459  1.1  ragge  */
    460  1.4  ragge #define MSCP_MSGTYPE(m) ((m) & 0xf0)
    461  1.4  ragge #define MSCP_CREDITS(m) ((m) & 0x0f)
    462  1.1  ragge 
    463  1.4  ragge #define MSCPT_SEQ		0x00	/* sequential message */
    464  1.4  ragge #define MSCPT_DATAGRAM		0x10	/* error datagram */
    465  1.4  ragge #define MSCPT_CREDITS		0x20	/* credit notification */
    466  1.4  ragge #define MSCPT_MAINTENANCE	0xf0	/* who knows */
    467  1.1  ragge 
    468  1.1  ragge 
    469  1.1  ragge /*
    470  1.1  ragge  * Here begin more perhaps brash assumptions about MSCP devices...
    471  1.1  ragge  */
    472  1.1  ragge 
    473  1.1  ragge /*
    474  1.4  ragge  * MSCP controllers have `command rings' and `response rings'.	A
    475  1.1  ragge  * command ring is a pool of MSCP packets that the host uses to give
    476  1.1  ragge  * commands to the controller; a response ring is a pool of MSCP
    477  1.1  ragge  * packets that the controller uses to give back responses.  Entries
    478  1.1  ragge  * in the command and response rings are `owned' by either the host
    479  1.1  ragge  * or the controller; only the owner is allowed to alter any of the
    480  1.1  ragge  * fields in the MSCP packet.  Thus, free command packets are owned
    481  1.1  ragge  * by the host, and free response packets by the controller.  When
    482  1.1  ragge  * the host gives a packet to the controller, it tells the controller
    483  1.1  ragge  * by touching a device register; when the controller gives a response
    484  1.1  ragge  * to the host, it generates an interrupt if enabled, and sets
    485  1.1  ragge  * a device register as well.
    486  1.1  ragge  *
    487  1.1  ragge  * The pool is `described' by a set of pointers to the packets, along
    488  1.1  ragge  * with the two flags below.
    489  1.1  ragge  */
    490  1.4  ragge #define MSCP_OWN	0x80000000	/* controller owns this packet */
    491  1.4  ragge #define MSCP_INT	0x40000000	/* controller should interrupt */
    492