1 /*        $NetBSD: chio.h,v 1.13 2015/09/06 06:01:02 dholland Exp $   */
2 
3 /*-
4  * Copyright (c) 1996, 1999 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9  * NASA Ames Research Center.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
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  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #ifndef _SYS_CHIO_H_
34 #define _SYS_CHIO_H_
35 
36 #include <sys/ioccom.h>
37 
38 /*
39  * Element types.  Used as "to" and "from" type indicators in move
40  * and exchange operations.
41  *
42  * Note that code in sys/dev/scsipi/ch.c relies on these values (uses
43  * them as offsets in an array, and other evil), so don't muck with them
44  * unless you know what you're doing.
45  */
46 #define CHET_MT               0         /* medium transport (picker) */
47 #define CHET_ST               1         /* storage transport (slot) */
48 #define CHET_IE               2         /* import/export (portal) */
49 #define CHET_DT               3         /* data transfer (drive) */
50 
51 /*
52  * Structure used to execute a MOVE MEDIUM command.
53  */
54 struct changer_move_request {
55           int       cm_fromtype;        /* element type to move from */
56           int       cm_fromunit;        /* logical unit of from element */
57           int       cm_totype;          /* element type to move to */
58           int       cm_tounit;          /* logical unit of to element */
59           int       cm_flags; /* misc. flags */
60 };
61 
62 /* cm_flags */
63 #define CM_INVERT   0x01      /* invert media */
64 
65 /*
66  * Structure used to execute an EXCHANGE MEDIUM command.  In an
67  * exchange operation, the following steps occur:
68  *
69  *        - media from source is moved to first destination.
70  *
71  *        - media previously occupying first destination is moved
72  *          to the second destination.
73  *
74  * The second destination may or may not be the same as the source.
75  * In the case of a simple exchange, the source and second destination
76  * are the same.
77  */
78 struct changer_exchange_request {
79           int       ce_srctype;         /* element type of source */
80           int       ce_srcunit;         /* logical unit of source */
81           int       ce_fdsttype;        /* element type of first destination */
82           int       ce_fdstunit;        /* logical unit of first destination */
83           int       ce_sdsttype;        /* element type of second destination */
84           int       ce_sdstunit;        /* logical unit of second destination */
85           int       ce_flags; /* misc. flags */
86 };
87 
88 /* ce_flags */
89 #define CE_INVERT1  0x01      /* invert media 1 */
90 #define CE_INVERT2  0x02      /* invert media 2 */
91 
92 /*
93  * Structure used to execute a POSITION TO ELEMENT command.  This
94  * moves the current picker in front of the specified element.
95  */
96 struct changer_position_request {
97           int       cp_type;  /* element type */
98           int       cp_unit;  /* logical unit of element */
99           int       cp_flags; /* misc. flags */
100 };
101 
102 /* cp_flags */
103 #define CP_INVERT   0x01      /* invert picker */
104 
105 /*
106  * Data returned by CHIOGPARAMS.
107  */
108 struct changer_params {
109           int       cp_curpicker;       /* current picker */
110           int       cp_npickers;        /* number of pickers */
111           int       cp_nslots;          /* number of slots */
112           int       cp_nportals;        /* number of import/export portals */
113           int       cp_ndrives;         /* number of drives */
114 };
115 
116 /*
117  * Old-style command used to get element status.
118  */
119 struct ochanger_element_status_request {
120           int       cesr_type;          /* element type */
121           uint8_t *cesr_data; /* pre-allocated data storage */
122 };
123 
124 /*
125  * Structure of a changer volume tag.
126  */
127 #define   CHANGER_VOLTAG_SIZE 32        /* same as SCSI voltag size */
128 struct changer_voltag {
129           char      cv_tag[CHANGER_VOLTAG_SIZE + 1];        /* ASCII tag */
130           uint16_t cv_serial;                               /* serial number */
131 };
132 
133 /*
134  * Data returned by CHIOGSTATUS.
135  */
136 struct changer_element_status {
137           int       ces_flags;          /* CESTATUS_* flags; see below */
138 
139           /*
140            * The following is only valid on Data Transport elements (drives).
141            */
142           char      ces_xname[16];      /* external name of drive device */
143 
144           /*
145            * The following fieds indicate the element the medium was
146            * moved from in order to arrive in this element.
147            */
148           int       ces_from_type;      /* type of element */
149           int       ces_from_unit;      /* logical unit of element */
150 
151           /*
152            * Volume tag information.
153            */
154           struct changer_voltag ces_pvoltag;      /* primary volume tag */
155           struct changer_voltag ces_avoltag;      /* alternate volume tag */
156 
157           size_t    ces_vendor_len;     /* length of any vendor-specific data */
158 
159           /*
160            * These two fields are only valid if CESTATUS_EXCEPT is
161            * set in ces_flags, and are only valid on SCSI changers.
162            */
163           uint8_t ces_asc;    /* Additional Sense Code */
164           uint8_t ces_ascq;   /* Additional Sense Code Qualifier */
165 
166           /*
167            * These two fields may be useful if ces_xname is not valid.
168            * They indicate the target and lun of a drive element.  These
169            * are only valid on SCSI changers.
170            */
171           uint8_t ces_target; /* SCSI target of drive */
172           uint8_t ces_lun;    /* SCSI LUN of drive */
173 };
174 
175 /*
176  * Flags for changer_element_status.  These are flags that are returned
177  * by hardware.  Not all flags have meaning for all element types.
178  */
179 #define CESTATUS_FULL                   0x0001    /* element is full */
180 #define CESTATUS_IMPEXP                 0x0002    /* media deposited by operator */
181 #define CESTATUS_EXCEPT                 0x0004    /* element in abnormal state */
182 #define CESTATUS_ACCESS                 0x0008    /* media accessible by picker */
183 #define CESTATUS_EXENAB                 0x0010    /* element supports exporting */
184 #define CESTATUS_INENAB                 0x0020    /* element supports importing */
185 
186 #define CESTATUS_PICKER_MASK  0x0005    /* flags valid for pickers */
187 #define CESTATUS_SLOT_MASK    0x000c    /* flags valid for slots */
188 #define CESTATUS_PORTAL_MASK  0x003f    /* flags valid for portals */
189 #define CESTATUS_DRIVE_MASK   0x000c    /* flags valid for drives */
190 
191 #define   CESTATUS_INVERTED   0x0040    /* medium inverted from storage */
192 #define   CESTATUS_NOTBUS               0x0080    /* drive not on same bus as changer */
193 
194 /*
195  * These changer_element_status flags indicate the validity of fields
196  * in the returned data.
197  */
198 #define   CESTATUS_STATUS_VALID         0x0100    /* entire structure valid */
199 #define   CESTATUS_XNAME_VALID          0x0200    /* ces_xname valid */
200 #define   CESTATUS_FROM_VALID 0x0400    /* ces_from_* valid */
201 #define   CESTATUS_PVOL_VALID 0x0800    /* ces_pvoltag valid */
202 #define   CESTATUS_AVOL_VALID 0x1000    /* ces_avoltag valid */
203 #define   CESTATUS_TARGET_VALID         0x2000    /* ces_target valid */
204 #define   CESTATUS_LUN_VALID  0x4000    /* ces_lun valid */
205 
206 #define CESTATUS_BITS         \
207           "\20\6INEAB\5EXENAB\4ACCESS\3EXCEPT\2IMPEXP\1FULL"
208 
209 /*
210  * Command used to get element status.
211  */
212 struct changer_element_status_request {
213           int       cesr_type;          /* element type */
214           int       cesr_unit;          /* start at this unit */
215           int       cesr_count;         /* for this many units */
216           int       cesr_flags;         /* flags; see below */
217                                         /* pre-allocated data storage */
218           /*
219            * These fields point to the data to be returned to the
220            * user:
221            *
222            *        cesr_deta: pointer to array of cesr_count status descriptors
223            *
224            *        cesr_vendor_data: pointer to array of void *'s which point
225            *        to pre-allocated areas for vendor-specific data.  Optional.
226            */
227           struct changer_element_status *cesr_data;
228           void      **cesr_vendor_data;
229 };
230 
231 #define   CESR_VOLTAGS                  0x01      /* request volume tags */
232 
233 /*
234  * Command used to modify a media element's volume tag.
235  */
236 struct changer_set_voltag_request {
237           int       csvr_type;          /* element type */
238           int       csvr_unit;          /* unit to modify */
239           int       csvr_flags;         /* flags; see below */
240                                         /* the actual volume tag; ignored if clearing
241                                            the tag */
242           struct changer_voltag csvr_voltag;
243 };
244 
245 #define   CSVR_MODE_SET                 0x00      /* set volume tag if not set */
246 #define   CSVR_MODE_REPLACE   0x01      /* unconditionally replace volume tag */
247 #define   CSVR_MODE_CLEAR               0x02      /* clear volume tag */
248 #define   CSVR_MODE_MASK                0x0f
249 #define   CSVR_ALTERNATE                0x10      /* modify alternate volume tag */
250 
251 /*
252  * Changer events.
253  *
254  * When certain events occur, the kernel can indicate this by setting
255  * a bit in a bitmask.
256  *
257  * When a read is issued to the changer, the kernel returns this event
258  * bitmask.  The read never blocks; if no events are pending, the bitmask
259  * will be all-clear.
260  *
261  * A process may select for read to wait for an event to occur.
262  *
263  * The event mask is cleared when the changer is closed.
264  */
265 #define   CHANGER_EVENT_SIZE            sizeof(u_int)
266 #define   CHEV_ELEMENT_STATUS_CHANGED   0x00000001
267 
268 /*
269  * ioctls applicable to changers.
270  */
271 #define CHIOMOVE    _IOW('c', 0x01, struct changer_move_request)
272 #define CHIOEXCHANGE          _IOW('c', 0x02, struct changer_exchange_request)
273 #define CHIOPOSITION          _IOW('c', 0x03, struct changer_position_request)
274 #define CHIOGPICKER _IOR('c', 0x04, int)
275 #define CHIOSPICKER _IOW('c', 0x05, int)
276 #define CHIOGPARAMS _IOR('c', 0x06, struct changer_params)
277 #define CHIOIELEM    _IO('c', 0x07)
278 #define OCHIOGSTATUS          _IOW('c', 0x08, struct ochanger_element_status_request)
279 #define   CHIOGSTATUS         _IOW('c', 0x09, struct changer_element_status_request)
280 #define   CHIOSVOLTAG         _IOW('c', 0x0a, struct changer_set_voltag_request)
281 
282 #endif /* _SYS_CHIO_H_ */
283