/*-------------------------------------------------------------------*/ int ARCH_DEP(common_load_finish) (REGS *regs) { /* Zeroize the interrupt code in the PSW */ regs->psw.intcode = 0; /* Load IPL PSW from PSA+X'0' */ if (ARCH_DEP(load_psw) (regs, regs->psa->iplpsw) != 0) { logmsg (_("HHCCP030E %s mode IPL failed: Invalid IPL PSW: " "%2.2X%2.2X%2.2X%2.2X %2.2X%2.2X%2.2X%2.2X\n"), get_arch_mode_string(regs), regs->psa->iplpsw[0], regs->psa->iplpsw[1], regs->psa->iplpsw[2], regs->psa->iplpsw[3], regs->psa->iplpsw[4], regs->psa->iplpsw[5], regs->psa->iplpsw[6], regs->psa->iplpsw[7]); HDC1(debug_cpu_state, regs); return -1; } /* Set the CPU into the started state */ regs->opinterv = 0; regs->cpustate = CPUSTATE_STARTED; /* The actual IPL (load) is now completed... */ regs->loadstate = 0; /* Signal the CPU to retest stopped indicator */ WAKEUP_CPU (regs); HDC1(debug_cpu_state, regs); return 0; } /* end function common_load_finish */
/*-------------------------------------------------------------------*/ int ARCH_DEP(common_load_finish) (REGS *regs) { int rc; /* Zeroize the interrupt code in the PSW */ regs->psw.intcode = 0; /* Load IPL PSW from PSA+X'0' */ if ((rc = ARCH_DEP(load_psw) (regs, regs->psa->iplpsw)) ) { char buf[80]; MSGBUF(buf, "architecture mode %s, invalid ipl psw %2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X", get_arch_mode_string((REGS *)0), regs->psa->iplpsw[0], regs->psa->iplpsw[1], regs->psa->iplpsw[2], regs->psa->iplpsw[3], regs->psa->iplpsw[4], regs->psa->iplpsw[5], regs->psa->iplpsw[6], regs->psa->iplpsw[7]); WRMSG (HHC00839, "E", PTYPSTR(sysblk.pcpu), sysblk.pcpu, buf); HDC1(debug_cpu_state, regs); return rc; } /* Set the CPU into the started state */ regs->opinterv = 0; regs->cpustate = CPUSTATE_STARTED; /* The actual IPL (load) is now completed... */ regs->loadstate = 0; /* reset sys_reset flag to indicate a active machine */ sysblk.sys_reset = FALSE; /* Signal the CPU to retest stopped indicator */ WAKEUP_CPU (regs); HDC1(debug_cpu_state, regs); return 0; } /* end function common_load_finish */
int resume_cmd(int argc, char *argv[],char *cmdline) { char *fn = SR_DEFAULT_FILENAME; SR_FILE *file; U32 key = 0, len = 0; U64 mainsize = 0; U64 xpndsize = 0; CPU_BITMAP started_mask = 0; int i, rc = -1; REGS *regs = NULL; U16 devnum=0; U16 lcss=0; U16 hw; int devargc=0; char *devargv[16]; int devargx=0; DEVBLK *dev = NULL; IOINT *ioq = NULL; char buf[SR_MAX_STRING_LENGTH+1]; char zeros[16]; S64 dreg; UNREFERENCED(cmdline); if (argc > 2) { // "SR: too many arguments" WRMSG(HHC02000, "E"); return -1; } if (argc == 2) fn = argv[1]; memset (zeros, 0, sizeof(zeros)); TRACE("SR: Begin Resume Processing...\n"); /* Make sure all CPUs are deconfigured or stopped */ TRACE("SR: Waiting for CPUs to stop...\n"); OBTAIN_INTLOCK(NULL); for (i = 0; i < sysblk.maxcpu; i++) if (IS_CPU_ONLINE(i) && CPUSTATE_STOPPED != sysblk.regs[i]->cpustate) { RELEASE_INTLOCK(NULL); // "SR: all processors must be stopped to resume" WRMSG(HHC02005, "E"); return -1; } RELEASE_INTLOCK(NULL); file = SR_OPEN (fn, "rb"); if (file == NULL) { // "SR: error in function '%s': '%s'" WRMSG(HHC02001, "E", "open()",strerror(errno)); return -1; } /* First key must be SR_HDR_ID and string must match SR_ID */ TRACE("SR: Reading File Header...\n"); SR_READ_HDR(file, key, len); if (key == SR_HDR_ID) SR_READ_STRING(file, buf, len); if (key != SR_HDR_ID || strcmp(buf, SR_ID)) { // "SR: file identifier error" WRMSG(HHC02006, "E"); goto sr_error_exit; } /* Deconfigure all CPUs */ TRACE("SR: Deconfiguring all CPUs...\n"); OBTAIN_INTLOCK(NULL); for (i = 0; i < sysblk.maxcpu; i++) if (IS_CPU_ONLINE(i)) deconfigure_cpu(i); RELEASE_INTLOCK(NULL); TRACE("SR: Processing Resume File...\n"); while (key != SR_EOF) { SR_READ_HDR(file, key, len); switch (key) { case SR_HDR_DATE: SR_READ_STRING(file, buf, len); if (len >= 2) { len -= 2; while (len > 0 && isspace(buf[len])) --len; buf[len+1]=0; } // "SR: resuming suspended file created on '%s'" WRMSG(HHC02007, "I", buf); break; case SR_SYS_STARTED_MASK: SR_READ_VALUE(file, len, &started_mask, sizeof(started_mask)); break; case SR_SYS_ARCH_NAME: SR_READ_STRING(file, buf, len); i = -1; #if defined (_370) if (strcasecmp (buf, arch_name[ARCH_370]) == 0) { i = ARCH_370; } #endif #if defined (_390) if (strcasecmp (buf, arch_name[ARCH_390]) == 0) { i = ARCH_390; } #endif #if defined (_900) if (0 || strcasecmp (buf, arch_name[ARCH_900]) == 0 || strcasecmp (buf, "ESAME") == 0 ) { i = ARCH_900; } #endif if (i < 0) { // "SR: archmode '%s' not supported" WRMSG(HHC02008, "E", buf); goto sr_error_exit; } sysblk.arch_mode = i; sysblk.pcpu = 0; sysblk.dummyregs.arch_mode = sysblk.arch_mode; #if defined(OPTION_FISHIO) ios_arch_mode = sysblk.arch_mode; #endif break; case SR_SYS_MAINSIZE: SR_READ_VALUE(file, len, &mainsize, sizeof(mainsize)); if (mainsize > sysblk.mainsize) { char buf1[20]; char buf2[20]; MSGBUF(buf1, "%dM", (U32)(mainsize / (1024*1024))); MSGBUF(buf2, "%dM", (U32)(sysblk.mainsize / (1024*1024))); // "SR: mismatch in '%s': '%s' found, '%s' expected" WRMSG(HHC02009, "E", "mainsize", buf1, buf2); goto sr_error_exit; } break; case SR_SYS_MAINSTOR: TRACE("SR: Restoring MAINSTOR...\n"); SR_READ_BUF(file, sysblk.mainstor, mainsize); break; case SR_SYS_SKEYSIZE: SR_READ_VALUE(file, len, &len, sizeof(len)); if (len > (U32)(sysblk.mainsize/STORAGE_KEY_UNITSIZE)) { char buf1[20]; char buf2[20]; MSGBUF(buf1, "%d", len); MSGBUF(buf2, "%d", (U32)(sysblk.mainsize/STORAGE_KEY_UNITSIZE)); // "SR: mismatch in '%s': '%s' found, '%s' expected" WRMSG(HHC02009, "E", "storkey size", buf1, buf2); goto sr_error_exit; } break; case SR_SYS_STORKEYS: TRACE("SR: Restoring Storage Keys...\n"); SR_READ_BUF(file, sysblk.storkeys, len); break; case SR_SYS_XPNDSIZE: SR_READ_VALUE(file, len, &xpndsize, sizeof(xpndsize)); if (xpndsize > sysblk.xpndsize) { char buf1[20]; char buf2[20]; MSGBUF(buf1, "%dM", (U32)(xpndsize / (256))); MSGBUF(buf2, "%dM", sysblk.xpndsize / (256)); // "SR: mismatch in '%s': '%s' found, '%s' expected" WRMSG(HHC02009, "E", "expand size", buf1, buf2); goto sr_error_exit; } break; case SR_SYS_XPNDSTOR: TRACE("SR: Restoring Expanded Storage...\n"); SR_READ_BUF(file, sysblk.xpndstor, xpndsize * 4096); break; case SR_SYS_IPLDEV: SR_READ_VALUE(file, len, &sysblk.ipldev, sizeof(sysblk.ipldev)); break; case SR_SYS_IPLCPU: SR_READ_VALUE(file, len, &sysblk.iplcpu, sizeof(sysblk.iplcpu)); break; case SR_SYS_MBO: SR_READ_VALUE(file, len, &sysblk.mbo, sizeof(sysblk.mbo)); break; case SR_SYS_MBK: SR_READ_VALUE(file, len, &sysblk.mbk, sizeof(sysblk.mbk)); break; case SR_SYS_MBM: SR_READ_VALUE(file, len, &sysblk.mbm, sizeof(sysblk.mbm)); break; case SR_SYS_MBD: SR_READ_VALUE(file, len, &sysblk.mbd, sizeof(sysblk.mbd)); break; case SR_SYS_IOPENDING_LCSS: SR_READ_VALUE(file,len,&lcss,sizeof(lcss)); break; case SR_SYS_IOPENDING: SR_READ_VALUE(file, len, &hw, sizeof(hw)); dev = find_device_by_devnum(lcss,hw); if (dev == NULL) break; if (ioq == NULL) sysblk.iointq = &dev->ioint; else ioq->next = &dev->ioint; ioq = &dev->ioint; dev = NULL; lcss = 0; break; case SR_SYS_PCIPENDING_LCSS: SR_READ_VALUE(file,len,&lcss,sizeof(lcss)); break; case SR_SYS_PCIPENDING: SR_READ_VALUE(file, len, &hw, sizeof(hw)); dev = find_device_by_devnum(lcss,hw); if (dev == NULL) break; if (ioq == NULL) sysblk.iointq = &dev->pciioint; else ioq->next = &dev->pciioint; ioq = &dev->pciioint; dev = NULL; lcss = 0; break; case SR_SYS_ATTNPENDING_LCSS: SR_READ_VALUE(file,len,&lcss,sizeof(lcss)); break; case SR_SYS_ATTNPENDING: SR_READ_VALUE(file, len, &hw, sizeof(hw)); dev = find_device_by_devnum(lcss,hw); if (dev == NULL) break; if (ioq == NULL) sysblk.iointq = &dev->attnioint; else ioq->next = &dev->attnioint; ioq = &dev->attnioint; dev = NULL; lcss = 0; break; case SR_SYS_CHP_RESET_0: case SR_SYS_CHP_RESET_1: case SR_SYS_CHP_RESET_2: case SR_SYS_CHP_RESET_3: case SR_SYS_CHP_RESET_4: case SR_SYS_CHP_RESET_5: case SR_SYS_CHP_RESET_6: case SR_SYS_CHP_RESET_7: i = key - SR_SYS_CHP_RESET; SR_READ_VALUE(file, len, &sysblk.chp_reset[i], sizeof(sysblk.chp_reset[0])); break; case SR_SYS_SERVPARM: SR_READ_VALUE(file, len, &sysblk.servparm, sizeof(sysblk.servparm)); break; case SR_SYS_SIGINTREQ: SR_READ_VALUE(file, len, &rc, sizeof(rc)); sysblk.sigintreq = rc; break; case SR_SYS_LOADPARM: SR_READ_STRING(file, buf, len); set_loadparm ((char *)buf); break; case SR_SYS_SERVC: TRACE("SR: Restoring Service Console State...\n"); rc = servc_hresume(file); if (rc < 0) goto sr_error_exit; break; case SR_SYS_CLOCK: TRACE("SR: Restoring Clock State...\n"); rc = clock_hresume(file); if (rc < 0) goto sr_error_exit; break; case SR_CPU: SR_READ_VALUE(file, len, &i, sizeof(i)); TRACE("SR: Restoring CPU %d Data...\n", i); if (i >= sysblk.maxcpu) { // "SR: processor CP%02X exceeds max allowed CP%02X" WRMSG(HHC02010, "E", i, sysblk.maxcpu-1); goto sr_error_exit; } OBTAIN_INTLOCK(NULL); if (IS_CPU_ONLINE(i)) { RELEASE_INTLOCK(NULL); // "SR: processor %s%02X already configured" WRMSG(HHC02011, "E", PTYPSTR(i), i); goto sr_error_exit; } rc = configure_cpu(i); RELEASE_INTLOCK(NULL); if (rc < 0) { // "SR: processor %s%02X unable to configure online" WRMSG(HHC02012, "E", PTYPSTR(i), i); goto sr_error_exit; } regs = sysblk.regs[i]; break; case SR_CPU_PX: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->px, sizeof(regs->px)); break; case SR_CPU_PSW: SR_NULL_REGS_CHECK(regs); if (len != 8 && len != 16) { // "SR: processor %s%02X invalid psw length %d" WRMSG(HHC02013, "E", PTYPSTR(regs->cpuad), regs->cpuad, len); goto sr_error_exit; } memset(buf, 0, 16); SR_READ_BUF(file, buf, len); switch (regs->arch_mode) { #if defined (_370) case ARCH_370: len = 8; rc = s370_load_psw(regs, (BYTE *)&buf); break; #endif #if defined (_390) case ARCH_390: len = 8; rc = s390_load_psw(regs, (BYTE *)&buf); break; #endif #if defined (_900) case ARCH_900: len = 16; rc = z900_load_psw(regs, (BYTE *)&buf); break; #endif } /* switch (regs->arch_mode) */ if (rc != 0 && memcmp(buf, zeros, len)) { // "SR: processor %s%02X error loading psw, rc %d" WRMSG(HHC02014, "E", PTYPSTR(regs->cpuad), regs->cpuad, rc); goto sr_error_exit; } break; case SR_CPU_GR_0: case SR_CPU_GR_1: case SR_CPU_GR_2: case SR_CPU_GR_3: case SR_CPU_GR_4: case SR_CPU_GR_5: case SR_CPU_GR_6: case SR_CPU_GR_7: case SR_CPU_GR_8: case SR_CPU_GR_9: case SR_CPU_GR_10: case SR_CPU_GR_11: case SR_CPU_GR_12: case SR_CPU_GR_13: case SR_CPU_GR_14: case SR_CPU_GR_15: SR_NULL_REGS_CHECK(regs); i = key - SR_CPU_GR; SR_READ_VALUE(file, len, ®s->gr[i], sizeof(regs->gr[0])); break; case SR_CPU_CR_0: case SR_CPU_CR_1: case SR_CPU_CR_2: case SR_CPU_CR_3: case SR_CPU_CR_4: case SR_CPU_CR_5: case SR_CPU_CR_6: case SR_CPU_CR_7: case SR_CPU_CR_8: case SR_CPU_CR_9: case SR_CPU_CR_10: case SR_CPU_CR_11: case SR_CPU_CR_12: case SR_CPU_CR_13: case SR_CPU_CR_14: case SR_CPU_CR_15: SR_NULL_REGS_CHECK(regs); i = key - SR_CPU_CR; SR_READ_VALUE(file, len, ®s->CR(i), sizeof(regs->CR(0))); break; case SR_CPU_AR_0: case SR_CPU_AR_1: case SR_CPU_AR_2: case SR_CPU_AR_3: case SR_CPU_AR_4: case SR_CPU_AR_5: case SR_CPU_AR_6: case SR_CPU_AR_7: case SR_CPU_AR_8: case SR_CPU_AR_9: case SR_CPU_AR_10: case SR_CPU_AR_11: case SR_CPU_AR_12: case SR_CPU_AR_13: case SR_CPU_AR_14: case SR_CPU_AR_15: SR_NULL_REGS_CHECK(regs); i = key - SR_CPU_AR; SR_READ_VALUE(file, len, ®s->ar[i], sizeof(regs->ar[0])); break; case SR_CPU_FPR_0: case SR_CPU_FPR_1: case SR_CPU_FPR_2: case SR_CPU_FPR_3: case SR_CPU_FPR_4: case SR_CPU_FPR_5: case SR_CPU_FPR_6: case SR_CPU_FPR_7: case SR_CPU_FPR_8: case SR_CPU_FPR_9: case SR_CPU_FPR_10: case SR_CPU_FPR_11: case SR_CPU_FPR_12: case SR_CPU_FPR_13: case SR_CPU_FPR_14: case SR_CPU_FPR_15: case SR_CPU_FPR_16: case SR_CPU_FPR_17: case SR_CPU_FPR_18: case SR_CPU_FPR_19: case SR_CPU_FPR_20: case SR_CPU_FPR_21: case SR_CPU_FPR_22: case SR_CPU_FPR_23: case SR_CPU_FPR_24: case SR_CPU_FPR_25: case SR_CPU_FPR_26: case SR_CPU_FPR_27: case SR_CPU_FPR_28: case SR_CPU_FPR_29: case SR_CPU_FPR_30: case SR_CPU_FPR_31: SR_NULL_REGS_CHECK(regs); i = key - SR_CPU_FPR; SR_READ_VALUE(file, len, ®s->fpr[i], sizeof(regs->fpr[0])); break; case SR_CPU_FPC: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->fpc, sizeof(regs->fpc)); break; case SR_CPU_DXC: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->dxc, sizeof(regs->dxc)); break; case SR_CPU_MC: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->mc, sizeof(regs->mc)); break; case SR_CPU_EA: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->ea, sizeof(regs->ea)); break; case SR_CPU_PTIMER: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, &dreg, sizeof(S64)); set_cpu_timer(regs, dreg); break; case SR_CPU_CLKC: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->clkc, sizeof(regs->clkc)); break; case SR_CPU_CHANSET: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->chanset, sizeof(regs->chanset)); break; case SR_CPU_TODPR: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->todpr, sizeof(regs->todpr)); break; case SR_CPU_MONCLASS: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->monclass, sizeof(regs->monclass)); break; case SR_CPU_EXCARID: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->excarid, sizeof(regs->excarid)); break; case SR_CPU_BEAR: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->bear, sizeof(regs->bear)); break; case SR_CPU_OPNDRID: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->opndrid, sizeof(regs->opndrid)); break; case SR_CPU_CHECKSTOP: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, &rc, sizeof(rc)); regs->checkstop = rc; break; case SR_CPU_HOSTINT: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, &rc, sizeof(rc)); regs->hostint = rc; break; case SR_CPU_LOADSTATE: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, &rc, sizeof(rc)); regs->loadstate = rc; break; case SR_CPU_INVALIDATE: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, &rc, sizeof(rc)); regs->invalidate = rc; break; case SR_CPU_SIGPRESET: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, &rc, sizeof(rc)); regs->sigpreset = rc; break; case SR_CPU_SIGPIRESET: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, &rc, sizeof(rc)); regs->sigpireset = rc; break; case SR_CPU_INTS_STATE: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->ints_state, sizeof(regs->ints_state)); /* Force CPU to examine the interrupt state */ ON_IC_INTERRUPT(regs); break; case SR_CPU_INTS_MASK: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->ints_mask, sizeof(regs->ints_mask)); break; case SR_CPU_MALFCPU_0: case SR_CPU_MALFCPU_1: case SR_CPU_MALFCPU_2: case SR_CPU_MALFCPU_3: case SR_CPU_MALFCPU_4: case SR_CPU_MALFCPU_5: case SR_CPU_MALFCPU_6: case SR_CPU_MALFCPU_7: case SR_CPU_MALFCPU_8: case SR_CPU_MALFCPU_9: case SR_CPU_MALFCPU_10: case SR_CPU_MALFCPU_11: case SR_CPU_MALFCPU_12: case SR_CPU_MALFCPU_13: case SR_CPU_MALFCPU_14: case SR_CPU_MALFCPU_15: case SR_CPU_MALFCPU_16: case SR_CPU_MALFCPU_17: case SR_CPU_MALFCPU_18: case SR_CPU_MALFCPU_19: case SR_CPU_MALFCPU_20: case SR_CPU_MALFCPU_21: case SR_CPU_MALFCPU_22: case SR_CPU_MALFCPU_23: case SR_CPU_MALFCPU_24: case SR_CPU_MALFCPU_25: case SR_CPU_MALFCPU_26: case SR_CPU_MALFCPU_27: case SR_CPU_MALFCPU_28: case SR_CPU_MALFCPU_29: case SR_CPU_MALFCPU_30: case SR_CPU_MALFCPU_31: SR_NULL_REGS_CHECK(regs); i = key - SR_CPU_MALFCPU; if (i < sysblk.maxcpu) SR_READ_VALUE(file, len, ®s->malfcpu[i], sizeof(regs->malfcpu[0])); break; case SR_CPU_EMERCPU_0: case SR_CPU_EMERCPU_1: case SR_CPU_EMERCPU_2: case SR_CPU_EMERCPU_3: case SR_CPU_EMERCPU_4: case SR_CPU_EMERCPU_5: case SR_CPU_EMERCPU_6: case SR_CPU_EMERCPU_7: case SR_CPU_EMERCPU_8: case SR_CPU_EMERCPU_9: case SR_CPU_EMERCPU_10: case SR_CPU_EMERCPU_11: case SR_CPU_EMERCPU_12: case SR_CPU_EMERCPU_13: case SR_CPU_EMERCPU_14: case SR_CPU_EMERCPU_15: case SR_CPU_EMERCPU_16: case SR_CPU_EMERCPU_17: case SR_CPU_EMERCPU_18: case SR_CPU_EMERCPU_19: case SR_CPU_EMERCPU_20: case SR_CPU_EMERCPU_21: case SR_CPU_EMERCPU_22: case SR_CPU_EMERCPU_23: case SR_CPU_EMERCPU_24: case SR_CPU_EMERCPU_25: case SR_CPU_EMERCPU_26: case SR_CPU_EMERCPU_27: case SR_CPU_EMERCPU_28: case SR_CPU_EMERCPU_29: case SR_CPU_EMERCPU_30: case SR_CPU_EMERCPU_31: SR_NULL_REGS_CHECK(regs); i = key - SR_CPU_EMERCPU; if (i < sysblk.maxcpu) SR_READ_VALUE(file, len, ®s->emercpu[i], sizeof(regs->emercpu[0])); break; case SR_DEV: SR_READ_VALUE(file, len, &devnum, sizeof(devnum)); TRACE("SR: Restoring Device %4.4X...\n", devnum); lcss=0; break; case SR_DEV_LCSS: SR_READ_VALUE(file, len, &lcss, sizeof(U16)); break; case SR_DEV_ARGC: SR_READ_VALUE(file, len, &devargc, sizeof(devargc)); if (devargc > 16) devargc = 16; for (i = 0; i < devargc; i++) devargv[i] = NULL; devargx = 0; break; case SR_DEV_ARGV: SR_READ_STRING(file, buf, len); if (devargx < devargc) devargv[devargx++] = strdup(buf); break; case SR_DEV_TYPNAME: SR_READ_STRING(file, buf, len); dev = find_device_by_devnum(lcss,devnum); if (dev == NULL) { if (attach_device (lcss, devnum, buf, devargc, devargv)) { // "SR: %04X: device initialization failed" WRMSG(HHC02015, "E", devnum); } } else if (strcmp(dev->typname, buf)) { // "SR: %04X: device type mismatch; '%s' found, '%s' expected" WRMSG(HHC02016, "W", devnum, buf, dev->typname); dev = NULL; } for (i = 0; i < devargx; i++) { if (devargv[i]) free(devargv[i]); devargv[i] = NULL; } devnum = devargc = devargx = 0; break; case SR_DEV_ORB: SR_SKIP_NULL_DEV(dev, file, len); if (len != sizeof(ORB)) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "ORB", len, (int)sizeof(ORB)); goto sr_error_exit; } SR_READ_BUF(file, &dev->orb, len); break; case SR_DEV_PMCW: SR_SKIP_NULL_DEV(dev, file, len); if (len != sizeof(PMCW)) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "PMCW", len, (int)sizeof(PMCW)); goto sr_error_exit; } SR_READ_BUF(file, &dev->pmcw, len); break; case SR_DEV_SCSW: SR_SKIP_NULL_DEV(dev, file, len); if (len != sizeof(SCSW)) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "SCSW", len, (int)sizeof(SCSW)); goto sr_error_exit; } SR_READ_BUF(file, &dev->scsw, len); break; case SR_DEV_PCISCSW: SR_SKIP_NULL_DEV(dev, file, len); if (len != sizeof(SCSW)) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "PCI SCSW", len, (int)sizeof(SCSW)); goto sr_error_exit; } SR_READ_BUF(file, &dev->pciscsw, len); break; case SR_DEV_ATTNSCSW: SR_SKIP_NULL_DEV(dev, file, len); if (len != sizeof(SCSW)) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "ATTN SCSW", len, (int)sizeof(SCSW)); goto sr_error_exit; } SR_READ_BUF(file, &dev->attnscsw, len); break; case SR_DEV_CSW: SR_SKIP_NULL_DEV(dev, file, len); if (len != 8) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "CSW", len, 8); goto sr_error_exit; } SR_READ_BUF(file, &dev->csw, len); break; case SR_DEV_PCICSW: SR_SKIP_NULL_DEV(dev, file, len); if (len != 8) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "PCI CSW", len, 8); goto sr_error_exit; } SR_READ_BUF(file, &dev->pcicsw, len); break; case SR_DEV_ATTNCSW: SR_SKIP_NULL_DEV(dev, file, len); if (len != 8) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "ATTN CSW", len, 8); goto sr_error_exit; } SR_READ_BUF(file, &dev->attncsw, len); break; case SR_DEV_ESW: SR_SKIP_NULL_DEV(dev, file, len); if (len != sizeof(ESW)) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "ESW", len, (int)sizeof(ESW)); goto sr_error_exit; } SR_READ_BUF(file, &dev->esw, len); break; case SR_DEV_ECW: SR_SKIP_NULL_DEV(dev, file, len); if (len != 32) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "ECW", len, 32); goto sr_error_exit; } SR_READ_BUF(file, &dev->ecw, len); break; case SR_DEV_SENSE: SR_SKIP_NULL_DEV(dev, file, len); if (len != 32) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "Sense", len, 32); goto sr_error_exit; } SR_READ_BUF(file, &dev->ecw, len); break; case SR_DEV_PGSTAT: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &dev->pgstat, sizeof(dev->pgstat)); break; case SR_DEV_PGID: SR_SKIP_NULL_DEV(dev, file, len); if (len != 11) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "PGID", len, 11); goto sr_error_exit; } SR_READ_BUF(file, &dev->pgid, len); break; /* By Adrian - SR_DEV_DRVPWD */ case SR_DEV_DRVPWD: SR_SKIP_NULL_DEV(dev, file, len); if (len != 11) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "DRVPWD", len, 11); goto sr_error_exit; } SR_READ_BUF(file, &dev->drvpwd, len); break; case SR_DEV_BUSY: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &rc, sizeof(rc)); dev->busy = rc; break; case SR_DEV_RESERVED: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &rc, sizeof(rc)); dev->reserved = rc; break; case SR_DEV_SUSPENDED: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &rc, sizeof(rc)); dev->suspended = rc; break; case SR_DEV_PENDING: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &rc, sizeof(rc)); dev->pending = rc; QUEUE_IO_INTERRUPT(&dev->ioint); break; case SR_DEV_PCIPENDING: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &rc, sizeof(rc)); dev->pcipending = rc; QUEUE_IO_INTERRUPT(&dev->pciioint); break; case SR_DEV_ATTNPENDING: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &rc, sizeof(rc)); dev->attnpending = rc; QUEUE_IO_INTERRUPT(&dev->attnioint); break; case SR_DEV_STARTPENDING: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &rc, sizeof(rc)); dev->startpending = rc; break; case SR_DEV_CRWPENDING: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &rc, sizeof(rc)); dev->crwpending = rc; break; case SR_DEV_CCWADDR: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &dev->ccwaddr, sizeof(dev->ccwaddr)); break; case SR_DEV_IDAPMASK: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &dev->idapmask, sizeof(dev->idapmask)); break; case SR_DEV_IDAWFMT: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &dev->idawfmt, sizeof(dev->idawfmt)); break; case SR_DEV_CCWFMT: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &dev->ccwfmt, sizeof(dev->ccwfmt)); break; case SR_DEV_CCWKEY: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &dev->ccwkey, sizeof(dev->ccwkey)); break; /* This is the trigger to call the device dependent resume routine */ case SR_DEV_DEVTYPE: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &hw, sizeof(hw)); if (hw != dev->devtype) { char buf1[20]; char buf2[20]; MSGBUF(buf1, "%04X", hw); MSGBUF(buf2, "%04X", dev->devtype); // "SR: %04X: device type mismatch; '%s' found, '%s' expected" WRMSG(HHC02016, "E", dev->devnum, buf1, buf2); goto sr_error_exit; } if (dev->hnd->hresume) { rc = (dev->hnd->hresume) (dev, file); if (rc < 0) goto sr_error_exit; } break; default: if ((key & SR_KEY_ID_MASK) != SR_KEY_ID) { // "SR: invalid key %8.8X" WRMSG(HHC02018, "E", key); goto sr_error_exit; } SR_READ_SKIP(file, len); break; } /* switch (key) */ } /* while (key != SR_EOF) */ TRACE("SR: Resume File Processing Complete...\n"); TRACE("SR: Resuming Devices...\n"); /* For all suspended devices, resume the `suspended' state */ for (dev = sysblk.firstdev; dev; dev = dev->nextdev) { if (dev->suspended && (dev->pmcw.flag5 & PMCW5_V)) { dev->resumesuspended=1; switch (sysblk.arch_mode) { #if defined(_370) case ARCH_370: rc = create_thread (&dev->tid, DETACHED, s370_execute_ccw_chain, dev, "device thread"); break; #endif #if defined(_390) case ARCH_390: rc = create_thread (&dev->tid, DETACHED, s390_execute_ccw_chain, dev, "device thread"); break; #endif #if defined(_900) case ARCH_900: rc = create_thread (&dev->tid, DETACHED, z900_execute_ccw_chain, dev, "device thread"); break; #endif } /* switch (sysblk.arch_mode) */ if (rc != 0) { // "Error in function create_thread(): %s" WRMSG(HHC00102, "E", strerror(rc)); goto sr_error_exit; } } /* If suspended device */ } /* For each device */ /* Indicate crw pending for any new devices */ #if defined(_370) if (sysblk.arch_mode != ARCH_370) #endif machine_check_crwpend(); /* Start the CPUs */ TRACE("SR: Resuming CPUs...\n"); OBTAIN_INTLOCK(NULL); ON_IC_IOPENDING; for (i = 0; i < sysblk.maxcpu; i++) if (IS_CPU_ONLINE(i) && (started_mask & CPU_BIT(i))) { sysblk.regs[i]->opinterv = 0; sysblk.regs[i]->cpustate = CPUSTATE_STARTED; sysblk.regs[i]->checkstop = 0; WAKEUP_CPU(sysblk.regs[i]); } RELEASE_INTLOCK(NULL); TRACE("SR: Resume Complete; System Resumed.\n"); return 0; sr_null_regs_exit: // "SR: CPU key %8.8X found but no active CPU" WRMSG(HHC02019, "E", key); goto sr_error_exit; sr_error_exit: // "SR: error processing file '%s'" WRMSG(HHC02004, "E", fn); SR_CLOSE (file); return -1; }