1 /* HSCCMD.C     (c) Copyright Roger Bowler, 1999-2009                */
2 /*              (c) Copyright "Fish" (David B. Trout), 2002-2009     */
3 /*              Execute Hercules System Commands                     */
4 /*                                                                   */
5 /*   Released under the Q Public License                             */
6 /*   (http://www.hercules-390.org/herclic.html) as modifications to  */
7 /*   Hercules.                                                       */
8 
9 /*-------------------------------------------------------------------*/
10 /* This module implements the various Hercules System Console        */
11 /* (i.e. hardware console) commands that the emulator supports.      */
12 /* To define a new commmand, add an entry to the "Commands" CMDTAB   */
13 /* table pointing to the command processing function, and optionally */
14 /* add additional help text to the HelpTab HELPTAB. Both tables are  */
15 /* near the end of this module.                                      */
16 /*-------------------------------------------------------------------*/
17 
18 /*
19 
20    Standard conventions are:
21 
22      argc             contains the number of elements in argv[]
23      argv[0]          contains the actual command
24      argv[1..argc-1]  contains the optional arguments
25      cmdline          contains the original command line
26 
27      returncode:
28 
29      0 = Success
30 
31      < 0 Error: Command not executed
32 
33      > 1 Failure:  one or more functions could not complete
34 
35    int test_cmd(int argc, char *argv[],char *cmdline)
36    {
37 
38    .
39    .
40    .
41    return rc
42 
43    }
44 
45 
46 */
47 
48 
49 #include "hstdinc.h"
50 
51 #define _HSCCMD_C_
52 #define _HENGINE_DLL_
53 
54 #include "hercules.h"
55 #include "devtype.h"
56 #include "opcode.h"
57 #include "history.h"
58 #include "httpmisc.h"
59 
60 #if defined(OPTION_FISHIO)
61 #include "w32chan.h"
62 #endif /* defined(OPTION_FISHIO) */
63 
64 #include "tapedev.h"
65 #include "dasdtab.h"
66 #include "ctcadpt.h"
67 
68 
69 // (forward references, etc)
70 
71 #define MAX_DEVLIST_DEVICES  1024
72 
73 #if defined(FEATURE_ECPSVM)
74 extern void ecpsvm_command(int argc, char **argv);
75 #endif
76 int ProcessPanelCommand(char*);
77 int process_script_file(char *, int);
78 static void fcb_dump(DEVBLK*, char *, unsigned int);
79 
80 /* $test_cmd - do something or other */
81 
82 #ifdef _MSVC_
83 #pragma optimize( "", off )
84 #endif
85 
86 int test_p   = 0;
87 int test_n   = 0;
88 int test_t   = 0;
89 TID test_tid = 0;
90 int test_msg_num = 0;
91 
92 char* test_p_msg = "<pnl,color(lightyellow,black),keep>Test protected message %d...\n";
93 char* test_n_msg =                                    "Test normal message %d...\n";
94 
do_test_msgs()95 void do_test_msgs()
96 {
97     int  i;
98     for (i=0; i < test_n; i++)
99         logmsg(   test_n_msg, test_msg_num++ );
100 
101     if (         !test_p) return;
102     for (i=0; i < test_p; i++)
103         logmsg(   test_p_msg, test_msg_num++ );
104 
105     if (         !test_n) return;
106     for (i=0; i < test_n; i++)
107         logmsg(   test_n_msg, test_msg_num++ );
108 
109 }
110 
test_thread(void * parg)111 void* test_thread(void* parg)
112 {
113     UNREFERENCED(parg);
114 
115     logmsg("test thread: STARTING\n");
116 
117     SLEEP( 5 );
118 
119     do_test_msgs();
120 
121     logmsg("test thread: EXITING\n");
122     test_tid = 0;
123     return NULL;
124 }
125 
126 /*-------------------------------------------------------------------*/
127 /* test command                                                      */
128 /*-------------------------------------------------------------------*/
test_cmd(int argc,char * argv[],char * cmdline)129 int test_cmd(int argc, char *argv[],char *cmdline)
130 {
131 //  UNREFERENCED(argc);
132 //  UNREFERENCED(argv);
133     UNREFERENCED(cmdline);
134 //  cause_crash();
135 
136     if (test_tid)
137     {
138         logmsg("ERROR: test thread still running!\n");
139         return 0;
140     }
141 
142     if (argc < 2 || argc > 4)
143     {
144         logmsg("Format: \"$test p=#msgs n=#msgs &\" (args can be in any order)\n");
145         return 0;
146     }
147 
148     test_p = 0;
149     test_n = 0;
150     test_t = 0;
151 
152     if (argc > 1)
153     {
154         if (strncasecmp(argv[1],   "p=",2) == 0) test_p = atoi( &argv[1][2] );
155         if (strncasecmp(argv[1],   "n=",2) == 0) test_n = atoi( &argv[1][2] );
156         if (argv[1][0] == '&') test_t = 1;
157     }
158 
159     if (argc > 2)
160     {
161         if (strncasecmp(argv[2],   "p=",2) == 0) test_p = atoi( &argv[2][2] );
162         if (strncasecmp(argv[2],   "n=",2) == 0) test_n = atoi( &argv[2][2] );
163         if (argv[2][0] == '&') test_t = 1;
164     }
165 
166     if (argc > 3)
167     {
168         if (strncasecmp(argv[3],   "p=",2) == 0) test_p = atoi( &argv[3][2] );
169         if (strncasecmp(argv[3],   "n=",2) == 0) test_n = atoi( &argv[3][2] );
170         if (argv[3][0] == '&') test_t = 1;
171     }
172 
173     if (test_t)
174         create_thread( &test_tid, DETACHED, test_thread, NULL, "test thread" );
175     else
176         do_test_msgs();
177 
178     return 0;
179 }
180 
181 #ifdef _MSVC_
182 #pragma optimize( "", on )
183 #endif
184 
185 /* Issue generic Device not found error message */
devnotfound_msg(U16 lcss,U16 devnum)186 static inline int devnotfound_msg(U16 lcss,U16 devnum)
187 {
188     logmsg(_("HHCPN181E Device number %d:%4.4X not found\n"),lcss,devnum);
189     return -1;
190 }
191 /* Issue generic Missing device number message */
missing_devnum()192 static inline void missing_devnum()
193 {
194     logmsg( _("HHCPN031E Missing device number\n") );
195 }
196 
197 
198 /* maxrates command - report maximum seen mips/sios rates */
199 
200 #ifdef OPTION_MIPS_COUNTING
201 
202 /*-------------------------------------------------------------------*/
203 /* maxrates command                                                  */
204 /*-------------------------------------------------------------------*/
maxrates_cmd(int argc,char * argv[],char * cmdline)205 int maxrates_cmd(int argc, char *argv[],char *cmdline)
206 {
207     UNREFERENCED(cmdline);
208 
209     if (argc > 1)
210     {
211         int bError = FALSE;
212         if (argc > 2)
213         {
214             logmsg( _("Improper command format") );
215             bError = TRUE;
216         }
217         else
218         {
219             int   interval = 0;
220             BYTE  c;
221             if ( sscanf( argv[1], "%d%c", &interval, &c ) != 1 || interval < 1 )
222             {
223                 logmsg( _("\"%s\": invalid maxrates interval"), argv[1] );
224                 bError = TRUE;
225             }
226             else
227             {
228                 maxrates_rpt_intvl = interval;
229                 logmsg( _("Maxrates interval set to %d minutes.\n"), maxrates_rpt_intvl );
230             }
231         }
232         if (bError)
233             logmsg( _("; enter \"help maxrates\" for help.\n") );
234     }
235     else
236     {
237         char*   pszPrevIntervalStartDateTime;
238         char*   pszCurrIntervalStartDateTime;
239         char*   pszCurrentDateTime;
240         time_t  current_time;
241 
242         current_time = time( NULL );
243 
244         pszPrevIntervalStartDateTime = strdup( ctime( &prev_int_start_time ) );
245         pszCurrIntervalStartDateTime = strdup( ctime( &curr_int_start_time ) );
246         pszCurrentDateTime           = strdup( ctime(    &current_time     ) );
247 
248         logmsg
249         (
250             "Highest observed MIPS/SIOS rates:\n\n"
251 
252             "  From: %s"
253             "  To:   %s\n"
254 
255             ,pszPrevIntervalStartDateTime
256             ,pszCurrIntervalStartDateTime
257         );
258 
259         logmsg
260         (
261             "        MIPS: %2.1d.%2.2d\n"
262             "        SIOS: %d\n\n"
263 
264             ,prev_high_mips_rate / 1000000
265             ,prev_high_mips_rate % 1000000
266             ,prev_high_sios_rate
267         );
268 
269         logmsg
270         (
271             "  From: %s"
272             "  To:   %s\n"
273 
274             ,pszCurrIntervalStartDateTime
275             ,pszCurrentDateTime
276         );
277 
278         logmsg
279         (
280             "        MIPS: %2.1d.%2.2d\n"
281             "        SIOS: %d\n\n"
282 
283             ,curr_high_mips_rate / 1000000
284             ,curr_high_mips_rate % 1000000
285             ,curr_high_sios_rate
286         );
287 
288         logmsg
289         (
290             "Current interval = %d minutes.\n"
291 
292             ,maxrates_rpt_intvl
293         );
294 
295         free( pszPrevIntervalStartDateTime );
296         free( pszCurrIntervalStartDateTime );
297         free( pszCurrentDateTime           );
298     }
299 
300     return 0;   // (make compiler happy)
301 }
302 
303 #endif // OPTION_MIPS_COUNTING
304 
305 
306 /*-------------------------------------------------------------------*/
307 /* message command - Display a line of text at the console           */
308 /*-------------------------------------------------------------------*/
message_cmd(int argc,char * argv[],char * cmdline,int withhdr)309 int message_cmd(int argc,char *argv[], char *cmdline,int withhdr)
310 {
311     char    *msgtxt;
312     time_t  mytime;
313     struct  tm *mytm;
314     int     toskip,state,i;
315     msgtxt=NULL;
316     toskip=3;
317     if(argc>2)
318     {
319         if(strcasecmp(argv[2],"AT")==0)
320         {
321             toskip=5;
322         }
323     }
324 
325     for(state=0,i=0;cmdline[i];i++)
326     {
327         if(!state)
328         {
329             if(cmdline[i]!=' ')
330             {
331                 state=1;
332                 toskip--;
333                 if(!toskip) break;
334             }
335         }
336         else
337         {
338             if(cmdline[i]==' ')
339             {
340                 state=0;
341                 if(toskip==1)
342                 {
343                     i++;
344                     toskip=0;
345                     break;
346                 }
347             }
348         }
349     }
350     if(!toskip)
351     {
352         msgtxt=&cmdline[i];
353     }
354     if(msgtxt && strlen(msgtxt)>0)
355     {
356         if(withhdr)
357         {
358             time(&mytime);
359             mytm=localtime(&mytime);
360             logmsg(
361 #if defined(OPTION_MSGCLR)
362                 "<pnl,color(white,black)>"
363 #endif
364                 " %2.2u:%2.2u:%2.2u  * MSG FROM HERCULES: %s\n",
365                     mytm->tm_hour,
366                     mytm->tm_min,
367                     mytm->tm_sec,
368                     msgtxt);
369         }
370         else
371         {
372                 logmsg(
373 #if defined(OPTION_MSGCLR)
374                 "<pnl,color(white,black)>"
375 #endif
376                 "%s\n",msgtxt);
377         }
378     }
379     return 0;
380 }
381 
382 
383 /*-------------------------------------------------------------------*/
384 /* msg command - Display a line of text at the console               */
385 /*-------------------------------------------------------------------*/
msg_cmd(int argc,char * argv[],char * cmdline)386 int msg_cmd(int argc,char *argv[], char *cmdline)
387 {
388     return(message_cmd(argc,argv,cmdline,1));
389 }
390 
391 
392 /*-------------------------------------------------------------------*/
393 /* msgnoh command - Display a line of text at the console            */
394 /*-------------------------------------------------------------------*/
msgnoh_cmd(int argc,char * argv[],char * cmdline)395 int msgnoh_cmd(int argc,char *argv[], char *cmdline)
396 {
397     return(message_cmd(argc,argv,cmdline,0));
398 }
399 
400 
401 /*-------------------------------------------------------------------*/
402 /* comment command - do absolutely nothing                           */
403 /*-------------------------------------------------------------------*/
comment_cmd(int argc,char * argv[],char * cmdline)404 int comment_cmd(int argc, char *argv[],char *cmdline)
405 {
406     UNREFERENCED(argc);
407     UNREFERENCED(argv);
408     UNREFERENCED(cmdline);
409     // Do nothing; command has already been echo'ed to console...
410     return 0;   // (make compiler happy)
411 }
412 
413 
414 /*-------------------------------------------------------------------*/
415 /* quit or exit command - terminate the emulator                     */
416 /*-------------------------------------------------------------------*/
quit_cmd(int argc,char * argv[],char * cmdline)417 int quit_cmd(int argc, char *argv[],char *cmdline)
418 {
419     UNREFERENCED(argc);
420     UNREFERENCED(argv);
421     UNREFERENCED(cmdline);
422     do_shutdown();
423     return 0;   /* (make compiler happy) */
424 }
425 
426 
427 /*-------------------------------------------------------------------*/
428 /* history command                                                   */
429 /*-------------------------------------------------------------------*/
History(int argc,char * argv[],char * cmdline)430 int History(int argc, char *argv[], char *cmdline)
431 {
432     UNREFERENCED(cmdline);
433     /* last stored command is for sure command 'hst' so remove it
434        this is the only place where history_remove is called */
435     history_remove();
436     history_requested = 1;
437     /* only 'hst' called */
438     if (argc == 1) {
439       if (history_relative_line(-1) == -1)
440         history_requested = 0;
441       return 0;
442     }
443     /* hst with argument called */
444     if (argc == 2) {
445       int x;
446       switch (argv[1][0]) {
447       case 'l':
448         history_show();
449         history_requested = 0;
450         break;
451       default:
452         x = atoi(argv[1]);
453         if (x>0) {
454           if (history_absolute_line(x) == -1)
455             history_requested = 0;
456         }
457         else {
458           if (x<0) {
459             if (history_relative_line(x) == -1)
460               history_requested = 0;
461           }
462           else {
463             /* x == 0 */
464             history_show();
465             history_requested = 0;
466           }
467         }
468       }
469     }
470     return 0;
471 }
472 
473 
474 /*-------------------------------------------------------------------*/
475 /* log command - direct log output                                   */
476 /*-------------------------------------------------------------------*/
log_cmd(int argc,char * argv[],char * cmdline)477 int log_cmd(int argc, char *argv[],char *cmdline)
478 {
479     UNREFERENCED(cmdline);
480 
481     if(argc > 1)
482     {
483         if(strcasecmp("off",argv[1]))
484             log_sethrdcpy(argv[1]);
485         else
486             log_sethrdcpy(NULL);
487     }
488     else
489         logmsg(_("HHCPN160E no argument\n"));
490 
491     return 0;
492 }
493 
494 
495 /*-------------------------------------------------------------------*/
496 /* logopt command - change log options                               */
497 /*-------------------------------------------------------------------*/
logopt_cmd(int argc,char * argv[],char * cmdline)498 int logopt_cmd(int argc, char *argv[],char *cmdline)
499 {
500     UNREFERENCED(cmdline);
501 
502     if(argc < 2)
503     {
504         logmsg(_("HHCPN195I Log options:%s\n"),
505                 sysblk.logoptnotime ? " NOTIMESTAMP" : " TIMESTAMP"
506                );
507     }
508     else
509     {
510         while (argc > 1)
511         {
512             argv++; argc--;
513             if (strcasecmp(argv[0],"timestamp") == 0 ||
514                 strcasecmp(argv[0],"time"     ) == 0)
515             {
516                 sysblk.logoptnotime = 0;
517                 logmsg(_("HHCPN197I Log option set: TIMESTAMP\n"));
518                 continue;
519             }
520             if (strcasecmp(argv[0],"notimestamp") == 0 ||
521                 strcasecmp(argv[0],"notime"     ) == 0)
522             {
523                 sysblk.logoptnotime = 1;
524                 logmsg(_("HHCPN197I Log option set: NOTIMESTAMP\n"));
525                 continue;
526             }
527 
528             logmsg(_("HHCPN196E Invalid logopt value %s\n"), argv[0]);
529         } /* while (argc > 1) */
530     }
531     return 0;
532 }
533 
534 
535 /*-------------------------------------------------------------------*/
536 /* uptime command - display how long Hercules has been running       */
537 /*-------------------------------------------------------------------*/
538 
uptime_cmd(int argc,char * argv[],char * cmdline)539 int uptime_cmd(int argc, char *argv[],char *cmdline)
540 {
541 time_t  now;
542 unsigned uptime, weeks, days, hours, mins, secs;
543 
544     UNREFERENCED( cmdline );
545     UNREFERENCED(  argc   );
546     UNREFERENCED(  argv   );
547 
548     time( &now );
549 
550     uptime = (unsigned) difftime( now, sysblk.impltime );
551 
552 #define  SECS_PER_MIN     ( 60                 )
553 #define  SECS_PER_HOUR    ( 60 * SECS_PER_MIN  )
554 #define  SECS_PER_DAY     ( 24 * SECS_PER_HOUR )
555 #define  SECS_PER_WEEK    (  7 * SECS_PER_DAY  )
556 
557     weeks = uptime /  SECS_PER_WEEK;
558             uptime %= SECS_PER_WEEK;
559     days  = uptime /  SECS_PER_DAY;
560             uptime %= SECS_PER_DAY;
561     hours = uptime /  SECS_PER_HOUR;
562             uptime %= SECS_PER_HOUR;
563     mins  = uptime /  SECS_PER_MIN;
564             uptime %= SECS_PER_MIN;
565     secs  = uptime;
566 
567     if (weeks)
568     {
569         logmsg(_("Hercules has been up for %u week%s, %u day%s, %02u:%02u:%02u.\n"),
570                     weeks, weeks >  1 ? "s" : "",
571                     days,  days  != 1 ? "s" : "",
572                     hours, mins, secs);
573     }
574     else if (days)
575     {
576         logmsg(_("Hercules has been up for %u day%s, %02u:%02u:%02u.\n"),
577                     days, days != 1 ? "s" : "",
578                     hours, mins, secs);
579     }
580     else
581     {
582         logmsg(_("Hercules has been up for %02u:%02u:%02u.\n"),
583                     hours, mins, secs);
584     }
585     return 0;
586 }
587 
588 
589 /*-------------------------------------------------------------------*/
590 /* version command - display version information                     */
591 /*-------------------------------------------------------------------*/
version_cmd(int argc,char * argv[],char * cmdline)592 int version_cmd(int argc, char *argv[],char *cmdline)
593 {
594     UNREFERENCED(cmdline);
595     UNREFERENCED(argc);
596     UNREFERENCED(argv);
597     display_version (stdout, "Hercules ", TRUE);
598     return 0;
599 }
600 
601 /*-------------------------------------------------------------------*/
602 /* fcb - display or load                                             */
603 /*-------------------------------------------------------------------*/
fcb_cmd(int argc,char * argv[],char * cmdline)604 int fcb_cmd(int argc, char *argv[], char *cmdline)
605 {
606     U16      devnum;
607     U16      lcss;
608     DEVBLK*  dev;
609     char*    devclass;
610     int      rc;
611     int      iarg,jarg;
612     int      chan;
613     int      line;
614     char     wbuf[150];
615     int      wlpi;
616     int      windex;
617     int      wlpp;
618     int      wffchan;
619     int      wfcb[FCBSIZE+1];
620     char     *ptr, *nxt;
621 
622     UNREFERENCED(cmdline);
623 
624     /* process specified printer device */
625 
626     if (argc < 2)
627     {
628         logmsg( _("HHCPN021E Missing device address\n")) ;
629         return -1 ;
630     }
631 
632     rc=parse_single_devnum(argv[1],&lcss,&devnum);
633     if (rc<0)
634     {
635         return -1;
636     }
637 
638     if (!(dev = find_device_by_devnum (lcss,devnum)))
639     {
640         devnotfound_msg(lcss,devnum);
641         return -1;
642     }
643 
644     (dev->hnd->query)(dev, &devclass, 0, NULL);
645 
646     if (strcasecmp(devclass,"PRT"))
647     {
648         logmsg( _("HHCPNzzzE Device %d:%4.4X is not a printer device\n"),
649                   lcss, devnum );
650         return -1;
651     }
652 
653     if ( argc == 2 )
654     {
655         fcb_dump(dev, wbuf, sizeof(wbuf));
656         logmsg("HHCPN210I %d:%4.4X %s\n",
657                 lcss, devnum, wbuf);
658         return 0;
659     }
660 
661     if ( !dev->stopprt )
662     {
663         logmsg( _("HHCPNzzzE Device %d:%4.4X not stopped \n"),
664                   lcss, devnum );
665         return -1;
666     }
667 
668     wlpi = dev->lpi;
669     windex = dev->index;
670     wlpp = dev->lpp;
671     wffchan = dev->ffchan;
672     for (line = 0; line <= FCBSIZE; line++)
673         wfcb[line] = dev->fcb[line];
674 
675     for (iarg = 2; iarg < argc; iarg++)
676     {
677         if (strncasecmp("lpi=", argv[iarg], 4) == 0)
678         {
679             ptr = argv[iarg]+4;
680             errno = 0;
681             wlpi = (int) strtoul(ptr,&nxt,10) ;
682             if (errno != 0 || nxt == ptr || *nxt != 0 || ( wlpi != 6 && wlpi != 8 && wlpi != 10) )
683             {
684                 jarg = ptr - argv[iarg] ;
685                 logmsg("HHCPN103E %d:%4.4X Printer: parameter %s in argument %d at position %d is invalid\n",
686                         SSID_TO_LCSS(dev->ssid), dev->devnum, argv[iarg], iarg + 1, jarg);
687                 return -1;
688             }
689             continue;
690         }
691 
692         if (strncasecmp("index=", argv[iarg], 6) == 0)
693         {
694             if (0x3211 != dev->devtype )
695             {
696                 logmsg("HHCPN103E %d:%4.4X Printer: parameter %s in argument %d at position %d is invalid\n",
697                         SSID_TO_LCSS(dev->ssid), dev->devnum, argv[iarg], iarg + 1, 1);
698                 return -1;
699             }
700             ptr = argv[iarg]+6;
701             errno = 0;
702             windex = (int) strtoul(ptr,&nxt,10) ;
703             if (errno != 0 || nxt == ptr || *nxt != 0 || ( windex < 0 || windex > 15) )
704             {
705                 jarg = ptr - argv[iarg] ;
706                 logmsg("HHCPN103E %d:%4.4X Printer: parameter %s in argument %d at position %d is invalid\n",
707                         SSID_TO_LCSS(dev->ssid), dev->devnum, argv[iarg], iarg + 1, jarg);
708                 return -1;
709             }
710             continue;
711         }
712 
713         if (strncasecmp("lpp=", argv[iarg], 4) == 0)
714         {
715             ptr = argv[iarg]+4;
716             errno = 0;
717             wlpp = (int) strtoul(ptr,&nxt,10) ;
718             if (errno != 0 || nxt == ptr || *nxt != 0 ||wlpp > FCBSIZE)
719             {
720                 jarg = ptr - argv[iarg] ;
721                 logmsg("HHCPN103E %d:%4.4X Printer: parameter %s in argument %d at position %d is invalid\n",
722                         SSID_TO_LCSS(dev->ssid), dev->devnum, argv[iarg], iarg + 1, jarg);
723                 return -1;
724             }
725             continue;
726         }
727 #if 0
728         if (strncasecmp("ffchan=", argv[iarg], 7) == 0)
729         {
730             ptr = argv[iarg]+7;
731             errno = 0;
732             wffchan = (int) strtoul(ptr,&nxt,10) ;
733             if (errno != 0 || nxt == ptr || *nxt != 0 ||  wffchan < 1 || wffchan > 12)
734             {
735                 jarg = ptr - argv[iarg] ;
736                 logmsg("HHCPN103E %d:%4.4X Printer: parameter %s in argument %d at position %d is invalid\n",
737                         SSID_TO_LCSS(dev->ssid), dev->devnum, argv[iarg], iarg + 1, jarg);
738                 return -1;
739             }
740             continue ;
741         }
742 #endif
743         if (strncasecmp("fcb=", argv[iarg], 4) == 0)
744         {
745             for (line = 0 ; line <= FCBSIZE; line++)  wfcb[line] = 0;
746             /* check for simple mode */
747             if ( strstr(argv[iarg],":") )
748             {
749                 /* ':" found  ==> new mode */
750                 ptr = argv[iarg]+4;
751                 while (*ptr)
752                 {
753                     errno = 0;
754                     line = (int) strtoul(ptr,&nxt,10) ;
755                     if (errno != 0 || *nxt != ':' || nxt == ptr || line > wlpp || wfcb[line] != 0 )
756                     {
757                         jarg = ptr - argv[iarg] ;
758                         logmsg("HHCPN103E %d:%4.4X Printer: parameter %s in argument %d at position %d is invalid\n",
759                                 SSID_TO_LCSS(dev->ssid), dev->devnum, argv[iarg], iarg + 1, jarg);
760                         return -1;
761                     }
762 
763                     ptr = nxt + 1 ;
764                     errno = 0;
765                     chan = (int) strtoul(ptr,&nxt,10) ;
766                     if (errno != 0 || (*nxt != ',' && *nxt != 0) || nxt == ptr || chan < 1 || chan > 12 )
767                     {
768                         jarg = ptr - argv[iarg] ;
769                         logmsg("HHCPN103E %d:%4.4X Printer: parameter %s in argument %d at position %d is invalid\n",
770                                 SSID_TO_LCSS(dev->ssid), dev->devnum, argv[iarg], iarg + 1, jarg);
771                         return -1;
772                     }
773                     wfcb[line] = chan;
774                     if ( nxt == 0 )
775                         break ;
776                     ptr = nxt + 1;
777                 }
778 
779             }
780             else
781             {
782                 /* ':" NOT found  ==> old mode */
783                 ptr = argv[iarg]+4;
784                 chan = 0;
785                 while (*ptr)
786                 {
787                     errno = 0;
788                     line = (int) strtoul(ptr,&nxt,10) ;
789                     if (errno != 0 || (*nxt != ',' && *nxt != 0) || nxt == ptr || line > wlpp || wfcb[line] != 0 )
790                     {
791                         jarg = ptr - argv[iarg] ;
792                         logmsg("HHCPN103E %d:%4.4X Printer: parameter %s in argument %d at position %d is invalid\n",
793                                 SSID_TO_LCSS(dev->ssid), dev->devnum, argv[iarg], iarg + 1, jarg);
794                         return -1;
795                     }
796                     chan += 1;
797                     if ( chan > 12 )
798                     {
799                         jarg = ptr - argv[iarg] ;
800                         logmsg("HHCPN103E %d:%4.4X Printer: parameter %s in argument %d at position %d is invalid\n",
801                                 SSID_TO_LCSS(dev->ssid), dev->devnum, argv[iarg], iarg + 1, jarg);
802                         return -1;
803                     }
804                     wfcb[line] = chan;
805                     if ( nxt == 0 )
806                         break ;
807                     ptr = nxt + 1;
808                 }
809                 if ( chan != 12 )
810                 {
811                     jarg = 5 ;
812                     logmsg("HHCPN103E %d:%4.4X Printer: parameter %s in argument %d at position %d is invalid\n",
813                             SSID_TO_LCSS(dev->ssid), dev->devnum, argv[iarg], iarg + 1, jarg);
814                     return -1;
815                 }
816             }
817 
818             continue;
819         }
820 
821         logmsg("HHCPN102E %d:%4.4X Printer: parameter %s in argument %d is invalid\n",
822                 SSID_TO_LCSS(dev->ssid), dev->devnum, argv[iarg], iarg + 1);
823         return -1;
824     }
825 
826     /* It's all ok, copy it to the dev block */
827     dev->lpi = wlpi;
828     dev->index = windex ;
829     dev->lpp = wlpp;
830     dev->ffchan = wffchan;
831     for (line = 0; line <= FCBSIZE; line++)
832         dev->fcb[line] = wfcb[line];
833 
834     fcb_dump(dev, wbuf, sizeof(wbuf));
835     logmsg("HHCPN210I %d:%4.4X %s\n",
836             lcss, devnum, wbuf );
837     return 0;
838 }
839 
fcb_dump(DEVBLK * dev,char * buf,unsigned int buflen)840 static void fcb_dump(DEVBLK* dev, char *buf, unsigned int buflen)
841 {
842     int i;
843     char wrk[16];
844     char sep[1];
845     sep[0] = '=';
846     snprintf( buf, buflen, "lpi=%d index=%d lpp=%d fcb", dev->lpi, dev->index, dev->lpp );
847     for (i = 1; i <= dev->lpp; i++)
848     {
849         if (dev->fcb[i] != 0)
850         {
851             sprintf(wrk, "%c%d:%d", sep[0], i, dev->fcb[i]);
852             sep[0] = ',' ;
853             if (strlen(buf) + strlen(wrk) >= buflen - 4)
854             {
855                 /* Too long, truncate it */
856                 strcat(buf, ",...");
857                 return;
858             }
859             strcat(buf, wrk);
860         }
861     }
862     return;
863 
864 }
865 
866 /*-------------------------------------------------------------------*/
867 /* start command - start CPU (or printer device if argument given)   */
868 /*-------------------------------------------------------------------*/
start_cmd(int argc,char * argv[],char * cmdline)869 int start_cmd(int argc, char *argv[], char *cmdline)
870 {
871     UNREFERENCED(cmdline);
872 
873     if (argc < 2)
874     {
875         OBTAIN_INTLOCK(NULL);
876         if (IS_CPU_ONLINE(sysblk.pcpu))
877         {
878             REGS *regs = sysblk.regs[sysblk.pcpu];
879             regs->opinterv = 0;
880             regs->cpustate = CPUSTATE_STARTED;
881             regs->checkstop = 0;
882             WAKEUP_CPU(regs);
883         }
884         RELEASE_INTLOCK(NULL);
885     }
886     else
887     {
888         /* start specified printer device */
889 
890         U16      devnum;
891         U16      lcss;
892         int      stopprt;
893         DEVBLK*  dev;
894         char*    devclass;
895         int      rc;
896 
897         rc=parse_single_devnum(argv[1],&lcss,&devnum);
898         if (rc<0)
899         {
900             return -1;
901         }
902 
903         if (!(dev = find_device_by_devnum (lcss,devnum)))
904         {
905             devnotfound_msg(lcss,devnum);
906             return -1;
907         }
908 
909         (dev->hnd->query)(dev, &devclass, 0, NULL);
910 
911         if (strcasecmp(devclass,"PRT"))
912         {
913             logmsg( _("HHCPN017E Device %d:%4.4X is not a printer device\n"),
914                       lcss, devnum );
915             return -1;
916         }
917 
918         /* un-stop the printer and raise attention interrupt */
919 
920         stopprt = dev->stopprt; dev->stopprt = 0;
921 
922         rc = device_attention (dev, CSW_ATTN);
923 
924         if (rc) dev->stopprt = stopprt;
925 
926         switch (rc) {
927             case 0: logmsg(_("HHCPN018I Printer %d:%4.4X started\n"), lcss,devnum);
928                     break;
929             case 1: logmsg(_("HHCPN019E Printer %d:%4.4X not started: "
930                              "busy or interrupt pending\n"), lcss, devnum);
931                     break;
932             case 2: logmsg(_("HHCPN020E Printer %d:%4.4X not started: "
933                              "attention request rejected\n"), lcss, devnum);
934                     break;
935             case 3: logmsg(_("HHCPN021E Printer %d:%4.4X not started: "
936                              "subchannel not enabled\n"), lcss, devnum);
937                     break;
938         }
939 
940     }
941 
942     return 0;
943 }
944 
945 
946 /*-------------------------------------------------------------------*/
947 /* g command - turn off single stepping and start CPU                */
948 /*-------------------------------------------------------------------*/
g_cmd(int argc,char * argv[],char * cmdline)949 int g_cmd(int argc, char *argv[], char *cmdline)
950 {
951     int i;
952 
953     UNREFERENCED(cmdline);
954     UNREFERENCED(argc);
955     UNREFERENCED(argv);
956 
957     OBTAIN_INTLOCK(NULL);
958     sysblk.inststep = 0;
959     SET_IC_TRACE;
960     for (i = 0; i < HI_CPU; i++)
961         if (IS_CPU_ONLINE(i) && sysblk.regs[i]->stepwait)
962         {
963             sysblk.regs[i]->cpustate = CPUSTATE_STARTED;
964             WAKEUP_CPU(sysblk.regs[i]);
965         }
966     RELEASE_INTLOCK(NULL);
967     return 0;
968 }
969 
970 
971 /*-------------------------------------------------------------------*/
972 /* stop command - stop CPU (or printer device if argument given)     */
973 /*-------------------------------------------------------------------*/
stop_cmd(int argc,char * argv[],char * cmdline)974 int stop_cmd(int argc, char *argv[], char *cmdline)
975 {
976     UNREFERENCED(cmdline);
977 
978     if (argc < 2)
979     {
980         OBTAIN_INTLOCK(NULL);
981         if (IS_CPU_ONLINE(sysblk.pcpu))
982         {
983             REGS *regs = sysblk.regs[sysblk.pcpu];
984             regs->opinterv = 1;
985             regs->cpustate = CPUSTATE_STOPPING;
986             ON_IC_INTERRUPT(regs);
987             WAKEUP_CPU (regs);
988         }
989         RELEASE_INTLOCK(NULL);
990     }
991     else
992     {
993         /* stop specified printer device */
994 
995         U16      devnum;
996         U16      lcss;
997         DEVBLK*  dev;
998         char*    devclass;
999         int     rc;
1000 
1001         rc=parse_single_devnum(argv[1],&lcss,&devnum);
1002         if (rc<0)
1003         {
1004             return -1;
1005         }
1006 
1007         if (!(dev = find_device_by_devnum (lcss, devnum)))
1008         {
1009             devnotfound_msg(lcss,devnum);
1010             return -1;
1011         }
1012 
1013         (dev->hnd->query)(dev, &devclass, 0, NULL);
1014 
1015         if (strcasecmp(devclass,"PRT"))
1016         {
1017             logmsg( _("HHCPN024E Device %d:%4.4X is not a printer device\n"),
1018                       lcss, devnum );
1019             return -1;
1020         }
1021 
1022         dev->stopprt = 1;
1023 
1024         logmsg( _("HHCPN025I Printer %d:%4.4X stopped\n"), lcss, devnum );
1025     }
1026 
1027     return 0;
1028 }
1029 
1030 
1031 /*-------------------------------------------------------------------*/
1032 /* startall command - start all CPU's                                */
1033 /*-------------------------------------------------------------------*/
startall_cmd(int argc,char * argv[],char * cmdline)1034 int startall_cmd(int argc, char *argv[], char *cmdline)
1035 {
1036     int i;
1037     CPU_BITMAP mask;
1038 
1039     UNREFERENCED(cmdline);
1040     UNREFERENCED(argc);
1041     UNREFERENCED(argv);
1042 
1043     OBTAIN_INTLOCK(NULL);
1044     mask = (~sysblk.started_mask) & sysblk.config_mask;
1045     for (i = 0; mask; i++)
1046     {
1047         if (mask & 1)
1048         {
1049             REGS *regs = sysblk.regs[i];
1050             regs->opinterv = 0;
1051             regs->cpustate = CPUSTATE_STARTED;
1052             signal_condition(&regs->intcond);
1053         }
1054         mask >>= 1;
1055     }
1056 
1057     RELEASE_INTLOCK(NULL);
1058 
1059     return 0;
1060 }
1061 
1062 
1063 /*-------------------------------------------------------------------*/
1064 /* stopall command - stop all CPU's                                  */
1065 /*-------------------------------------------------------------------*/
stopall_cmd(int argc,char * argv[],char * cmdline)1066 DLL_EXPORT int stopall_cmd(int argc, char *argv[], char *cmdline)
1067 {
1068     int i;
1069     CPU_BITMAP mask;
1070 
1071     UNREFERENCED(cmdline);
1072     UNREFERENCED(argc);
1073     UNREFERENCED(argv);
1074 
1075     OBTAIN_INTLOCK(NULL);
1076 
1077     mask = sysblk.started_mask;
1078     for (i = 0; mask; i++)
1079     {
1080         if (mask & 1)
1081         {
1082             REGS *regs = sysblk.regs[i];
1083             regs->opinterv = 1;
1084             regs->cpustate = CPUSTATE_STOPPING;
1085             ON_IC_INTERRUPT(regs);
1086             signal_condition(&regs->intcond);
1087         }
1088         mask >>= 1;
1089     }
1090 
1091     RELEASE_INTLOCK(NULL);
1092 
1093     return 0;
1094 }
1095 
1096 #ifdef _FEATURE_CPU_RECONFIG
1097 
1098 
1099 /*-------------------------------------------------------------------*/
1100 /* cf command - configure/deconfigure a CPU                          */
1101 /*-------------------------------------------------------------------*/
cf_cmd(int argc,char * argv[],char * cmdline)1102 int cf_cmd(int argc, char *argv[], char *cmdline)
1103 {
1104     int on = -1;
1105 
1106     UNREFERENCED(cmdline);
1107 
1108     if (argc == 2)
1109     {
1110         if (!strcasecmp(argv[1],"on"))
1111             on = 1;
1112         else if (!strcasecmp(argv[1], "off"))
1113             on = 0;
1114     }
1115 
1116     OBTAIN_INTLOCK(NULL);
1117 
1118     if (IS_CPU_ONLINE(sysblk.pcpu))
1119     {
1120         if (on < 0)
1121             logmsg(_("HHCPN152I CPU%4.4X online\n"), sysblk.pcpu);
1122         else if (on == 0)
1123             deconfigure_cpu(sysblk.pcpu);
1124     }
1125     else
1126     {
1127         if (on < 0)
1128             logmsg(_("HHCPN153I CPU%4.4X offline\n"), sysblk.pcpu);
1129         else if (on > 0)
1130             configure_cpu(sysblk.pcpu);
1131     }
1132 
1133     RELEASE_INTLOCK(NULL);
1134 
1135     if (on >= 0) cf_cmd (0, NULL, NULL);
1136 
1137     return 0;
1138 }
1139 
1140 
1141 /*-------------------------------------------------------------------*/
1142 /* cfall command - configure/deconfigure all CPU's                   */
1143 /*-------------------------------------------------------------------*/
cfall_cmd(int argc,char * argv[],char * cmdline)1144 int cfall_cmd(int argc, char *argv[], char *cmdline)
1145 {
1146     int i;
1147     int on = -1;
1148 
1149     UNREFERENCED(cmdline);
1150 
1151     if (argc == 2)
1152     {
1153         if (!strcasecmp(argv[1],"on"))
1154             on = 1;
1155         else if (!strcasecmp(argv[1], "off"))
1156             on = 0;
1157     }
1158 
1159     OBTAIN_INTLOCK(NULL);
1160 
1161     for (i = 0; i < MAX_CPU_ENGINES; i++)
1162         if (IS_CPU_ONLINE(i))
1163         {
1164             if (on < 0)
1165                 logmsg(_("HHCPN154I CPU%4.4X online\n"), i);
1166             else if (on == 0)
1167                 deconfigure_cpu(i);
1168         }
1169         else
1170         {
1171             if (on < 0)
1172                 logmsg(_("HHCPN155I CPU%4.4X offline\n"), i);
1173             else if (on > 0 && i < MAX_CPU)
1174                 configure_cpu(i);
1175         }
1176 
1177     RELEASE_INTLOCK(NULL);
1178 
1179     if (on >= 0) cfall_cmd (0, NULL, NULL);
1180 
1181     return 0;
1182 }
1183 
1184 #endif /*_FEATURE_CPU_RECONFIG*/
1185 
1186 
1187 /*-------------------------------------------------------------------*/
1188 /* quiet command - quiet PANEL                                       */
1189 /*-------------------------------------------------------------------*/
quiet_cmd(int argc,char * argv[],char * cmdline)1190 int quiet_cmd(int argc, char *argv[], char *cmdline)
1191 {
1192     UNREFERENCED(cmdline);
1193     UNREFERENCED(argc);
1194     UNREFERENCED(argv);
1195 #ifdef EXTERNALGUI
1196     if (extgui)
1197     {
1198         logmsg( _("HHCPN026W Ignored. (external GUI active)\n") );
1199         return 0;
1200     }
1201 #endif /*EXTERNALGUI*/
1202     sysblk.npquiet = !sysblk.npquiet;
1203     logmsg( _("HHCPN027I Automatic refresh %s.\n"),
1204               sysblk.npquiet ? _("disabled") : _("enabled") );
1205     return 0;
1206 }
1207 
1208 
1209 /* format_tod - generate displayable date from TOD value */
1210 /* always uses epoch of 1900 */
format_tod(char * buf,U64 tod,int flagdate)1211 char * format_tod(char *buf, U64 tod, int flagdate)
1212 {
1213     int leapyear, years, days, hours, minutes, seconds, microseconds;
1214 
1215     if(tod >= TOD_YEAR)
1216     {
1217         tod -= TOD_YEAR;
1218         years = (tod / TOD_4YEARS * 4) + 1;
1219         tod %= TOD_4YEARS;
1220         if((leapyear = tod / TOD_YEAR) == 4)
1221         {
1222             tod %= TOD_YEAR;
1223             years--;
1224             tod += TOD_YEAR;
1225         }
1226         else
1227             tod %= TOD_YEAR;
1228 
1229         years += leapyear;
1230     }
1231     else
1232         years = 0;
1233 
1234     days = tod / TOD_DAY;
1235     tod %= TOD_DAY;
1236     hours = tod / TOD_HOUR;
1237     tod %= TOD_HOUR;
1238     minutes = tod / TOD_MIN;
1239     tod %= TOD_MIN;
1240     seconds = tod / TOD_SEC;
1241     microseconds = (tod % TOD_SEC) / TOD_USEC;
1242 
1243     if (flagdate)
1244     {
1245         years += 1900;
1246         days += 1;
1247     }
1248 
1249     sprintf(buf,"%4d.%03d %02d:%02d:%02d.%06d",
1250         years,days,hours,minutes,seconds,microseconds);
1251 
1252     return buf;
1253 }
1254 
1255 
1256 /*-------------------------------------------------------------------*/
1257 /* timerint - display or set the timer interval                      */
1258 /*-------------------------------------------------------------------*/
timerint_cmd(int argc,char * argv[],char * cmdline)1259 int timerint_cmd(int argc, char *argv[], char *cmdline)
1260 {
1261     UNREFERENCED(cmdline);
1262 
1263     if (argc > 1)
1264     {
1265         if (!strcasecmp(argv[1],"default"))
1266             sysblk.timerint = DEFAULT_TIMER_REFRESH_USECS;
1267         else if (!strcasecmp(argv[1],"reset"))
1268             sysblk.timerint = DEFAULT_TIMER_REFRESH_USECS;
1269         else
1270         {
1271             int timerint = 0; BYTE c;
1272 
1273             if (1
1274                 && sscanf(argv[1], "%d%c", &timerint, &c) == 1
1275                 && timerint >= 1
1276                 && timerint <= 1000000
1277             )
1278             {
1279                 sysblk.timerint = timerint;
1280             }
1281         }
1282     }
1283     else
1284         logmsg( _("HHCPN037I Timer update interval = %d microsecond(s)\n"),
1285               sysblk.timerint );
1286 
1287     return 0;
1288 }
1289 
1290 
1291 /*-------------------------------------------------------------------*/
1292 /* clocks command - display tod clkc and cpu timer                   */
1293 /*-------------------------------------------------------------------*/
clocks_cmd(int argc,char * argv[],char * cmdline)1294 int clocks_cmd(int argc, char *argv[], char *cmdline)
1295 {
1296 REGS *regs;
1297 char clock_buf[30];
1298 U64 tod_now;
1299 U64 hw_now;
1300 S64 epoch_now;
1301 U64 epoch_now_abs;
1302 char epoch_sign;
1303 U64 clkc_now;
1304 S64 cpt_now;
1305 #if defined(_FEATURE_SIE)
1306 U64 vtod_now = 0;
1307 S64 vepoch_now = 0;
1308 U64 vepoch_now_abs = 0;
1309 char vepoch_sign = ' ';
1310 U64 vclkc_now = 0;
1311 S64 vcpt_now = 0;
1312 char sie_flag = 0;
1313 #endif
1314 U32 itimer = 0;
1315 char itimer_formatted[20];
1316 char arch370_flag = 0;
1317 
1318     UNREFERENCED(cmdline);
1319     UNREFERENCED(argc);
1320     UNREFERENCED(argv);
1321 
1322     obtain_lock(&sysblk.cpulock[sysblk.pcpu]);
1323 
1324     if (!IS_CPU_ONLINE(sysblk.pcpu))
1325     {
1326         release_lock(&sysblk.cpulock[sysblk.pcpu]);
1327         logmsg( _("HHCPN160W CPU%4.4X not configured\n"), sysblk.pcpu);
1328         return 0;
1329     }
1330     regs = sysblk.regs[sysblk.pcpu];
1331 
1332 /* Get the clock values all at once for consistency and so we can
1333    release the CPU lock more quickly. */
1334     tod_now = (tod_clock(regs) << 8) >> 8;
1335     hw_now = hw_tod;
1336     epoch_now = regs->tod_epoch;
1337     clkc_now = regs->clkc;
1338     cpt_now = CPU_TIMER(regs);
1339 #if defined(_FEATURE_SIE)
1340     if(regs->sie_active)
1341     {
1342         vtod_now = (TOD_CLOCK(regs->guestregs) << 8) >> 8;
1343         vepoch_now = regs->guestregs->tod_epoch;
1344         vclkc_now = regs->guestregs->clkc;
1345         vcpt_now = CPU_TIMER(regs->guestregs);
1346         sie_flag = 1;
1347     }
1348 #endif
1349     if (regs->arch_mode == ARCH_370)
1350     {
1351         itimer = INT_TIMER(regs);
1352         /* The interval timer counts 76800 per second, or one every
1353            13.0208 microseconds. */
1354         sprintf(itimer_formatted,"%02u:%02u:%02u.%06u",
1355                 (itimer/(76800*60*60)),((itimer%(76800*60*60))/(76800*60)),
1356                 ((itimer%(76800*60))/76800),((itimer%76800)*13));
1357         arch370_flag = 1;
1358     }
1359 
1360     release_lock(&sysblk.cpulock[sysblk.pcpu]);
1361 
1362     logmsg( _("HHCPN028I tod = %16.16" I64_FMT "X    %s\n"),
1363                (tod_now << 8),format_tod(clock_buf,tod_now,TRUE));
1364 
1365     logmsg( _("          h/w = %16.16" I64_FMT "X    %s\n"),
1366                (hw_now << 8),format_tod(clock_buf,hw_now,TRUE));
1367 
1368     if (epoch_now < 0) {
1369         epoch_now_abs = -(epoch_now);
1370         epoch_sign = '-';
1371     }
1372     else
1373     {
1374         epoch_now_abs = epoch_now;
1375         epoch_sign = ' ';
1376     }
1377     logmsg( _("          off = %16.16" I64_FMT "X   %c%s\n"),
1378                (epoch_now << 8),epoch_sign,
1379                format_tod(clock_buf,epoch_now_abs,FALSE));
1380 
1381     logmsg( _("          ckc = %16.16" I64_FMT "X    %s\n"),
1382                (clkc_now << 8),format_tod(clock_buf,clkc_now,TRUE));
1383 
1384     if (regs->cpustate != CPUSTATE_STOPPED)
1385         logmsg( _("          cpt = %16.16" I64_FMT "X\n"), cpt_now << 8);
1386     else
1387         logmsg( _("          cpt = not decrementing\n"));
1388 
1389 #if defined(_FEATURE_SIE)
1390     if(sie_flag)
1391     {
1392 
1393         logmsg( _("         vtod = %16.16" I64_FMT "X    %s\n"),
1394                    (vtod_now << 8),format_tod(clock_buf,vtod_now,TRUE));
1395 
1396         if (epoch_now < 0) {
1397             epoch_now_abs = -(epoch_now);
1398             epoch_sign = '-';
1399         }
1400         else
1401         {
1402             epoch_now_abs = epoch_now;
1403             epoch_sign = ' ';
1404         }
1405         logmsg( _("         voff = %16.16" I64_FMT "X   %c%s\n"),
1406                    (vepoch_now << 8),vepoch_sign,
1407                    format_tod(clock_buf,vepoch_now_abs,FALSE));
1408 
1409         logmsg( _("         vckc = %16.16" I64_FMT "X    %s\n"),
1410                    (vclkc_now << 8),format_tod(clock_buf,vclkc_now,TRUE));
1411 
1412         logmsg( _("         vcpt = %16.16" I64_FMT "X\n"),vcpt_now << 8);
1413     }
1414 #endif
1415 
1416     if (arch370_flag)
1417     {
1418         logmsg( _("          itm = %8.8" I32_FMT "X                     %s\n"),
1419                    itimer, itimer_formatted );
1420     }
1421 
1422     return 0;
1423 }
1424 
1425 #ifdef OPTION_IODELAY_KLUDGE
1426 
1427 
1428 /*-------------------------------------------------------------------*/
1429 /* iodelay command - display or set I/O delay value                  */
1430 /*-------------------------------------------------------------------*/
iodelay_cmd(int argc,char * argv[],char * cmdline)1431 int iodelay_cmd(int argc, char *argv[], char *cmdline)
1432 {
1433     UNREFERENCED(cmdline);
1434 
1435     if (argc > 1)
1436     {
1437         int iodelay = 0;
1438         BYTE    c;                      /* Character work area       */
1439 
1440         if (sscanf(argv[1], "%d%c", &iodelay, &c) != 1)
1441             logmsg( _("HHCPN029E Invalid I/O delay value: %s\n"), argv[1] );
1442         else
1443             sysblk.iodelay = iodelay;
1444     }
1445     else
1446         logmsg( _("HHCPN030I I/O delay = %d\n"), sysblk.iodelay );
1447 
1448     return 0;
1449 }
1450 
1451 #endif /*OPTION_IODELAY_KLUDGE*/
1452 
1453 
1454 #if defined( OPTION_TAPE_AUTOMOUNT )
1455 /*-------------------------------------------------------------------*/
1456 /* automount_cmd - show or update AUTOMOUNT directories list         */
1457 /*-------------------------------------------------------------------*/
automount_cmd(int argc,char * argv[],char * cmdline)1458 int automount_cmd(int argc, char *argv[], char *cmdline)
1459 {
1460 int rc;
1461 
1462     UNREFERENCED(cmdline);
1463 
1464     if (argc < 2)
1465     {
1466         logmsg(_("HHCPN200E Missing operand; enter 'HELP AUTOMOUNT' for syntax.\n"));
1467         return -1;
1468     }
1469 
1470     if (strcasecmp(argv[1],"list") == 0)
1471     {
1472         TAMDIR* pTAMDIR = sysblk.tamdir;
1473 
1474         if (argc != 2)
1475         {
1476             logmsg(_("HHCPN201E Invalid syntax; enter 'HELP AUTOMOUNT' for help.\n"));
1477             return -1;
1478         }
1479 
1480         if (!pTAMDIR)
1481         {
1482             logmsg(_("HHCPN202E Empty list.\n"));
1483             return -1;
1484         }
1485 
1486         // List all entries...
1487 
1488         for (; pTAMDIR; pTAMDIR = pTAMDIR->next)
1489             logmsg(_("HHCPN203I \"%c%s\"\n")
1490                 ,pTAMDIR->rej ? '-' : '+'
1491                 ,pTAMDIR->dir
1492                 );
1493         return 0;
1494     }
1495 
1496     if (strcasecmp(argv[1],"add") == 0 || *argv[1] == '+')
1497     {
1498         char *argv2;
1499         char tamdir[MAX_PATH+1]; /* +1 for optional '+' or '-' prefix */
1500         TAMDIR* pTAMDIR = NULL;
1501 //      int was_empty = (sysblk.tamdir == NULL);
1502 
1503         if(*argv[1] == '+')
1504         {
1505             argv2 = argv[1] + 1;
1506 
1507             if (argc != 2 )
1508             {
1509                 logmsg(_("HHCPN204E Invalid syntax; enter 'HELP AUTOMOUNT' for help.\n"));
1510                 return -1;
1511             }
1512         }
1513         else
1514         {
1515             argv2 = argv[2];
1516 
1517             if (argc != 3 )
1518             {
1519                 logmsg(_("HHCPN204E Invalid syntax; enter 'HELP AUTOMOUNT' for help.\n"));
1520                 return -1;
1521             }
1522         }
1523 
1524 
1525         // Add the requested entry...
1526 
1527         strlcpy (tamdir, argv2, sizeof(tamdir));
1528         rc = add_tamdir( tamdir, &pTAMDIR );
1529 
1530         // Did that work?
1531 
1532         switch (rc)
1533         {
1534             default:     /* (oops!) */
1535             {
1536                 logmsg( _("HHCPN205E **LOGIC ERROR** file \"%s\", line %d\n"),
1537                     __FILE__, __LINE__);
1538                 return -1;
1539             }
1540 
1541             case 5:     /* ("out of memory") */
1542             {
1543                 logmsg( _("HHCPN206E Out of memory!\n"));
1544                 return -1;
1545             }
1546 
1547             case 1:     /* ("unresolvable path") */
1548             case 2:     /* ("path inaccessible") */
1549             {
1550                 logmsg( _("HHCPN207E Invalid AUTOMOUNT directory: \"%s\": %s\n"),
1551                        tamdir, strerror(errno));
1552                 return -1;
1553             }
1554 
1555             case 3:     /* ("conflict w/previous") */
1556             {
1557                 logmsg( _("HHCPN208E AUTOMOUNT directory \"%s\""
1558                     " conflicts with previous specification\n"),
1559                     tamdir);
1560                 return -1;
1561             }
1562 
1563             case 4:     /* ("duplicates previous") */
1564             {
1565                 logmsg( _("HHCPN209E AUTOMOUNT directory \"%s\""
1566                     " duplicates previous specification\n"),
1567                     tamdir);
1568                 return -1;
1569             }
1570 
1571             case 0:     /* ("success") */
1572             {
1573                 logmsg(_("HHCPN210I %s%s AUTOMOUNT directory = \"%s\"\n"),
1574                     pTAMDIR->dir == sysblk.defdir ? "Default " : "",
1575                     pTAMDIR->rej ? "Disallowed" : "Allowed",
1576                     pTAMDIR->dir);
1577 
1578                 /* Define default AUTOMOUNT directory if needed */
1579 
1580                 if (sysblk.defdir == NULL)
1581                 {
1582                     static char cwd[ MAX_PATH ];
1583 
1584                     VERIFY( getcwd( cwd, sizeof(cwd) ) != NULL );
1585                     rc = strlen( cwd );
1586                     if (cwd[rc-1] != *PATH_SEP)
1587                         strlcat (cwd, PATH_SEP, sizeof(cwd));
1588 
1589                     if (!(pTAMDIR = malloc( sizeof(TAMDIR) )))
1590                     {
1591                         logmsg( _("HHCPN211E Out of memory!\n"));
1592                         sysblk.defdir = cwd; /* EMERGENCY! */
1593                     }
1594                     else
1595                     {
1596                         pTAMDIR->dir = strdup (cwd);
1597                         pTAMDIR->len = strlen (cwd);
1598                         pTAMDIR->rej = 0;
1599                         pTAMDIR->next = sysblk.tamdir;
1600                         sysblk.tamdir = pTAMDIR;
1601                         sysblk.defdir = pTAMDIR->dir;
1602                     }
1603 
1604                     logmsg(_("HHCPN212I Default Allowed AUTOMOUNT directory = \"%s\"\n"),
1605                         sysblk.defdir);
1606                 }
1607 
1608                 return 0;
1609             }
1610         }
1611     }
1612 
1613     if (strcasecmp(argv[1],"del") == 0 || *argv[1] == '-')
1614     {
1615         char *argv2;
1616         char tamdir1[MAX_PATH+1] = {0};     // (resolved path)
1617         char tamdir2[MAX_PATH+1] = {0};     // (expanded but unresolved path)
1618         char workdir[MAX_PATH+1] = {0};     // (work)
1619         char *tamdir = tamdir1;             // (-> tamdir2 on retry)
1620 
1621         TAMDIR* pPrevTAMDIR = NULL;
1622         TAMDIR* pCurrTAMDIR = sysblk.tamdir;
1623 
1624 //      int was_empty = (sysblk.tamdir == NULL);
1625 
1626         if(*argv[1] == '-')
1627         {
1628             argv2 = argv[1] + 1;
1629 
1630             if (argc != 2 )
1631             {
1632                 logmsg(_("HHCPN213E Invalid syntax; enter 'HELP AUTOMOUNT' for help.\n"));
1633                 return -1;
1634             }
1635         }
1636         else
1637         {
1638             argv2 = argv[2];
1639 
1640             if (argc != 3 )
1641             {
1642                 logmsg(_("HHCPN213E Invalid syntax; enter 'HELP AUTOMOUNT' for help.\n"));
1643                 return -1;
1644             }
1645         }
1646 
1647         // Convert argument to absolute path ending with a slash
1648 
1649         strlcpy( tamdir2, argv2, sizeof(tamdir2) );
1650         if      (tamdir2[0] == '-') memmove (&tamdir2[0], &tamdir2[1], MAX_PATH);
1651         else if (tamdir2[0] == '+') memmove (&tamdir2[0], &tamdir2[1], MAX_PATH);
1652 
1653 #if defined(_MSVC_)
1654         // (expand any embedded %var% environment variables)
1655         rc = expand_environ_vars( tamdir2, workdir, MAX_PATH );
1656         if (rc == 0)
1657             strlcpy (tamdir2, workdir, MAX_PATH);
1658 #endif // _MSVC_
1659 
1660         if (sysblk.defdir == NULL
1661 #if defined(_MSVC_)
1662             || tamdir2[1] == ':'    // (fullpath given?)
1663 #else // !_MSVC_
1664             || tamdir2[0] == '/'    // (fullpath given?)
1665 #endif // _MSVC_
1666             || tamdir2[0] == '.'    // (relative path given?)
1667         )
1668             tamdir1[0] = 0;         // (then use just given spec)
1669         else                        // (else prepend with default)
1670             strlcpy( tamdir1, sysblk.defdir, sizeof(tamdir1) );
1671 
1672         // (finish building path to be resolved)
1673         strlcat( tamdir1, tamdir2, sizeof(tamdir1) );
1674 
1675         // (try resolving it to an absolute path and
1676         //  append trailing path separator if needed)
1677 
1678         if (realpath(tamdir1, workdir) != NULL)
1679         {
1680             strlcpy (tamdir1, workdir, MAX_PATH);
1681             rc = strlen( tamdir1 );
1682             if (tamdir1[rc-1] != *PATH_SEP)
1683                 strlcat (tamdir1, PATH_SEP, MAX_PATH);
1684             tamdir = tamdir1;   // (try tamdir1 first)
1685         }
1686         else
1687             tamdir = tamdir2;   // (try only tamdir2)
1688 
1689         rc = strlen( tamdir2 );
1690         if (tamdir2[rc-1] != *PATH_SEP)
1691             strlcat (tamdir2, PATH_SEP, MAX_PATH);
1692 
1693         // Find entry to be deleted...
1694 
1695         for (;;)
1696         {
1697             for (pCurrTAMDIR = sysblk.tamdir, pPrevTAMDIR = NULL;
1698                 pCurrTAMDIR;
1699                 pPrevTAMDIR = pCurrTAMDIR, pCurrTAMDIR = pCurrTAMDIR->next)
1700             {
1701                 if (strfilenamecmp( pCurrTAMDIR->dir, tamdir ) == 0)
1702                 {
1703                     int def = (sysblk.defdir == pCurrTAMDIR->dir);
1704 
1705                     // Delete the found entry...
1706 
1707                     if (pPrevTAMDIR)
1708                         pPrevTAMDIR->next = pCurrTAMDIR->next;
1709                     else
1710                         sysblk.tamdir = pCurrTAMDIR->next;
1711 
1712                     free( pCurrTAMDIR->dir );
1713                     free( pCurrTAMDIR );
1714 
1715                     // (point back to list begin)
1716                     pCurrTAMDIR = sysblk.tamdir;
1717 
1718                     logmsg(_("HHCPN214I Ok.%s\n"),
1719                         pCurrTAMDIR ? "" : " (list now empty)");
1720 
1721                     // Default entry just deleted?
1722 
1723                     if (def)
1724                     {
1725                         if (!pCurrTAMDIR)
1726                             sysblk.defdir = NULL;  // (no default)
1727                         else
1728                         {
1729                             // Set new default entry...
1730 
1731                             for (; pCurrTAMDIR; pCurrTAMDIR = pCurrTAMDIR->next)
1732                             {
1733                                 if (pCurrTAMDIR->rej == 0)
1734                                 {
1735                                     sysblk.defdir = pCurrTAMDIR->dir;
1736                                     break;
1737                                 }
1738                             }
1739 
1740                             // If we couldn't find an existing allowable
1741                             // directory entry to use as the new default,
1742                             // then add the current directory and use it.
1743 
1744                             if (!pCurrTAMDIR)
1745                             {
1746                                 static char cwd[ MAX_PATH ] = {0};
1747 
1748                                 VERIFY( getcwd( cwd, sizeof(cwd) ) != NULL );
1749                                 rc = strlen( cwd );
1750                                 if (cwd[rc-1] != *PATH_SEP)
1751                                     strlcat (cwd, PATH_SEP, sizeof(cwd));
1752 
1753                                 if (!(pCurrTAMDIR = malloc( sizeof(TAMDIR) )))
1754                                 {
1755                                     logmsg( _("HHCPN215E Out of memory!\n"));
1756                                     sysblk.defdir = cwd; /* EMERGENCY! */
1757                                 }
1758                                 else
1759                                 {
1760                                     pCurrTAMDIR->dir = strdup (cwd);
1761                                     pCurrTAMDIR->len = strlen (cwd);
1762                                     pCurrTAMDIR->rej = 0;
1763                                     pCurrTAMDIR->next = sysblk.tamdir;
1764                                     sysblk.tamdir = pCurrTAMDIR;
1765                                     sysblk.defdir = pCurrTAMDIR->dir;
1766                                 }
1767                             }
1768 
1769                             logmsg(_("HHCPN216I Default Allowed AUTOMOUNT directory = \"%s\"\n"),
1770                                 sysblk.defdir);
1771                         }
1772                     }
1773 
1774                     return 0;   // (success)
1775                 }
1776             }
1777 
1778             // (not found; try tamdir2 if we haven't yet)
1779 
1780             if (tamdir == tamdir2) break;
1781             tamdir = tamdir2;
1782         }
1783 
1784         if (sysblk.tamdir == NULL)
1785             logmsg(_("HHCPN217E Empty list.\n"));
1786         else
1787             logmsg(_("HHCPN218E Entry not found.\n"));
1788         return -1;
1789     }
1790 
1791     logmsg(_("HHCPN219E Unsupported function; enter 'HELP AUTOMOUNT' for syntax.\n"));
1792     return 0;
1793 }
1794 
1795 #endif /* OPTION_TAPE_AUTOMOUNT */
1796 
1797 #if defined( OPTION_SCSI_TAPE )
1798 
1799 
1800 // (helper function for 'scsimount' and 'devlist' commands)
1801 
try_scsi_refresh(DEVBLK * dev)1802 static void try_scsi_refresh( DEVBLK* dev )
1803 {
1804     // PROGRAMMING NOTE: we can only ever cause the auto-scsi-mount
1805     // thread to startup or shutdown [according to the current user
1806     // setting] if the current drive status is "not mounted".
1807 
1808     // What we unfortunately CANNOT do (indeed MUST NOT do!) however
1809     // is actually "force" a refresh of a current [presumably bogus]
1810     // "mounted" status (to presumably detect that a tape that was
1811     // once mounted has now been manually unmounted for example).
1812 
1813     // The reasons for why this is not possible is clearly explained
1814     // in the 'update_status_scsitape' function in 'scsitape.c'.
1815 
1816     // If the user manually unloaded a mounted tape (such that there
1817     // is now no longer a tape mounted even though the drive status
1818     // says there is), then they unfortunately have no choice but to
1819     // manually issue the 'devinit' command themselves, because, as
1820     // explained, we unfortunately cannot refresh a mounted status
1821     // for them (due to the inherent danger of doing so as explained
1822     // by comments in 'update_status_scsitape' in member scsitape.c).
1823 
1824     GENTMH_PARMS  gen_parms;
1825 
1826     gen_parms.action  = GENTMH_SCSI_ACTION_UPDATE_STATUS;
1827     gen_parms.dev     = dev;
1828 
1829     VERIFY( dev->tmh->generic( &gen_parms ) == 0 ); // (maybe update status)
1830     usleep(10*1000);                                // (let thread start/end)
1831 }
1832 
1833 
1834 /*-------------------------------------------------------------------*/
1835 /* scsimount command - display or adjust the SCSI auto-mount option  */
1836 /*-------------------------------------------------------------------*/
scsimount_cmd(int argc,char * argv[],char * cmdline)1837 int scsimount_cmd(int argc, char *argv[], char *cmdline)
1838 {
1839     char*  eyecatcher =
1840 "*************************************************************************************************";
1841     DEVBLK*  dev;
1842     int      tapeloaded;
1843     char*    tapemsg="";
1844     char     volname[7];
1845     BYTE     mountreq, unmountreq;
1846     char*    label_type;
1847     // Unused..
1848     // int      old_auto_scsi_mount_secs = sysblk.auto_scsi_mount_secs;
1849     UNREFERENCED(cmdline);
1850 
1851     if (argc > 1)
1852     {
1853         if ( strcasecmp( argv[1], "no" ) == 0 )
1854         {
1855             sysblk.auto_scsi_mount_secs = 0;
1856         }
1857         else if ( strcasecmp( argv[1], "yes" ) == 0 )
1858         {
1859             sysblk.auto_scsi_mount_secs = DEFAULT_AUTO_SCSI_MOUNT_SECS;
1860         }
1861         else
1862         {
1863             int auto_scsi_mount_secs; BYTE c;
1864             if ( sscanf( argv[1], "%d%c", &auto_scsi_mount_secs, &c ) != 1
1865                 || auto_scsi_mount_secs < 0 || auto_scsi_mount_secs > 99 )
1866             {
1867                 logmsg
1868                 (
1869                     _( "HHCCF068E Invalid value: %s; Enter \"help scsimount\" for help.\n" )
1870 
1871                     ,argv[1]
1872                 );
1873                 return 0;
1874             }
1875             sysblk.auto_scsi_mount_secs = auto_scsi_mount_secs;
1876         }
1877     }
1878 
1879     if ( sysblk.auto_scsi_mount_secs )
1880         logmsg( _("SCSI auto-mount queries = every %d seconds (when needed)\n"),
1881             sysblk.auto_scsi_mount_secs );
1882     else
1883         logmsg( _("SCSI auto-mount queries are disabled.\n") );
1884 
1885     // Scan the device list looking for all SCSI tape devices
1886     // with either an active scsi mount thread and/or an out-
1887     // standing tape mount request...
1888 
1889     for ( dev = sysblk.firstdev; dev; dev = dev->nextdev )
1890     {
1891         if ( !dev->allocated || TAPEDEVT_SCSITAPE != dev->tapedevt )
1892             continue;  // (not an active SCSI tape device; skip)
1893 
1894         try_scsi_refresh( dev );    // (see comments in function)
1895 
1896         logmsg
1897         (
1898             _("thread %s active for drive %u:%4.4X = %s.\n")
1899             ,dev->stape_mntdrq.link.Flink ? "IS" : "is NOT"
1900             ,SSID_TO_LCSS(dev->ssid)
1901             ,dev->devnum
1902             ,dev->filename
1903         );
1904 
1905         if (!dev->tdparms.displayfeat)
1906             continue;
1907 
1908         mountreq   = FALSE;     // (default)
1909         unmountreq = FALSE;     // (default)
1910 
1911         if (0
1912             || TAPEDISPTYP_MOUNT       == dev->tapedisptype
1913             || TAPEDISPTYP_UNMOUNT     == dev->tapedisptype
1914             || TAPEDISPTYP_UMOUNTMOUNT == dev->tapedisptype
1915         )
1916         {
1917             tapeloaded = dev->tmh->tapeloaded( dev, NULL, 0 );
1918 
1919             if ( TAPEDISPTYP_MOUNT == dev->tapedisptype && !tapeloaded )
1920             {
1921                 mountreq   = TRUE;
1922                 unmountreq = FALSE;
1923                 tapemsg = dev->tapemsg1;
1924             }
1925             else if ( TAPEDISPTYP_UNMOUNT == dev->tapedisptype && tapeloaded )
1926             {
1927                 unmountreq = TRUE;
1928                 mountreq   = FALSE;
1929                 tapemsg = dev->tapemsg1;
1930             }
1931             else // ( TAPEDISPTYP_UMOUNTMOUNT == dev->tapedisptype )
1932             {
1933                 if (tapeloaded)
1934                 {
1935                     if ( !(dev->tapedispflags & TAPEDISPFLG_MESSAGE2) )
1936                     {
1937                         unmountreq = TRUE;
1938                         mountreq   = FALSE;
1939                         tapemsg = dev->tapemsg1;
1940                     }
1941                 }
1942                 else // (!tapeloaded)
1943                 {
1944                     mountreq   = TRUE;
1945                     unmountreq = FALSE;
1946                     tapemsg = dev->tapemsg2;
1947                 }
1948             }
1949         }
1950 
1951         if ((mountreq || unmountreq) && ' ' != *tapemsg)
1952         {
1953             switch (*(tapemsg+7))
1954             {
1955                 case 'A': label_type = "ascii-standard"; break;
1956                 case 'S': label_type = "standard"; break;
1957                 case 'N': label_type = "non"; break;
1958                 case 'U': label_type = "un"; break;
1959                 default : label_type = "??"; break;
1960             }
1961 
1962             volname[0]=0;
1963 
1964             if (*(tapemsg+1))
1965             {
1966                 strncpy( volname, tapemsg+1, 6 );
1967                 volname[6]=0;
1968             }
1969 
1970             logmsg
1971             (
1972                 _("\n%s\nHHCCF069I %s of %s-labeled volume \"%s\" pending for drive %u:%4.4X = %s\n%s\n\n")
1973 
1974                 ,eyecatcher
1975                 ,mountreq ? "Mount" : "Dismount"
1976                 ,label_type
1977                 ,volname
1978                 ,SSID_TO_LCSS(dev->ssid)
1979                 ,dev->devnum
1980                 ,dev->filename
1981                 ,eyecatcher
1982             );
1983         }
1984         else
1985         {
1986             logmsg( _("No mount/dismount requests pending for drive %u:%4.4X = %s.\n"),
1987                 SSID_TO_LCSS(dev->ssid),dev->devnum, dev->filename );
1988         }
1989     }
1990 
1991     return 0;
1992 }
1993 #endif /* defined( OPTION_SCSI_TAPE ) */
1994 
1995 
1996 /*-------------------------------------------------------------------*/
1997 /* cckd command                                                      */
1998 /*-------------------------------------------------------------------*/
cckd_cmd(int argc,char * argv[],char * cmdline)1999 int cckd_cmd(int argc, char *argv[], char *cmdline)
2000 {
2001     char* p = strtok(cmdline+4," \t");
2002 
2003     UNREFERENCED(argc);
2004     UNREFERENCED(argv);
2005 
2006     return cckd_command(p,1);
2007 }
2008 
2009 
2010 /*-------------------------------------------------------------------*/
2011 /* ctc command - enable/disable CTC debugging                        */
2012 /*-------------------------------------------------------------------*/
ctc_cmd(int argc,char * argv[],char * cmdline)2013 int ctc_cmd( int argc, char *argv[], char *cmdline )
2014 {
2015     DEVBLK*  dev;
2016     CTCBLK*  pCTCBLK;
2017     LCSDEV*  pLCSDEV;
2018     LCSBLK*  pLCSBLK;
2019     U16      lcss;
2020     U16      devnum;
2021     BYTE     onoff;
2022 
2023     UNREFERENCED( cmdline );
2024 
2025     // Format:  "ctc  debug  { on | off }  [ <devnum> | ALL ]"
2026 
2027     if (0
2028         || argc < 3
2029         ||  strcasecmp( argv[1], "debug" ) != 0
2030         || (1
2031             && strcasecmp( argv[2], "on"  ) != 0
2032             && strcasecmp( argv[2], "off" ) != 0
2033            )
2034         || argc > 4
2035         || (1
2036             && argc == 4
2037             && strcasecmp( argv[3], "ALL" ) != 0
2038             && parse_single_devnum( argv[3], &lcss, &devnum) < 0
2039            )
2040     )
2041     {
2042         panel_command ("help ctc");
2043         return -1;
2044     }
2045 
2046     onoff = (strcasecmp( argv[2], "on" ) == 0);
2047 
2048     if (argc < 4 || strcasecmp( argv[3], "ALL" ) == 0)
2049     {
2050         for ( dev = sysblk.firstdev; dev; dev = dev->nextdev )
2051         {
2052             if (0
2053                 || !dev->allocated
2054                 || 0x3088 != dev->devtype
2055                 || (CTC_CTCI != dev->ctctype && CTC_LCS != dev->ctctype)
2056             )
2057                 continue;
2058 
2059             if (CTC_CTCI == dev->ctctype)
2060             {
2061                 pCTCBLK = dev->dev_data;
2062                 pCTCBLK->fDebug = onoff;
2063             }
2064             else // (CTC_LCS == dev->ctctype)
2065             {
2066                 pLCSDEV = dev->dev_data;
2067                 pLCSBLK = pLCSDEV->pLCSBLK;
2068                 pLCSBLK->fDebug = onoff;
2069             }
2070         }
2071 
2072         logmsg( _("HHCPNXXXI CTC debugging now %s for all CTCI/LCS device groups.\n"),
2073                   onoff ? _("ON") : _("OFF") );
2074     }
2075     else
2076     {
2077         int i;
2078         DEVGRP* pDEVGRP;
2079         DEVBLK* pDEVBLK;
2080 
2081         if (!(dev = find_device_by_devnum ( lcss, devnum )))
2082         {
2083             devnotfound_msg( lcss, devnum );
2084             return -1;
2085         }
2086 
2087         pDEVGRP = dev->group;
2088 
2089         if (CTC_CTCI == dev->ctctype)
2090         {
2091             for (i=0; i < pDEVGRP->acount; i++)
2092             {
2093                 pDEVBLK = pDEVGRP->memdev[i];
2094                 pCTCBLK = pDEVBLK->dev_data;
2095                 pCTCBLK->fDebug = onoff;
2096             }
2097         }
2098         else if (CTC_LCS == dev->ctctype)
2099         {
2100             for (i=0; i < pDEVGRP->acount; i++)
2101             {
2102                 pDEVBLK = pDEVGRP->memdev[i];
2103                 pLCSDEV = pDEVBLK->dev_data;
2104                 pLCSBLK = pLCSDEV->pLCSBLK;
2105                 pLCSBLK->fDebug = onoff;
2106             }
2107         }
2108         else
2109         {
2110             logmsg( _("HHCPN034E Device %d:%4.4X is not a CTCI or LCS device\n"),
2111                       lcss, devnum );
2112             return -1;
2113         }
2114 
2115         logmsg( _("HHCPNXXXI CTC debugging now %s for %s device %d:%4.4X group.\n"),
2116                   onoff ? _("ON") : _("OFF"),
2117                   CTC_LCS == dev->ctctype ? "LCS" : "CTCI",
2118                   lcss, devnum );
2119     }
2120 
2121     return 0;
2122 }
2123 
2124 
2125 #if defined(OPTION_W32_CTCI)
2126 /*-------------------------------------------------------------------*/
2127 /* tt32 command - control/query CTCI-W32 functionality               */
2128 /*-------------------------------------------------------------------*/
tt32_cmd(int argc,char * argv[],char * cmdline)2129 int tt32_cmd( int argc, char *argv[], char *cmdline )
2130 {
2131     int      rc = 0;
2132     U16      devnum;
2133     U16      lcss;
2134     DEVBLK*  dev;
2135 
2136     UNREFERENCED(cmdline);
2137 
2138     if (argc < 2)
2139     {
2140         logmsg( _("HHCPN188E Missing arguments; enter 'help tt32' for help.\n") );
2141         rc = -1;
2142     }
2143     else if (strcasecmp(argv[1],"stats") == 0)
2144     {
2145         if (argc < 3)
2146         {
2147             missing_devnum();
2148             return -1;
2149         }
2150 
2151         if ((rc = parse_single_devnum(argv[2], &lcss, &devnum)) < 0)
2152             return -1;
2153 
2154         if (!(dev = find_device_by_devnum (lcss, devnum)) &&
2155             !(dev = find_device_by_devnum (lcss, devnum ^ 0x01)))
2156         {
2157             devnotfound_msg(lcss,devnum);
2158             return -1;
2159         }
2160 
2161         if (CTC_CTCI != dev->ctctype && CTC_LCS != dev->ctctype)
2162         {
2163             logmsg( _("HHCPN034E Device %d:%4.4X is not a CTCI or LCS device\n"),
2164                       lcss, devnum );
2165             return -1;
2166         }
2167 
2168         if (debug_tt32_stats)
2169             rc = debug_tt32_stats (dev->fd);
2170         else
2171         {
2172             logmsg( _("(error)\n") );
2173             rc = -1;
2174         }
2175     }
2176     else if (strcasecmp(argv[1],"debug") == 0)
2177     {
2178         if (debug_tt32_tracing)
2179         {
2180             debug_tt32_tracing(1); // 1=ON
2181             rc = 0;
2182             logmsg( _("HHCPN189I TT32 debug tracing messages enabled\n") );
2183         }
2184         else
2185         {
2186             logmsg( _("(error)\n") );
2187             rc = -1;
2188         }
2189     }
2190     else if (strcasecmp(argv[1],"nodebug") == 0)
2191     {
2192         if (debug_tt32_tracing)
2193         {
2194             debug_tt32_tracing(0); // 0=OFF
2195             rc = 0;
2196             logmsg( _("HHCPN189I TT32 debug tracing messages disabled\n") );
2197         }
2198         else
2199         {
2200             logmsg( _("(error)\n") );
2201             rc = -1;
2202         }
2203     }
2204     else
2205     {
2206         logmsg( _("HHCPN187E Invalid argument\n") );
2207         rc = -1;
2208     }
2209 
2210     return rc;
2211 }
2212 #endif /* defined(OPTION_W32_CTCI) */
2213 
2214 
2215 /*-------------------------------------------------------------------*/
2216 /* store command - store CPU status at absolute zero                 */
2217 /*-------------------------------------------------------------------*/
store_cmd(int argc,char * argv[],char * cmdline)2218 int store_cmd(int argc, char *argv[], char *cmdline)
2219 {
2220 REGS *regs;
2221 
2222     UNREFERENCED(cmdline);
2223     UNREFERENCED(argc);
2224     UNREFERENCED(argv);
2225 
2226     obtain_lock(&sysblk.cpulock[sysblk.pcpu]);
2227 
2228     if (!IS_CPU_ONLINE(sysblk.pcpu))
2229     {
2230         release_lock(&sysblk.cpulock[sysblk.pcpu]);
2231         logmsg( _("HHCPN160W CPU%4.4X not configured\n"), sysblk.pcpu);
2232         return 0;
2233     }
2234     regs = sysblk.regs[sysblk.pcpu];
2235 
2236     /* Command is valid only when CPU is stopped */
2237     if (regs->cpustate != CPUSTATE_STOPPED)
2238     {
2239         logmsg( _("HHCPN035E store status rejected: CPU not stopped\n") );
2240         return -1;
2241     }
2242 
2243     /* Store status in 512 byte block at absolute location 0 */
2244     store_status (regs, 0);
2245 
2246     release_lock(&sysblk.cpulock[sysblk.pcpu]);
2247 
2248     logmsg (_("HHCCP010I CPU%4.4X store status completed.\n"),
2249             regs->cpuad);
2250 
2251     return 0;
2252 }
2253 
2254 
2255 /*-------------------------------------------------------------------*/
2256 /* sclproot command - set SCLP base directory                        */
2257 /*-------------------------------------------------------------------*/
sclproot_cmd(int argc,char * argv[],char * cmdline)2258 int sclproot_cmd(int argc, char *argv[], char *cmdline)
2259 {
2260 char *basedir;
2261 
2262     UNREFERENCED(cmdline);
2263 
2264     if (argc > 1)
2265         if (!strcasecmp(argv[1],"none"))
2266             set_sce_dir(NULL);
2267         else
2268             set_sce_dir(argv[1]);
2269     else
2270         if((basedir = get_sce_dir()))
2271             logmsg(_("SCLPROOT %s\n"),basedir);
2272         else
2273             logmsg(_("SCLP DISK I/O Disabled\n"));
2274 
2275     return 0;
2276 }
2277 
2278 
2279 #if defined(OPTION_HTTP_SERVER)
2280 /*-------------------------------------------------------------------*/
2281 /* httproot command - set HTTP server base directory                 */
2282 /*-------------------------------------------------------------------*/
httproot_cmd(int argc,char * argv[],char * cmdline)2283 int httproot_cmd(int argc, char *argv[], char *cmdline)
2284 {
2285     UNREFERENCED(cmdline);
2286 
2287     if (argc > 1)
2288     {
2289         if (sysblk.httproot)
2290             free(sysblk.httproot);
2291         sysblk.httproot = strdup(argv[1]);
2292     }
2293     else
2294         if(sysblk.httproot)
2295             logmsg(_("HHCnnxxxI HTTPROOT %s\n"),sysblk.httproot);
2296         else
2297             logmsg(_("HHCnnxxxI HTTPROOT not specified\n"));
2298 
2299     return 0;
2300 }
2301 
2302 
2303 /*-------------------------------------------------------------------*/
2304 /* httpport command - set HTTP server port                           */
2305 /*-------------------------------------------------------------------*/
httpport_cmd(int argc,char * argv[],char * cmdline)2306 int httpport_cmd(int argc, char *argv[], char *cmdline)
2307 {
2308 char c;
2309 
2310     UNREFERENCED(cmdline);
2311 
2312     if (argc > 1)
2313     {
2314         if (!strcasecmp(argv[1],"none"))
2315         {
2316             if(sysblk.httpport)
2317             {
2318                 sysblk.httpport = 0;
2319                 signal_thread(sysblk.httptid, SIGUSR2);
2320             }
2321         }
2322         else if(sysblk.httpport)
2323         {
2324             logmsg(_("HHCCF040S HTTP server already active\n"));
2325             return -1;
2326         }
2327         else
2328         {
2329             if (sscanf(argv[1], "%hu%c", &sysblk.httpport, &c) != 1
2330                 || sysblk.httpport == 0 || (sysblk.httpport < 1024 && sysblk.httpport != 80) )
2331             {
2332                 logmsg(_("HHCCF029S Invalid HTTP port number %s\n"), argv[1]);
2333                 return -1;
2334             }
2335             if (argc > 2)
2336             {
2337                 if (!strcasecmp(argv[2],"auth"))
2338                     sysblk.httpauth = 1;
2339                 else if (strcasecmp(argv[2],"noauth"))
2340                 {
2341                     logmsg(_("HHCCF005S Unrecognized argument %s\n"),argv[2]);
2342                     return -1;
2343                 }
2344             }
2345             if (argc > 3)
2346             {
2347                 if (sysblk.httpuser)
2348                     free(sysblk.httpuser);
2349                 sysblk.httpuser = strdup(argv[3]);
2350             }
2351             if (argc > 4)
2352             {
2353                 if (sysblk.httppass)
2354                     free(sysblk.httppass);
2355                 sysblk.httppass = strdup(argv[4]);
2356             }
2357 
2358             /* Start the http server connection thread */
2359             if ( create_thread (&sysblk.httptid, DETACHED,
2360                                 http_server, NULL, "http_server") )
2361             {
2362                 logmsg(_("HHCCF041S Cannot create http_server thread: %s\n"),
2363                         strerror(errno));
2364                 return -1;
2365             }
2366         }
2367     }
2368     else
2369         logmsg(_("HHCCF049I HTTPPORT %d\n"),sysblk.httpport);
2370     return 0;
2371 }
2372 
2373 
2374 #if defined( HTTP_SERVER_CONNECT_KLUDGE )
2375 /*-------------------------------------------------------------------*/
2376 /* http_server_kludge_msecs                                          */
2377 /*-------------------------------------------------------------------*/
httpskm_cmd(int argc,char * argv[],char * cmdline)2378 int httpskm_cmd(int argc, char *argv[], char *cmdline)
2379 {
2380 char c;
2381 
2382     UNREFERENCED(cmdline);
2383 
2384     if (argc > 1)
2385     {
2386     int http_server_kludge_msecs;
2387         if ( sscanf( argv[1], "%d%c", &http_server_kludge_msecs, &c ) != 1
2388             || http_server_kludge_msecs <= 0 || http_server_kludge_msecs > 50 )
2389         {
2390             logmsg(_("HHCCF066S Invalid HTTP_SERVER_CONNECT_KLUDGE value: %s\n" ),argv[1]);
2391             return -1;
2392         }
2393         sysblk.http_server_kludge_msecs = http_server_kludge_msecs;
2394     }
2395     else
2396         logmsg(_("HHCCF042S HTTP_SERVER_CONNECT_KLUDGE value: %s\n" )
2397                 ,sysblk.http_server_kludge_msecs);
2398     return 0;
2399 }
2400 #endif // defined( HTTP_SERVER_CONNECT_KLUDGE )
2401 #endif /*defined(OPTION_HTTP_SERVER)*/
2402 
2403 #if defined(_FEATURE_ASN_AND_LX_REUSE)
2404 /*-------------------------------------------------------------------*/
2405 /* alrf command - display or set asn_and_lx_reuse                    */
2406 /*-------------------------------------------------------------------*/
alrf_cmd(int argc,char * argv[],char * cmdline)2407 int alrf_cmd(int argc, char *argv[], char *cmdline)
2408 {
2409     UNREFERENCED(cmdline);
2410 
2411     if (argc > 1)
2412     {
2413         if(strcasecmp(argv[1],"enable")==0)
2414             sysblk.asnandlxreuse=1;
2415         else
2416         {
2417             if(strcasecmp(argv[1],"disable")==0)
2418                 sysblk.asnandlxreuse=0;
2419             else {
2420                 logmsg(_("HHCCF067S Incorrect keyword %s for the ASN_AND_LX_REUSE statement.\n"),
2421                             argv[1]);
2422                 return -1;
2423                 }
2424         }
2425     }
2426     else
2427         logmsg(_("HHCCF0028I ASN and LX reuse is %s\n"),sysblk.asnandlxreuse ? "Enabled" : "Disabled");
2428 
2429     return 0;
2430 }
2431 #endif /*defined(_FEATURE_ASN_AND_LX_REUSE)*/
2432 
2433 
2434 /*-------------------------------------------------------------------*/
2435 /* toddrag command - display or set TOD clock drag factor            */
2436 /*-------------------------------------------------------------------*/
toddrag_cmd(int argc,char * argv[],char * cmdline)2437 int toddrag_cmd(int argc, char *argv[], char *cmdline)
2438 {
2439     UNREFERENCED(cmdline);
2440 
2441     if (argc > 1)
2442     {
2443         double toddrag = -1.0;
2444 
2445         sscanf(argv[1], "%lf", &toddrag);
2446 
2447         if (toddrag >= 0.0001 && toddrag <= 10000.0)
2448         {
2449             /* Set clock steering based on drag factor */
2450             set_tod_steering(-(1.0-(1.0/toddrag)));
2451         }
2452     }
2453     else
2454         logmsg( _("HHCPN036I TOD clock drag factor = %lf\n"), (1.0/(1.0+get_tod_steering())));
2455 
2456     return 0;
2457 }
2458 
2459 
2460 #ifdef PANEL_REFRESH_RATE
2461 
2462 
2463 /*-------------------------------------------------------------------*/
2464 /* panrate command - display or set rate at which console refreshes  */
2465 /*-------------------------------------------------------------------*/
panrate_cmd(int argc,char * argv[],char * cmdline)2466 int panrate_cmd(int argc, char *argv[], char *cmdline)
2467 {
2468     UNREFERENCED(cmdline);
2469 
2470     if (argc > 1)
2471     {
2472         if (!strcasecmp(argv[1],"fast"))
2473             sysblk.panrate = PANEL_REFRESH_RATE_FAST;
2474         else if (!strcasecmp(argv[1],"slow"))
2475             sysblk.panrate = PANEL_REFRESH_RATE_SLOW;
2476         else
2477         {
2478             int trate = 0;
2479 
2480             sscanf(argv[1],"%d", &trate);
2481 
2482             if (trate >= (1000 / CLK_TCK) && trate < 5001)
2483                 sysblk.panrate = trate;
2484         }
2485     }
2486     else
2487         logmsg( _("HHCPN037I Panel refresh rate = %d millisecond(s)\n"),
2488               sysblk.panrate );
2489 
2490     return 0;
2491 }
2492 
2493 #endif /*PANEL_REFRESH_RATE */
2494 
2495 
2496 /*-------------------------------------------------------------------*/
2497 /* pantitle xxxxxxxx command - set console title                     */
2498 /*-------------------------------------------------------------------*/
pantitle_cmd(int argc,char * argv[],char * cmdline)2499 int pantitle_cmd(int argc, char *argv[], char *cmdline)
2500 {
2501 
2502     UNREFERENCED(cmdline);
2503 
2504     /* Update pantitle if operand is specified */
2505     if (argc > 1)
2506     {
2507         if (sysblk.pantitle)
2508             free(sysblk.pantitle);
2509         sysblk.pantitle = strdup(argv[1]);
2510     }
2511     else
2512         logmsg( _("HHCCF100I pantitle = %s\n"),sysblk.pantitle);
2513 
2514     return 0;
2515 }
2516 
2517 
2518 #ifdef OPTION_MSGHLD
2519 /*-------------------------------------------------------------------*/
2520 /* msghld command - display or set rate at which console refreshes   */
2521 /*-------------------------------------------------------------------*/
msghld_cmd(int argc,char * argv[],char * cmdline)2522 int msghld_cmd(int argc, char *argv[], char *cmdline)
2523 {
2524   UNREFERENCED(cmdline);
2525   if(argc == 2)
2526   {
2527     if(!strcasecmp(argv[1], "info"))
2528     {
2529       logmsg("HHCCF101I Current message held time is %d seconds.\n", sysblk.keep_timeout_secs);
2530       return(0);
2531     }
2532     else if(!strcasecmp(argv[1], "clear"))
2533     {
2534       expire_kept_msgs(1);
2535       logmsg("HHCCF102I Held messages cleared.\n");
2536       return(0);
2537     }
2538     else
2539     {
2540       int new_timeout;
2541 
2542       if(sscanf(argv[1], "%d", &new_timeout) && new_timeout >= 0)
2543       {
2544         sysblk.keep_timeout_secs = new_timeout;
2545         logmsg("HHCCF103I The message held time is set to %d seconds.\n", sysblk.keep_timeout_secs);
2546         return(0);
2547       }
2548     }
2549   }
2550   logmsg("msghld: Invalid usage\n");
2551   return(0);
2552 }
2553 #endif // OPTION_MSGHLD
2554 
2555 
2556 /*-------------------------------------------------------------------*/
2557 /* shell command                                                     */
2558 /*-------------------------------------------------------------------*/
sh_cmd(int argc,char * argv[],char * cmdline)2559 int sh_cmd(int argc, char *argv[], char *cmdline)
2560 {
2561     char* cmd;
2562     UNREFERENCED(argc);
2563     UNREFERENCED(argv);
2564     if (sysblk.shcmdopt & SHCMDOPT_DISABLE)
2565     {
2566         logmsg( _("HHCPN180E shell commands are disabled\n"));
2567         return -1;
2568     }
2569     cmd = cmdline + 2;
2570     while (isspace(*cmd)) cmd++;
2571     if (*cmd)
2572         return herc_system (cmd);
2573 
2574     return -1;
2575 }
2576 
2577 
2578 /*-------------------------------------------------------------------*/
2579 /* change directory command                                          */
2580 /*-------------------------------------------------------------------*/
cd_cmd(int argc,char * argv[],char * cmdline)2581 int cd_cmd(int argc, char *argv[], char *cmdline)
2582 {
2583     char* path;
2584     char cwd [ MAX_PATH ];
2585     UNREFERENCED(argc);
2586     UNREFERENCED(argv);
2587     if (sysblk.shcmdopt & SHCMDOPT_DISABLE)
2588     {
2589         logmsg( _("HHCPN180E shell commands are disabled\n"));
2590         return -1;
2591     }
2592     path = cmdline + 2;
2593     while (isspace(*path)) path++;
2594     chdir(path);
2595     getcwd( cwd, sizeof(cwd) );
2596     logmsg("%s\n",cwd);
2597     HDC1( debug_cd_cmd, cwd );
2598     return 0;
2599 }
2600 
2601 
2602 /*-------------------------------------------------------------------*/
2603 /* print working directory command                                   */
2604 /*-------------------------------------------------------------------*/
pwd_cmd(int argc,char * argv[],char * cmdline)2605 int pwd_cmd(int argc, char *argv[], char *cmdline)
2606 {
2607     char cwd [ MAX_PATH ];
2608     UNREFERENCED(argv);
2609     UNREFERENCED(cmdline);
2610     if (sysblk.shcmdopt & SHCMDOPT_DISABLE)
2611     {
2612         logmsg( _("HHCPN180E shell commands are disabled\n"));
2613         return -1;
2614     }
2615     if (argc > 1)
2616     {
2617         logmsg( _("HHCPN163E Invalid format. Command does not support any arguments.\n"));
2618         return -1;
2619     }
2620     getcwd( cwd, sizeof(cwd) );
2621     logmsg("%s\n",cwd);
2622     return 0;
2623 }
2624 
2625 
2626 /*-------------------------------------------------------------------*/
2627 /* gpr command - display or alter general purpose registers          */
2628 /*-------------------------------------------------------------------*/
gpr_cmd(int argc,char * argv[],char * cmdline)2629 int gpr_cmd(int argc, char *argv[], char *cmdline)
2630 {
2631 REGS *regs;
2632 
2633     UNREFERENCED(cmdline);
2634 
2635     obtain_lock(&sysblk.cpulock[sysblk.pcpu]);
2636 
2637     if (!IS_CPU_ONLINE(sysblk.pcpu))
2638     {
2639         release_lock(&sysblk.cpulock[sysblk.pcpu]);
2640         logmsg( _("HHCPN160W CPU%4.4X not configured\n"), sysblk.pcpu);
2641         return 0;
2642     }
2643 
2644     regs = sysblk.regs[sysblk.pcpu];
2645 
2646     if (argc > 1)
2647     {
2648         int   reg_num;
2649         BYTE  equal_sign, c;
2650         U64   reg_value;
2651 
2652         if (argc > 2)
2653         {
2654             release_lock(&sysblk.cpulock[sysblk.pcpu]);
2655             logmsg( _("HHCPN162E Invalid format. Enter \"help gpr\" for help.\n"));
2656             return 0;
2657         }
2658 
2659         if (0
2660             || sscanf( argv[1], "%d%c%"I64_FMT"x%c", &reg_num, &equal_sign, &reg_value, &c ) != 3
2661             || 0  > reg_num
2662             || 15 < reg_num
2663             || '=' != equal_sign
2664         )
2665         {
2666             release_lock(&sysblk.cpulock[sysblk.pcpu]);
2667             logmsg( _("HHCPN162E Invalid format. .Enter \"help gpr\" for help.\n"));
2668             return 0;
2669         }
2670 
2671         if ( ARCH_900 == regs->arch_mode )
2672             regs->GR_G(reg_num) = (U64) reg_value;
2673         else
2674             regs->GR_L(reg_num) = (U32) reg_value;
2675     }
2676 
2677     display_regs (regs);
2678 
2679     release_lock(&sysblk.cpulock[sysblk.pcpu]);
2680 
2681     return 0;
2682 }
2683 
2684 
2685 /*-------------------------------------------------------------------*/
2686 /* fpr command - display floating point registers                    */
2687 /*-------------------------------------------------------------------*/
fpr_cmd(int argc,char * argv[],char * cmdline)2688 int fpr_cmd(int argc, char *argv[], char *cmdline)
2689 {
2690 REGS *regs;
2691 
2692     UNREFERENCED(cmdline);
2693     UNREFERENCED(argc);
2694     UNREFERENCED(argv);
2695 
2696     obtain_lock(&sysblk.cpulock[sysblk.pcpu]);
2697 
2698     if (!IS_CPU_ONLINE(sysblk.pcpu))
2699     {
2700         release_lock(&sysblk.cpulock[sysblk.pcpu]);
2701         logmsg( _("HHCPN160W CPU%4.4X not configured\n"), sysblk.pcpu);
2702         return 0;
2703     }
2704     regs = sysblk.regs[sysblk.pcpu];
2705 
2706     display_fregs (regs);
2707 
2708     release_lock(&sysblk.cpulock[sysblk.pcpu]);
2709 
2710     return 0;
2711 }
2712 
2713 
2714 /*-------------------------------------------------------------------*/
2715 /* fpc command - display floating point control register             */
2716 /*-------------------------------------------------------------------*/
fpc_cmd(int argc,char * argv[],char * cmdline)2717 int fpc_cmd(int argc, char *argv[], char *cmdline)
2718 {
2719 REGS *regs;
2720 
2721     UNREFERENCED(cmdline);
2722     UNREFERENCED(argc);
2723     UNREFERENCED(argv);
2724 
2725     obtain_lock(&sysblk.cpulock[sysblk.pcpu]);
2726 
2727     if (!IS_CPU_ONLINE(sysblk.pcpu))
2728     {
2729         release_lock(&sysblk.cpulock[sysblk.pcpu]);
2730         logmsg( _("HHCPN160W CPU%4.4X not configured\n"), sysblk.pcpu);
2731         return 0;
2732     }
2733     regs = sysblk.regs[sysblk.pcpu];
2734 
2735     logmsg( "FPC=%8.8"I32_FMT"X\n", regs->fpc );
2736 
2737     release_lock(&sysblk.cpulock[sysblk.pcpu]);
2738 
2739     return 0;
2740 }
2741 
2742 
2743 /*-------------------------------------------------------------------*/
2744 /* cr command - display or alter control registers                   */
2745 /*-------------------------------------------------------------------*/
cr_cmd(int argc,char * argv[],char * cmdline)2746 int cr_cmd(int argc, char *argv[], char *cmdline)
2747 {
2748 REGS *regs;
2749 int   cr_num;
2750 BYTE  equal_sign, c;
2751 U64   cr_value;
2752 
2753     UNREFERENCED(cmdline);
2754 
2755     obtain_lock(&sysblk.cpulock[sysblk.pcpu]);
2756 
2757     if (!IS_CPU_ONLINE(sysblk.pcpu))
2758     {
2759         release_lock(&sysblk.cpulock[sysblk.pcpu]);
2760         logmsg( _("HHCPN160W CPU%4.4X not configured\n"), sysblk.pcpu);
2761         return 0;
2762     }
2763     regs = sysblk.regs[sysblk.pcpu];
2764 
2765     if (argc > 1)
2766     {
2767         if (argc > 2
2768             || sscanf( argv[1], "%d%c%"I64_FMT"x%c", &cr_num, &equal_sign, &cr_value, &c ) != 3
2769             || '=' != equal_sign || cr_num < 0 || cr_num > 15)
2770         {
2771             release_lock(&sysblk.cpulock[sysblk.pcpu]);
2772             logmsg( _("HHCPN164E Invalid format. .Enter \"help cr\" for help.\n"));
2773             return 0;
2774         }
2775         if ( ARCH_900 == regs->arch_mode )
2776             regs->CR_G(cr_num) = (U64)cr_value;
2777         else
2778             regs->CR_G(cr_num) = (U32)cr_value;
2779     }
2780 
2781     display_cregs (regs);
2782 
2783     release_lock(&sysblk.cpulock[sysblk.pcpu]);
2784 
2785     return 0;
2786 }
2787 
2788 
2789 /*-------------------------------------------------------------------*/
2790 /* ar command - display access registers                             */
2791 /*-------------------------------------------------------------------*/
ar_cmd(int argc,char * argv[],char * cmdline)2792 int ar_cmd(int argc, char *argv[], char *cmdline)
2793 {
2794 REGS *regs;
2795 
2796     UNREFERENCED(cmdline);
2797     UNREFERENCED(argc);
2798     UNREFERENCED(argv);
2799 
2800     obtain_lock(&sysblk.cpulock[sysblk.pcpu]);
2801 
2802     if (!IS_CPU_ONLINE(sysblk.pcpu))
2803     {
2804         release_lock(&sysblk.cpulock[sysblk.pcpu]);
2805         logmsg( _("HHCPN160W CPU%4.4X not configured\n"), sysblk.pcpu);
2806         return 0;
2807     }
2808     regs = sysblk.regs[sysblk.pcpu];
2809 
2810     display_aregs (regs);
2811 
2812     release_lock(&sysblk.cpulock[sysblk.pcpu]);
2813 
2814     return 0;
2815 }
2816 
2817 
2818 /*-------------------------------------------------------------------*/
2819 /* pr command - display prefix register                              */
2820 /*-------------------------------------------------------------------*/
pr_cmd(int argc,char * argv[],char * cmdline)2821 int pr_cmd(int argc, char *argv[], char *cmdline)
2822 {
2823 REGS *regs;
2824 
2825     UNREFERENCED(cmdline);
2826     UNREFERENCED(argc);
2827     UNREFERENCED(argv);
2828 
2829     obtain_lock(&sysblk.cpulock[sysblk.pcpu]);
2830 
2831     if (!IS_CPU_ONLINE(sysblk.pcpu))
2832     {
2833         release_lock(&sysblk.cpulock[sysblk.pcpu]);
2834         logmsg( _("HHCPN160W CPU%4.4X not configured\n"), sysblk.pcpu);
2835         return 0;
2836     }
2837     regs = sysblk.regs[sysblk.pcpu];
2838 
2839     if(regs->arch_mode == ARCH_900)
2840         logmsg( "Prefix=%16.16" I64_FMT "X\n", (long long)regs->PX_G );
2841     else
2842         logmsg( "Prefix=%8.8X\n", regs->PX_L );
2843 
2844     release_lock(&sysblk.cpulock[sysblk.pcpu]);
2845 
2846     return 0;
2847 }
2848 
2849 
2850 /*-------------------------------------------------------------------*/
2851 /* psw command - display or alter program status word                */
2852 /*-------------------------------------------------------------------*/
psw_cmd(int argc,char * argv[],char * cmdline)2853 int psw_cmd(int argc, char *argv[], char *cmdline)
2854 {
2855 REGS *regs;
2856 BYTE  c;
2857 U64   newia=0;
2858 int   newam=0, newas=0, newcc=0, newcmwp=0, newpk=0, newpm=0, newsm=0;
2859 int   updia=0, updas=0, updcc=0, updcmwp=0, updpk=0, updpm=0, updsm=0;
2860 int   n, errflag, stopflag=0, modflag=0;
2861 
2862     UNREFERENCED(cmdline);
2863 
2864     obtain_lock(&sysblk.cpulock[sysblk.pcpu]);
2865 
2866     if (!IS_CPU_ONLINE(sysblk.pcpu))
2867     {
2868         release_lock(&sysblk.cpulock[sysblk.pcpu]);
2869         logmsg( _("HHCPN160W CPU%4.4X not configured\n"), sysblk.pcpu);
2870         return 0;
2871     }
2872     regs = sysblk.regs[sysblk.pcpu];
2873 
2874     /* Process optional operands */
2875     for (n = 1; n < argc; n++)
2876     {
2877         modflag = 1;
2878         errflag = 0;
2879         if (strncasecmp(argv[n],"sm=",3) == 0)
2880         {
2881             /* PSW system mask operand */
2882             if (sscanf(argv[n]+3, "%x%c", &newsm, &c) == 1
2883                 && newsm >= 0 && newsm <= 255)
2884                 updsm = 1;
2885             else
2886                 errflag = 1;
2887         }
2888         else if (strncasecmp(argv[n],"pk=",3) == 0)
2889         {
2890             /* PSW protection key operand */
2891             if (sscanf(argv[n]+3, "%d%c", &newpk, &c) == 1
2892                 && newpk >= 0 && newpk <= 15)
2893                 updpk = 1;
2894             else
2895                 errflag = 1;
2896         }
2897         else if (strncasecmp(argv[n],"cmwp=",5) == 0)
2898         {
2899             /* PSW CMWP bits operand */
2900             if (sscanf(argv[n]+5, "%x%c", &newcmwp, &c) == 1
2901                 && newcmwp >= 0 && newcmwp <= 15)
2902                 updcmwp = 1;
2903             else
2904                 errflag = 1;
2905         }
2906         else if (strncasecmp(argv[n],"as=",3) == 0)
2907         {
2908             /* PSW address-space control operand */
2909             if (strcasecmp(argv[n]+3,"pri") == 0)
2910                 newas = PSW_PRIMARY_SPACE_MODE;
2911             else if (strcmp(argv[n]+3,"ar") == 0)
2912                 newas = PSW_ACCESS_REGISTER_MODE;
2913             else if (strcmp(argv[n]+3,"sec") == 0)
2914                 newas = PSW_SECONDARY_SPACE_MODE;
2915             else if (strcmp(argv[n]+3,"home") == 0)
2916                 newas = PSW_HOME_SPACE_MODE;
2917             else
2918                 errflag = 1;
2919             if (errflag == 0) updas = 1;
2920         }
2921         else if (strncasecmp(argv[n],"cc=",3) == 0)
2922         {
2923             /* PSW condition code operand */
2924             if (sscanf(argv[n]+3, "%d%c", &newcc, &c) == 1
2925                 && newcc >= 0 && newcc <= 3)
2926                 updcc = 1;
2927             else
2928                 errflag = 1;
2929         }
2930         else if (strncasecmp(argv[n],"pm=",3) == 0)
2931         {
2932             /* PSW program mask operand */
2933             if (sscanf(argv[n]+3, "%x%c", &newpm, &c) == 1
2934                 && newpm >= 0 && newpm <= 15)
2935                 updpm = 1;
2936             else
2937                 errflag = 1;
2938         }
2939         else if (strncasecmp(argv[n],"am=",3) == 0)
2940         {
2941             /* PSW addressing mode operand */
2942             if (strcmp(argv[n]+3,"24") == 0)
2943                 newam = 24;
2944             else if (strcmp(argv[n]+3,"31") == 0
2945                     && (sysblk.arch_mode == ARCH_390
2946                         || sysblk.arch_mode == ARCH_900))
2947                 newam = 31;
2948             else if (strcmp(argv[n]+3,"64") == 0
2949                     && sysblk.arch_mode == ARCH_900)
2950                 newam = 64;
2951             else
2952                 errflag = 1;
2953         }
2954         else if (strncasecmp(argv[n],"ia=",3) == 0)
2955         {
2956             /* PSW instruction address operand */
2957             if (sscanf(argv[n]+3, "%"I64_FMT"x%c", &newia, &c) == 1)
2958                 updia = 1;
2959             else
2960                 errflag = 1;
2961         }
2962         else /* unknown operand keyword */
2963             errflag = 1;
2964 
2965         /* Error message if this operand was invalid */
2966         if (errflag)
2967         {
2968             logmsg( _("HHCPN165E Invalid operand %s\n"), argv[n]);
2969             stopflag = 1;
2970         }
2971     } /* end for(n) */
2972 
2973     /* Finish now if any errors occurred */
2974     if (stopflag)
2975     {
2976         release_lock(&sysblk.cpulock[sysblk.pcpu]);
2977         return 0;
2978     }
2979 
2980     /* Update the PSW system mask, if specified */
2981     if (updsm)
2982     {
2983         regs->psw.sysmask = newsm;
2984     }
2985 
2986     /* Update the PSW protection key, if specified */
2987     if (updpk)
2988     {
2989         regs->psw.pkey = newpk << 4;
2990     }
2991 
2992     /* Update the PSW CMWP bits, if specified */
2993     if (updcmwp)
2994     {
2995         regs->psw.states = newcmwp;
2996     }
2997 
2998     /* Update the PSW address-space control mode, if specified */
2999     if (updas
3000         && (ECMODE(&regs->psw)
3001             || sysblk.arch_mode == ARCH_390
3002             || sysblk.arch_mode == ARCH_900))
3003     {
3004         regs->psw.asc = newas;
3005     }
3006 
3007     /* Update the PSW condition code, if specified */
3008     if (updcc)
3009     {
3010         regs->psw.cc = newcc;
3011     }
3012 
3013     /* Update the PSW program mask, if specified */
3014     if (updpm)
3015     {
3016         regs->psw.progmask = newpm;
3017     }
3018 
3019     /* Update the PSW addressing mode, if specified */
3020     switch(newam) {
3021     case 64:
3022         regs->psw.amode = regs->psw.amode64 = 1;
3023         regs->psw.AMASK_G = AMASK64;
3024         break;
3025     case 31:
3026         regs->psw.amode = 1;
3027         regs->psw.amode64 = 0;
3028         regs->psw.AMASK_G = AMASK31;
3029         break;
3030     case 24:
3031         regs->psw.amode = regs->psw.amode64 = 0;
3032         regs->psw.AMASK_G = AMASK24;
3033         break;
3034     } /* end switch(newam) */
3035 
3036     /* Update the PSW instruction address, if specified */
3037     if (updia)
3038     {
3039         regs->psw.IA_G = newia;
3040     }
3041 
3042     /* If any modifications were made, reapply the addressing mode mask
3043        to the instruction address and invalidate the instruction pointer */
3044     if (modflag)
3045     {
3046         regs->psw.IA_G &= regs->psw.AMASK_G;
3047         regs->aie = NULL;
3048     }
3049 
3050     /* Display the PSW field by field */
3051     logmsg("psw sm=%2.2X pk=%d cmwp=%X as=%s cc=%d pm=%X am=%s ia=%"I64_FMT"X\n",
3052         regs->psw.sysmask,
3053         regs->psw.pkey >> 4,
3054         regs->psw.states,
3055         (regs->psw.asc == PSW_PRIMARY_SPACE_MODE ? "pri" :
3056             regs->psw.asc == PSW_ACCESS_REGISTER_MODE ? "ar" :
3057             regs->psw.asc == PSW_SECONDARY_SPACE_MODE ? "sec" :
3058             regs->psw.asc == PSW_HOME_SPACE_MODE ? "home" : "???"),
3059         regs->psw.cc,
3060         regs->psw.progmask,
3061         (regs->psw.amode == 0 && regs->psw.amode64 == 0 ? "24" :
3062             regs->psw.amode == 1 && regs->psw.amode64 == 0 ? "31" :
3063             regs->psw.amode == 1 && regs->psw.amode64 == 1 ? "64" : "???"),
3064         regs->psw.IA_G);
3065 
3066     /* Display the PSW */
3067     display_psw (regs);
3068 
3069     release_lock(&sysblk.cpulock[sysblk.pcpu]);
3070 
3071     return 0;
3072 }
3073 
3074 
3075 /*-------------------------------------------------------------------*/
3076 /* restart command - generate restart interrupt                      */
3077 /*-------------------------------------------------------------------*/
restart_cmd(int argc,char * argv[],char * cmdline)3078 int restart_cmd(int argc, char *argv[], char *cmdline)
3079 {
3080     UNREFERENCED(cmdline);
3081     UNREFERENCED(argc);
3082     UNREFERENCED(argv);
3083 
3084     /* Check that target processor type allows IPL */
3085     if (sysblk.ptyp[sysblk.pcpu] == SCCB_PTYP_IFA
3086      || sysblk.ptyp[sysblk.pcpu] == SCCB_PTYP_SUP)
3087     {
3088         logmsg(_("HHCPN052E Target CPU %d type %d"
3089                 " does not allow ipl nor restart\n"),
3090                 sysblk.pcpu, sysblk.ptyp[sysblk.pcpu]);
3091         return -1;
3092     }
3093 
3094     logmsg( _("HHCPN038I Restart key depressed\n") );
3095 
3096     /* Obtain the interrupt lock */
3097     OBTAIN_INTLOCK(NULL);
3098 
3099     if (!IS_CPU_ONLINE(sysblk.pcpu))
3100     {
3101         RELEASE_INTLOCK(NULL);
3102         logmsg( _("HHCPN160W CPU%4.4X not configured\n"), sysblk.pcpu );
3103         return 0;
3104     }
3105 
3106     /* Indicate that a restart interrupt is pending */
3107     ON_IC_RESTART(sysblk.regs[sysblk.pcpu]);
3108 
3109     /* Ensure that a stopped CPU will recognize the restart */
3110     if (sysblk.regs[sysblk.pcpu]->cpustate == CPUSTATE_STOPPED)
3111         sysblk.regs[sysblk.pcpu]->cpustate = CPUSTATE_STOPPING;
3112 
3113     sysblk.regs[sysblk.pcpu]->checkstop = 0;
3114 
3115     /* Signal CPU that an interrupt is pending */
3116     WAKEUP_CPU (sysblk.regs[sysblk.pcpu]);
3117 
3118     /* Release the interrupt lock */
3119     RELEASE_INTLOCK(NULL);
3120 
3121     return 0;
3122 }
3123 
3124 
3125 /*-------------------------------------------------------------------*/
3126 /* r command - display or alter real storage                         */
3127 /*-------------------------------------------------------------------*/
r_cmd(int argc,char * argv[],char * cmdline)3128 int r_cmd(int argc, char *argv[], char *cmdline)
3129 {
3130 REGS *regs;
3131 
3132     UNREFERENCED(argc);
3133     UNREFERENCED(argv);
3134 
3135     obtain_lock(&sysblk.cpulock[sysblk.pcpu]);
3136 
3137     if (!IS_CPU_ONLINE(sysblk.pcpu))
3138     {
3139         release_lock(&sysblk.cpulock[sysblk.pcpu]);
3140         logmsg( _("HHCPN160W CPU%4.4X not configured\n"), sysblk.pcpu);
3141         return 0;
3142     }
3143     regs = sysblk.regs[sysblk.pcpu];
3144 
3145     alter_display_real (cmdline+1, regs);
3146 
3147     release_lock(&sysblk.cpulock[sysblk.pcpu]);
3148 
3149     return 0;
3150 }
3151 
3152 
3153 /*-------------------------------------------------------------------*/
3154 /* u command - disassemble                                           */
3155 /*-------------------------------------------------------------------*/
u_cmd(int argc,char * argv[],char * cmdline)3156 int u_cmd(int argc, char *argv[], char *cmdline)
3157 {
3158 REGS *regs;
3159 
3160     UNREFERENCED(argc);
3161     UNREFERENCED(argv);
3162 
3163     obtain_lock(&sysblk.cpulock[sysblk.pcpu]);
3164 
3165     if (!IS_CPU_ONLINE(sysblk.pcpu))
3166     {
3167         release_lock(&sysblk.cpulock[sysblk.pcpu]);
3168         logmsg( _("HHCPN160W CPU%4.4X not configured\n"), sysblk.pcpu);
3169         return 0;
3170     }
3171     regs = sysblk.regs[sysblk.pcpu];
3172 
3173     disasm_stor (regs, cmdline+2);
3174 
3175     release_lock(&sysblk.cpulock[sysblk.pcpu]);
3176 
3177     return 0;
3178 }
3179 
3180 
3181 /*-------------------------------------------------------------------*/
3182 /* v command - display or alter virtual storage                      */
3183 /*-------------------------------------------------------------------*/
v_cmd(int argc,char * argv[],char * cmdline)3184 int v_cmd(int argc, char *argv[], char *cmdline)
3185 {
3186 REGS *regs;
3187 
3188     UNREFERENCED(argc);
3189     UNREFERENCED(argv);
3190 
3191     obtain_lock(&sysblk.cpulock[sysblk.pcpu]);
3192 
3193     if (!IS_CPU_ONLINE(sysblk.pcpu))
3194     {
3195         release_lock(&sysblk.cpulock[sysblk.pcpu]);
3196         logmsg( _("HHCPN160W CPU%4.4X not configured\n"), sysblk.pcpu);
3197         return 0;
3198     }
3199     regs = sysblk.regs[sysblk.pcpu];
3200 
3201     alter_display_virt (cmdline+1, regs);
3202 
3203     release_lock(&sysblk.cpulock[sysblk.pcpu]);
3204 
3205     return 0;
3206 }
3207 
3208 
3209 /*-------------------------------------------------------------------*/
3210 /* tracing commands: t, t+, t-, t?, s, s+, s-, s?, b                 */
3211 /*-------------------------------------------------------------------*/
trace_cmd(int argc,char * argv[],char * cmdline)3212 int trace_cmd(int argc, char *argv[], char *cmdline)
3213 {
3214 int  on = 0, off = 0, query = 0;
3215 int  trace = 0;
3216 int  rc;
3217 BYTE c[2];
3218 U64  addr[2];
3219 char range[256];
3220 
3221     trace = cmdline[0] == 't';
3222 
3223     if (strlen(cmdline) > 1)
3224     {
3225         on = cmdline[1] == '+'
3226          || (cmdline[0] == 'b' && cmdline[1] == ' ');
3227         off = cmdline[1] == '-';
3228         query = cmdline[1] == '?';
3229     }
3230 
3231     if (argc > 2 || (off && argc > 1) || (query && argc > 1))
3232     {
3233         logmsg( _("HHCPN039E Invalid arguments\n") );
3234         return -1;
3235     }
3236 
3237     /* Get address range */
3238     if (argc == 2)
3239     {
3240         rc = sscanf(argv[1], "%"I64_FMT"x%c%"I64_FMT"x%c",
3241                     &addr[0], &c[0], &addr[1], &c[1]);
3242         if (rc == 1)
3243         {
3244             c[0] = '-';
3245             addr[1] = addr[0];
3246         }
3247         else if (rc != 3 || (c[0] != '-' && c[0] != ':' && c[0] != '.'))
3248         {
3249             logmsg( _("HHCPN039E Invalid arguments\n") );
3250             return -1;
3251         }
3252         if (c[0] == '.')
3253             addr[1] += addr[0] - 1;
3254         if (trace)
3255         {
3256             sysblk.traceaddr[0] = addr[0];
3257             sysblk.traceaddr[1] = addr[1];
3258         }
3259         else
3260         {
3261             sysblk.stepaddr[0] = addr[0];
3262             sysblk.stepaddr[1] = addr[1];
3263         }
3264     }
3265     else
3266         c[0] = '-';
3267 
3268     /* Set tracing/stepping bit on or off */
3269     if (on || off)
3270     {
3271         OBTAIN_INTLOCK(NULL);
3272         if (trace)
3273             sysblk.insttrace = on;
3274         else
3275             sysblk.inststep = on;
3276         SET_IC_TRACE;
3277         RELEASE_INTLOCK(NULL);
3278     }
3279 
3280     /* Build range for message */
3281     range[0] = '\0';
3282     if (trace && (sysblk.traceaddr[0] != 0 || sysblk.traceaddr[1] != 0))
3283         sprintf(range, "range %" I64_FMT "x%c%" I64_FMT "x",
3284                 sysblk.traceaddr[0], c[0],
3285                 c[0] != '.' ? sysblk.traceaddr[1] :
3286                 sysblk.traceaddr[1] - sysblk.traceaddr[0] + 1);
3287     else if (!trace && (sysblk.stepaddr[0] != 0 || sysblk.stepaddr[1] != 0))
3288         sprintf(range, "range %" I64_FMT "x%c%" I64_FMT "x",
3289                 sysblk.stepaddr[0], c[0],
3290                 c[0] != '.' ? sysblk.stepaddr[1] :
3291                 sysblk.stepaddr[1] - sysblk.stepaddr[0] + 1);
3292 
3293     /* Determine if this trace is on or off for message */
3294     on = (trace && sysblk.insttrace) || (!trace && sysblk.inststep);
3295 
3296     /* Display message */
3297     logmsg(_("HHCPN040I Instruction %s %s %s\n"),
3298            cmdline[0] == 't' ? _("tracing") :
3299            cmdline[0] == 's' ? _("stepping") : _("break"),
3300            on ? _("on") : _("off"),
3301            range);
3302 
3303     return 0;
3304 }
3305 
3306 
3307 /*-------------------------------------------------------------------*/
3308 /* i command - generate I/O attention interrupt for device           */
3309 /*-------------------------------------------------------------------*/
i_cmd(int argc,char * argv[],char * cmdline)3310 int i_cmd(int argc, char *argv[], char *cmdline)
3311 {
3312 REGS *regs;
3313 
3314     int      rc = 0;
3315     U16      devnum;
3316     U16      lcss;
3317     DEVBLK*  dev;
3318 
3319     UNREFERENCED(cmdline);
3320 
3321     if (argc < 2)
3322     {
3323         missing_devnum();
3324         return -1;
3325     }
3326 
3327     rc=parse_single_devnum(argv[1],&lcss,&devnum);
3328     if (rc<0)
3329     {
3330         return -1;
3331     }
3332 
3333     if (!(dev = find_device_by_devnum (lcss, devnum)))
3334     {
3335         devnotfound_msg(lcss,devnum);
3336         return -1;
3337     }
3338 
3339     rc = device_attention (dev, CSW_ATTN);
3340 
3341     switch (rc) {
3342         case 0: logmsg(_("HHCPN045I Device %4.4X attention request raised\n"),
3343                          devnum);
3344                 break;
3345         case 1: logmsg(_("HHCPN046E Device %4.4X busy or interrupt pending\n"),
3346                          devnum);
3347                 break;
3348         case 2: logmsg(_("HHCPN047E Device %4.4X attention request rejected\n"),
3349                          devnum);
3350                 break;
3351         case 3: logmsg(_("HHCPN048E Device %4.4X subchannel not enabled\n"),
3352                          devnum);
3353                 break;
3354     }
3355 
3356     regs = sysblk.regs[sysblk.pcpu];
3357     if (rc == 3 && IS_CPU_ONLINE(sysblk.pcpu) && CPUSTATE_STOPPED == regs->cpustate)
3358         logmsg( _("HHCPN049W Are you sure you didn't mean 'ipl %4.4X' "
3359                   "instead?\n"), devnum );
3360 
3361     return rc;
3362 }
3363 
3364 
3365 /*-------------------------------------------------------------------*/
3366 /* ext command - generate external interrupt                         */
3367 /*-------------------------------------------------------------------*/
ext_cmd(int argc,char * argv[],char * cmdline)3368 int ext_cmd(int argc, char *argv[], char *cmdline)
3369 {
3370     UNREFERENCED(cmdline);
3371     UNREFERENCED(argc);
3372     UNREFERENCED(argv);
3373 
3374     OBTAIN_INTLOCK(NULL);
3375 
3376     ON_IC_INTKEY;
3377 
3378     logmsg( _("HHCPN050I Interrupt key depressed\n") );
3379 
3380     /* Signal waiting CPUs that an interrupt is pending */
3381     WAKEUP_CPUS_MASK (sysblk.waiting_mask);
3382 
3383     RELEASE_INTLOCK(NULL);
3384 
3385     return 0;
3386 }
3387 
3388 
3389 /*-------------------------------------------------------------------*/
3390 /* pgmprdos config command                                           */
3391 /*-------------------------------------------------------------------*/
pgmprdos_cmd(int argc,char * argv[],char * cmdline)3392 int pgmprdos_cmd(int argc, char *argv[], char *cmdline)
3393 {
3394 
3395     UNREFERENCED(cmdline);
3396 
3397     /* Parse program product OS allowed */
3398     if (argc > 1)
3399     {
3400         if (strcasecmp (argv[1], "LICENSED") == 0)
3401         {
3402             losc_set(PGM_PRD_OS_LICENSED);
3403         }
3404         /* Handle silly British spelling. */
3405         else if (strcasecmp (argv[1], "LICENCED") == 0)
3406         {
3407             losc_set(PGM_PRD_OS_LICENSED);
3408         }
3409         else if (strcasecmp (argv[1], "RESTRICTED") == 0)
3410         {
3411             losc_set(PGM_PRD_OS_RESTRICTED);
3412         }
3413         else
3414         {
3415             logmsg( _("HHCCF028S Invalid program product OS license setting %s\n"),
3416                     argv[1]);
3417         }
3418     }
3419     else
3420         return -1;
3421 
3422     return 0;
3423 }
3424 
3425 
3426 /*-------------------------------------------------------------------*/
3427 /* diag8cmd command                                                  */
3428 /*-------------------------------------------------------------------*/
diag8_cmd(int argc,char * argv[],char * cmdline)3429 int diag8_cmd(int argc, char *argv[], char *cmdline)
3430 {
3431 int i;
3432 
3433     UNREFERENCED(cmdline);
3434 
3435     /* Parse diag8cmd operand */
3436     if(argc > 1)
3437         for(i = 1; i < argc; i++)
3438         {
3439             if(strcasecmp(argv[i],"echo")==0)
3440                 sysblk.diag8cmd |= DIAG8CMD_ECHO;
3441             else
3442             if(strcasecmp(argv[i],"noecho")==0)
3443                 sysblk.diag8cmd &= ~DIAG8CMD_ECHO;
3444             else
3445             if(strcasecmp(argv[i],"enable")==0)
3446                 sysblk.diag8cmd |= DIAG8CMD_ENABLE;
3447             else
3448             if(strcasecmp(argv[i],"disable")==0)
3449                 // disable implies no echo
3450                 sysblk.diag8cmd &= ~(DIAG8CMD_ENABLE | DIAG8CMD_ECHO);
3451             else
3452             {
3453                 logmsg(_("HHCCF052S DIAG8CMD invalid option: %s\n"),argv[i]);
3454                 return -1;
3455             }
3456 
3457         }
3458     else
3459         logmsg(_("HHCCF054S DIAG8CMD: %sable, %secho\n"),
3460             (sysblk.diag8cmd & DIAG8CMD_ENABLE) ? "en" : "dis",
3461             (sysblk.diag8cmd & DIAG8CMD_ECHO)   ? ""   : "no");
3462 
3463     return 0;
3464 }
3465 
3466 
3467 /*-------------------------------------------------------------------*/
3468 /* shcmdopt command                                                  */
3469 /*-------------------------------------------------------------------*/
shcmdopt_cmd(int argc,char * argv[],char * cmdline)3470 int shcmdopt_cmd(int argc, char *argv[], char *cmdline)
3471 {
3472 int i;
3473 
3474     UNREFERENCED(cmdline);
3475 
3476     /* Parse SHCMDOPT operand */
3477     if (argc > 1)
3478         for(i = 1; i < argc; i++)
3479         {
3480             if (strcasecmp (argv[i], "enable") == 0)
3481                 sysblk.shcmdopt &= ~SHCMDOPT_DISABLE;
3482             else
3483             if (strcasecmp (argv[i], "diag8") == 0)
3484                 sysblk.shcmdopt &= ~SHCMDOPT_NODIAG8;
3485             else
3486             if (strcasecmp (argv[i], "disable") == 0)
3487                 sysblk.shcmdopt |= SHCMDOPT_DISABLE;
3488             else
3489             if (strcasecmp (argv[i], "nodiag8") == 0)
3490                 sysblk.shcmdopt |= SHCMDOPT_NODIAG8;
3491             else
3492             {
3493                 logmsg(_("HHCCF053I SHCMDOPT invalid option: %s\n"),
3494                   argv[i]);
3495                 return -1;
3496             }
3497         }
3498     else
3499         logmsg(_("HHCCF053I SCHMDOPT %sabled%s\n"),
3500           (sysblk.shcmdopt&SHCMDOPT_DISABLE)?"Dis":"En",
3501           (sysblk.shcmdopt&SHCMDOPT_NODIAG8)?" NoDiag8":"");
3502 
3503     return 0;
3504 }
3505 
3506 
3507 /*-------------------------------------------------------------------*/
3508 /* legacysenseid command                                             */
3509 /*-------------------------------------------------------------------*/
lsid_cmd(int argc,char * argv[],char * cmdline)3510 int lsid_cmd(int argc, char *argv[], char *cmdline)
3511 {
3512 
3513     UNREFERENCED(cmdline);
3514 
3515     /* Parse Legacy SenseID option */
3516     if (argc > 1)
3517     {
3518         if(strcasecmp(argv[1],"enable") == 0)
3519             sysblk.legacysenseid = 1;
3520         else
3521         if(strcasecmp(argv[1],"on") == 0)
3522             sysblk.legacysenseid = 1;
3523         else
3524         if(strcasecmp(argv[1],"disable") == 0)
3525             sysblk.legacysenseid = 0;
3526         else
3527         if(strcasecmp(argv[1],"off") == 0)
3528             sysblk.legacysenseid = 0;
3529         else
3530         {
3531             logmsg(_("HHCCF110E Legacysenseid invalid option: %s\n"),
3532               argv[1]);
3533             return -1;
3534         }
3535     }
3536     else
3537         logmsg(_("HHCCF111I Legacysenseid %sabled\n"),
3538           sysblk.legacysenseid?"En":"Dis");
3539 
3540     return 0;
3541 }
3542 
3543 
3544 /*-------------------------------------------------------------------*/
3545 /* codepage xxxxxxxx command                                         */
3546 /*-------------------------------------------------------------------*/
codepage_cmd(int argc,char * argv[],char * cmdline)3547 int codepage_cmd(int argc, char *argv[], char *cmdline)
3548 {
3549 
3550     UNREFERENCED(cmdline);
3551 
3552     /* Update LPAR name if operand is specified */
3553     if (argc > 1)
3554         set_codepage(argv[1]);
3555     else
3556     {
3557         logmsg( _("Usage %s <codepage>\n"),argv[0]);
3558         return -1;
3559     }
3560 
3561     return 0;
3562 }
3563 
3564 
3565 #if defined(OPTION_SET_STSI_INFO)
3566 /*-------------------------------------------------------------------*/
3567 /* model config statement                                            */
3568 /* operands: hardware_model [capacity_model [perm_model temp_model]] */
3569 /*-------------------------------------------------------------------*/
stsi_model_cmd(int argc,char * argv[],char * cmdline)3570 int stsi_model_cmd(int argc, char *argv[], char *cmdline)
3571 {
3572 
3573     UNREFERENCED(cmdline);
3574 
3575     /* Update model name if operand is specified */
3576     if (argc > 1)
3577         set_model(argc, argv[1], argv[2], argv[3], argv[4]);
3578     else
3579     {
3580         logmsg( _("HHCCF113E MODEL: no model code\n"));
3581         return -1;
3582     }
3583 
3584     return 0;
3585 }
3586 
3587 
3588 /*-------------------------------------------------------------------*/
3589 /* plant config statement                                            */
3590 /*-------------------------------------------------------------------*/
stsi_plant_cmd(int argc,char * argv[],char * cmdline)3591 int stsi_plant_cmd(int argc, char *argv[], char *cmdline)
3592 {
3593 
3594     UNREFERENCED(cmdline);
3595 
3596     /* Update model name if operand is specified */
3597     if (argc > 1)
3598         set_plant(argv[1]);
3599     else
3600     {
3601         logmsg( _("HHCCF114E PLANT: no plant code\n"));
3602         return -1;
3603     }
3604 
3605     return 0;
3606 }
3607 
3608 
3609 /*-------------------------------------------------------------------*/
3610 /* manufacturer config statement                                     */
3611 /*-------------------------------------------------------------------*/
stsi_mfct_cmd(int argc,char * argv[],char * cmdline)3612 int stsi_mfct_cmd(int argc, char *argv[], char *cmdline)
3613 {
3614 
3615     UNREFERENCED(cmdline);
3616 
3617     /* Update model name if operand is specified */
3618     if (argc > 1)
3619         set_manufacturer(argv[1]);
3620     else
3621     {
3622         logmsg( _("HHCCF115E MANUFACTURER: no manufacturer code\n"));
3623         return -1;
3624     }
3625 
3626     return 0;
3627 }
3628 #endif /* defined(OPTION_SET_STSI_INFO) */
3629 
3630 
3631 /*-------------------------------------------------------------------*/
3632 /* lparname - set or display LPAR name                               */
3633 /*-------------------------------------------------------------------*/
lparname_cmd(int argc,char * argv[],char * cmdline)3634 int lparname_cmd(int argc, char *argv[], char *cmdline)
3635 {
3636 
3637     UNREFERENCED(cmdline);
3638 
3639     /* Update LPAR name if operand is specified */
3640     if (argc > 1)
3641         set_lparname(argv[1]);
3642     else
3643         logmsg( _("HHCPN056I LPAR name = %s\n"),str_lparname());
3644 
3645     return 0;
3646 }
3647 
3648 
3649 /*-------------------------------------------------------------------*/
3650 /* lparnum command - set or display LPAR identification number       */
3651 /*-------------------------------------------------------------------*/
lparnum_cmd(int argc,char * argv[],char * cmdline)3652 int lparnum_cmd(int argc, char *argv[], char *cmdline)
3653 {
3654 U16     id;
3655 BYTE    c;
3656 
3657     UNREFERENCED(cmdline);
3658 
3659     /* Update LPAR identification number if operand is specified */
3660     if (argc > 1)
3661     {
3662         if (argv[1] != NULL
3663           && strlen(argv[1]) >= 1 && strlen(argv[1]) <= 2
3664           && sscanf(argv[1], "%hx%c", &id, &c) == 1)
3665         {
3666             sysblk.lparnum = id;
3667             sysblk.lparnuml = strlen(argv[1]);
3668         }
3669         else
3670         {
3671             logmsg( _("HHCPN058E LPARNUM must be one or two hex digits\n"));
3672             return -1;
3673         }
3674     }
3675     else
3676         logmsg( _("HHCPN060I LPAR number = %"I16_FMT"X\n"), sysblk.lparnum);
3677 
3678     return 0;
3679 }
3680 
3681 
3682 /*-------------------------------------------------------------------*/
3683 /* loadparm - set or display IPL parameter                           */
3684 /*-------------------------------------------------------------------*/
loadparm_cmd(int argc,char * argv[],char * cmdline)3685 int loadparm_cmd(int argc, char *argv[], char *cmdline)
3686 {
3687 
3688     UNREFERENCED(cmdline);
3689 
3690     /* Update IPL parameter if operand is specified */
3691     if (argc > 1)
3692         set_loadparm(argv[1]);
3693     else
3694         logmsg( _("HHCPN051I LOADPARM=%s\n"),str_loadparm());
3695 
3696     return 0;
3697 }
3698 
3699 
3700 /*-------------------------------------------------------------------*/
3701 /* system reset/system reset clear function                          */
3702 /*-------------------------------------------------------------------*/
reset_cmd(int ac,char * av[],char * cmdline,int clear)3703 static int reset_cmd(int ac,char *av[],char *cmdline,int clear)
3704 {
3705     int i;
3706 
3707     UNREFERENCED(ac);
3708     UNREFERENCED(av);
3709     UNREFERENCED(cmdline);
3710     OBTAIN_INTLOCK(NULL);
3711 
3712     for (i = 0; i < MAX_CPU; i++)
3713         if (IS_CPU_ONLINE(i)
3714          && sysblk.regs[i]->cpustate != CPUSTATE_STOPPED)
3715         {
3716             RELEASE_INTLOCK(NULL);
3717             logmsg( _("HHCPN053E System reset/clear rejected: All CPU's must be stopped\n") );
3718             return -1;
3719         }
3720 
3721     system_reset (sysblk.pcpu, clear);
3722 
3723     RELEASE_INTLOCK(NULL);
3724 
3725     return 0;
3726 
3727 }
3728 
3729 
3730 /*-------------------------------------------------------------------*/
3731 /* system reset command                                              */
3732 /*-------------------------------------------------------------------*/
sysr_cmd(int ac,char * av[],char * cmdline)3733 int sysr_cmd(int ac,char *av[],char *cmdline)
3734 {
3735     return(reset_cmd(ac,av,cmdline,0));
3736 }
3737 
3738 
3739 /*-------------------------------------------------------------------*/
3740 /* system reset clear command                                        */
3741 /*-------------------------------------------------------------------*/
sysc_cmd(int ac,char * av[],char * cmdline)3742 int sysc_cmd(int ac,char *av[],char *cmdline)
3743 {
3744     return(reset_cmd(ac,av,cmdline,1));
3745 }
3746 
3747 
3748 /*-------------------------------------------------------------------*/
3749 /* ipl function                                                      */
3750 /*-------------------------------------------------------------------*/
ipl_cmd2(int argc,char * argv[],char * cmdline,int clear)3751 int ipl_cmd2(int argc, char *argv[], char *cmdline, int clear)
3752 {
3753 BYTE c;                                 /* Character work area       */
3754 int  rc;                                /* Return code               */
3755 int  i;
3756 #if defined(OPTION_IPLPARM)
3757 int j;
3758 size_t  maxb;
3759 #endif
3760 U16  lcss;
3761 U16  devnum;
3762 char *cdev, *clcss;
3763 
3764     /* Check that target processor type allows IPL */
3765     if (sysblk.ptyp[sysblk.pcpu] == SCCB_PTYP_IFA
3766      || sysblk.ptyp[sysblk.pcpu] == SCCB_PTYP_SUP)
3767     {
3768         logmsg(_("HHCPN052E Target CPU %d type %d"
3769                 " does not allow ipl nor restart\n"),
3770                 sysblk.pcpu, sysblk.ptyp[sysblk.pcpu]);
3771         return -1;
3772     }
3773 
3774     /* Check the parameters of the IPL command */
3775     if (argc < 2)
3776     {
3777         missing_devnum();
3778         return -1;
3779     }
3780 #if defined(OPTION_IPLPARM)
3781 #define MAXPARMSTRING   sizeof(sysblk.iplparmstring)
3782     sysblk.haveiplparm=0;
3783     maxb=0;
3784     if(argc>2)
3785     {
3786         if(strcasecmp(argv[2],"parm")==0)
3787         {
3788             memset(sysblk.iplparmstring,0,MAXPARMSTRING);
3789             sysblk.haveiplparm=1;
3790             for(i=3;i<argc && maxb<MAXPARMSTRING;i++)
3791             {
3792                 if(i!=3)
3793                 {
3794                     sysblk.iplparmstring[maxb++]=0x40;
3795                 }
3796                 for(j=0;j<(int)strlen(argv[i]) && maxb<MAXPARMSTRING;j++)
3797                 {
3798                     if(islower(argv[i][j]))
3799                     {
3800                         argv[i][j]=toupper(argv[i][j]);
3801                     }
3802                     sysblk.iplparmstring[maxb]=host_to_guest(argv[i][j]);
3803                     maxb++;
3804                 }
3805             }
3806         }
3807     }
3808 #endif
3809 
3810     OBTAIN_INTLOCK(NULL);
3811 
3812     for (i = 0; i < MAX_CPU; i++)
3813         if (IS_CPU_ONLINE(i)
3814          && sysblk.regs[i]->cpustate != CPUSTATE_STOPPED)
3815         {
3816             RELEASE_INTLOCK(NULL);
3817             logmsg( _("HHCPN053E ipl rejected: All CPU's must be stopped\n") );
3818             return -1;
3819         }
3820 
3821     /* The ipl device number might be in format lcss:devnum */
3822     if((cdev = strchr(argv[1],':')))
3823     {
3824         clcss = argv[1];
3825         cdev++;
3826     }
3827     else
3828     {
3829         clcss = NULL;
3830         cdev = argv[1];
3831     }
3832 
3833     /* If the ipl device is not a valid hex number we assume */
3834     /* This is a load from the service processor             */
3835     if (sscanf(cdev, "%hx%c", &devnum, &c) != 1)
3836         rc = load_hmc(strtok(cmdline+3+clear," \t"), sysblk.pcpu, clear);
3837     else
3838     {
3839         *--cdev = '\0';
3840 
3841         if(clcss)
3842         {
3843             if (sscanf(clcss, "%hd%c", &lcss, &c) != 1)
3844             {
3845                 logmsg( _("HHCPN059E LCSS id %s is invalid\n"), clcss );
3846                 return -1;
3847             }
3848         }
3849         else
3850             lcss = 0;
3851 
3852         rc = load_ipl (lcss, devnum, sysblk.pcpu, clear);
3853     }
3854 
3855     RELEASE_INTLOCK(NULL);
3856 
3857     return rc;
3858 }
3859 
3860 
3861 /*-------------------------------------------------------------------*/
3862 /* ipl command                                                       */
3863 /*-------------------------------------------------------------------*/
ipl_cmd(int argc,char * argv[],char * cmdline)3864 int ipl_cmd(int argc, char *argv[], char *cmdline)
3865 {
3866     return(ipl_cmd2(argc,argv,cmdline,0));
3867 }
3868 
3869 
3870 /*-------------------------------------------------------------------*/
3871 /* ipl clear command                                                 */
3872 /*-------------------------------------------------------------------*/
iplc_cmd(int argc,char * argv[],char * cmdline)3873 int iplc_cmd(int argc, char *argv[], char *cmdline)
3874 {
3875     return(ipl_cmd2(argc,argv,cmdline,1));
3876 }
3877 
3878 
3879 /*-------------------------------------------------------------------*/
3880 /* cpu command - define target cpu for panel display and commands    */
3881 /*-------------------------------------------------------------------*/
cpu_cmd(int argc,char * argv[],char * cmdline)3882 int cpu_cmd(int argc, char *argv[], char *cmdline)
3883 {
3884 BYTE c;                                 /* Character work area       */
3885 
3886     int cpu;
3887 
3888     UNREFERENCED(cmdline);
3889 
3890     if (argc < 2)
3891     {
3892         logmsg( _("HHCPN054E Missing argument\n") );
3893         return -1;
3894     }
3895 
3896     if (sscanf(argv[1], "%x%c", &cpu, &c) != 1
3897      || cpu < 0 || cpu >= MAX_CPU)
3898     {
3899         logmsg( _("HHCPN055E Target CPU %s is invalid\n"), argv[1] );
3900         return -1;
3901     }
3902 
3903     sysblk.dummyregs.cpuad = cpu;
3904     sysblk.pcpu = cpu;
3905 
3906     return 0;
3907 }
3908 
3909 
SortDevBlkPtrsAscendingByDevnum(const void * pDevBlkPtr1,const void * pDevBlkPtr2)3910 static int SortDevBlkPtrsAscendingByDevnum(const void* pDevBlkPtr1, const void* pDevBlkPtr2)
3911 {
3912     return
3913         ((int)((*(DEVBLK**)pDevBlkPtr1)->devnum) -
3914          (int)((*(DEVBLK**)pDevBlkPtr2)->devnum));
3915 }
3916 
3917 
3918 /*-------------------------------------------------------------------*/
3919 /* devlist command - list devices                                    */
3920 /*-------------------------------------------------------------------*/
devlist_cmd(int argc,char * argv[],char * cmdline)3921 int devlist_cmd(int argc, char *argv[], char *cmdline)
3922 {
3923     DEVBLK*  dev;
3924     char*    devclass;
3925     char     devnam[1024];
3926     DEVBLK** pDevBlkPtr;
3927     DEVBLK** orig_pDevBlkPtrs;
3928     size_t   nDevCount, i;
3929     int      bTooMany = 0;
3930     U16      lcss;
3931     U16      ssid=0;
3932     U16      devnum;
3933     int      single_devnum = 0;
3934 
3935     UNREFERENCED(cmdline);
3936     UNREFERENCED(argc);
3937     UNREFERENCED(argv);
3938 
3939     if (argc >= 2)
3940     {
3941         single_devnum = 1;
3942 
3943         if (parse_single_devnum(argv[1], &lcss, &devnum) < 0)
3944         {
3945             // (error message already issued)
3946             return -1;
3947         }
3948 
3949         if (!(dev = find_device_by_devnum (lcss, devnum)))
3950         {
3951             devnotfound_msg(lcss, devnum);
3952             return -1;
3953         }
3954 
3955         ssid = LCSS_TO_SSID(lcss);
3956     }
3957 
3958     // Since we wish to display the list of devices in ascending device
3959     // number order, we build our own private a sorted array of DEVBLK
3960     // pointers and use that instead to make the devlist command wholly
3961     // immune from the actual order/sequence of the actual DEVBLK chain.
3962 
3963     // Note too that there is no lock to lock access to ALL device blocks
3964     // (even though there really SHOULD be), only one to lock an individual
3965     // DEVBLK (which doesn't do us much good here).
3966 
3967     if (!(orig_pDevBlkPtrs = malloc(sizeof(DEVBLK*) * MAX_DEVLIST_DEVICES)))
3968     {
3969         logmsg( _("HHCPN146E Work buffer malloc failed: %s\n"),
3970             strerror(errno) );
3971         return -1;
3972     }
3973 
3974     nDevCount = 0;
3975     pDevBlkPtr = orig_pDevBlkPtrs;
3976 
3977     for (dev = sysblk.firstdev; dev && nDevCount <= MAX_DEVLIST_DEVICES; dev = dev->nextdev)
3978     {
3979         if (dev->allocated)  // (valid device?)
3980         {
3981             if (single_devnum && (dev->ssid != ssid || dev->devnum != devnum))
3982                 continue;
3983 
3984             if (nDevCount < MAX_DEVLIST_DEVICES)
3985             {
3986                 *pDevBlkPtr = dev;      // (save ptr to DEVBLK)
3987                 nDevCount++;            // (count array entries)
3988                 pDevBlkPtr++;           // (bump to next entry)
3989 
3990                 if (single_devnum)
3991                     break;
3992             }
3993             else
3994             {
3995                 bTooMany = 1;           // (no more room)
3996                 break;                  // (no more room)
3997             }
3998         }
3999     }
4000 
4001     ASSERT(nDevCount <= MAX_DEVLIST_DEVICES);   // (sanity check)
4002 
4003     // Sort the DEVBLK pointers into ascending sequence by device number.
4004 
4005     qsort(orig_pDevBlkPtrs, nDevCount, sizeof(DEVBLK*), SortDevBlkPtrsAscendingByDevnum);
4006 
4007     // Now use our sorted array of DEVBLK pointers
4008     // to display our sorted list of devices...
4009 
4010     for (i = nDevCount, pDevBlkPtr = orig_pDevBlkPtrs; i; --i, pDevBlkPtr++)
4011     {
4012         dev = *pDevBlkPtr;                  // --> DEVBLK
4013 
4014         /* Call device handler's query definition function */
4015 
4016 #if defined(OPTION_SCSI_TAPE)
4017         if (TAPEDEVT_SCSITAPE == dev->tapedevt)
4018             try_scsi_refresh( dev );  // (see comments in function)
4019 #endif
4020         dev->hnd->query( dev, &devclass, sizeof(devnam), devnam );
4021 
4022         /* Display the device definition and status */
4023         logmsg( "%d:%4.4X %4.4X %s %s%s%s\n",
4024                 SSID_TO_LCSS(dev->ssid),
4025                 dev->devnum, dev->devtype, devnam,
4026                 (dev->fd > 2 ? _("open ") : ""),
4027                 (dev->busy ? _("busy ") : ""),
4028                 (IOPENDING(dev) ? _("pending ") : "")
4029             );
4030 
4031         if (dev->bs)
4032         {
4033             char *clientip, *clientname;
4034 
4035             get_connected_client(dev,&clientip,&clientname);
4036 
4037             if (clientip)
4038             {
4039                 logmsg( _("     (client %s (%s) connected)\n"),
4040                     clientip, clientname
4041                     );
4042             }
4043             else
4044             {
4045                 logmsg( _("     (no one currently connected)\n") );
4046             }
4047 
4048             if (clientip)   free(clientip);
4049             if (clientname) free(clientname);
4050         }
4051     }
4052 
4053     free ( orig_pDevBlkPtrs );
4054 
4055     if (bTooMany)
4056     {
4057         logmsg( _("HHCPN147W Warning: not all devices shown (max %d)\n"),
4058             MAX_DEVLIST_DEVICES);
4059 
4060         return -1;      // (treat as error)
4061     }
4062 
4063     return 0;
4064 }
4065 
4066 
4067 /*-------------------------------------------------------------------*/
4068 /* qd command - query dasd                                           */
4069 /*-------------------------------------------------------------------*/
qd_cmd(int argc,char * argv[],char * cmdline)4070 int qd_cmd(int argc, char *argv[], char *cmdline)
4071 {
4072     DEVBLK*  dev;
4073     DEVBLK** pDevBlkPtr;
4074     DEVBLK** orig_pDevBlkPtrs;
4075     size_t   nDevCount, i, j, num;
4076     int      bTooMany = 0;
4077     U16      lcss;
4078     U16      ssid=0;
4079     U16      devnum;
4080     int      single_devnum = 0;
4081     BYTE     iobuf[256];
4082     BYTE     cbuf[17];
4083 
4084     UNREFERENCED(cmdline);
4085 
4086     if (argc >= 2)
4087     {
4088         single_devnum = 1;
4089 
4090         if (parse_single_devnum(argv[1], &lcss, &devnum) < 0)
4091             return -1;
4092         if (!(dev = find_device_by_devnum (lcss, devnum)))
4093         {
4094             devnotfound_msg(lcss, devnum);
4095             return -1;
4096         }
4097         ssid = LCSS_TO_SSID(lcss);
4098     }
4099 
4100     if (!(orig_pDevBlkPtrs = malloc(sizeof(DEVBLK*) * MAX_DEVLIST_DEVICES)))
4101     {
4102         logmsg( _("HHCPN146E Work buffer malloc failed: %s\n"),
4103             strerror(errno) );
4104         return -1;
4105     }
4106 
4107     nDevCount = 0;
4108     pDevBlkPtr = orig_pDevBlkPtrs;
4109 
4110     for (dev = sysblk.firstdev; dev && nDevCount <= MAX_DEVLIST_DEVICES; dev = dev->nextdev)
4111     {
4112         if (dev->allocated)  // (valid device?)
4113         {
4114             if (single_devnum && (dev->ssid != ssid || dev->devnum != devnum))
4115                 continue;
4116             if (!dev->ckdcyls)
4117                 continue;
4118 
4119             if (nDevCount < MAX_DEVLIST_DEVICES)
4120             {
4121                 *pDevBlkPtr = dev;      // (save ptr to DEVBLK)
4122                 nDevCount++;            // (count array entries)
4123                 pDevBlkPtr++;           // (bump to next entry)
4124 
4125                 if (single_devnum)
4126                     break;
4127             }
4128             else
4129             {
4130                 bTooMany = 1;           // (no more room)
4131                 break;                  // (no more room)
4132             }
4133         }
4134     }
4135 
4136     // Sort the DEVBLK pointers into ascending sequence by device number.
4137 
4138     qsort(orig_pDevBlkPtrs, nDevCount, sizeof(DEVBLK*), SortDevBlkPtrsAscendingByDevnum);
4139 
4140     // Now use our sorted array of DEVBLK pointers
4141     // to display our sorted list of devices...
4142 
4143     for (i = nDevCount, pDevBlkPtr = orig_pDevBlkPtrs; i; --i, pDevBlkPtr++)
4144     {
4145         dev = *pDevBlkPtr;                  // --> DEVBLK
4146 
4147         /* Display sense-id */
4148         for (j = 0; j < dev->numdevid; j++)
4149         {
4150             if (j == 0)
4151                 logmsg("%d:%4.4x SNSID 00 ", SSID_TO_LCSS(dev->ssid), dev->devnum);
4152             else if (j%16 == 0)
4153                 logmsg("\n           %2.2x ", j);
4154             if (j%4 == 0)
4155                 logmsg(" ");
4156             logmsg("%2.2x", dev->devid[j]);
4157         }
4158         logmsg("\n");
4159 
4160         /* Display device characteristics */
4161         for (j = 0; j < dev->numdevchar; j++)
4162         {
4163             if (j == 0)
4164                 logmsg("%d:%4.4x RDC   00 ", SSID_TO_LCSS(dev->ssid), dev->devnum);
4165             else if (j%16 == 0)
4166                 logmsg("\n           %2.2x ", j);
4167             if (j%4 == 0)
4168                 logmsg(" ");
4169             logmsg("%2.2x", dev->devchar[j]);
4170         }
4171         logmsg("\n");
4172 
4173         /* Display configuration data */
4174         dasd_build_ckd_config_data (dev, iobuf, 256);
4175         cbuf[16]=0;
4176         for (j = 0; j < 256; j++)
4177         {
4178             if (j == 0)
4179                 logmsg("%4.4x RCD   00 ",dev->devnum);
4180             else if (j%16 == 0)
4181                 logmsg(" |%s|\n           %2.2x ", cbuf, j);
4182             if (j%4 == 0)
4183                 logmsg(" ");
4184             logmsg("%2.2x", iobuf[j]);
4185             cbuf[j%16] = isprint(guest_to_host(iobuf[j])) ? guest_to_host(iobuf[j]) : '.';
4186         }
4187         logmsg(" |%s|\n", cbuf);
4188 
4189         /* Display subsystem status */
4190         num = dasd_build_ckd_subsys_status(dev, iobuf, 44);
4191         for (j = 0; j < num; j++)
4192         {
4193             if (j == 0)
4194                 logmsg("%4.4x SNSS  00 ",dev->devnum);
4195             else if (j%16 == 0)
4196                 logmsg("\n           %2.2x ", j);
4197             if (j%4 == 0)
4198                 logmsg(" ");
4199             logmsg("%2.2x", iobuf[j]);
4200         }
4201         logmsg("\n");
4202     }
4203 
4204     free ( orig_pDevBlkPtrs );
4205 
4206     if (bTooMany)
4207     {
4208         logmsg( _("HHCPN147W Warning: not all devices shown (max %d)\n"),
4209             MAX_DEVLIST_DEVICES);
4210 
4211         return -1;      // (treat as error)
4212     }
4213 
4214     return 0;
4215 #undef myssid
4216 #undef CONFIG_DATA_SIZE
4217 }
4218 
4219 
4220 /*-------------------------------------------------------------------*/
4221 /* attach command - configure a device                               */
4222 /*-------------------------------------------------------------------*/
attach_cmd(int argc,char * argv[],char * cmdline)4223 int attach_cmd(int argc, char *argv[], char *cmdline)
4224 {
4225     UNREFERENCED(cmdline);
4226 
4227     if (argc < 3)
4228     {
4229         logmsg( _("HHCPN057E Missing argument(s)\n") );
4230         return -1;
4231     }
4232     return parse_and_attach_devices(argv[1],argv[2],argc-3,&argv[3]);
4233 
4234 #if 0
4235     if((cdev = strchr(argv[1],':')))
4236     {
4237         clcss = argv[1];
4238         *cdev++ = '\0';
4239     }
4240     else
4241     {
4242         clcss = NULL;
4243         cdev = argv[1];
4244     }
4245 
4246     if (sscanf(cdev, "%hx%c", &devnum, &c) != 1)
4247     {
4248         logmsg( _("HHCPN059E Device number %s is invalid\n"), cdev );
4249         return -1;
4250     }
4251 
4252     if(clcss)
4253     {
4254         if (sscanf(clcss, "%hd%c", &lcss, &c) != 1)
4255         {
4256             logmsg( _("HHCPN059E LCSS id %s is invalid\n"), clcss );
4257             return -1;
4258         }
4259     }
4260     else
4261         lcss = 0;
4262 
4263 #if 0 /* JAP - Breaks the whole idea behind devtype.c */
4264     if (sscanf(argv[2], "%hx%c", &dummy_devtype, &c) != 1)
4265     {
4266         logmsg( _("Device type %s is invalid\n"), argv[2] );
4267         return -1;
4268     }
4269 #endif
4270 
4271     return  attach_device (lcss, devnum, argv[2], argc-3, &argv[3]);
4272 #endif
4273 }
4274 
4275 
4276 /*-------------------------------------------------------------------*/
4277 /* detach command - remove device                                    */
4278 /*-------------------------------------------------------------------*/
detach_cmd(int argc,char * argv[],char * cmdline)4279 int detach_cmd(int argc, char *argv[], char *cmdline)
4280 {
4281 U16  devnum;
4282 U16  lcss;
4283 int rc;
4284 
4285     UNREFERENCED(cmdline);
4286 
4287     if (argc < 2)
4288     {
4289         missing_devnum();
4290         return -1;
4291     }
4292 
4293     rc=parse_single_devnum(argv[1],&lcss,&devnum);
4294     if (rc<0)
4295     {
4296         return -1;
4297     }
4298 
4299     return  detach_device (lcss, devnum);
4300 }
4301 
4302 
4303 /*-------------------------------------------------------------------*/
4304 /* define command - rename a device                                  */
4305 /*-------------------------------------------------------------------*/
define_cmd(int argc,char * argv[],char * cmdline)4306 int define_cmd(int argc, char *argv[], char *cmdline)
4307 {
4308 U16  devnum, newdevn;
4309 U16 lcss,newlcss;
4310 int rc;
4311 
4312     UNREFERENCED(cmdline);
4313 
4314     if (argc < 3)
4315     {
4316         logmsg( _("HHCPN062E Missing argument(s)\n") );
4317         return -1;
4318     }
4319 
4320     rc=parse_single_devnum(argv[1],&lcss,&devnum);
4321     if (rc<0)
4322     {
4323         return -1;
4324     }
4325     rc=parse_single_devnum(argv[2],&newlcss,&newdevn);
4326     if (rc<0)
4327     {
4328         return -1;
4329     }
4330     if(lcss!=newlcss)
4331     {
4332         logmsg(_("HHCPN182E Device numbers can only be redefined within the same Logical channel subsystem\n"));
4333         return -1;
4334     }
4335 
4336     return  define_device (lcss, devnum, newdevn);
4337 }
4338 
4339 
4340 /*-------------------------------------------------------------------*/
4341 /* pgmtrace command - trace program interrupts                       */
4342 /*-------------------------------------------------------------------*/
pgmtrace_cmd(int argc,char * argv[],char * cmdline)4343 int pgmtrace_cmd(int argc, char *argv[], char *cmdline)
4344 {
4345 int abs_rupt_num, rupt_num;
4346 BYTE    c;                              /* Character work area       */
4347 
4348     UNREFERENCED(cmdline);
4349 
4350     if (argc < 2)
4351     {
4352         if (sysblk.pgminttr == 0xFFFFFFFFFFFFFFFFULL)
4353             logmsg("pgmtrace == all\n");
4354         else if (sysblk.pgminttr == 0)
4355             logmsg("pgmtrace == none\n");
4356         else
4357         {
4358             char flags[64+1]; int i;
4359             for (i=0; i < 64; i++)
4360                 flags[i] = (sysblk.pgminttr & (1ULL << i)) ? ' ' : '*';
4361             flags[64] = 0;
4362             logmsg
4363             (
4364                 " * = Tracing suppressed; otherwise tracing enabled\n"
4365                 " 0000000000000001111111111111111222222222222222233333333333333334\n"
4366                 " 123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0\n"
4367                 " %s\n"
4368                 ,flags
4369             );
4370         }
4371         return 0;
4372     }
4373 
4374     if (sscanf(argv[1], "%x%c", &rupt_num, &c) != 1)
4375     {
4376         logmsg( _("HHCPN066E Program interrupt number %s is invalid\n"),
4377                   argv[1] );
4378         return -1;
4379     }
4380 
4381     if ((abs_rupt_num = abs(rupt_num)) < 1 || abs_rupt_num > 0x40)
4382     {
4383         logmsg( _("HHCPN067E Program interrupt number out of range (%4.4X)\n"),
4384                   abs_rupt_num );
4385         return -1;
4386     }
4387 
4388     /* Add to, or remove interruption code from mask */
4389 
4390     if (rupt_num < 0)
4391         sysblk.pgminttr &= ~((U64)1 << (abs_rupt_num - 1));
4392     else
4393         sysblk.pgminttr |=  ((U64)1 << (abs_rupt_num - 1));
4394 
4395     return 0;
4396 }
4397 
4398 
4399 /*-------------------------------------------------------------------*/
4400 /* ostailor command - trace program interrupts                       */
4401 /*-------------------------------------------------------------------*/
ostailor_cmd(int argc,char * argv[],char * cmdline)4402 int ostailor_cmd(int argc, char *argv[], char *cmdline)
4403 {
4404     UNREFERENCED(cmdline);
4405 
4406     if (argc < 2)
4407     {
4408         char* sostailor = "(custom)";
4409         if (sysblk.pgminttr == OS_OS390 ) sostailor = "OS/390";
4410         if (sysblk.pgminttr == OS_ZOS   ) sostailor = "z/OS";
4411         if (sysblk.pgminttr == OS_VSE   ) sostailor = "VSE";
4412         if (sysblk.pgminttr == OS_VM    ) sostailor = "VM";
4413         if (sysblk.pgminttr == OS_LINUX ) sostailor = "LINUX";
4414         if (sysblk.pgminttr == OS_OPENSOLARIS ) sostailor = "OpenSolaris";
4415         if (sysblk.pgminttr == 0xFFFFFFFFFFFFFFFFULL) sostailor = "NULL";
4416         if (sysblk.pgminttr == 0                    ) sostailor = "QUIET";
4417         logmsg( _("OSTAILOR %s\n"),sostailor);
4418         return 0;
4419     }
4420     if (strcasecmp (argv[1], "OS/390") == 0)
4421     {
4422         sysblk.pgminttr = OS_OS390;
4423         return 0;
4424     }
4425     if (strcasecmp (argv[1], "+OS/390") == 0)
4426     {
4427         sysblk.pgminttr &= OS_OS390;
4428         return 0;
4429     }
4430     if (strcasecmp (argv[1], "-OS/390") == 0)
4431     {
4432         sysblk.pgminttr |= ~OS_OS390;
4433         return 0;
4434     }
4435     if (strcasecmp (argv[1], "Z/OS") == 0)
4436     {
4437         sysblk.pgminttr = OS_ZOS;
4438         return 0;
4439     }
4440     if (strcasecmp (argv[1], "+Z/OS") == 0)
4441     {
4442         sysblk.pgminttr &= OS_ZOS;
4443         return 0;
4444     }
4445     if (strcasecmp (argv[1], "-Z/OS") == 0)
4446     {
4447         sysblk.pgminttr |= ~OS_ZOS;
4448         return 0;
4449     }
4450     if (strcasecmp (argv[1], "VSE") == 0)
4451     {
4452         sysblk.pgminttr = OS_VSE;
4453         return 0;
4454     }
4455     if (strcasecmp (argv[1], "+VSE") == 0)
4456     {
4457         sysblk.pgminttr &= OS_VSE;
4458         return 0;
4459     }
4460     if (strcasecmp (argv[1], "-VSE") == 0)
4461     {
4462         sysblk.pgminttr |= ~OS_VSE;
4463         return 0;
4464     }
4465     if (strcasecmp (argv[1], "VM") == 0)
4466     {
4467         sysblk.pgminttr = OS_VM;
4468         return 0;
4469     }
4470     if (strcasecmp (argv[1], "+VM") == 0)
4471     {
4472         sysblk.pgminttr &= OS_VM;
4473         return 0;
4474     }
4475     if (strcasecmp (argv[1], "-VM") == 0)
4476     {
4477         sysblk.pgminttr |= ~OS_VM;
4478         return 0;
4479     }
4480     if (strcasecmp (argv[1], "LINUX") == 0)
4481     {
4482         sysblk.pgminttr = OS_LINUX;
4483         return 0;
4484     }
4485     if (strcasecmp (argv[1], "+LINUX") == 0)
4486     {
4487         sysblk.pgminttr &= OS_LINUX;
4488         return 0;
4489     }
4490     if (strcasecmp (argv[1], "-LINUX") == 0)
4491     {
4492         sysblk.pgminttr |= ~OS_LINUX;
4493         return 0;
4494     }
4495     if (strcasecmp (argv[1], "OpenSolaris") == 0)
4496     {
4497         sysblk.pgminttr = OS_OPENSOLARIS;
4498         return 0;
4499     }
4500     if (strcasecmp (argv[1], "+OpenSolaris") == 0)
4501     {
4502         sysblk.pgminttr &= OS_OPENSOLARIS;
4503         return 0;
4504     }
4505     if (strcasecmp (argv[1], "-OpenSolaris") == 0)
4506     {
4507         sysblk.pgminttr |= ~OS_OPENSOLARIS;
4508         return 0;
4509     }
4510     if (strcasecmp (argv[1], "NULL") == 0)
4511     {
4512         sysblk.pgminttr = 0xFFFFFFFFFFFFFFFFULL;
4513         return 0;
4514     }
4515     if (strcasecmp (argv[1], "QUIET") == 0)
4516     {
4517         sysblk.pgminttr = 0;
4518         return 0;
4519     }
4520     logmsg( _("Unknown OS tailor specification %s\n"),
4521                 argv[1] );
4522     return -1;
4523 }
4524 
4525 
4526 /*-------------------------------------------------------------------*/
4527 /* k command - print out cckd internal trace                         */
4528 /*-------------------------------------------------------------------*/
k_cmd(int argc,char * argv[],char * cmdline)4529 int k_cmd(int argc, char *argv[], char *cmdline)
4530 {
4531     UNREFERENCED(cmdline);
4532     UNREFERENCED(argc);
4533     UNREFERENCED(argv);
4534 
4535     cckd_print_itrace ();
4536 
4537     return 0;
4538 }
4539 
4540 
4541 /*-------------------------------------------------------------------*/
4542 /* ds - display subchannel                                           */
4543 /*-------------------------------------------------------------------*/
ds_cmd(int argc,char * argv[],char * cmdline)4544 int ds_cmd(int argc, char *argv[], char *cmdline)
4545 {
4546 DEVBLK*  dev;
4547 U16      devnum;
4548 U16      lcss;
4549 int rc;
4550 
4551     UNREFERENCED(cmdline);
4552 
4553     if (argc < 2)
4554     {
4555         missing_devnum();
4556         return -1;
4557     }
4558 
4559     rc=parse_single_devnum(argv[1],&lcss,&devnum);
4560 
4561     if (rc<0)
4562     {
4563         return -1;
4564     }
4565 
4566     if (!(dev = find_device_by_devnum (lcss,devnum)))
4567     {
4568         devnotfound_msg(lcss,devnum);
4569         return -1;
4570     }
4571 
4572     display_subchannel (dev);
4573 
4574     return 0;
4575 }
4576 
4577 
4578 /*-------------------------------------------------------------------*/
4579 /* syncio command - list syncio devices statistics                   */
4580 /*-------------------------------------------------------------------*/
syncio_cmd(int argc,char * argv[],char * cmdline)4581 int syncio_cmd(int argc, char *argv[], char *cmdline)
4582 {
4583     DEVBLK*   dev;
4584     U64       syncios = 0, asyncios = 0;
4585     int       found = 0;
4586 
4587     UNREFERENCED(cmdline);
4588     UNREFERENCED(argc);
4589     UNREFERENCED(argv);
4590 
4591     for (dev = sysblk.firstdev; dev != NULL; dev = dev->nextdev)
4592     {
4593         if (!dev->syncio) continue;
4594 
4595         found = 1;
4596 
4597         logmsg( _("HHCPN072I %4.4X  synchronous: %12" I64_FMT "d "
4598                   "asynchronous: %12" I64_FMT "d\n"),
4599                 dev->devnum, (long long)dev->syncios,
4600                 (long long)dev->asyncios
4601             );
4602 
4603         syncios  += dev->syncios;
4604         asyncios += dev->asyncios;
4605     }
4606 
4607     if (!found)
4608         logmsg( _("HHCPN073I No synchronous I/O devices found\n") );
4609     else
4610         logmsg( _("HHCPN074I TOTAL synchronous: %12" I64_FMT "d "
4611                   "asynchronous: %12" I64_FMT "d  %3" I64_FMT "d%%\n"),
4612                (long long)syncios, (long long)asyncios,
4613                (long long)((syncios * 100) / (syncios + asyncios + 1))
4614             );
4615 
4616     return 0;
4617 }
4618 
4619 
4620 #if !defined(OPTION_FISHIO)
4621 void *device_thread(void *arg);
4622 #endif /* !defined(OPTION_FISHIO) */
4623 
4624 /*-------------------------------------------------------------------*/
4625 /* devtmax command - display or set max device threads               */
4626 /*-------------------------------------------------------------------*/
devtmax_cmd(int argc,char * argv[],char * cmdline)4627 int devtmax_cmd(int argc, char *argv[], char *cmdline)
4628 {
4629     int devtmax = -2;
4630 
4631 #if defined(OPTION_FISHIO)
4632 
4633     UNREFERENCED(cmdline);
4634 
4635     /* Note: no need to lock scheduler vars since WE are
4636      * the only one that updates "ios_devtmax" (the scheduler
4637      * just references it) and we only display (but not update)
4638      * all the other variables.
4639      */
4640 
4641     if (argc > 1)
4642     {
4643         sscanf(argv[1], "%d", &devtmax);
4644 
4645         if (devtmax >= -1)
4646             ios_devtmax = devtmax;
4647         else
4648         {
4649             logmsg( _("HHCPN075E Invalid max device threads value "
4650                       "(must be -1 to n)\n") );
4651             return -1;
4652         }
4653 
4654         TrimDeviceThreads();    /* (enforce newly defined threshold) */
4655     }
4656     else
4657         logmsg( _("HHCPN076I Max device threads: %d, current: %d, most: %d, "
4658             "waiting: %d, max exceeded: %d\n"),
4659             ios_devtmax, ios_devtnbr, ios_devthwm,
4660             (int)ios_devtwait, ios_devtunavail
4661         );
4662 
4663 #else /* !defined(OPTION_FISHIO) */
4664 
4665     TID tid;
4666 
4667     UNREFERENCED(cmdline);
4668 
4669     if (argc > 1)
4670     {
4671         sscanf(argv[1], "%d", &devtmax);
4672 
4673         if (devtmax >= -1)
4674             sysblk.devtmax = devtmax;
4675         else
4676         {
4677             logmsg( _("HHCPN077E Invalid max device threads value "
4678                       "(must be -1 to n)\n") );
4679             return -1;
4680         }
4681 
4682         /* Create a new device thread if the I/O queue is not NULL
4683            and more threads can be created */
4684 
4685         /* the IOQ lock is obtained in order to write to sysblk.devtwait */
4686         obtain_lock(&sysblk.ioqlock);
4687         if (sysblk.ioq && (!sysblk.devtmax || sysblk.devtnbr < sysblk.devtmax))
4688             create_thread(&tid, DETACHED, device_thread, NULL, "idle device thread");
4689 
4690         /* Wakeup threads in case they need to terminate */
4691         sysblk.devtwait=0;
4692         broadcast_condition (&sysblk.ioqcond);
4693         release_lock(&sysblk.ioqlock);
4694     }
4695     else
4696         logmsg( _("HHCPN078E Max device threads %d current %d most %d "
4697             "waiting %d total I/Os queued %d\n"),
4698             sysblk.devtmax, sysblk.devtnbr, sysblk.devthwm,
4699             sysblk.devtwait, sysblk.devtunavail
4700         );
4701 
4702 #endif /* defined(OPTION_FISHIO) */
4703 
4704     return 0;
4705 }
4706 
4707 
4708 
4709 /*-------------------------------------------------------------------*/
4710 /* sf commands - shadow file add/remove/set/compress/display         */
4711 /*-------------------------------------------------------------------*/
ShadowFile_cmd(int argc,char * argv[],char * cmdline)4712 int ShadowFile_cmd(int argc, char *argv[], char *cmdline)
4713 {
4714 char    action;                         /* Action character `+-cd'   */
4715 char   *devascii;                       /* -> Device name            */
4716 DEVBLK *dev;                            /* -> Device block           */
4717 U16     devnum;                         /* Device number             */
4718 U16     lcss;                           /* Logical CSS               */
4719 int     flag = 1;                       /* sf- flag (default merge)  */
4720 int     level = 2;                      /* sfk level (default 2)     */
4721 TID     tid;                            /* sf command thread id      */
4722 char    c;                              /* work for sscan            */
4723 
4724     UNREFERENCED(cmdline);
4725 
4726     if (strlen(argv[0]) < 3 || strchr ("+-cdk", argv[0][2]) == NULL)
4727     {
4728         logmsg( _("HHCPN091E Command must be 'sf+', 'sf-', "
4729                                 "'sfc', 'sfk' or 'sfd'\n") );
4730         return -1;
4731     }
4732 
4733     action = argv[0][2];
4734     /*
4735      * device name either follows the action character or is the
4736      * next operand
4737      */
4738     if (strlen(argv[0]) > 3)
4739         devascii = argv[0] + 3;
4740     else
4741     {
4742         argv++; argc--;
4743         if (argc <= 0 || (devascii = argv[0]) == NULL)
4744         {
4745             missing_devnum();
4746             return -1;
4747         }
4748     }
4749 
4750     /* device name can be `*' meaning all cckd devices */
4751     if (strcmp (devascii, "*") == 0)
4752     {
4753         for (dev=sysblk.firstdev; dev && !dev->cckd_ext; dev=dev->nextdev);
4754             /* nothing */
4755         if (!dev)
4756         {
4757             logmsg( _("HHCPN081E No cckd devices found\n") );
4758             return -1;
4759         }
4760         dev = NULL;
4761     }
4762     else
4763     {
4764         if (parse_single_devnum(devascii,&lcss,&devnum) < 0)
4765             return -1;
4766         if ((dev = find_device_by_devnum (lcss,devnum)) == NULL)
4767             return devnotfound_msg(lcss,devnum);
4768         if (dev->cckd_ext == NULL)
4769         {
4770             logmsg( _("HHCPN084E Device number %d:%4.4X "
4771                       "is not a cckd device\n"), lcss, devnum );
4772             return -1;
4773         }
4774     }
4775 
4776     /* For `sf-' the operand can be `nomerge', `merge' or `force' */
4777     if (action == '-' && argc > 1)
4778     {
4779         if (strcmp(argv[1], "nomerge") == 0)
4780             flag = 0;
4781         else if (strcmp(argv[1], "merge") == 0)
4782             flag = 1;
4783         else if (strcmp(argv[1], "force") == 0)
4784             flag = 2;
4785         else
4786         {
4787             logmsg( _("HHCPN087E Operand must be "
4788                       "`merge', `nomerge' or `force'\n") );
4789             return -1;
4790         }
4791         argv++; argc--;
4792     }
4793 
4794     /* For `sfk' the operand is an integer -1 .. 4 */
4795     if (action == 'k' && argc > 1)
4796     {
4797         if (sscanf(argv[1], "%d%c", &level, &c) != 1 || level < -1 || level > 4)
4798         {
4799             logmsg( _("HHCPN087E Operand must be a number -1 .. 4\n"));
4800             return -1;
4801         }
4802         argv++; argc--;
4803     }
4804 
4805     /* No other operands allowed */
4806     if (argc > 1)
4807     {
4808         logmsg( _("HHCPN089E Unexpected operand: %s\n"), argv[1] );
4809         return -1;
4810     }
4811 
4812     /* Set sf- flags in either cckdblk or the cckd extension */
4813     if (action == '-')
4814     {
4815         if (dev)
4816         {
4817             CCKDDASD_EXT *cckd = dev->cckd_ext;
4818             cckd->sfmerge = flag == 1;
4819             cckd->sfforce = flag == 2;
4820         }
4821         else
4822         {
4823             cckdblk.sfmerge = flag == 1;
4824             cckdblk.sfforce = flag == 2;
4825         }
4826     }
4827     /* Set sfk level in either cckdblk or the cckd extension */
4828     else if (action == 'k')
4829     {
4830         if (dev)
4831         {
4832             CCKDDASD_EXT *cckd = dev->cckd_ext;
4833             cckd->sflevel = level;
4834         }
4835         else
4836             cckdblk.sflevel = level;
4837     }
4838 
4839     /* Process the command */
4840     switch (action) {
4841         case '+': if (create_thread(&tid, DETACHED, cckd_sf_add, dev, "sf+ command"))
4842                       cckd_sf_add(dev);
4843                   break;
4844         case '-': if (create_thread(&tid, DETACHED, cckd_sf_remove, dev, "sf- command"))
4845                       cckd_sf_remove(dev);
4846                   break;
4847         case 'c': if (create_thread(&tid, DETACHED, cckd_sf_comp, dev, "sfc command"))
4848                       cckd_sf_comp(dev);
4849                   break;
4850         case 'd': if (create_thread(&tid, DETACHED, cckd_sf_stats, dev, "sfd command"))
4851                       cckd_sf_stats(dev);
4852                   break;
4853         case 'k': if (create_thread(&tid, DETACHED, cckd_sf_chk, dev, "sfk command"))
4854                       cckd_sf_chk(dev);
4855                   break;
4856     }
4857 
4858     return 0;
4859 }
4860 
4861 
4862 /*-------------------------------------------------------------------*/
4863 /* mounted_tape_reinit statement                                     */
4864 /*-------------------------------------------------------------------*/
mnttapri_cmd(int argc,char * argv[],char * cmdline)4865 int mnttapri_cmd(int argc, char *argv[], char *cmdline)
4866 {
4867     UNREFERENCED(cmdline);
4868 
4869     if(argc > 1)
4870     {
4871         if ( !strcasecmp( argv[1], "disallow" ) )
4872             sysblk.nomountedtapereinit = 1;
4873         else if ( !strcasecmp( argv[1], "allow" ) )
4874             sysblk.nomountedtapereinit = 0;
4875         else
4876         {
4877             logmsg( _("HHCCF052S %s: %s invalid argument\n"),argv[0],argv[1]);
4878             return -1;
4879         }
4880     }
4881     else
4882         logmsg( _("Tape mount reinit %sallowed\n"),sysblk.nomountedtapereinit?"dis":"");
4883 
4884     return 0;
4885 }
4886 
4887 #if defined( OPTION_SCSI_TAPE )
4888 /*-------------------------------------------------------------------*/
4889 /* auto_scsi_mount statement                                         */
4890 /*-------------------------------------------------------------------*/
ascsimnt_cmd(int argc,char * argv[],char * cmdline)4891 int ascsimnt_cmd(int argc, char *argv[], char *cmdline)
4892 {
4893     UNREFERENCED(cmdline);
4894 
4895     if(argc > 1)
4896     {
4897         if ( !strcasecmp( argv[1], "no" ) )
4898             sysblk.auto_scsi_mount_secs = 0;
4899         else if ( !strcasecmp( argv[1], "yes" ) )
4900             sysblk.auto_scsi_mount_secs = DEFAULT_AUTO_SCSI_MOUNT_SECS;
4901         else
4902         {
4903             int secs; char c;
4904             if ( sscanf( argv[1], "%d%c", &secs, &c ) != 1
4905                 || secs <= 0 || secs > 99 )
4906             {
4907                 logmsg( _("HHCCF052S %s: %s invalid argument\n"),argv[0],argv[1]);
4908                 return -1;
4909             }
4910             else
4911                 sysblk.auto_scsi_mount_secs = secs;
4912         }
4913     }
4914     else
4915         logmsg( _("Auto SCSI mount %d seconds\n"),sysblk.auto_scsi_mount_secs);
4916 
4917     return 0;
4918 }
4919 #endif /*defined( OPTION_SCSI_TAPE )*/
4920 
4921 
4922 /*-------------------------------------------------------------------*/
4923 /* devinit command - assign/open a file for a configured device      */
4924 /*-------------------------------------------------------------------*/
devinit_cmd(int argc,char * argv[],char * cmdline)4925 int devinit_cmd(int argc, char *argv[], char *cmdline)
4926 {
4927 DEVBLK*  dev;
4928 U16      devnum;
4929 U16      lcss;
4930 int      i, rc;
4931 int      init_argc;
4932 char   **init_argv;
4933 
4934     UNREFERENCED(cmdline);
4935 
4936     if (argc < 2)
4937     {
4938         logmsg( _("HHCPN093E Missing argument(s)\n") );
4939         return -1;
4940     }
4941 
4942     rc=parse_single_devnum(argv[1],&lcss,&devnum);
4943 
4944     if (rc<0)
4945     {
4946         return -1;
4947     }
4948 
4949     if (!(dev = find_device_by_devnum (lcss, devnum)))
4950     {
4951         devnotfound_msg(lcss,devnum);
4952         return -1;
4953     }
4954 
4955     /* Obtain the device lock */
4956     obtain_lock (&dev->lock);
4957 
4958     /* Reject if device is busy or interrupt pending */
4959     if (dev->busy || IOPENDING(dev)
4960      || (dev->scsw.flag3 & SCSW3_SC_PEND))
4961     {
4962         release_lock (&dev->lock);
4963         logmsg( _("HHCPN096E Device %d:%4.4X busy or interrupt pending\n"),
4964                   lcss, devnum );
4965         return -1;
4966     }
4967 
4968     /* Close the existing file, if any */
4969     if (dev->fd < 0 || dev->fd > 2)
4970     {
4971         (dev->hnd->close)(dev);
4972     }
4973 
4974     /* Build the device initialization arguments array */
4975     if (argc > 2)
4976     {
4977         /* Use the specified new arguments */
4978         init_argc = argc-2;
4979         init_argv = &argv[2];
4980     }
4981     else
4982     {
4983         /* Use the same arguments as originally used */
4984         init_argc = dev->argc;
4985         if (init_argc)
4986         {
4987             init_argv = malloc ( init_argc * sizeof(char*) );
4988             for (i = 0; i < init_argc; i++)
4989                 if (dev->argv[i])
4990                     init_argv[i] = strdup(dev->argv[i]);
4991                 else
4992                     init_argv[i] = NULL;
4993         }
4994         else
4995             init_argv = NULL;
4996     }
4997 
4998     /* Call the device init routine to do the hard work */
4999     if ((rc = (dev->hnd->init)(dev, init_argc, init_argv)) < 0)
5000     {
5001         logmsg( _("HHCPN097E Initialization failed for device %d:%4.4X\n"),
5002                   lcss, devnum );
5003     } else {
5004         logmsg( _("HHCPN098I Device %d:%4.4X initialized\n"), lcss, devnum );
5005     }
5006 
5007     /* Save arguments for next time */
5008     if (rc == 0)
5009     {
5010         for (i = 0; i < dev->argc; i++)
5011             if (dev->argv[i])
5012                 free(dev->argv[i]);
5013         if (dev->argv)
5014             free(dev->argv);
5015 
5016         dev->argc = init_argc;
5017         if (init_argc)
5018         {
5019             dev->argv = malloc ( init_argc * sizeof(char*) );
5020             for (i = 0; i < init_argc; i++)
5021                 if (init_argv[i])
5022                     dev->argv[i] = strdup(init_argv[i]);
5023                 else
5024                     dev->argv[i] = NULL;
5025         }
5026         else
5027             dev->argv = NULL;
5028     }
5029 
5030     /* Release the device lock */
5031     release_lock (&dev->lock);
5032 
5033     /* Raise unsolicited device end interrupt for the device */
5034     if (rc == 0)
5035         rc = device_attention (dev, CSW_DE);
5036 
5037     return rc;
5038 }
5039 
5040 
5041 /*-------------------------------------------------------------------*/
5042 /* savecore filename command - save a core image to file             */
5043 /*-------------------------------------------------------------------*/
savecore_cmd(int argc,char * argv[],char * cmdline)5044 int savecore_cmd(int argc, char *argv[], char *cmdline)
5045 {
5046 REGS *regs;
5047 
5048     char   *fname;                      /* -> File name (ASCIIZ)     */
5049     char   *loadaddr;                   /* loadcore memory address   */
5050     U32     aaddr;                      /* Absolute storage address  */
5051     U32     aaddr2;                     /* Absolute storage address  */
5052     int     fd;                         /* File descriptor           */
5053     int     len;                        /* Number of bytes read      */
5054     BYTE    c;                          /* (dummy sscanf work area)  */
5055     char    pathname[MAX_PATH];         /* fname in host path format */
5056 
5057     UNREFERENCED(cmdline);
5058 
5059     if (argc < 2)
5060     {
5061         logmsg( _("HHCPN099E savecore rejected: filename missing\n") );
5062         return -1;
5063     }
5064 
5065     fname = argv[1];
5066 
5067     obtain_lock(&sysblk.cpulock[sysblk.pcpu]);
5068 
5069     if (!IS_CPU_ONLINE(sysblk.pcpu))
5070     {
5071         release_lock(&sysblk.cpulock[sysblk.pcpu]);
5072         logmsg( _("HHCPN160W CPU%4.4X not configured\n"), sysblk.pcpu);
5073         return 0;
5074     }
5075     regs = sysblk.regs[sysblk.pcpu];
5076 
5077     if (argc < 3 || '*' == *(loadaddr = argv[2]))
5078     {
5079         for (aaddr = 0; aaddr < sysblk.mainsize &&
5080             !(STORAGE_KEY(aaddr, regs) & STORKEY_CHANGE); aaddr += 4096)
5081         {
5082             ;   /* (nop) */
5083         }
5084 
5085         if (aaddr >= sysblk.mainsize)
5086             aaddr = 0;
5087         else
5088             aaddr &= ~0xFFF;
5089     }
5090     else if (sscanf(loadaddr, "%x%c", &aaddr, &c) !=1 ||
5091                                        aaddr >= sysblk.mainsize )
5092     {
5093         release_lock(&sysblk.cpulock[sysblk.pcpu]);
5094         logmsg( _("HHCPN100E savecore: invalid starting address: %s \n"),
5095                   loadaddr );
5096         return -1;
5097     }
5098 
5099     if (argc < 4 || '*' == *(loadaddr = argv[3]))
5100     {
5101         for (aaddr2 = sysblk.mainsize - 4096; aaddr2 > 0 &&
5102             !(STORAGE_KEY(aaddr2, regs) & STORKEY_CHANGE); aaddr2 -= 4096)
5103         {
5104             ;   /* (nop) */
5105         }
5106 
5107         if ( STORAGE_KEY(aaddr2, regs) & STORKEY_CHANGE )
5108             aaddr2 |= 0xFFF;
5109         else
5110         {
5111             release_lock(&sysblk.cpulock[sysblk.pcpu]);
5112             logmsg( _("HHCPN148E savecore: no modified storage found\n") );
5113             return -1;
5114         }
5115     }
5116     else if (sscanf(loadaddr, "%x%c", &aaddr2, &c) !=1 ||
5117                                        aaddr2 >= sysblk.mainsize )
5118     {
5119         release_lock(&sysblk.cpulock[sysblk.pcpu]);
5120         logmsg( _("HHCPN101E savecore: invalid ending address: %s \n"),
5121                   loadaddr );
5122         return -1;
5123     }
5124 
5125     /* Command is valid only when CPU is stopped */
5126     if (CPUSTATE_STOPPED != regs->cpustate)
5127     {
5128         release_lock(&sysblk.cpulock[sysblk.pcpu]);
5129         logmsg( _("HHCPN102E savecore rejected: CPU not stopped\n") );
5130         return -1;
5131     }
5132 
5133     if (aaddr > aaddr2)
5134     {
5135         release_lock(&sysblk.cpulock[sysblk.pcpu]);
5136         logmsg( _("HHCPN103E invalid range: %8.8X-%8.8X\n"), aaddr, aaddr2 );
5137         return -1;
5138     }
5139 
5140     /* Save the file from absolute storage */
5141     logmsg( _("HHCPN104I Saving locations %8.8X-%8.8X to %s\n"),
5142               aaddr, aaddr2, fname );
5143 
5144     hostpath(pathname, fname, sizeof(pathname));
5145 
5146     if ((fd = hopen(pathname, O_CREAT|O_WRONLY|O_EXCL|O_BINARY, S_IREAD|S_IWRITE|S_IRGRP)) < 0)
5147     {
5148         int saved_errno = errno;
5149         release_lock(&sysblk.cpulock[sysblk.pcpu]);
5150         logmsg( _("HHCPN105E savecore error creating %s: %s\n"),
5151                   fname, strerror(saved_errno) );
5152         return -1;
5153     }
5154 
5155     if ((len = write(fd, regs->mainstor + aaddr, (aaddr2 - aaddr) + 1)) < 0)
5156         logmsg( _("HHCPN106E savecore error writing to %s: %s\n"),
5157                   fname, strerror(errno) );
5158     else if((U32)len < (aaddr2 - aaddr) + 1)
5159         logmsg( _("HHCPN107E savecore: unable to save %d bytes\n"),
5160             ((aaddr2 - aaddr) + 1) - len );
5161 
5162     close(fd);
5163 
5164     release_lock(&sysblk.cpulock[sysblk.pcpu]);
5165 
5166     logmsg( _("HHCPN170I savecore command complete.\n"));
5167 
5168     return 0;
5169 }
5170 
5171 
5172 /*-------------------------------------------------------------------*/
5173 /* loadcore filename command - load a core image file                */
5174 /*-------------------------------------------------------------------*/
loadcore_cmd(int argc,char * argv[],char * cmdline)5175 int loadcore_cmd(int argc, char *argv[], char *cmdline)
5176 {
5177 REGS *regs;
5178 
5179     char   *fname;                      /* -> File name (ASCIIZ)     */
5180     struct stat statbuff;               /* Buffer for file status    */
5181     char   *loadaddr;                   /* loadcore memory address   */
5182     U32     aaddr;                      /* Absolute storage address  */
5183     int     len;                        /* Number of bytes read      */
5184     char    pathname[MAX_PATH];         /* file in host path format  */
5185 
5186     UNREFERENCED(cmdline);
5187 
5188     if (argc < 2)
5189     {
5190         logmsg( _("HHCPN108E loadcore rejected: filename missing\n") );
5191         return -1;
5192     }
5193 
5194     fname = argv[1];
5195     hostpath(pathname, fname, sizeof(pathname));
5196 
5197     if (stat(pathname, &statbuff) < 0)
5198     {
5199         logmsg( _("HHCPN109E Cannot open %s: %s\n"),
5200             fname, strerror(errno));
5201         return -1;
5202     }
5203 
5204     if (argc < 3) aaddr = 0;
5205     else
5206     {
5207         loadaddr = argv[2];
5208 
5209         if (sscanf(loadaddr, "%x", &aaddr) !=1)
5210         {
5211             logmsg( _("HHCPN110E invalid address: %s \n"), loadaddr );
5212             return -1;
5213         }
5214     }
5215 
5216     obtain_lock(&sysblk.cpulock[sysblk.pcpu]);
5217 
5218     if (!IS_CPU_ONLINE(sysblk.pcpu))
5219     {
5220         release_lock(&sysblk.cpulock[sysblk.pcpu]);
5221         logmsg( _("HHCPN160W CPU%4.4X not configured\n"), sysblk.pcpu);
5222         return 0;
5223     }
5224     regs = sysblk.regs[sysblk.pcpu];
5225 
5226     /* Command is valid only when CPU is stopped */
5227     if (CPUSTATE_STOPPED != regs->cpustate)
5228     {
5229         release_lock(&sysblk.cpulock[sysblk.pcpu]);
5230         logmsg( _("HHCPN111E loadcore rejected: CPU not stopped\n") );
5231         return -1;
5232     }
5233 
5234     /* Read the file into absolute storage */
5235     logmsg( _("HHCPN112I Loading %s to location %x \n"), fname, aaddr );
5236 
5237     len = load_main(fname, aaddr);
5238 
5239     release_lock(&sysblk.cpulock[sysblk.pcpu]);
5240 
5241     logmsg( _("HHCPN113I %d bytes read from %s\n"), len, fname );
5242 
5243     return 0;
5244 }
5245 
5246 
5247 /*-------------------------------------------------------------------*/
5248 /* loadtext filename command - load a text deck file                 */
5249 /*-------------------------------------------------------------------*/
loadtext_cmd(int argc,char * argv[],char * cmdline)5250 int loadtext_cmd(int argc, char *argv[], char *cmdline)
5251 {
5252     char   *fname;                      /* -> File name (ASCIIZ)     */
5253     char   *loadaddr;                   /* loadcore memory address   */
5254     U32     aaddr;                      /* Absolute storage address  */
5255     int     fd;                         /* File descriptor           */
5256     BYTE    buf[80];                    /* Read buffer               */
5257     int     len;                        /* Number of bytes read      */
5258     int     n;
5259     REGS   *regs;
5260     char    pathname[MAX_PATH];
5261 
5262     UNREFERENCED(cmdline);
5263 
5264     if (argc < 2)
5265     {
5266         logmsg( _("HHCPN114E loadtext rejected: filename missing\n") );
5267         return -1;
5268     }
5269 
5270     fname = argv[1];
5271 
5272     if (argc < 3) aaddr = 0;
5273     else
5274     {
5275         loadaddr = argv[2];
5276 
5277         if (sscanf(loadaddr, "%x", &aaddr) !=1)
5278         {
5279             logmsg( _("HHCPN115E invalid address: %s \n"), loadaddr );
5280             return -1;
5281         }
5282     }
5283 
5284     obtain_lock(&sysblk.cpulock[sysblk.pcpu]);
5285 
5286     if (!IS_CPU_ONLINE(sysblk.pcpu))
5287     {
5288         release_lock(&sysblk.cpulock[sysblk.pcpu]);
5289         logmsg( _("HHCPN160W CPU%4.4X not configured\n"), sysblk.pcpu);
5290         return 0;
5291     }
5292     regs = sysblk.regs[sysblk.pcpu];
5293 
5294     if (aaddr > regs->mainlim)
5295     {
5296         release_lock(&sysblk.cpulock[sysblk.pcpu]);
5297         logmsg( _("HHCPN116E Address greater than mainstore size\n") );
5298         return -1;
5299     }
5300 
5301     /* Command is valid only when CPU is stopped */
5302     if (CPUSTATE_STOPPED != regs->cpustate)
5303     {
5304         release_lock(&sysblk.cpulock[sysblk.pcpu]);
5305         logmsg( _("HHCPN117E loadtext rejected: CPU not stopped\n") );
5306         return -1;
5307     }
5308 
5309     /* Open the specified file name */
5310     hostpath(pathname, fname, sizeof(pathname));
5311     if ((fd = open (pathname, O_RDONLY | O_BINARY)) < 0)
5312     {
5313         release_lock(&sysblk.cpulock[sysblk.pcpu]);
5314         logmsg( _("HHCPN118E Cannot open %s: %s\n"),
5315             fname, strerror(errno));
5316         return -1;
5317     }
5318 
5319     for ( n = 0; ; )
5320     {
5321         /* Read 80 bytes into buffer */
5322         if ((len = read (fd, buf, 80)) < 0)
5323         {
5324             release_lock(&sysblk.cpulock[sysblk.pcpu]);
5325             logmsg( _("HHCPN119E Cannot read %s: %s\n"),
5326                     fname, strerror(errno));
5327             close (fd);
5328             return -1;
5329         }
5330 
5331         /* if record is "END" then break out of loop */
5332         if (0xC5 == buf[1] && 0xD5 == buf[2] && 0xC4 == buf[3])
5333             break;
5334 
5335         /* if record is "TXT" then copy bytes to mainstore */
5336         if (0xE3 == buf[1] && 0xE7 == buf[2] && 0xE3 == buf[3])
5337         {
5338             n   = buf[5]*65536 + buf[6]*256 + buf[7];
5339             len = buf[11];
5340             memcpy(regs->mainstor + aaddr + n, &buf[16], len);
5341             STORAGE_KEY(aaddr + n, regs) |= (STORKEY_REF | STORKEY_CHANGE);
5342             STORAGE_KEY(aaddr + n + len - 1, regs) |= (STORKEY_REF | STORKEY_CHANGE);
5343         }
5344     }
5345 
5346     /* Close file and issue status message */
5347     close (fd);
5348     logmsg( _("HHCPN120I Finished loading TEXT deck file\n") );
5349     logmsg( _("          Last 'TXT' record had address: %3.3X\n"), n );
5350     release_lock(&sysblk.cpulock[sysblk.pcpu]);
5351 
5352     return 0;
5353 }
5354 
5355 
5356 /*-------------------------------------------------------------------*/
5357 /* ipending command - display pending interrupts                     */
5358 /*-------------------------------------------------------------------*/
ipending_cmd(int argc,char * argv[],char * cmdline)5359 int ipending_cmd(int argc, char *argv[], char *cmdline)
5360 {
5361     DEVBLK *dev;                        /* -> Device block           */
5362     IOINT  *io;                         /* -> I/O interrupt entry    */
5363     unsigned i;
5364     char    sysid[12];
5365     BYTE    curpsw[16];
5366     char *states[] = { "?(0)", "STARTED", "STOPPING", "STOPPED" };
5367 
5368     UNREFERENCED(argc);
5369     UNREFERENCED(argv);
5370     UNREFERENCED(cmdline);
5371 
5372     for (i = 0; i < MAX_CPU_ENGINES; i++)
5373     {
5374         if (!IS_CPU_ONLINE(i))
5375         {
5376             logmsg(_("HHCPN123I CPU%4.4X: offline\n"), i);
5377             continue;
5378         }
5379 
5380 // /*DEBUG*/logmsg( _("CPU%4.4X: Any cpu interrupt %spending\n"),
5381 // /*DEBUG*/    sysblk.regs[i]->cpuad, sysblk.regs[i]->cpuint ? "" : _("not ") );
5382         logmsg( _("HHCPN123I CPU%4.4X: CPUint=%8.8X "
5383                   "(State:%8.8X)&(Mask:%8.8X)\n"),
5384             sysblk.regs[i]->cpuad, IC_INTERRUPT_CPU(sysblk.regs[i]),
5385             sysblk.regs[i]->ints_state, sysblk.regs[i]->ints_mask
5386             );
5387         logmsg( _("          CPU%4.4X: Interrupt %spending\n"),
5388             sysblk.regs[i]->cpuad,
5389             IS_IC_INTERRUPT(sysblk.regs[i]) ? "" : _("not ")
5390             );
5391         logmsg( _("          CPU%4.4X: I/O interrupt %spending\n"),
5392             sysblk.regs[i]->cpuad,
5393             IS_IC_IOPENDING                 ? "" : _("not ")
5394             );
5395         logmsg( _("          CPU%4.4X: Clock comparator %spending\n"),
5396             sysblk.regs[i]->cpuad,
5397             IS_IC_CLKC(sysblk.regs[i]) ? "" : _("not ")
5398             );
5399         logmsg( _("          CPU%4.4X: CPU timer %spending\n"),
5400             sysblk.regs[i]->cpuad,
5401             IS_IC_PTIMER(sysblk.regs[i]) ? "" : _("not ")
5402             );
5403 #if defined(_FEATURE_INTERVAL_TIMER)
5404         logmsg( _("          CPU%4.4X: Interval timer %spending\n"),
5405             sysblk.regs[i]->cpuad,
5406             IS_IC_ITIMER(sysblk.regs[i]) ? "" : _("not ")
5407             );
5408 #if defined(_FEATURE_ECPSVM)
5409         logmsg( _("          CPU%4.4X: ECPS vtimer %spending\n"),
5410             sysblk.regs[i]->cpuad,
5411             IS_IC_ECPSVTIMER(sysblk.regs[i]) ? "" : _("not ")
5412             );
5413 #endif /*defined(_FEATURE_ECPSVM)*/
5414 #endif /*defined(_FEATURE_INTERVAL_TIMER)*/
5415         logmsg( _("          CPU%4.4X: External call %spending\n"),
5416             sysblk.regs[i]->cpuad,
5417             IS_IC_EXTCALL(sysblk.regs[i]) ? "" : _("not ")
5418             );
5419         logmsg( _("          CPU%4.4X: Emergency signal %spending\n"),
5420             sysblk.regs[i]->cpuad,
5421             IS_IC_EMERSIG(sysblk.regs[i]) ? "" : _("not ")
5422             );
5423         logmsg( _("          CPU%4.4X: Machine check interrupt %spending\n"),
5424             sysblk.regs[i]->cpuad,
5425             IS_IC_MCKPENDING(sysblk.regs[i]) ? "" : _("not ")
5426             );
5427         logmsg( _("          CPU%4.4X: Service signal %spending\n"),
5428             sysblk.regs[i]->cpuad,
5429             IS_IC_SERVSIG                    ? "" : _("not ")
5430             );
5431         logmsg( _("          CPU%4.4X: Mainlock held: %s\n"),
5432             sysblk.regs[i]->cpuad,
5433             sysblk.regs[i]->cpuad == sysblk.mainowner ? _("yes") : _("no")
5434             );
5435         logmsg( _("          CPU%4.4X: Intlock held: %s\n"),
5436             sysblk.regs[i]->cpuad,
5437             sysblk.regs[i]->cpuad == sysblk.intowner ? _("yes") : _("no")
5438             );
5439         logmsg( _("          CPU%4.4X: Waiting for intlock: %s\n"),
5440             sysblk.regs[i]->cpuad,
5441             sysblk.regs[i]->intwait && !(sysblk.waiting_mask & CPU_BIT(i)) ? _("yes") : _("no")
5442             );
5443         logmsg( _("          CPU%4.4X: lock %sheld\n"),
5444             sysblk.regs[i]->cpuad,
5445             test_lock(&sysblk.cpulock[i]) ? "" : _("not ")
5446             );
5447         if (ARCH_370 == sysblk.arch_mode)
5448         {
5449             if (0xFFFF == sysblk.regs[i]->chanset)
5450                 logmsg( _("          CPU%4.4X: No channelset connected\n"),
5451                     sysblk.regs[i]->cpuad
5452                     );
5453             else
5454                 logmsg( _("          CPU%4.4X: Connected to channelset "
5455                           "%4.4X\n"),
5456                     sysblk.regs[i]->cpuad,sysblk.regs[i]->chanset
5457                     );
5458         }
5459         logmsg( _("          CPU%4.4X: state %s\n"),
5460                sysblk.regs[i]->cpuad,states[sysblk.regs[i]->cpustate]);
5461         logmsg( _("          CPU%4.4X: instcount %" I64_FMT "d\n"),
5462                sysblk.regs[i]->cpuad,(long long)INSTCOUNT(sysblk.regs[i]));
5463         logmsg( _("          CPU%4.4X: siocount %" I64_FMT "d\n"),
5464                sysblk.regs[i]->cpuad,(long long)sysblk.regs[i]->siototal);
5465         copy_psw(sysblk.regs[i], curpsw);
5466         logmsg( _("          CPU%4.4X: psw %2.2x%2.2x%2.2x%2.2x %2.2x%2.2x%2.2x%2.2x"),
5467                sysblk.regs[i]->cpuad,curpsw[0],curpsw[1],curpsw[2],curpsw[3],
5468                curpsw[4],curpsw[5],curpsw[6],curpsw[7]);
5469         if (ARCH_900 == sysblk.arch_mode)
5470         logmsg( _(" %2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x"),
5471                curpsw[8],curpsw[9],curpsw[10],curpsw[11],
5472                curpsw[12],curpsw[13],curpsw[14],curpsw[15]);
5473         logmsg("\n");
5474 
5475         if (sysblk.regs[i]->sie_active)
5476         {
5477             logmsg( _("HHCPN123I SIE%4.4X: CPUint=%8.8X "
5478                       "(State:%8.8X)&(Mask:%8.8X)\n"),
5479                 sysblk.regs[i]->guestregs->cpuad, IC_INTERRUPT_CPU(sysblk.regs[i]->guestregs),
5480                 sysblk.regs[i]->guestregs->ints_state, sysblk.regs[i]->guestregs->ints_mask
5481                 );
5482             logmsg( _("          SIE%4.4X: Interrupt %spending\n"),
5483                 sysblk.regs[i]->guestregs->cpuad,
5484                 IS_IC_INTERRUPT(sysblk.regs[i]->guestregs) ? "" : _("not ")
5485                 );
5486             logmsg( _("          SIE%4.4X: I/O interrupt %spending\n"),
5487                 sysblk.regs[i]->guestregs->cpuad,
5488                 IS_IC_IOPENDING                 ? "" : _("not ")
5489                 );
5490             logmsg( _("          SIE%4.4X: Clock comparator %spending\n"),
5491                 sysblk.regs[i]->guestregs->cpuad,
5492                 IS_IC_CLKC(sysblk.regs[i]->guestregs) ? "" : _("not ")
5493                 );
5494             logmsg( _("          SIE%4.4X: CPU timer %spending\n"),
5495                 sysblk.regs[i]->guestregs->cpuad,
5496                 IS_IC_PTIMER(sysblk.regs[i]->guestregs) ? "" : _("not ")
5497                 );
5498             logmsg( _("          SIE%4.4X: Interval timer %spending\n"),
5499                 sysblk.regs[i]->guestregs->cpuad,
5500                 IS_IC_ITIMER(sysblk.regs[i]->guestregs) ? "" : _("not ")
5501                 );
5502             logmsg( _("          SIE%4.4X: External call %spending\n"),
5503                 sysblk.regs[i]->guestregs->cpuad,
5504                 IS_IC_EXTCALL(sysblk.regs[i]->guestregs) ? "" : _("not ")
5505                 );
5506             logmsg( _("          SIE%4.4X: Emergency signal %spending\n"),
5507                 sysblk.regs[i]->guestregs->cpuad,
5508                 IS_IC_EMERSIG(sysblk.regs[i]->guestregs) ? "" : _("not ")
5509                 );
5510             logmsg( _("          SIE%4.4X: Machine check interrupt %spending\n"),
5511                 sysblk.regs[i]->guestregs->cpuad,
5512                 IS_IC_MCKPENDING(sysblk.regs[i]->guestregs) ? "" : _("not ")
5513                 );
5514             logmsg( _("          SIE%4.4X: Service signal %spending\n"),
5515                 sysblk.regs[i]->guestregs->cpuad,
5516                 IS_IC_SERVSIG                    ? "" : _("not ")
5517                 );
5518             logmsg( _("          SIE%4.4X: lock %sheld\n"),
5519                 sysblk.regs[i]->guestregs->cpuad,
5520                 test_lock(&sysblk.cpulock[i]) ? "" : _("not ")
5521                 );
5522             if (ARCH_370 == sysblk.arch_mode)
5523             {
5524                 if (0xFFFF == sysblk.regs[i]->guestregs->chanset)
5525                     logmsg( _("          SIE%4.4X: No channelset connected\n"),
5526                         sysblk.regs[i]->guestregs->cpuad
5527                         );
5528                 else
5529                     logmsg( _("          SIE%4.4X: Connected to channelset "
5530                               "%4.4X\n"),
5531                         sysblk.regs[i]->guestregs->cpuad,sysblk.regs[i]->guestregs->chanset
5532                         );
5533             }
5534             logmsg( _("          SIE%4.4X: state %s\n"),
5535                    sysblk.regs[i]->guestregs->cpuad,states[sysblk.regs[i]->guestregs->cpustate]);
5536             logmsg( _("          SIE%4.4X: instcount %" I64_FMT "d\n"),
5537                    sysblk.regs[i]->guestregs->cpuad,(long long)sysblk.regs[i]->guestregs->instcount);
5538             logmsg( _("          SIE%4.4X: siocount %" I64_FMT "d\n"),
5539                    sysblk.regs[i]->guestregs->cpuad,(long long)sysblk.regs[i]->guestregs->siototal);
5540             copy_psw(sysblk.regs[i]->guestregs, curpsw);
5541             logmsg( _("          SIE%4.4X: psw %2.2x%2.2x%2.2x%2.2x %2.2x%2.2x%2.2x%2.2x"),
5542                    sysblk.regs[i]->guestregs->cpuad,curpsw[0],curpsw[1],curpsw[2],curpsw[3],
5543                    curpsw[4],curpsw[5],curpsw[6],curpsw[7]);
5544             if (ARCH_900 == sysblk.regs[i]->guestregs->arch_mode)
5545             logmsg( _(" %2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x"),
5546                curpsw[8],curpsw[9],curpsw[10],curpsw[11],
5547                curpsw[12],curpsw[13],curpsw[14],curpsw[15]);
5548             logmsg("\n");
5549         }
5550     }
5551 
5552     logmsg( _("          Config mask "F_CPU_BITMAP
5553                 " started mask "F_CPU_BITMAP
5554                 " waiting mask "F_CPU_BITMAP"\n"),
5555         sysblk.config_mask, sysblk.started_mask, sysblk.waiting_mask
5556         );
5557     logmsg( _("          Syncbc mask "F_CPU_BITMAP" %s\n"),
5558         sysblk.sync_mask, sysblk.syncing ? _("Sync in progress") : ""
5559         );
5560     logmsg( _("          Signaling facility %sbusy\n"),
5561         test_lock(&sysblk.sigplock) ? "" : _("not ")
5562         );
5563     logmsg( _("          TOD lock %sheld\n"),
5564         test_lock(&sysblk.todlock) ? "" : _("not ")
5565         );
5566     logmsg( _("          Mainlock %sheld; owner %4.4x\n"),
5567         test_lock(&sysblk.mainlock) ? "" : _("not "),
5568         sysblk.mainowner
5569         );
5570     logmsg( _("          Intlock %sheld; owner %4.4x\n"),
5571         test_lock(&sysblk.intlock) ? "" : _("not "),
5572         sysblk.intowner
5573         );
5574 #if !defined(OPTION_FISHIO)
5575     logmsg( _("          Ioq lock %sheld\n"),
5576         test_lock(&sysblk.ioqlock) ? "" : _("not ")
5577         );
5578 #endif
5579 
5580     for (dev = sysblk.firstdev; dev != NULL; dev = dev->nextdev)
5581     {
5582         if (dev->ioactive == DEV_SYS_NONE)
5583             strcpy (sysid, "(none)");
5584         else if (dev->ioactive == DEV_SYS_LOCAL)
5585             strcpy (sysid, "local");
5586         else
5587             sprintf (sysid, "id=%d", dev->ioactive);
5588         if (dev->busy && !(dev->suspended && dev->ioactive == DEV_SYS_NONE))
5589             logmsg( _("          DEV %d:%4.4X: busy %s\n"), SSID_TO_LCSS(dev->ssid), dev->devnum, sysid );
5590         if (dev->reserved)
5591             logmsg( _("          DEV %d:%4.4X: reserved %s\n"), SSID_TO_LCSS(dev->ssid), dev->devnum, sysid );
5592         if (dev->suspended)
5593             logmsg( _("          DEV %d:%4.4X: suspended\n"), SSID_TO_LCSS(dev->ssid), dev->devnum );
5594         if (dev->pending && (dev->pmcw.flag5 & PMCW5_V))
5595             logmsg( _("          DEV %d:%4.4X: I/O pending\n"), SSID_TO_LCSS(dev->ssid), dev->devnum );
5596         if (dev->pcipending && (dev->pmcw.flag5 & PMCW5_V))
5597             logmsg( _("          DEV %d:%4.4X: PCI pending\n"), SSID_TO_LCSS(dev->ssid), dev->devnum );
5598         if (dev->attnpending && (dev->pmcw.flag5 & PMCW5_V))
5599             logmsg( _("          DEV %d:%4.4X: Attn pending\n"), SSID_TO_LCSS(dev->ssid), dev->devnum );
5600         if ((dev->crwpending) && (dev->pmcw.flag5 & PMCW5_V))
5601             logmsg( _("          DEV %d:%4.4X: CRW pending\n"), SSID_TO_LCSS(dev->ssid), dev->devnum );
5602         if (test_lock(&dev->lock) && (dev->pmcw.flag5 & PMCW5_V))
5603             logmsg( _("          DEV %d:%4.4X: lock held\n"), SSID_TO_LCSS(dev->ssid), dev->devnum );
5604     }
5605 
5606     logmsg( _("          I/O interrupt queue: ") );
5607 
5608     if (!sysblk.iointq)
5609         logmsg( _("(NULL)") );
5610     logmsg("\n");
5611 
5612     for (io = sysblk.iointq; io; io = io->next)
5613         logmsg
5614         (
5615             _("          DEV %d:%4.4X,%s%s%s%s, pri %d\n")
5616 
5617             ,SSID_TO_LCSS(io->dev->ssid)
5618             ,io->dev->devnum
5619 
5620             ,io->pending      ? " normal"  : ""
5621             ,io->pcipending   ? " PCI"     : ""
5622             ,io->attnpending  ? " ATTN"    : ""
5623             ,!IOPENDING(io)   ? " unknown" : ""
5624 
5625             ,io->priority
5626         );
5627 
5628     return 0;
5629 }
5630 
5631 
5632 #if defined(OPTION_INSTRUCTION_COUNTING)
5633 /*-------------------------------------------------------------------*/
5634 /* icount command - display instruction counts                       */
5635 /*-------------------------------------------------------------------*/
icount_cmd(int argc,char * argv[],char * cmdline)5636 int icount_cmd(int argc, char *argv[], char *cmdline)
5637 {
5638     int i, i1, i2, i3;
5639     unsigned char *opcode1;
5640     unsigned char *opcode2;
5641     U64 *count;
5642     U64 total;
5643 
5644     UNREFERENCED(cmdline);
5645 
5646     obtain_lock( &sysblk.icount_lock );
5647 
5648     if (argc > 1 && !strcasecmp(argv[1], "clear"))
5649     {
5650         memset(IMAP_FIRST,0,IMAP_SIZE);
5651         logmsg( _("HHCPN124I Instruction counts reset to zero.\n") );
5652         release_lock( &sysblk.icount_lock );
5653         return 0;
5654     }
5655 
5656 #define  MAX_ICOUNT_INSTR   1000    /* Maximum number of instructions
5657                                      in architecture instruction set */
5658 
5659     if(argc > 1 && !strcasecmp(argv[1], "sort"))
5660     {
5661       /* Allocate space */
5662       if(!(opcode1 = malloc(MAX_ICOUNT_INSTR * sizeof(unsigned char))))
5663       {
5664         logmsg("Sorry, not enough memory\n");
5665         release_lock( &sysblk.icount_lock );
5666         return 0;
5667       }
5668       if(!(opcode2 = malloc(MAX_ICOUNT_INSTR * sizeof(unsigned char))))
5669       {
5670         logmsg("Sorry, not enough memory\n");
5671         free(opcode1);
5672         release_lock( &sysblk.icount_lock );
5673         return 0;
5674       }
5675       if(!(count = malloc(MAX_ICOUNT_INSTR * sizeof(U64))))
5676       {
5677         logmsg("Sorry, not enough memory\n");
5678         free(opcode1);
5679         free(opcode2);
5680         release_lock( &sysblk.icount_lock );
5681         return(0);
5682       }
5683       for(i = 0; i < (MAX_ICOUNT_INSTR-1); i++)
5684       {
5685         opcode1[i] = 0;
5686         opcode2[i] = 0;
5687         count[i] = 0;
5688       }
5689 
5690       /* Collect */
5691       i = 0;
5692       total = 0;
5693       for(i1 = 0; i1 < 256; i1++)
5694       {
5695         switch(i1)
5696         {
5697           case 0x01:
5698           {
5699             for(i2 = 0; i2 < 256; i2++)
5700             {
5701               if(sysblk.imap01[i2])
5702               {
5703                 opcode1[i] = i1;
5704                 opcode2[i] = i2;
5705                 count[i++] = sysblk.imap01[i2];
5706                 total += sysblk.imap01[i2];
5707                 if(i == (MAX_ICOUNT_INSTR-1))
5708                 {
5709                   logmsg("Sorry, too many instructions\n");
5710                   free(opcode1);
5711                   free(opcode2);
5712                   free(count);
5713                   release_lock( &sysblk.icount_lock );
5714                   return 0;
5715                 }
5716               }
5717             }
5718             break;
5719           }
5720           case 0xA4:
5721           {
5722             for(i2 = 0; i2 < 256; i2++)
5723             {
5724               if(sysblk.imapa4[i2])
5725               {
5726                 opcode1[i] = i1;
5727                 opcode2[i] = i2;
5728                 count[i++] = sysblk.imapa4[i2];
5729                 total += sysblk.imapa4[i2];
5730                 if(i == (MAX_ICOUNT_INSTR-1))
5731                 {
5732                   logmsg("Sorry, too many instructions\n");
5733                   free(opcode1);
5734                   free(opcode2);
5735                   free(count);
5736                   release_lock( &sysblk.icount_lock );
5737                   return 0;
5738                 }
5739               }
5740             }
5741             break;
5742           }
5743           case 0xA5:
5744           {
5745             for(i2 = 0; i2 < 16; i2++)
5746             {
5747               if(sysblk.imapa5[i2])
5748               {
5749                 opcode1[i] = i1;
5750                 opcode2[i] = i2;
5751                 count[i++] = sysblk.imapa5[i2];
5752                 total += sysblk.imapa5[i2];
5753                 if(i == (MAX_ICOUNT_INSTR-1))
5754                 {
5755                   logmsg("Sorry, too many instructions\n");
5756                   free(opcode1);
5757                   free(opcode2);
5758                   free(count);
5759                   release_lock( &sysblk.icount_lock );
5760                   return 0;
5761                 }
5762               }
5763             }
5764             break;
5765           }
5766           case 0xA6:
5767           {
5768             for(i2 = 0; i2 < 256; i2++)
5769             {
5770               if(sysblk.imapa6[i2])
5771               {
5772                 opcode1[i] = i1;
5773                 opcode2[i] = i2;
5774                 count[i++] = sysblk.imapa6[i2];
5775                 total += sysblk.imapa6[i2];
5776                 if(i == (MAX_ICOUNT_INSTR-1))
5777                 {
5778                   logmsg("Sorry, too many instructions\n");
5779                   free(opcode1);
5780                   free(opcode2);
5781                   free(count);
5782                   release_lock( &sysblk.icount_lock );
5783                   return 0;
5784                 }
5785               }
5786             }
5787             break;
5788           }
5789           case 0xA7:
5790           {
5791             for(i2 = 0; i2 < 16; i2++)
5792             {
5793               if(sysblk.imapa7[i2])
5794               {
5795                 opcode1[i] = i1;
5796                 opcode2[i] = i2;
5797                 count[i++] = sysblk.imapa7[i2];
5798                 total += sysblk.imapa7[i2];
5799                 if(i == (MAX_ICOUNT_INSTR-1))
5800                 {
5801                   logmsg("Sorry, too many instructions\n");
5802                   free(opcode1);
5803                   free(opcode2);
5804                   free(count);
5805                   release_lock( &sysblk.icount_lock );
5806                   return 0;
5807                 }
5808               }
5809             }
5810             break;
5811           }
5812           case 0xB2:
5813           {
5814             for(i2 = 0; i2 < 256; i2++)
5815             {
5816               if(sysblk.imapb2[i2])
5817               {
5818                 opcode1[i] = i1;
5819                 opcode2[i] = i2;
5820                 count[i++] = sysblk.imapb2[i2];
5821                 total += sysblk.imapb2[i2];
5822                 if(i == (MAX_ICOUNT_INSTR-1))
5823                 {
5824                   logmsg("Sorry, too many instructions\n");
5825                   free(opcode1);
5826                   free(opcode2);
5827                   free(count);
5828                   release_lock( &sysblk.icount_lock );
5829                   return 0;
5830                 }
5831               }
5832             }
5833             break;
5834           }
5835           case 0xB3:
5836           {
5837             for(i2 = 0; i2 < 256; i2++)
5838             {
5839               if(sysblk.imapb3[i2])
5840               {
5841                 opcode1[i] = i1;
5842                 opcode2[i] = i2;
5843                 count[i++] = sysblk.imapb3[i2];
5844                 total += sysblk.imapb3[i2];
5845                 if(i == (MAX_ICOUNT_INSTR-1))
5846                 {
5847                   logmsg("Sorry, too many instructions\n");
5848                   free(opcode1);
5849                   free(opcode2);
5850                   free(count);
5851                   release_lock( &sysblk.icount_lock );
5852                   return 0;
5853                 }
5854               }
5855             }
5856             break;
5857           }
5858           case 0xB9:
5859           {
5860             for(i2 = 0; i2 < 256; i2++)
5861             {
5862               if(sysblk.imapb9[i2])
5863               {
5864                 opcode1[i] = i1;
5865                 opcode2[i] = i2;
5866                 count[i++] = sysblk.imapb9[i2];
5867                 total += sysblk.imapb9[i2];
5868                 if(i == (MAX_ICOUNT_INSTR-1))
5869                 {
5870                   logmsg("Sorry, too many instructions\n");
5871                   free(opcode1);
5872                   free(opcode2);
5873                   free(count);
5874                   release_lock( &sysblk.icount_lock );
5875                   return 0;
5876                 }
5877               }
5878             }
5879             break;
5880           }
5881           case 0xC0:
5882           {
5883             for(i2 = 0; i2 < 16; i2++)
5884             {
5885               if(sysblk.imapc0[i2])
5886               {
5887                 opcode1[i] = i1;
5888                 opcode2[i] = i2;
5889                 count[i++] = sysblk.imapc0[i2];
5890                 total += sysblk.imapc0[i2];
5891                 if(i == (MAX_ICOUNT_INSTR-1))
5892                 {
5893                   logmsg("Sorry, too many instructions\n");
5894                   free(opcode1);
5895                   free(opcode2);
5896                   free(count);
5897                   release_lock( &sysblk.icount_lock );
5898                   return 0;
5899                 }
5900               }
5901             }
5902             break;
5903           }
5904           case 0xC2:
5905           {
5906             for(i2 = 0; i2 < 16; i2++)
5907             {
5908               if(sysblk.imapc2[i2])
5909               {
5910                 opcode1[i] = i1;
5911                 opcode2[i] = i2;
5912                 count[i++] = sysblk.imapc2[i2];
5913                 total += sysblk.imapc2[i2];
5914                 if(i == (MAX_ICOUNT_INSTR-1))
5915                 {
5916                   logmsg("Sorry, too many instructions\n");
5917                   free(opcode1);
5918                   free(opcode2);
5919                   free(count);
5920                   release_lock( &sysblk.icount_lock );
5921                   return 0;
5922                 }
5923               }
5924             }
5925             break;
5926           }
5927           case 0xC4:
5928           {
5929             for(i2 = 0; i2 < 16; i2++)
5930             {
5931               if(sysblk.imapc4[i2])
5932               {
5933                 opcode1[i] = i1;
5934                 opcode2[i] = i2;
5935                 count[i++] = sysblk.imapc4[i2];
5936                 total += sysblk.imapc4[i2];
5937                 if(i == (MAX_ICOUNT_INSTR-1))
5938                 {
5939                   logmsg("Sorry, too many instructions\n");
5940                   free(opcode1);
5941                   free(opcode2);
5942                   free(count);
5943                   release_lock( &sysblk.icount_lock );
5944                   return 0;
5945                 }
5946               }
5947             }
5948             break;
5949           }
5950           case 0xC6:
5951           {
5952             for(i2 = 0; i2 < 16; i2++)
5953             {
5954               if(sysblk.imapc6[i2])
5955               {
5956                 opcode1[i] = i1;
5957                 opcode2[i] = i2;
5958                 count[i++] = sysblk.imapc6[i2];
5959                 total += sysblk.imapc6[i2];
5960                 if(i == (MAX_ICOUNT_INSTR-1))
5961                 {
5962                   logmsg("Sorry, too many instructions\n");
5963                   free(opcode1);
5964                   free(opcode2);
5965                   free(count);
5966                   release_lock( &sysblk.icount_lock );
5967                   return 0;
5968                 }
5969               }
5970             }
5971             break;
5972           }
5973           case 0xC8:
5974           {
5975             for(i2 = 0; i2 < 16; i2++)
5976             {
5977               if(sysblk.imapc8[i2])
5978               {
5979                 opcode1[i] = i1;
5980                 opcode2[i] = i2;
5981                 count[i++] = sysblk.imapc8[i2];
5982                 total += sysblk.imapc8[i2];
5983                 if(i == (MAX_ICOUNT_INSTR-1))
5984                 {
5985                   logmsg("Sorry, too many instructions\n");
5986                   free(opcode1);
5987                   free(opcode2);
5988                   free(count);
5989                   release_lock( &sysblk.icount_lock );
5990                   return 0;
5991                 }
5992               }
5993             }
5994             break;
5995           }
5996           case 0xE3:
5997           {
5998             for(i2 = 0; i2 < 256; i2++)
5999             {
6000               if(sysblk.imape3[i2])
6001               {
6002                 opcode1[i] = i1;
6003                 opcode2[i] = i2;
6004                 count[i++] = sysblk.imape3[i2];
6005                 total += sysblk.imape3[i2];
6006                 if(i == (MAX_ICOUNT_INSTR-1))
6007                 {
6008                   logmsg("Sorry, too many instructions\n");
6009                   free(opcode1);
6010                   free(opcode2);
6011                   free(count);
6012                   release_lock( &sysblk.icount_lock );
6013                   return 0;
6014                 }
6015               }
6016             }
6017             break;
6018           }
6019           case 0xE4:
6020           {
6021             for(i2 = 0; i2 < 256; i2++)
6022             {
6023               if(sysblk.imape4[i2])
6024               {
6025                 opcode1[i] = i1;
6026                 opcode2[i] = i2;
6027                 count[i++] = sysblk.imape4[i2];
6028                 total += sysblk.imape4[i2];
6029                 if(i == (MAX_ICOUNT_INSTR-1))
6030                 {
6031                   logmsg("Sorry, too many instructions\n");
6032                   free(opcode1);
6033                   free(opcode2);
6034                   free(count);
6035                   release_lock( &sysblk.icount_lock );
6036                   return 0;
6037                 }
6038               }
6039             }
6040             break;
6041           }
6042           case 0xE5:
6043           {
6044             for(i2 = 0; i2 < 256; i2++)
6045             {
6046               if(sysblk.imape5[i2])
6047               {
6048                 opcode1[i] = i1;
6049                 opcode2[i] = i2;
6050                 count[i++] = sysblk.imape5[i2];
6051                 total += sysblk.imape5[i2];
6052                 if(i == (MAX_ICOUNT_INSTR-1))
6053                 {
6054                   logmsg("Sorry, too many instructions\n");
6055                   free(opcode1);
6056                   free(opcode2);
6057                   free(count);
6058                   release_lock( &sysblk.icount_lock );
6059                   return 0;
6060                 }
6061               }
6062             }
6063             break;
6064           }
6065           case 0xEB:
6066           {
6067             for(i2 = 0; i2 < 256; i2++)
6068             {
6069               if(sysblk.imapeb[i2])
6070               {
6071                 opcode1[i] = i1;
6072                 opcode2[i] = i2;
6073                 count[i++] = sysblk.imapeb[i2];
6074                 total += sysblk.imapeb[i2];
6075                 if(i == (MAX_ICOUNT_INSTR-1))
6076                 {
6077                   logmsg("Sorry, too many instructions\n");
6078                   free(opcode1);
6079                   free(opcode2);
6080                   free(count);
6081                   release_lock( &sysblk.icount_lock );
6082                   return 0;
6083                 }
6084               }
6085             }
6086             break;
6087           }
6088           case 0xEC:
6089           {
6090             for(i2 = 0; i2 < 256; i2++)
6091             {
6092               if(sysblk.imapec[i2])
6093               {
6094                 opcode1[i] = i1;
6095                 opcode2[i] = i2;
6096                 count[i++] = sysblk.imapec[i2];
6097                 total += sysblk.imapec[i2];
6098                 if(i == (MAX_ICOUNT_INSTR-1))
6099                 {
6100                   logmsg("Sorry, too many instructions\n");
6101                   free(opcode1);
6102                   free(opcode2);
6103                   free(count);
6104                   release_lock( &sysblk.icount_lock );
6105                   return 0;
6106                 }
6107               }
6108             }
6109             break;
6110           }
6111           case 0xED:
6112           {
6113             for(i2 = 0; i2 < 256; i2++)
6114             {
6115               if(sysblk.imaped[i2])
6116               {
6117                 opcode1[i] = i1;
6118                 opcode2[i] = i2;
6119                 count[i++] = sysblk.imaped[i2];
6120                 total += sysblk.imaped[i2];
6121                 if(i == (MAX_ICOUNT_INSTR-1))
6122                 {
6123                   logmsg("Sorry, too many instructions\n");
6124                   free(opcode1);
6125                   free(opcode2);
6126                   free(count);
6127                   release_lock( &sysblk.icount_lock );
6128                   return 0;
6129                 }
6130               }
6131             }
6132             break;
6133           }
6134           default:
6135           {
6136             if(sysblk.imapxx[i1])
6137             {
6138               opcode1[i] = i1;
6139               opcode2[i] = 0;
6140               count[i++] = sysblk.imapxx[i1];
6141               total += sysblk.imapxx[i1];
6142               if(i == (MAX_ICOUNT_INSTR-1))
6143               {
6144                 logmsg("Sorry, too many instructions\n");
6145                 free(opcode1);
6146                 free(opcode2);
6147                 free(count);
6148                 release_lock( &sysblk.icount_lock );
6149                 return 0;
6150               }
6151             }
6152             break;
6153           }
6154         }
6155       }
6156 
6157       /* Sort */
6158       for(i1 = 0; i1 < i; i1++)
6159       {
6160         /* Find Highest */
6161         for(i2 = i1, i3 = i1; i2 < i; i2++)
6162         {
6163           if(count[i2] > count[i3])
6164             i3 = i2;
6165         }
6166         /* Exchange */
6167         opcode1[(MAX_ICOUNT_INSTR-1)] = opcode1[i1];
6168         opcode2[(MAX_ICOUNT_INSTR-1)] = opcode2[i1];
6169         count  [(MAX_ICOUNT_INSTR-1)] = count  [i1];
6170 
6171         opcode1[i1] = opcode1[i3];
6172         opcode2[i1] = opcode2[i3];
6173         count  [i1] = count  [i3];
6174 
6175         opcode1[i3] = opcode1[(MAX_ICOUNT_INSTR-1)];
6176         opcode2[i3] = opcode2[(MAX_ICOUNT_INSTR-1)];
6177         count  [i3] = count  [(MAX_ICOUNT_INSTR-1)];
6178       }
6179 
6180 #define  ICOUNT_WIDTH  "12"     /* Print field width */
6181 
6182       /* Print */
6183       logmsg(_("HHCPN125I Sorted instruction count display:\n"));
6184       for(i1 = 0; i1 < i; i1++)
6185       {
6186         switch(opcode1[i1])
6187         {
6188           case 0x01:
6189           {
6190             logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\t(%2d%%)\n", opcode1[i1], opcode2[i1], count[i1], (int) (count[i1] * 100 / total));
6191             break;
6192           }
6193           case 0xA4:
6194           {
6195             logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\t(%2d%%)\n", opcode1[i1], opcode2[i1], count[i1], (int) (count[i1] * 100 / total));
6196             break;
6197           }
6198           case 0xA5:
6199           {
6200             logmsg("          INST=%2.2Xx%1.1X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\t(%2d%%)\n", opcode1[i1], opcode2[i1], count[i1], (int) (count[i1] * 100 / total));
6201             break;
6202           }
6203           case 0xA6:
6204           {
6205             logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\t(%2d%%)\n", opcode1[i1], opcode2[i1], count[i1], (int) (count[i1] * 100 / total));
6206             break;
6207           }
6208           case 0xA7:
6209           {
6210             logmsg("          INST=%2.2Xx%1.1X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\t(%2d%%)\n", opcode1[i1], opcode2[i1], count[i1], (int) (count[i1] * 100 / total));
6211             break;
6212           }
6213           case 0xB2:
6214           {
6215             logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\t(%2d%%)\n", opcode1[i1], opcode2[i1], count[i1], (int) (count[i1] * 100 / total));
6216             break;
6217           }
6218           case 0xB3:
6219           {
6220             logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\t(%2d%%)\n", opcode1[i1], opcode2[i1], count[i1], (int) (count[i1] * 100 / total));
6221             break;
6222           }
6223           case 0xB9:
6224           {
6225             logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\t(%2d%%)\n", opcode1[i1], opcode2[i1], count[i1], (int) (count[i1] * 100 / total));
6226             break;
6227           }
6228           case 0xC0:
6229           {
6230             logmsg("          INST=%2.2Xx%1.1X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\t(%2d%%)\n", opcode1[i1], opcode2[i1], count[i1], (int) (count[i1] * 100 / total));
6231             break;
6232           }
6233           case 0xC2:
6234           {
6235             logmsg("          INST=%2.2Xx%1.1X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\t(%2d%%)\n", opcode1[i1], opcode2[i1], count[i1], (int) (count[i1] * 100 / total));
6236             break;
6237           }
6238           case 0xC4:
6239           {
6240             logmsg("          INST=%2.2Xx%1.1X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\t(%2d%%)\n", opcode1[i1], opcode2[i1], count[i1], (int) (count[i1] * 100 / total));
6241             break;
6242           }
6243           case 0xC6:
6244           {
6245             logmsg("          INST=%2.2Xx%1.1X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\t(%2d%%)\n", opcode1[i1], opcode2[i1], count[i1], (int) (count[i1] * 100 / total));
6246             break;
6247           }
6248           case 0xC8:
6249           {
6250             logmsg("          INST=%2.2Xx%1.1X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\t(%2d%%)\n", opcode1[i1], opcode2[i1], count[i1], (int) (count[i1] * 100 / total));
6251             break;
6252           }
6253           case 0xE3:
6254           {
6255             logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\t(%2d%%)\n", opcode1[i1], opcode2[i1], count[i1], (int) (count[i1] * 100 / total));
6256             break;
6257           }
6258           case 0xE4:
6259           {
6260             logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\t(%2d%%)\n", opcode1[i1], opcode2[i1], count[i1], (int) (count[i1] * 100 / total));
6261             break;
6262           }
6263           case 0xE5:
6264           {
6265             logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\t(%2d%%)\n", opcode1[i1], opcode2[i1], count[i1], (int) (count[i1] * 100 / total));
6266             break;
6267           }
6268           case 0xEB:
6269           {
6270             logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\t(%2d%%)\n", opcode1[i1], opcode2[i1], count[i1], (int) (count[i1] * 100 / total));
6271             break;
6272           }
6273           case 0xEC:
6274           {
6275             logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\t(%2d%%)\n", opcode1[i1], opcode2[i1], count[i1], (int) (count[i1] * 100 / total));
6276             break;
6277           }
6278           case 0xED:
6279           {
6280             logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\t(%2d%%)\n", opcode1[i1], opcode2[i1], count[i1], (int) (count[i1] * 100 / total));
6281             break;
6282           }
6283           default:
6284           {
6285             logmsg("          INST=%2.2X  \tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\t(%2d%%)\n", opcode1[i1], count[i1], (int) (count[i1] * 100 / total));
6286             break;
6287           }
6288         }
6289       }
6290       free(opcode1);
6291       free(opcode2);
6292       free(count);
6293       release_lock( &sysblk.icount_lock );
6294       return 0;
6295     }
6296 
6297     logmsg(_("HHCPN125I Instruction count display:\n"));
6298     for (i1 = 0; i1 < 256; i1++)
6299     {
6300         switch (i1)
6301         {
6302             case 0x01:
6303                 for(i2 = 0; i2 < 256; i2++)
6304                     if(sysblk.imap01[i2])
6305                         logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\n",
6306                             i1, i2, sysblk.imap01[i2]);
6307                 break;
6308             case 0xA4:
6309                 for(i2 = 0; i2 < 256; i2++)
6310                     if(sysblk.imapa4[i2])
6311                         logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\n",
6312                             i1, i2, sysblk.imapa4[i2]);
6313                 break;
6314             case 0xA5:
6315                 for(i2 = 0; i2 < 16; i2++)
6316                     if(sysblk.imapa5[i2])
6317                         logmsg("          INST=%2.2Xx%1.1X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\n",
6318                             i1, i2, sysblk.imapa5[i2]);
6319                 break;
6320             case 0xA6:
6321                 for(i2 = 0; i2 < 256; i2++)
6322                     if(sysblk.imapa6[i2])
6323                         logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\n",
6324                             i1, i2, sysblk.imapa6[i2]);
6325                 break;
6326             case 0xA7:
6327                 for(i2 = 0; i2 < 16; i2++)
6328                     if(sysblk.imapa7[i2])
6329                         logmsg("          INST=%2.2Xx%1.1X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\n",
6330                             i1, i2, sysblk.imapa7[i2]);
6331                 break;
6332             case 0xB2:
6333                 for(i2 = 0; i2 < 256; i2++)
6334                     if(sysblk.imapb2[i2])
6335                         logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\n",
6336                             i1, i2, sysblk.imapb2[i2]);
6337                 break;
6338             case 0xB3:
6339                 for(i2 = 0; i2 < 256; i2++)
6340                     if(sysblk.imapb3[i2])
6341                         logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\n",
6342                             i1, i2, sysblk.imapb3[i2]);
6343                 break;
6344             case 0xB9:
6345                 for(i2 = 0; i2 < 256; i2++)
6346                     if(sysblk.imapb9[i2])
6347                         logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\n",
6348                             i1, i2, sysblk.imapb9[i2]);
6349                 break;
6350             case 0xC0:
6351                 for(i2 = 0; i2 < 16; i2++)
6352                     if(sysblk.imapc0[i2])
6353                         logmsg("          INST=%2.2Xx%1.1X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\n",
6354                             i1, i2, sysblk.imapc0[i2]);
6355                 break;
6356             case 0xC2:                                                      /*@Z9*/
6357                 for(i2 = 0; i2 < 16; i2++)                                  /*@Z9*/
6358                     if(sysblk.imapc2[i2])                                   /*@Z9*/
6359                         logmsg("          INST=%2.2Xx%1.1X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\n",  /*@Z9*/
6360                             i1, i2, sysblk.imapc2[i2]);                     /*@Z9*/
6361                 break;                                                      /*@Z9*/
6362             case 0xC4:
6363                 for(i2 = 0; i2 < 16; i2++)
6364                     if(sysblk.imapc4[i2])
6365                         logmsg("          INST=%2.2Xx%1.1X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\n",
6366                             i1, i2, sysblk.imapc4[i2]);
6367                 break;
6368             case 0xC6:
6369                 for(i2 = 0; i2 < 16; i2++)
6370                     if(sysblk.imapc6[i2])
6371                         logmsg("          INST=%2.2Xx%1.1X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\n",
6372                             i1, i2, sysblk.imapc6[i2]);
6373                 break;
6374             case 0xC8:
6375                 for(i2 = 0; i2 < 16; i2++)
6376                     if(sysblk.imapc8[i2])
6377                         logmsg("          INST=%2.2Xx%1.1X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\n",
6378                             i1, i2, sysblk.imapc8[i2]);
6379                 break;
6380             case 0xE3:
6381                 for(i2 = 0; i2 < 256; i2++)
6382                     if(sysblk.imape3[i2])
6383                         logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\n",
6384                             i1, i2, sysblk.imape3[i2]);
6385                 break;
6386             case 0xE4:
6387                 for(i2 = 0; i2 < 256; i2++)
6388                     if(sysblk.imape4[i2])
6389                         logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\n",
6390                             i1, i2, sysblk.imape4[i2]);
6391                 break;
6392             case 0xE5:
6393                 for(i2 = 0; i2 < 256; i2++)
6394                     if(sysblk.imape5[i2])
6395                         logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\n",
6396                             i1, i2, sysblk.imape5[i2]);
6397                 break;
6398             case 0xEB:
6399                 for(i2 = 0; i2 < 256; i2++)
6400                     if(sysblk.imapeb[i2])
6401                         logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\n",
6402                             i1, i2, sysblk.imapeb[i2]);
6403                 break;
6404             case 0xEC:
6405                 for(i2 = 0; i2 < 256; i2++)
6406                     if(sysblk.imapec[i2])
6407                         logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\n",
6408                             i1, i2, sysblk.imapec[i2]);
6409                 break;
6410             case 0xED:
6411                 for(i2 = 0; i2 < 256; i2++)
6412                     if(sysblk.imaped[i2])
6413                         logmsg("          INST=%2.2X%2.2X\tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\n",
6414                             i1, i2, sysblk.imaped[i2]);
6415                 break;
6416             default:
6417                 if(sysblk.imapxx[i1])
6418                     logmsg("          INST=%2.2X  \tCOUNT=%" ICOUNT_WIDTH I64_FMT "u\n",
6419                         i1, sysblk.imapxx[i1]);
6420                 break;
6421         }
6422     }
6423     release_lock( &sysblk.icount_lock );
6424     return 0;
6425 }
6426 
6427 #endif /*defined(OPTION_INSTRUCTION_COUNTING)*/
6428 
6429 
6430 #if defined(OPTION_CONFIG_SYMBOLS)
6431 /*-------------------------------------------------------------------*/
6432 /* defsym command - define substitution symbol                       */
6433 /*-------------------------------------------------------------------*/
defsym_cmd(int argc,char * argv[],char * cmdline)6434 int defsym_cmd(int argc, char *argv[], char *cmdline)
6435 {
6436     char* sym;
6437     char* value;
6438 
6439     UNREFERENCED(cmdline);
6440 
6441     if (argc < 2)
6442     {
6443         list_all_symbols();
6444         return 0;
6445     }
6446 
6447     /* point to symbol name */
6448     sym = argv[1];
6449 
6450     if (argc > 3)
6451     {
6452         logmsg(_("HHCCF060S DEFSYM requires a single value"
6453                 " (use quotes if necessary)\n"));
6454         return -1;
6455     }
6456 
6457     /* point to symbol value if specified, otherwise set to blank */
6458     value = (argc > 2) ? argv[2] : "";
6459 
6460     /* define the symbol */
6461     set_symbol(sym,value);
6462     return 0;
6463 }
6464 #endif // defined(OPTION_CONFIG_SYMBOLS)
6465 
6466 
6467 /*-------------------------------------------------------------------*/
6468 /* archmode command - set architecture mode                          */
6469 /*-------------------------------------------------------------------*/
archmode_cmd(int argc,char * argv[],char * cmdline)6470 int archmode_cmd(int argc, char *argv[], char *cmdline)
6471 {
6472     int i;
6473 
6474     UNREFERENCED(cmdline);
6475 
6476     if (argc < 2)
6477     {
6478         logmsg( _("HHCPN126I Architecture mode = %s\n"),
6479                   get_arch_mode_string(NULL) );
6480         return 0;
6481     }
6482 
6483     OBTAIN_INTLOCK(NULL);
6484 
6485     /* Make sure all CPUs are deconfigured or stopped */
6486     for (i = 0; i < MAX_CPU_ENGINES; i++)
6487         if (IS_CPU_ONLINE(i)
6488          && CPUSTATE_STOPPED != sysblk.regs[i]->cpustate)
6489         {
6490             RELEASE_INTLOCK(NULL);
6491             logmsg( _("HHCPN127E All CPU's must be stopped to change "
6492                       "architecture\n") );
6493             return -1;
6494         }
6495 #if defined(_370)
6496     if (!strcasecmp (argv[1], arch_name[ARCH_370]))
6497     {
6498         sysblk.arch_mode = ARCH_370;
6499         sysblk.maxcpu = sysblk.numcpu;
6500     }
6501     else
6502 #endif
6503 #if defined(_390)
6504     if (!strcasecmp (argv[1], arch_name[ARCH_390]))
6505     {
6506         sysblk.arch_mode = ARCH_390;
6507 #if defined(_FEATURE_CPU_RECONFIG)
6508         sysblk.maxcpu = MAX_CPU_ENGINES;
6509 #else
6510         sysblk.maxcpu = sysblk.numcpu;
6511 #endif
6512     }
6513     else
6514 #endif
6515 #if defined(_900)
6516     if (0
6517         || !strcasecmp (argv[1], arch_name[ARCH_900])
6518         || !strcasecmp (argv[1], "ESAME")
6519     )
6520     {
6521         sysblk.arch_mode = ARCH_900;
6522 #if defined(_FEATURE_CPU_RECONFIG)
6523         sysblk.maxcpu = MAX_CPU_ENGINES;
6524 #else
6525         sysblk.maxcpu = sysblk.numcpu;
6526 #endif
6527     }
6528     else
6529 #endif
6530     {
6531         RELEASE_INTLOCK(NULL);
6532         logmsg( _("HHCPN128E Invalid architecture mode %s\n"), argv[1] );
6533         return -1;
6534     }
6535     if (sysblk.pcpu >= MAX_CPU)
6536         sysblk.pcpu = 0;
6537 
6538     sysblk.dummyregs.arch_mode = sysblk.arch_mode;
6539 #if defined(OPTION_FISHIO)
6540     ios_arch_mode = sysblk.arch_mode;
6541 #endif /* defined(OPTION_FISHIO) */
6542 
6543     /* Indicate if z/Architecture is supported */
6544     sysblk.arch_z900 = sysblk.arch_mode != ARCH_390;
6545 
6546 #if defined(_FEATURE_CPU_RECONFIG) && defined(_S370)
6547     /* Configure CPUs for S/370 mode */
6548     if (sysblk.archmode == ARCH_370)
6549         for (i = MAX_CPU_ENGINES - 1; i >= 0; i--)
6550             if (i < MAX_CPU && !IS_CPU_ONLINE(i))
6551                 configure_cpu(i);
6552             else if (i >= MAX_CPU && IS_CPU_ONLINE(i))
6553                 deconfigure_cpu(i);
6554 #endif
6555 
6556     RELEASE_INTLOCK(NULL);
6557 
6558     return 0;
6559 }
6560 
6561 
6562 /*-------------------------------------------------------------------*/
6563 /* x+ and x- commands - turn switches on or off                      */
6564 /*-------------------------------------------------------------------*/
OnOffCommand(int argc,char * argv[],char * cmdline)6565 int OnOffCommand(int argc, char *argv[], char *cmdline)
6566 {
6567     char   *cmd = cmdline;              /* Copy of panel command     */
6568     int     oneorzero;                  /* 1=x+ command, 0=x-        */
6569     char   *onoroff;                    /* "on" or "off"             */
6570     U32     aaddr;                      /* Absolute storage address  */
6571     DEVBLK* dev;
6572     U16     devnum;
6573     U16     lcss;
6574 REGS *regs;
6575 BYTE c;                                 /* Character work area       */
6576 
6577     UNREFERENCED(argc);
6578     UNREFERENCED(argv);
6579 
6580     if (cmd[1] == '+') {
6581         oneorzero = 1;
6582         onoroff = _("on");
6583     } else {
6584         oneorzero = 0;
6585         onoroff = _("off");
6586     }
6587 
6588     OBTAIN_INTLOCK(NULL);
6589 
6590     if (!IS_CPU_ONLINE(sysblk.pcpu))
6591     {
6592         RELEASE_INTLOCK(NULL);
6593         logmsg( _("HHCPN160W CPU%4.4X not configured\n"), sysblk.pcpu);
6594         return 0;
6595     }
6596     regs=sysblk.regs[sysblk.pcpu];
6597 
6598 
6599     // f- and f+ commands - mark frames unusable/usable
6600 
6601     if ((cmd[0] == 'f') && sscanf(cmd+2, "%x%c", &aaddr, &c) == 1)
6602     {
6603         if (aaddr > regs->mainlim)
6604         {
6605             RELEASE_INTLOCK(NULL);
6606             logmsg( _("HHCPN130E Invalid frame address %8.8X\n"), aaddr );
6607             return -1;
6608         }
6609         STORAGE_KEY(aaddr, regs) &= ~(STORKEY_BADFRM);
6610         if (!oneorzero)
6611             STORAGE_KEY(aaddr, regs) |= STORKEY_BADFRM;
6612         RELEASE_INTLOCK(NULL);
6613         logmsg( _("HHCPN131I Frame %8.8X marked %s\n"), aaddr,
6614                 oneorzero ? _("usable") : _("unusable")
6615             );
6616         return 0;
6617     }
6618 
6619 #ifdef OPTION_CKD_KEY_TRACING
6620 
6621     // t+ckd and t-ckd commands - turn CKD_KEY tracing on/off
6622 
6623     if ((cmd[0] == 't') && (strcasecmp(cmd+2, "ckd") == 0))
6624     {
6625         for (dev = sysblk.firstdev; dev != NULL; dev = dev->nextdev)
6626         {
6627             if (dev->devchar[10] == 0x20)
6628                 dev->ckdkeytrace = oneorzero;
6629         }
6630         RELEASE_INTLOCK(NULL);
6631         logmsg( _("HHCPN134I CKD KEY trace is now %s\n"), onoroff );
6632         return 0;
6633     }
6634 
6635 #endif
6636 
6637     // t+devn and t-devn commands - turn CCW tracing on/off
6638     // s+devn and s-devn commands - turn CCW stepping on/off
6639 
6640     if ((cmd[0] == 't' || cmd[0] == 's')
6641         && parse_single_devnum_silent(&cmd[2],&lcss,&devnum)==0 )
6642     {
6643         dev = find_device_by_devnum (lcss, devnum);
6644         if (dev == NULL)
6645         {
6646             devnotfound_msg(lcss,devnum);
6647             RELEASE_INTLOCK(NULL);
6648             return -1;
6649         }
6650 
6651         if (cmd[0] == 't')
6652         {
6653             dev->ccwtrace = oneorzero;
6654             logmsg( _("HHCPN136I CCW tracing is now %s for device %d:%4.4X\n"),
6655                 onoroff, lcss, devnum
6656                 );
6657         } else {
6658             dev->ccwstep = oneorzero;
6659             logmsg( _("HHCPN137I CCW stepping is now %s for device %d:%4.4X\n"),
6660                 onoroff, lcss, devnum
6661                 );
6662         }
6663         RELEASE_INTLOCK(NULL);
6664         return 0;
6665     }
6666 
6667     RELEASE_INTLOCK(NULL);
6668     logmsg( _("HHCPN138E Unrecognized +/- command.\n") );
6669     return -1;
6670 }
6671 
aea_mode_str(BYTE mode)6672 static inline char *aea_mode_str(BYTE mode)
6673 {
6674 static char *name[] = { "DAT-Off", "Primary", "AR", "Secondary", "Home",
6675 0, 0, 0, "PER/DAT-Off", "PER/Primary", "PER/AR", "PER/Secondary", "PER/Home" };
6676 
6677     return name[(mode & 0x0f) | ((mode & 0xf0) ? 8 : 0)];
6678 }
6679 
6680 
6681 /*-------------------------------------------------------------------*/
6682 /* aea - display aea values                                          */
6683 /*-------------------------------------------------------------------*/
aea_cmd(int argc,char * argv[],char * cmdline)6684 int aea_cmd(int argc, char *argv[], char *cmdline)
6685 {
6686     int     i;                          /* Index                     */
6687     REGS   *regs;
6688 
6689     UNREFERENCED(argc);
6690     UNREFERENCED(argv);
6691     UNREFERENCED(cmdline);
6692 
6693     obtain_lock(&sysblk.cpulock[sysblk.pcpu]);
6694 
6695     if (!IS_CPU_ONLINE(sysblk.pcpu))
6696     {
6697         release_lock(&sysblk.cpulock[sysblk.pcpu]);
6698         logmsg( _("HHCPN160W CPU%4.4X not configured\n"), sysblk.pcpu);
6699         return 0;
6700     }
6701     regs = sysblk.regs[sysblk.pcpu];
6702 
6703     logmsg ("aea mode   %s\n",aea_mode_str(regs->aea_mode));
6704 
6705     logmsg ("aea ar    ");
6706     for (i = 16; i < 21; i++)
6707          if(regs->aea_ar[i] > 0)
6708             logmsg(" %2.2x",regs->aea_ar[i]);
6709         else
6710             logmsg(" %2d",regs->aea_ar[i]);
6711     for (i = 0; i < 16; i++)
6712          if(regs->aea_ar[i] > 0)
6713             logmsg(" %2.2x",regs->aea_ar[i]);
6714         else
6715             logmsg(" %2d",regs->aea_ar[i]);
6716     logmsg ("\n");
6717 
6718     logmsg ("aea common            ");
6719     if(regs->aea_common[32] > 0)
6720         logmsg(" %2.2x",regs->aea_common[32]);
6721     else
6722         logmsg(" %2d",regs->aea_common[32]);
6723     for (i = 0; i < 16; i++)
6724         if(regs->aea_common[i] > 0)
6725             logmsg(" %2.2x",regs->aea_common[i]);
6726         else
6727             logmsg(" %2d",regs->aea_common[i]);
6728     logmsg ("\n");
6729 
6730     logmsg ("aea cr[1]  %16.16" I64_FMT "x\n    cr[7]  %16.16" I64_FMT "x\n"
6731             "    cr[13] %16.16" I64_FMT "x\n",
6732             regs->CR_G(1),regs->CR_G(7),regs->CR_G(13));
6733 
6734     logmsg ("    cr[r]  %16.16" I64_FMT "x\n",
6735             regs->CR_G(CR_ASD_REAL));
6736 
6737     for(i = 0; i < 16; i++)
6738         if(regs->aea_ar[i] > 15)
6739             logmsg ("    alb[%d] %16.16" I64_FMT "x\n",
6740                     regs->cr[CR_ALB_OFFSET + i]);
6741 
6742     if (regs->sie_active)
6743     {
6744         regs = regs->guestregs;
6745 
6746         logmsg ("aea SIE\n");
6747         logmsg ("aea mode   %s\n",aea_mode_str(regs->aea_mode));
6748 
6749         logmsg ("aea ar    ");
6750         for (i = 16; i < 21; i++)
6751             if(regs->aea_ar[i] > 0)
6752                 logmsg(" %2.2x",regs->aea_ar[i]);
6753             else
6754                 logmsg(" %2d",regs->aea_ar[i]);
6755         for (i = 0; i < 16; i++)
6756             if(regs->aea_ar[i] > 0)
6757                 logmsg(" %2.2x",regs->aea_ar[i]);
6758             else
6759                 logmsg(" %2d",regs->aea_ar[i]);
6760         logmsg ("\n");
6761 
6762         logmsg ("aea common            ");
6763         if(regs->aea_common[32] > 0)
6764             logmsg(" %2.2x",regs->aea_common[32]);
6765         else
6766             logmsg(" %2d",regs->aea_common[32]);
6767         for (i = 0; i < 16; i++)
6768         if(regs->aea_common[i] > 0)
6769             logmsg(" %2.2x",regs->aea_common[i]);
6770         else
6771             logmsg(" %2d",regs->aea_common[i]);
6772         logmsg ("\n");
6773 
6774         logmsg ("aea cr[1]  %16.16" I64_FMT "x\n    cr[7]  %16.16" I64_FMT "x\n"
6775                 "    cr[13] %16.16" I64_FMT "x\n",
6776                 regs->CR_G(1),regs->CR_G(7),regs->CR_G(13));
6777 
6778         logmsg ("    cr[r]  %16.16" I64_FMT "x\n",
6779                 regs->CR_G(CR_ASD_REAL));
6780 
6781         for(i = 0; i < 16; i++)
6782             if(regs->aea_ar[i] > 15)
6783                 logmsg ("    alb[%d] %16.16" I64_FMT "x\n",
6784                         regs->cr[CR_ALB_OFFSET + i]);
6785     }
6786 
6787     release_lock (&sysblk.cpulock[sysblk.pcpu]);
6788 
6789     return 0;
6790 }
6791 
6792 
6793 /*-------------------------------------------------------------------*/
6794 /* aia - display aia values                                          */
6795 /*-------------------------------------------------------------------*/
aia_cmd(int argc,char * argv[],char * cmdline)6796 DLL_EXPORT int aia_cmd(int argc, char *argv[], char *cmdline)
6797 {
6798     REGS   *regs;
6799 
6800     UNREFERENCED(argc);
6801     UNREFERENCED(argv);
6802     UNREFERENCED(cmdline);
6803 
6804     obtain_lock(&sysblk.cpulock[sysblk.pcpu]);
6805 
6806     if (!IS_CPU_ONLINE(sysblk.pcpu))
6807     {
6808         release_lock(&sysblk.cpulock[sysblk.pcpu]);
6809         logmsg( _("HHCPN160W CPU%4.4X not configured\n"), sysblk.pcpu);
6810         return 0;
6811     }
6812     regs = sysblk.regs[sysblk.pcpu];
6813 
6814     logmsg ("AIV %16.16" I64_FMT "x aip %p ip %p aie %p aim %p\n",
6815             regs->aiv,regs->aip,regs->ip,regs->aie,(BYTE *)regs->aim);
6816 
6817     if (regs->sie_active)
6818     {
6819         regs = regs->guestregs;
6820         logmsg ("SIE:\n");
6821         logmsg ("AIV %16.16" I64_FMT "x aip %p ip %p aie %p\n",
6822             regs->aiv,regs->aip,regs->ip,regs->aie);
6823     }
6824 
6825     release_lock (&sysblk.cpulock[sysblk.pcpu]);
6826 
6827     return 0;
6828 }
6829 
6830 
6831 /*-------------------------------------------------------------------*/
6832 /* tlb - display tlb table                                           */
6833 /*-------------------------------------------------------------------*/
6834 /*                                                                   */
6835 /* NOTES:                                                            */
6836 /*   The "tlbid" field is part of TLB_VADDR so it must be extracted  */
6837 /*   whenever it's used or displayed. The TLB_VADDR does not contain */
6838 /*   all of the effective address bits so they are created on-the-fly*/
6839 /*   with (i << shift) The "main" field of the tlb contains an XOR   */
6840 /*   hash of effective address. So MAINADDR() macro is used to remove*/
6841 /*   the hash before it's displayed.                                 */
6842 /*                                                                   */
tlb_cmd(int argc,char * argv[],char * cmdline)6843 int tlb_cmd(int argc, char *argv[], char *cmdline)
6844 {
6845     int     i;                          /* Index                     */
6846     int     shift;                      /* Number of bits to shift   */
6847     int     bytemask;                   /* Byte mask                 */
6848     U64     pagemask;                   /* Page mask                 */
6849     int     matches = 0;                /* Number aeID matches       */
6850     REGS   *regs;
6851 
6852     UNREFERENCED(argc);
6853     UNREFERENCED(argv);
6854     UNREFERENCED(cmdline);
6855 
6856     obtain_lock(&sysblk.cpulock[sysblk.pcpu]);
6857 
6858     if (!IS_CPU_ONLINE(sysblk.pcpu))
6859     {
6860         release_lock(&sysblk.cpulock[sysblk.pcpu]);
6861         logmsg( _("HHCPN160W CPU%4.4X not configured\n"), sysblk.pcpu);
6862         return 0;
6863     }
6864     regs = sysblk.regs[sysblk.pcpu];
6865     shift = regs->arch_mode == ARCH_370 ? 11 : 12;
6866     bytemask = regs->arch_mode == ARCH_370 ? 0x1FFFFF : 0x3FFFFF;
6867     pagemask = regs->arch_mode == ARCH_370 ? 0x00E00000 :
6868                regs->arch_mode == ARCH_390 ? 0x7FC00000 :
6869                                      0xFFFFFFFFFFC00000ULL;
6870 
6871     logmsg ("tlbID 0x%6.6x mainstor %p\n",regs->tlbID,regs->mainstor);
6872     logmsg ("  ix              asd            vaddr              pte   id c p r w ky       main\n");
6873     for (i = 0; i < TLBN; i++)
6874     {
6875         logmsg("%s%3.3x %16.16" I64_FMT "x %16.16" I64_FMT "x %16.16" I64_FMT "x %4.4x %1d %1d %1d %1d %2.2x %8.8x\n",
6876          ((regs->tlb.TLB_VADDR_G(i) & bytemask) == regs->tlbID ? "*" : " "),
6877          i,regs->tlb.TLB_ASD_G(i),
6878          ((regs->tlb.TLB_VADDR_G(i) & pagemask) | (i << shift)),
6879          regs->tlb.TLB_PTE_G(i),(int)(regs->tlb.TLB_VADDR_G(i) & bytemask),
6880          regs->tlb.common[i],regs->tlb.protect[i],
6881          (regs->tlb.acc[i] & ACC_READ) != 0,(regs->tlb.acc[i] & ACC_WRITE) != 0,
6882          regs->tlb.skey[i],
6883          MAINADDR(regs->tlb.main[i],
6884                   ((regs->tlb.TLB_VADDR_G(i) & pagemask) | (i << shift)))
6885                   - regs->mainstor);
6886         matches += ((regs->tlb.TLB_VADDR(i) & bytemask) == regs->tlbID);
6887     }
6888     logmsg("%d tlbID matches\n", matches);
6889 
6890     if (regs->sie_active)
6891     {
6892         regs = regs->guestregs;
6893         shift = regs->guestregs->arch_mode == ARCH_370 ? 11 : 12;
6894         bytemask = regs->arch_mode == ARCH_370 ? 0x1FFFFF : 0x3FFFFF;
6895         pagemask = regs->arch_mode == ARCH_370 ? 0x00E00000 :
6896                    regs->arch_mode == ARCH_390 ? 0x7FC00000 :
6897                                          0xFFFFFFFFFFC00000ULL;
6898 
6899         logmsg ("\nSIE: tlbID 0x%4.4x mainstor %p\n",regs->tlbID,regs->mainstor);
6900         logmsg ("  ix              asd            vaddr              pte   id c p r w ky       main\n");
6901         for (i = matches = 0; i < TLBN; i++)
6902         {
6903             logmsg("%s%3.3x %16.16" I64_FMT "x %16.16" I64_FMT "x %16.16" I64_FMT "x %4.4x %1d %1d %1d %1d %2.2x %p\n",
6904              ((regs->tlb.TLB_VADDR_G(i) & bytemask) == regs->tlbID ? "*" : " "),
6905              i,regs->tlb.TLB_ASD_G(i),
6906              ((regs->tlb.TLB_VADDR_G(i) & pagemask) | (i << shift)),
6907              regs->tlb.TLB_PTE_G(i),(int)(regs->tlb.TLB_VADDR_G(i) & bytemask),
6908              regs->tlb.common[i],regs->tlb.protect[i],
6909              (regs->tlb.acc[i] & ACC_READ) != 0,(regs->tlb.acc[i] & ACC_WRITE) != 0,
6910              regs->tlb.skey[i],
6911              MAINADDR(regs->tlb.main[i],
6912                      ((regs->tlb.TLB_VADDR_G(i) & pagemask) | (i << shift)))
6913                     - regs->mainstor);
6914             matches += ((regs->tlb.TLB_VADDR(i) & bytemask) == regs->tlbID);
6915         }
6916         logmsg("SIE: %d tlbID matches\n", matches);
6917     }
6918 
6919     release_lock (&sysblk.cpulock[sysblk.pcpu]);
6920 
6921     return 0;
6922 }
6923 
6924 
6925 #if defined(SIE_DEBUG_PERFMON)
6926 /*-------------------------------------------------------------------*/
6927 /* spm - SIE performance monitor table                               */
6928 /*-------------------------------------------------------------------*/
spm_cmd(int argc,char * argv[],char * cmdline)6929 int spm_cmd(int argc, char *argv[], char *cmdline)
6930 {
6931     UNREFERENCED(argc);
6932     UNREFERENCED(argv);
6933     UNREFERENCED(cmdline);
6934 
6935     sie_perfmon_disp();
6936 
6937     return 0;
6938 }
6939 #endif
6940 
6941 
6942 #if defined(_FEATURE_SYSTEM_CONSOLE)
6943 /*-------------------------------------------------------------------*/
6944 /* ssd - signal shutdown command                                     */
6945 /*-------------------------------------------------------------------*/
ssd_cmd(int argc,char * argv[],char * cmdline)6946 int ssd_cmd(int argc, char *argv[], char *cmdline)
6947 {
6948     UNREFERENCED(argc);
6949     UNREFERENCED(argv);
6950     UNREFERENCED(cmdline);
6951 
6952     signal_quiesce(0, 0);
6953 
6954     return 0;
6955 }
6956 #endif
6957 
6958 
6959 #if defined(OPTION_COUNTING)
6960 /*-------------------------------------------------------------------*/
6961 /* count - display counts                                            */
6962 /*-------------------------------------------------------------------*/
count_cmd(int argc,char * argv[],char * cmdline)6963 int count_cmd(int argc, char *argv[], char *cmdline)
6964 {
6965     int     i;                          /* Index                     */
6966     U64     instcount = 0;              /* Instruction count         */
6967 
6968     UNREFERENCED(argc);
6969     UNREFERENCED(argv);
6970     UNREFERENCED(cmdline);
6971 
6972     if (argc > 1 && strcasecmp(argv[1],"clear") == 0)
6973     {
6974         for (i = 0; i < MAX_CPU; i++)
6975             if (IS_CPU_ONLINE(i))
6976                 sysblk.regs[i]->instcount = sysblk.regs[i]->prevcount = 0;
6977         for (i = 0; i < OPTION_COUNTING; i++)
6978             sysblk.count[i] = 0;
6979     }
6980     for (i = 0; i < MAX_CPU; i++)
6981         if (IS_CPU_ONLINE(i))
6982             instcount += INSTCOUNT(sysblk.regs[i]);
6983     logmsg ("  i: %12" I64_FMT "d\n", instcount);
6984 
6985     for (i = 0; i < OPTION_COUNTING; i++)
6986         logmsg ("%3d: %12" I64_FMT "d\n", i, sysblk.count[i]);
6987 
6988     return 0;
6989 }
6990 #endif
6991 
6992 
6993 #if defined(OPTION_DYNAMIC_LOAD)
6994 /*-------------------------------------------------------------------*/
6995 /* ldmod - load a module                                             */
6996 /*-------------------------------------------------------------------*/
ldmod_cmd(int argc,char * argv[],char * cmdline)6997 int ldmod_cmd(int argc, char *argv[], char *cmdline)
6998 {
6999     int     i;                          /* Index                     */
7000 
7001     UNREFERENCED(cmdline);
7002 
7003     if(argc <= 1)
7004     {
7005         logmsg("Usage: %s <module>\n",argv[0]);
7006         return -1;
7007     }
7008 
7009     for(i = 1; i < argc; i++)
7010     {
7011         logmsg(_("HHCHD100I Loading %s ...\n"),argv[i]);
7012         if(!hdl_load(argv[i], 0))
7013             logmsg(_("HHCHD101I Module %s loaded\n"),argv[i]);
7014     }
7015 
7016     return 0;
7017 }
7018 
7019 
7020 /*-------------------------------------------------------------------*/
7021 /* rmmod - delete a module                                           */
7022 /*-------------------------------------------------------------------*/
rmmod_cmd(int argc,char * argv[],char * cmdline)7023 int rmmod_cmd(int argc, char *argv[], char *cmdline)
7024 {
7025     int     i;                          /* Index                     */
7026 
7027     UNREFERENCED(cmdline);
7028 
7029     if(argc <= 1)
7030     {
7031         logmsg("Usage: %s <module>\n",argv[0]);
7032         return -1;
7033     }
7034 
7035     for(i = 1; i < argc; i++)
7036     {
7037         logmsg(_("HHCHD102I Unloading %s ...\n"),argv[i]);
7038         if(!hdl_dele(argv[i]))
7039             logmsg(_("HHCHD103I Module %s unloaded\n"),argv[i]);
7040     }
7041 
7042     return 0;
7043 }
7044 
7045 
7046 /*-------------------------------------------------------------------*/
7047 /* lsmod - list dynamic modules                                      */
7048 /*-------------------------------------------------------------------*/
lsmod_cmd(int argc,char * argv[],char * cmdline)7049 int lsmod_cmd(int argc, char *argv[], char *cmdline)
7050 {
7051     UNREFERENCED(cmdline);
7052     UNREFERENCED(argc);
7053     UNREFERENCED(argv);
7054 
7055     hdl_list(HDL_LIST_DEFAULT);
7056 
7057     return 0;
7058 }
7059 
7060 
7061 /*-------------------------------------------------------------------*/
7062 /* lsdep - list module dependencies                                  */
7063 /*-------------------------------------------------------------------*/
lsdep_cmd(int argc,char * argv[],char * cmdline)7064 int lsdep_cmd(int argc, char *argv[], char *cmdline)
7065 {
7066     UNREFERENCED(cmdline);
7067     UNREFERENCED(argc);
7068     UNREFERENCED(argv);
7069 
7070     hdl_dlst();
7071 
7072     return 0;
7073 }
7074 
7075 
7076 /*-------------------------------------------------------------------*/
7077 /* modpath - set module path                                         */
7078 /*-------------------------------------------------------------------*/
modpath_cmd(int argc,char * argv[],char * cmdline)7079 int modpath_cmd(int argc, char *argv[], char *cmdline)
7080 {
7081     UNREFERENCED(cmdline);
7082 
7083     if(argc <= 1)
7084     {
7085         logmsg("Usage: %s <path>\n",argv[0]);
7086         return -1;
7087     }
7088     else
7089     {
7090         hdl_setpath(strdup(argv[1]));
7091         return 0;
7092     }
7093 }
7094 
7095 #endif /*defined(OPTION_DYNAMIC_LOAD)*/
7096 
7097 
7098 #ifdef FEATURE_ECPSVM
7099 /*-------------------------------------------------------------------*/
7100 /* evm - ECPS:VM command                                             */
7101 /*-------------------------------------------------------------------*/
evm_cmd_1(int argc,char * argv[],char * cmdline)7102 int evm_cmd_1(int argc, char *argv[], char *cmdline)
7103 {
7104     UNREFERENCED(cmdline);
7105     UNREFERENCED(argc);
7106     UNREFERENCED(argv);
7107 
7108     logmsg(_("HHCPN150W evm command is deprecated. Use \"ecpsvm\" instead\n"));
7109     ecpsvm_command(argc,argv);
7110     return 0;
7111 }
7112 
7113 
7114 /*-------------------------------------------------------------------*/
7115 /* evm - ECPS:VM command                                             */
7116 /*-------------------------------------------------------------------*/
evm_cmd(int argc,char * argv[],char * cmdline)7117 int evm_cmd(int argc, char *argv[], char *cmdline)
7118 {
7119     UNREFERENCED(cmdline);
7120     UNREFERENCED(argc);
7121     UNREFERENCED(argv);
7122 
7123     ecpsvm_command(argc,argv);
7124     return 0;
7125 }
7126 #endif
7127 
7128 
7129 /*-------------------------------------------------------------------*/
7130 /* herclogo - Set the hercules logo file                             */
7131 /*-------------------------------------------------------------------*/
herclogo_cmd(int argc,char * argv[],char * cmdline)7132 int herclogo_cmd(int argc,char *argv[], char *cmdline)
7133 {
7134     UNREFERENCED(cmdline);
7135     if(argc<2)
7136     {
7137         sysblk.logofile=NULL;
7138         clearlogo();
7139         return 0;
7140     }
7141     return readlogo(argv[1]);
7142 }
7143 
7144 
7145 /*-------------------------------------------------------------------*/
7146 /* sizeof - Display sizes of various structures/tables               */
7147 /*-------------------------------------------------------------------*/
sizeof_cmd(int argc,char * argv[],char * cmdline)7148 int sizeof_cmd(int argc, char *argv[], char *cmdline)
7149 {
7150     UNREFERENCED(cmdline);
7151     UNREFERENCED(argc);
7152     UNREFERENCED(argv);
7153 
7154     logmsg(_("HHCPN161I (void *) ..........%7d\n"),sizeof(void *));
7155     logmsg(_("HHCPN161I (unsigned int) ....%7d\n"),sizeof(unsigned int));
7156     logmsg(_("HHCPN161I (long) ............%7d\n"),sizeof(long));
7157     logmsg(_("HHCPN161I (long long) .......%7d\n"),sizeof(long long));
7158     logmsg(_("HHCPN161I (size_t) ..........%7d\n"),sizeof(size_t));
7159     logmsg(_("HHCPN161I (off_t) ...........%7d\n"),sizeof(off_t));
7160     logmsg(_("HHCPN161I SYSBLK ............%7d\n"),sizeof(SYSBLK));
7161     logmsg(_("HHCPN161I REGS ..............%7d\n"),sizeof(REGS));
7162     logmsg(_("HHCPN161I REGS (copy len) ...%7d\n"),sysblk.regs_copy_len);
7163     logmsg(_("HHCPN161I PSW ...............%7d\n"),sizeof(PSW));
7164     logmsg(_("HHCPN161I DEVBLK ............%7d\n"),sizeof(DEVBLK));
7165     logmsg(_("HHCPN161I TLB entry .........%7d\n"),sizeof(TLB)/TLBN);
7166     logmsg(_("HHCPN161I TLB table .........%7d\n"),sizeof(TLB));
7167     logmsg(_("HHCPN161I FILENAME_MAX ......%7d\n"),FILENAME_MAX);
7168     logmsg(_("HHCPN161I PATH_MAX ..........%7d\n"),PATH_MAX);
7169     logmsg(_("HHCPN161I CPU_BITMAP ........%7d\n"),sizeof(CPU_BITMAP));
7170     logmsg(_("HHCPN161I FD_SETSIZE ........%7d\n"),FD_SETSIZE);
7171     return 0;
7172 }
7173 
7174 
7175 #if defined(OPTION_HAO)
7176 /*-------------------------------------------------------------------*/
7177 /* hao - Hercules Automatic Operator                                 */
7178 /*-------------------------------------------------------------------*/
hao_cmd(int argc,char * argv[],char * cmdline)7179 int hao_cmd(int argc, char *argv[], char *cmdline)
7180 {
7181     UNREFERENCED(argc);
7182     UNREFERENCED(argv);
7183     hao_command(cmdline);   /* (actual HAO code is in module hao.c) */
7184     return 0;
7185 }
7186 #endif /* defined(OPTION_HAO) */
7187 
7188 
7189 /*-------------------------------------------------------------------*/
7190 /* conkpalv - set console session TCP keep-alive values              */
7191 /*-------------------------------------------------------------------*/
conkpalv_cmd(int argc,char * argv[],char * cmdline)7192 int conkpalv_cmd( int argc, char *argv[], char *cmdline )
7193 {
7194     int idle, intv, cnt;
7195 
7196     UNREFERENCED( cmdline );
7197 
7198     idle = sysblk.kaidle;
7199     intv = sysblk.kaintv;
7200     cnt  = sysblk.kacnt;
7201 
7202     if(argc < 2)
7203         logmsg( _("HHCPN190I Keep-alive = (%d,%d,%d)\n"),idle,intv,cnt);
7204     else
7205     {
7206         if (argc == 2 && parse_conkpalv( argv[1], &idle, &intv, &cnt ) == 0)
7207         {
7208             sysblk.kaidle = idle;
7209             sysblk.kaintv = intv;
7210             sysblk.kacnt  = cnt;
7211         }
7212         else
7213         {
7214             logmsg( _("HHCPN192E Invalid format. Enter \"help conkpalv\" for help.\n"));
7215             return -1;
7216         }
7217     }
7218     return 0;
7219 }
7220 
7221 
7222 /*-------------------------------------------------------------------*/
7223 /* traceopt - perform display_inst traditionally or new              */
7224 /*-------------------------------------------------------------------*/
traceopt_cmd(int argc,char * argv[],char * cmdline)7225 int traceopt_cmd(int argc, char *argv[], char *cmdline)
7226 {
7227     UNREFERENCED(cmdline);
7228     if (argc > 1)
7229     {
7230         if (strcasecmp(argv[1], "traditional") == 0)
7231         {
7232             sysblk.showregsfirst = 0;
7233             sysblk.showregsnone = 0;
7234         }
7235         if (strcasecmp(argv[1], "regsfirst") == 0)
7236         {
7237             sysblk.showregsfirst = 1;
7238             sysblk.showregsnone = 0;
7239         }
7240         if (strcasecmp(argv[1], "noregs") == 0)
7241         {
7242             sysblk.showregsfirst = 0;
7243             sysblk.showregsnone = 1;
7244         }
7245     }
7246     else
7247         logmsg(_("HHCPN162I Hercules instruction trace displayed in %s mode\n"),
7248             sysblk.showregsnone ? _("noregs") :
7249             sysblk.showregsfirst ? _("regsfirst") :
7250                             _("traditional"));
7251     return 0;
7252 }
7253 
7254 
7255 #ifdef OPTION_CMDTGT
7256 /*-------------------------------------------------------------------*/
7257 /* cmdtgt - Specify the command target                               */
7258 /*-------------------------------------------------------------------*/
cmdtgt_cmd(int argc,char * argv[],char * cmdline)7259 int cmdtgt_cmd(int argc, char *argv[], char *cmdline)
7260 {
7261   int print = 1;
7262 
7263   UNREFERENCED(cmdline);
7264   if(argc == 2)
7265   {
7266     if(!strcasecmp(argv[1], "herc"))
7267       sysblk.cmdtgt = 0;
7268     else if(!strcasecmp(argv[1], "scp"))
7269       sysblk.cmdtgt = 1;
7270     else if(!strcasecmp(argv[1], "pscp"))
7271       sysblk.cmdtgt = 2;
7272     else if(!strcasecmp(argv[1], "?"))
7273       ;
7274     else
7275       print = 0;
7276   }
7277   else
7278     print = 0;
7279 
7280   if(print)
7281   {
7282     switch(sysblk.cmdtgt)
7283     {
7284       case 0:
7285       {
7286         logmsg("cmdtgt: Commands are sent to hercules\n");
7287         break;
7288       }
7289       case 1:
7290       {
7291         logmsg("cmdtgt: Commands are sent to scp\n");
7292         break;
7293       }
7294       case 2:
7295       {
7296         logmsg("cmdtgt: Commands are sent as priority messages to scp\n");
7297         break;
7298       }
7299     }
7300   }
7301   else
7302     logmsg("cmdtgt: Use cmdtgt [herc | scp | pscp | ?]\n");
7303 
7304   return 0;
7305 }
7306 
7307 
7308 /*-------------------------------------------------------------------*/
7309 /* scp - Send scp command in any mode                                */
7310 /*-------------------------------------------------------------------*/
scp_cmd(int argc,char * argv[],char * cmdline)7311 int scp_cmd(int argc, char *argv[], char *cmdline)
7312 {
7313   UNREFERENCED(argv);
7314   if(argc == 1)
7315     scp_command(" ", 0);
7316   else
7317     scp_command(&cmdline[4], 0);
7318   return 0;
7319 }
7320 
7321 
7322 /*-------------------------------------------------------------------*/
7323 /* pscp - Send a priority message in any mode                        */
7324 /*-------------------------------------------------------------------*/
prioscp_cmd(int argc,char * argv[],char * cmdline)7325 int prioscp_cmd(int argc, char *argv[], char *cmdline)
7326 {
7327   UNREFERENCED(argv);
7328   if(argc == 1)
7329     scp_command(" ", 1);
7330   else
7331     scp_command(&cmdline[5], 1);
7332   return 0;
7333 }
7334 
7335 
7336 /*-------------------------------------------------------------------*/
7337 /* herc - Send a Hercules command in any mode                        */
7338 /*-------------------------------------------------------------------*/
herc_cmd(int argc,char * argv[],char * cmdline)7339 int herc_cmd(int argc, char *argv[], char *cmdline)
7340 {
7341   UNREFERENCED(argv);
7342   if(argc == 1)
7343     ProcessPanelCommand(" ");
7344   else
7345     ProcessPanelCommand(&cmdline[5]);
7346   return 0;
7347 }
7348 #endif // OPTION_CMDTGT
7349 
7350 
7351 /* PATCH ISW20030220 - Script command support */
7352 static int scr_recursion=0;     /* Recursion count (set to 0) */
7353 static int scr_aborted=0;          /* Script abort flag */
7354 static int scr_uaborted=0;          /* Script user abort flag */
7355 TID scr_tid=0;
scr_recursion_level()7356 int scr_recursion_level() { return scr_recursion; }
7357 
7358 /*-------------------------------------------------------------------*/
7359 /* cancel script command                                             */
7360 /*-------------------------------------------------------------------*/
cscript_cmd(int argc,char * argv[],char * cmdline)7361 int cscript_cmd(int argc, char *argv[], char *cmdline)
7362 {
7363     UNREFERENCED(cmdline);
7364     UNREFERENCED(argc);
7365     UNREFERENCED(argv);
7366     if(scr_tid!=0)
7367     {
7368         scr_uaborted=1;
7369     }
7370     return 0;
7371 }
7372 
7373 
7374 /*-------------------------------------------------------------------*/
7375 /* script command                                                    */
7376 /*-------------------------------------------------------------------*/
script_cmd(int argc,char * argv[],char * cmdline)7377 int script_cmd(int argc, char *argv[], char *cmdline)
7378 {
7379 
7380     int i;
7381 
7382     UNREFERENCED(cmdline);
7383     if(argc<2)
7384     {
7385         logmsg(_("HHCPN996E The script command requires a filename\n"));
7386         return 1;
7387     }
7388     if(scr_tid==0)
7389     {
7390         scr_tid=thread_id();
7391         scr_aborted=0;
7392         scr_uaborted=0;
7393     }
7394     else
7395     {
7396         if(scr_tid!=thread_id())
7397         {
7398             logmsg(_("HHCPN997E Only 1 script may be invoked from the panel at any time\n"));
7399             return 1;
7400         }
7401     }
7402 
7403     for(i=1;i<argc;i++)
7404     {
7405         process_script_file(argv[i],0);
7406     }
7407     return(0);
7408 }
7409 
7410 
7411 
script_test_userabort()7412 void script_test_userabort()
7413 {
7414         if(scr_uaborted)
7415         {
7416            logmsg(_("HHCPN998E Script aborted : user cancel request\n"));
7417            scr_aborted=1;
7418         }
7419 }
7420 
7421 
7422 
process_script_file(char * script_name,int isrcfile)7423 int process_script_file(char *script_name,int isrcfile)
7424 {
7425 FILE   *scrfp;                          /* RC file pointer           */
7426 size_t  scrbufsize = 1024;              /* Size of RC file  buffer   */
7427 char   *scrbuf = NULL;                  /* RC file input buffer      */
7428 int     scrlen;                         /* length of RC file record  */
7429 int     scr_pause_amt = 0;              /* seconds to pause RC file  */
7430 char   *p;                              /* (work)                    */
7431 char    pathname[MAX_PATH];             /* (work)                    */
7432 
7433     /* Check the recursion level - if it exceeds a certain amount
7434        abort the script stack
7435     */
7436     if(scr_recursion>=10)
7437     {
7438         logmsg(_("HHCPN998E Script aborted : Script recursion level exceeded\n"));
7439         scr_aborted=1;
7440         return 0;
7441     }
7442 
7443     /* Open RC file */
7444 
7445     hostpath(pathname, script_name, sizeof(pathname));
7446 
7447     if (!(scrfp = fopen(pathname, "r")))
7448     {
7449         int save_errno = errno;
7450 
7451         if (!isrcfile)
7452         {
7453             if (ENOENT != errno)
7454                 logmsg(_("HHCPN007E Script file \"%s\" open failed: %s\n"),
7455                     script_name, strerror(errno));
7456             else
7457                 logmsg(_("HHCPN995E Script file \"%s\" not found\n"),
7458                     script_name);
7459         }
7460         else /* (this IS the .rc file...) */
7461         {
7462             if (ENOENT != errno)
7463                 logmsg(_("HHCPN007E Script file \"%s\" open failed: %s\n"),
7464                     script_name, strerror(errno));
7465         }
7466 
7467         errno = save_errno;
7468         return -1;
7469     }
7470 
7471     scr_recursion++;
7472 
7473     if(isrcfile)
7474     {
7475         logmsg(_("HHCPN008I Script file processing started using file \"%s\"\n"),
7476            script_name);
7477     }
7478 
7479     /* Obtain storage for the SCRIPT file buffer */
7480 
7481     if (!(scrbuf = malloc (scrbufsize)))
7482     {
7483         logmsg(_("HHCPN009E Script file buffer malloc failed: %s\n"),
7484             strerror(errno));
7485         fclose(scrfp);
7486         return 0;
7487     }
7488 
7489     for (; ;)
7490     {
7491         script_test_userabort();
7492         if(scr_aborted)
7493         {
7494            break;
7495         }
7496         /* Read a complete line from the SCRIPT file */
7497 
7498         if (!fgets(scrbuf, scrbufsize, scrfp)) break;
7499 
7500         /* Remove trailing whitespace */
7501 
7502         for (scrlen = strlen(scrbuf); scrlen && isspace(scrbuf[scrlen-1]); scrlen--);
7503         scrbuf[scrlen] = 0;
7504 
7505         /* Remove any # comments on the line before processing */
7506 
7507         if ((p = strchr(scrbuf,'#')) && p > scrbuf)
7508             do *p = 0; while (isspace(*--p) && p >= scrbuf);
7509 
7510         if (strncasecmp(scrbuf,"pause",5) == 0)
7511         {
7512             sscanf(scrbuf+5, "%d", &scr_pause_amt);
7513 
7514             if (scr_pause_amt < 0 || scr_pause_amt > 999)
7515             {
7516                 logmsg(_("HHCPN010W Ignoring invalid SCRIPT file pause "
7517                          "statement: %s\n"),
7518                          scrbuf+5);
7519                 continue;
7520             }
7521 
7522             logmsg (_("HHCPN011I Pausing SCRIPT file processing for %d "
7523                       "seconds...\n"),
7524                       scr_pause_amt);
7525             SLEEP(scr_pause_amt);
7526             logmsg (_("HHCPN012I Resuming SCRIPT file processing...\n"));
7527 
7528             continue;
7529         }
7530 
7531         /* Process the command */
7532 
7533         for (p = scrbuf; isspace(*p); p++);
7534 
7535         panel_command(p);
7536         script_test_userabort();
7537         if(scr_aborted)
7538         {
7539            break;
7540         }
7541     }
7542 
7543     if (feof(scrfp))
7544         logmsg (_("HHCPN013I EOF reached on SCRIPT file. Processing complete.\n"));
7545     else
7546     {
7547         if(!scr_aborted)
7548         {
7549            logmsg (_("HHCPN014E I/O error reading SCRIPT file: %s\n"),
7550                  strerror(errno));
7551         }
7552         else
7553         {
7554            logmsg (_("HHCPN999I Script \"%s\" aborted due to previous conditions\n"),
7555                script_name);
7556            scr_uaborted=1;
7557         }
7558     }
7559 
7560     fclose(scrfp);
7561     scr_recursion--;    /* Decrement recursion count */
7562     if(scr_recursion==0)
7563     {
7564       scr_aborted=0;    /* reset abort flag */
7565       scr_tid=0;    /* reset script thread id */
7566     }
7567 
7568     return 0;
7569 }
7570 /* END PATCH ISW20030220 */
7571