Imported Upstream version 1.2.16rel
[debian/mtx] / mtx.h
1 /* MTX -- SCSI Tape Attached Medium Control Program
2
3    Copyright 1997-1998 Leonard N. Zubkoff <lnz@dandelion.com>
4  
5    Changes 1999 Eric Lee Green to add support for multi-drive tape changers.
6
7    $Date: 2001/06/19 21:51:32 $
8    $Revision: 1.3 $
9    See mtx.c for licensing information. 
10
11 */
12
13 #ifndef MTX_H  /* protect against multiple includes... */
14 #define MTX_H 1
15
16 /* surround all the Unix-stuff w/ifndef VMS */
17 #ifdef VMS
18 #include "[.vms]defs.h"
19 #else /* all the Unix stuff:  */
20
21 #include "config.h"  /* all the autoconf stuff. */
22
23 /* all the general Unix includes: */
24
25 #include <stdio.h>
26 #include <errno.h>
27
28 #if HAVE_STDLIB_H
29 #  include <stdlib.h>
30 #endif
31
32 #if HAVE_FCNTL_H
33 #  include <fcntl.h>
34 #endif
35
36 #if HAVE_SYS_TYPES_H
37 #  include <sys/types.h>
38 #endif
39
40 #if HAVE_STRING_H
41 # include <string.h>
42 #else
43 # include <strings.h>
44 #endif
45
46 #if HAVE_UNISTD_H
47 #  include <unistd.h>
48 #endif
49
50 #if HAVE_STDARG_H
51 #  include <stdarg.h>
52 #endif
53
54 #if HAVE_SYS_STAT_H
55 # include <sys/stat.h>
56 #endif
57
58 #if HAVE_SYS_IOCTL_H
59 #  include <sys/ioctl.h>
60 #endif
61
62 /* Now greately modified to use GNU Autoconf stuff: */
63 /* If we use the 'sg' interface, like Linux, do this: */
64 #if HAVE_SCSI_SG_H
65 #  include <scsi/scsi.h>
66 #  include <scsi/scsi_ioctl.h>
67 #  include <scsi/sg.h>
68 typedef int DEVICE_TYPE; /* the sg interface uses this. */
69 #  define HAVE_GET_ID_LUN 1  /* signal that we have it... */
70 #endif
71
72 /* The 'cam' interface, like FreeBSD: */
73 #if HAVE_CAMLIB_H
74 #  include <camlib.h> /* easy (?) access to the CAM user library. */
75 #  include <cam/cam_ccb.h>
76 #  include <cam/scsi/scsi_message.h> /* sigh sigh sigh! */
77 typedef struct cam_device *DEVICE_TYPE;
78 #endif
79
80
81 /* the 'uscsi' interface, as used on Solaris: */
82 #if HAVE_SYS_SCSI_IMPL_USCSI_H
83 #include <sys/scsi/impl/uscsi.h>
84 typedef int DEVICE_TYPE;
85 #endif
86
87 /* the scsi_ctl interface, as used on HP/UX: */
88 #if HAVE_SYS_SCSI_CTL_H
89 #  include <sys/wsio.h>
90 #  include <sys/spinlock.h>
91 #  include <sys/scsi.h>
92 #  include <sys/scsi_ctl.h>
93   typedef int DEVICE_TYPE;
94 #  ifndef VERSION
95 #     define VERSION "1.2.12 hbb"
96 #  endif
97 #endif
98
99
100 /* The 'tm_buf' interface, as used on AIX. */
101 #ifdef HAVE_SYS_SCSI_H
102 #include <sys/scsi.h>
103 #include <sys/scsi_buf.h>
104 #include <sys/devinfo.h> /* devinfo. */
105 typedef struct tm_device_type {
106   int filenum;
107   int id;
108   int lun;
109   char *DeviceName;
110 } *DEVICE_TYPE;
111     
112 #endif
113
114    /* the 'dslib' interface, as used on SGI.  */
115 #if HAVE_DSLIB_H
116 #include <dslib.h>
117 typedef dsreq_t *DEVICE_TYPE; /* 64-bit pointers/32bit int on later sgi? */
118 #endif
119
120
121 #if ((defined(__alpha) && defined(__osf__)) || \
122      defined(ultrix) || defined(__ultrix))
123 #include "du/defs.h"
124 #endif
125
126
127 #endif /* VMS protect. */
128
129 /* Do a test for LITTLE_ENDIAN_BITFIELDS. Use WORDS_BIGENDIAN as set
130  * by configure: 
131  */
132
133 #if WORDS_BIGENDIAN
134 # define BIG_ENDIAN_BITFIELDS
135 #else
136 # define LITTLE_ENDIAN_BITFIELDS
137 #endif
138
139 /* Get rid of some Hocky Pux defines: */
140 #ifdef S_NO_SENSE
141 #undef S_NO_SENSE
142 #endif
143 #ifdef S_RECOVERED_ERROR
144 #undef S_RECOVERED_ERROR
145 #endif
146 #ifdef S_NOT_READY
147 #undef S_NOT_READY
148 #endif
149 #ifdef S_MEDIUM_ERROR
150 #undef S_MEDIUM_ERROR
151 #endif
152 #ifdef S_HARDWARE_ERROR
153 #undef S_HARDWARE_ERROR
154 #endif
155 #ifdef S_UNIT_ATTENTION
156 #undef S_UNIT_ATTENTION
157 #endif
158 #ifdef S_BLANK_CHECK
159 #undef S_BLANK_CHECK
160 #endif
161 #ifdef S_VOLUME_OVERFLOW
162 #undef S_VOLUME_OVERFLOW
163 #endif
164
165 /* Note: These are only used for defaults for when we don't have 
166  * the element assignment mode page to tell us real amount...
167  */
168 #define MAX_STORAGE_ELEMENTS 64 /* for the BIG jukeboxes! */
169 #define MAX_TRANSFER_ELEMENTS 2  /* we just do dual-drive for now :-} */
170 #define MAX_TRANSPORT_ELEMENTS 1 /* we just do one arm for now... */
171
172 /* These are flags used for the READ_ELEMENT_STATUS and MOVE_MEDIUM
173  * commands:
174  */
175 typedef struct SCSI_Flags_Struct {
176   unsigned char eepos;
177   unsigned char invert;
178   unsigned char no_attached; /* ignore _attached bit */
179   unsigned char no_barcodes;  /* don't try to get barcodes. */
180   int numbytes;
181   int elementtype;
182   int numelements;
183   int attached;
184   int has_barcodes;
185 } SCSI_Flags_T;
186
187 typedef enum { false, true } boolean;
188
189
190 typedef enum { Input, Output } Direction_T;
191
192
193 typedef unsigned char CDB_T[12];
194
195
196 typedef struct Inquiry
197 {
198 #ifdef LITTLE_ENDIAN_BITFIELDS
199   unsigned char PeripheralDeviceType:5;                 /* Byte 0 Bits 0-4 */
200   unsigned char PeripheralQualifier:3;                  /* Byte 0 Bits 5-7 */
201   unsigned char DeviceTypeModifier:7;                   /* Byte 1 Bits 0-6 */
202   boolean RMB:1;                                        /* Byte 1 Bit 7 */
203   unsigned char ANSI_ApprovedVersion:3;                 /* Byte 2 Bits 0-2 */
204   unsigned char ECMA_Version:3;                         /* Byte 2 Bits 3-5 */
205   unsigned char ISO_Version:2;                          /* Byte 2 Bits 6-7 */
206   unsigned char ResponseDataFormat:4;                   /* Byte 3 Bits 0-3 */
207   unsigned char :2;                                     /* Byte 3 Bits 4-5 */
208   boolean TrmIOP:1;                                     /* Byte 3 Bit 6 */
209   boolean AENC:1;                                       /* Byte 3 Bit 7 */
210 #else
211   unsigned char PeripheralQualifier:3;                  /* Byte 0 Bits 5-7 */
212   unsigned char PeripheralDeviceType:5;                 /* Byte 0 Bits 0-4 */
213   boolean RMB:1;                                        /* Byte 1 Bit 7 */
214   unsigned char DeviceTypeModifier:7;                   /* Byte 1 Bits 0-6 */
215   unsigned char ISO_Version:2;                          /* Byte 2 Bits 6-7 */
216   unsigned char ECMA_Version:3;                         /* Byte 2 Bits 3-5 */
217   unsigned char ANSI_ApprovedVersion:3;                 /* Byte 2 Bits 0-2 */
218   boolean AENC:1;                                       /* Byte 3 Bit 7 */
219   boolean TrmIOP:1;                                     /* Byte 3 Bit 6 */
220   unsigned char :2;                                     /* Byte 3 Bits 4-5 */
221   unsigned char ResponseDataFormat:4;                   /* Byte 3 Bits 0-3 */
222 #endif
223   unsigned char AdditionalLength;                       /* Byte 4 */
224   unsigned char :8;                                     /* Byte 5 */
225 #ifdef LITTLE_ENDIAN_BITFIELDS
226   boolean ADDR16:1;                                    /* Byte 6 bit 0 */
227   boolean Obs6_1:1;                                    /* Byte 6 bit 1 */
228   boolean Obs6_2:1; /* obsolete */                     /* Byte 6 bit 2 */
229   boolean MChngr:1; /* Media Changer */                /* Byte 6 bit 3 */
230   boolean MultiP:1;                                    /* Byte 6 bit 4 */
231   boolean VS:1;                                        /* Byte 6 bit 5 */
232   boolean EncServ:1;                                   /* Byte 6 bit 6 */
233   boolean BQue:1;                                      /* Byte 6 bit 7 */
234 #else
235   boolean BQue:1;                                      /* Byte 6 bit 7 */
236   boolean EncServ:1;                                   /* Byte 6 bit 6 */
237   boolean VS:1;                                        /* Byte 6 bit 5 */
238   boolean MultiP:1;                                    /* Byte 6 bit 4 */
239   boolean MChngr:1; /* Media Changer */                /* Byte 6 bit 3 */
240   boolean Obs6_2:1; /* obsolete */                     /* Byte 6 bit 2 */
241   boolean Obs6_1:1;                                    /* Byte 6 bit 1 */
242   boolean ADDR16:1;                                    /* Byte 6 bit 0 */
243 #endif
244 #ifdef LITTLE_ENDIAN_BITFIELDS
245   boolean SftRe:1;                                      /* Byte 7 Bit 0 */
246   boolean CmdQue:1;                                     /* Byte 7 Bit 1 */
247   boolean :1;                                           /* Byte 7 Bit 2 */
248   boolean Linked:1;                                     /* Byte 7 Bit 3 */
249   boolean Sync:1;                                       /* Byte 7 Bit 4 */
250   boolean WBus16:1;                                     /* Byte 7 Bit 5 */
251   boolean WBus32:1;                                     /* Byte 7 Bit 6 */
252   boolean RelAdr:1;                                     /* Byte 7 Bit 7 */
253 #else
254   boolean RelAdr:1;                                     /* Byte 7 Bit 7 */
255   boolean WBus32:1;                                     /* Byte 7 Bit 6 */
256   boolean WBus16:1;                                     /* Byte 7 Bit 5 */
257   boolean Sync:1;                                       /* Byte 7 Bit 4 */
258   boolean Linked:1;                                     /* Byte 7 Bit 3 */
259   boolean :1;                                           /* Byte 7 Bit 2 */
260   boolean CmdQue:1;                                     /* Byte 7 Bit 1 */
261   boolean SftRe:1;                                      /* Byte 7 Bit 0 */
262 #endif
263   unsigned char VendorIdentification[8];                /* Bytes 8-15 */
264   unsigned char ProductIdentification[16];              /* Bytes 16-31 */
265   unsigned char ProductRevisionLevel[4];                /* Bytes 32-35 */
266   unsigned char FullProductRevisionLevel[19];           /* bytes 36-54 */
267   unsigned char VendorFlags;                            /* byte 55 */
268 }
269 Inquiry_T;
270
271 /* Hockey Pux may define these. If so, *UN*define them. */
272 #ifdef ILI
273 #undef ILI
274 #endif
275
276 #ifdef EOM
277 #undef EOM
278 #endif
279
280 typedef struct RequestSense
281 {
282 #ifdef LITTLE_ENDIAN_BITFIELDS
283   unsigned char ErrorCode:7;                            /* Byte 0 Bits 0-6 */
284   boolean Valid:1;                                      /* Byte 0 Bit 7 */
285 #else
286   boolean Valid:1;                                      /* Byte 0 Bit 7 */
287   unsigned char ErrorCode:7;                            /* Byte 0 Bits 0-6 */
288 #endif
289   unsigned char SegmentNumber;                          /* Byte 1 */
290 #ifdef LITTLE_ENDIAN_BITFIELDS
291   unsigned char SenseKey:4;                             /* Byte 2 Bits 0-3 */
292   unsigned char :1;                                     /* Byte 2 Bit 4 */
293   boolean ILI:1;                                        /* Byte 2 Bit 5 */
294   boolean EOM:1;                                        /* Byte 2 Bit 6 */
295   boolean Filemark:1;                                   /* Byte 2 Bit 7 */
296 #else
297   boolean Filemark:1;                                   /* Byte 2 Bit 7 */
298   boolean EOM:1;                                        /* Byte 2 Bit 6 */
299   boolean ILI:1;                                        /* Byte 2 Bit 5 */
300   unsigned char :1;                                     /* Byte 2 Bit 4 */
301   unsigned char SenseKey:4;                             /* Byte 2 Bits 0-3 */
302 #endif
303   unsigned char Information[4];                         /* Bytes 3-6 */
304   unsigned char AdditionalSenseLength;                  /* Byte 7 */
305   unsigned char CommandSpecificInformation[4];          /* Bytes 8-11 */
306   unsigned char AdditionalSenseCode;                    /* Byte 12 */
307   unsigned char AdditionalSenseCodeQualifier;           /* Byte 13 */
308   unsigned char :8;                                     /* Byte 14 */
309 #ifdef LITTLE_ENDIAN_BITFIELDS
310   unsigned char BitPointer:3;                           /* Byte 15 */
311   boolean BPV:1;
312   unsigned char :2;
313   boolean CommandData :1;
314   boolean SKSV:1;      
315 #else
316   boolean SKSV:1;      
317   boolean CommandData :1;
318   unsigned char :2;
319   boolean BPV:1;
320   unsigned char BitPointer:3;                           /* Byte 15 */
321 #endif
322   unsigned char FieldData[2];                           /* Byte 16,17 */
323 }
324 RequestSense_T;
325
326 /* Okay, now for the element status mode sense page (0x1d): */
327
328 typedef struct ElementModeSensePageHeader {
329   unsigned char PageCode;  /* byte 0 */
330   unsigned char ParameterLengthList;  /* byte 1; */
331   unsigned char MediumTransportStartHi; /* byte 2,3 */
332   unsigned char MediumTransportStartLo;
333   unsigned char NumMediumTransportHi;   /* byte 4,5 */
334   unsigned char NumMediumTransportLo;   /* byte 4,5 */
335   unsigned char StorageStartHi;         /* byte 6,7 */
336   unsigned char StorageStartLo;         /* byte 6,7 */
337   unsigned char NumStorageHi;           /* byte 8,9 */
338   unsigned char NumStorageLo;           /* byte 8,9 */
339   unsigned char ImportExportStartHi;    /* byte 10,11 */
340   unsigned char ImportExportStartLo;    /* byte 10,11 */
341   unsigned char NumImportExportHi;      /* byte 12,13 */
342   unsigned char NumImportExportLo;      /* byte 12,13 */
343   unsigned char DataTransferStartHi;    /* byte 14,15 */
344   unsigned char DataTransferStartLo;    /* byte 14,15 */
345   unsigned char NumDataTransferHi;      /* byte 16,17 */
346   unsigned char NumDataTransferLo;      /* byte 16,17 */
347   unsigned char Reserved1;             /* byte 18, 19 */
348   unsigned char Reserved2;             /* byte 18, 19 */
349 } ElementModeSensePage_T;
350
351 typedef struct ElementModeSenseHeader {
352   int MaxReadElementStatusData; /* 'nuff for all of below. */
353   int NumElements;              /* total # of elements. */
354   int MediumTransportStart;
355   int NumMediumTransport;
356   int StorageStart;
357   int NumStorage;
358   int ImportExportStart;
359   int NumImportExport;
360   int DataTransferStart;
361   int NumDataTransfer;
362 } ElementModeSense_T;
363
364
365 typedef enum ElementTypeCode
366 {
367   AllElementTypes =             0,
368   MediumTransportElement =      1,
369   StorageElement =              2,
370   ImportExportElement =         3,
371   DataTransferElement =         4
372 }
373 ElementTypeCode_T;
374
375
376 typedef struct ElementStatusDataHeader
377 {
378   unsigned char FirstElementAddressReported[2];         /* Bytes 0-1 */
379   unsigned char NumberOfElementsAvailable[2];           /* Bytes 2-3 */
380   unsigned char :8;                                     /* Byte 4 */
381   unsigned char ByteCountOfReportAvailable[3];          /* Bytes 5-7 */
382 }
383 ElementStatusDataHeader_T;
384
385
386 typedef struct ElementStatusPage
387 {
388   ElementTypeCode_T ElementTypeCode:8;                  /* Byte 0 */
389 #ifdef LITTLE_ENDIAN_BITFIELDS
390   unsigned char :6;                                     /* Byte 1 Bits 0-5 */
391   boolean AVolTag:1;                                    /* Byte 1 Bit 6 */
392   boolean PVolTag:1;                                    /* Byte 1 Bit 7 */
393 #else
394   boolean PVolTag:1;                                    /* Byte 1 Bit 7 */
395   boolean AVolTag:1;                                    /* Byte 1 Bit 6 */
396   unsigned char :6;                                     /* Byte 1 Bits 0-5 */
397 #endif
398   unsigned char ElementDescriptorLength[2];             /* Bytes 2-3 */
399   unsigned char :8;                                     /* Byte 4 */
400   unsigned char ByteCountOfDescriptorDataAvailable[3];  /* Bytes 5-7 */
401 }
402 ElementStatusPage_T;
403
404 typedef struct Element2StatusPage
405 {
406   ElementTypeCode_T ElementTypeCode:8;                  /* Byte 0 */
407   unsigned char VolBits ; /* byte 1 */
408 #define E2_PVOLTAG 0x80
409 #define E2_AVOLTAG 0x40
410   unsigned char ElementDescriptorLength[2];             /* Bytes 2-3 */
411   unsigned char :8;                                     /* Byte 4 */
412   unsigned char ByteCountOfDescriptorDataAvailable[3];  /* Bytes 5-7 */
413 }
414 Element2StatusPage_T;
415
416
417
418 typedef struct TransportElementDescriptorShort
419 {
420   unsigned char ElementAddress[2];                      /* Bytes 0-1 */
421 #ifdef LITTLE_ENDIAN_BITFIELDS
422   boolean Full:1;                                       /* Byte 2 Bit 0 */
423   unsigned char :1;                                     /* Byte 2 Bit 1 */
424   boolean Except:1;                                     /* Byte 2 Bit 2 */
425   unsigned char :5;                                     /* Byte 2 Bits 3-7 */
426 #else
427   unsigned char :5;                                     /* Byte 2 Bits 3-7 */
428   boolean Except:1;                                     /* Byte 2 Bit 2 */
429   unsigned char :1;                                     /* Byte 2 Bit 1 */
430   boolean Full:1;                                       /* Byte 2 Bit 0 */
431 #endif
432   unsigned char :8;                                     /* Byte 3 */
433   unsigned char AdditionalSenseCode;                    /* Byte 4 */
434   unsigned char AdditionalSenseCodeQualifier;           /* Byte 5 */
435   unsigned char :8;                                     /* Byte 6 */
436   unsigned char :8;                                     /* Byte 7 */
437   unsigned char :8;                                     /* Byte 8 */
438 #ifdef LITTLE_ENDIAN_BITFIELDS
439   unsigned char :6;                                     /* Byte 9 Bits 0-5 */
440   boolean SValid:1;                                     /* Byte 9 Bit 6 */
441   boolean Invert:1;                                     /* Byte 9 Bit 7 */
442 #else
443   boolean Invert:1;                                     /* Byte 9 Bit 7 */
444   boolean SValid:1;                                     /* Byte 9 Bit 6 */
445   unsigned char :6;                                     /* Byte 9 Bits 0-5 */
446 #endif
447   unsigned char SourceStorageElementAddress[2];         /* Bytes 10-11 */
448 }
449 TransportElementDescriptorShort_T;
450
451
452 typedef struct TransportElementDescriptor
453 {
454   unsigned char ElementAddress[2];                      /* Bytes 0-1 */
455 #ifdef LITTLE_ENDIAN_BITFIELDS
456   boolean Full:1;                                       /* Byte 2 Bit 0 */
457   unsigned char :1;                                     /* Byte 2 Bit 1 */
458   boolean Except:1;                                     /* Byte 2 Bit 2 */
459   unsigned char :5;                                     /* Byte 2 Bits 3-7 */
460 #else
461   unsigned char :5;                                     /* Byte 2 Bits 3-7 */
462   boolean Except:1;                                     /* Byte 2 Bit 2 */
463   unsigned char :1;                                     /* Byte 2 Bit 1 */
464   boolean Full:1;                                       /* Byte 2 Bit 0 */
465 #endif
466   unsigned char :8;                                     /* Byte 3 */
467   unsigned char AdditionalSenseCode;                    /* Byte 4 */
468   unsigned char AdditionalSenseCodeQualifier;           /* Byte 5 */
469   unsigned char :8;                                     /* Byte 6 */
470   unsigned char :8;                                     /* Byte 7 */
471   unsigned char :8;                                     /* Byte 8 */
472 #ifdef LITTLE_ENDIAN_BITFIELDS
473   unsigned char :6;                                     /* Byte 9 Bits 0-5 */
474   boolean SValid:1;                                     /* Byte 9 Bit 6 */
475   boolean Invert:1;                                     /* Byte 9 Bit 7 */
476 #else
477   boolean Invert:1;                                     /* Byte 9 Bit 7 */
478   boolean SValid:1;                                     /* Byte 9 Bit 6 */
479   unsigned char :6;                                     /* Byte 9 Bits 0-5 */
480 #endif
481   unsigned char SourceStorageElementAddress[2];         /* Bytes 10-11 */
482   unsigned char PrimaryVolumeTag[36];          /* barcode */
483   unsigned char AlternateVolumeTag[36];        
484 }
485 TransportElementDescriptor_T;
486
487
488
489 /* Now for element status data; */
490
491 typedef unsigned char barcode[37];
492
493 typedef struct ElementStatus {
494
495   int StorageElementCount;
496   int ImportExportCount;
497   int DataTransferElementCount;
498   int *DataTransferElementAddress;  /* array. */
499   int *DataTransferElementSourceStorageElementNumber; /* array */
500   barcode *DataTransferPrimaryVolumeTag; /* array. */
501   barcode *DataTransferAlternateVolumeTag; /* array. */
502   barcode *PrimaryVolumeTag;  /* array */
503   barcode *AlternateVolumeTag; /* array */
504   int *StorageElementAddress; /* array */
505   boolean *StorageElementIsImportExport; /* array */
506
507   int TransportElementAddress;  /* assume only one of those... */
508
509   boolean *DataTransferElementFull; /* array */
510   boolean *StorageElementFull;  /* array */
511
512 } ElementStatus_T;
513
514
515 /* Now for the SCSI ID and LUN information: */
516 typedef struct scsi_id {
517   int id;
518   int lun;
519 } scsi_id_t;
520
521 #define MEDIUM_CHANGER_TYPE 8  /* what type bits are set for medium changers. */
522
523 #endif  /* of multi-include protection. */