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