The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/cam/scsi/scsi_ch.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* $FreeBSD$ */
    2 /*      $NetBSD: scsi_changer.h,v 1.11 1998/02/13 08:28:32 enami Exp $  */
    3 
    4 /*-
    5  * SPDX-License-Identifier: BSD-4-Clause
    6  *
    7  * Copyright (c) 1996 Jason R. Thorpe <thorpej@and.com>
    8  * All rights reserved.
    9  *
   10  * Partially based on an autochanger driver written by Stefan Grefen
   11  * and on an autochanger driver written by the Systems Programming Group
   12  * at the University of Utah Computer Science Department.
   13  *
   14  * Redistribution and use in source and binary forms, with or without
   15  * modification, are permitted provided that the following conditions
   16  * are met:
   17  * 1. Redistributions of source code must retain the above copyright
   18  *    notice, this list of conditions and the following disclaimer.
   19  * 2. Redistributions in binary form must reproduce the above copyright
   20  *    notice, this list of conditions and the following disclaimer in the
   21  *    documentation and/or other materials provided with the distribution.
   22  * 3. All advertising materials mentioning features or use of this software
   23  *    must display the following acknowledgements:
   24  *      This product includes software developed by Jason R. Thorpe
   25  *      for And Communications, http://www.and.com/
   26  * 4. The name of the author may not be used to endorse or promote products
   27  *    derived from this software without specific prior written permission.
   28  *
   29  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   30  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   31  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   32  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   33  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   34  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   35  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
   36  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   37  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   38  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   39  * SUCH DAMAGE.
   40  */
   41 
   42 /*
   43  * SCSI changer interface description
   44  */
   45 
   46 /*-
   47  * Partially derived from software written by Stefan Grefen
   48  * (grefen@goofy.zdv.uni-mainz.de soon grefen@convex.com)
   49  * based on the SCSI System by written Julian Elischer (julian@tfs.com)
   50  * for TRW Financial Systems.
   51  *
   52  * TRW Financial Systems, in accordance with their agreement with Carnegie
   53  * Mellon University, makes this software available to CMU to distribute
   54  * or use in any manner that they see fit as long as this message is kept with 
   55  * the software. For this reason TFS also grants any other persons or
   56  * organisations permission to use or modify this software.
   57  *
   58  * TFS supplies this software to be publicly redistributed
   59  * on the understanding that TFS is not responsible for the correct
   60  * functioning of this software in any circumstances.
   61  *
   62  * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
   63  */
   64 
   65 #ifndef _SCSI_SCSI_CH_H
   66 #define _SCSI_SCSI_CH_H 1
   67 
   68 #include <sys/cdefs.h>
   69 
   70 /*
   71  * SCSI command format
   72  */
   73 
   74 /*
   75  * Exchange the medium in the source element with the medium
   76  * located at the destination element.
   77  */
   78 struct scsi_exchange_medium {
   79         u_int8_t        opcode;
   80 #define EXCHANGE_MEDIUM         0xa6
   81         u_int8_t        byte2;
   82         u_int8_t        tea[2]; /* transport element address */
   83         u_int8_t        src[2]; /* source address */
   84         u_int8_t        fdst[2]; /* first destination address */
   85         u_int8_t        sdst[2]; /* second destination address */
   86         u_int8_t        invert;
   87 #define EXCHANGE_MEDIUM_INV1    0x01
   88 #define EXCHANGE_MEDIUM_INV2    0x02
   89         u_int8_t        control;
   90 };
   91 
   92 /*
   93  * Cause the medium changer to check all elements for medium and any
   94  * other status relevant to the element.
   95  */
   96 struct scsi_initialize_element_status {
   97         u_int8_t        opcode;
   98 #define INITIALIZE_ELEMENT_STATUS       0x07
   99         u_int8_t        byte2;
  100         u_int8_t        reserved[3];
  101         u_int8_t        control;
  102 };
  103 
  104 /*
  105  * Request the changer to move a unit of media from the source element
  106  * to the destination element.
  107  */
  108 struct scsi_move_medium {
  109         u_int8_t        opcode;
  110         u_int8_t        byte2;
  111         u_int8_t        tea[2]; /* transport element address */
  112         u_int8_t        src[2]; /* source element address */
  113         u_int8_t        dst[2]; /* destination element address */
  114         u_int8_t        reserved[2];
  115         u_int8_t        invert;
  116 #define MOVE_MEDIUM_INVERT      0x01
  117         u_int8_t        control;
  118 };
  119 
  120 /*
  121  * Position the specified transport element (picker) in front of
  122  * the destination element specified.
  123  */
  124 struct scsi_position_to_element {
  125         u_int8_t        opcode;
  126         u_int8_t        byte2;
  127         u_int8_t        tea[2]; /* transport element address */
  128         u_int8_t        dst[2]; /* destination element address */
  129         u_int8_t        reserved[2];
  130         u_int8_t        invert;
  131 #define POSITION_TO_ELEMENT_INVERT      0x01
  132         u_int8_t        control;
  133 };
  134 
  135 /*
  136  * Request that the changer report the status of its internal elements.
  137  */
  138 struct scsi_read_element_status {
  139         u_int8_t        opcode;
  140         u_int8_t        byte2;
  141 #define READ_ELEMENT_STATUS_VOLTAG      0x10    /* report volume tag info */
  142         /* ...next 4 bits are an element type code... */
  143         u_int8_t        sea[2]; /* starting element address */
  144         u_int8_t        count[2]; /* number of elements */
  145         u_int8_t        flags;
  146 #define READ_ELEMENT_STATUS_DVCID       0x01 /* report device serial number */
  147 #define READ_ELEMENT_STATUS_CURDATA     0x02 /* allow motion during command */
  148 
  149         u_int8_t        len[3]; /* length of data buffer */
  150         u_int8_t        reserved1;
  151         u_int8_t        control;
  152 };
  153 
  154 struct scsi_request_volume_element_address {
  155         u_int8_t        opcode;
  156         u_int8_t        byte2;
  157 #define REQUEST_VOLUME_ELEMENT_ADDRESS_VOLTAG   0x10
  158         /* ...next 4 bits are an element type code... */
  159         u_int8_t        eaddr[2];       /* element address */
  160         u_int8_t        count[2];       /* number of elements */
  161         u_int8_t        reserved0;
  162         u_int8_t        len[3];         /* length of data buffer */
  163         u_int8_t        reserved1;
  164         u_int8_t        control;
  165 };
  166 
  167 /* XXX scsi_release */
  168 
  169 /*
  170  * Changer-specific mode page numbers.
  171  */
  172 #define CH_ELEMENT_ADDR_ASSIGN_PAGE     0x1D
  173 #define CH_TRANS_GEOM_PARAMS_PAGE       0x1E
  174 #define CH_DEVICE_CAP_PAGE              0x1F
  175 
  176 /*
  177  * Data returned by READ ELEMENT STATUS consists of an 8-byte header
  178  * followed by one or more read_element_status_pages.
  179  */
  180 struct read_element_status_header {
  181         u_int8_t        fear[2];  /* first element address reported */
  182         u_int8_t        count[2]; /* number of elements available */
  183         u_int8_t        reserved;
  184         u_int8_t        nbytes[3]; /* byte count of all pages */
  185 };
  186 
  187 struct read_element_status_page_header {
  188         u_int8_t        type;   /* element type code; see type codes below */
  189         u_int8_t        flags;
  190 #define READ_ELEMENT_STATUS_AVOLTAG     0x40
  191 #define READ_ELEMENT_STATUS_PVOLTAG     0x80
  192         u_int8_t        edl[2]; /* element descriptor length */
  193         u_int8_t        reserved;
  194         u_int8_t        nbytes[3]; /* byte count of all descriptors */
  195 };
  196 
  197 /*
  198  * Format of a volume tag
  199  */
  200 
  201 struct volume_tag {
  202         u_int8_t        vif[32];        /* volume identification field */
  203         u_int8_t        reserved[2];
  204         u_int8_t        vsn[2];         /* volume sequence number */
  205 };
  206 
  207 struct read_element_status_device_id {
  208         u_int8_t        prot_code_set;
  209 #define READ_ELEMENT_STATUS_CODE_SET(p) ((p) & 0x0F)
  210 #define READ_ELEMENT_STATUS_PROTOCOL_ID(p) ((p) >> 4)
  211 
  212         u_int8_t        piv_assoc_designator_type;
  213 #define READ_ELEMENT_STATUS_PIV_SET 0x80
  214 #define READ_ELEMENT_STATUS_ASSOCIATION(p) ((p) >> 4)
  215 #define READ_ELEMENT_STATUS_DESIGNATOR_TYPE(p) ((p) & 0x0F)
  216 
  217         u_int8_t        reserved2;
  218         u_int8_t        designator_length;
  219         u_int8_t        designator[256]; /* Allocate max length */
  220 };
  221 
  222 struct read_element_status_descriptor {
  223         u_int8_t        eaddr[2];       /* element address */
  224         u_int8_t        flags1;
  225 
  226 #define READ_ELEMENT_STATUS_FULL        0x01
  227 #define READ_ELEMENT_STATUS_IMPEXP      0x02
  228 #define READ_ELEMENT_STATUS_EXCEPT      0x04
  229 #define READ_ELEMENT_STATUS_ACCESS      0x08
  230 #define READ_ELEMENT_STATUS_EXENAB      0x10
  231 #define READ_ELEMENT_STATUS_INENAB      0x20
  232 
  233 #define READ_ELEMENT_STATUS_MT_MASK1    0x05
  234 #define READ_ELEMENT_STATUS_ST_MASK1    0x0c
  235 #define READ_ELEMENT_STATUS_IE_MASK1    0x3f
  236 #define READ_ELEMENT_STATUS_DT_MASK1    0x0c
  237 
  238         u_int8_t        reserved0;
  239         u_int8_t        sense_code;
  240         u_int8_t        sense_qual;
  241 
  242         union {
  243                 struct {
  244                         u_int8_t        dt_scsi_flags;
  245 
  246 #define READ_ELEMENT_STATUS_DT_LUNMASK  0x07
  247 #define READ_ELEMENT_STATUS_DT_LUVALID  0x10
  248 #define READ_ELEMENT_STATUS_DT_IDVALID  0x20
  249 #define READ_ELEMENT_STATUS_DT_NOTBUS   0x80
  250 
  251                         u_int8_t        dt_scsi_addr;
  252                         u_int8_t        reserved1;
  253                 } scsi_2;
  254 
  255                 /* reserved and obsolete (as of SCSI-3) fields */
  256                 u_int8_t        reserved_or_obsolete[3];
  257         } dt_or_obsolete;
  258 
  259         u_int8_t        flags2;
  260 #define READ_ELEMENT_STATUS_INVERT              0x40
  261 #define READ_ELEMENT_STATUS_SVALID              0x80
  262 #define READ_ELEMENT_STATUS_ED                  0x80
  263 #define READ_ELEMENT_STATUS_MEDIA_TYPE_MASK     0x07
  264 
  265         u_int8_t        ssea[2];        /* source storage element address */
  266 
  267         union {
  268                 struct volume_tag                       pvoltag;
  269                 struct volume_tag                       voltag[2];
  270                 struct read_element_status_device_id    devid;
  271                 struct {
  272                         struct volume_tag                       pvoltag;
  273                         struct read_element_status_device_id    devid;
  274                 } pvol_and_devid;
  275                 struct {
  276                         struct volume_tag                       voltag[2];
  277                         struct read_element_status_device_id    devid;
  278                 } vol_tags_and_devid;
  279         } voltag_devid;
  280 };
  281 
  282 /* XXX add data returned by REQUEST VOLUME ELEMENT ADDRESS */
  283 
  284 /* Element type codes */
  285 #define ELEMENT_TYPE_MASK       0x0f    /* Note: these aren't bits */
  286 #define ELEMENT_TYPE_ALL        0x00
  287 #define ELEMENT_TYPE_MT         0x01
  288 #define ELEMENT_TYPE_ST         0x02
  289 #define ELEMENT_TYPE_IE         0x03
  290 #define ELEMENT_TYPE_DT         0x04
  291 
  292 /*
  293  * XXX The following definitions should be common to all SCSI device types.
  294  */
  295 #define PGCODE_MASK     0x3f    /* valid page number bits in pg_code */
  296 #define PGCODE_PS       0x80    /* indicates page is savable */
  297 
  298 /*
  299  * Send volume tag information to the changer
  300  */
  301 
  302 struct scsi_send_volume_tag {
  303         u_int8_t        opcode;
  304 #define SEND_VOLUME_TAG 0xb6
  305         u_int8_t        byte2;
  306         u_int8_t        ea[2];          /* element address */
  307         u_int8_t        reserved2;
  308         u_int8_t        sac;            /* send action code */
  309 
  310 #define SEND_VOLUME_TAG_ASSERT_PRIMARY          0x08
  311 #define SEND_VOLUME_TAG_ASSERT_ALTERNATE        0x09
  312 #define SEND_VOLUME_TAG_REPLACE_PRIMARY         0x0a
  313 #define SEND_VOLUME_TAG_REPLACE_ALTERNATE       0x0b
  314 #define SEND_VOLUME_TAG_UNDEFINED_PRIMARY       0x0c
  315 #define SEND_VOLUME_TAG_UNDEFINED_ALTERNATE     0x0d
  316 
  317         u_int8_t        reserved4[2];
  318         u_int8_t        pll[2];         /* parameter list length */
  319         u_int8_t        reserved5;
  320         u_int8_t        control;
  321 };
  322 
  323 /*
  324  * Parameter format for SEND VOLUME TAG
  325  */
  326 
  327 struct scsi_send_volume_tag_parameters {
  328         u_int8_t        vitf[32];       /* volume tag identification template */
  329         u_int8_t        reserved1[2];
  330         u_int8_t        minvsn[2];      /* minimum volume sequence number */
  331         u_int8_t        reserved2[2];
  332         u_int8_t        maxvsn[2];      /* maximum volume sequence number */
  333 };
  334 
  335 /*
  336  * Device capabilities page.
  337  *
  338  * This page defines characteristics of the element types in the
  339  * medium changer device.
  340  *
  341  * Note in the definitions below, the following abbreviations are
  342  * used:
  343  *              MT      Medium transport element (picker)
  344  *              ST      Storage transport element (slot)
  345  *              IE      Import/export element (portal)
  346  *              DT      Data transfer element (tape/disk drive)
  347  */
  348 struct page_device_capabilities {
  349         u_int8_t        pg_code;        /* page code (0x1f) */
  350         u_int8_t        pg_length;      /* page length (0x12) */
  351 
  352         /*
  353          * The STOR_xx bits indicate that an element of a given
  354          * type may provide independent storage for a unit of
  355          * media.  The top four bits of this value are reserved.
  356          */
  357         u_int8_t        stor;
  358 #define STOR_MT         0x01
  359 #define STOR_ST         0x02
  360 #define STOR_IE         0x04
  361 #define STOR_DT         0x08
  362 
  363         u_int8_t        reserved0;
  364 
  365         /*
  366          * The MOVE_TO_yy bits indicate the changer supports
  367          * moving a unit of medium from an element of a given type to an
  368          * element of type yy.  This is used to determine if a given
  369          * MOVE MEDIUM command is legal.  The top four bits of each
  370          * of these values are reserved.
  371          */
  372         u_int8_t        move_from[CHET_MAX + 1];
  373 #define MOVE_TO_MT      0x01
  374 #define MOVE_TO_ST      0x02
  375 #define MOVE_TO_IE      0x04
  376 #define MOVE_TO_DT      0x08
  377 
  378         u_int8_t        reserved1[4];
  379 
  380         /*
  381          * Similar to above, but for EXCHANGE MEDIUM.
  382          */
  383         u_int8_t        exchange_with[CHET_MAX + 1];
  384 #define EXCHANGE_WITH_MT        0x01
  385 #define EXCHANGE_WITH_ST        0x02
  386 #define EXCHANGE_WITH_IE        0x04
  387 #define EXCHANGE_WITH_DT        0x08
  388 };
  389 
  390 /*
  391  * Medium changer elemement address assignment page.
  392  *
  393  * Some of these fields can be a little confusing, so an explanation
  394  * is in order.
  395  *
  396  * Each component within a medium changer apparatus is called an
  397  * "element".
  398  *
  399  * The "medium transport element address" is the address of the first
  400  * picker (robotic arm).  "Number of medium transport elements" tells
  401  * us how many pickers exist in the changer.
  402  *
  403  * The "first storage element address" is the address of the first
  404  * slot in the tape or disk magazine.  "Number of storage elements" tells
  405  * us how many slots exist in the changer.
  406  *
  407  * The "first import/export element address" is the address of the first
  408  * medium portal accessible both by the medium changer and an outside
  409  * human operator.  This is where the changer might deposit tapes destined
  410  * for some vault.  The "number of import/export elements" tells us
  411  * not many of these portals exist in the changer.  NOTE: this number may
  412  * be 0.
  413  *
  414  * The "first data transfer element address" is the address of the first
  415  * tape or disk drive in the changer.  "Number of data transfer elements"
  416  * tells us how many drives exist in the changer.
  417  */
  418 struct page_element_address_assignment {
  419         u_int8_t        pg_code;        /* page code (0x1d) */
  420         u_int8_t        pg_length;      /* page length (0x12) */
  421 
  422         /* Medium transport element address */
  423         u_int8_t        mtea[2];
  424 
  425         /* Number of medium transport elements */
  426         u_int8_t        nmte[2];
  427 
  428         /* First storage element address */
  429         u_int8_t        fsea[2];
  430 
  431         /* Number of storage elements */
  432         u_int8_t        nse[2];
  433 
  434         /* First import/export element address */
  435         u_int8_t        fieea[2];
  436 
  437         /* Number of import/export elements */
  438         u_int8_t        niee[2];
  439 
  440         /* First data transfer element address */
  441         u_int8_t        fdtea[2];
  442 
  443         /* Number of data transfer elements */
  444         u_int8_t        ndte[2];
  445 
  446         u_int8_t        reserved[2];
  447 };
  448 
  449 /*
  450  * Transport geometry parameters page.
  451  *
  452  * Defines whether each medium transport element is a member of a set of
  453  * elements that share a common robotics subsystem and whether the element
  454  * is capable of media rotation.  One transport geometry descriptor is
  455  * transferred for each medium transport element, beginning with the first
  456  * medium transport element (other than the default transport element address
  457  * of 0).
  458  */
  459 struct page_transport_geometry_parameters {
  460         u_int8_t        pg_code;        /* page code (0x1e) */
  461         u_int8_t        pg_length;      /* page length; variable */
  462 
  463         /* Transport geometry descriptor(s) are here. */
  464 
  465         u_int8_t        misc;
  466 #define CAN_ROTATE      0x01
  467 
  468         /* Member number in transport element set. */
  469         u_int8_t        member;
  470 };
  471 
  472 __BEGIN_DECLS
  473 void scsi_move_medium(struct ccb_scsiio *csio, u_int32_t retries,
  474                       void (*cbfcnp)(struct cam_periph *, union ccb *),
  475                       u_int8_t tag_action, u_int32_t tea, u_int32_t src,
  476                       u_int32_t dst, int invert, u_int8_t sense_len,
  477                       u_int32_t timeout);
  478 
  479 void scsi_exchange_medium(struct ccb_scsiio *csio, u_int32_t retries,
  480                           void (*cbfcnp)(struct cam_periph *, union ccb *),
  481                           u_int8_t tag_action, u_int32_t tea, u_int32_t src,
  482                           u_int32_t dst1, u_int32_t dst2, int invert1,
  483                           int invert2, u_int8_t sense_len, u_int32_t timeout);
  484 
  485 void scsi_position_to_element(struct ccb_scsiio *csio, u_int32_t retries,
  486                               void (*cbfcnp)(struct cam_periph *, union ccb *),
  487                               u_int8_t tag_action, u_int32_t tea, u_int32_t dst,
  488                               int invert, u_int8_t sense_len,
  489                               u_int32_t timeout);
  490 
  491 void scsi_read_element_status(struct ccb_scsiio *csio, u_int32_t retries,
  492                               void (*cbfcnp)(struct cam_periph *, union ccb *),
  493                               u_int8_t tag_action, int voltag, u_int32_t sea,
  494                               int curdata, int dvcid,
  495                               u_int32_t count, u_int8_t *data_ptr,
  496                               u_int32_t dxfer_len, u_int8_t sense_len,
  497                               u_int32_t timeout);
  498 
  499 void scsi_initialize_element_status(struct ccb_scsiio *csio, u_int32_t retries,
  500                                void (*cbfcnp)(struct cam_periph *, union ccb *),
  501                                u_int8_t tag_action, u_int8_t sense_len,
  502                                u_int32_t timeout);
  503 void scsi_send_volume_tag(struct ccb_scsiio *csio, u_int32_t retries,
  504                           void (*cbfcnp)(struct cam_periph *, union ccb *),
  505                           u_int8_t tag_action, 
  506                           u_int16_t element_address,
  507                           u_int8_t send_action_code,
  508                           struct scsi_send_volume_tag_parameters *parameters,
  509                           u_int8_t sense_len, u_int32_t timeout);
  510 __END_DECLS
  511 
  512 #endif /* _SCSI_SCSI_CH_H */

Cache object: 5e5268e2a30928d8190e61e1db9f9b28


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.