Annotation of sys/scsi/scsi_changer.h, Revision 1.1
1.1 ! nbrk 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 */
CVSweb