Merge Jason Thorpe's updated changer stuff into the actual system.

Many things have been changing in the kernel since mid-1996, so there's
quite some amount of diffs here already.  It compiles, but i cannot
test it anywhere here.

2.2 candidate?

Closes PR # 1201.
This commit is contained in:
Joerg Wunsch 1997-03-06 15:36:45 +00:00
parent a88f199c80
commit f357773315
4 changed files with 1130 additions and 549 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,54 @@
/*
* Copyright (c) 1996 Jason R. Thorpe <thorpej@and.com>
* All rights reserved.
*
* Partially based on an autochanger driver written by Stefan Grefen
* and on an autochanger driver written by the Systems Programming Group
* at the University of Utah Computer Science Department.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgements:
* This product includes software developed by Jason R. Thorpe
* for And Communications, http://www.and.com/
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: scsi_changer.h,v 1.9 1997/02/22 09:44:29 peter Exp $
*/
/*
* SCSI changer interface description
*/
/*
* Written by Stefan Grefen (grefen@goofy.zdv.uni-mainz.de soon grefen@convex.com)
* Partially derived from software written by Stefan Grefen
* (grefen@goofy.zdv.uni-mainz.de soon grefen@convex.com)
* based on the SCSI System by written Julian Elischer (julian@tfs.com)
* for TRW Financial Systems.
*
* TRW Financial Systems, in accordance with their agreement with Carnegie
* Mellon University, makes this software available to CMU to distribute
* or use in any manner that they see fit as long as this message is kept with
* or use in any manner that they see fit as long as this message is kept with
* the software. For this reason TFS also grants any other persons or
* organisations permission to use or modify this software.
*
@ -18,81 +57,344 @@
* functioning of this software in any circumstances.
*
* Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
*
* $Id$
*/
#ifndef _SCSI_SCSI_CHANGER_H
#define _SCSI_SCSI_CHANGER_H 1
/*
* SCSI command format
*/
struct scsi_read_element_status
{
u_char op_code;
u_char byte2;
#define SRES_ELEM_TYPE_CODE 0x0F
#define SRES_ELEM_VOLTAG 0x10
u_char starting_element_addr[2];
u_char number_of_elements[2];
u_char resv1;
u_char allocation_length[3];
u_char resv2;
u_char control;
};
#define RE_ALL_ELEMENTS 0
#define RE_MEDIUM_TRANSPORT_ELEMENT 1
#define RE_STORAGE_ELEMENT 2
#define RE_IMPORT_EXPORT 3
#define RE_DATA_TRANSFER_ELEMENT 4
struct scsi_move_medium
{
u_char op_code;
u_char byte2;
u_char transport_element_address[2];
u_char source_address[2];
u_char destination_address[2];
u_char rsvd[2];
u_char invert;
u_char control;
};
struct scsi_position_to_element
{
u_char op_code;
u_char byte2;
u_char transport_element_address[2];
u_char source_address[2];
u_char rsvd[2];
u_char invert;
u_char control;
/*
* Exchange the medium in the source element with the medium
* located at the destination element.
*/
struct scsi_exchange_medium {
u_int8_t opcode;
#define EXCHANGE_MEDIUM 0xa6
u_int8_t byte2;
u_int8_t tea[2]; /* transport element address */
u_int8_t src[2]; /* source address */
u_int8_t fdst[2]; /* first destination address */
u_int8_t sdst[2]; /* second destination address */
u_int8_t flags;
#define EXCHANGE_MEDIUM_INV1 0x01
#define EXCHANGE_MEDIUM_INV2 0x02
u_int8_t control;
};
/*
* Opcodes
* Cause the medium changer to check all elements for medium and any
* other status relevant to the element.
*/
#define POSITION_TO_ELEMENT 0x2b
#define MOVE_MEDIUM 0xa5
#define READ_ELEMENT_STATUS 0xb8
struct scsi_element_status_data
{
u_char first_element_reported[2];
u_char number_of_elements_reported[2];
u_char rsvd;
u_char byte_count_of_report[3];
struct scsi_initialize_elememt_status {
u_int8_t opcode;
#define INITIALIZE_ELEMENT_STATUS 0x07
u_int8_t byte2;
u_int8_t reserved[3];
u_int8_t control;
};
struct element_status_page
{
u_char element_type_code;
u_char flags;
#define ESP_AVOLTAG 0x40
#define ESP_PVOLTAG 0x80
u_char element_descriptor_length[2];
u_char rsvd;
u_char byte_count_of_descriptor_data[3];
/*
* Request the changer to move a unit of media from the source element
* to the destination element.
*/
struct scsi_move_medium {
u_int8_t opcode;
#define MOVE_MEDIUM 0xa5
u_int8_t byte2;
u_int8_t tea[2]; /* transport element address */
u_int8_t src[2]; /* source element address */
u_int8_t dst[2]; /* destination element address */
u_int8_t reserved[2];
u_int8_t flags;
#define MOVE_MEDIUM_INVERT 0x01
u_int8_t control;
};
#endif /*_SCSI_SCSI_CHANGER_H*/
/*
* Position the specified transport element (picker) in front of
* the destination element specified.
*/
struct scsi_position_to_element {
u_int8_t opcode;
#define POSITION_TO_ELEMENT 0x2b
u_int8_t byte2;
u_int8_t tea[2]; /* transport element address */
u_int8_t dst[2]; /* destination element address */
u_int8_t reserved[2];
u_int8_t flags;
#define POSITION_TO_ELEMENT_INVERT 0x01
u_int8_t control;
};
/*
* Request that the changer report the status of its internal elements.
*/
struct scsi_read_element_status {
u_int8_t opcode;
#define READ_ELEMENT_STATUS 0xb8
u_int8_t byte2;
#define READ_ELEMENT_STATUS_VOLTAG 0x10 /* report volume tag info */
/* ...next 4 bits are an element type code... */
u_int8_t sea[2]; /* starting element address */
u_int8_t count[2]; /* number of elements */
u_int8_t reserved0;
u_int8_t len[3]; /* length of data buffer */
u_int8_t reserved1;
u_int8_t control;
};
struct scsi_request_volume_element_address {
u_int8_t opcode;
#define REQUEST_VOLUME_ELEMENT_ADDRESS 0xb5
u_int8_t byte2;
#define REQUEST_VOLUME_ELEMENT_ADDRESS_VOLTAG 0x10
/* ...next 4 bits are an element type code... */
u_int8_t eaddr[2]; /* element address */
u_int8_t count[2]; /* number of elements */
u_int8_t reserved0;
u_int8_t len[3]; /* length of data buffer */
u_int8_t reserved1;
u_int8_t control;
};
/* XXX scsi_release */
/*
* Data returned by READ ELEMENT STATUS consists of an 8-byte header
* followed by one or more read_element_status_pages.
*/
struct read_element_status_header {
u_int8_t fear[2]; /* first element address reported */
u_int8_t count[2]; /* number of elements available */
u_int8_t reserved;
u_int8_t nbytes[3]; /* byte count of all pages */
};
struct read_element_status_page_header {
u_int8_t type; /* element type code; see type codes below */
u_int8_t flags;
#define READ_ELEMENT_STATUS_AVOLTAG 0x40
#define READ_ELEMENT_STATUS_PVOLTAG 0x80
u_int8_t edl[2]; /* element descriptor length */
u_int8_t reserved;
u_int8_t nbytes[3]; /* byte count of all descriptors */
};
struct read_element_status_descriptor {
u_int8_t eaddr[2]; /* element address */
u_int8_t flags1;
#define READ_ELEMENT_STATUS_FULL 0x01
#define READ_ELEMENT_STATUS_IMPEXP 0x02
#define READ_ELEMENT_STATUS_EXCEPT 0x04
#define READ_ELEMENT_STATUS_ACCESS 0x08
#define READ_ELEMENT_STATUS_EXENAB 0x10
#define READ_ELEMENT_STATUS_INENAB 0x20
#define READ_ELEMENT_STATUS_MT_MASK1 0x05
#define READ_ELEMENT_STATUS_ST_MASK1 0x0c
#define READ_ELEMENT_STATUS_IE_MASK1 0x3f
#define READ_ELEMENT_STATUS_DT_MASK1 0x0c
u_int8_t reserved0;
u_int8_t sense_code;
u_int8_t sense_qual;
/*
* dt_scsi_flags and dt_scsi_addr are valid only on data transport
* elements. These bytes are undefined for all other element types.
*/
u_int8_t dt_scsi_flags;
#define READ_ELEMENT_STATUS_DT_LUNMASK 0x07
#define READ_ELEMENT_STATUS_DT_LUVALID 0x10
#define READ_ELEMENT_STATUS_DT_IDVALID 0x20
#define READ_ELEMENT_STATUS_DT_NOTBUS 0x80
u_int8_t dt_scsi_addr;
u_int8_t reserved1;
u_int8_t flags2;
#define READ_ELEMENT_STATUS_INVERT 0x40
#define READ_ELEMENT_STATUS_SVALID 0x80
u_int8_t ssea[2]; /* source storage element address */
/*
* bytes 12-47: Primary volume tag information.
* (field omitted if PVOLTAG = 0)
*
* bytes 48-83: Alternate volume tag information.
* (field omitted if AVOLTAG = 0)
*
* bytes 84-87: Reserved (moved up if either of the above fields
* are omitted)
*
* bytes 88-end: Vendor-specific: (moved up if either of the
* above fields are missing)
*/
};
/* XXX add data returned by REQUEST VOLUME ELEMENT ADDRESS */
/* Element type codes */
#define ELEMENT_TYPE_MASK 0x0f /* Note: these aren't bits */
#define ELEMENT_TYPE_ALL 0x00
#define ELEMENT_TYPE_MT 0x01
#define ELEMENT_TYPE_ST 0x02
#define ELEMENT_TYPE_IE 0x03
#define ELEMENT_TYPE_DT 0x04
/*
* XXX The following definitions should be common to all SCSI device types.
*/
#define PGCODE_MASK 0x3f /* valid page number bits in pg_code */
#define PGCODE_PS 0x80 /* indicates page is savable */
/*
* Device capabilities page.
*
* This page defines characteristics of the elemenet types in the
* medium changer device.
*
* Note in the definitions below, the following abbreviations are
* used:
* MT Medium transport element (picker)
* ST Storage transport element (slot)
* IE Import/export element (portal)
* DT Data tranfer element (tape/disk drive)
*/
struct page_device_capabilities {
u_int8_t pg_code; /* page code (0x1f) */
u_int8_t pg_length; /* page length (0x12) */
/*
* The STOR_xx bits indicate that an element of a given
* type may provide independent storage for a unit of
* media. The top four bits of this value are reserved.
*/
u_int8_t stor;
#define STOR_MT 0x01
#define STOR_ST 0x02
#define STOR_IE 0x04
#define STOR_DT 0x08
u_int8_t reserved0;
/*
* The MOVE_TO_yy bits indicate the changer supports
* moving a unit of medium from an element of a given type to an
* element of type yy. This is used to determine if a given
* MOVE MEDIUM command is legal. The top four bits of each
* of these values are reserved.
*/
u_int8_t move_from_mt;
u_int8_t move_from_st;
u_int8_t move_from_ie;
u_int8_t move_from_dt;
#define MOVE_TO_MT 0x01
#define MOVE_TO_ST 0x02
#define MOVE_TO_IE 0x04
#define MOVE_TO_DT 0x08
u_int8_t reserved1[2];
/*
* Similar to above, but for EXCHANGE MEDIUM.
*/
u_int8_t exchange_with_mt;
u_int8_t exchange_with_st;
u_int8_t exchange_with_ie;
u_int8_t exchange_with_dt;
#define EXCHANGE_WITH_MT 0x01
#define EXCHANGE_WITH_ST 0x02
#define EXCHANGE_WITH_IE 0x04
#define EXCHANGE_WITH_DT 0x08
};
/*
* Medium changer elemement address assignment page.
*
* Some of these fields can be a little confusing, so an explanation
* is in order.
*
* Each component within a a medium changer apparatus is called an
* "element".
*
* The "medium transport element address" is the address of the first
* picker (robotic arm). "Number of medium transport elements" tells
* us how many pickers exist in the changer.
*
* The "first storage element address" is the address of the first
* slot in the tape or disk magazine. "Number of storage elements" tells
* us how many slots exist in the changer.
*
* The "first import/export element address" is the address of the first
* medium portal accessible both by the medium changer and an outside
* human operator. This is where the changer might deposit tapes destined
* for some vault. The "number of import/export elements" tells us
* not many of these portals exist in the changer. NOTE: this number may
* be 0.
*
* The "first data transfer element address" is the address of the first
* tape or disk drive in the changer. "Number of data transfer elements"
* tells us how many drives exist in the changer.
*/
struct page_element_address_assignment {
u_int8_t pg_code; /* page code (0x1d) */
u_int8_t pg_length; /* page length (0x12) */
/* Medium transport element address */
u_int8_t mtea[2];
/* Number of medium transport elements */
u_int8_t nmte[2];
/* First storage element address */
u_int8_t fsea[2];
/* Number of storage elements */
u_int8_t nse[2];
/* First import/export element address */
u_int8_t fieea[2];
/* Number of import/export elements */
u_int8_t niee[2];
/* First data transfer element address */
u_int8_t fdtea[2];
/* Number of data trafer elements */
u_int8_t ndte[2];
u_int8_t reserved[2];
};
/*
* Transport geometry parameters page.
*
* Defines whether each medium transport element is a member of a set of
* elements that share a common robotics subsystem and whether the element
* is capable of media rotation. One transport geometry descriptor is
* transferred for each medium transport element, beginning with the first
* medium transport element (other than the default transport element address
* of 0).
*/
struct page_transport_geometry_parameters {
u_int8_t pg_code; /* page code (0x1e) */
u_int8_t pg_length; /* page length; variable */
/* Transport geometry descriptor(s) are here. */
u_int8_t misc;
#define CAN_ROTATE 0x01
/* Member number in transport element set. */
u_int8_t member;
};
#endif /* _SCSI_SCSI_CHANGER_H */

View File

@ -16,7 +16,7 @@
*
* New configuration setup: dufault@hda.com
*
* $Id$
* $Id: scsiconf.c,v 1.79 1997/02/22 09:44:34 peter Exp $
*/
#include "opt_scsi.h"
@ -309,7 +309,23 @@ static struct scsidevs knowndevs[] =
T_SEQUENTIAL, T_SEQUENTIAL, T_REMOV, "HP", "C1553A", "*",
"st", SC_MORE_LUS, 0
},
{
T_SEQUENTIAL, T_SEQUENTIAL, T_REMOV, "ARCHIVE", "Python 28849-*", "*",
"st", SC_MORE_LUS, 0
},
#endif /* NST */
#if NCH > 0
/*
* The <ARCHIVE, Python 28849-XXX, 4.98> is a SCSI changer device
* with an Archive Python DAT drive built-in. The tape appears
* at LUN 0 and the changer at LUN 1.
* This entry should not be needed at all.
*/
{
T_CHANGER, T_CHANGER, T_REMOV, "ARCHIVE", "Python 28849-*", "*",
"ch", SC_MORE_LUS
},
#endif /* NCH */
#if NCD > 0
#ifndef UKTEST /* make cdroms unrecognised to test the uk driver */
/*
@ -411,9 +427,15 @@ static struct scsidevs knowndevs[] =
},
#endif /* NST */
#if NCH > 0
/*
* Due to the way media changers are working, they are most
* likely always on a different LUN than the transfer element
* device. Thus, it should be safe to always probe all LUNs
* on them.
*/
{
T_CHANGER, T_CHANGER, T_REMOV, "*", "*", "*",
"ch", SC_ONE_LU
"ch", SC_MORE_LUS
},
#endif /* NCH */
#if NCD > 0 && !defined(UKTEST)

View File

@ -1,98 +1,151 @@
/*
* 16 Feb 93 Julian Elischer ADDED for SCSI system
* Copyright (c) 1996 Jason R. Thorpe <thorpej@and.com>
* All rights reserved.
*
* $Id$
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgements:
* This product includes software developed by Jason R. Thorpe
* for And Communications, http://www.and.com/
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: chio.h,v 1.9 1997/02/22 09:44:56 peter Exp $
*/
/* This is a "converted" mtio.h from 386BSD
Stefan Grefen grefen@goofy.zdv.uni-mainz.de
*/
#ifndef _SYS_CHIO_H_
#define _SYS_CHIO_H_
/*
* Structures and definitions for changer io control commands
* Element types. Used as "to" and "from" type indicators in move
* and exchange operations.
*
* Note that code in sys/scsi/ch.c relies on these values (uses them
* as offsets in an array, and other evil), so don't muck with them
* unless you know what you're doing.
*/
#define CHET_MT 0 /* medium transport (picker) */
#define CHET_ST 1 /* storage transport (slot) */
#define CHET_IE 2 /* import/export (portal) */
#define CHET_DT 3 /* data transfer (drive) */
#ifndef _SYS_CHIO_H_
#define _SYS_CHIO_H_
#ifndef KERNEL
#include <sys/types.h>
#endif
#include <sys/ioccom.h>
#define CH_INVERT 0x10000
#define CH_ADDR_MASK 0xffff
struct chop {
short ch_op; /* operations defined below */
short result; /* The result */
union {
struct {
int chm; /* Transport element */
int from;
int to;
} move;
struct {
int chm; /* Transport element */
int to;
} position;
struct {
short chmo; /* Offset of first CHM */
short chms; /* No. of CHM */
short slots; /* No. of Storage Elements */
short sloto; /* Offset of first SE */
short imexs; /* No. of Import/Export Slots */
short imexo; /* Offset of first IM/EX */
short drives; /* No. of CTS */
short driveo; /* Offset of first CTS */
short rot; /* CHM can rotate */
} getparam;
struct {
int type;
#define CH_CHM 1
#define CH_STOR 2
#define CH_IMEX 3
#define CH_CTS 4
int from;
struct {
u_char elema_1;
u_char elema_0;
u_char full:1;
u_char rsvd:1;
u_char except:1;
u_char :5;
u_char rsvd2;
union {
struct {
u_char add_sense_code;
u_char add_sense_code_qualifier;
} specs;
short add_sense;
/* WARNING LSB only */
#define CH_CHOLDER 0x0290 /* Cartridge holder is missing */
#define CH_STATUSQ 0x0390 /* Status is questionable */
#define CH_CTS_CLOSED 0x0490 /* CTS door is closed */
} ch_add_sense;
u_char rsvd3[3];
u_char :6;
u_char invert:1;
u_char svalid:1;
u_char source_1;
u_char source_0;
u_char rsvd4[4];
} elem_data;
} get_elem_stat;
} u;
/*
* Structure used to execute a MOVE MEDIUM command.
*/
struct changer_move {
int cm_fromtype; /* element type to move from */
int cm_fromunit; /* logical unit of from element */
int cm_totype; /* element type to move to */
int cm_tounit; /* logical unit of to element */
int cm_flags; /* misc. flags */
};
/* operations */
#define CHMOVE 1
#define CHPOSITION 2
#define CHGETPARAM 3
#define CHGETELEM 4
/* cm_flags */
#define CM_INVERT 0x01 /* invert media */
/*
* Structure used to execute an EXCHANGE MEDIUM command. In an
* exchange operation, the following steps occur:
*
* - media from source is moved to first destination.
*
* - media previously occupying first destination is moved
* to the second destination.
*
* The second destination may or may not be the same as the source.
* In the case of a simple exchange, the source and second destination
* are the same.
*/
struct changer_exchange {
int ce_srctype; /* element type of source */
int ce_srcunit; /* logical unit of source */
int ce_fdsttype; /* element type of first destination */
int ce_fdstunit; /* logical unit of first destination */
int ce_sdsttype; /* element type of second destination */
int ce_sdstunit; /* logical unit of second destination */
int ce_flags; /* misc. flags */
};
/* Changer IO control command */
#define CHIOOP _IOWR('c', 1, struct chop) /* do a mag tape op */
/* ce_flags */
#define CE_INVERT1 0x01 /* invert media 1 */
#define CE_INVERT2 0x02 /* invert media 2 */
#endif /* !_SYS_CHIO_H_ */
/*
* Structure used to execute a POSITION TO ELEMENT command. This
* moves the current picker in front of the specified element.
*/
struct changer_position {
int cp_type; /* element type */
int cp_unit; /* logical unit of element */
int cp_flags; /* misc. flags */
};
/* cp_flags */
#define CP_INVERT 0x01 /* invert picker */
/*
* Data returned by CHIOGPARAMS.
*/
struct changer_params {
int cp_curpicker; /* current picker */
int cp_npickers; /* number of pickers */
int cp_nslots; /* number of slots */
int cp_nportals; /* number of import/export portals */
int cp_ndrives; /* number of drives */
};
/*
* Command used to get element status.
*/
struct changer_element_status {
int ces_type; /* element type */
u_int8_t *ces_data; /* pre-allocated data storage */
};
/*
* Data returned by CHIOGSTATUS is an array of flags bytes.
* Not all flags have meaning for all element types.
*/
#define CESTATUS_FULL 0x01 /* element is full */
#define CESTATUS_IMPEXP 0x02 /* media deposited by operator */
#define CESTATUS_EXCEPT 0x04 /* element in abnormal state */
#define CESTATUS_ACCESS 0x08 /* media accessible by picker */
#define CESTATUS_EXENAB 0x10 /* element supports exporting */
#define CESTATUS_INENAB 0x20 /* element supports importing */
#define CESTATUS_PICKER_MASK 0x05 /* flags valid for pickers */
#define CESTATUS_SLOT_MASK 0x0c /* flags valid for slots */
#define CESTATUS_PORTAL_MASK 0x3f /* flags valid for portals */
#define CESTATUS_DRIVE_MASK 0x0c /* flags valid for drives */
#define CESTATUS_BITS \
"\20\6INEAB\5EXENAB\4ACCESS\3EXCEPT\2IMPEXP\1FULL"
#define CHIOMOVE _IOW('c', 0x01, struct changer_move)
#define CHIOEXCHANGE _IOW('c', 0x02, struct changer_exchange)
#define CHIOPOSITION _IOW('c', 0x03, struct changer_position)
#define CHIOGPICKER _IOR('c', 0x04, int)
#define CHIOSPICKER _IOW('c', 0x05, int)
#define CHIOGPARAMS _IOR('c', 0x06, struct changer_params)
#define CHIOGSTATUS _IOW('c', 0x08, struct changer_element_status)
#endif /* _SYS_CHIO_H_ */