1 /* $NetBSD: scsi_changer.h,v 1.16.20.2 2005/03/04 16:50:33 skrll Exp $ */
4 * Copyright (c) 1996, 1999 Jason R. Thorpe <thorpej@and.com>
7 * Partially based on an autochanger driver written by Stefan Grefen
8 * and on an autochanger driver written by the Systems Programming Group
9 * at the University of Utah Computer Science Department.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgements:
21 * This product includes software developed by Jason R. Thorpe
22 * for And Communications, http://www.and.com/
23 * 4. The name of the author may not be used to endorse or promote products
24 * derived from this software without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
33 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
34 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 * SCSI changer interface description
44 * Partially derived from software written by Stefan Grefen
45 * (grefen@goofy.zdv.uni-mainz.de soon grefen@convex.com)
46 * based on the SCSI System by written Julian Elischer (julian@tfs.com)
47 * for TRW Financial Systems.
49 * TRW Financial Systems, in accordance with their agreement with Carnegie
50 * Mellon University, makes this software available to CMU to distribute
51 * or use in any manner that they see fit as long as this message is kept with
52 * the software. For this reason TFS also grants any other persons or
53 * organisations permission to use or modify this software.
55 * TFS supplies this software to be publicly redistributed
56 * on the understanding that TFS is not responsible for the correct
57 * functioning of this software in any circumstances.
59 * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
67 * Exchange the medium in the source element with the medium
68 * located at the destination element.
70 struct scsi_exchange_medium
{
72 #define EXCHANGE_MEDIUM 0xa6
74 u_int8_t tea
[2]; /* transport element address */
75 u_int8_t src
[2]; /* source address */
76 u_int8_t fdst
[2]; /* first destination address */
77 u_int8_t sdst
[2]; /* second destination address */
79 #define EXCHANGE_MEDIUM_INV1 0x01
80 #define EXCHANGE_MEDIUM_INV2 0x02
85 * Cause the medium changer to check all elements for medium and any
86 * other status relevant to the element.
88 struct scsi_initialize_element_status
{
90 #define INITIALIZE_ELEMENT_STATUS 0x07
97 * Request the changer to move a unit of media from the source element
98 * to the destination element.
100 struct scsi_move_medium
{
102 #define MOVE_MEDIUM 0xa5
104 u_int8_t tea
[2]; /* transport element address */
105 u_int8_t src
[2]; /* source element address */
106 u_int8_t dst
[2]; /* destination element address */
107 u_int8_t reserved
[2];
109 #define MOVE_MEDIUM_INVERT 0x01
114 * Position the specified transport element (picker) in front of
115 * the destination element specified.
117 struct scsi_position_to_element
{
119 #define POSITION_TO_ELEMENT 0x2b
121 u_int8_t tea
[2]; /* transport element address */
122 u_int8_t dst
[2]; /* destination element address */
123 u_int8_t reserved
[2];
125 #define POSITION_TO_ELEMENT_INVERT 0x01
130 * Request that the changer report the status of its internal elements.
132 struct scsi_read_element_status
{
134 #define READ_ELEMENT_STATUS 0xb8
136 #define READ_ELEMENT_STATUS_VOLTAG 0x10 /* report volume tag info */
137 /* ...next 4 bits are an element type code... */
138 u_int8_t sea
[2]; /* starting element address */
139 u_int8_t count
[2]; /* number of elements */
141 u_int8_t len
[3]; /* length of data buffer */
146 struct scsi_request_volume_element_address
{
148 #define REQUEST_VOLUME_ELEMENT_ADDRESS 0xb5
150 #define REQUEST_VOLUME_ELEMENT_ADDRESS_VOLTAG 0x10
151 /* ...next 4 bits are an element type code... */
152 u_int8_t eaddr
[2]; /* element address */
153 u_int8_t count
[2]; /* number of elements */
155 u_int8_t len
[3]; /* length of data buffer */
160 /* XXX scsi_release */
163 * Data returned by READ ELEMENT STATUS consists of an 8-byte header
164 * followed by one or more read_element_status_pages.
166 struct read_element_status_header
{
167 u_int8_t fear
[2]; /* first element address reported */
168 u_int8_t count
[2]; /* number of elements available */
170 u_int8_t nbytes
[3]; /* byte count of all pages */
174 * Data returned by REQUEST VOLUME ELEMENT ADDRESS consists of an 8-byte
175 * header followed by one or more read_element_status pages (i.e. same
176 * data format as returned by READ ELEMENT STATUS, except for the initial
179 struct request_volume_element_address_header
{
180 u_int8_t fear
[2]; /* first element address reported */
181 u_int8_t count
[2]; /* number of elements available */
182 u_int8_t sac
; /* send action code */
183 #define REQUEST_VOLUME_ELEMENT_ADDRESS_SACMASK 0x1f
184 u_int8_t nbytes
[3];/* byte count of all pages */
187 struct read_element_status_page_header
{
188 u_int8_t type
; /* element type code; see type codes below */
190 #define READ_ELEMENT_STATUS_AVOLTAG 0x40
191 #define READ_ELEMENT_STATUS_PVOLTAG 0x80
192 u_int8_t edl
[2]; /* element descriptor length */
194 u_int8_t nbytes
[3]; /* byte count of all descriptors */
197 struct read_element_status_descriptor
{
198 u_int8_t eaddr
[2]; /* element address */
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
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
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.
221 u_int8_t dt_scsi_flags
;
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
228 u_int8_t dt_scsi_addr
;
233 #define READ_ELEMENT_STATUS_INVERT 0x40
234 #define READ_ELEMENT_STATUS_SVALID 0x80
235 u_int8_t ssea
[2]; /* source storage element address */
238 * bytes 12-47: Primary volume tag information.
239 * (field omitted if PVOLTAG = 0)
241 * bytes 48-83: Alternate volume tag information.
242 * (field omitted if AVOLTAG = 0)
244 * bytes 84-87: Reserved (moved up if either of the above fields
247 * bytes 88-end: Vendor-specific: (moved up if either of the
248 * above fields are missing)
255 * Volume Tags are a sequence of ASCII characters, unused portion is
256 * blank-filled. There should be no blanks in the significant portion
257 * of the tag. For maximum compatibility, volume tag characters should
258 * be limited to '0'..'9', 'A'..'Z', '_'.
260 struct changer_volume_tag
{
261 u_int8_t volid
[32]; /* 32 bytes of ASCII, blank-terminated */
262 u_int8_t reserved
[2];
263 u_int8_t volseq
[2]; /* volume sequence number */
269 struct scsi_send_volume_tag
{
271 #define SEND_VOLUME_TAG 0xb6
273 u_int8_t eaddr
[2]; /* element address */
275 u_int8_t sac
; /* send action code */
276 #define SAC_TRANSLATE_ALL 0x00
277 #define SAC_TRANSLATE_PRIMARY 0x01
278 #define SAC_TRANSLATE_ALT 0x02
279 #define SAC_TRANSLATE_ALL_NOSEQ 0x04
280 #define SAC_TRANSLATE_PRIMARY_NOSEQ 0x05
281 #define SAC_TRANSLATE_ALT_NOSEQ 0x06
282 #define SAC_ASSERT_PRIMARY 0x08
283 #define SAC_ASSERT_ALT 0x09
284 #define SAC_REPLACE_PRIMARY 0x0a
285 #define SAC_REPLACE_ALT 0x0b
286 #define SAC_UNDEFINED_PRIMARY 0x0c
287 #define SAC_UNDEFINED_ALT 0x0d
288 /* 0x0e - 0x1b reserved */
289 /* 0x1c - 0x1f vendor-specific */
290 u_int8_t reserved1
[2];
291 u_int8_t length
[2]; /* paremeter list length */
296 /* Element type codes */
297 #define ELEMENT_TYPE_MASK 0x0f /* Note: these aren't bits */
298 #define ELEMENT_TYPE_ALL 0x00
299 #define ELEMENT_TYPE_MT 0x01
300 #define ELEMENT_TYPE_ST 0x02
301 #define ELEMENT_TYPE_IE 0x03
302 #define ELEMENT_TYPE_DT 0x04
305 * Device capabilities page.
307 * This page defines characteristics of the element types in the
308 * medium changer device.
310 * Note in the definitions below, the following abbreviations are
312 * MT Medium transport element (picker)
313 * ST Storage transport element (slot)
314 * IE Import/export element (portal)
315 * DT Data transfer element (tape/disk drive)
317 struct page_device_capabilities
{
318 u_int8_t pg_code
; /* page code (0x1f) */
319 u_int8_t pg_length
; /* page length (0x12) */
322 * The STOR_xx bits indicate that an element of a given
323 * type may provide independent storage for a unit of
324 * media. The top four bits of this value are reserved.
335 * The MOVE_TO_yy bits indicate the changer supports
336 * moving a unit of medium from an element of a given type to an
337 * element of type yy. This is used to determine if a given
338 * MOVE MEDIUM command is legal. The top four bits of each
339 * of these values are reserved.
341 u_int8_t move_from_mt
;
342 u_int8_t move_from_st
;
343 u_int8_t move_from_ie
;
344 u_int8_t move_from_dt
;
345 #define MOVE_TO_MT 0x01
346 #define MOVE_TO_ST 0x02
347 #define MOVE_TO_IE 0x04
348 #define MOVE_TO_DT 0x08
350 u_int8_t reserved1
[4];
353 * Similar to above, but for EXCHANGE MEDIUM.
355 u_int8_t exchange_with_mt
;
356 u_int8_t exchange_with_st
;
357 u_int8_t exchange_with_ie
;
358 u_int8_t exchange_with_dt
;
359 #define EXCHANGE_WITH_MT 0x01
360 #define EXCHANGE_WITH_ST 0x02
361 #define EXCHANGE_WITH_IE 0x04
362 #define EXCHANGE_WITH_DT 0x08
366 * Medium changer element address assignment page.
368 * Some of these fields can be a little confusing, so an explanation
371 * Each component within a a medium changer apparatus is called an
374 * The "medium transport element address" is the address of the first
375 * picker (robotic arm). "Number of medium transport elements" tells
376 * us how many pickers exist in the changer.
378 * The "first storage element address" is the address of the first
379 * slot in the tape or disk magazine. "Number of storage elements" tells
380 * us how many slots exist in the changer.
382 * The "first import/export element address" is the address of the first
383 * medium portal accessible both by the medium changer and an outside
384 * human operator. This is where the changer might deposit tapes destined
385 * for some vault. The "number of import/export elements" tells us
386 * not many of these portals exist in the changer. NOTE: this number may
389 * The "first data transfer element address" is the address of the first
390 * tape or disk drive in the changer. "Number of data transfer elements"
391 * tells us how many drives exist in the changer.
393 struct page_element_address_assignment
{
394 u_int8_t pg_code
; /* page code (0x1d) */
395 u_int8_t pg_length
; /* page length (0x12) */
397 /* Medium transport element address */
400 /* Number of medium transport elements */
403 /* First storage element address */
406 /* Number of storage elements */
409 /* First import/export element address */
412 /* Number of import/export elements */
415 /* First data transfer element address */
418 /* Number of data transfer elements */
421 u_int8_t reserved
[2];
425 * Transport geometry parameters page.
427 * Defines whether each medium transport element is a member of a set of
428 * elements that share a common robotics subsystem and whether the element
429 * is capable of media rotation. One transport geometry descriptor is
430 * transferred for each medium transport element, beginning with the first
431 * medium transport element (other than the default transport element address
434 struct page_transport_geometry_parameters
{
435 u_int8_t pg_code
; /* page code (0x1e) */
436 u_int8_t pg_length
; /* page length; variable */
438 /* Transport geometry descriptor(s) are here. */
441 #define CAN_ROTATE 0x01
443 /* Member number in transport element set. */