root/scsi/scsi_changer.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


    1 /*      $OpenBSD: scsi_changer.h,v 1.5 2006/12/21 02:05:46 krw Exp $    */
    2 /*      $NetBSD: scsi_changer.h,v 1.7 1996/04/03 00:25:48 thorpej Exp $ */
    3 
    4 /*
    5  * Copyright (c) 1996 Jason R. Thorpe <thorpej@and.com>
    6  * All rights reserved.
    7  *
    8  * Partially based on an autochanger driver written by Stefan Grefen
    9  * and on an autochanger driver written by the Systems Programming Group
   10  * at the University of Utah Computer Science Department.
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer.
   17  * 2. Redistributions in binary form must reproduce the above copyright
   18  *    notice, this list of conditions and the following disclaimer in the
   19  *    documentation and/or other materials provided with the distribution.
   20  * 3. All advertising materials mentioning features or use of this software
   21  *    must display the following acknowledgements:
   22  *      This product includes software developed by Jason R. Thorpe
   23  *      for And Communications, http://www.and.com/
   24  * 4. The name of the author may not be used to endorse or promote products
   25  *    derived from this software without specific prior written permission.
   26  *
   27  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   28  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   29  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   30  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   31  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   32  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   33  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
   34  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   35  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   36  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   37  * SUCH DAMAGE.
   38  */
   39 
   40 /*
   41  * SCSI changer interface description
   42  */
   43 
   44 /*
   45  * Partially derived from software written by Stefan Grefen
   46  * (grefen@goofy.zdv.uni-mainz.de soon grefen@convex.com)
   47  * based on the SCSI System by written Julian Elischer (julian@tfs.com)
   48  * for TRW Financial Systems.
   49  *
   50  * TRW Financial Systems, in accordance with their agreement with Carnegie
   51  * Mellon University, makes this software available to CMU to distribute
   52  * or use in any manner that they see fit as long as this message is kept with
   53  * the software. For this reason TFS also grants any other persons or
   54  * organisations permission to use or modify this software.
   55  *
   56  * TFS supplies this software to be publicly redistributed
   57  * on the understanding that TFS is not responsible for the correct
   58  * functioning of this software in any circumstances.
   59  *
   60  * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
   61  */
   62 
   63 #ifndef _SCSI_SCSI_CHANGER_H
   64 #define _SCSI_SCSI_CHANGER_H 1
   65 
   66 /*
   67  * SCSI command format
   68  */
   69 
   70 /*
   71  * Exchange the medium in the source element with the medium
   72  * located at the destination element.
   73  */
   74 struct scsi_exchange_medium {
   75         u_int8_t        opcode;
   76 #define EXCHANGE_MEDIUM         0xa6
   77         u_int8_t        byte2;
   78         u_int8_t        tea[2]; /* transport element address */
   79         u_int8_t        src[2]; /* source address */
   80         u_int8_t        fdst[2]; /* first destination address */
   81         u_int8_t        sdst[2]; /* second destination address */
   82         u_int8_t        flags;
   83 #define EXCHANGE_MEDIUM_INV1    0x01
   84 #define EXCHANGE_MEDIUM_INV2    0x02
   85         u_int8_t        control;
   86 };
   87 
   88 /*
   89  * Cause the medium changer to check all elements for medium and any
   90  * other status relevant to the element.
   91  */
   92 struct scsi_initialize_elememt_status {
   93         u_int8_t        opcode;
   94 #define INITIALIZE_ELEMENT_STATUS       0x07
   95         u_int8_t        byte2;
   96         u_int8_t        reserved[3];
   97         u_int8_t        control;
   98 };
   99 
  100 /*
  101  * Request the changer to move a unit of media from the source element
  102  * to the destination element.
  103  */
  104 struct scsi_move_medium {
  105         u_int8_t        opcode;
  106 #define MOVE_MEDIUM     0xa5
  107         u_int8_t        byte2;
  108         u_int8_t        tea[2]; /* transport element address */
  109         u_int8_t        src[2]; /* source element address */
  110         u_int8_t        dst[2]; /* destination element address */
  111         u_int8_t        reserved[2];
  112         u_int8_t        flags;
  113 #define MOVE_MEDIUM_INVERT      0x01
  114         u_int8_t        control;
  115 };
  116 
  117 /*
  118  * Position the specified transport element (picker) in front of
  119  * the destination element specified.
  120  */
  121 struct scsi_position_to_element {
  122         u_int8_t        opcode;
  123 #define POSITION_TO_ELEMENT     0x2b
  124         u_int8_t        byte2;
  125         u_int8_t        tea[2]; /* transport element address */
  126         u_int8_t        dst[2]; /* destination element address */
  127         u_int8_t        reserved[2];
  128         u_int8_t        flags;
  129 #define POSITION_TO_ELEMENT_INVERT      0x01
  130         u_int8_t        control;
  131 };
  132 
  133 /*
  134  * Request that the changer report the status of its internal elements.
  135  */
  136 struct scsi_read_element_status {
  137         u_int8_t        opcode;
  138 #define READ_ELEMENT_STATUS     0xb8
  139         u_int8_t        byte2;
  140 #define READ_ELEMENT_STATUS_VOLTAG      0x10    /* report volume tag info */
  141         /* ...next 4 bits are an element type code... */
  142         u_int8_t        sea[2]; /* starting element address */
  143         u_int8_t        count[2]; /* number of elements */
  144         u_int8_t        reserved0;
  145         u_int8_t        len[3]; /* length of data buffer */
  146         u_int8_t        reserved1;
  147         u_int8_t        control;
  148 };
  149 
  150 struct scsi_request_volume_element_address {
  151         u_int8_t        opcode;
  152 #define REQUEST_VOLUME_ELEMENT_ADDRESS  0xb5
  153         u_int8_t        byte2;
  154 #define REQUEST_VOLUME_ELEMENT_ADDRESS_VOLTAG   0x10
  155         /* ...next 4 bits are an element type code... */
  156         u_int8_t        eaddr[2];       /* element address */
  157         u_int8_t        count[2];       /* number of elements */
  158         u_int8_t        reserved0;
  159         u_int8_t        len[3];         /* length of data buffer */
  160         u_int8_t        reserved1;
  161         u_int8_t        control;
  162 };
  163 
  164 /* XXX scsi_release */
  165 
  166 /*
  167  * Data returned by READ ELEMENT STATUS consists of an 8-byte header
  168  * followed by one or more read_element_status_pages.
  169  */
  170 struct read_element_status_header {
  171         u_int8_t        fear[2];  /* first element address reported */
  172         u_int8_t        count[2]; /* number of elements available */
  173         u_int8_t        reserved;
  174         u_int8_t        nbytes[3]; /* byte count of all pages */
  175 };
  176 
  177 struct read_element_status_page_header {
  178         u_int8_t        type;   /* element type code; see type codes below */
  179         u_int8_t        flags;
  180 #define READ_ELEMENT_STATUS_AVOLTAG     0x40
  181 #define READ_ELEMENT_STATUS_PVOLTAG     0x80
  182         u_int8_t        edl[2]; /* element descriptor length */
  183         u_int8_t        reserved;
  184         u_int8_t        nbytes[3]; /* byte count of all descriptors */
  185 };
  186 
  187 /*
  188  * Format of a volume tag
  189  */
  190 
  191 struct volume_tag {
  192         u_int8_t        vif[32];        /* volume identification field */
  193         u_int8_t        reserved[2];
  194         u_int8_t        vsn[2];         /* volume sequence number */
  195 };
  196 
  197 struct read_element_status_descriptor {
  198         u_int8_t        eaddr[2];       /* element address */
  199         u_int8_t        flags1;
  200 
  201 #define READ_ELEMENT_STATUS_FULL        0x01
  202 #define READ_ELEMENT_STATUS_IMPEXP      0x02
  203 #define READ_ELEMENT_STATUS_EXCEPT      0x04
  204 #define READ_ELEMENT_STATUS_ACCESS      0x08
  205 #define READ_ELEMENT_STATUS_EXENAB      0x10
  206 #define READ_ELEMENT_STATUS_INENAB      0x20
  207 
  208 #define READ_ELEMENT_STATUS_MT_MASK1    0x05
  209 #define READ_ELEMENT_STATUS_ST_MASK1    0x0c
  210 #define READ_ELEMENT_STATUS_IE_MASK1    0x3f
  211 #define READ_ELEMENT_STATUS_DT_MASK1    0x0c
  212 
  213         u_int8_t        reserved0;
  214         u_int8_t        sense_code;
  215         u_int8_t        sense_qual;
  216 
  217         /*
  218          * dt_scsi_flags and dt_scsi_addr are valid only on data transport
  219          * elements.  These bytes are undefined for all other element types.
  220          */
  221         u_int8_t        dt_scsi_flags;
  222 
  223 #define READ_ELEMENT_STATUS_DT_LUNMASK  0x07
  224 #define READ_ELEMENT_STATUS_DT_LUVALID  0x10
  225 #define READ_ELEMENT_STATUS_DT_IDVALID  0x20
  226 #define READ_ELEMENT_STATUS_DT_NOTBUS   0x80
  227 
  228         u_int8_t        dt_scsi_addr;
  229 
  230         u_int8_t        reserved1;
  231 
  232         u_int8_t        flags2;
  233 #define READ_ELEMENT_STATUS_INVERT      0x40
  234 #define READ_ELEMENT_STATUS_SVALID      0x80
  235         u_int8_t        ssea[2];        /* source storage element address */
  236 
  237         /*
  238          * bytes 12-47: Primary volume tag information.
  239          *              (field omitted if PVOLTAG = 0)
  240          *
  241          * bytes 48-83: Alternate volume tag information.
  242          *              (field omitted if AVOLTAG = 0)
  243          */
  244         
  245         struct volume_tag pvoltag;      /* omitted if PVOLTAG == 0 */
  246         struct volume_tag avoltag;      /* omitted if AVOLTAG == 0 */
  247         
  248         /*
  249          * bytes 84-87: Reserved (moved up if either of the above fields
  250          *              are omitted)
  251          *
  252          * bytes 88-end: Vendor-specific: (moved up if either of the
  253          *               above fields are missing)
  254          */
  255 };
  256 
  257 /* XXX add data returned by REQUEST VOLUME ELEMENT ADDRESS */
  258 
  259 /* Element type codes */
  260 #define ELEMENT_TYPE_MASK       0x0f    /* Note: these aren't bits */
  261 #define ELEMENT_TYPE_ALL        0x00
  262 #define ELEMENT_TYPE_MT         0x01
  263 #define ELEMENT_TYPE_ST         0x02
  264 #define ELEMENT_TYPE_IE         0x03
  265 #define ELEMENT_TYPE_DT         0x04
  266 
  267 /*
  268  * XXX The following definitions should be common to all SCSI device types.
  269  */
  270 #define PGCODE_MASK     0x3f    /* valid page number bits in pg_code */
  271 #define PGCODE_PS       0x80    /* indicates page is savable */
  272 
  273 /*
  274  * Device capabilities page.
  275  *
  276  * This page defines characteristics of the elemenet types in the
  277  * medium changer device.
  278  *
  279  * Note in the definitions below, the following abbreviations are
  280  * used:
  281  *              MT      Medium transport element (picker)
  282  *              ST      Storage transport element (slot)
  283  *              IE      Import/export element (portal)
  284  *              DT      Data transfer element (tape/disk drive)
  285  */
  286 struct page_device_capabilities {
  287         u_int8_t        pg_code;        /* page code (0x1f) */
  288         u_int8_t        pg_length;      /* page length (0x12) */
  289 
  290         /*
  291          * The STOR_xx bits indicate that an element of a given
  292          * type may provide independent storage for a unit of
  293          * media.  The top four bits of this value are reserved.
  294          */
  295         u_int8_t        stor;
  296 #define STOR_MT         0x01
  297 #define STOR_ST         0x02
  298 #define STOR_IE         0x04
  299 #define STOR_DT         0x08
  300 
  301         u_int8_t        reserved0;
  302 
  303         /*
  304          * The MOVE_TO_yy bits indicate the changer supports
  305          * moving a unit of medium from an element of a given type to an
  306          * element of type yy.  This is used to determine if a given
  307          * MOVE MEDIUM command is legal.  The top four bits of each
  308          * of these values are reserved.
  309          */
  310         u_int8_t        move_from_mt;
  311         u_int8_t        move_from_st;
  312         u_int8_t        move_from_ie;
  313         u_int8_t        move_from_dt;
  314 #define MOVE_TO_MT      0x01
  315 #define MOVE_TO_ST      0x02
  316 #define MOVE_TO_IE      0x04
  317 #define MOVE_TO_DT      0x08
  318 
  319         u_int8_t        reserved1[2];
  320 
  321         /*
  322          * Similar to above, but for EXCHANGE MEDIUM.
  323          */
  324         u_int8_t        exchange_with_mt;
  325         u_int8_t        exchange_with_st;
  326         u_int8_t        exchange_with_ie;
  327         u_int8_t        exchange_with_dt;
  328 #define EXCHANGE_WITH_MT        0x01
  329 #define EXCHANGE_WITH_ST        0x02
  330 #define EXCHANGE_WITH_IE        0x04
  331 #define EXCHANGE_WITH_DT        0x08
  332 };
  333 
  334 /*
  335  * Medium changer elemement address assignment page.
  336  *
  337  * Some of these fields can be a little confusing, so an explanation
  338  * is in order.
  339  *
  340  * Each component within a a medium changer apparatus is called an
  341  * "element".
  342  *
  343  * The "medium transport element address" is the address of the first
  344  * picker (robotic arm).  "Number of medium transport elements" tells
  345  * us how many pickers exist in the changer.
  346  *
  347  * The "first storage element address" is the address of the first
  348  * slot in the tape or disk magazine.  "Number of storage elements" tells
  349  * us how many slots exist in the changer.
  350  *
  351  * The "first import/export element address" is the address of the first
  352  * medium portal accessible both by the medium changer and an outside
  353  * human operator.  This is where the changer might deposit tapes destined
  354  * for some vault.  The "number of import/export elements" tells us
  355  * not many of these portals exist in the changer.  NOTE: this number may
  356  * be 0.
  357  *
  358  * The "first data transfer element address" is the address of the first
  359  * tape or disk drive in the changer.  "Number of data transfer elements"
  360  * tells us how many drives exist in the changer.
  361  */
  362 struct page_element_address_assignment {
  363         u_int8_t        pg_code;        /* page code (0x1d) */
  364         u_int8_t        pg_length;      /* page length (0x12) */
  365 
  366         /* Medium transport element address */
  367         u_int8_t        mtea[2];
  368 
  369         /* Number of medium transport elements */
  370         u_int8_t        nmte[2];
  371 
  372         /* First storage element address */
  373         u_int8_t        fsea[2];
  374 
  375         /* Number of storage elements */
  376         u_int8_t        nse[2];
  377 
  378         /* First import/export element address */
  379         u_int8_t        fieea[2];
  380 
  381         /* Number of import/export elements */
  382         u_int8_t        niee[2];
  383 
  384         /* First data transfer element address */
  385         u_int8_t        fdtea[2];
  386 
  387         /* Number of data trafer elements */
  388         u_int8_t        ndte[2];
  389 
  390         u_int8_t        reserved[2];
  391 };
  392 
  393 /*
  394  * Transport geometry parameters page.
  395  *
  396  * Defines whether each medium transport element is a member of a set of
  397  * elements that share a common robotics subsystem and whether the element
  398  * is capable of media rotation.  One transport geometry descriptor is
  399  * transferred for each medium transport element, beginning with the first
  400  * medium transport element (other than the default transport element address
  401  * of 0).
  402  */
  403 struct page_transport_geometry_parameters {
  404         u_int8_t        pg_code;        /* page code (0x1e) */
  405         u_int8_t        pg_length;      /* page length; variable */
  406 
  407         /* Transport geometry descriptor(s) are here. */
  408 
  409         u_int8_t        misc;
  410 #define CAN_ROTATE      0x01
  411 
  412         /* Member number in transport element set. */
  413         u_int8_t        member;
  414 };
  415 
  416 #endif /* _SCSI_SCSI_CHANGER_H */

/* [<][>][^][v][top][bottom][index][help] */