1 /* SCEDASD.C    (c) Copyright Jan Jaeger, 2001-2009                  */
2 /*              Service Control Element DASD I/O functions           */
3 
4 #include "hstdinc.h"
5 
6 #define _HENGINE_DLL_
7 
8 #include "hercules.h"
9 #include "opcode.h"
10 
11 #if !defined(_SCEDASD_C)
12 #define _SCEDASD_C
13 
14 static TID     scedio_tid;             /* Thread id of the i/o driver
15                                                                      */
16 static char *sce_basedir = NULL;
17 
18 
get_sce_dir()19 char *get_sce_dir()
20 {
21     return sce_basedir;
22 }
23 
24 
set_sce_dir(char * path)25 void set_sce_dir(char *path)
26 {
27 char realdir[MAX_PATH];
28 char tempdir[MAX_PATH];
29 
30     if(sce_basedir)
31     {
32         free(sce_basedir);
33         sce_basedir = NULL;
34     }
35 
36     if(!path)
37         sce_basedir = NULL;
38     else
39         if(!realpath(path,tempdir))
40         {
41             logmsg(_("HHCSC011E set_sce_dir: %s: %s\n"),path,strerror(errno));
42             sce_basedir = NULL;
43         }
44         else
45         {
46             hostpath(realdir, tempdir, sizeof(realdir));
47             strlcat(realdir,"/",sizeof(realdir));
48             sce_basedir = strdup(realdir);
49         }
50 }
51 
52 
set_sce_basedir(char * path)53 static char *set_sce_basedir(char *path)
54 {
55 char *basedir;
56 char realdir[MAX_PATH];
57 char tempdir[MAX_PATH];
58 
59     if(sce_basedir)
60     {
61         free(sce_basedir);
62         sce_basedir = NULL;
63     }
64 
65     if(!realpath(path,tempdir))
66     {
67         logmsg(_("HHCSC012E set_sce_basedir: %s: %s\n"),path,strerror(errno));
68         sce_basedir = NULL;
69         return NULL;
70     }
71     hostpath(realdir, tempdir, sizeof(realdir));
72 
73     if((basedir = strrchr(realdir,'/')))
74     {
75         *(++basedir) = '\0';
76         sce_basedir = strdup(realdir);
77         return (basedir = strrchr(path,'/')) ? ++basedir : path;
78     }
79     else
80     {
81         sce_basedir = NULL;
82         return path;
83     }
84 }
85 
86 
check_sce_filepath(const char * path,char * fullpath)87 static char *check_sce_filepath(const char *path, char *fullpath)
88 {
89 char temppath[MAX_PATH];
90 char tempreal[MAX_PATH];
91 
92     /* Return file access error if no basedir has been set */
93     if(!sce_basedir)
94     {
95         strlcpy(fullpath,path,sizeof(temppath));
96         errno = EACCES;
97         return NULL;
98     }
99 
100     /* Establish the full path of the file we are trying to access */
101     strlcpy(temppath,sce_basedir,sizeof(temppath));
102     strlcat(temppath,path,sizeof(temppath));
103 
104     if(!realpath(temppath,tempreal))
105     {
106         hostpath(fullpath, tempreal, sizeof(temppath));
107         if(strncmp( sce_basedir, fullpath, strlen(sce_basedir)))
108             errno = EACCES;
109         return NULL;
110     }
111 
112     hostpath(fullpath, tempreal, sizeof(temppath));
113     if(strncmp( sce_basedir, fullpath, strlen(sce_basedir)))
114     {
115         errno = EACCES;
116         return NULL;
117     }
118 
119     return fullpath;
120 }
121 
122 #endif /* !defined(_SCEDASD_C) */
123 
124 
125 /*-------------------------------------------------------------------*/
126 /* function load_hmc simulates the load from the service processor   */
127 /*   the filename pointed to is a descriptor file which has the      */
128 /*   following format:                                               */
129 /*                                                                   */
130 /*   '*' in col 1 is comment                                         */
131 /*   core image file followed by address where it should be loaded   */
132 /*                                                                   */
133 /* For example:                                                      */
134 /*                                                                   */
135 /* * Linux/390 cdrom boot image                                      */
136 /* boot_images/tapeipl.ikr 0x00000000                                */
137 /* boot_images/initrd 0x00800000                                     */
138 /* boot_images/parmfile 0x00010480                                   */
139 /*                                                                   */
140 /* The location of the image files is relative to the location of    */
141 /* the descriptor file.                         Jan Jaeger 10-11-01  */
142 /*                                                                   */
143 /*-------------------------------------------------------------------*/
ARCH_DEP(load_hmc)144 int ARCH_DEP(load_hmc) (char *fname, int cpu, int clear)
145 {
146 REGS   *regs;                           /* -> Regs                   */
147 FILE   *fp;
148 char    inputbuff[MAX_PATH];
149 char   *inputline;
150 char    filename[MAX_PATH];                 /* filename of image file    */
151 char    pathname[MAX_PATH];                 /* pathname of image file    */
152 U32     fileaddr;
153 int     rc = 0;                         /* Return codes (work)       */
154 
155     /* Get started */
156     if (ARCH_DEP(common_load_begin) (cpu, clear) != 0)
157         return -1;
158 
159     /* The actual IPL proper starts here... */
160 
161     regs = sysblk.regs[cpu];    /* Point to IPL CPU's registers */
162 
163     if(fname == NULL)                   /* Default ipl from DASD     */
164         fname = "HERCULES.ins";         /*   from HERCULES.ins       */
165 
166     hostpath(pathname, fname, sizeof(pathname));
167 
168     if(!(fname = set_sce_basedir(pathname)))
169         return -1;
170 
171     /* Construct and check full pathname */
172     if(!check_sce_filepath(fname,filename))
173     {
174         logmsg(_("HHCSC001E Load from %s failed: %s\n"),fname,strerror(errno));
175         return -1;
176     }
177 
178     fp = fopen(filename, "r");
179     if(fp == NULL)
180     {
181         logmsg(_("HHCSC002E Load from %s failed: %s\n"),fname,strerror(errno));
182         return -1;
183     }
184 
185     do
186     {
187         inputline = fgets(inputbuff,sizeof(inputbuff),fp);
188 
189 #if !defined(_MSVC_)
190         if(inputline && *inputline == 0x1a)
191             inputline = NULL;
192 #endif /*!defined(_MSVC_)*/
193 
194         if(inputline)
195         {
196             rc = sscanf(inputline,"%" MSTRING(MAX_PATH) "s %i",filename,&fileaddr);
197         }
198 
199         /* If no load address was found load to location zero */
200         if(inputline && rc < 2)
201             fileaddr = 0;
202 
203         if(inputline && rc > 0 && *filename != '*' && *filename != '#')
204         {
205             hostpath(pathname, filename, sizeof(pathname));
206 
207             /* Construct and check full pathname */
208             if(!check_sce_filepath(pathname,filename))
209             {
210                 logmsg(_("HHCSC003E Load from %s failed: %s\n"),pathname,strerror(errno));
211                 return -1;
212             }
213 
214             if( ARCH_DEP(load_main) (filename, fileaddr) < 0 )
215             {
216                 fclose(fp);
217                 HDC1(debug_cpu_state, regs);
218                 return -1;
219             }
220             sysblk.main_clear = sysblk.xpnd_clear = 0;
221         }
222     } while(inputline);
223     fclose(fp);
224 
225     /* Finish up... */
226     return ARCH_DEP(common_load_finish) (regs);
227 
228 } /* end function load_hmc */
229 
230 
231 /*-------------------------------------------------------------------*/
232 /* Function to Load (read) specified file into absolute main storage */
233 /*-------------------------------------------------------------------*/
ARCH_DEP(load_main)234 int ARCH_DEP(load_main) (char *fname, RADR startloc)
235 {
236 int fd;
237 int len;
238 int rc = 0;
239 RADR pageaddr;
240 U32  pagesize;
241 
242     fd = hopen(fname, O_RDONLY|O_BINARY);
243     if (fd < 0)
244     {
245         if(errno != ENOENT)
246             logmsg(_("HHCSC031E load_main: %s: %s\n"), fname, strerror(errno));
247         return fd;
248     }
249 
250     pagesize = PAGEFRAME_PAGESIZE - (startloc & PAGEFRAME_BYTEMASK);
251     pageaddr = startloc;
252 
253     for( ; ; ) {
254         if (pageaddr >= sysblk.mainsize)
255         {
256             logmsg(_("HHCSC032W load_main: terminated at end of mainstor\n"));
257             close(fd);
258             return rc;
259         }
260 
261         len = read(fd, sysblk.mainstor + pageaddr, pagesize);
262         if (len > 0)
263         {
264             STORAGE_KEY(pageaddr, &sysblk) |= STORKEY_REF|STORKEY_CHANGE;
265             rc += len;
266         }
267 
268         if (len < (int)pagesize)
269         {
270             close(fd);
271             return rc;
272         }
273 
274         pageaddr += PAGEFRAME_PAGESIZE;
275         pageaddr &= PAGEFRAME_PAGEMASK;
276         pagesize  = PAGEFRAME_PAGESIZE;
277     }
278 
279 } /* end function load_main */
280 
281 
282 #if defined(FEATURE_SCEDIO)
283 
284 /*-------------------------------------------------------------------*/
285 /* Function to write to a file on the service processor disk         */
286 /*-------------------------------------------------------------------*/
ARCH_DEP(write_file)287 static S64 ARCH_DEP(write_file)(char *fname, int mode, CREG sto, S64 size)
288 {
289 int fd, nwrite;
290 U64 totwrite = 0;
291 
292     fd = hopen(fname, mode |O_WRONLY|O_BINARY,
293             S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
294     if (fd < 0)
295     {
296         logmsg (_("HHCSC041E %s open error: %s\n"), fname, strerror(errno));
297         return -1;
298     }
299 
300 #if defined(FEATURE_ESAME)
301     sto &= ASCE_TO;
302 #else /*!defined(FEATURE_ESAME)*/
303     sto &= STD_STO;
304 #endif /*!defined(FEATURE_ESAME)*/
305 
306     for( ; size > 0 ; sto += sizeof(sto))
307     {
308 #if defined(FEATURE_ESAME)
309     DBLWRD *ste;
310 #else /*!defined(FEATURE_ESAME)*/
311     FWORD *ste;
312 #endif /*!defined(FEATURE_ESAME)*/
313     CREG pto, pti;
314 
315         /* Fetch segment table entry and calc Page Table Origin */
316         if( sto >= sysblk.mainsize)
317             goto eof;
318 #if defined(FEATURE_ESAME)
319         ste = (DBLWRD*)(sysblk.mainstor + sto);
320 #else /*!defined(FEATURE_ESAME)*/
321         ste = (FWORD*)(sysblk.mainstor + sto);
322 #endif /*!defined(FEATURE_ESAME)*/
323         FETCH_W(pto, ste);
324         STORAGE_KEY(sto, &sysblk) |= (STORKEY_REF);
325         if( pto & SEGTAB_INVALID )
326             goto eof;
327 #if defined(FEATURE_ESAME)
328         pto &= ZSEGTAB_PTO;
329 #else /*!defined(FEATURE_ESAME)*/
330         pto &= SEGTAB_PTO;
331 #endif /*!defined(FEATURE_ESAME)*/
332 
333         for(pti = 0; pti < 256 && size > 0; pti++, pto += sizeof(pto))
334         {
335 #if defined(FEATURE_ESAME)
336         DBLWRD *pte;
337 #else /*!defined(FEATURE_ESAME)*/
338         FWORD *pte;
339 #endif /*!defined(FEATURE_ESAME)*/
340         CREG pgo;
341         BYTE *page;
342 
343             /* Fetch Page Table Entry to get page origin */
344             if( pto >= sysblk.mainsize)
345                 goto eof;
346 
347 #if defined(FEATURE_ESAME)
348             pte = (DBLWRD*)(sysblk.mainstor + pto);
349 #else /*!defined(FEATURE_ESAME)*/
350             pte = (FWORD*)(sysblk.mainstor + pto);
351 #endif /*!defined(FEATURE_ESAME)*/
352             FETCH_W(pgo, pte);
353             STORAGE_KEY(pto, &sysblk) |= (STORKEY_REF);
354             if( !(pgo & PAGETAB_INVALID) )
355             {
356 #if defined(FEATURE_ESAME)
357                 pgo &= ZPGETAB_PFRA;
358 #else /*!defined(FEATURE_ESAME)*/
359                 pgo &= PAGETAB_PFRA;
360 #endif /*!defined(FEATURE_ESAME)*/
361 
362                 /* Write page to SCE disk */
363                 if( pgo >= sysblk.mainsize)
364                     goto eof;
365 
366                 page = sysblk.mainstor + pgo;
367                 nwrite = write(fd, page, STORAGE_KEY_PAGESIZE);
368                 totwrite += nwrite;
369                 if( nwrite != STORAGE_KEY_PAGESIZE )
370                     goto eof;
371 
372                 STORAGE_KEY(pgo, &sysblk) |= (STORKEY_REF);
373             }
374             size -= STORAGE_KEY_PAGESIZE;
375         }
376     }
377 eof:
378     close(fd);
379     return totwrite;
380 }
381 
382 
383 /*-------------------------------------------------------------------*/
384 /* Function to read from a file on the service processor disk        */
385 /*-------------------------------------------------------------------*/
ARCH_DEP(read_file)386 static S64 ARCH_DEP(read_file)(char *fname, CREG sto, S64 seek, S64 size)
387 {
388 int fd, nread;
389 U64 totread = 0;
390 
391     fd = hopen(fname, O_RDONLY|O_BINARY);
392     if (fd < 0)
393     {
394         if(errno != ENOENT)
395             logmsg (_("HHCSC051E %s open error: %s\n"), fname, strerror(errno));
396         return -1;
397     }
398 
399     if(lseek(fd, (off_t)seek, SEEK_SET) == (off_t)seek)
400     {
401 #if defined(FEATURE_ESAME)
402         sto &= ASCE_TO;
403 #else /*!defined(FEATURE_ESAME)*/
404         sto &= STD_STO;
405 #endif /*!defined(FEATURE_ESAME)*/
406 
407         for( ; size > 0 ; sto += sizeof(sto))
408         {
409 #if defined(FEATURE_ESAME)
410         DBLWRD *ste;
411 #else /*!defined(FEATURE_ESAME)*/
412         FWORD *ste;
413 #endif /*!defined(FEATURE_ESAME)*/
414         CREG pto, pti;
415 
416             /* Fetch segment table entry and calc Page Table Origin */
417             if( sto >= sysblk.mainsize)
418                 goto eof;
419 #if defined(FEATURE_ESAME)
420             ste = (DBLWRD*)(sysblk.mainstor + sto);
421 #else /*!defined(FEATURE_ESAME)*/
422             ste = (FWORD*)(sysblk.mainstor + sto);
423 #endif /*!defined(FEATURE_ESAME)*/
424             FETCH_W(pto, ste);
425             STORAGE_KEY(sto, &sysblk) |= (STORKEY_REF);
426             if( pto & SEGTAB_INVALID )
427                 goto eof;
428 #if defined(FEATURE_ESAME)
429             pto &= ZSEGTAB_PTO;
430 #else /*!defined(FEATURE_ESAME)*/
431             pto &= SEGTAB_PTO;
432 #endif /*!defined(FEATURE_ESAME)*/
433 
434             for(pti = 0; pti < 256 && size > 0; pti++, pto += sizeof(pto))
435             {
436 #if defined(FEATURE_ESAME)
437             DBLWRD *pte;
438 #else /*!defined(FEATURE_ESAME)*/
439             FWORD *pte;
440 #endif /*!defined(FEATURE_ESAME)*/
441             CREG pgo;
442             BYTE *page;
443 
444                 /* Fetch Page Table Entry to get page origin */
445                 if( pto >= sysblk.mainsize)
446                     goto eof;
447 #if defined(FEATURE_ESAME)
448                 pte = (DBLWRD*)(sysblk.mainstor + pto);
449 #else /*!defined(FEATURE_ESAME)*/
450                 pte = (FWORD*)(sysblk.mainstor + pto);
451 #endif /*!defined(FEATURE_ESAME)*/
452                 FETCH_W(pgo, pte);
453                 STORAGE_KEY(pto, &sysblk) |= (STORKEY_REF);
454                 if( pgo & PAGETAB_INVALID )
455                     goto eof;
456 #if defined(FEATURE_ESAME)
457                 pgo &= ZPGETAB_PFRA;
458 #else /*!defined(FEATURE_ESAME)*/
459                 pgo &= PAGETAB_PFRA;
460 #endif /*!defined(FEATURE_ESAME)*/
461 
462                 /* Read page into main storage */
463                 if( pgo >= sysblk.mainsize)
464                     goto eof;
465                 page = sysblk.mainstor + pgo;
466                 nread = read(fd, page, STORAGE_KEY_PAGESIZE);
467                 totread += nread;
468                 size -= nread;
469                 if( nread != STORAGE_KEY_PAGESIZE )
470                     goto eof;
471                 STORAGE_KEY(pgo, &sysblk) |= (STORKEY_REF|STORKEY_CHANGE);
472             }
473         }
474     }
475 eof:
476     close(fd);
477     return totread;
478 }
479 
480 
ARCH_DEP(scedio_ior)481 static int ARCH_DEP(scedio_ior)(SCCB_SCEDIOR_BK *scedior_bk)
482 {
483 U32  origin;
484 char image[9];
485 S32  size;
486 unsigned int i;
487 char filename[MAX_PATH];
488 
489     FETCH_FW(origin,scedior_bk->origin);
490 
491     /* Convert image filename to null terminated ascii string */
492     for(i = 0; i < sizeof(image)-1 && scedior_bk->image[i] != 0x40; i++)
493         image[i] = guest_to_host((int)scedior_bk->image[i]);
494     image[i] = '\0';
495 
496     /* Ensure file access is allowed and within specified directory */
497     if(!check_sce_filepath(image,filename))
498     {
499         if(errno != ENOENT)
500             logmsg (_("HHCSC101E access error: %s: %s\n"), image, strerror(errno));
501         return FALSE;
502     }
503 
504     size = ARCH_DEP(load_main)(filename,origin);
505 
506     return (size >= 0) ? TRUE : FALSE;
507 }
508 
509 
ARCH_DEP(scedio_iov)510 static int ARCH_DEP(scedio_iov)(SCCB_SCEDIOV_BK *scediov_bk)
511 {
512 S64     seek;
513 S64     length;
514 S64     totread, totwrite;
515 U64     sto;
516 char    fname[MAX_PATH];
517 
518     switch(scediov_bk->type) {
519 
520     case SCCB_SCEDIOV_TYPE_INIT:
521         return TRUE;
522         break;
523 
524 
525     case SCCB_SCEDIOV_TYPE_READ:
526         /* Ensure file access is allowed and within specified directory */
527         if(!check_sce_filepath((char*)scediov_bk->filename,fname))
528         {
529             if(errno != ENOENT)
530                 logmsg (_("HHCSC201E access error: %s: %s\n"), fname, strerror(errno));
531             return FALSE;
532         }
533         FETCH_DW(sto,scediov_bk->sto);
534         FETCH_DW(seek,scediov_bk->seek);
535         FETCH_DW(length,scediov_bk->length);
536 
537         totread = ARCH_DEP(read_file)(fname, sto, seek, length);
538 
539         if(totread > 0)
540         {
541             STORE_DW(scediov_bk->length,totread);
542 
543             if(totread == length)
544                 STORE_DW(scediov_bk->ncomp,0);
545             else
546                 STORE_DW(scediov_bk->ncomp,seek+totread);
547 
548             return TRUE;
549         }
550         else
551             return FALSE;
552 
553         break;
554 
555 
556     case SCCB_SCEDIOV_TYPE_CREATE:
557     case SCCB_SCEDIOV_TYPE_APPEND:
558         /* Ensure file access is allowed and within specified directory */
559         if(!check_sce_filepath((char*)scediov_bk->filename,fname))
560         {
561             if(errno != ENOENT)
562                 logmsg (_("HHCSC202I access error: %s: %s\n"), fname, strerror(errno));
563 
564             /* A file not found error may be expected for a create request */
565             if(!(errno == ENOENT && scediov_bk->type == SCCB_SCEDIOV_TYPE_CREATE))
566                 return FALSE;
567         }
568         FETCH_DW(sto,scediov_bk->sto);
569         FETCH_DW(seek,scediov_bk->seek);
570         FETCH_DW(length,scediov_bk->length);
571 
572         totwrite = ARCH_DEP(write_file)(fname,
573           ((scediov_bk->type == SCCB_SCEDIOV_TYPE_CREATE) ? (O_CREAT|O_TRUNC) : O_APPEND), sto, length);
574 
575         if(totwrite >= 0)
576         {
577             STORE_DW(scediov_bk->ncomp,totwrite);
578             return TRUE;
579         }
580         else
581             return FALSE;
582         break;
583 
584 
585     default:
586         PTT(PTT_CL_ERR,"*SERVC",(U32)scediov_bk->type,(U32)scediov_bk->flag1,scediov_bk->flag2);
587         return FALSE;
588 
589     }
590 }
591 
592 
593 /*-------------------------------------------------------------------*/
594 /* Thread to perform service processor I/O functions                 */
595 /*-------------------------------------------------------------------*/
ARCH_DEP(scedio_thread)596 static void ARCH_DEP(scedio_thread)(SCCB_SCEDIO_BK *scedio_bk)
597 {
598 SCCB_SCEDIOV_BK *scediov_bk;
599 SCCB_SCEDIOR_BK *scedior_bk;
600 
601     switch(scedio_bk->flag1) {
602 
603     case SCCB_SCEDIO_FLG1_IOV:
604         scediov_bk = (SCCB_SCEDIOV_BK*)(scedio_bk + 1);
605         if( ARCH_DEP(scedio_iov)(scediov_bk) )
606             scedio_bk->flag3 |= SCCB_SCEDIO_FLG3_COMPLETE;
607         else
608             scedio_bk->flag3 &= ~SCCB_SCEDIO_FLG3_COMPLETE;
609         break;
610 
611     case SCCB_SCEDIO_FLG1_IOR:
612         scedior_bk = (SCCB_SCEDIOR_BK*)(scedio_bk + 1);
613         if( ARCH_DEP(scedio_ior)(scedior_bk) )
614             scedio_bk->flag3 |= SCCB_SCEDIO_FLG3_COMPLETE;
615         else
616             scedio_bk->flag3 &= ~SCCB_SCEDIO_FLG3_COMPLETE;
617         break;
618 
619     default:
620         PTT(PTT_CL_ERR,"*SERVC",(U32)scedio_bk->flag0,(U32)scedio_bk->flag1,scedio_bk->flag3);
621     }
622 
623 
624     OBTAIN_INTLOCK(NULL);
625 
626     while(IS_IC_SERVSIG)
627     {
628         RELEASE_INTLOCK(NULL);
629         sched_yield();
630         OBTAIN_INTLOCK(NULL);
631     }
632 
633     sclp_attention(SCCB_EVD_TYPE_SCEDIO);
634 
635     scedio_tid = 0;
636 
637     RELEASE_INTLOCK(NULL);
638 }
639 
640 
641 /*-------------------------------------------------------------------*/
642 /* Function to interface with the service processor I/O thread       */
643 /*-------------------------------------------------------------------*/
ARCH_DEP(scedio_request)644 static int ARCH_DEP(scedio_request)(U32 sclp_command, SCCB_EVD_HDR *evd_hdr)
645 {
646 SCCB_SCEDIO_BK  *scedio_bk = (SCCB_SCEDIO_BK*)(evd_hdr + 1);
647 SCCB_SCEDIOV_BK *scediov_bk;
648 SCCB_SCEDIOR_BK *scedior_bk;
649 
650 
651 static struct {
652     SCCB_SCEDIO_BK scedio_bk;
653     union {
654         SCCB_SCEDIOV_BK v;
655         SCCB_SCEDIOR_BK r;
656         } io;
657     } static_scedio_bk ;
658 
659 static int scedio_pending;
660 
661     if(sclp_command == SCLP_READ_EVENT_DATA)
662     {
663     int pending_req = scedio_pending;
664     U16 evd_len;
665 
666         /* Return no data if the scedio thread is still active */
667         if(scedio_tid)
668             return 0;
669 
670         /* Update the scedio_bk copy in the SCCB */
671         if(scedio_pending)
672         {
673             /* Zero all fields */
674             memset (evd_hdr, 0, sizeof(SCCB_EVD_HDR));
675 
676             /* Set type in event header */
677             evd_hdr->type = SCCB_EVD_TYPE_SCEDIO;
678 
679             /* Store scedio header */
680             *scedio_bk = static_scedio_bk.scedio_bk;
681 
682             /* Calculate event response length */
683             evd_len = sizeof(SCCB_EVD_HDR) + sizeof(SCCB_SCEDIO_BK);
684 
685             switch(scedio_bk->flag1) {
686             case SCCB_SCEDIO_FLG1_IOR:
687                 scedior_bk = (SCCB_SCEDIOR_BK*)(scedio_bk + 1);
688                 *scedior_bk = static_scedio_bk.io.r;
689                 evd_len += sizeof(SCCB_SCEDIOR_BK);
690                 break;
691             case SCCB_SCEDIO_FLG1_IOV:
692                 scediov_bk = (SCCB_SCEDIOV_BK*)(scedio_bk + 1);
693                 *scediov_bk = static_scedio_bk.io.v ;
694                 evd_len += sizeof(SCCB_SCEDIOV_BK);
695                 break;
696             default:
697                 PTT(PTT_CL_ERR,"*SERVC",(U32)evd_hdr->type,(U32)scedio_bk->flag1,scedio_bk->flag3);
698             }
699 
700             /* Set length in event header */
701             STORE_HW(evd_hdr->totlen, evd_len);
702         }
703 
704 
705         /* Reset the pending flag */
706         scedio_pending = 0;
707 
708         /* Return true if a request was pending */
709         return pending_req;
710 
711     }
712     else
713     {
714 #if !defined(NO_SIGABEND_HANDLER)
715         switch(scedio_bk->flag1) {
716             case SCCB_SCEDIO_FLG1_IOV:
717                 scediov_bk = (SCCB_SCEDIOV_BK*)(scedio_bk + 1);
718                 switch(scediov_bk->type) {
719                     case SCCB_SCEDIOV_TYPE_INIT:
720                         /* Kill the scedio thread if it is active */
721                         if( scedio_tid )
722                         {
723                             OBTAIN_INTLOCK(NULL);
724                             signal_thread(scedio_tid, SIGKILL);
725                             scedio_tid = 0;
726                             scedio_pending = 0;
727                             RELEASE_INTLOCK(NULL);
728                         }
729                         break;
730                 }
731                 break;
732         }
733 #endif
734 
735         /* Take a copy of the scedio_bk in the SCCB */
736         static_scedio_bk.scedio_bk = *scedio_bk;
737         switch(scedio_bk->flag1) {
738         case SCCB_SCEDIO_FLG1_IOR:
739             scedior_bk = (SCCB_SCEDIOR_BK*)(scedio_bk + 1);
740             static_scedio_bk.io.r = *scedior_bk;
741             break;
742         case SCCB_SCEDIO_FLG1_IOV:
743             scediov_bk = (SCCB_SCEDIOV_BK*)(scedio_bk + 1);
744             static_scedio_bk.io.v = *scediov_bk;
745             break;
746         default:
747             PTT(PTT_CL_ERR,"*SERVC",(U32)evd_hdr->type,(U32)scedio_bk->flag1,scedio_bk->flag3);
748         }
749 
750         /* Create the scedio thread */
751         if( create_thread(&scedio_tid, &sysblk.detattr,
752             ARCH_DEP(scedio_thread), &static_scedio_bk, "scedio_thread") )
753             return -1;
754 
755         scedio_pending = 1;
756 
757     }
758 
759     return 0;
760 }
761 
762 
763 /*-------------------------------------------------------------------*/
764 /* Function to request service processor I/O                         */
765 /*-------------------------------------------------------------------*/
ARCH_DEP(sclp_scedio_request)766 void ARCH_DEP(sclp_scedio_request) (SCCB_HEADER *sccb)
767 {
768 SCCB_EVD_HDR    *evd_hdr = (SCCB_EVD_HDR*)(sccb + 1);
769 
770     if( ARCH_DEP(scedio_request)(SCLP_WRITE_EVENT_DATA, evd_hdr) )
771     {
772         /* Set response code X'0040' in SCCB header */
773         sccb->reas = SCCB_REAS_NONE;
774         sccb->resp = SCCB_RESP_BACKOUT;
775     }
776     else
777     {
778         /* Set response code X'0020' in SCCB header */
779         sccb->reas = SCCB_REAS_NONE;
780         sccb->resp = SCCB_RESP_COMPLETE;
781     }
782 
783     /* Indicate Event Processed */
784     evd_hdr->flag |= SCCB_EVD_FLAG_PROC;
785 
786 }
787 
788 
789 /*-------------------------------------------------------------------*/
790 /* Function to read service processor I/O event data                 */
791 /*-------------------------------------------------------------------*/
ARCH_DEP(sclp_scedio_event)792 void ARCH_DEP(sclp_scedio_event) (SCCB_HEADER *sccb)
793 {
794 SCCB_EVD_HDR    *evd_hdr = (SCCB_EVD_HDR*)(sccb + 1);
795 U16 sccb_len;
796 U16 evd_len;
797 
798     if( ARCH_DEP(scedio_request)(SCLP_READ_EVENT_DATA, evd_hdr) )
799     {
800         /* Update SCCB length field if variable request */
801         if (sccb->type & SCCB_TYPE_VARIABLE)
802         {
803             FETCH_HW(evd_len, evd_hdr->totlen);
804             sccb_len = evd_len + sizeof(SCCB_HEADER);
805             STORE_HW(sccb->length, sccb_len);
806             sccb->type &= ~SCCB_TYPE_VARIABLE;
807         }
808 
809         /* Set response code X'0020' in SCCB header */
810         sccb->reas = SCCB_REAS_NONE;
811         sccb->resp = SCCB_RESP_COMPLETE;
812     }
813 
814 }
815 
816 #endif /*defined(FEATURE_SCEDIO)*/
817 
818 
819 #if !defined(_GEN_ARCH)
820 
821 #if defined(_ARCHMODE2)
822  #define  _GEN_ARCH _ARCHMODE2
823  #include "scedasd.c"
824 #endif
825 
826 #if defined(_ARCHMODE3)
827  #undef   _GEN_ARCH
828  #define  _GEN_ARCH _ARCHMODE3
829  #include "scedasd.c"
830 #endif
831 
832 
833 /*-------------------------------------------------------------------*/
834 /*  Service Processor Load    (load/ipl from the specified file)     */
835 /*-------------------------------------------------------------------*/
836 
load_hmc(char * fname,int cpu,int clear)837 int load_hmc (char *fname, int cpu, int clear)
838 {
839     switch(sysblk.arch_mode) {
840 #if defined(_370)
841         case ARCH_370:
842             return s370_load_hmc (fname, cpu, clear);
843 #endif
844 #if defined(_390)
845         case ARCH_390:
846             return s390_load_hmc (fname, cpu, clear);
847 #endif
848 #if defined(_900)
849         case ARCH_900:
850             /* z/Arch always starts out in ESA390 mode */
851             return s390_load_hmc (fname, cpu, clear);
852 #endif
853     }
854     return -1;
855 }
856 
857 
858 /*-------------------------------------------------------------------*/
859 /* Load/Read specified file into absolute main storage               */
860 /*-------------------------------------------------------------------*/
load_main(char * fname,RADR startloc)861 int load_main (char *fname, RADR startloc)
862 {
863     switch(sysblk.arch_mode) {
864 #if defined(_370)
865         case ARCH_370:
866             return s370_load_main (fname, startloc);
867 #endif
868 #if defined(_390)
869         case ARCH_390:
870             return s390_load_main (fname, startloc);
871 #endif
872 #if defined(_900)
873         case ARCH_900:
874             return z900_load_main (fname, startloc);
875 #endif
876     }
877     return -1;
878 }
879 
880 #endif /*!defined(_GEN_ARCH)*/
881