1 /* SCSITAPE.H   (c) Copyright "Fish" (David B. Trout), 2005-2012     */
2 /*              Hercules SCSI tape handling module header file       */
3 
4 // (c) Copyright "Fish" (David B. Trout), 2005-2009. Released under
5 // the Q Public License (http://www.hercules-390.org/herclic.html)
6 // as modifications to Hercules.
7 
8 #ifndef _SCSITAPE_H_
9 #define _SCSITAPE_H_
10 
11 #if defined(OPTION_SCSI_TAPE)
12 
13 #include "tapedev.h"
14 #include "w32stape.h"
15 
16 // External TMH-vector calls...
17 
18 extern int   update_status_scsitape   ( DEVBLK *dev ); // (via "generic" vector)
19 extern int   open_scsitape            ( DEVBLK *dev,                     BYTE *unitstat, BYTE code );
20 extern int   finish_scsitape_open     ( DEVBLK *dev,                     BYTE *unitstat, BYTE code );
21 extern void  close_scsitape           ( DEVBLK *dev );
22 extern int   read_scsitape            ( DEVBLK *dev, BYTE *buf,          BYTE *unitstat, BYTE code );
23 extern int   write_scsitape           ( DEVBLK *dev, BYTE *buf, U16 len, BYTE *unitstat, BYTE code );
24 extern int   rewind_scsitape          ( DEVBLK *dev,                     BYTE *unitstat, BYTE code );
25 extern int   bsb_scsitape             ( DEVBLK *dev,                     BYTE *unitstat, BYTE code );
26 extern int   fsb_scsitape             ( DEVBLK *dev,                     BYTE *unitstat, BYTE code );
27 extern int   bsf_scsitape             ( DEVBLK *dev,                     BYTE *unitstat, BYTE code );
28 extern int   fsf_scsitape             ( DEVBLK *dev,                     BYTE *unitstat, BYTE code );
29 extern int   write_scsimark           ( DEVBLK *dev,                     BYTE *unitstat, BYTE code );
30 extern int   sync_scsitape            ( DEVBLK *dev,                     BYTE *unitstat, BYTE code );
31 extern int   dse_scsitape             ( DEVBLK *dev,                     BYTE *unitstat, BYTE code );
32 extern int   erg_scsitape             ( DEVBLK *dev,                     BYTE *unitstat, BYTE code );
33 extern int   is_tape_mounted_scsitape ( DEVBLK *dev,                     BYTE *unitstat, BYTE code );
34 extern int   passedeot_scsitape       ( DEVBLK *dev );
35 extern int   readblkid_scsitape       ( DEVBLK* dev, BYTE* logical, BYTE* physical );
36 extern int   locateblk_scsitape       ( DEVBLK* dev, U32 blockid,        BYTE *unitstat, BYTE code );
37 
38 // Internal functions...
39 
40 extern void  int_scsi_rewind_unload( DEVBLK *dev, BYTE *unitstat, BYTE code );
41 extern void  int_scsi_status_update( DEVBLK *dev, int mountstat_only );
42 extern int   int_write_scsimark    ( DEVBLK *dev );
43 
44 extern void  blockid_emulated_to_actual( DEVBLK *dev, BYTE *emu_blkid, BYTE *act_blkid );
45 extern void  blockid_actual_to_emulated( DEVBLK *dev, BYTE *act_blkid, BYTE *emu_blkid );
46 
47 extern void  blockid_32_to_22( BYTE *in_32blkid, BYTE *out_22blkid );
48 extern void  blockid_22_to_32( BYTE *in_22blkid, BYTE *out_32blkid );
49 
50 extern void  create_automount_thread( DEVBLK* dev );
51 extern void *scsi_tapemountmon_thread( void* notused );
52 extern void  define_BOT_pos( DEVBLK *dev );
53 
54 // PROGRAMMING NOTE: I'm not sure of what the the actual/proper value
55 // should be (or is) for the following value but I've coded what seems
56 // to me to be a reasonable value for it. As you can probably guess
57 // based on its [admittedly rather verbose] name, it's the maximum
58 // amount of time that a SCSI tape drive query call should take (i.e.
59 // asking the system for the drive's status shouldn't, under normal
60 // circumstances, take any longer than this time). It should be set
61 // to the most pessimistic value we can reasonably stand, and should
62 // probably be at least as long as the host operating system's thread
63 // scheduling time-slice quantum.  --  Fish, April 2006
64 
65 // August, 2006: further testing/experimentation has revealed that the
66 // "proper" value (i.e. one that causes the fewest potential problems)
67 // for the below timeout setting varies greatly from one system to an-
68 // other with different host CPU speeds and different hardware (SCSI
69 // adapter cards, etc) being the largest factors. Thus, in order to try
70 // and define it to a value likely to cause the LEAST number of problems
71 // on the largest number of systems, I am changing it from its original
72 // 25 millisecond value to the EXTREMELY PESSIMISTIC (but nonetheless
73 // completely(?) safe (since it is afterall only a timeout setting!))
74 // value of 250 milliseconds.
75 
76 // This is because I happened to notice on some systems with moderate
77 // host (Windows) workload, etc, querying the status of the tape drive,
78 // while *usually* only taking 4-6 milliseconds maximum, would sometimes
79 // take up to 113 or more milliseconds! (thereby sometimes causing the
80 // guest to experience intermittent/sporadic unsolicited ATTN interrupts
81 // on the tape drive as their tape jobs ran (since "not mounted" status
82 // was thus getting set as a result of the status query taking longer
83 // than expected, causing the auto-mount thread to kick-in and then
84 // immediately exit again (with an ATTN interrupt of course) whenever
85 // it eventually noticed a tape was indeed still mounted on the drive)).
86 
87 // Thus, even though such unsolicited ATTN interrupts occuring in the
88 // middle of (i.e. during) an already running tape job should NOT, under
89 // ordinary circumstances, cause any problems (as long as auto-scsi-mount
90 // is enabled of course), in order to reduce the likelihood of it happening,
91 // I am increasing the below timeout setting to a value that, ideally,
92 // *should* work on most *all* systems, even under the most pessimistic
93 // of host workloads. -- Fish, August 2006.
94 
95 // ZZ FIXME: should we maybe make this a config file option??
96 
97 #define MAX_NORMAL_SCSI_DRIVE_QUERY_RESPONSE_TIMEOUT_USECS  (250*1000)
98 
99 #endif // defined(OPTION_SCSI_TAPE)
100 
101 #endif // _SCSITAPE_H_
102