예제 #1
0
파일: cgibin.c 프로젝트: mstram/spinhawk
void cgibin_reg_general(WEBBLK *webblk)
{
int i;

    REGS *regs;

    regs = sysblk.regs[sysblk.pcpu];
    if (!regs) regs = &sysblk.dummyregs;

    html_header(webblk);

    hprintf(webblk->sock, "<H2>General Registers</H2>\n");
    hprintf(webblk->sock, "<PRE>\n");
    if(regs->arch_mode != ARCH_900)
        for (i = 0; i < 16; i++)
            hprintf(webblk->sock, "GR%2.2d=%8.8X%s", i, regs->GR_L(i),
                ((i & 0x03) == 0x03) ? "\n" : "\t");
    else
        for (i = 0; i < 16; i++)
            hprintf(webblk->sock, "GR%1.1X=%16.16" I64_FMT "X%s", i,
                (U64)regs->GR_G(i), ((i & 0x03) == 0x03) ? "\n" : " ");

    hprintf(webblk->sock, "</PRE>\n");

    html_footer(webblk);

}
예제 #2
0
파일: cgibin.c 프로젝트: mstram/spinhawk
void cgibin_debug_registers(WEBBLK *webblk)
{
int i, cpu = 0;
int select_gr, select_cr, select_ar;
char *value;
REGS *regs;

    if((value = cgi_variable(webblk,"cpu")))
        cpu = atoi(value);

    if((value = cgi_variable(webblk,"select_gr")) && *value == 'S')
        select_gr = 1;
    else
        select_gr = 0;

    if((value = cgi_variable(webblk,"select_cr")) && *value == 'S')
        select_cr = 1;
    else
        select_cr = 0;

    if((value = cgi_variable(webblk,"select_ar")) && *value == 'S')
        select_ar = 1;
    else
        select_ar = 0;

    /* Validate cpu number */
    if (cpu < 0 || cpu >= MAX_CPU || !IS_CPU_ONLINE(cpu))
        for (cpu = 0; cpu < MAX_CPU; cpu++)
            if(IS_CPU_ONLINE(cpu))
                break;

    if(cpu < MAX_CPU)
        regs = sysblk.regs[cpu];
    else
        regs = sysblk.regs[sysblk.pcpu];

    if (!regs) regs = &sysblk.dummyregs;

    if((value = cgi_variable(webblk,"alter_gr")) && *value == 'A')
    {
        for(i = 0; i < 16; i++)
        {
        char regname[16];
            sprintf(regname,"alter_gr%d",i);
            if((value = cgi_variable(webblk,regname)))
            {
                if(regs->arch_mode != ARCH_900)
                    sscanf(value,"%"I32_FMT"x",&(regs->GR_L(i)));
                else
                    sscanf(value,"%"I64_FMT"x",&(regs->GR_G(i)));
            }
        }
    }

    if((value = cgi_variable(webblk,"alter_cr")) && *value == 'A')
    {
        for(i = 0; i < 16; i++)
        {
        char regname[16];
            sprintf(regname,"alter_cr%d",i);
            if((value = cgi_variable(webblk,regname)))
            {
                if(regs->arch_mode != ARCH_900)
                    sscanf(value,"%"I32_FMT"x",&(regs->CR_L(i)));
                else
                    sscanf(value,"%"I64_FMT"x",&(regs->CR_G(i)));
            }
        }
    }

    if((value = cgi_variable(webblk,"alter_ar")) && *value == 'A')
    {
        for(i = 0; i < 16; i++)
        {
        char regname[16];
            sprintf(regname,"alter_ar%d",i);
            if((value = cgi_variable(webblk,regname)))
                sscanf(value,"%x",&(regs->AR(i)));
        }
    }

    html_header(webblk);

    hprintf(webblk->sock,"<form method=post>\n"
                          "<select type=submit name=cpu>\n");

    for(i = 0; i < MAX_CPU; i++)
        if(IS_CPU_ONLINE(i))
            hprintf(webblk->sock,"<option value=%d%s>CPU%4.4X</option>\n",
              i,i==cpu?" selected":"",i);

    hprintf(webblk->sock,"</select>\n"
                          "<input type=submit name=selcpu value=\"Select\">\n"
                          "<input type=hidden name=cpu value=%d>\n"
                          "<input type=hidden name=select_gr value=%c>\n"
                          "<input type=hidden name=select_cr value=%c>\n"
                          "<input type=hidden name=select_ar value=%c>\n",
                          cpu, select_gr?'S':'H',select_cr?'S':'H',select_ar?'S':'H');
    hprintf(webblk->sock,"Mode: %s\n",get_arch_mode_string(regs));
    hprintf(webblk->sock,"</form>\n");

    if(!select_gr)
    {
        hprintf(webblk->sock,"<form method=post>\n"
                              "<input type=submit name=select_gr "
                              "value=\"Select General Registers\">\n"
                              "<input type=hidden name=cpu value=%d>\n"
                              "<input type=hidden name=select_cr value=%c>\n"
                              "<input type=hidden name=select_ar value=%c>\n"
                              "</form>\n",cpu,select_cr?'S':'H',select_ar?'S':'H');
    }
    else
    {
        hprintf(webblk->sock,"<form method=post>\n"
                              "<input type=submit name=select_gr "
                              "value=\"Hide General Registers\">\n"
                              "<input type=hidden name=cpu value=%d>\n"
                              "<input type=hidden name=select_cr value=%c>\n"
                              "<input type=hidden name=select_ar value=%c>\n"
                              "</form>\n",cpu,select_cr?'S':'H',select_ar?'S':'H');

        hprintf(webblk->sock,"<form method=post>\n"
                              "<table>\n");
        for(i = 0; i < 16; i++)
        {
            if(regs->arch_mode != ARCH_900)
                hprintf(webblk->sock,"%s<td>GR%d</td><td><input type=text name=alter_gr%d size=8 "
                  "value=%8.8X></td>\n%s",
                  (i&3)==0?"<tr>\n":"",i,i,regs->GR_L(i),((i&3)==3)?"</tr>\n":"");
            else
                hprintf(webblk->sock,"%s<td>GR%d</td><td><input type=text name=alter_gr%d size=16 "
                  "value=%16.16" I64_FMT "X></td>\n%s",
                  (i&3)==0?"<tr>\n":"",i,i,(U64)regs->GR_G(i),((i&3)==3)?"</tr>\n":"");
        }
        hprintf(webblk->sock,"</table>\n"
                              "<input type=submit name=refresh value=\"Refresh\">\n"
                              "<input type=submit name=alter_gr value=\"Alter\">\n"
                              "<input type=hidden name=cpu value=%d>\n"
                              "<input type=hidden name=select_gr value=S>\n"
                              "<input type=hidden name=select_cr value=%c>\n"
                              "<input type=hidden name=select_ar value=%c>\n"
                              "</form>\n",cpu,select_cr?'S':'H',select_ar?'S':'H');
    }


    if(!select_cr)
    {
        hprintf(webblk->sock,"<form method=post>\n"
                              "<input type=submit name=select_cr "
                              "value=\"Select Control Registers\">\n"
                              "<input type=hidden name=cpu value=%d>\n"
                              "<input type=hidden name=select_gr value=%c>\n"
                              "<input type=hidden name=select_ar value=%c>\n"
                              "</form>\n",cpu,select_gr?'S':'H',select_ar?'S':'H');
    }
    else
    {
        hprintf(webblk->sock,"<form method=post>\n"
                              "<input type=submit name=select_cr "
                              "value=\"Hide Control Registers\">\n"
                              "<input type=hidden name=cpu value=%d>\n"
                              "<input type=hidden name=select_gr value=%c>\n"
                              "<input type=hidden name=select_ar value=%c>\n"
                              "</form>\n",cpu,select_gr?'S':'H',select_ar?'S':'H');

        hprintf(webblk->sock,"<form method=post>\n"
                              "<table>\n");
        for(i = 0; i < 16; i++)
        {
            if(regs->arch_mode != ARCH_900)
                hprintf(webblk->sock,"%s<td>CR%d</td><td><input type=text name=alter_cr%d size=8 "
                  "value=%8.8X></td>\n%s",
                  (i&3)==0?"<tr>\n":"",i,i,regs->CR_L(i),((i&3)==3)?"</tr>\n":"");
            else
                hprintf(webblk->sock,"%s<td>CR%d</td><td><input type=text name=alter_cr%d size=16 "
                  "value=%16.16" I64_FMT "X></td>\n%s",
                  (i&3)==0?"<tr>\n":"",i,i,(U64)regs->CR_G(i),((i&3)==3)?"</tr>\n":"");
        }
        hprintf(webblk->sock,"</table>\n"
                              "<input type=submit name=refresh value=\"Refresh\">\n"
                              "<input type=submit name=alter_cr value=\"Alter\">\n"
                              "<input type=hidden name=cpu value=%d>\n"
                              "<input type=hidden name=select_cr value=S>\n"
                              "<input type=hidden name=select_gr value=%c>\n"
                              "<input type=hidden name=select_ar value=%c>\n"
                              "</form>\n",cpu,select_gr?'S':'H',select_ar?'S':'H');
    }


    if(regs->arch_mode != ARCH_370)
    {
        if(!select_ar)
        {
            hprintf(webblk->sock,"<form method=post>\n"
                                  "<input type=submit name=select_ar "
                                  "value=\"Select Access Registers\">\n"
                                  "<input type=hidden name=cpu value=%d>\n"
                                  "<input type=hidden name=select_gr value=%c>\n"
                                  "<input type=hidden name=select_cr value=%c>\n"
                                  "</form>\n",cpu,select_gr?'S':'H',select_cr?'S':'H');
        }
        else
        {
            hprintf(webblk->sock,"<form method=post>\n"
                                  "<input type=submit name=select_ar "
                                  "value=\"Hide Access Registers\">\n"
                                  "<input type=hidden name=cpu value=%d>\n"
                                  "<input type=hidden name=select_gr value=%c>\n"
                                  "<input type=hidden name=select_cr value=%c>\n"
                                  "</form>\n",cpu,select_gr?'S':'H',select_cr?'S':'H');

            hprintf(webblk->sock,"<form method=post>\n"
                                  "<table>\n");
            for(i = 0; i < 16; i++)
            {
                hprintf(webblk->sock,"%s<td>AR%d</td><td><input type=text name=alter_ar%d size=8 "
                  "value=%8.8X></td>\n%s",
                  (i&3)==0?"<tr>\n":"",i,i,regs->AR(i),((i&3)==3)?"</tr>\n":"");
            }
            hprintf(webblk->sock,"</table>\n"
                                  "<input type=submit name=refresh value=\"Refresh\">\n"
                                  "<input type=submit name=alter_ar value=\"Alter\">\n"
                                  "<input type=hidden name=cpu value=%d>\n"
                                  "<input type=hidden name=select_gr value=%c>\n"
                                  "<input type=hidden name=select_cr value=%c>\n"
                                  "<input type=hidden name=select_ar value=S>\n"
                                  "</form>\n",cpu,select_gr?'S':'H',select_cr?'S':'H');
        }
    }

    html_footer(webblk);

}
예제 #3
0
int suspend_cmd(int argc, char *argv[],char *cmdline)
{
char    *fn = SR_DEFAULT_FILENAME;
SR_FILE *file;
CPU_BITMAP started_mask;
struct   timeval tv;
time_t   tt;
int      i, j, rc;
REGS    *regs;
DEVBLK  *dev;
IOINT   *ioq;
BYTE     psw[16];

    UNREFERENCED(cmdline);

    if (argc > 2)
    {
        // "SR: too many arguments"
        WRMSG(HHC02000, "E");
        return -1;
    }

    if (argc == 2)
        fn = argv[1];

    file = SR_OPEN (fn, "wb");
    if (file == NULL)
    {
        // "SR: error in function '%s': '%s'"
        WRMSG(HHC02001, "E","open()",strerror(errno));
        return -1;
    }

    TRACE("SR: Begin Suspend Processing...\n");

    /* Save CPU state and stop all CPU's */
    TRACE("SR: Stopping All CPUs...\n");
    OBTAIN_INTLOCK(NULL);
    started_mask = sysblk.started_mask;
    while (sysblk.started_mask)
    {
        for (i = 0; i < sysblk.maxcpu; i++)
        {
            if (IS_CPU_ONLINE(i))
            {
                sysblk.regs[i]->cpustate = CPUSTATE_STOPPING;
                ON_IC_INTERRUPT(sysblk.regs[i]);
                signal_condition(&sysblk.regs[i]->intcond);
            }
        }
        RELEASE_INTLOCK(NULL);
        usleep (1000);
        OBTAIN_INTLOCK(NULL);
    }
    RELEASE_INTLOCK(NULL);

    /* Wait for I/O queue to clear out */
    TRACE("SR: Waiting for I/O Queue to clear...\n");
#ifdef OPTION_FISHIO
    SLEEP (2);
#else
    obtain_lock (&sysblk.ioqlock);
    while (sysblk.ioq)
    {
        release_lock (&sysblk.ioqlock);
        usleep (1000);
        obtain_lock (&sysblk.ioqlock);
    }
    release_lock (&sysblk.ioqlock);
#endif

    /* Wait for active I/Os to complete */
    TRACE("SR: Waiting for Active I/Os to Complete...\n");
    for (i = 1; i < 5000; i++)
    {
        dev = sr_active_devices();
        if (dev == NULL) break;
        if (i % 500 == 0)
        {
            // "SR: waiting for device %04X"
            WRMSG(HHC02002, "W", dev->devnum);
        }
        usleep (10000);
    }
    if (dev != NULL)
    {
        // "SR: device %04X still busy, proceeding anyway"
        WRMSG(HHC02003, "W",dev->devnum);
    }

    /* Write header */
    TRACE("SR: Writing File Header...\n");
    SR_WRITE_STRING(file, SR_HDR_ID, SR_ID);
    SR_WRITE_STRING(file, SR_HDR_VERSION, VERSION);
    gettimeofday(&tv, NULL); tt = tv.tv_sec;
    SR_WRITE_STRING(file, SR_HDR_DATE, ctime(&tt));

    /* Write system data */
    TRACE("SR: Saving System Data...\n");
    SR_WRITE_STRING(file,SR_SYS_ARCH_NAME,arch_name[sysblk.arch_mode]);
    SR_WRITE_VALUE (file,SR_SYS_STARTED_MASK,started_mask,sizeof(started_mask));
    SR_WRITE_VALUE (file,SR_SYS_MAINSIZE,sysblk.mainsize,sizeof(sysblk.mainsize));
    TRACE("SR: Saving MAINSTOR...\n");
    SR_WRITE_BUF   (file,SR_SYS_MAINSTOR,sysblk.mainstor,sysblk.mainsize);
    SR_WRITE_VALUE (file,SR_SYS_SKEYSIZE,(sysblk.mainsize/STORAGE_KEY_UNITSIZE),sizeof(U32));
    TRACE("SR: Saving Storage Keys...\n");
    SR_WRITE_BUF   (file,SR_SYS_STORKEYS,sysblk.storkeys,sysblk.mainsize/STORAGE_KEY_UNITSIZE);
    SR_WRITE_VALUE (file,SR_SYS_XPNDSIZE,sysblk.xpndsize,sizeof(sysblk.xpndsize));
    TRACE("SR: Saving Expanded Storage...\n");
    SR_WRITE_BUF   (file,SR_SYS_XPNDSTOR,sysblk.xpndstor,4096*sysblk.xpndsize);
    SR_WRITE_VALUE (file,SR_SYS_CPUID,sysblk.cpuid,sizeof(sysblk.cpuid));
    SR_WRITE_VALUE (file,SR_SYS_IPLDEV,sysblk.ipldev,sizeof(sysblk.ipldev));
    SR_WRITE_VALUE (file,SR_SYS_IPLCPU,sysblk.iplcpu,sizeof(sysblk.iplcpu));
    SR_WRITE_VALUE (file,SR_SYS_MBO,sysblk.mbo,sizeof(sysblk.mbo));
    SR_WRITE_VALUE (file,SR_SYS_MBK,sysblk.mbk,sizeof(sysblk.mbk));
    SR_WRITE_VALUE (file,SR_SYS_MBM,sysblk.mbm,sizeof(sysblk.mbm));
    SR_WRITE_VALUE (file,SR_SYS_MBD,sysblk.mbd,sizeof(sysblk.mbd));

    for (ioq = sysblk.iointq; ioq; ioq = ioq->next)
        if (ioq->pcipending)
        {
            SR_WRITE_VALUE(file,SR_SYS_PCIPENDING_LCSS, SSID_TO_LCSS(ioq->dev->ssid),sizeof(U16));
            SR_WRITE_VALUE(file,SR_SYS_PCIPENDING, ioq->dev->devnum,sizeof(ioq->dev->devnum));
        }
        else if (ioq->attnpending)
        {
            SR_WRITE_VALUE(file,SR_SYS_ATTNPENDING_LCSS, SSID_TO_LCSS(ioq->dev->ssid),sizeof(U16));
            SR_WRITE_VALUE(file,SR_SYS_ATTNPENDING, ioq->dev->devnum,sizeof(ioq->dev->devnum));
        }
        else
        {
            SR_WRITE_VALUE(file,SR_SYS_IOPENDING_LCSS, SSID_TO_LCSS(ioq->dev->ssid),sizeof(U16));
            SR_WRITE_VALUE(file,SR_SYS_IOPENDING, ioq->dev->devnum,sizeof(ioq->dev->devnum));
        }

    for (i = 0; i < 8; i++)
        SR_WRITE_VALUE(file,SR_SYS_CHP_RESET+i,sysblk.chp_reset[i],sizeof(sysblk.chp_reset[0]));

    SR_WRITE_VALUE (file,SR_SYS_SERVPARM,sysblk.servparm,sizeof(sysblk.servparm));
    SR_WRITE_VALUE (file,SR_SYS_SIGINTREQ,sysblk.sigintreq,1);
    SR_WRITE_STRING(file,SR_SYS_LOADPARM,str_loadparm());
    SR_WRITE_VALUE (file,SR_SYS_INTS_STATE,sysblk.ints_state,sizeof(sysblk.ints_state));
    SR_WRITE_HDR(file, SR_DELIMITER, 0);

    /* Save service console state */
    TRACE("SR: Saving Service Console State...\n");
    SR_WRITE_HDR(file, SR_SYS_SERVC, 0);
    servc_hsuspend(file);
    SR_WRITE_HDR(file, SR_DELIMITER, 0);

    /* Save clock state */
    TRACE("SR: Saving Clock State...\n");
    SR_WRITE_HDR(file, SR_SYS_CLOCK, 0);
    clock_hsuspend(file);
    SR_WRITE_HDR(file, SR_DELIMITER, 0);

    /* Write CPU data */
    for (i = 0; i < sysblk.maxcpu; i++)
    {
        if (!IS_CPU_ONLINE(i)) continue;

        TRACE("SR: Saving CPU %d Data...\n", i);

        regs = sysblk.regs[i];
        SR_WRITE_VALUE(file, SR_CPU, i, sizeof(i));
        SR_WRITE_VALUE(file, SR_CPU_ARCHMODE, regs->arch_mode,sizeof(regs->arch_mode));
        SR_WRITE_VALUE(file, SR_CPU_PX, regs->PX_G,sizeof(regs->PX_G));
        copy_psw (regs, psw);
        SR_WRITE_BUF(file, SR_CPU_PSW, psw, 16);
        for (j = 0; j < 16; j++)
            SR_WRITE_VALUE(file, SR_CPU_GR+j, regs->GR_G(j),sizeof(regs->GR_G(0)));
        for (j = 0; j < 16; j++)
            SR_WRITE_VALUE(file, SR_CPU_CR+j, regs->CR_G(j),sizeof(regs->CR_G(0)));
        for (j = 0; j < 16; j++)
            SR_WRITE_VALUE(file, SR_CPU_AR+j, regs->ar[j],sizeof(regs->ar[0]));
        for (j = 0; j < 32; j++)
            SR_WRITE_VALUE(file, SR_CPU_FPR+j, regs->fpr[j],sizeof(regs->fpr[0]));
        SR_WRITE_VALUE(file, SR_CPU_FPC, regs->fpc, sizeof(regs->fpc));
        SR_WRITE_VALUE(file, SR_CPU_DXC, regs->dxc, sizeof(regs->dxc));
        SR_WRITE_VALUE(file, SR_CPU_MC, regs->MC_G, sizeof(regs->MC_G));
        SR_WRITE_VALUE(file, SR_CPU_EA, regs->EA_G, sizeof(regs->EA_G));
        SR_WRITE_VALUE(file, SR_CPU_PTIMER, cpu_timer(regs), sizeof(S64));
        SR_WRITE_VALUE(file, SR_CPU_CLKC, regs->clkc, sizeof(regs->clkc));
        SR_WRITE_VALUE(file, SR_CPU_CHANSET, regs->chanset, sizeof(regs->chanset));
        SR_WRITE_VALUE(file, SR_CPU_TODPR, regs->todpr, sizeof(regs->todpr));
        SR_WRITE_VALUE(file, SR_CPU_MONCLASS, regs->monclass, sizeof(regs->monclass));
        SR_WRITE_VALUE(file, SR_CPU_EXCARID, regs->excarid, sizeof(regs->excarid));
        SR_WRITE_VALUE(file, SR_CPU_BEAR, regs->bear, sizeof(regs->bear));
        SR_WRITE_VALUE(file, SR_CPU_OPNDRID, regs->opndrid, sizeof(regs->opndrid));
        SR_WRITE_VALUE(file, SR_CPU_CHECKSTOP, regs->checkstop, 1);
        SR_WRITE_VALUE(file, SR_CPU_HOSTINT, regs->hostint, 1);
        SR_WRITE_VALUE(file, SR_CPU_EXECFLAG, regs->execflag, 1);
//      SR_WRITE_VALUE(file, SR_CPU_INSTVALID, regs->instvalid, 1);
        SR_WRITE_VALUE(file, SR_CPU_PERMODE, regs->permode, 1);
        SR_WRITE_VALUE(file, SR_CPU_LOADSTATE, regs->loadstate, 1);
        SR_WRITE_VALUE(file, SR_CPU_INVALIDATE, regs->invalidate, 1);
        SR_WRITE_VALUE(file, SR_CPU_SIGPRESET, regs->sigpreset, 1);
        SR_WRITE_VALUE(file, SR_CPU_SIGPIRESET, regs->sigpireset, 1);
        SR_WRITE_VALUE(file, SR_CPU_INTS_STATE, regs->ints_state, sizeof(regs->ints_state));
        SR_WRITE_VALUE(file, SR_CPU_INTS_MASK, regs->ints_mask, sizeof(regs->ints_mask));
        for (j = 0; j < sysblk.maxcpu; j++)
            SR_WRITE_VALUE(file, SR_CPU_MALFCPU+j, regs->malfcpu[j], sizeof(regs->malfcpu[0]));
        for (j = 0; j < sysblk.maxcpu; j++)
            SR_WRITE_VALUE(file, SR_CPU_EMERCPU+j, regs->emercpu[j], sizeof(regs->emercpu[0]));
        SR_WRITE_VALUE(file, SR_CPU_EXTCCPU, regs->extccpu, sizeof(regs->extccpu));
        SR_WRITE_HDR(file, SR_DELIMITER, 0);
    }

    /* Write Device data */
    for (dev = sysblk.firstdev; dev; dev = dev->nextdev)
    {
        if (!(dev->pmcw.flag5 & PMCW5_V)) continue;

        TRACE("SR: Saving Device %4.4X...\n", dev->devnum);

        /* These fields must come first so the device could be attached */
        SR_WRITE_VALUE(file, SR_DEV, dev->devnum, sizeof(dev->devnum));
        SR_WRITE_VALUE(file, SR_DEV_LCSS, SSID_TO_LCSS(dev->ssid), sizeof(U16));
        SR_WRITE_VALUE(file, SR_DEV_ARGC, dev->argc, sizeof(dev->argc));
        for (i = 0; i < dev->argc; i++)
            if (dev->argv[i])
            {
                SR_WRITE_STRING(file, SR_DEV_ARGV, dev->argv[i]);
            }
            else
            {
                SR_WRITE_STRING(file, SR_DEV_ARGV, "");
            }
        SR_WRITE_STRING(file, SR_DEV_TYPNAME, dev->typname);

        /* Common device fields */
        SR_WRITE_BUF  (file, SR_DEV_ORB, &dev->orb, sizeof(ORB));
        SR_WRITE_BUF  (file, SR_DEV_PMCW, &dev->pmcw, sizeof(PMCW));
        SR_WRITE_BUF  (file, SR_DEV_SCSW, &dev->scsw, sizeof(SCSW));
        SR_WRITE_BUF  (file, SR_DEV_PCISCSW, &dev->pciscsw, sizeof(SCSW));
        SR_WRITE_BUF  (file, SR_DEV_ATTNSCSW, &dev->attnscsw, sizeof(SCSW));
        SR_WRITE_BUF  (file, SR_DEV_CSW, dev->csw, 8);
        SR_WRITE_BUF  (file, SR_DEV_PCICSW, dev->pcicsw, 8);
        SR_WRITE_BUF  (file, SR_DEV_ATTNCSW, dev->attncsw, 8);
        SR_WRITE_BUF  (file, SR_DEV_ESW, &dev->esw, sizeof(ESW));
        SR_WRITE_BUF  (file, SR_DEV_ECW, dev->ecw, 32);
        SR_WRITE_BUF  (file, SR_DEV_SENSE, dev->sense, 32);
        SR_WRITE_VALUE(file, SR_DEV_PGSTAT, dev->pgstat, sizeof(dev->pgstat));
        SR_WRITE_BUF  (file, SR_DEV_PGID, dev->pgid, 11);
        /* By Adrian - SR_DEV_DRVPWD */
        SR_WRITE_BUF  (file, SR_DEV_DRVPWD, dev->drvpwd, 11);
        SR_WRITE_VALUE(file, SR_DEV_BUSY, dev->busy, 1);
        SR_WRITE_VALUE(file, SR_DEV_RESERVED, dev->reserved, 1);
        SR_WRITE_VALUE(file, SR_DEV_SUSPENDED, dev->suspended, 1);
        SR_WRITE_VALUE(file, SR_DEV_PCIPENDING, dev->pcipending, 1);
        SR_WRITE_VALUE(file, SR_DEV_ATTNPENDING, dev->attnpending, 1);
        SR_WRITE_VALUE(file, SR_DEV_PENDING, dev->pending, 1);
        SR_WRITE_VALUE(file, SR_DEV_STARTPENDING, dev->startpending, 1);
        SR_WRITE_VALUE(file, SR_DEV_CRWPENDING, dev->crwpending, 1);
        SR_WRITE_VALUE(file, SR_DEV_CCWADDR, dev->ccwaddr, sizeof(dev->ccwaddr));
        SR_WRITE_VALUE(file, SR_DEV_IDAPMASK, dev->idapmask, sizeof(dev->idapmask));
        SR_WRITE_VALUE(file, SR_DEV_IDAWFMT, dev->idawfmt, sizeof(dev->idawfmt));
        SR_WRITE_VALUE(file, SR_DEV_CCWFMT, dev->ccwfmt, sizeof(dev->ccwfmt));
        SR_WRITE_VALUE(file, SR_DEV_CCWKEY, dev->ccwkey, sizeof(dev->ccwkey));

        /* Device type specific data */
        SR_WRITE_VALUE(file, SR_DEV_DEVTYPE, dev->devtype, sizeof(dev->devtype));
        if (dev->hnd->hsuspend)
        {
            rc = (dev->hnd->hsuspend) (dev, file);
            if (rc < 0) goto sr_error_exit;
        }
        SR_WRITE_HDR(file, SR_DELIMITER, 0);
    }

    TRACE("SR: Writing EOF\n");

    SR_WRITE_HDR(file, SR_EOF, 0);
    SR_CLOSE (file);

    TRACE("SR: Suspend Complete; shutting down...\n");

    /* Shutdown */
    do_shutdown();

    return 0;

sr_error_exit:
    // "SR: error processing file '%s'"
    WRMSG(HHC02004, "E", fn);
    SR_CLOSE (file);
    return -1;
}