1 /* CTCADPT.C    (c) Copyright James A. Pierson, 2002-2012            */
2 /*              (c) Copyright Roger Bowler, 2000-2012                */
3 /*              (c) Copyright Willem Konynenberg, 2000-2009          */
4 /*              (c) Copyright Vic Cross, 2001-2009                   */
5 /*              Hercules Channel-to-Channel Emulation Support        */
6 
7 // vmnet     (C) Copyright Willem Konynenberg, 2000-2009
8 // CTCT      (C) Copyright Vic Cross, 2001-2009
9 // CTCE      (C) Copyright Peter J. Jansen, 2014-2016
10 
11 // Notes:
12 //   This module contains the remaining CTC emulation modes that
13 //   have not been moved to seperate modules. There is also logic
14 //   to allow old style 3088 device definitions for compatibility
15 //   and may be removed in a future release.
16 //
17 //   Please read README.NETWORKING for more info.
18 //
19 
20 #include "hstdinc.h"
21 
22 #define _CTCADPT_C_
23 #define _HENGINE_DLL_
24 
25 #include "hercules.h"
26 #include "devtype.h"
27 #include "ctcadpt.h"
28 
29 #include "opcode.h"
30 #include "devtype.h"
31 
32 // --------------------------------------------------------------------
33 // CTCE Info also for use by CTCE Tracing when requested
34 // --------------------------------------------------------------------
35 
36 typedef struct _CTCE_INFO
37 {
38     BYTE               state_x_prev;   /* This  side previous state  */
39     BYTE               state_y_prev;   /* Other side previous state  */
40     BYTE               actions;        /* Triggered by CCW received  */
41     BYTE               state_new;      /* The updated FSM state      */
42     BYTE               x_unit_stat;    /* Resulting device unit stat */
43     BYTE               scb;            /* Last SCB returned          */
44     BYTE               busy_waits;     /* Number of times waited for */
45                                        /* a Busy condition to end    */
46     BYTE               de_ready;       /* Device-End status          */
47                                        /* indicating ready to be     */
48                                        /* presented, yielding ...    */
49     u_int              sent : 1;       /* = 1 : CTCE_Send done       */
50     u_int              attn_can : 1;   /* = 1 : Atttention Cancelled */
51     u_int              con_lost : 1;   /* = 1 : contention lost      */
52     u_int              con_won  : 1;   /* = 1 : contention won       */
53     int                wait_rc;        /* CTCE_Send Wait RC if used  */
54     int                de_ready_attn_rc;   /* device_attention RC    */
55     int                working_attn_rc;    /* device_attention RC    */
56                                        /* from transition to         */
57                                        /* "Working(D)" state         */
58     int                sok_buf_len;    /* socket buffer length       */
59 }
60 CTCE_INFO;
61 
62 // --------------------------------------------------------------------
63 // CTCE_Cmd_Xfr enumeration type used by CTCE_Trace
64 // --------------------------------------------------------------------
65 
66 enum CTCE_Cmd_Xfr
67 {
68     CTCE_LCL,                          /* Cmd remains Local only     */
69     CTCE_SND,                          /* Cmd Send to y-side         */
70     CTCE_RCV                           /* Cmd Received from y-side   */
71 };
72 
73 // ====================================================================
74 // Declarations
75 // ====================================================================
76 
77 static int      CTCT_Init( DEVBLK *dev, int argc, char *argv[] );
78 
79 static void     CTCT_Read( DEVBLK* pDEVBLK,   U16   sCount,
80                            BYTE*   pIOBuf,    BYTE* pUnitStat,
81                            U16*    pResidual, BYTE* pMore );
82 
83 static void     CTCT_Write( DEVBLK* pDEVBLK,   U16   sCount,
84                             BYTE*   pIOBuf,    BYTE* pUnitStat,
85                             U16*    pResidual );
86 
87 static void*    CTCT_ListenThread( void* argp );
88 
89 static void     CTCE_ExecuteCCW( DEVBLK* pDEVBLK, BYTE  bCode,
90                                  BYTE    bFlags,  BYTE  bChained,
91                                  U16     sCount,  BYTE  bPrevCode,
92                                  int     iCCWSeq, BYTE* pIOBuf,
93                                  BYTE*   pMore,   BYTE* pUnitStat,
94                                  U16*    pResidual );
95 
96 static int      CTCE_Init( DEVBLK *dev, int argc, char *argv[] );
97 
98 static void     CTCE_Send( DEVBLK* pDEVBLK,   U16        sCount,
99                             BYTE*  pIOBuf,    BYTE*      pUnitStat,
100                             U16*   pResidual, CTCE_INFO* pCTCE_Info );
101 
102 static void*    CTCE_RecvThread( void* argp );
103 
104 static void*    CTCE_ListenThread( void* argp );
105 
106 static void     CTCE_Halt( DEVBLK* pDEVBLK );
107 
108 static U32      CTCE_ChkSum( const BYTE* pBuf, const U16 BufLen );
109 
110 static void     CTCE_Trace( const DEVBLK*             pDEVBLK,
111                             const U16                 sCount,
112                             const enum CTCE_Cmd_Xfr   eCTCE_Cmd_Xfr,
113                             const CTCE_INFO*          pCTCE_Info,
114                             const BYTE*               pCTCE_Buf,
115                             const BYTE*               pUnitStat );
116 
117 static int      CTCE_Connect_Timeout( int                    sockfd,
118                                       const struct sockaddr* saptr,
119                                       const socklen_t        salen,
120                                       const int              usec );
121 
122 static int      VMNET_Init( DEVBLK *dev, int argc, char *argv[] );
123 
124 static int      VMNET_Write( DEVBLK *dev, BYTE *iobuf,
125                              U16 count, BYTE *unitstat );
126 
127 static int      VMNET_Read( DEVBLK *dev, BYTE *iobuf,
128                             U16 count, BYTE *unitstat );
129 
130 // --------------------------------------------------------------------
131 // Definitions for CTC general data blocks
132 // --------------------------------------------------------------------
133 
134 typedef struct _CTCG_PARMBLK
135 {
136     int                 listenfd;
137     struct sockaddr_in  addr;
138     DEVBLK*             dev;
139 }
140 CTCG_PARMBLK;
141 
142 // --------------------------------------------------------------------
143 // CTCE Send-Receive Socket Prefix at the start of the DEVBLK buf
144 // --------------------------------------------------------------------
145 
146 typedef struct _CTCE_SOKPFX
147 {
148     BYTE                CmdReg;        /* CTCE command register      */
149     BYTE                FsmSta;        /* CTCE FSM state             */
150     U16                 sCount;        /* CTCE sCount copy           */
151     U16                 PktSeq;        /* CTCE Packet Sequence ID    */
152     U16                 SndLen;        /* CTCE Packet Sent Length    */
153     U16                 DevNum;        /* CTCE Sender's devnum       */
154     U16                 ssid;          /* CTCE Sender's ssid         */
155 }
156 CTCE_SOKPFX;
157 
158 // --------------------------------------------------------------------
159 // CTCE Equivalent of CTCG_PARMBLK
160 // --------------------------------------------------------------------
161 
162 typedef struct _CTCE_PARMBLK
163 {
164     int                 listenfd[2];   /* [0] = read, [1] = write    */
165     struct sockaddr_in  addr;
166     DEVBLK*             dev;
167 }
168 CTCE_PARMBLK;
169 
170 // --------------------------------------------------------------------
171 // CTCE Constants (generated by a small REXX script)
172 // --------------------------------------------------------------------
173 
174 #define CTCE_PREPARE                0
175 #define CTCE_CONTROL                1
176 #define CTCE_READ                   2
177 #define CTCE_WRITE                  3
178 #define CTCE_SENSE_COMMAND_BYTE     4
179 #define CTCE_READ_BACKWARD          6
180 #define CTCE_WRITE_END_OF_FILE      7
181 #define CTCE_NO_OPERATION           8
182 #define CTCE_SET_EXTENDED_MODE      9
183 #define CTCE_SENSE_ADAPTER_STATE    10
184 #define CTCE_SENSE_ID               11
185 #define CTCE_READ_CONFIG_DATA       12
186 #define CTCE_SET_BASIC_MODE         15
187 
188 static char *CTCE_CmdStr[16] = {
189     "PRE" , //  0 = 00 = Prepare
190     "CTL" , //  1 = 01 = Control
191     "RED" , //  2 = 02 = Read
192     "WRT" , //  3 = 03 = Write
193     "SCB" , //  4 = 04 = Sense Command Byte
194     "???" , //  5 = 05 = Not Used
195     "RBK" , //  6 = 06 = Read Backward
196     "WEF" , //  7 = 07 = Write End Of File
197     "NOP" , //  8 = 10 = No Operation
198     "SEM" , //  9 = 11 = Set Extended Mode
199     "SAS" , // 10 = 12 = Sense Adapter State
200     "SID" , // 11 = 13 = Sense ID
201     "RCD" , // 12 = 14 = Read Configuration Data
202     "???" , // 13 = 15 = Invalid Command Code
203     "CB0" , // 14 = 16 = Invalid Command Code Used to Report SCB 0
204     "SBM"   // 15 = 17 = Set Basic Mode
205 };
206 
207 static BYTE CTCE_command[256] = {
208     14, 3, 2, 8,10, 3, 2, 1,13, 3, 2, 8, 6, 3, 2, 1,
209     13, 3, 2, 8, 4, 3, 2, 1,13, 3, 2, 8, 6, 3, 2, 1,
210     13, 3, 2, 8,13, 3, 2, 1,13, 3, 2, 8, 6, 3, 2, 1,
211     13, 3, 2, 8, 4, 3, 2, 1,13, 3, 2, 8, 6, 3, 2, 1,
212     13, 3, 2,15,13, 3, 2, 1,13, 3, 2,15, 6, 3, 2, 1,
213     13, 3, 2,15, 4, 3, 2, 1,13, 3, 2,15, 6, 3, 2, 1,
214     13, 3, 2,15,13, 3, 2, 1,13, 3, 2,15, 6, 3, 2, 1,
215     13, 3, 2,15, 4, 3, 2, 1,13, 3, 2,15, 6, 3, 2, 1,
216     13, 7, 2, 8,13, 7, 2, 1,13, 7, 2, 8, 6, 7, 2, 1,
217     13, 7, 2, 8, 4, 7, 2, 1,13, 7, 2, 8, 6, 7, 2, 1,
218     13, 7, 2, 8,13, 7, 2, 1,13, 7, 2, 8, 6, 7, 2, 1,
219     13, 7, 2, 8, 4, 7, 2, 1,13, 7, 2, 8, 6, 7, 2, 1,
220     13, 7, 2, 9,13, 7, 2, 1,13, 7, 2,13, 6, 7, 2, 1,
221     13, 7, 2,13, 4, 7, 2, 1,13, 7, 2,13, 6, 7, 2, 1,
222     13, 7, 2, 0,11, 7, 2, 1,13, 7, 2,13, 6, 7, 2, 1,
223     13, 7, 2,13, 4, 7, 2, 1,13, 7, 2,13, 6, 7, 2, 1
224 };
225 
226 /* In base (non-extended) mode the WEOF (WEF) */
227 /* command does not exist but classifies as   */
228 /* a regular WRITE command.  The WEOF-to-WRT  */
229 /* mapping is performed with this macro:      */
230 #define CTCE_CMD(c)             (pDEVBLK->ctcxmode == 1 ?   (CTCE_command[c]) : \
231                                 ((CTCE_command[c])==7 ? 3 : (CTCE_command[c])))
232 
233 #define IS_CTCE_CCW_PRE(c)      ((CTCE_command[c]==0))
234 #define IS_CTCE_CCW_CTL(c)      ((CTCE_command[c]==1))
235 #define IS_CTCE_CCW_RED(c)      ((CTCE_command[c]==2))
236 #define IS_CTCE_CCW_WRT(c)      ((CTCE_CMD( c) ==3))
237 #define IS_CTCE_CCW_SCB(c)      ((CTCE_command[c]==4))
238 #define IS_CTCE_CCW_RBK(c)      ((CTCE_command[c]==6))
239 #define IS_CTCE_CCW_WEF(c)      ((CTCE_CMD( c )==7))
240 #define IS_CTCE_CCW_NOP(c)      ((CTCE_command[c]==8))
241 #define IS_CTCE_CCW_SEM(c)      ((CTCE_command[c]==9))
242 #define IS_CTCE_CCW_SBM(c)      ((CTCE_command[c]==15))
243 #define IS_CTCE_CCW_SAS(c)      ((CTCE_command[c]==10))
244 #define IS_CTCE_CCW_SID(c)      ((CTCE_command[c]==11))
245 #define IS_CTCE_CCW_RCD(c)      ((CTCE_command[c]==12))
246 #define IS_CTCE_CCW_DEP(c)      ((CTCE_CMD( c )<7))           /* Any Dependent Command */
247 #define IS_CTCE_CCW_RDA(c)      (((CTCE_command[c]&0xFB)==2)) /* Read or Read Backward */
248 #define IS_CTCE_CCW_WRA(c)      (((CTCE_command[c]&0xFB)==3)) /* Write or Write EOF    */
249 
250 /* Macros for classifying CTC states follow.  */
251 /* These are numbered 0 thru 7 as per the     */
252 /* column numbers 0-3 and 4-7 in the table    */
253 /* in section 2.13 in SA22-7203-00 by IBM,    */
254 /* which is (alomost) the same as the table   */
255 /* in section 3.15 in SA22-7901-01 by IBM.    */
256 /*                                            */
257 /* But in base (non-extended) mode, the table */
258 /* in section 2.13 in SA77-7901-01 applies,   */
259 /* omitting column 5 for the Not-Ready state: */
260 /* base (non-extended) mode considers this    */
261 /* the same as Available.  We perform this    */
262 /* Base-Not-Ready mapping into Available with */
263 /* this macro:                                */
264 #define CTCE_STATE(c)           (pDEVBLK->ctcxmode == 1 ?  ((c)&0x07) : \
265                                 (((c)&0x07)==0x05 ? 0x04 : ((c)&0x07)))
266 
267 #define IS_CTCE_YWP(c)          (((c)&0x07)==0x00)
268 #define IS_CTCE_YWC(c)          (((c)&0x07)==0x01)
269 #define IS_CTCE_YWR(c)          (((c)&0x07)==0x02)
270 #define IS_CTCE_YWW(c)          (((c)&0x07)==0x03)
271 #define IS_CTCE_YAV(c)          ((CTCE_STATE(c))==0x04)
272 #define IS_CTCE_YNR(c)          ((CTCE_STATE(c))==0x05)
273 #define IS_CTCE_XWK(c)          (((c)&0x07)==0x06)
274 #define IS_CTCE_XIP(c)          (((c)&0x07)==0x07)
275 
276 /* These two are useful combinations :        */
277 /* - The 0 (YWP) or 4 (YAV) states READY      */
278 #define IS_CTCE_YAP(c)          (((CTCE_STATE(c))&0x03)==0x00)
279 /* - Any Y working state: YWP, YWC, YWR or YWW */
280 #define IS_CTCE_YWK(c)          (((c)&0x04)==0x00)
281 /* - Any of the states Cntl, Read, or Write   */
282 #define IS_CTCE_CRW(c)         ((((c)&0x04)==0x00) && (((c)&0x07)!=0x00))
283 
284 /* A special one is "X available" (XAV) which */
285 /* includes the not ready state.              */
286 #define IS_CTCE_XAV(c)          (((c)<6))
287 
288 /* And the corresponding SET macros for these */
289 /* The first four, i.e. a SET to any YWK,     */
290 /* includes the setting of the CTCE_WAIT bit. */
291 #define SET_CTCE_YWP(c)         (c=(((c)&0xF8)|0x00))
292 #define SET_CTCE_YWC(c)         (c=(((c)&0xF8)|0x01))
293 #define SET_CTCE_YWR(c)         (c=(((c)&0xF8)|0x02))
294 #define SET_CTCE_YWW(c)         (c=(((c)&0xF8)|0x03))
295 #define SET_CTCE_YAV(c)         (c=(((c)&0xF8)|0x04))
296 #define SET_CTCE_YNR(c)         (c=(((c)&0xF8)|0x05))
297 #define SET_CTCE_XWK(c)         (c=(((c)&0xF8)|0x06))
298 #define SET_CTCE_XIP(c)         (c=((c)|0x07))
299 
300 /* One letter CTC state abbreviations         */
301 static char *CTCE_StaStr[8] = {"P", "C", "R", "W", "A", "N", "X", "I"};
302 
303 /* The CTCE CCW command will trigger actions  */
304 /* which are dependent on the CTCE state.     */
305 /* These different action flags are :         */
306 #define CTCE_WEOF               (0x80)
307 #define CTCE_SEND               (0x40)
308 #define CTCE_WAIT               (0x20)
309 #define CTCE_ATTN               (0x10)
310 #define CTCE_MATCH              (0x08)
311 
312 /* Corresponding macros to test for these     */
313 #define IS_CTCE_WEOF(c)         (((c)&CTCE_WEOF)==CTCE_WEOF)
314 #define IS_CTCE_SEND(c)         (((c)&CTCE_SEND)==CTCE_SEND)
315 #define IS_CTCE_WAIT(c)         (((c)&CTCE_WAIT)==CTCE_WAIT)
316 #define IS_CTCE_ATTN(c)         (((c)&CTCE_ATTN)==CTCE_ATTN)
317 #define IS_CTCE_MATCH(c)        (((c)&CTCE_MATCH)==CTCE_MATCH)
318 
319 /* And the corresponding SET macros for these */
320 #define SET_CTCE_WEOF(c)        (c|=CTCE_WEOF)
321 #define SET_CTCE_SEND(c)        (c|=CTCE_SEND)
322 #define SET_CTCE_WAIT(c)        (c|=CTCE_WAIT)
323 #define SET_CTCE_ATTN(c)        (c|=CTCE_ATTN)
324 #define SET_CTCE_MATCH(c)       (c|=CTCE_MATCH)
325 
326 /* And the corresponding CLeaR macros         */
327 #define CLR_CTCE_WEOF(c)        (c&=~CTCE_WEOF)
328 #define CLR_CTCE_SEND(c)        (c&=~CTCE_SEND)
329 #define CLR_CTCE_WAIT(c)        (c&=~CTCE_WAIT)
330 #define CLR_CTCE_ATTN(c)        (c&=~CTCE_ATTN)
331 #define CLR_CTCE_MATCH(c)       (c&=~CTCE_MATCH)
332 
333 /* To CLeaR all flags                         */
334 #define CLR_CTCE_ALLF(c)        (c&=~CTCE_WEOF)
335 
336 /* Enhanced CTC processing is selected by     */
337 /* omitting default MTU bufsize CTCE_MTU_MIN, */
338 /* or by specifying a larger number.  The     */
339 /* default is equal to 61592, calculated as   */
340 /*    sizeof(CTCE_SOKPFX) +                   */
341 /*    sizeof(U16=pSokBuf->sCount=2) +         */
342 /*    61578 (=0xF08A)                         */
343 /* the latter number is the largest data      */
344 /* sCount seen used by  CTC programs to date. */
345 /* If that number would be too small one day, */
346 /* a severe error message will instruct the   */
347 /* user to specify an increased MTU bufsize   */
348 /* in the device configuration statement.     */
349 #define CTCE_MTU_MIN ( (int)( 61578 + sizeof(CTCE_SOKPFX) + sizeof(U16 /* sCount */) ) )
350 
351 /**********************************************************************/
352 /* A summary of the Channel-to-Channel command operations this CTCE   */
353 /* device emulates can be found in IBM publications SA22-7203-00 in   */
354 /* section 2.13, and in SA22-7091-01 sections 2.13 and 3.15.  The     */
355 /* tables show the device states of both sides, and the influence of  */
356 /* CCW commands depending on this state.  Our CTCE implemention is    */
357 /* assisted by a Finite State Machine (FSM) table closely matching    */
358 /* the figures in these prublications.                                */
359 /*                                                                    */
360 /* Eeach CTCE side is in a given state at any point in time, which    */
361 /* corresponds to the columns in the FSM table, matching columns 0    */
362 /* through 7 in the publications mentionned.  Each CCW command has a  */
363 /* row in the FSM table.  A CCW command received will (1) trigger a   */
364 /* transition to a new_state, (2) cause a Unit Status update, and (3) */
365 /* cause a number of actions to be carried out.                       */
366 /*                                                                    */
367 /* The FSM table coding is assisted with macro's for the state each   */
368 /* CTCE side (x=local, y=remote) can have, matching the FSM column    */
369 /* column numbers 0-7: Prepare, Control, Read, Write, Available,      */
370 /* Not-ready, X-working (=P/C/R/W) or Int-pending, all represented by */
371 /* a single letter: P, C, R, W, A, N, X, I.  Additionally, the CTCE   */
372 /* FSM table uses U for Unchanged to cover the case of no state       */
373 /* change whatsoever, e.g. for CCW commands SAS, SID, RCD and others. */
374 /* Please see macro's CTCE_NEW_X_STATE & CTCE_NEW_Y_STATE down below. */
375 /**********************************************************************/
376 #define P    0
377 #define C    1
378 #define R    2
379 #define W    3
380 #define A    4
381 #define N    5
382 #define X    6
383 #define I    7
384 #define U  255
385 
386 /**********************************************************************/
387 /* Each CTCE FSM table entry contains a macro up to 7 letters long:   */
388 /*                                                                    */
389 /*      +---------- new_state = P, C, R, W, A or U                    */
390 /*      |++-------- Unit Status bits encoded with up to two letters:  */
391 /*      |||         . CD = CE + DE                                    */
392 /*      |||         . C  = CE                                         */
393 /*      |||         . BA = BUSY + ATTN                                */
394 /*      |||         . B  = BUSY                                       */
395 /*      |||         . UC = Unit Check                                 */
396 /*      |||+------- S = Send this commands also to the other (y-)side */
397 /*      ||||+------ M = a Matching command for the other (y-)side     */
398 /*      |||||+----- W = our (x-)side must Wait for a matching command */
399 /*      ||||||+---- A = cause Attention interrupt at the other y-side */
400 /*      |||||||                                                       */
401 #define PC_S_W  { P, CSW_CE             , 0, CTCE_SEND              | CTCE_WAIT             }
402 #define C__S_WA { C, 0                  , 0, CTCE_SEND              | CTCE_WAIT | CTCE_ATTN }
403 #define R__S_WA { R, 0                  , 0, CTCE_SEND              | CTCE_WAIT | CTCE_ATTN }
404 #define W__S_WA { W, 0                  , 0, CTCE_SEND              | CTCE_WAIT | CTCE_ATTN }
405 #define CC_SMW  { C, CSW_CE             , 0, CTCE_SEND | CTCE_MATCH | CTCE_WAIT             }
406 #define R__SMW  { R, 0                  , 0, CTCE_SEND | CTCE_MATCH | CTCE_WAIT             }
407 #define W__SMW  { W, 0                  , 0, CTCE_SEND | CTCE_MATCH | CTCE_WAIT             }
408 #define ACDSM   { A, CSW_CE   | CSW_DE  , 0, CTCE_SEND | CTCE_MATCH                         }
409 #define ACDS    { A, CSW_CE   | CSW_DE  , 0, CTCE_SEND                                      }
410 #define AUCS    { A,       CSW_UC       , 0, CTCE_SEND                                      }
411 #define  CDSM   { U, CSW_CE   | CSW_DE  , 0, CTCE_SEND | CTCE_MATCH                         }
412 #define  CDS    { U, CSW_CE   | CSW_DE  , 0, CTCE_SEND                                      }
413 #define  CD     { U, CSW_CE   | CSW_DE  , 0, 0                                              }
414 #define  B      { U, CSW_BUSY           , 0, 0                                              }
415 #define  BA     { U, CSW_BUSY | CSW_ATTN, 0, 0                                              }
416 #define  UC     { U,       CSW_UC       , 0, 0                                              }
417 #define  UCS    { U,       CSW_UC       , 0, CTCE_SEND                                      }
418 
419 /**********************************************************************/
420 /* Now finally the CTCE FSM table:                                    */
421 /**********************************************************************/
422 static struct CTCE_FsmEnt {
423    BYTE new_state;
424    BYTE x_unit_stat;
425    BYTE y_unit_stat;
426    BYTE actions;
427 }
428 const CTCE_Fsm[16][8] = {
429 /* cmd/stat P       C       R       W       A       N       X       I     */
430 /* PRE */ {ACDSM  , CD    , CD    , CD    ,PC_S_W , UCS   , B     , B     },
431 /* CTL */ {CC_SMW , BA    , BA    , BA    ,C__S_WA, UCS   , B     , B     },
432 /* RED */ {R__SMW , BA    , BA    ,ACDSM  ,R__S_WA, UCS   , B     , B     },
433 /* WRT */ {W__SMW , BA    ,ACDSM  , BA    ,W__S_WA, UCS   , B     , B     },
434 /* SCB */ { CD    ,ACDSM  , CD    , CD    , CD    , UCS   , B     , B     },
435 /* nus */ { UC    , UC    , UC    , UC    , UC    , UC    , B     , B     },
436 /* RBK */ {R__SMW , BA    , BA    ,ACDSM  ,R__S_WA, UCS   , B     , B     },
437 /* WEF */ { CDS   , BA    ,ACDSM  , BA    , CDS   , UCS   , B     , B     },
438 /* NOP */ { CD    , BA    , BA    , BA    , CD    , UC    , B     , B     },
439 /* SEM */ { CDS   , BA    , BA    , BA    ,ACDS   ,AUCS   , B     , B     },
440 
441 /* SAS */ { CD    , CD    , CD    , CD    , CD    , CD    , B     , B     },
442 /* SID */ { CD    , CD    , CD    , CD    , CD    , CD    , B     , B     },
443 /* RCD */ { CD    , CD    , CD    , CD    , CD    , CD    , B     , B     },
444 
445 /* inv */ { UC    , UC    , UC    , UC    , UC    , UC    , B     , B     },
446 /* CB0 */ { UC    , UC    , UC    , UC    , UC    , UC    , B     , B     },
447 /* SBM */ { CDS   , BA    , BA    , BA    ,ACDS   ,AUCS   , B     , B     }
448 };
449 
450 #undef P
451 #undef C
452 #undef R
453 #undef W
454 #undef A
455 #undef N
456 #undef X
457 #undef I
458 #undef U
459 
460 #undef PC_S_W
461 #undef C__S_WA
462 #undef R__S_WA
463 #undef W__S_WA
464 #undef CC_SMW
465 #undef R__SMW
466 #undef W__SMW
467 #undef ACDSM
468 #undef ACDS
469 #undef AUCS
470 #undef  CDSM
471 #undef  CDS
472 #undef  CD
473 #undef  B
474 #undef  BA
475 #undef  UC
476 #undef  UCS
477 
478 #define CTCE_ACTIONS_PRT(s)     IS_CTCE_WEOF(s)  ? _(" WEOF")  : _("") \
479                               , IS_CTCE_WAIT(s)  ? _(" WAIT")  : _("") \
480                               , IS_CTCE_MATCH(s) ? _(" MATCH") : _("") \
481                               , IS_CTCE_ATTN(s)  ? _(" ATTN")  : _("")
482 
483 #define CTCE_X_STATE_FSM_IDX                                                \
484     ( ( ( pDEVBLK->ctcexState & 0x04 ) == 0x00 ) ? 0x06 : CTCE_STATE( pDEVBLK->ctceyState ) )
485 
486 #define CTCE_Y_STATE_FSM_IDX                                                \
487     ( ( ( pDEVBLK->ctceyState & 0x04 ) == 0x00 ) ? 0x06 : CTCE_STATE( pDEVBLK->ctcexState ) )
488 
489 #define CTCE_NEW_X_STATE(c)                                                 \
490     ( ( CTCE_Fsm[CTCE_CMD( c )][CTCE_X_STATE_FSM_IDX].new_state != 255 ) ?  \
491       ( CTCE_Fsm[CTCE_CMD( c )][CTCE_X_STATE_FSM_IDX].new_state )        :  \
492       ( pDEVBLK->ctcexState & 0x07 ) )
493 
494 #define CTCE_NEW_Y_STATE(c)                                                 \
495     ( ( CTCE_Fsm[CTCE_CMD( c )][CTCE_Y_STATE_FSM_IDX].new_state != 255 ) ?  \
496       ( CTCE_Fsm[CTCE_CMD( c )][CTCE_Y_STATE_FSM_IDX].new_state )        :  \
497       ( pDEVBLK->ctceyState & 0x07 ) )
498 
499 #define CTCE_DISABLE_NAGLE
500 #define CTCE_UDP
501 
502 /* The following macro's attempt to maximize source commonality between  */
503 /* different Hercules versions, whilst adhering to different styles.     */
504 #define CTCX_DEVNUM(p)          p->devnum
505 #define CTCE_FILENAME           pDEVBLK->filename + 2
506 
507 /**********************************************************************/
508 /* This table is used by channel.c to determine if a CCW code is an   */
509 /* immediate command or not                                           */
510 /* The table is addressed in the DEVHND structure as 'DEVIMM immed'   */
511 /* 0 : Command is NOT an immediate command                            */
512 /* 1 : Command is an immediate command                                */
513 /* Note : An immediate command is defined as a command which returns  */
514 /* CE (channel end) during initialisation (that is, no data is        */
515 /* actually transfered). In this case, IL is not indicated for a CCW  */
516 /* Format 0 or for a CCW Format 1 when IL Suppression Mode is in      */
517 /* effect                                                             */
518 /**********************************************************************/
519 
520 static BYTE CTCE_immed_commands[256] =
521 {
522 /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
523    0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1, /* 0x */
524    0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1, /* 1x */
525    0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1, /* 2x */
526    0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1, /* 3x */
527    0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1, /* 4x */
528    0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1, /* 5x */
529    0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1, /* 6x */
530    0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1, /* 7x */
531    0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1, /* 8x */
532    0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1, /* 9x */
533    0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1, /* Ax */
534    0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1, /* Bx */
535    0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1, /* Cx */
536    0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1, /* Dx */
537    0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1, /* Ex */
538    0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1  /* Fx */
539 };
540 
541 //  X0XX X011  No Operation
542 //  MMMM M111  Control
543 //  1100 0011  Set Extended Mode
544 //  10XX X011  Set Basic Mode
545 //  1110 0011  Prepare
546 //  1XXX XX01  Write EOF (but not treated as such !)
547 
548 // --------------------------------------------------------------------
549 // Device Handler Information Block
550 // --------------------------------------------------------------------
551 
552 DEVHND ctcadpt_device_hndinfo =
553 {
554         &CTCX_Init,                    /* Device Initialisation      */
555         &CTCX_ExecuteCCW,              /* Device CCW execute         */
556         &CTCX_Close,                   /* Device Close               */
557         &CTCX_Query,                   /* Device Query               */
558         NULL,                          /* Device Start channel pgm   */
559         NULL,                          /* Device End channel pgm     */
560         NULL,                          /* Device Resume channel pgm  */
561         NULL,                          /* Device Suspend channel pgm */
562         NULL,                          /* Device Read                */
563         NULL,                          /* Device Write               */
564         NULL,                          /* Device Query used          */
565         NULL,                          /* Device Reserve             */
566         NULL,                          /* Device Release             */
567         NULL,                          /* Device Attention           */
568         NULL,                          /* Immediate CCW Codes        */
569         NULL,                          /* Signal Adapter Input       */
570         NULL,                          /* Signal Adapter Output      */
571         NULL,                          /* Hercules suspend           */
572         NULL                           /* Hercules resume            */
573 };
574 
575 DEVHND ctct_device_hndinfo =
576 {
577         &CTCT_Init,                    /* Device Initialisation      */
578         &CTCX_ExecuteCCW,              /* Device CCW execute         */
579         &CTCX_Close,                   /* Device Close               */
580         &CTCX_Query,                   /* Device Query               */
581         NULL,                          /* Device Start channel pgm   */
582         NULL,                          /* Device End channel pgm     */
583         NULL,                          /* Device Resume channel pgm  */
584         NULL,                          /* Device Suspend channel pgm */
585         NULL,                          /* Device Read                */
586         NULL,                          /* Device Write               */
587         NULL,                          /* Device Query used          */
588         NULL,                          /* Device Reserve             */
589         NULL,                          /* Device Release             */
590         NULL,                          /* Device Attention           */
591         NULL,                          /* Immediate CCW Codes        */
592         NULL,                          /* Signal Adapter Input       */
593         NULL,                          /* Signal Adapter Output      */
594         NULL,                          /* Hercules suspend           */
595         NULL                           /* Hercules resume            */
596 };
597 
598 DEVHND ctce_device_hndinfo =
599 {
600         &CTCE_Init,                    /* Device Initialisation      */
601         &CTCE_ExecuteCCW,              /* Device CCW execute         */
602         &CTCX_Close,                   /* Device Close               */
603         &CTCX_Query,                   /* Device Query               */
604         NULL,                          /* Device Start channel pgm   */
605         NULL,                          /* Device End channel pgm     */
606         NULL,                          /* Device Resume channel pgm  */
607         NULL,                          /* Device Suspend channel pgm */
608         NULL,                          /* Device Read                */
609         NULL,                          /* Device Write               */
610         NULL,                          /* Device Query used          */
611         NULL,                          /* Device Reserve             */
612         NULL,                          /* Device Release             */
613         NULL,                          /* Device Attention           */
614         CTCE_immed_commands,           /* Immediate CCW Codes        */
615         NULL,                          /* Signal Adapter Input       */
616         NULL,                          /* Signal Adapter Output      */
617         NULL,                          /* Hercules suspend           */
618         NULL                           /* Hercules resume            */
619 };
620 
621 DEVHND vmnet_device_hndinfo =
622 {
623         &VMNET_Init,                   /* Device Initialisation      */
624         &CTCX_ExecuteCCW,              /* Device CCW execute         */
625         &CTCX_Close,                   /* Device Close               */
626         &CTCX_Query,                   /* Device Query               */
627         NULL,                          /* Device Start channel pgm   */
628         NULL,                          /* Device End channel pgm     */
629         NULL,                          /* Device Resume channel pgm  */
630         NULL,                          /* Device Suspend channel pgm */
631         NULL,                          /* Device Read                */
632         NULL,                          /* Device Write               */
633         NULL,                          /* Device Query used          */
634         NULL,                          /* Device Reserve             */
635         NULL,                          /* Device Release             */
636         NULL,                          /* Device Attention           */
637         NULL,                          /* Immediate CCW Codes        */
638         NULL,                          /* Signal Adapter Input       */
639         NULL,                          /* Signal Adapter Output      */
640         NULL,                          /* Hercules suspend           */
641         NULL                           /* Hercules resume            */
642 };
643 
644 extern DEVHND ctci_device_hndinfo;
645 extern DEVHND lcs_device_hndinfo;
646 
647 // ====================================================================
648 // Primary Module Entry Points
649 // ====================================================================
650 
651 // --------------------------------------------------------------------
652 // Device Initialization Handler (Generic)
653 // --------------------------------------------------------------------
654 
CTCX_Init(DEVBLK * pDEVBLK,int argc,char * argv[])655 int  CTCX_Init( DEVBLK* pDEVBLK, int argc, char *argv[] )
656 {
657     pDEVBLK->devtype = 0x3088;
658 
659     // The first argument is the device emulation type
660     if( argc < 1 )
661     {
662         logmsg( _("HHCCT001E %4.4X: Incorrect number of parameters\n"),
663             pDEVBLK->devnum );
664         return -1;
665     }
666 
667     if((pDEVBLK->hnd = hdl_ghnd(argv[0])))
668     {
669         if(pDEVBLK->hnd->init == &CTCX_Init)
670             return -1;
671         free(pDEVBLK->typname);
672         pDEVBLK->typname = strdup(argv[0]);
673         return (pDEVBLK->hnd->init)( pDEVBLK, --argc, ++argv );
674     }
675     logmsg (_("HHCCT034E %s: Unrecognized/unsupported CTC emulation type\n"),
676         argv[0]);
677     return -1;
678 }
679 
680 // -------------------------------------------------------------------
681 // Query the device definition (Generic)
682 // -------------------------------------------------------------------
683 
CTCX_Query(DEVBLK * pDEVBLK,char ** ppszClass,int iBufLen,char * pBuffer)684 void  CTCX_Query( DEVBLK* pDEVBLK,
685                   char**  ppszClass,
686                   int     iBufLen,
687                   char*   pBuffer )
688 {
689     BEGIN_DEVICE_CLASS_QUERY( "CTCA", pDEVBLK, ppszClass, iBufLen, pBuffer );
690 
691     snprintf( pBuffer, iBufLen, "%s", pDEVBLK->filename );
692 }
693 
694 // -------------------------------------------------------------------
695 // Close the device (Generic)
696 // -------------------------------------------------------------------
697 
CTCX_Close(DEVBLK * pDEVBLK)698 int  CTCX_Close( DEVBLK* pDEVBLK )
699 {
700 
701     // Close the device file (if not already closed)
702     if( pDEVBLK->fd >= 0 )
703     {
704         if (socket_is_socket( pDEVBLK->fd ))
705             close_socket( pDEVBLK->fd );
706         else
707             close( pDEVBLK->fd );
708         pDEVBLK->fd = -1;           // indicate we're now closed
709     }
710     return 0;
711 }
712 
713 // -------------------------------------------------------------------
714 // Execute a Channel Command Word (Generic)
715 // -------------------------------------------------------------------
716 
CTCX_ExecuteCCW(DEVBLK * pDEVBLK,BYTE bCode,BYTE bFlags,BYTE bChained,U16 sCount,BYTE bPrevCode,int iCCWSeq,BYTE * pIOBuf,BYTE * pMore,BYTE * pUnitStat,U16 * pResidual)717 void  CTCX_ExecuteCCW( DEVBLK* pDEVBLK, BYTE  bCode,
718                        BYTE    bFlags,  BYTE  bChained,
719                        U16     sCount,  BYTE  bPrevCode,
720                        int     iCCWSeq, BYTE* pIOBuf,
721                        BYTE*   pMore,   BYTE* pUnitStat,
722                        U16*    pResidual )
723 {
724     int             iNum;               // Number of bytes to move
725     BYTE            bOpCode;            // CCW opcode with modifier
726                                         //   bits masked off
727 
728     UNREFERENCED( bFlags    );
729     UNREFERENCED( bChained  );
730     UNREFERENCED( bPrevCode );
731     UNREFERENCED( iCCWSeq   );
732 
733     // Intervention required if the device file is not open
734     if( pDEVBLK->fd < 0 &&
735         !IS_CCW_SENSE( bCode ) &&
736         !IS_CCW_CONTROL( bCode ) )
737     {
738         pDEVBLK->sense[0] = SENSE_IR;
739         *pUnitStat = CSW_CE | CSW_DE | CSW_UC;
740         return;
741     }
742 
743     // Mask off the modifier bits in the CCW bOpCode
744     if( ( bCode & 0x07 ) == 0x07 )
745         bOpCode = 0x07;
746     else if( ( bCode & 0x03 ) == 0x02 )
747         bOpCode = 0x02;
748     else if( ( bCode & 0x0F ) == 0x0C )
749         bOpCode = 0x0C;
750     else if( ( bCode & 0x03 ) == 0x01 )
751         bOpCode = pDEVBLK->ctcxmode ? ( bCode & 0x83 ) : 0x01;
752     else if( ( bCode & 0x1F ) == 0x14 )
753         bOpCode = 0x14;
754     else if( ( bCode & 0x47 ) == 0x03 )
755         bOpCode = 0x03;
756     else if( ( bCode & 0xC7 ) == 0x43 )
757         bOpCode = 0x43;
758     else
759         bOpCode = bCode;
760 
761     // Process depending on CCW bOpCode
762     switch (bOpCode)
763     {
764     case 0x01:  // 0MMMMM01  WRITE
765         //------------------------------------------------------------
766         // WRITE
767         //------------------------------------------------------------
768 
769         // Return normal status if CCW count is zero
770         if( sCount == 0 )
771         {
772             *pUnitStat = CSW_CE | CSW_DE;
773             break;
774         }
775 
776         // Write data and set unit status and residual byte count
777         switch( pDEVBLK->ctctype )
778         {
779         case CTC_CTCT:
780             CTCT_Write( pDEVBLK, sCount, pIOBuf, pUnitStat, pResidual );
781             break;
782         case CTC_VMNET:
783             *pResidual = sCount - VMNET_Write( pDEVBLK, pIOBuf,
784                                                sCount,  pUnitStat );
785             break;
786         }
787         break;
788 
789     case 0x81:  // 1MMMMM01  WEOF
790         //------------------------------------------------------------
791         // WRITE EOF
792         //------------------------------------------------------------
793 
794         // Return normal status
795         *pUnitStat = CSW_CE | CSW_DE;
796         break;
797 
798     case 0x02:  // MMMMMM10  READ
799     case 0x0C:  // MMMM1100  RDBACK
800         // -----------------------------------------------------------
801         // READ & READ BACKWARDS
802         // -----------------------------------------------------------
803 
804         // Read data and set unit status and residual byte count
805         switch( pDEVBLK->ctctype )
806         {
807         case CTC_CTCT:
808             CTCT_Read( pDEVBLK, sCount, pIOBuf, pUnitStat, pResidual, pMore );
809             break;
810         case CTC_VMNET:
811             *pResidual = sCount - VMNET_Read( pDEVBLK, pIOBuf,
812                                               sCount,  pUnitStat );
813             break;
814         }
815         break;
816 
817     case 0x07:  // MMMMM111  CTL
818         // -----------------------------------------------------------
819         // CONTROL
820         // -----------------------------------------------------------
821 
822         *pUnitStat = CSW_CE | CSW_DE;
823         break;
824 
825     case 0x03:  // M0MMM011  NOP
826         // -----------------------------------------------------------
827         // CONTROL NO-OPERATON
828         // -----------------------------------------------------------
829 
830         *pUnitStat = CSW_CE | CSW_DE;
831         break;
832 
833     case 0x43:  // 00XXX011  SBM
834         // -----------------------------------------------------------
835         // SET BASIC MODE
836         // -----------------------------------------------------------
837 
838         // Command reject if in basic mode
839         if( pDEVBLK->ctcxmode == 0 )
840         {
841             pDEVBLK->sense[0] = SENSE_CR;
842             *pUnitStat        = CSW_CE | CSW_DE | CSW_UC;
843 
844             break;
845         }
846 
847         // Reset extended mode and return normal status
848         pDEVBLK->ctcxmode = 0;
849 
850         *pResidual = 0;
851         *pUnitStat = CSW_CE | CSW_DE;
852 
853         break;
854 
855     case 0xC3:  // 11000011  SEM
856         // -----------------------------------------------------------
857         // SET EXTENDED MODE
858         // -----------------------------------------------------------
859 
860         pDEVBLK->ctcxmode = 1;
861 
862         *pResidual = 0;
863         *pUnitStat = CSW_CE | CSW_DE;
864 
865         break;
866 
867     case 0xE3:  // 11100011
868         // -----------------------------------------------------------
869         // PREPARE (PREP)
870         // -----------------------------------------------------------
871 
872         *pUnitStat = CSW_CE | CSW_DE;
873 
874         break;
875 
876     case 0x14:  // XXX10100  SCB
877         // -----------------------------------------------------------
878         // SENSE COMMAND BYTE
879         // -----------------------------------------------------------
880 
881         *pUnitStat = CSW_CE | CSW_DE;
882         break;
883 
884     case 0x04:  // 00000100  SENSE
885       // -----------------------------------------------------------
886       // SENSE
887       // -----------------------------------------------------------
888 
889         // Command reject if in basic mode
890         if( pDEVBLK->ctcxmode == 0 )
891         {
892             pDEVBLK->sense[0] = SENSE_CR;
893             *pUnitStat        = CSW_CE | CSW_DE | CSW_UC;
894             break;
895         }
896 
897         // Calculate residual byte count
898         iNum = ( sCount < pDEVBLK->numsense ) ?
899             sCount : pDEVBLK->numsense;
900 
901         *pResidual = sCount - iNum;
902 
903         if( sCount < pDEVBLK->numsense )
904             *pMore = 1;
905 
906         // Copy device sense bytes to channel I/O buffer
907         memcpy( pIOBuf, pDEVBLK->sense, iNum );
908 
909         // Clear the device sense bytes
910         memset( pDEVBLK->sense, 0, sizeof( pDEVBLK->sense ) );
911 
912         // Return unit status
913         *pUnitStat = CSW_CE | CSW_DE;
914 
915         break;
916 
917     case 0xE4:  //  11100100  SID
918         // -----------------------------------------------------------
919         // SENSE ID
920         // -----------------------------------------------------------
921 
922         // Calculate residual byte count
923         iNum = ( sCount < pDEVBLK->numdevid ) ?
924             sCount : pDEVBLK->numdevid;
925 
926         *pResidual = sCount - iNum;
927 
928         if( sCount < pDEVBLK->numdevid )
929             *pMore = 1;
930 
931         // Copy device identifier bytes to channel I/O buffer
932         memcpy( pIOBuf, pDEVBLK->devid, iNum );
933 
934         // Return unit status
935         *pUnitStat = CSW_CE | CSW_DE;
936 
937         break;
938 
939     default:
940         // ------------------------------------------------------------
941         // INVALID OPERATION
942         // ------------------------------------------------------------
943 
944         // Set command reject sense byte, and unit check status
945         pDEVBLK->sense[0] = SENSE_CR;
946         *pUnitStat        = CSW_CE | CSW_DE | CSW_UC;
947     }
948 }
949 
950 // ====================================================================
951 // CTCT Support
952 // ====================================================================
953 
954 //
955 // CTCT_Init
956 //
957 
CTCT_Init(DEVBLK * dev,int argc,char * argv[])958 static int  CTCT_Init( DEVBLK *dev, int argc, char *argv[] )
959 {
960     char           str[80];            // Thread name
961     int            rc;                 // Return code
962     int            mtu;                // MTU size (binary)
963     int            lport;              // Listen port (binary)
964     int            rport;              // Destination port (binary)
965     char*          listenp;            // Listening port number
966     char*          remotep;            // Destination port number
967     char*          mtusize;            // MTU size (characters)
968     char*          remaddr;            // Remote IP address
969     struct in_addr ipaddr;             // Work area for IP address
970     BYTE           c;                  // Character work area
971     TID            tid;                // Thread ID for server
972     CTCG_PARMBLK   parm;               // Parameters for the server
973     char           address[20]="";     // temp space for IP address
974 
975     dev->devtype = 0x3088;
976 
977     dev->ctctype = CTC_CTCT;
978 
979     SetSIDInfo( dev, 0x3088, 0x08, 0x3088, 0x01 );
980 
981     // Check for correct number of arguments
982     if (argc != 4)
983     {
984         logmsg( _("HHCCT002E %4.4X: Incorrect number of parameters\n"),
985                 dev->devnum );
986         return -1;
987     }
988 
989     // The first argument is the listening port number
990     listenp = *argv++;
991 
992     if( strlen( listenp ) > 5 ||
993         sscanf( listenp, "%u%c", &lport, &c ) != 1 ||
994         lport < 1024 || lport > 65534 )
995     {
996         logmsg( _("HHCCT003E %4.4X: Invalid port number: %s\n"),
997                 dev->devnum, listenp );
998         return -1;
999     }
1000 
1001     // The second argument is the IP address or hostname of the
1002     // remote side of the point-to-point link
1003     remaddr = *argv++;
1004 
1005     if( inet_aton( remaddr, &ipaddr ) == 0 )
1006     {
1007         struct hostent *hp;
1008 
1009         if( ( hp = gethostbyname( remaddr ) ) != NULL )
1010         {
1011             memcpy( &ipaddr, hp->h_addr, hp->h_length );
1012             strcpy( address, inet_ntoa( ipaddr ) );
1013             remaddr = address;
1014         }
1015         else
1016         {
1017             logmsg( _("HHCCT004E %4.4X: Invalid IP address %s\n"),
1018                     dev->devnum, remaddr );
1019             return -1;
1020         }
1021     }
1022 
1023     // The third argument is the destination port number
1024     remotep = *argv++;
1025 
1026     if( strlen( remotep ) > 5 ||
1027         sscanf( remotep, "%u%c", &rport, &c ) != 1 ||
1028         rport < 1024 || rport > 65534 )
1029     {
1030         logmsg( _("HHCCT005E %4.4X: Invalid port number: %s\n"),
1031                 dev->devnum, remotep );
1032         return -1;
1033     }
1034 
1035     // The fourth argument is the maximum transmission unit (MTU) size
1036     mtusize = *argv;
1037 
1038     if( strlen( mtusize ) > 5 ||
1039         sscanf( mtusize, "%u%c", &mtu, &c ) != 1 ||
1040         mtu < 46 || mtu > 65536 )
1041     {
1042         logmsg( _("HHCCT006E %4.4X: Invalid MTU size %s\n"),
1043                 dev->devnum, mtusize );
1044         return -1;
1045     }
1046 
1047     // Set the device buffer size equal to the MTU size
1048     dev->bufsize = mtu;
1049 
1050     // Initialize the file descriptor for the socket connection
1051 
1052     // It's a little confusing, but we're using a couple of the
1053     // members of the server paramter structure to initiate the
1054     // outgoing connection.  Saves a couple of variable declarations,
1055     // though.  If we feel strongly about it, we can declare separate
1056     // variables...
1057 
1058     // make a TCP socket
1059     parm.listenfd = socket( AF_INET, SOCK_STREAM, 0 );
1060 
1061     if( parm.listenfd < 0 )
1062     {
1063         logmsg( _("HHCCT007E %4.4X: Error creating socket: %s\n"),
1064                 dev->devnum, strerror( HSO_errno ) );
1065         CTCX_Close( dev );
1066         return -1;
1067     }
1068 
1069     // bind socket to our local port
1070     // (might seem like overkill, and usually isn't done, but doing this
1071     // bind() to the local port we configure gives the other end a chance
1072     // at validating the connection request)
1073     memset( &(parm.addr), 0, sizeof( parm.addr ) );
1074     parm.addr.sin_family      = AF_INET;
1075     parm.addr.sin_port        = htons(lport);
1076     parm.addr.sin_addr.s_addr = htonl(INADDR_ANY);
1077 
1078     rc = bind( parm.listenfd,
1079                (struct sockaddr *)&parm.addr,
1080                sizeof( parm.addr ) );
1081     if( rc < 0 )
1082     {
1083         logmsg( _("HHCCT008E %4.4X: Error binding to socket: %s\n"),
1084                 dev->devnum, strerror( HSO_errno ) );
1085         CTCX_Close( dev );
1086         return -1;
1087     }
1088 
1089     // initiate a connection to the other end
1090     memset( &(parm.addr), 0, sizeof( parm.addr ) );
1091     parm.addr.sin_family = AF_INET;
1092     parm.addr.sin_port   = htons(rport);
1093     parm.addr.sin_addr   = ipaddr;
1094     rc = connect( parm.listenfd,
1095                   (struct sockaddr *)&parm.addr,
1096                   sizeof( parm.addr ) );
1097 
1098     // if connection was not successful, start a server
1099     if( rc < 0 )
1100     {
1101         // used to pass parameters to the server thread
1102         CTCG_PARMBLK* arg;
1103 
1104         logmsg( _("HHCCT009I %4.4X: Connect to %s:%s failed, starting server\n"),
1105                 dev->devnum, remaddr, remotep );
1106 
1107         // probably don't need to do this, not sure...
1108         close_socket( parm.listenfd );
1109 
1110         parm.listenfd = socket( AF_INET, SOCK_STREAM, 0 );
1111 
1112         if( parm.listenfd < 0 )
1113         {
1114             logmsg( _("HHCCT010E %4.4X: Error creating socket: %s\n"),
1115                     dev->devnum, strerror( HSO_errno ) );
1116             CTCX_Close( dev );
1117             return -1;
1118         }
1119 
1120         // set up the listening port
1121         memset( &(parm.addr), 0, sizeof( parm.addr ) );
1122 
1123         parm.addr.sin_family      = AF_INET;
1124         parm.addr.sin_port        = htons(lport);
1125         parm.addr.sin_addr.s_addr = htonl(INADDR_ANY);
1126 
1127         if( bind( parm.listenfd,
1128                   (struct sockaddr *)&parm.addr,
1129                   sizeof( parm.addr ) ) < 0 )
1130         {
1131             logmsg( _("HHCCT011E %4.4X: Error binding to socket: %s\n"),
1132                     dev->devnum, strerror( HSO_errno ) );
1133             CTCX_Close( dev );
1134             return -1;
1135         }
1136 
1137         if( listen( parm.listenfd, 1 ) < 0 )
1138         {
1139             logmsg( _("HHCCT012E %4.4X: Error on call to listen: %s\n"),
1140                     dev->devnum, strerror( HSO_errno ) );
1141             CTCX_Close( dev );
1142             return -1;
1143         }
1144 
1145         // we are listening, so create a thread to accept connection
1146         arg = malloc( sizeof( CTCG_PARMBLK ) );
1147         memcpy( arg, &parm, sizeof( parm ) );
1148         arg->dev = dev;
1149         snprintf(str,sizeof(str),"CTCT %4.4X ListenThread",dev->devnum);
1150         str[sizeof(str)-1]=0;
1151         create_thread( &tid, JOINABLE, CTCT_ListenThread, arg, str );
1152     }
1153     else  // successfully connected (outbound) to the other end
1154     {
1155         logmsg( _("HHCCT013I %4.4X: Connected to %s:%s\n"),
1156                 dev->devnum, remaddr, remotep );
1157         dev->fd = parm.listenfd;
1158     }
1159 
1160     // for cosmetics, since we are successfully connected or serving,
1161     // fill in some details for the panel.
1162     sprintf( dev->filename, "%s:%s", remaddr, remotep );
1163 
1164     return 0;
1165 }
1166 
1167 //
1168 // CTCT_Write
1169 //
1170 
CTCT_Write(DEVBLK * pDEVBLK,U16 sCount,BYTE * pIOBuf,BYTE * pUnitStat,U16 * pResidual)1171 static void  CTCT_Write( DEVBLK* pDEVBLK,   U16   sCount,
1172                          BYTE*   pIOBuf,    BYTE* pUnitStat,
1173                          U16*    pResidual )
1174 {
1175     PCTCIHDR   pFrame;                  // -> Frame header
1176     PCTCISEG   pSegment;                // -> Segment in buffer
1177     U16        sOffset;                 // Offset of next frame
1178     U16        sSegLen;                 // Current segment length
1179     U16        sDataLen;                // Length of IP Frame data
1180     int        iPos;                    // Offset into buffer
1181     U16        i;                       // Array subscript
1182     int        rc;                      // Return code
1183     BYTE       szStackID[33];           // VSE IP stack identity
1184     U32        iStackCmd;               // VSE IP stack command
1185 
1186     // Check that CCW count is sufficient to contain block header
1187     if( sCount < sizeof( CTCIHDR ) )
1188     {
1189         logmsg( _("HHCCT014E %4.4X: Write CCW count %u is invalid\n"),
1190                 pDEVBLK->devnum, sCount );
1191 
1192         pDEVBLK->sense[0] = SENSE_DC;
1193         *pUnitStat        = CSW_CE | CSW_DE | CSW_UC;
1194         return;
1195     }
1196 
1197     // Fix-up frame pointer
1198     pFrame = (PCTCIHDR)pIOBuf;
1199 
1200     // Extract the frame length from the header
1201     FETCH_HW( sOffset, pFrame->hwOffset );
1202 
1203 
1204     // Check for special VSE TCP/IP stack command packet
1205     if( sOffset == 0 && sCount == 40 )
1206     {
1207         // Extract the 32-byte stack identity string
1208         for( i = 0;
1209              i < sizeof( szStackID ) - 1 && i < sCount - 4;
1210              i++)
1211             szStackID[i] = guest_to_host( pIOBuf[i+4] );
1212 
1213         szStackID[i] = '\0';
1214 
1215         // Extract the stack command word
1216         FETCH_FW( iStackCmd, *((FWORD*)&pIOBuf[36]) );
1217 
1218         // Display stack command and discard the packet
1219         logmsg( _("HHCCT015I %4.4X: Interface command: %s %8.8X\n"),
1220                 pDEVBLK->devnum, szStackID, iStackCmd );
1221 
1222         *pUnitStat = CSW_CE | CSW_DE;
1223         *pResidual = 0;
1224         return;
1225     }
1226 
1227     // Check for special L/390 initialization packet
1228     if( sOffset == 0 )
1229     {
1230         // Return normal status and discard the packet
1231         *pUnitStat = CSW_CE | CSW_DE;
1232         *pResidual = 0;
1233         return;
1234     }
1235 
1236     // Adjust the residual byte count
1237     *pResidual -= sizeof( CTCIHDR );
1238 
1239     // Process each segment in the buffer
1240     for( iPos  = sizeof( CTCIHDR );
1241          iPos  < sOffset;
1242          iPos += sSegLen )
1243     {
1244         // Check that the segment is fully contained within the block
1245         if( iPos + sizeof( CTCISEG ) > sOffset )
1246         {
1247             logmsg( _("HHCCT016E %4.4X: Write buffer contains incomplete "
1248                       "segment header at offset %4.4X\n"),
1249                     pDEVBLK->devnum, iPos );
1250 
1251             pDEVBLK->sense[0] = SENSE_DC;
1252             *pUnitStat        = CSW_CE | CSW_DE | CSW_UC;
1253             return;
1254         }
1255 
1256         // Fix-up segment header in the I/O buffer
1257         pSegment = (PCTCISEG)(pIOBuf + iPos);
1258 
1259         // Extract the segment length from the segment header
1260         FETCH_HW( sSegLen, pSegment->hwLength );
1261 
1262         // Check that the segment length is valid
1263         if( ( sSegLen        < sizeof( CTCISEG ) ) ||
1264             ( iPos + sSegLen > sOffset           ) ||
1265             ( iPos + sSegLen > sCount            ) )
1266         {
1267             logmsg( _("HHCCT017E %4.4X: Write buffer contains invalid "
1268                     "segment length %u at offset %4.4X\n"),
1269                     pDEVBLK->devnum, sSegLen, iPos );
1270 
1271             pDEVBLK->sense[0] = SENSE_DC;
1272             *pUnitStat        = CSW_CE | CSW_DE | CSW_UC;
1273             return;
1274         }
1275 
1276         // Calculate length of IP frame data
1277         sDataLen = sSegLen - sizeof( CTCISEG );
1278 
1279         // Trace the IP packet before sending
1280         if( pDEVBLK->ccwtrace || pDEVBLK->ccwstep )
1281         {
1282             logmsg( _("HHCCT018I %4.4X: Sending packet to %s:\n"),
1283                     pDEVBLK->devnum, pDEVBLK->filename );
1284             if( pDEVBLK->ccwtrace )
1285                 packet_trace( pSegment->bData, sDataLen );
1286         }
1287 
1288         // Write the IP packet
1289         rc = write_socket( pDEVBLK->fd, pSegment->bData, sDataLen );
1290 
1291         if( rc < 0 )
1292         {
1293             logmsg( _("HHCCT019E %4.4X: Error writing to %s: %s\n"),
1294                     pDEVBLK->devnum, pDEVBLK->filename,
1295                     strerror( HSO_errno ) );
1296 
1297             pDEVBLK->sense[0] = SENSE_EC;
1298             *pUnitStat        = CSW_CE | CSW_DE | CSW_UC;
1299             return;
1300         }
1301 
1302         // Adjust the residual byte count
1303         *pResidual -= sSegLen;
1304 
1305         // We are done if current segment satisfies CCW count
1306         if( iPos + sSegLen == sCount )
1307         {
1308             *pResidual -= sSegLen;
1309             *pUnitStat = CSW_CE | CSW_DE;
1310             return;
1311         }
1312     }
1313 
1314     // Set unit status and residual byte count
1315     *pUnitStat = CSW_CE | CSW_DE;
1316     *pResidual = 0;
1317 }
1318 
1319 //
1320 // CTCT_Read
1321 //
1322 
CTCT_Read(DEVBLK * pDEVBLK,U16 sCount,BYTE * pIOBuf,BYTE * pUnitStat,U16 * pResidual,BYTE * pMore)1323 static void  CTCT_Read( DEVBLK* pDEVBLK,   U16   sCount,
1324                         BYTE*   pIOBuf,    BYTE* pUnitStat,
1325                         U16*    pResidual, BYTE* pMore )
1326 {
1327     PCTCIHDR    pFrame   = NULL;       // -> Frame header
1328     PCTCISEG    pSegment = NULL;       // -> Segment in buffer
1329     fd_set      rfds;                  // Read FD_SET
1330     int         iRetVal;               // Return code from 'select'
1331     ssize_t     iLength  = 0;
1332 
1333     static struct timeval tv;          // Timeout time for 'select'
1334 
1335 
1336     // Limit how long we should wait for data to come in
1337     FD_ZERO( &rfds );
1338     FD_SET( pDEVBLK->fd, &rfds );
1339 
1340     tv.tv_sec  = CTC_READ_TIMEOUT_SECS;
1341     tv.tv_usec = 0;
1342 
1343     iRetVal = select( pDEVBLK->fd + 1, &rfds, NULL, NULL, &tv );
1344 
1345     switch( iRetVal )
1346     {
1347     case 0:
1348         *pUnitStat = CSW_CE | CSW_DE | CSW_UC | CSW_SM;
1349         pDEVBLK->sense[0] = 0;
1350         return;
1351 
1352     case -1:
1353         if( HSO_errno == HSO_EINTR )
1354             return;
1355 
1356         logmsg( _("HHCCT020E %4.4X: Error reading from %s: %s\n"),
1357                 pDEVBLK->devnum, pDEVBLK->filename, strerror( HSO_errno ) );
1358 
1359         pDEVBLK->sense[0] = SENSE_EC;
1360         *pUnitStat = CSW_CE | CSW_DE | CSW_UC;
1361         return;
1362 
1363     default:
1364         break;
1365     }
1366 
1367     // Read an IP packet from the TUN device
1368     iLength = read_socket( pDEVBLK->fd, pDEVBLK->buf, pDEVBLK->bufsize );
1369 
1370     // Check for other error condition
1371     if( iLength < 0 )
1372     {
1373         logmsg( _("HHCCT021E %4.4X: Error reading from %s: %s\n"),
1374                 pDEVBLK->devnum, pDEVBLK->filename, strerror( HSO_errno ) );
1375         pDEVBLK->sense[0] = SENSE_EC;
1376         *pUnitStat = CSW_CE | CSW_DE | CSW_UC;
1377         return;
1378     }
1379 
1380     // Trace the packet received from the TUN device
1381     if( pDEVBLK->ccwtrace || pDEVBLK->ccwstep )
1382     {
1383         logmsg( _("HHCCT022I %4.4X: Received packet from %s (%d bytes):\n"),
1384                 pDEVBLK->devnum, pDEVBLK->filename, iLength );
1385         packet_trace( pDEVBLK->buf, iLength );
1386     }
1387 
1388     // Fix-up Frame pointer
1389     pFrame = (PCTCIHDR)pIOBuf;
1390 
1391     // Fix-up Segment pointer
1392     pSegment = (PCTCISEG)( pIOBuf + sizeof( CTCIHDR ) );
1393 
1394     // Initialize segment
1395     memset( pSegment, 0, iLength + sizeof( CTCISEG ) );
1396 
1397     // Update next frame offset
1398     STORE_HW( pFrame->hwOffset,
1399               iLength + sizeof( CTCIHDR ) + sizeof( CTCISEG ) );
1400 
1401     // Store segment length
1402     STORE_HW( pSegment->hwLength, iLength + sizeof( CTCISEG ) );
1403 
1404     // Store Frame type
1405     STORE_HW( pSegment->hwType, ETH_TYPE_IP );
1406 
1407     // Copy data
1408     memcpy( pSegment->bData, pDEVBLK->buf, iLength );
1409 
1410     // Fix-up frame pointer and terminate block
1411     pFrame = (PCTCIHDR)( pIOBuf + sizeof( CTCIHDR ) +
1412                          sizeof( CTCISEG ) + iLength );
1413     STORE_HW( pFrame->hwOffset, 0x0000 );
1414 
1415     // Calculate #of bytes returned including two slack bytes
1416     iLength += sizeof( CTCIHDR ) + sizeof( CTCISEG ) + 2;
1417 
1418     if( sCount < iLength )
1419     {
1420         *pMore     = 1;
1421         *pResidual = 0;
1422 
1423         iLength    = sCount;
1424     }
1425     else
1426     {
1427         *pMore      = 0;
1428         *pResidual -= iLength;
1429     }
1430 
1431     // Set unit status
1432     *pUnitStat = CSW_CE | CSW_DE;
1433 }
1434 
1435 //
1436 // CTCT_ListenThread
1437 //
1438 
CTCT_ListenThread(void * argp)1439 static void*  CTCT_ListenThread( void* argp )
1440 {
1441     int          connfd;
1442     socklen_t    servlen;
1443     char         str[80];
1444     CTCG_PARMBLK parm;
1445 
1446     // set up the parameters passed via create_thread
1447     parm = *((CTCG_PARMBLK*) argp);
1448     free( argp );
1449 
1450     for( ; ; )
1451     {
1452         servlen = sizeof(parm.addr);
1453 
1454         // await a connection
1455         connfd = accept( parm.listenfd,
1456                          (struct sockaddr *)&parm.addr,
1457                          &servlen );
1458 
1459         sprintf( str, "%s:%d",
1460                  inet_ntoa( parm.addr.sin_addr ),
1461                  ntohs( parm.addr.sin_port ) );
1462 
1463         if( strcmp( str, parm.dev->filename ) != 0 )
1464         {
1465             logmsg( _("HHCCT023E %4.4X: Incorrect client or config error\n"
1466                       "                 Config=%s, connecting client=%s\n"),
1467                     parm.dev->devnum,
1468                     parm.dev->filename, str);
1469             close_socket( connfd );
1470         }
1471         else
1472         {
1473             parm.dev->fd = connfd;
1474         }
1475 
1476         // Ok, so having done that we're going to loop back to the
1477         // accept().  This was meant to handle the connection failing
1478         // at the other end; this end will be ready to accept another
1479         // connection.  Although this will happen, I'm sure you can
1480         // see the possibility for bad things to occur (eg if another
1481         // Hercules tries to connect).  This will also be fixed RSN.
1482     }
1483 
1484     return NULL;    // make compiler happy
1485 }
1486 
1487 // ====================================================================
1488 // VMNET Support -- written by Willem Konynenberg
1489 // ====================================================================
1490 
1491 /*-------------------------------------------------------------------*/
1492 /* Definitions for SLIP encapsulation                                */
1493 /*-------------------------------------------------------------------*/
1494 #define SLIP_END        0300
1495 #define SLIP_ESC        0333
1496 #define SLIP_ESC_END    0334
1497 #define SLIP_ESC_ESC    0335
1498 
1499 /*-------------------------------------------------------------------*/
1500 /* Functions to support vmnet written by Willem Konynenberg          */
1501 /*-------------------------------------------------------------------*/
start_vmnet(DEVBLK * dev,DEVBLK * xdev,int argc,char * argv[])1502 static int start_vmnet(DEVBLK *dev, DEVBLK *xdev, int argc, char *argv[])
1503 {
1504 int sockfd[2];
1505 int r, i;
1506 char *ipaddress;
1507 
1508     if (argc < 2) {
1509         logmsg (_("HHCCT024E %4.4X: Not enough arguments to start vmnet\n"),
1510                         dev->devnum);
1511         return -1;
1512     }
1513 
1514     ipaddress = argv[0];
1515     argc--;
1516     argv++;
1517 
1518     if (socketpair (AF_UNIX, SOCK_STREAM, 0, sockfd) < 0) {
1519         logmsg (_("HHCCT025E %4.4X: Failed: socketpair: %s\n"),
1520                         dev->devnum, strerror(errno));
1521         return -1;
1522     }
1523 
1524     r = fork ();
1525 
1526     if (r < 0) {
1527         logmsg (_("HHCCT026E %4.4X: Failed: fork: %s\n"),
1528                         dev->devnum, strerror(errno));
1529         return -1;
1530     } else if (r == 0) {
1531         /* child */
1532         close (0);
1533         close (1);
1534         dup (sockfd[1]);
1535         dup (sockfd[1]);
1536         r = (sockfd[0] > sockfd[1]) ? sockfd[0] : sockfd[1];
1537         for (i = 3; i <= r; i++) {
1538             close (i);
1539         }
1540 
1541         /* the ugly cast is to silence a compiler warning due to const */
1542         execv (argv[0], (EXECV_ARG2_ARGV_T)argv);
1543 
1544         exit (1);
1545     }
1546 
1547     close (sockfd[1]);
1548     dev->fd = sockfd[0];
1549     xdev->fd = sockfd[0];
1550 
1551     /* We just blindly copy these out in the hope vmnet will pick them
1552      * up correctly.  I don't feel like implementing a complete login
1553      * scripting facility here...
1554      */
1555     write(dev->fd, ipaddress, strlen(ipaddress));
1556     write(dev->fd, "\n", 1);
1557     return 0;
1558 }
1559 
VMNET_Init(DEVBLK * dev,int argc,char * argv[])1560 static int VMNET_Init(DEVBLK *dev, int argc, char *argv[])
1561 {
1562 U16             xdevnum;                /* Pair device devnum        */
1563 DEVBLK          *xdev;                  /* Pair device               */
1564 int rc;
1565 U16 lcss;
1566 
1567     dev->devtype = 0x3088;
1568 
1569     /* parameters for network CTC are:
1570      *    devnum of the other CTC device of the pair
1571      *    ipaddress
1572      *    vmnet command line
1573      *
1574      * CTC adapters are used in pairs, one for READ, one for WRITE.
1575      * The vmnet is only initialised when both are initialised.
1576      */
1577     if (argc < 3) {
1578         logmsg(_("HHCCT027E %4.4X: Not enough parameters\n"), dev->devnum);
1579         return -1;
1580     }
1581     rc=parse_single_devnum(argv[0],&lcss,&xdevnum);
1582     if (rc<0)
1583     {
1584         logmsg(_("HHCCT028E %d:%4.4X: Bad device number '%s'\n"),
1585                   SSID_TO_LCSS(dev->ssid), dev->devnum, argv[0]);
1586         return -1;
1587     }
1588     xdev = find_device_by_devnum(lcss,xdevnum);
1589     if (xdev != NULL) {
1590         if (start_vmnet(dev, xdev, argc - 1, &argv[1]))
1591             return -1;
1592     }
1593     strcpy(dev->filename, "vmnet");
1594 
1595     /* Set the control unit type */
1596     /* Linux/390 currently only supports 3088 model 2 CTCA and ESCON */
1597     dev->ctctype = CTC_VMNET;
1598 
1599     SetSIDInfo( dev, 0x3088, 0x08, 0x3088, 0x01 );
1600 
1601     /* Initialize the device dependent fields */
1602     dev->ctcpos = 0;
1603     dev->ctcrem = 0;
1604 
1605     /* Set length of buffer */
1606     /* This size guarantees we can write a full iobuf of 65536
1607      * as a SLIP packet in a single write.  Probably overkill... */
1608     dev->bufsize = 65536 * 2 + 1;
1609     return 0;
1610 }
1611 
VMNET_Write(DEVBLK * dev,BYTE * iobuf,U16 count,BYTE * unitstat)1612 static int VMNET_Write(DEVBLK *dev, BYTE *iobuf, U16 count, BYTE *unitstat)
1613 {
1614 int blklen = (iobuf[0]<<8) | iobuf[1];
1615 int pktlen;
1616 BYTE *p = iobuf + 2;
1617 BYTE *buffer = dev->buf;
1618 int len = 0, rem;
1619 
1620     if (count < blklen) {
1621         logmsg (_("HHCCT029E %4.4X: bad block length: %d < %d\n"),
1622                 dev->devnum, count, blklen);
1623         blklen = count;
1624     }
1625     while (p < iobuf + blklen) {
1626         pktlen = (p[0]<<8) | p[1];
1627 
1628         rem = iobuf + blklen - p;
1629 
1630         if (rem < pktlen) {
1631             logmsg (_("HHCCT030E %4.4X: bad packet length: %d < %d\n"),
1632                     dev->devnum, rem, pktlen);
1633             pktlen = rem;
1634         }
1635         if (pktlen < 6) {
1636         logmsg (_("HHCCT031E %4.4X: bad packet length: %d < 6\n"),
1637                     dev->devnum, pktlen);
1638             pktlen = 6;
1639         }
1640 
1641         pktlen -= 6;
1642         p += 6;
1643 
1644         while (pktlen--) {
1645             switch (*p) {
1646             case SLIP_END:
1647                 buffer[len++] = SLIP_ESC;
1648                 buffer[len++] = SLIP_ESC_END;
1649                 break;
1650             case SLIP_ESC:
1651                 buffer[len++] = SLIP_ESC;
1652                 buffer[len++] = SLIP_ESC_ESC;
1653                 break;
1654             default:
1655                 buffer[len++] = *p;
1656                 break;
1657             }
1658             p++;
1659         }
1660         buffer[len++] = SLIP_END;
1661         write(dev->fd, buffer, len);   /* should check error conditions? */
1662         len = 0;
1663     }
1664 
1665     *unitstat = CSW_CE | CSW_DE;
1666 
1667     return count;
1668 }
1669 
bufgetc(DEVBLK * dev,int blocking)1670 static int bufgetc(DEVBLK *dev, int blocking)
1671 {
1672 BYTE *bufp = dev->buf + dev->ctcpos, *bufend = bufp + dev->ctcrem;
1673 int n;
1674 
1675     if (bufp >= bufend) {
1676         if (blocking == 0) return -1;
1677         do {
1678             n = read(dev->fd, dev->buf, dev->bufsize);
1679             if (n <= 0) {
1680                 if (n == 0) {
1681                     /* VMnet died on us. */
1682                     logmsg (_("HHCCT032E %4.4X: Error: EOF on read, "
1683                               "CTC network down\n"),
1684                             dev->devnum);
1685                     /* -2 will cause an error status to be set */
1686                     return -2;
1687                 }
1688                 if( n == EINTR )
1689                     return -3;
1690                 logmsg (_("HHCCT033E %4.4X: Error: read: %s\n"),
1691                         dev->devnum, strerror(errno));
1692                 SLEEP(2);
1693             }
1694         } while (n <= 0);
1695         dev->ctcrem = n;
1696         bufend = &dev->buf[n];
1697         dev->ctclastpos = dev->ctclastrem = dev->ctcpos = 0;
1698         bufp = dev->buf;
1699     }
1700 
1701     dev->ctcpos++;
1702     dev->ctcrem--;
1703 
1704     return *bufp;
1705 }
1706 
setblkheader(BYTE * iobuf,int buflen)1707 static void setblkheader(BYTE *iobuf, int buflen)
1708 {
1709     iobuf[0] = (buflen >> 8) & 0xFF;
1710     iobuf[1] = buflen & 0xFF;
1711 }
1712 
setpktheader(BYTE * iobuf,int packetpos,int packetlen)1713 static void setpktheader(BYTE *iobuf, int packetpos, int packetlen)
1714 {
1715     iobuf[packetpos] = (packetlen >> 8) & 0xFF;
1716     iobuf[packetpos+1] = packetlen & 0xFF;
1717     iobuf[packetpos+2] = 0x08;
1718     iobuf[packetpos+3] = 0;
1719     iobuf[packetpos+4] = 0;
1720     iobuf[packetpos+5] = 0;
1721 }
1722 
1723 /* read data from the CTC connection.
1724  * If a packet overflows the iobuf or the read buffer runs out, there are
1725  * 2 possibilities:
1726  * - block has single packet: continue reading packet, drop bytes,
1727  *   then return truncated packet.
1728  * - block has multiple packets: back up on last packet and return
1729  *   what we have.  Do this last packet in the next IO.
1730  */
VMNET_Read(DEVBLK * dev,BYTE * iobuf,U16 count,BYTE * unitstat)1731 static int VMNET_Read(DEVBLK *dev, BYTE *iobuf, U16 count, BYTE *unitstat)
1732 {
1733 int             c;                      /* next byte to process      */
1734 int             len = 8;                /* length of block           */
1735 int             lastlen = 2;            /* block length at last pckt */
1736 
1737     dev->ctclastpos = dev->ctcpos;
1738     dev->ctclastrem = dev->ctcrem;
1739 
1740     while (1) {
1741         c = bufgetc(dev, lastlen == 2);
1742         if (c < 0) {
1743             if(c == -3)
1744                 return 0;
1745             /* End of input buffer.  Return what we have. */
1746 
1747             setblkheader (iobuf, lastlen);
1748 
1749             dev->ctcpos = dev->ctclastpos;
1750             dev->ctcrem = dev->ctclastrem;
1751 
1752             *unitstat = CSW_CE | CSW_DE | (c == -2 ? CSW_UX : 0);
1753 
1754             return lastlen;
1755         }
1756         switch (c) {
1757         case SLIP_END:
1758             if (len > 8) {
1759                 /* End of packet.  Set up for next. */
1760 
1761                 setpktheader (iobuf, lastlen, len-lastlen);
1762 
1763                 dev->ctclastpos = dev->ctcpos;
1764                 dev->ctclastrem = dev->ctcrem;
1765                 lastlen = len;
1766 
1767                 len += 6;
1768             }
1769             break;
1770         case SLIP_ESC:
1771             c = bufgetc(dev, lastlen == 2);
1772             if (c < 0) {
1773                 if(c == -3)
1774                     return 0;
1775                 /* End of input buffer.  Return what we have. */
1776 
1777                 setblkheader (iobuf, lastlen);
1778 
1779                 dev->ctcpos = dev->ctclastpos;
1780                 dev->ctcrem = dev->ctclastrem;
1781 
1782                 *unitstat = CSW_CE | CSW_DE | (c == -2 ? CSW_UX : 0);
1783 
1784                 return lastlen;
1785             }
1786             switch (c) {
1787             case SLIP_ESC_END:
1788                 c = SLIP_END;
1789                 break;
1790             case SLIP_ESC_ESC:
1791                 c = SLIP_ESC;
1792                 break;
1793             }
1794             /* FALLTHRU */
1795         default:
1796             if (len < count) {
1797                 iobuf[len++] = c;
1798             } else if (lastlen > 2) {
1799                 /* IO buffer is full and we have data to return */
1800 
1801                 setblkheader (iobuf, lastlen);
1802 
1803                 dev->ctcpos = dev->ctclastpos;
1804                 dev->ctcrem = dev->ctclastrem;
1805 
1806                 *unitstat = CSW_CE | CSW_DE | (c == -2 ? CSW_UX : 0);
1807 
1808                 return lastlen;
1809             } /* else truncate end of very large single packet... */
1810         }
1811     }
1812 }
1813 /*-------------------------------------------------------------------*/
1814 /* End of VMNET functions written by Willem Konynenberg              */
1815 /*-------------------------------------------------------------------*/
1816 
1817 // ====================================================================
1818 // CTCE Support
1819 // ====================================================================
1820 
1821 // CTC Enhanced
1822 // ============
1823 //   Enhanced CTC functionality is designed to emulate real
1824 //   3088 CTC Adapter hardware, using a pair of TCP sockets
1825 //   with a likewise configured Hercules instance on a
1826 //   different PC (or same PC).  The new device type is CTCE.
1827 
1828 //   The implementation is based mostly on IBM publications,
1829 //   "ESCON Channel-to-Channel Adapter", SA22-7203-00, and
1830 //   also  "Channel-to-Channel Adapter", SA22-7091-01, although
1831 //   no claim for completeness of this implemenation is feasible.
1832 
1833 //   The CTCE configuration is similar to the CTCT device.  The
1834 //   MTU bufsize parameter is optional, but when specified must be
1835 //   >= CTCE_MTU_MIN (=61592). This is the default value when omitted.
1836 //   (Please note that 61592 = sizeof(CTCE_SOKPFX) + sizeof(sCount) + 0xF08A
1837 //   the latter being the maximum sCount experienced in CTC CCW programs.)
1838 
1839 //   CTCE requires an even-odd pair of port numbers per device side
1840 //   but only the even port numbers are to be configured; the odd
1841 //   numbers are just derived by adding 1 to the (configured) even
1842 //   port numbers.  The socket connection pairs cross-connect, the
1843 //   arrows showing the send->receive direction :
1844 //
1845 //      x-lport-even -> y-rport-odd
1846 //      x-lport-odd  <- y-rport-even
1847 //
1848 //   A sample CTCE device configuration is shown below:
1849 //
1850 //      Hercules PC Host A with IP address 192.168.1.100 :
1851 //
1852 //         0E40  CTCE  30880  192.168.1.200  30880
1853 //         0E41  CTCE  30882  192.168.1.200  30882
1854 //
1855 //      Hercules PC Host B with IP address 192.168.1.200 :
1856 //
1857 //         0E40  CTCE  30880  192.168.1.100  30880
1858 //         0E41  CTCE  30882  192.168.1.100  30882
1859 
1860 // -------------------------------------------------------------------
1861 // Execute a Channel Command Word (CTCE)
1862 // -------------------------------------------------------------------
1863 
CTCE_ExecuteCCW(DEVBLK * pDEVBLK,BYTE bCode,BYTE bFlags,BYTE bChained,U16 sCount,BYTE bPrevCode,int iCCWSeq,BYTE * pIOBuf,BYTE * pMore,BYTE * pUnitStat,U16 * pResidual)1864 void  CTCE_ExecuteCCW( DEVBLK* pDEVBLK, BYTE  bCode,
1865                        BYTE    bFlags,  BYTE  bChained,
1866                        U16     sCount,  BYTE  bPrevCode,
1867                        int     iCCWSeq, BYTE* pIOBuf,
1868                        BYTE*   pMore,   BYTE* pUnitStat,
1869                        U16*    pResidual )
1870 {
1871     int             iNum;               // Number of bytes to move
1872     CTCE_PARMBLK    parm;               // Parameters for the server
1873                                         //   as in CTCE_Init, used here for the client side
1874     int             optval;             // Argument for setsockopt
1875     char*           remaddr;            // Remote IP address
1876     char            address[20]="";     // temp space for IP address
1877     int             rc;                 // Return code
1878     CTCE_INFO       CTCE_Info;          // CTCE information (also for tracing)
1879 
1880     UNREFERENCED( bChained  );
1881     UNREFERENCED( bPrevCode );
1882     UNREFERENCED( iCCWSeq   );
1883     UNREFERENCED( pMore     );
1884 
1885     // Initialise our CTCE_Info and save the previous x- and y-states in it.
1886     CTCE_Info.wait_rc            = 0;
1887     CTCE_Info.de_ready           = 0;
1888     CTCE_Info.de_ready_attn_rc   = 0;
1889     CTCE_Info.working_attn_rc    = 0;
1890     CTCE_Info.busy_waits         = 0;
1891     CTCE_Info.sent               = 0;
1892     CTCE_Info.con_lost           = 0;
1893     CTCE_Info.con_won            = 0;
1894     CTCE_Info.sok_buf_len        = 0;
1895     CTCE_Info.state_x_prev       = pDEVBLK->ctcexState;
1896     CTCE_Info.state_y_prev       = pDEVBLK->ctceyState;
1897 
1898     // Connect to the partner CTCE device if the device file is not open
1899     if (pDEVBLK->fd < 0)
1900     {
1901 
1902         // It's a little confusing, but we're using a couple of the
1903         // members of the server paramter structure to initiate the
1904         // outgoing connection.  Saves a couple of variable declarations,
1905         // though.  If we feel strongly about it, we can declare separate
1906         // variables...
1907 
1908         // make a TCP socket
1909         parm.listenfd[0] = socket(AF_INET, SOCK_STREAM, 0);
1910         if( parm.listenfd[0] < 0 )
1911         {
1912             logmsg( _("HHCCT050E %04X CTCE: Error creating socket: %s\n"),
1913                 CTCX_DEVNUM( pDEVBLK ), strerror( HSO_errno ) );
1914             *pUnitStat = CSW_CE | CSW_DE | CSW_UC;
1915             release_lock( &pDEVBLK->lock );
1916             return;
1917         }
1918 
1919         // Allow previous instance of socket to be reused
1920         optval = 1;
1921         setsockopt( parm.listenfd[0], SOL_SOCKET, SO_REUSEADDR,
1922             ( GETSET_SOCKOPT_T* )&optval, sizeof( optval ) );
1923 
1924 #if defined(CTCE_DISABLE_NAGLE)
1925         optval = 1;
1926         rc = setsockopt( parm.listenfd[0], IPPROTO_TCP, TCP_NODELAY,
1927             ( char* )&optval, sizeof( optval ) );
1928         if( rc < 0 )
1929         {
1930             logmsg( _("HHCCT051E %04X CTCE: TCP_NODELAY error for socket (port %d): %s\n"),
1931                 CTCX_DEVNUM( pDEVBLK ), pDEVBLK->ctce_lport, strerror(HSO_errno));
1932             *pUnitStat = CSW_CE | CSW_DE | CSW_UC;
1933             release_lock(&pDEVBLK->lock);
1934             return;
1935         }
1936 #endif
1937 
1938         // bind socket to our local port
1939         // (might seem like overkill, and usually isn't done, but doing this
1940         // bind() to the local port we configure gives the other end a chance
1941         // at validating the connection request)
1942         memset( &( parm.addr ), 0, sizeof( parm.addr ) );
1943         parm.addr.sin_family = AF_INET;
1944         parm.addr.sin_port = htons( pDEVBLK->ctce_lport );
1945         parm.addr.sin_addr.s_addr = htonl( INADDR_ANY );
1946 
1947         rc = bind( parm.listenfd[0],
1948             ( struct sockaddr * )&parm.addr,
1949             sizeof( parm.addr ) );
1950         if( rc < 0 )
1951         {
1952             logmsg( _("HHCCT052E %04X CTCE: Error binding to socket (port %d): %s\n"),
1953                 CTCX_DEVNUM( pDEVBLK ), pDEVBLK->ctce_lport, strerror( HSO_errno ) );
1954             *pUnitStat = CSW_CE | CSW_DE | CSW_UC;
1955             release_lock( &pDEVBLK->lock );
1956             return;
1957         }
1958         strcpy( address, inet_ntoa( pDEVBLK->ctce_ipaddr ) );
1959         remaddr = address;
1960 
1961         // initiate a connection to the other end
1962         memset( &( parm.addr ), 0, sizeof( parm.addr ) );
1963         parm.addr.sin_family = AF_INET;
1964 
1965         // the even (=read) port must connect to the odd (=write) port
1966         // at the other side and vice-versa
1967         parm.addr.sin_port = htons(pDEVBLK->ctce_rport + 1 );
1968         parm.addr.sin_addr = pDEVBLK->ctce_ipaddr;
1969 
1970         // We connect() but with a timeout value of 1000000 usec = 1 sec
1971         rc = CTCE_Connect_Timeout( parm.listenfd[0],
1972             ( struct sockaddr * )&parm.addr,
1973             sizeof( parm.addr), 1000000 );
1974 
1975         // if connection was not successful, then we may retry later on when the other side becomes ready.
1976         if( rc < 0 )
1977         {
1978             logmsg( _("HHCCT053I %04X CTCE: Connect error :%d -> %s:%d, retry is possible\n"),
1979                 CTCX_DEVNUM( pDEVBLK ), pDEVBLK->ctce_lport, remaddr, pDEVBLK->ctce_rport + 1 );
1980         }
1981         else  // successfully connected to the other end
1982         {
1983             logmsg( _("HHCCT054I %04X CTCE: Started outbound connection :%d -> %s:%d\n"),
1984                 CTCX_DEVNUM( pDEVBLK ), pDEVBLK->ctce_lport, remaddr, pDEVBLK->ctce_rport + 1 );
1985 
1986             // The even local port (form the config) is for writing
1987             pDEVBLK->fd = parm.listenfd[0];
1988         }
1989     }
1990 
1991     // The contention winning CTCE side initially is the first one to
1992     // attempt commands; each matching SCB command sent sets this as well.
1993     if( ( pDEVBLK->fd < 0 ) || ( pDEVBLK->ctcefd < 0 ) )
1994     {
1995         pDEVBLK->ctce_contention_loser = 0;
1996 
1997         // Intervention required if the device file is not open
1998         if( !IS_CCW_SENSE( bCode ) &&
1999             !IS_CCW_CONTROL( bCode ) )
2000         {
2001             pDEVBLK->sense[0] = SENSE_IR;
2002             *pUnitStat = CSW_CE | CSW_DE | CSW_UC;
2003             return;
2004         }
2005     }
2006 
2007     // Changes to DEVBLK are lock protected as the CTCE_RecvThread
2008     // might update as well.
2009     obtain_lock( &pDEVBLK->lock );
2010 
2011     // The CCW Flags Command Chaining indicator being set indicates
2012     // that a CCW Program is in progress.  The last CCW in the chain
2013     // has this flag turned off.
2014     pDEVBLK->ctce_ccw_flags_cc = ( ( bFlags & CCW_FLAGS_CC ) != 0 );
2015 
2016     // Copy control command byte in x command register
2017     pDEVBLK->ctcexCmd = bCode;
2018 
2019     // A valid Set Extended / Base Mode (SEM / SBM) command will have
2020     // an immediate effect so that it can from then on be handled as
2021     // a NOP command.  Valid means x-state Available and y-state
2022     // not in Working(D) with Control, Read or Write (CRW).
2023     // Please note that the Basic to Extended mode switch influences
2024     // the CTCS FSM table indexing which is why this is done up front.
2025     // So we set Extended mode and enforce Available x-state.
2026     if( IS_CTCE_CCW_SEM( pDEVBLK->ctcexCmd ) &&
2027         IS_CTCE_YAV( pDEVBLK->ctcexState   ) &&
2028        !IS_CTCE_CRW( pDEVBLK->ctceyState   ) )
2029     {
2030         pDEVBLK->ctcxmode = 1;
2031         SET_CTCE_YAV( pDEVBLK->ctcexState );
2032     }
2033 
2034     // Or we just set Base mode.
2035     else if( IS_CTCE_CCW_SBM( pDEVBLK->ctcexCmd ) &&
2036              IS_CTCE_YAV( pDEVBLK->ctcexState   ) &&
2037             !IS_CTCE_CRW( pDEVBLK->ctceyState   ) )
2038     {
2039         pDEVBLK->ctcxmode = 0;
2040     }
2041 
2042     // The new X-state and transition actions are derived from the FSM table.
2043     CTCE_Info.state_new   = CTCE_NEW_X_STATE( pDEVBLK->ctcexCmd );
2044     CTCE_Info.actions     = CTCE_Fsm[CTCE_CMD( pDEVBLK->ctcexCmd )][CTCE_X_STATE_FSM_IDX].actions;
2045     CTCE_Info.x_unit_stat = CTCE_Fsm[CTCE_CMD( pDEVBLK->ctcexCmd )][CTCE_X_STATE_FSM_IDX].x_unit_stat;
2046 
2047     *pUnitStat            = CTCE_Fsm[CTCE_CMD( pDEVBLK->ctcexCmd )][CTCE_X_STATE_FSM_IDX].x_unit_stat;
2048 
2049     // We avoid a possible command collision between a SEM command and
2050     // a WRITE command already issued by the other side but not received
2051     // yet.  The BUSY+ATTN response to that would cause an endless loop,
2052     // which we simple avoid by replacing it with CE+DE.
2053     if( IS_CTCE_CCW_SEM( pDEVBLK->ctcexCmd ) &&
2054         IS_CTCE_YAV( pDEVBLK->ctcexState   ) &&
2055         *pUnitStat == ( CSW_BUSY | CSW_ATTN ) )
2056     {
2057         *pUnitStat = CSW_CE | CSW_DE;
2058     }
2059 
2060     // If a READ or READ_BACKWARD command is received whilst the WEOF
2061     // bit is set then the sole case for a Unit Exception applies.
2062     else if( IS_CTCE_WEOF( pDEVBLK->ctcexState ) &&
2063         IS_CTCE_CCW_RDA( pDEVBLK->ctcexCmd ) )
2064     {
2065         CLR_CTCE_WEOF( pDEVBLK->ctcexState );
2066         *pResidual = 0;
2067         *pUnitStat = CSW_CE | CSW_DE | CSW_UX;
2068     }
2069 
2070     // Otherwise in case the CTCE device is not busy actions may result.
2071     else if( !( CTCE_Info.x_unit_stat & CSW_BUSY ) )
2072     {
2073         CLR_CTCE_WEOF( pDEVBLK->ctcexState );
2074 
2075         // Process depending on the CCW command.
2076         switch ( CTCE_CMD( pDEVBLK->ctcexCmd ) )
2077         {
2078 
2079         // Most of the CTCE commands processing (if any at all)
2080         // takes place in CTCE_Send and CTCE_RECV down below.
2081         case CTCE_PREPARE:
2082         case CTCE_CONTROL:
2083         case CTCE_READ:
2084         case CTCE_WRITE:
2085         case CTCE_READ_BACKWARD:
2086         case CTCE_WRITE_END_OF_FILE:
2087         case CTCE_NO_OPERATION:
2088         case CTCE_SET_EXTENDED_MODE:
2089         case CTCE_SET_BASIC_MODE:
2090             break;
2091 
2092         case CTCE_SENSE_COMMAND_BYTE:
2093 
2094             // In y-state available we return 0 otherwise the last y-side command.
2095             *pIOBuf = ( IS_CTCE_YAV( pDEVBLK->ctceyState ) ) ?
2096                 0 : pDEVBLK->ctceyCmdSCB;
2097             CTCE_Info.scb = *pIOBuf;
2098             *pResidual = sCount - 1;
2099             break;
2100 
2101         case CTCE_SENSE_ADAPTER_STATE:
2102 
2103             // Calculate residual byte count
2104             iNum = ( sCount < pDEVBLK->numsense ) ?
2105                 sCount : pDEVBLK->numsense;
2106             *pResidual = sCount - iNum;
2107 
2108             // Copy device sense bytes to channel I/O buffer
2109             memcpy( pIOBuf, pDEVBLK->sense, iNum );
2110 
2111             // Clear the device sense bytes
2112             memset( pDEVBLK->sense, 0, sizeof( pDEVBLK->sense ) );
2113             break;
2114 
2115         case CTCE_SENSE_ID:
2116 
2117             // Calculate residual byte count
2118             iNum = ( sCount < pDEVBLK->numdevid ) ?
2119                 sCount : pDEVBLK->numdevid;
2120             *pResidual = sCount - iNum;
2121 
2122             // Copy device identifier bytes to channel I/O buffer
2123             memcpy( pIOBuf, pDEVBLK->devid, iNum );
2124             break;
2125 
2126         // Invalid commands
2127         // (or never experienced / tested / supported ones)
2128         case CTCE_READ_CONFIG_DATA:
2129         default:
2130 
2131             // Signalling invalid commands using Unit Check with a
2132             // Command Reject sense code for this CTCE device failed.
2133             // (MVS results were a WAIT 064 RSN 9 during NIP.)
2134             // An Interface Control Check would probably be needed but
2135             // we do not know how to generate that, so we use SENSE_EC.
2136             //
2137             //    pDEVBLK->sense[0] = SENSE_CR;
2138 
2139             pDEVBLK->sense[0] = SENSE_EC;
2140             *pUnitStat        = CSW_CE | CSW_DE | CSW_UC;
2141 
2142         } // switch ( CTCE_CMD( pDEVBLK->ctcexCMD ) )
2143 
2144         // In most cases we need to inform the other (y-)side so we SEND
2145         // our command (and data) to the other side.  During this process
2146         // and any response received, all other actions take place.
2147         if( IS_CTCE_SEND( CTCE_Info.actions ) )
2148         {
2149             CTCE_Send( pDEVBLK, sCount, pIOBuf, pUnitStat, pResidual, &CTCE_Info );
2150 
2151             // In case we sent a matching SCB command, this side becomes
2152             // the contention winner side; the receiver updates accordingly.
2153             if( IS_CTCE_CCW_SCB( pDEVBLK->ctcexCmd ) && CTCE_Info.sent )
2154             {
2155                 pDEVBLK->ctce_contention_loser = 0;
2156             }
2157         }
2158 
2159         // This (x-)side will leave the Not Ready state.
2160         if( IS_CTCE_YNR( pDEVBLK->ctcexState ) )
2161         {
2162             SET_CTCE_YAV( pDEVBLK->ctcexState );
2163         }
2164 
2165     } // if( !( CTCE_Info.x_unit_stat & CSW_BUSY ) )
2166 
2167     // We merge a Unit Check in case the Y state is Not Ready.
2168     // But only when pUnitStat is still 0 or just Busy (no Attn).
2169     if( IS_CTCE_YNR( pDEVBLK -> ctceyState ) &&
2170         ( ( *pUnitStat & (~ CSW_BUSY ) ) == 0 ) )
2171     {
2172         *pUnitStat |= CSW_UC;
2173         pDEVBLK->sense[0] = SENSE_IR;
2174     }
2175 
2176     // Produce a CTCE Trace logging if requested, noting that for the
2177     // IS_CTCE_WAIT cases such a logging is produced prior to the WAIT,
2178     // and CTCE_Recv will produce a logging for the matching command.
2179     if( ( pDEVBLK->ccwtrace || pDEVBLK->ccwstep ) &&
2180         ( !( IS_CTCE_WAIT( CTCE_Info.actions ) ) ||
2181           !CTCE_Info.sent ) )
2182     {
2183         CTCE_Trace( pDEVBLK, sCount, CTCE_Info.sent ? CTCE_SND : CTCE_LCL,
2184                     &CTCE_Info, pDEVBLK->buf, pUnitStat );
2185     }
2186 
2187     release_lock( &pDEVBLK->lock );
2188 }
2189 
2190 //
2191 // CTCE_Init
2192 //
2193 
CTCE_Init(DEVBLK * dev,int argc,char * argv[])2194 static int  CTCE_Init( DEVBLK *dev, int argc, char *argv[] )
2195 {
2196     char           str[80];            // Thread name
2197     int            mtu;                // MTU size (binary)
2198     char*          listenp;            // Listening port number
2199     char*          remotep;            // Destination port number
2200     char*          mtusize;            // MTU size (characters)
2201     char*          remaddr;            // Remote IP address
2202     BYTE           c;                  // Character work area
2203     TID            tid;                // Thread ID for server
2204     int            ctceSmlBin;         // Small size (binary)
2205     char*          ctceSmlChr;         // Small size (characters)
2206     CTCE_PARMBLK   parm;               // Parameters for the server
2207     CTCE_PARMBLK*  arg;                // used to pass parameters to the server thread
2208     char           address[20]="";     // temp space for IP address
2209     int            optval;             // Argument for setsockopt
2210 
2211     dev->devtype = 0x3088;
2212 
2213     dev->ctctype = CTC_CTCE;
2214 
2215 //  SetSIDInfo( dev, 0x3088, 0x08, 0x0000, 0x00 ); CTCA, Extended Mode
2216 //  SetSIDInfo( dev, 0x3088, 0x08, 0x0000, 0x01 ); CTCA, Basic    Mode
2217 //  SetSIDInfo( dev, 0x3088, 0x1F, 0x0000, 0x00 ); ESCON CTC, Extended Mode, i.e. SCTC
2218 //  SetSIDInfo( dev, 0x3088, 0x1F, 0x0000, 0x01 ); ESCON CTC, Basic    Mode, i.e. BCTC
2219 //  SetSIDInfo( dev, 0x3088, 0x1E, 0x0000, 0x00 ); FICON CTC
2220 //  SetSIDInfo( dev, 0x3088, 0x01, ...          ); P390 OSA emulation
2221 //  SetSIDInfo( dev, 0x3088, 0x60, ...          ); OSA/2 adapter
2222 //  SetSIDInfo( dev, 0x3088, 0x61, ...          ); CISCO 7206 CLAW protocol ESCON connected
2223 //  SetSIDInfo( dev, 0x3088, 0x62, ...          ); OSA/D device
2224 //  But the orignal CTCX_init had this :
2225     SetSIDInfo( dev, 0x3088, 0x08, 0x3088, 0x01 );
2226 
2227     dev->numsense = 2;
2228 
2229     // A version 4 only feature ...
2230 //  dev->excps = 0;
2231 
2232     // The halt_device exit is established; in version 4 this is in DEVHND in the ctce_device_hndinfo.
2233     dev->halt_device = &CTCE_Halt;
2234 
2235     // Mark both socket file descriptors as not yet connected.
2236     dev->fd = -1;
2237     dev->ctcefd = -1;
2238 
2239     // Check for correct number of arguments
2240     if( (argc < 3) && (argc > 5) )
2241     {
2242         logmsg( _("HHCCT055E %04X CTCE: Incorrect number of parameters\n"),
2243             CTCX_DEVNUM( dev ) );
2244         return -1;
2245     }
2246 
2247     // The first argument is the listening port number
2248     // which for CTCE must be an even port number.
2249     listenp = *argv++;
2250 
2251     if( strlen( listenp ) > 5 ||
2252         sscanf( listenp, "%u%c", &dev->ctce_lport, &c ) != 1 ||
2253         dev->ctce_lport < 1024 || dev->ctce_lport > 65534 )
2254     {
2255         logmsg( _("HHCCT056E %04X CTCE: Invalid port number: %s\n"),
2256             CTCX_DEVNUM( dev ), listenp );
2257         return -1;
2258     }
2259     if( dev->ctce_lport % 2 )
2260     {
2261         logmsg( _("HHCCT057E %04X CTCE: Local port number not even: %s\n"),
2262             CTCX_DEVNUM( dev ), listenp );
2263         return -1;
2264     }
2265 
2266     // The second argument is the IP address or hostname of the
2267     // remote side of the point-to-point link
2268     remaddr = *argv++;
2269 
2270     if( inet_aton( remaddr, &dev->ctce_ipaddr ) == 0 )
2271     {
2272         struct hostent *hp;
2273 
2274         if( ( hp = gethostbyname( remaddr ) ) != NULL )
2275         {
2276             memcpy( &dev->ctce_ipaddr, hp->h_addr, hp->h_length );
2277             strcpy( address, inet_ntoa( dev->ctce_ipaddr ) );
2278             remaddr = address;
2279         }
2280         else
2281         {
2282             logmsg( _("HHCCT058E %04X CTCE: Invalid IP address %s\n"),
2283                 CTCX_DEVNUM( dev ), remaddr );
2284             return -1;
2285         }
2286     }
2287 
2288     // The third argument is the destination port number
2289     // which for CTCE must be an even port number.
2290     remotep = *argv++;
2291 
2292     if( strlen( remotep ) > 5 ||
2293         sscanf( remotep, "%u%c", &dev->ctce_rport, &c ) != 1 ||
2294         dev->ctce_rport < 1024 || dev->ctce_rport > 65534 )
2295     {
2296         logmsg( _("HHCCT059E %04X CTCE: Invalid port number: %s\n"),
2297             CTCX_DEVNUM( dev ), remotep );
2298         return -1;
2299     }
2300     if( dev->ctce_rport % 2 )
2301     {
2302         logmsg( _("HHCCT060E %04X CTCE: Remote port number not even: %s\n"),
2303             CTCX_DEVNUM( dev ), remotep );
2304         return -1;
2305     }
2306 
2307     // Enhanced CTC default MTU bufsize is CTCE_MTU_MIN.
2308     if( argc < 4 )
2309     {
2310         mtu = CTCE_MTU_MIN;
2311     }
2312     else
2313     {
2314 
2315         // The fourth argument is the maximum transmission unit (MTU) size
2316         mtusize = *argv;
2317 
2318         if( strlen( mtusize ) > 5 ||
2319             sscanf( mtusize, "%u%c", &mtu, &c ) != 1 ||
2320             mtu < CTCE_MTU_MIN || mtu > 65536 )
2321         {
2322             logmsg( _("HHCCT061E %04X CTCE: Invalid MTU size %s, allowed range is %d to 65536\n"),
2323                 CTCX_DEVNUM( dev ), mtusize, CTCE_MTU_MIN );
2324             return -1;
2325         }
2326     }
2327 
2328     // Enhanced CTC only supports an optional 5th parameter,
2329     // the Small MTU size, which defaults to the minimum size
2330     // of the TCP/IP packets exchanged: CTCE_SOKPFX.
2331     ctceSmlBin = sizeof(CTCE_SOKPFX);
2332     if( argc == 5 )
2333     {
2334         ctceSmlChr = *(++argv);
2335 
2336         if( strlen( ctceSmlChr ) > 5 ||
2337             sscanf( ctceSmlChr, "%u%c", &ctceSmlBin, &c ) != 1 ||
2338             ctceSmlBin < (int)sizeof(CTCE_SOKPFX) || ctceSmlBin > mtu )
2339         {
2340             ctceSmlBin = sizeof(CTCE_SOKPFX);
2341             logmsg( _("HHCCT062W %04X CTCE: Invalid Small MTU size %s ignored\n"),
2342                 CTCX_DEVNUM( dev ), ctceSmlChr );
2343         }
2344     }
2345     dev->ctceSndSml = ctceSmlBin;
2346 
2347     // Set the device buffer size equal to the MTU size
2348     dev->bufsize = mtu;
2349 
2350     logmsg( _("HHCCT063I %04X CTCE: Awaiting inbound connection :%d <- %s:%d\n"),
2351         CTCX_DEVNUM( dev ), dev->ctce_lport + 1, remaddr, dev->ctce_rport );
2352 
2353     // Initialize the file descriptor for the socket connection
2354     parm.listenfd[1] = socket(AF_INET, SOCK_STREAM, 0);
2355     if( parm.listenfd[1] < 0 )
2356     {
2357         logmsg( _("HHCCT064E %04X CTCE: Error creating socket: %s\n"),
2358             CTCX_DEVNUM( dev ), strerror( HSO_errno ) );
2359         CTCX_Close( dev );
2360         return -1;
2361     }
2362 
2363     // Allow previous instance of socket to be reused
2364     optval = 1;
2365     setsockopt(parm.listenfd[1], SOL_SOCKET, SO_REUSEADDR,
2366         (GETSET_SOCKOPT_T*)&optval, sizeof(optval));
2367 
2368     // set up the listening port
2369     memset( &(parm.addr), 0, sizeof( parm.addr ) );
2370 
2371     parm.addr.sin_family      = AF_INET;
2372     parm.addr.sin_port        = htons(dev->ctce_lport + 1) ;
2373     parm.addr.sin_addr.s_addr = htonl(INADDR_ANY);
2374 
2375     if( bind( parm.listenfd[1],
2376               ( struct sockaddr * )&parm.addr,
2377               sizeof( parm.addr ) ) < 0 )
2378     {
2379         logmsg( _("HHCCT065E %04X CTCE: Error binding to socket (port=%d): %s\n"),
2380             CTCX_DEVNUM( dev ), dev->ctce_lport + 1, strerror( HSO_errno ) );
2381         CTCX_Close( dev );
2382         return -1;
2383     }
2384 
2385     if( listen( parm.listenfd[1], 1 ) < 0 )
2386     {
2387         logmsg( _("HHCCT066E %04X CTCE: Error on call to listen (port=%d): %s\n"),
2388             CTCX_DEVNUM( dev ), dev->ctce_lport + 1, strerror( HSO_errno ) );
2389         CTCX_Close( dev );
2390         return -1;
2391     }
2392 
2393     // we are listening, so create a thread to accept connection
2394     arg = malloc( sizeof( CTCE_PARMBLK ) );
2395     memcpy( arg, &parm, sizeof( parm ) );
2396     arg->dev = dev;
2397     snprintf( str, sizeof( str ), "CTCE %4.4X ListenThread", dev->devnum);
2398     str[sizeof( str )-1]=0;
2399     create_thread( &tid, JOINABLE, CTCE_ListenThread, arg, str );
2400 
2401     // for cosmetics, since we are successfully serving,
2402     // fill in some details for the panel.
2403     // Also used for connection verification in CTCE_ListenThread.
2404     // The other side's CTCE device number will be completed
2405     // upon the first receive, we initialize here with dots.
2406     sprintf( dev->filename, ".:....=%s:%d", remaddr, dev->ctce_rport );
2407 
2408     // Enhanced CTC adapter intiialization for command register and CB.
2409     dev->ctcexCmd = 0x00;
2410     dev->ctceyCmd = 0x00;
2411     dev->ctceyCmdSCB = 0x00;
2412 
2413     // Enhanced CTC adapter sides are state-aware, with initial
2414     // state (1) "Available" and (2) "Not Ready" as in column 6 in
2415     // the table 2.13 in SA22-7203-00, i.e. we consider both
2416     // sides being in state YNR. ALL Flags are cleared.
2417     CLR_CTCE_ALLF( dev->ctcexState );
2418     SET_CTCE_YNR ( dev->ctcexState );
2419     CLR_CTCE_ALLF( dev->ctceyState );
2420     SET_CTCE_YNR ( dev->ctceyState );
2421 
2422     // Until we are successfully contacted by the other side,
2423     // we mark the "other side Intervention Required".
2424     dev->sense[0] = SENSE_IR;
2425 
2426     // Initialize the 12 bits Send->Recv packet sequence ID with
2427     // bits 13-12 of the CCUU devnum in bits 15-14, and
2428     // bits 01-00 of the CCUU devnum in bits 13-12.  This helps
2429     // distinguishing same-host traffic if the Send-Recv side
2430     // CCUU's are sufficiently different (e.g. when under VM).
2431     dev->ctcePktSeq = ((dev->devnum <<  2) & 0xC000) |
2432                       ((dev->devnum << 12) & 0x3000) ;
2433 
2434     // Initialize the CTC lock and condition used to signal
2435     // reception of a command matching the dependent one.
2436     initialize_lock( &dev->ctceEventLock );
2437     initialize_condition( &dev->ctceEvent );
2438 
2439     // The ctce_contention_loser side of a CTCE connection will act as
2440     // if a colliding dependent command arrived following the one at
2441     // the other side.  The CTC side connecting 1st will reset this,
2442     // and matching SCB commands may alter it also.
2443     dev->ctce_contention_loser = 1;
2444 
2445     return 0;
2446 }
2447 
2448 //
2449 // CTCE_ListenThread
2450 //
2451 
CTCE_ListenThread(void * argp)2452 static void*  CTCE_ListenThread( void* argp )
2453 {
2454     int          connfd;
2455     socklen_t    servlen;
2456     char         str[80];
2457     CTCE_PARMBLK parm;
2458     TID          tid2;               // Thread ID for read thread
2459     int          rc;                 // Return code
2460 #if defined( CTCE_DISABLE_NAGLE )
2461     int          optval;             // Argument for setsockopt
2462 #endif
2463 
2464     // set up the parameters passed via create_thread
2465     parm = *((CTCE_PARMBLK*) argp);
2466     free( argp );
2467 
2468     for( ; ; )
2469     {
2470         servlen = sizeof( parm.addr );
2471 
2472         // await a connection
2473         connfd = accept( parm.listenfd[1],
2474                          (struct sockaddr *)&parm.addr,
2475                          &servlen );
2476 
2477         sprintf( str, "%s:%d",
2478                  inet_ntoa( parm.addr.sin_addr ),
2479                  ntohs( parm.addr.sin_port ) );
2480 
2481         if( strcmp( str, parm.dev->filename + 7 ) != 0 )
2482         {
2483             logmsg( _("HHCCT067E %04X CTCE: Inconsistent config=%s+%d, connecting client=%s\n"),
2484                 CTCX_DEVNUM( parm.dev ), parm.dev->filename + 7, 1, str);
2485             close_socket( connfd );
2486         }
2487         else
2488         {
2489 
2490 #if defined( CTCE_DISABLE_NAGLE )
2491             optval = 1;
2492             rc = setsockopt(parm.listenfd[1], IPPROTO_TCP, TCP_NODELAY,
2493                 (char*)&optval, sizeof( optval ) );
2494             if( rc < 0 )
2495             {
2496                 logmsg( _("HHCCT068E %04X CTCE: TCP_NODELAY error for socket (port %d): %s\n"),
2497                     CTCX_DEVNUM( parm.dev ), parm.dev->ctce_lport + 1, strerror( HSO_errno ) );
2498                 close_socket( connfd );
2499             }
2500 #endif
2501 
2502             // The next odd local port is for reading
2503             parm.dev->ctcefd = connfd;
2504 
2505             // This side is ready to start receiving and sending so we
2506             // start a read thread to do the receiving part;
2507             snprintf( str, sizeof(str), "CTCE %04X RecvThread",
2508                 parm.dev->devnum );
2509             str[sizeof(str)-1]=0;
2510             rc = create_thread( &tid2, JOINABLE, CTCE_RecvThread, parm.dev, str );
2511             if( rc != 0 )
2512             {
2513                 logmsg( _("HHCCT069E %04X CTCE: create_thread error: %s\n"),
2514                     CTCX_DEVNUM( parm.dev ), strerror(errno));
2515             }
2516             else
2517             {
2518                 logmsg( _("HHCCT070I %04X CTCE: Accepted inbound connection :%d <- %s (bufsize=%d,%d)\n"),
2519                     CTCX_DEVNUM( parm.dev ), parm.dev->ctce_lport + 1,
2520                     parm.dev->filename + 7, parm.dev->bufsize, parm.dev->ctceSndSml );
2521             }
2522         }
2523 
2524         // Ok, so having done that we're going to loop back to the
2525         // accept().  This was meant to handle the connection failing
2526         // at the other end; this end will be ready to accept another
2527         // connection.  Although this will happen, I'm sure you can
2528         // see the possibility for bad things to occur (eg if another
2529         // Hercules tries to connect).  This will also be fixed RSN.
2530     }
2531 
2532     return NULL;    // make compiler happy
2533 }
2534 
2535 //
2536 // CTCE_Send
2537 //
2538 
CTCE_Send(DEVBLK * pDEVBLK,U16 sCount,BYTE * pIOBuf,BYTE * pUnitStat,U16 * pResidual,CTCE_INFO * pCTCE_Info)2539 static void   CTCE_Send( DEVBLK* pDEVBLK,   U16        sCount,
2540                          BYTE*   pIOBuf,    BYTE*      pUnitStat,
2541                          U16*    pResidual, CTCE_INFO* pCTCE_Info )
2542 {
2543     CTCE_SOKPFX   *pSokBuf;                 // overlay for buf inside DEVBLK
2544     int            rc;                      // Return code
2545 
2546     if( ! IS_CTCE_SEND( pCTCE_Info->actions ) )
2547     {
2548         logmsg( _("HHCCT071E %04X CTCE: SEND status incorrectly encoded !\n"),
2549             CTCX_DEVNUM( pDEVBLK ) );
2550     }
2551 
2552     // We only ever Send if the sockets are connected.
2553     if( ( pDEVBLK->fd < 0 ) || ( pDEVBLK->ctcefd < 0 ) )
2554     {
2555         logmsg( _("HHCCT072S %04X CTCE: Not all sockets connected: send=%d, receive=%d\n"),
2556             CTCX_DEVNUM( pDEVBLK ), pDEVBLK->fd, pDEVBLK->ctcefd );
2557         *pUnitStat = 0;
2558         return ;
2559     }
2560     pCTCE_Info->sent = 1;
2561 
2562     pDEVBLK->ctcexState = CTCE_NEW_X_STATE( pDEVBLK->ctcexCmd );
2563     pDEVBLK->ctce_UnitStat = *pUnitStat;
2564 
2565     pSokBuf = (CTCE_SOKPFX*) pDEVBLK->buf;
2566     pSokBuf->CmdReg = pDEVBLK->ctcexCmd;
2567     pSokBuf->FsmSta = pDEVBLK->ctcexState;
2568     pSokBuf->sCount = sCount;
2569     pSokBuf->PktSeq = ++pDEVBLK->ctcePktSeq;
2570     pSokBuf->SndLen = pDEVBLK->ctceSndSml;
2571     pSokBuf->DevNum = pDEVBLK->devnum;
2572     pSokBuf->ssid   = pDEVBLK->ssid;
2573 
2574     // Only a (non-WEOF) write command data includes sending the IOBuf.
2575     if( IS_CTCE_CCW_WRT( pDEVBLK->ctcexCmd ) )
2576     {
2577         memcpy( pDEVBLK->buf + sizeof(CTCE_SOKPFX), pIOBuf, sCount );
2578 
2579         // Increase the SndLen if the sCount is too large.
2580         if( pSokBuf->SndLen < ( sCount + sizeof(CTCE_SOKPFX) ) )
2581             pSokBuf->SndLen = ( sCount + sizeof(CTCE_SOKPFX) );
2582 
2583         // Write Data.
2584         if( pDEVBLK->ccwstep )
2585             packet_trace( pIOBuf, sCount );
2586 
2587         // If bufsize (init from the MTU parameter) is not large enough
2588         // then we will have a severe error as the CTC will not connect.
2589         if( pDEVBLK->bufsize < pSokBuf->SndLen )
2590         {
2591             logmsg( _("HHCCT073S %04X CTCE: bufsize parameter %d is too small; increase at least to %d\n"),
2592                 CTCX_DEVNUM( pDEVBLK ), pDEVBLK->bufsize, pSokBuf->SndLen );
2593         }
2594     }
2595     pCTCE_Info->sok_buf_len = pSokBuf->SndLen;
2596 
2597     // Write all of this to the other (y-)side.
2598     rc = write_socket( pDEVBLK->fd, pDEVBLK->buf, pSokBuf->SndLen );
2599 
2600     if( rc < 0 )
2601     {
2602         logmsg( _("HHCCT074E %04X CTCE: Error writing to %s: %s\n"),
2603             CTCX_DEVNUM( pDEVBLK ), CTCE_FILENAME, strerror( HSO_errno ) );
2604 
2605         pDEVBLK->sense[0] = SENSE_EC;
2606         *pUnitStat        = CSW_CE | CSW_DE | CSW_UC;
2607 
2608         // For lack of anything better, we return to the not ready state.
2609         CLR_CTCE_ALLF(pDEVBLK->ctcexState);
2610         SET_CTCE_YNR(pDEVBLK->ctcexState);
2611         return;
2612     }
2613 
2614     // If this command is a matching one for the other (y-)side
2615     // Working(D) state, then that (y-)side becomes available.
2616     if IS_CTCE_MATCH( pCTCE_Info->actions )
2617     {
2618         SET_CTCE_YAV( pDEVBLK->ctceyState );
2619     }
2620 
2621     // If we received a command that is going to put our (x-)side
2622     // in a Working(D) state, then we will need to wait until a
2623     // matching command arrives from the other (y-)side.  The WAIT
2624     // timeout is chosen to be long enough to not timeout over periods
2625     // if inactivity; we experienced up to 6 secs, so we set it to 60.
2626     if( IS_CTCE_WAIT( pCTCE_Info->actions ) )
2627     {
2628 
2629         // Produce a CTCE Trace logging if requested.
2630         if( pDEVBLK->ccwtrace || pDEVBLK->ccwstep )
2631         {
2632             CTCE_Trace( pDEVBLK, sCount, CTCE_SND, pCTCE_Info, pDEVBLK->buf, pUnitStat );
2633         }
2634 
2635         obtain_lock( &pDEVBLK->ctceEventLock );
2636         release_lock( &pDEVBLK->lock );
2637 
2638         pCTCE_Info->wait_rc = timed_wait_condition_relative_usecs(
2639             &pDEVBLK->ctceEvent,
2640             &pDEVBLK->ctceEventLock,
2641             60000000,
2642             NULL );
2643 
2644         obtain_lock( &pDEVBLK->lock );
2645         release_lock( &pDEVBLK->ctceEventLock );
2646 
2647         // First we check for Halt or Clear Subchannel
2648         if( pCTCE_Info->wait_rc == ETIMEDOUT || pCTCE_Info->wait_rc == EINTR )
2649         {
2650             // check for halt condition
2651             if( pDEVBLK->scsw.flag2 & SCSW2_FC_HALT ||
2652                 pDEVBLK->scsw.flag2 & SCSW2_FC_CLEAR )
2653             {
2654                 if( pDEVBLK->ccwtrace || pDEVBLK->ccwstep )
2655                 {
2656                     logmsg( _("HHCCT075I %04X CTCE: Halt or Clear Recognized\n"),
2657                         CTCX_DEVNUM( pDEVBLK ) );
2658                 }
2659 
2660 //???           *pUnitStat = CSW_CE | CSW_DE;
2661                 *pUnitStat = 0;
2662                 *pResidual = sCount;
2663             }
2664 
2665             // Other timeouts or errors should not occur.
2666             // But if they do, we try to recover as if the other side
2667             // was in a working(D) state.
2668             else
2669             {
2670                 *pUnitStat = CSW_BUSY | CSW_ATTN ;
2671                 SET_CTCE_YAV( pDEVBLK->ctcexState );
2672             }
2673 
2674             // Produce a trace logging if requested.
2675             if( pDEVBLK->ccwtrace || pDEVBLK->ccwstep )
2676             {
2677                 CTCE_Trace( pDEVBLK, sCount, CTCE_SND, pCTCE_Info, pDEVBLK->buf, pUnitStat );
2678             }
2679             return;
2680         }
2681 
2682         // Trace the non-zero WAIT RC (e.g. timeout, RC=138 (windows) or 110 (unix)).
2683         else if( pCTCE_Info->wait_rc != 0 )
2684         {
2685             CTCE_Trace( pDEVBLK, sCount, CTCE_SND, pCTCE_Info, pDEVBLK->buf, pUnitStat );
2686         }
2687 
2688         // A WRITE EOF command from the other side will have resulted
2689         // in the WEOF flag being set.  If this was a matching command
2690         // for a READ then unit exception needs to be included.
2691         else if( IS_CTCE_WEOF( pDEVBLK->ctcexState ) &&
2692                  IS_CTCE_CCW_RDA( pDEVBLK->ctcexCmd ) )
2693         {
2694             *pResidual = 0;
2695             *pUnitStat  = CSW_CE | CSW_DE | CSW_UX;
2696 
2697             // Produce a trace logging if requested.
2698             if( pDEVBLK->ccwtrace || pDEVBLK->ccwstep )
2699             {
2700                 CTCE_Trace( pDEVBLK, sCount, CTCE_SND, pCTCE_Info, pDEVBLK->buf, pUnitStat );
2701             }
2702             return;
2703         }
2704     } // if( IS_CTCE_WAIT( pCTCE_Info->actions ) )
2705 
2706     // In the non-WAIT case the final UnitStat is always
2707     // CE + DE provided the y-state is not Not_Ready.
2708     else if( !IS_CTCE_YNR( pDEVBLK -> ctceyState ) )
2709     {
2710         pDEVBLK->ctce_UnitStat = CSW_CE | CSW_DE;
2711     }
2712 
2713     // If the command (by now matched) was a CONTROL command, then this
2714     // side become the contention loser.
2715     if( IS_CTCE_CCW_CTL( pDEVBLK->ctcexCmd ) )
2716     {
2717         pDEVBLK->ctce_contention_loser = 1;
2718     }
2719 
2720     // Command collisions never return data.
2721     if( pDEVBLK->ctce_UnitStat == (CSW_BUSY | CSW_ATTN) )
2722     {
2723         *pResidual = sCount;
2724     }
2725 
2726     // If the command (by now matched) was a READ command, then the
2727     // other (y-)side data is available in the DEVBLK buf, so we
2728     // can copy it into the IO channel buffer and compute residual.
2729     else if( IS_CTCE_CCW_RED( pDEVBLK->ctcexCmd ) )
2730     {
2731 
2732         // The actual length of data transferred is the minimum of
2733         // the current READ sCount, and the original WRITE sCount
2734         // which is recorded immediately following the CTCE_SOKPFX.
2735         pSokBuf->sCount =
2736             ( sCount <= *(U16*)( pDEVBLK->buf + sizeof(CTCE_SOKPFX) ) )
2737             ? sCount :  *(U16*)( pDEVBLK->buf + sizeof(CTCE_SOKPFX) );
2738 
2739         // Immediately followed by the WRITE data previously received.
2740         memcpy( pIOBuf, pDEVBLK->buf + sizeof(CTCE_SOKPFX) + sizeof(pSokBuf->sCount),
2741             pSokBuf->sCount ) ;
2742         *pResidual = sCount - pSokBuf->sCount;
2743     }
2744     else
2745     {
2746         *pResidual = 0;
2747     }
2748 
2749     // The final UnitStat may have been amended by CTCE_Recv like when
2750     // it received a matching command (typically resulting in CE + DE).
2751     // We need to merge this.
2752     *pUnitStat |= pDEVBLK->ctce_UnitStat;
2753     pDEVBLK->ctce_UnitStat = 0;
2754 
2755     return;
2756 }
2757 
2758 //
2759 // CTCE_RecvThread
2760 //
2761 
CTCE_RecvThread(void * argp)2762 static void*  CTCE_RecvThread( void* argp )
2763 {
2764     DEVBLK        *pDEVBLK = (DEVBLK*) argp;     // device block pointer
2765     CTCE_SOKPFX   *pSokBuf;                      // overlay for buf inside DEVBLK
2766     CTCE_INFO      CTCE_Info;                    // CTCE information (also for tracing)
2767     int            iLength  = 0;
2768     BYTE          *buf;                          //-> Device recv data buffer
2769     U64            ctcePktCnt = 0;               // Recvd Packet Count
2770     U64            ctceBytCnt = 0;               // Recvd Byte Count
2771     BYTE           ctce_recv_mods_UnitStat;      // UnitStat modifications
2772     int            i = 0;                        // temporary variable
2773 
2774     // When the receiver thread is (re-)started, the CTCE devblk is (re-)initialized
2775     obtain_lock( &pDEVBLK->lock );
2776 
2777     // Enhanced CTC adapter intiialization for command register and CB
2778     pDEVBLK->ctcexCmd = 0x00;
2779     pDEVBLK->ctceyCmd = 0x00;
2780     pDEVBLK->ctceyCmdSCB = 0x00;
2781 
2782     // CTCE DEVBLK (re-)initialisation completed.
2783     release_lock( &pDEVBLK->lock );
2784 
2785     // Avoid having to lock the DEVBLK whilst awaiting data to arrive via read_socket
2786     buf = malloc( pDEVBLK->bufsize );
2787     pSokBuf = (CTCE_SOKPFX*)buf;
2788 
2789     // Initialise our CTCE_Info as needed.
2790     CTCE_Info.de_ready_attn_rc   = 0;
2791     CTCE_Info.working_attn_rc    = 0;
2792     CTCE_Info.busy_waits         = 0;
2793 
2794     // This thread will loop until we receive a zero-length packet caused by CTCX_close from the other side.
2795     for( ; ; )
2796     {
2797         // We read whatever the other (y-)side of the CTC has sent us,
2798         // which by now won't block until the complete bufsize is received.
2799         iLength = read_socket( pDEVBLK->ctcefd, buf, pDEVBLK->ctceSndSml );
2800 
2801         // Followed by the receiving the rest if the default SndLen was too small.
2802         if( ( pDEVBLK->ctceSndSml < pSokBuf->SndLen ) && ( iLength != 0 ) )
2803             iLength += read_socket( pDEVBLK->ctcefd, buf + pDEVBLK->ctceSndSml,
2804                 pSokBuf->SndLen - pDEVBLK->ctceSndSml );
2805 
2806         // In case we are closing down this thread can end.
2807         if( iLength == 0 )
2808         {
2809 
2810             // We report some statistics.
2811             logmsg( _("HHCCT076I %04X CTCE: Connection closed; %lld MB received in %lld packets from %s\n"),
2812                 CTCX_DEVNUM( pDEVBLK ), ctceBytCnt / 1048576 , ctcePktCnt, CTCE_FILENAME );
2813 
2814             // And this receiver socket can now be closed.
2815             close_socket( pDEVBLK->ctcefd );
2816             pDEVBLK->ctcefd = -1;
2817 
2818             free( buf );
2819             return NULL;    // make compiler happy
2820         }
2821 
2822         // Changes to DEVBLK must be lock protected as other threads might update as well.
2823         obtain_lock(&pDEVBLK->lock);
2824 
2825         // Check for other error condition
2826         if( iLength < 0 )
2827         {
2828             logmsg( _("HHCCT077E %04X CTCE: Error reading from %s: %s\n"),
2829                 CTCX_DEVNUM( pDEVBLK ), CTCE_FILENAME, strerror ( HSO_errno ) );
2830             pDEVBLK->sense[0] = SENSE_EC;
2831             pDEVBLK->scsw.unitstat = CSW_CE | CSW_DE | CSW_UC;
2832         }
2833         else
2834         {
2835 
2836             // Upon the first recv we will fill out the devnum in the filename.
2837             if( pDEVBLK->filename[2] == '.' )
2838             {
2839                 snprintf( pDEVBLK->filename, 7, "%1d:%04X",
2840                     SSID_TO_LCSS( pSokBuf->ssid ), pSokBuf->DevNum );
2841                 pDEVBLK->filename[6] = '=';
2842             }
2843 
2844             // Update the Receive statistics counters.
2845             ctcePktCnt += 1 ;
2846             ctceBytCnt += iLength ;
2847 
2848             // Initialise the UnitStat modifications.
2849             ctce_recv_mods_UnitStat = 0;
2850 
2851             // Save the previous CTCE states,
2852             // our (x-)side as well as the other (y-)side.
2853             CTCE_Info.state_x_prev = pDEVBLK->ctcexState;
2854             CTCE_Info.state_y_prev = pDEVBLK->ctceyState;
2855 
2856             // Set extended mode from the other side also applies to this side.
2857             if( IS_CTCE_CCW_SEM( pDEVBLK->ctceyCmd ) )
2858             {
2859                 pDEVBLK->ctcxmode = 1;
2860             }
2861 
2862             // The command received from the other (y-)side may cause a
2863             // state transition on our (x-)side, as well as some actions.
2864             // Both depend on our current (x-)side state and are encoded
2865             // within the FSM table.
2866             CTCE_Info.state_new = CTCE_NEW_Y_STATE( pSokBuf->CmdReg );
2867             CTCE_Info.actions     = CTCE_Fsm[CTCE_CMD( pSokBuf->CmdReg )]
2868                                             [CTCE_Y_STATE_FSM_IDX].actions;
2869             CTCE_Info.x_unit_stat = CTCE_Fsm[CTCE_CMD( pSokBuf->CmdReg )]
2870                                             [CTCE_Y_STATE_FSM_IDX].x_unit_stat;
2871             CTCE_Info.con_lost = 0;
2872             CTCE_Info.con_won = 0;
2873 
2874             // Command collision occurs when both sides receive a
2875             // (non-matching) DEPendent command at the same time,
2876             // crossing each other in xfer to the other side (e.g. two
2877             // READ or WRITE commands).  Both sides would respond with
2878             // a Busy+Attention device status.
2879             if( ( CTCE_Info.x_unit_stat == ( CSW_BUSY | CSW_ATTN ) )
2880                 && IS_CTCE_CCW_DEP(  pSokBuf->CmdReg ) )
2881             {
2882 
2883                 // In a real CTC this never occurs, there is always a
2884                 // first and a second side.  CTCE emulates the second
2885                 // side behaviour where ctce_contention_loser==1.
2886                 if( pDEVBLK->ctce_contention_loser )
2887                 {
2888 
2889                     // This is done by signaling this by now awaiting
2890                     // side as if a matching command was received, but
2891                     // only after re-instating the original FSM state
2892                     // and ensuring that the required Busy+Attention
2893                     // device status will bereturned.  Effectively,
2894                     // this is a contention lost situation.
2895                     CTCE_Info.con_lost = 1;
2896                     pDEVBLK->ctcexState = CTCE_Info.state_new;
2897                     pDEVBLK->ctce_UnitStat = CSW_BUSY | CSW_ATTN;
2898                     obtain_lock( &pDEVBLK->ctceEventLock );
2899                     signal_condition( &pDEVBLK->ctceEvent );
2900                     release_lock( &pDEVBLK->ctceEventLock );
2901 
2902                     // After our (x-)state is reset, we need to
2903                     // re-compute the FSM state transition effects.
2904                     CTCE_Info.state_new = CTCE_NEW_Y_STATE( pSokBuf->CmdReg );
2905                     CTCE_Info.actions = CTCE_Fsm[CTCE_CMD( pSokBuf->CmdReg )]
2906                                                 [CTCE_Y_STATE_FSM_IDX].actions;
2907                 }
2908 
2909                 // At the contention winning side, we can simply ignore
2910                 // the CTCE_Recv, as the losing side will effectively
2911                 // behave is if it never happened.
2912                 else
2913                 {
2914                     CTCE_Info.con_won = 1;
2915                 }
2916             }
2917             if( CTCE_Info.con_won != 1 )
2918             {
2919 
2920                 // Device-End status indicating ready will be presented
2921                 // if the y-side has just now become ready.
2922                 CTCE_Info.de_ready = ( IS_CTCE_YNR( pDEVBLK->ctceyState ) &&
2923                                       !IS_CTCE_YNR( pSokBuf->FsmSta ) ) ? 1 : 0;
2924 
2925                 // Our (x-)side knowledge from the other (y-)side is updated.
2926                 pDEVBLK->ctceyState = pSokBuf->FsmSta;
2927                 pDEVBLK->ctceyCmd =  pSokBuf->CmdReg;
2928                 pDEVBLK->ctceyCmdSCB = pSokBuf->CmdReg;
2929 
2930                 // Only if the other (y-)side sent us a write command will
2931                 // we copy the socket buffer into the device buffer.
2932                 if( IS_CTCE_CCW_WRT( pDEVBLK->ctceyCmd ) )
2933                 {
2934 
2935                     // We retain the sCount of this WRITE command for later
2936                     // comparison against the matching READ command, ahead
2937                     // of the data itself following CTCE_SOKPFX.
2938                     *(U16*)( pDEVBLK->buf + sizeof(CTCE_SOKPFX) ) = pSokBuf->sCount ;
2939 
2940                     memcpy( pDEVBLK->buf + sizeof(CTCE_SOKPFX) + sizeof(pSokBuf->sCount) ,
2941                         buf + sizeof(CTCE_SOKPFX), pSokBuf->sCount );
2942                 }
2943 
2944                 // If the other side sent us a WRITE EOF command
2945                 // then we just set the WEOF flag on our side.
2946                 else if( IS_CTCE_CCW_WEF( pDEVBLK->ctceyCmd ) )
2947                 {
2948                     SET_CTCE_WEOF( pDEVBLK->ctcexState );
2949                 }
2950 
2951                 // If the other side sent us a READ or READBK command whilst the
2952                 // previous command at our (x-) side was a WRITE EOF command then
2953                 // the other side will have generated a Unit Exception to the WEOF
2954                 // setting, effectively discarding that READ command.  We therefore
2955                 // ignore this READ command, but we need to set the resulting
2956                 // state to Available.  We clear the Wait + Attention actions.
2957                 else if( IS_CTCE_CCW_RDA( pDEVBLK->ctceyCmd ) &&
2958                          IS_CTCE_CCW_WEF( pDEVBLK->ctcexCmd ) &&
2959                          IS_CTCE_ATTN( CTCE_Info.actions ) )
2960                 {
2961                     SET_CTCE_YAV( pDEVBLK->ctceyState );
2962                     CLR_CTCE_WAIT( CTCE_Info.actions );
2963                     CLR_CTCE_ATTN( CTCE_Info.actions );
2964                 }
2965 
2966                 // If the other (y-)side sent us a matching command for our
2967                 // (x-)side Working(D) state, then we need to signal that
2968                 // condition so that CTCE_Send no longer needs to wait.
2969                 if( IS_CTCE_MATCH( CTCE_Info.actions ) )
2970                 {
2971                     obtain_lock( &pDEVBLK->ctceEventLock );
2972                     signal_condition( &pDEVBLK->ctceEvent );
2973                     release_lock( &pDEVBLK->ctceEventLock );
2974 
2975                     // Both sides return to the available state.
2976                     SET_CTCE_YAV( pDEVBLK->ctcexState );
2977                     SET_CTCE_YAV( pDEVBLK->ctceyState );
2978 
2979                     // All matching commands result in a final UnitStat
2980                     // CE + DE stat at the local device end.
2981                     ctce_recv_mods_UnitStat = CSW_CE | CSW_DE;
2982                 } // if( IS_CTCE_MATCH( CTCE_Info.actions ) )
2983 
2984                 // If the other (y-)side sent us a Device-End status
2985                 // indicating Ready then this has to be presented on this side.
2986                 else if( CTCE_Info.de_ready )
2987                 {
2988                     release_lock( &pDEVBLK->lock );
2989                     ctce_recv_mods_UnitStat = CSW_DE;
2990                     CTCE_Info.de_ready_attn_rc = device_attention( pDEVBLK, CSW_DE );
2991                     obtain_lock( &pDEVBLK->lock );
2992 
2993                     // Reset sense byte 0 bits 1 and 7.
2994                     pDEVBLK->sense[0] &= ~( SENSE_IR | SENSE_OC );
2995 
2996                 }
2997 
2998                 // If the other (y-)side sent us a command that may require
2999                 // us to signal attention then we will do so provided no
3000                 // program chain is in progress (SA22-7203-00, item 2.1.1,
3001                 // second paragraph).  We test for that condition using the
3002                 // Command Chaining flag on the last received CCW.
3003                 CTCE_Info.attn_can = 0;
3004                 if( IS_CTCE_ATTN( CTCE_Info.actions )
3005                     && ( !pDEVBLK->ctce_ccw_flags_cc )
3006                     && ( CTCE_Info.con_lost == 0 ) )
3007                 {
3008 
3009                     // Produce a CTCE Trace logging if requested.
3010                     if( pDEVBLK->ccwtrace || pDEVBLK->ccwstep )
3011                     {
3012 
3013                         // Disable ATTN RC reporting this time.
3014                         CTCE_Info.working_attn_rc = -1;
3015 
3016                         // In a contention winner situation, the command
3017                         // received from the other (y-)side still needs
3018                         // to be reported correctly.
3019                         pDEVBLK->ctceyCmd =  pSokBuf->CmdReg;
3020                         CTCE_Info.sok_buf_len = iLength;
3021                         CTCE_Trace( pDEVBLK, pSokBuf->sCount, CTCE_RCV, &CTCE_Info, buf, &ctce_recv_mods_UnitStat );
3022                     }
3023 
3024                     // The device_attention might not work on the first
3025                     // attempt due to the fact that we need to release
3026                     // the device lock around it, merely because that
3027                     // routine obtains and releases the device lock.
3028                     // During that short period, one or more commands
3029                     // may have come in between, causing a device busy
3030                     // and a possible other (y-)side status update. So
3031                     // we may need to re-try the ATTN if needed at all.
3032                     release_lock( &pDEVBLK->lock );
3033                     CTCE_Info.working_attn_rc = 1;
3034                     for( CTCE_Info.busy_waits = 0;
3035                          ( CTCE_Info.working_attn_rc == 1 ) &&
3036                          ( CTCE_Info.attn_can == 0 ) &&
3037                          ( CTCE_Info.busy_waits <= 20 ) ;
3038                          CTCE_Info.busy_waits++ )
3039                     {
3040                         CTCE_Info.working_attn_rc = device_attention( pDEVBLK, CSW_ATTN );
3041 
3042                         // ATTN RC=1 means a device busy status did
3043                         // appear so that the signal did not work.
3044                         // We will retry after some (increasingly)
3045                         // small amount of time.
3046                         if( CTCE_Info.working_attn_rc == 1 )
3047                         {
3048                             if( CTCE_Info.busy_waits == 0 )
3049                             {
3050                                 i = 10;
3051                             }
3052                             else
3053                             {
3054                                 i = i * 2;
3055                             }
3056                             usleep(i);
3057 
3058                             // Cancel the ATTN in case a CCW program
3059                             // has started in the mean time.
3060                             if ( pDEVBLK->ctce_ccw_flags_cc )
3061                             {
3062                                 CTCE_Info.attn_can = 1;
3063                             }
3064                         }
3065                     }
3066                     obtain_lock( &pDEVBLK->lock );
3067 
3068                     // We will show the ATTN status if it was signalled.
3069                     if( CTCE_Info.working_attn_rc == 0 )
3070                     {
3071                         ctce_recv_mods_UnitStat = CSW_ATTN;
3072                     }
3073                     CTCE_Info.busy_waits -= 1;
3074                 } // if( IS_CTCE_ATTN( CTCE_Info.actions ) && ... /* Attention Needed */
3075                 else if( IS_CTCE_ATTN( CTCE_Info.actions ) )
3076                 {
3077                     CTCE_Info.busy_waits = 0;
3078                     CTCE_Info.attn_can = 1;
3079                 }
3080             }
3081 
3082             // Merge any UnitStat modifications into the final one.
3083             pDEVBLK->ctce_UnitStat |= ctce_recv_mods_UnitStat;
3084 
3085             // Produce a CTCE Trace logging if requested.
3086             if( pDEVBLK->ccwtrace || pDEVBLK->ccwstep
3087                 || ( ctce_recv_mods_UnitStat == ( CSW_BUSY | CSW_ATTN ) )
3088                 || ( CTCE_Info.de_ready_attn_rc != 0 )
3089                 || ( ( CTCE_Info.working_attn_rc  != 0 ) && ( CTCE_Info.attn_can == 0 ) )
3090                 || ( CTCE_Info.busy_waits       >= 3 ) )
3091             {
3092 
3093                 // In a contention winner situation, the command
3094                 // received from the other (y-)side still needs
3095                 // to be reported correctly.
3096                 pDEVBLK->ctceyCmd =  pSokBuf->CmdReg;
3097 
3098                 if( ctce_recv_mods_UnitStat != 0 )
3099                 {
3100                     ctce_recv_mods_UnitStat = pDEVBLK->ctce_UnitStat;
3101                 }
3102                 CTCE_Info.sok_buf_len = iLength;
3103                 CTCE_Trace( pDEVBLK, pSokBuf->sCount, CTCE_RCV, &CTCE_Info, buf, &ctce_recv_mods_UnitStat );
3104             }
3105             CTCE_Info.de_ready_attn_rc = 0;
3106             CTCE_Info.working_attn_rc  = 0;
3107             CTCE_Info.busy_waits       = 0;
3108         }
3109 
3110         release_lock( &pDEVBLK->lock );
3111     }
3112 }
3113 
3114 //
3115 // CTCE_Halt -- Halt device for CTCE adapter
3116 //
3117 
CTCE_Halt(DEVBLK * pDEVBLK)3118 static void   CTCE_Halt( DEVBLK* pDEVBLK )
3119 {
3120 
3121     // obtain_lock( &pDEVBLK->lock ) already carried out by caller in channel.c
3122     if( pDEVBLK->ccwtrace || pDEVBLK->ccwstep )
3123     {
3124         logmsg( _("HHCCT078I %04X CTCE: -| Halt x=%s y=%s\n"),
3125             CTCX_DEVNUM( pDEVBLK ),
3126             CTCE_StaStr[pDEVBLK->ctcexState & 0x07],
3127             CTCE_StaStr[pDEVBLK->ctceyState & 0x07] );
3128     }
3129 
3130     // Halt device for a CTCE device is a selective reset,
3131     // requiring our (x-)side to cancel any Working(D) wait state
3132     // if needed, and to return to the not ready state.
3133     if( IS_CTCE_YWK( pDEVBLK->ctcexState ) )
3134     {
3135         obtain_lock( &pDEVBLK->ctceEventLock );
3136         signal_condition( &pDEVBLK->ctceEvent );
3137         release_lock( &pDEVBLK->ctceEventLock );
3138         CLR_CTCE_ALLF(pDEVBLK->ctcexState);
3139         SET_CTCE_YNR(pDEVBLK->ctcexState);
3140     }
3141 }
3142 
3143 // ====================================================================
3144 // Support Functions
3145 // ====================================================================
3146 
3147 // ---------------------------------------------------------------------
3148 // ParseMAC
3149 // ---------------------------------------------------------------------
3150 //
3151 // Parse a string containing a MAC (hardware) address and return the
3152 // binary equivalent.
3153 //
3154 // Input:
3155 //      pszMACAddr   Pointer to string containing a MAC Address in the
3156 //                   format "xx-xx-xx-xx-xx-xx" or "xx:xx:xx:xx:xx:xx".
3157 //
3158 // Output:
3159 //      pbMACAddr    Pointer to a BYTE array to receive the MAC Address
3160 //                   that MUST be at least sizeof(MAC) bytes long.
3161 //
3162 // Returns:
3163 //      0 on success, -1 otherwise
3164 //
3165 
ParseMAC(char * pszMACAddr,BYTE * pbMACAddr)3166 int  ParseMAC( char* pszMACAddr, BYTE* pbMACAddr )
3167 {
3168     char    work[((sizeof(MAC)*3)-0)];
3169     BYTE    sep;
3170     int       x;
3171     unsigned  i;
3172 
3173     if (strlen(pszMACAddr) != ((sizeof(MAC)*3)-1)
3174         || (sizeof(MAC) > 1 &&
3175             *(pszMACAddr+2) != '-' &&
3176             *(pszMACAddr+2) != ':')
3177     )
3178     {
3179         errno = EINVAL;
3180         return -1;
3181     }
3182 
3183     strncpy(work,pszMACAddr,((sizeof(MAC)*3)-1));
3184     work[((sizeof(MAC)*3)-1)] = sep = *(pszMACAddr+2);
3185 
3186     for (i=0; i < sizeof(MAC); i++)
3187     {
3188         if
3189         (0
3190             || !isxdigit(work[(i*3)+0])
3191             || !isxdigit(work[(i*3)+1])
3192             ||  sep  !=  work[(i*3)+2]
3193         )
3194         {
3195             errno = EINVAL;
3196             return -1;
3197         }
3198 
3199         work[(i*3)+2] = 0;
3200         sscanf(&work[(i*3)+0],"%x",&x);
3201         *(pbMACAddr+i) = x;
3202     }
3203 
3204     return 0;
3205 }
3206 
3207 // ---------------------------------------------------------------------
3208 // packet_trace
3209 // ---------------------------------------------------------------------
3210 //
3211 // Subroutine to trace the contents of a buffer
3212 //
3213 
packet_trace(BYTE * pAddr,int iLen)3214 void  packet_trace( BYTE* pAddr, int iLen )
3215 {
3216     int           offset;
3217     unsigned int  i;
3218     unsigned char c = '\0';
3219     unsigned char e = '\0';
3220     unsigned char print_chars[17];
3221 
3222     for( offset = 0; offset < iLen; )
3223     {
3224         memset( print_chars, 0, sizeof( print_chars ) );
3225 
3226         logmsg( "+%4.4X  ", offset );
3227 
3228         for( i = 0; i < 16; i++ )
3229         {
3230             c = *pAddr++;
3231 
3232             if( offset < iLen )
3233             {
3234                 logmsg("%2.2X", c);
3235 
3236                 print_chars[i] = '.';
3237                 e = guest_to_host( c );
3238 
3239                 if( isprint( e ) )
3240                     print_chars[i] = e;
3241                 if( isprint( c ) )
3242                     print_chars[i] = c;
3243             }
3244             else
3245             {
3246                 logmsg( "  " );
3247             }
3248 
3249             offset++;
3250             if( ( offset & 3 ) == 0 )
3251             {
3252                 logmsg( " " );
3253             }
3254         }
3255 
3256         logmsg( " %s\n", print_chars );
3257     }
3258 }
3259 
3260 // ---------------------------------------------------------------------
3261 // CTCE_ChkSum
3262 // ---------------------------------------------------------------------
3263 //
3264 // Subroutine to compute a XOR-based checksum for use in debug messages.
3265 //
3266 
CTCE_ChkSum(const BYTE * pBuf,const U16 BufLen)3267 U32 CTCE_ChkSum(const BYTE* pBuf, const U16 BufLen)
3268 {
3269     U32            i;
3270     U32            XORChk = 0;                   // XOR of buffer for checking
3271     BYTE          *pXOR = (BYTE*)&XORChk;        // -> XORChk
3272 
3273 
3274     // We initialize the result with the buffer length so that
3275     // different length zero buffers yield a different checksum.
3276     XORChk = BufLen;
3277     for(i = 0; i < BufLen; i++)
3278     {
3279         if( (i % 4) == 0 )
3280         {
3281            pXOR = (BYTE*)&XORChk;
3282         }
3283         *pXOR++ ^= *pBuf++;
3284     }
3285     return XORChk;
3286 }
3287 
3288 // ---------------------------------------------------------------------
3289 // CTCE_Trace
3290 // ---------------------------------------------------------------------
3291 //
3292 // Subroutine to produce a CTCE trace logging when requested.
3293 //
3294 
CTCE_Trace(const DEVBLK * pDEVBLK,const U16 sCount,const enum CTCE_Cmd_Xfr eCTCE_Cmd_Xfr,const CTCE_INFO * pCTCE_Info,const BYTE * pCTCE_Buf,const BYTE * pUnitStat)3295 void            CTCE_Trace( const DEVBLK*             pDEVBLK,
3296                             const U16                 sCount,
3297                             const enum CTCE_Cmd_Xfr   eCTCE_Cmd_Xfr,
3298                             const CTCE_INFO*          pCTCE_Info,
3299                             const BYTE*               pCTCE_Buf,
3300                             const BYTE*               pUnitStat )
3301 {
3302     static char *CTCE_XfrStr[3] = {
3303         "-|" ,  //  0 = CTCE_LCL
3304         "->" ,  //  1 = CTCE_SND
3305         "<-"    //  2 = CTCE_RCV
3306     };
3307     BYTE           ctce_Cmd;                   // CTCE command being traced
3308     BYTE           ctce_PktSeq;                // Packet Sequence number traced
3309     CTCE_SOKPFX   *pSokBuf;                    // overlay for buf inside DEVBLK
3310     BYTE           ctce_state_verify;          // CTCE state to be verfified
3311     char           ctce_state_l_xy[2];         // CTCE X+Y states, left
3312     char           ctce_state_r_xy[2];         // CTCE X+Y stares, right
3313     char           ctce_trace_stat[16];        // to contain " Stat=.. CC=."
3314     char           ctce_trace_xtra[256];       // to contain extra info when tracing
3315     char           ctce_trace_xtra_temp[256];  // temporary work area for the above
3316 
3317     pSokBuf = (CTCE_SOKPFX*)pCTCE_Buf;
3318 
3319     // Report on the device status and CCW Command Chaining flag.
3320     if( ( eCTCE_Cmd_Xfr != CTCE_RCV ) || ( *pUnitStat != 0 ) ||
3321         ( IS_CTCE_MATCH( pCTCE_Info->actions ) ) )
3322     {
3323         snprintf( ctce_trace_stat, sizeof( ctce_trace_stat ),
3324             "Stat=%02X CC=%d", *pUnitStat, pDEVBLK->ctce_ccw_flags_cc );
3325     }
3326     else
3327     {
3328         snprintf( ctce_trace_stat, sizeof( ctce_trace_stat ),
3329             "        CC=%d", pDEVBLK->ctce_ccw_flags_cc );
3330     }
3331 
3332     ctce_trace_xtra[0] = '\0' ;
3333 
3334     // The other side's entering a "Working" state may
3335     // require an Attention or not, which will be shown.
3336     // Please note that the CTCE_ACTIONS_PRT macro in
3337     // that case will show "ATTN" at the rightmost end.
3338     if( IS_CTCE_ATTN( pCTCE_Info->actions ) && ( eCTCE_Cmd_Xfr == CTCE_RCV ) )
3339     {
3340         if( pCTCE_Info->attn_can )
3341         {
3342             strlcat( ctce_trace_xtra, "->NONE", sizeof( ctce_trace_xtra ) );
3343         }
3344         else if( pCTCE_Info->working_attn_rc > -1 )
3345         {
3346             snprintf( ctce_trace_xtra_temp, sizeof( ctce_trace_xtra_temp ),
3347                 "->RC=%d", pCTCE_Info->working_attn_rc );
3348             strlcat( ctce_trace_xtra, ctce_trace_xtra_temp, sizeof( ctce_trace_xtra ) );
3349         }
3350     }
3351 
3352     // The other side's "DE Ready" signalling to be shown.
3353     if( pCTCE_Info->de_ready )
3354     {
3355         snprintf( ctce_trace_xtra_temp, sizeof( ctce_trace_xtra_temp ),
3356             " DE_READY->RC=%d",pCTCE_Info->de_ready_attn_rc );
3357         strlcat( ctce_trace_xtra, ctce_trace_xtra_temp, sizeof( ctce_trace_xtra ) );
3358     }
3359 
3360     // "WEOF" means that the "Write End of File" bit is or was set.
3361     // "WEOF->SET" means it just got set right now, in which case
3362     // "WEOF->SET->UX" means an Unit Exception (UX) will follow because
3363     // it got set because of a WEOF command matching a Read command
3364     // (which actually will clear the WEOF immediately thereafter).
3365     // "WEOF->CLR" indicates the WEOF bit just got reset.
3366     if(  IS_CTCE_WEOF( pCTCE_Info->state_x_prev ) ||
3367          IS_CTCE_WEOF( pDEVBLK->ctcexState      ) )
3368     {
3369         strlcat( ctce_trace_xtra, " WEOF", sizeof( ctce_trace_xtra ) );
3370     }
3371     if( !IS_CTCE_WEOF( pCTCE_Info->state_x_prev ) &&
3372          IS_CTCE_WEOF( pDEVBLK->ctcexState      ) )
3373     {
3374         strlcat( ctce_trace_xtra, "->SET", sizeof( ctce_trace_xtra ) );
3375         if( IS_CTCE_MATCH( pCTCE_Info->actions ) )
3376         {
3377             strlcat( ctce_trace_xtra, "->UX", sizeof( ctce_trace_xtra ) );
3378         }
3379     }
3380     if(  IS_CTCE_WEOF( pCTCE_Info->state_x_prev ) &&
3381         !IS_CTCE_WEOF( pDEVBLK->ctcexState      ) )
3382     {
3383         strlcat( ctce_trace_xtra, "->CLR", sizeof( ctce_trace_xtra ) );
3384     }
3385 
3386     // The source for reporting dependings on the Command X-fer
3387     // direction.  The CTCE states are reported in lower case,
3388     // but a changed state is highlighted in upper case.
3389     if( eCTCE_Cmd_Xfr == CTCE_RCV )
3390     {
3391         ctce_Cmd    = pDEVBLK->ctceyCmd;
3392         ctce_PktSeq = pSokBuf->PktSeq;
3393         ctce_state_r_xy[0] = 32 + *CTCE_StaStr[CTCE_STATE( pCTCE_Info->state_x_prev )];
3394         ctce_state_r_xy[1] = 32 + *CTCE_StaStr[CTCE_STATE( pCTCE_Info->state_y_prev )];
3395         if( ( pDEVBLK->ctcexState & 0x07 ) == ( pCTCE_Info->state_x_prev & 0x07 ) )
3396         {
3397             ctce_state_l_xy[0] = 32 + *CTCE_StaStr[CTCE_STATE( pDEVBLK->ctcexState )];
3398         }
3399         else
3400         {
3401             ctce_state_l_xy[0] = *CTCE_StaStr[CTCE_STATE( pDEVBLK->ctcexState )];
3402         }
3403         if( ( pDEVBLK->ctceyState & 0x07 ) == ( pCTCE_Info->state_y_prev & 0x07 ) )
3404         {
3405             ctce_state_l_xy[1] = 32 + *CTCE_StaStr[CTCE_STATE( pDEVBLK->ctceyState )];
3406         }
3407         else
3408         {
3409             ctce_state_l_xy[1] = *CTCE_StaStr[CTCE_STATE( pDEVBLK->ctceyState )];
3410         }
3411         ctce_state_verify = pDEVBLK->ctceyState & 0x07;
3412     }
3413     else
3414     {
3415         ctce_Cmd    = pDEVBLK->ctcexCmd;
3416         ctce_PktSeq = pDEVBLK->ctcePktSeq;
3417         ctce_state_l_xy[0] = 32 + *CTCE_StaStr[CTCE_STATE( pCTCE_Info->state_x_prev )];
3418         ctce_state_l_xy[1] = 32 + *CTCE_StaStr[CTCE_STATE( pCTCE_Info->state_y_prev )];
3419         if( pDEVBLK->ctcexState == pCTCE_Info->state_x_prev )
3420         {
3421             ctce_state_r_xy[0] = 32 + *CTCE_StaStr[CTCE_STATE( pDEVBLK->ctcexState )];
3422         }
3423         else
3424         {
3425             ctce_state_r_xy[0] = *CTCE_StaStr[CTCE_STATE( pDEVBLK->ctcexState )];
3426         }
3427         if( pDEVBLK->ctceyState == pCTCE_Info->state_y_prev )
3428         {
3429             ctce_state_r_xy[1] = 32 + *CTCE_StaStr[CTCE_STATE( pDEVBLK->ctceyState )];
3430         }
3431         else
3432         {
3433             ctce_state_r_xy[1] = *CTCE_StaStr[CTCE_STATE( pDEVBLK->ctceyState )];
3434         }
3435         ctce_state_verify = pDEVBLK->ctcexState & 0x07;
3436 
3437         // Report on the SCB returned if applicable.
3438         if( IS_CTCE_CCW_SCB( ctce_Cmd ) )
3439         {
3440             snprintf( ctce_trace_xtra_temp, sizeof( ctce_trace_xtra_temp ),
3441                 " SCB=%02X=%s", pCTCE_Info->scb, CTCE_CmdStr[CTCE_CMD( pCTCE_Info->scb )] );
3442             strlcat( ctce_trace_xtra, ctce_trace_xtra_temp, sizeof( ctce_trace_xtra ) );
3443         }
3444     }
3445 
3446     // Report on the device status.
3447     if( pCTCE_Info->busy_waits != 0 )
3448     {
3449         snprintf( ctce_trace_xtra_temp, sizeof( ctce_trace_xtra_temp ),
3450             " Busy_Waits=%d", pCTCE_Info->busy_waits );
3451         strlcat( ctce_trace_xtra, ctce_trace_xtra_temp, sizeof( ctce_trace_xtra ) );
3452     }
3453 
3454     // Report on the WAIT RC if needed.
3455     if( ( eCTCE_Cmd_Xfr == CTCE_SND ) && ( pCTCE_Info->wait_rc != 0 ) )
3456     {
3457         snprintf( ctce_trace_xtra_temp, sizeof( ctce_trace_xtra_temp ),
3458             " WAIT->RC=%d", pCTCE_Info->wait_rc );
3459         strlcat( ctce_trace_xtra, ctce_trace_xtra_temp, sizeof( ctce_trace_xtra ) );
3460     }
3461 
3462     // The "state mismatch" was used for debugging purposes
3463     // which would show logic errors.
3464     if( ( pCTCE_Info->state_new != ctce_state_verify )
3465         && !( ( !pCTCE_Info->sent ) && ( IS_CTCE_SEND( pCTCE_Info->actions ) ) ) )
3466     {
3467         snprintf( ctce_trace_xtra_temp, sizeof( ctce_trace_xtra_temp ),
3468             " CTCE_STATE MISMATCH %s!=%s(:FSM) !",
3469             CTCE_StaStr[ctce_state_verify],
3470             CTCE_StaStr[pCTCE_Info->state_new] );
3471         strlcat( ctce_trace_xtra, ctce_trace_xtra_temp, sizeof( ctce_trace_xtra ) );
3472     }
3473 
3474     // The unit "Stat mismatch" was used for debugging purposes
3475     // which would show logic errors.
3476     if( ( *pUnitStat !=
3477         ( ( ( eCTCE_Cmd_Xfr == CTCE_RCV ) && ( IS_CTCE_MATCH( pCTCE_Info->actions ) ) )
3478         ? ( CSW_CE | CSW_DE ) : ( pCTCE_Info->x_unit_stat ) ) )
3479         && !( *pUnitStat & ( CSW_UC | CSW_UX | CSW_SM ) )
3480         && !( ( eCTCE_Cmd_Xfr == CTCE_RCV ) && ( IS_CTCE_WAIT( pCTCE_Info->actions ) ) )
3481         &&  ( ( eCTCE_Cmd_Xfr != CTCE_RCV ) || ( *pUnitStat != 0 ) )
3482         && !( pCTCE_Info->de_ready ) )
3483     {
3484         snprintf( ctce_trace_xtra_temp, sizeof( ctce_trace_xtra_temp ),
3485             " Stat MISMATCH %02X!=%02X(:FSM) !",
3486             *pUnitStat, pCTCE_Info->x_unit_stat );
3487         strlcat( ctce_trace_xtra, ctce_trace_xtra_temp, sizeof( ctce_trace_xtra ) );
3488     }
3489 
3490     // Report a contention loser situation.
3491     if( pCTCE_Info->con_lost )
3492     {
3493         strlcat( ctce_trace_xtra, " CON_LOSER", sizeof( ctce_trace_xtra ) );
3494     }
3495 
3496     // Report a contention winner situation.
3497     if( pCTCE_Info->con_won )
3498     {
3499         strlcat( ctce_trace_xtra, " CON_WINNER", sizeof( ctce_trace_xtra ) );
3500     }
3501 
3502 /*
3503 
3504 HHCCT079I <src_dev> CTCE: <direction> <dst_dev> <seq#> cmd=<cmd>=<cmd_hex>
3505           xy=<x_src><y_src><direction><x_dst><y_dst> l=<length> k=<chksum>
3506           Stat=<stat> <extra_msgs>
3507 
3508 Explanation
3509         The CTCE device <local_dev> processes a <cmd> (hex value <cmd_hex>).
3510         The <direction> shows whether it originates locally (the x-side),
3511         and if it needs to be send (->) to the remote <remote_dev> device
3512         (the y-side), or if the command was received (<-) from the y-side.
3513         The command causes a state transition shown in <x_local><y_local>
3514         <direction> <x_remote><y_remote>, using single-letter presentations
3515         for these (p, c, r, w, a, n); the change is highlighted in uppercase.
3516         (p=Prepare, c=Control, r=Read, w=Write, a=Available, n=Not-Ready).
3517         The resulting unit device status is shown in hex <stat>.  Extra
3518         action indications are given in <extra_msgs>, .e.g. WAIT for a
3519         matching command from the other y-side, raise ATTN at the other
3520         side which results in ATTN->RC=rc or is canceled ATTN->NONE,
3521         DE_READY->RC=rc showing DE singalling READY from the other side,
3522         and End-of-File being set (WEOF->SET) or cleared (WEOF->CLR) or
3523         just found to be set (WEOF).  WEOF->UX shows when it generates a
3524         device Unit Exception.  Other <extra_msgs> may appear.
3525 
3526 Action
3527         None.
3528 
3529 */
3530 
3531     logmsg( _("HHCCT079I %04X CTCE: %s %.4s #%04X cmd=%s=%02X xy=%.2s%s%.2s l=%04X k=%08X %s%s%s%s%s%s\n"),
3532         CTCX_DEVNUM( pDEVBLK ), CTCE_XfrStr[eCTCE_Cmd_Xfr],
3533         CTCE_FILENAME, ctce_PktSeq,
3534         CTCE_CmdStr[CTCE_CMD( ctce_Cmd )], ctce_Cmd,
3535         ctce_state_l_xy, CTCE_XfrStr[eCTCE_Cmd_Xfr],
3536         ctce_state_r_xy,
3537         sCount, IS_CTCE_CCW_WRT( ctce_Cmd )
3538         ? CTCE_ChkSum( pCTCE_Buf + sizeof(CTCE_SOKPFX), sCount )
3539         : CTCE_ChkSum( pCTCE_Buf, pCTCE_Info->sok_buf_len ),
3540         ctce_trace_stat,
3541         CTCE_ACTIONS_PRT( pCTCE_Info->actions ),
3542         ctce_trace_xtra );
3543     if( pDEVBLK->ccwstep )
3544         packet_trace( (BYTE*)pCTCE_Buf, pCTCE_Info->sok_buf_len );
3545     return;
3546 }
3547 
3548 // ---------------------------------------------------------------------
3549 // CTCE_connect_timeout
3550 // ---------------------------------------------------------------------
3551 //
3552 // connect but with a timeout parameter.
3553 //
3554 
CTCE_Connect_Timeout(int sockfd,const struct sockaddr * saptr,const socklen_t salen,const int usec)3555 int CTCE_Connect_Timeout(int                    sockfd,
3556                          const struct sockaddr* saptr,
3557                          const socklen_t        salen,
3558                          const int              usec)
3559 {
3560     int                   rc;                    // connect return code
3561     fd_set                read_set, write_set;   // socket sets for select
3562     static struct timeval connect_timeout;       // max connect wait time
3563 
3564     // Switch to non-blocking mode during the next connect.
3565     socket_set_blocking_mode( sockfd, 0 ) ;
3566     rc = connect( sockfd, saptr, salen );
3567 
3568     // In case connect() did not complete immediately then we prepare
3569     // the select() to wait for the specified amount of time.
3570     if( rc < 0 )
3571     {
3572         FD_ZERO ( &read_set );
3573         FD_SET( sockfd, &read_set );
3574         write_set = read_set ;
3575         connect_timeout.tv_sec = 0;
3576         connect_timeout.tv_usec = usec;
3577 
3578         // Then we issue select() until it returns a real error.
3579         // A zero return code means the select() timed out,
3580         // a positive one signifies the connect() took place.
3581         do
3582         {
3583             rc = select( sockfd + 1, &read_set, &write_set, NULL,
3584           		   usec ? &connect_timeout : NULL );
3585         } while( (rc < 0) && ( HSO_errno == HSO_EINTR ) );
3586 
3587         if( rc == 0 )
3588         {
3589             close_socket( sockfd ) ;
3590             rc = -1;
3591         }
3592     }
3593 
3594     // Switch back to original non-blocking mode and return
3595     socket_set_blocking_mode( sockfd, 1 ) ;
3596     return rc;
3597 }
3598