Annotation of 43BSDTahoe/sys/vax/mscp.h, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.