1 /* HCHAN.C      (c) Copyright Ivan Warren, 2005-2009                 */
2 /*              Generic channel device handler                       */
3 
4 /* Based on work (c)Roger Bowler, Jan Jaeger & Others 1999-2009      */
5 /* This code is covered by the QPL Licence                           */
6 /**CAUTION*CAUTION*CAUTION*CAUTION*CAUTION*CAUTION*CAUTION*CAUTION****/
7 /* THIS CODE IS CURRENTLY IN A DEVELOPMENT STAGE AND IS NOT          */
8 /* OPERATIONAL                                                       */
9 /* THIS FONCTIONALITY IS NOT YET SUPPORTED                           */
10 /**CAUTION*CAUTION*CAUTION*CAUTION*CAUTION*CAUTION*CAUTION*CAUTION****/
11 
12 /*-------------------------------------------------------------------*/
13 /* This module contains code to handle a generic protocol to         */
14 /* communicate with external device handlers.                        */
15 /*-------------------------------------------------------------------*/
16 
17 #include "hstdinc.h"
18 
19 #include "hercules.h"
20 #include "devtype.h"
21 #include "hchan.h"
22 
23 #if defined(OPTION_DYNAMIC_LOAD) && defined(WIN32) && !defined(HDL_USE_LIBTOOL) && !defined(_MSVC_)
24  SYSBLK *psysblk;
25  #define sysblk (*psysblk)
26 #endif
27 
28 /*
29  * Initialisation string for a Generic Subchannel
30  *
31  * Format :
32  *        <method> parms
33  *   The 'EXEC' method will attempt to fork/exec the specified
34  *       program. If the program dies during device initialisation, the
35  *       subchannel will be invalidated (initialisation error). If it fails
36  *       afterwards, the subchannel will be put offline and the offload
37  *       thread will attempt to restart it at periodic intervals.
38  *   The 'CONNECT' method will attempt to establish a TCP connection
39  *       to the IP/PORT specified. If the connection fails, the connection
40  *       will be attempted at periodic intervals.
41  *   The 'ITHREAD' method will spawn a thread using a dynamically loaded module
42  */
hchan_init_handler(DEVBLK * dev,int argc,char * argv[])43 static int hchan_init_handler ( DEVBLK *dev, int argc, char *argv[] )
44 {
45     int rc;
46     dev->devtype=0x2880;        /* Temporary until the device is actually initialised */
47     while(1)
48     {
49         if(argc<1)
50         {
51             logmsg("HHCGCH003E %4.4X : Missing Generic Channel method\n",dev->devnum);
52             rc=-1;
53             break;
54         }
55 
56         if(strcasecmp(argv[0],"EXEC")==0)
57         {
58             rc=hchan_init_exec(dev,argc,argv);
59             break;
60         }
61         if(strcasecmp(argv[0],"CONNECT")==0)
62         {
63             rc=hchan_init_connect(dev,argc,argv);
64             break;
65         }
66         if(strcasecmp(argv[0],"ITHREAD")==0)
67         {
68             rc=hchan_init_int(dev,argc,argv);
69             break;
70         }
71         logmsg("HHCGCH001E %4.4X : Incorrect Generic Channel method %s\n",dev->devnum,argv[0]);
72         rc=-1;
73         break;
74     }
75     if(rc)
76     {
77         logmsg("HHCGCH002T %4.4X : Generic channel initialisation failed\n",dev->devnum);
78     }
79     logmsg("HHCGCH999W %4.4X : Generic channel is currently in development\n",dev->devnum);
80     return(rc);
81 }
82 
hchan_init_exec(DEVBLK * dev,int ac,char ** av)83 static  int     hchan_init_exec(DEVBLK *dev,int ac,char **av)
84 {
85     UNREFERENCED(dev);
86     UNREFERENCED(ac);
87     UNREFERENCED(av);
88     return(0);
89 }
hchan_init_connect(DEVBLK * dev,int ac,char ** av)90 static  int     hchan_init_connect(DEVBLK *dev,int ac,char **av)
91 {
92     UNREFERENCED(dev);
93     UNREFERENCED(ac);
94     UNREFERENCED(av);
95     return(0);
96 }
hchan_init_int(DEVBLK * dev,int ac,char ** av)97 static  int     hchan_init_int(DEVBLK *dev,int ac,char **av)
98 {
99     UNREFERENCED(dev);
100     UNREFERENCED(ac);
101     UNREFERENCED(av);
102     return(0);
103 }
104 
105 /*-------------------------------------------------------------------*/
106 /* Query the device definition                                       */
107 /*-------------------------------------------------------------------*/
hchan_query_device(DEVBLK * dev,char ** class,int buflen,char * buffer)108 static void hchan_query_device (DEVBLK *dev, char **class,
109                 int buflen, char *buffer)
110 {
111     BEGIN_DEVICE_CLASS_QUERY( "CHAN", dev, class, buflen, buffer );
112 
113     snprintf(buffer,buflen,"** CONTROL UNIT OFFLINE **");
114 }
115 
116 /*-------------------------------------------------------------------*/
117 /* Close the device                                                  */
118 /*-------------------------------------------------------------------*/
hchan_close_device(DEVBLK * dev)119 static int hchan_close_device ( DEVBLK *dev )
120 {
121     UNREFERENCED(dev);
122     return 0;
123 }
124 
125 
126 /*-------------------------------------------------------------------*/
127 /* Execute a Channel Command Word                                    */
128 /*-------------------------------------------------------------------*/
hchan_execute_ccw(DEVBLK * dev,BYTE code,BYTE flags,BYTE chained,U16 count,BYTE prevcode,int ccwseq,BYTE * iobuf,BYTE * more,BYTE * unitstat,U16 * residual)129 static void hchan_execute_ccw ( DEVBLK *dev, BYTE code, BYTE flags,
130         BYTE chained, U16 count, BYTE prevcode, int ccwseq,
131         BYTE *iobuf, BYTE *more, BYTE *unitstat, U16 *residual )
132 {
133 
134     UNREFERENCED(flags);
135     UNREFERENCED(prevcode);
136     UNREFERENCED(ccwseq);
137     UNREFERENCED(chained);
138     UNREFERENCED(count);
139     UNREFERENCED(iobuf);
140     UNREFERENCED(more);
141     UNREFERENCED(residual);
142 
143     /* Process depending on CCW opcode */
144     switch (code) {
145     default:
146     /*---------------------------------------------------------------*/
147     /* INVALID OPERATION                                             */
148     /*---------------------------------------------------------------*/
149         /* Set command reject sense byte, and unit check status */
150         dev->sense[0] = SENSE_CR;
151         *unitstat = CSW_CE | CSW_DE | CSW_UC;
152 
153     }
154 
155 }
156 
157 
158 #if defined(OPTION_DYNAMIC_LOAD)
159 static
160 #endif
161 DEVHND hchan_device_hndinfo = {
162         &hchan_init_handler,           /* Device Initialisation      */
163         &hchan_execute_ccw,            /* Device CCW execute         */
164         &hchan_close_device,           /* Device Close               */
165         &hchan_query_device,           /* Device Query               */
166         NULL,                          /* Device Start channel pgm   */
167         NULL,                          /* Device End channel pgm     */
168         NULL,                          /* Device Resume channel pgm  */
169         NULL,                          /* Device Suspend channel pgm */
170         NULL,                          /* Device Read                */
171         NULL,                          /* Device Write               */
172         NULL,                          /* Device Query used          */
173         NULL,                          /* Device Reserve             */
174         NULL,                          /* Device Release             */
175         NULL,                          /* Device Attention           */
176         NULL,                          /* Immediate CCW Codes        */
177         NULL,                          /* Signal Adapter Input       */
178         NULL,                          /* Signal Adapter Output      */
179         NULL,                          /* Hercules suspend           */
180         NULL                           /* Hercules resume            */
181 };
182 
183 /* Libtool static name colision resolution */
184 /* note : lt_dlopen will look for symbol & modulename_LTX_symbol */
185 #if !defined(HDL_BUILD_SHARED) && defined(HDL_USE_LIBTOOL)
186 #define hdl_ddev hdt0000_LTX_hdl_ddev
187 #define hdl_depc hdt0000_LTX_hdl_depc
188 #define hdl_reso hdt0000_LTX_hdl_reso
189 #define hdl_init hdt0000_LTX_hdl_init
190 #define hdl_fini hdt0000_LTX_hdl_fini
191 #endif
192 
193 
194 #if defined(OPTION_DYNAMIC_LOAD)
195 HDL_DEPENDENCY_SECTION;
196 {
197      HDL_DEPENDENCY(HERCULES);
198      HDL_DEPENDENCY(DEVBLK);
199      HDL_DEPENDENCY(SYSBLK);
200 }
201 END_DEPENDENCY_SECTION
202 
203 
204 #if defined(WIN32) && !defined(HDL_USE_LIBTOOL) && !defined(_MSVC_)
205   #undef sysblk
206   HDL_RESOLVER_SECTION;
207   {
208       HDL_RESOLVE_PTRVAR( psysblk, sysblk );
209   }
210   END_RESOLVER_SECTION
211 #endif
212 
213 
214 HDL_DEVICE_SECTION;
215 {
216     HDL_DEVICE(HCHAN, hchan_device_hndinfo );
217     HDL_DEVICE(2860, hchan_device_hndinfo );
218     HDL_DEVICE(2870, hchan_device_hndinfo );
219     HDL_DEVICE(2880, hchan_device_hndinfo );
220     HDL_DEVICE(9032, hchan_device_hndinfo );
221 }
222 END_DEVICE_SECTION
223 #endif
224