예제 #1
0
/*--------------------------------------------------------------------*/
DLL_EXPORT void  mpc_display_ptp_th_etc( DEVBLK* pDEVBLK, MPC_TH* pMPC_TH, BYTE bDir, int iLimit )
{
    MPC_RRH*   pMPC_RRH;
    int        iForRRH;
    U32        uOffRRH;
    U16        uNumRRH;

    /* Display MPC_TH. */
    mpc_display_th( pDEVBLK, pMPC_TH, bDir );

    /* Get the number of MPC_RRHs and the displacement from    */
    /* the start of the MPC_TH to the first (or only) MPC_RRH. */
    FETCH_HW( uNumRRH, pMPC_TH->numrrh );
    FETCH_FW( uOffRRH, pMPC_TH->offrrh );

    /* Process each of the MPC_RRHs. */
    for( iForRRH = 1; iForRRH <= uNumRRH; iForRRH++ )
    {

        /* Point to the first or subsequent MPC_RRH. */
        pMPC_RRH = (MPC_RRH*)((BYTE*)pMPC_TH + uOffRRH);

        /* Display the MPC_RRH etc. */
        if( pMPC_RRH->proto == PROTOCOL_LAYER2 &&
                pMPC_RRH->type == RRH_TYPE_CM )
        {
            /* Display MPC_RRH and following packet data. */
            mpc_display_rrh_and_pkt( pDEVBLK, pMPC_TH, pMPC_RRH, bDir, iLimit );
        }
        else if( pMPC_RRH->proto == PROTOCOL_LAYER2 &&
                 pMPC_RRH->type == RRH_TYPE_IPA )
        {
            /* Display MPC_RRH and following MPC_PIX etc. */
            mpc_display_rrh_and_pix( pDEVBLK, pMPC_TH, pMPC_RRH, bDir );
        }
        else if( pMPC_RRH->proto == PROTOCOL_UNKNOWN )
        {
            /* Display MPC_RRH and following MPC_PUK etc. */
            mpc_display_rrh_and_puk( pDEVBLK, pMPC_TH, pMPC_RRH, bDir );
        }
        else
        {
            /* Display MPC_RRH */
            mpc_display_rrh( pDEVBLK, pMPC_RRH, bDir );
        }

        /* Get the displacement from the start of the MPC_TH to the */
        /* next MPC_RRH. pMPC_RRH->offrrh will contain zero if this */
        /* is the last MPC_RRH.                                     */
        FETCH_FW( uOffRRH, pMPC_RRH->offrrh );

    }

    return;
}   /* End function  mpc_display_ptp_th_etc() */
예제 #2
0
파일: scedasd.c 프로젝트: bluecmd/hyperion
static int ARCH_DEP(scedio_ior)(SCCB_SCEDIOR_BK *scedior_bk)
{
U32  origin;
char image[9];
S32  size;
unsigned int i;
char filename[MAX_PATH];

    FETCH_FW(origin,scedior_bk->origin);

    /* Convert image filename to null terminated ascii string */
    for(i = 0; i < sizeof(image)-1 && scedior_bk->image[i] != 0x40; i++)
        image[i] = guest_to_host((int)scedior_bk->image[i]);
    image[i] = '\0';

    /* Ensure file access is allowed and within specified directory */
    if(!check_sce_filepath(image,filename))
    {
        if(errno != ENOENT)
            WRMSG (HHC00604, "E", filename, image, strerror(errno));
        return FALSE;
    }

    size = ARCH_DEP(load_main)(filename,origin,0);

    return (size >= 0) ? TRUE : FALSE;
}
예제 #3
0
/*--------------------------------------------------------------------*/
DLL_EXPORT void  mpc_display_th( DEVBLK* pDEVBLK, MPC_TH* pMPC_TH, BYTE bDir )
{
    U32    uOffRRH;

    // Display the MPC_TH.
    FETCH_FW( uOffRRH, pMPC_TH->offrrh );
    mpc_display_stuff( pDEVBLK, "TH", (BYTE*)pMPC_TH, uOffRRH, bDir );

    return;
}   /* End function  mpc_display_th() */
예제 #4
0
파일: cgibin.c 프로젝트: mstram/spinhawk
void cgibin_debug_storage(WEBBLK *webblk)
{
int i, j;
char *value;
U32 addr = 0;

    /* INCOMPLETE
     * no storage alter
     * no storage type (abs/real/prim virt/sec virt/access reg virt)
     * no cpu selection for storage other then abs
     */

    if((value = cgi_variable(webblk,"alter_a0")))
        sscanf(value,"%x",&addr);

    addr &= ~0x0F;

    html_header(webblk);


    hprintf(webblk->sock,"<form method=post>\n"
                          "<table>\n");

    if(addr > sysblk.mainsize || (addr + 128) > sysblk.mainsize)
        addr = sysblk.mainsize - 128;

    for(i = 0; i < 128;)
    {
        if(i == 0)
            hprintf(webblk->sock,"<tr>\n"
                                  "<td><input type=text name=alter_a0 size=8 value=%8.8X>"
                                  "<input type=hidden name=alter_a1 value=%8.8X></td>\n"
                                  "<td><input type=submit name=refresh value=\"Refresh\"></td>\n",
                                  i + addr, i + addr);
        else
            hprintf(webblk->sock,"<tr>\n"
                                  "<td align=center>%8.8X</td>\n"
                                  "<td></td>\n",
                                  i + addr);

    for(j = 0; j < 4; i += 4, j++)
        {
        U32 m;
            FETCH_FW(m,sysblk.mainstor + i + addr);
            hprintf(webblk->sock,"<td><input type=text name=alter_m%d size=8 value=%8.8X></td>\n",i,m);
        }

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

    hprintf(webblk->sock,"</table>\n"
                          "</form>\n");
    html_footer(webblk);

}
예제 #5
0
/*--------------------------------------------------------------------*/
DLL_EXPORT void  mpc_display_rrh_and_pdu( DEVBLK* pDEVBLK, MPC_TH* pMPC_TH, MPC_RRH* pMPC_RRH, BYTE bDir, int iLimit )
{
    MPC_PH*    pMPC_PH;
    U16        uNumPH;
    U16        uOffPH;
    int        iForPH;
    int        iDone;
    U32        uLenData;
    U32        uOffData;
    BYTE*      pData;

    /* Display the MPC_RRH.*/
    FETCH_HW( uOffPH, pMPC_RRH->offph );
    mpc_display_stuff( pDEVBLK, "RRH", (BYTE*)pMPC_RRH, uOffPH, bDir );

    /* Display the MPC_PH(s). */
    FETCH_HW( uNumPH, pMPC_RRH->numph );
    pMPC_PH = (MPC_PH*)((BYTE*)pMPC_RRH + uOffPH);
    for( iForPH = 1; iForPH <= uNumPH; iForPH++ )
    {
        mpc_display_stuff( pDEVBLK, "PH", (BYTE*)pMPC_PH, SIZE_PH, bDir );
        pMPC_PH = (MPC_PH*)((BYTE*)pMPC_PH + SIZE_PH);
    }

    /* Display the data referenced by the MPC_PH(s).              */
    /* if limit is negative or a silly number, don't display the  */
    /* data. If limit is zero, display all of the data, otherwise */
    /* limit the length of the data displayed.                    */
    iDone = 0;
    if( iLimit >= 0 && iLimit <= 65535 )
    {
        pMPC_PH = (MPC_PH*)((BYTE*)pMPC_RRH + uOffPH);
        for( iForPH = 1; iForPH <= uNumPH; iForPH++ )
        {
            FETCH_F3( uLenData, pMPC_PH->lendata );
            FETCH_FW( uOffData, pMPC_PH->offdata );
            pData = (BYTE*)pMPC_TH + uOffData;
            if( iLimit > 0 )
            {
                if( iDone >= iLimit )
                    break;
                if( (int)uLenData > ( iLimit - iDone ) )
                    uLenData = ( iLimit - iDone );
                iDone =+ uLenData;
            }
            mpc_display_stuff( pDEVBLK, "PDU", pData, uLenData, bDir );
            pMPC_PH = (MPC_PH*)((BYTE*)pMPC_PH + SIZE_PH);
        }
    }

    return;
}   /* End function  mpc_display_rrh_and_pdu() */
예제 #6
0
/*--------------------------------------------------------------------*/
DLL_EXPORT void  mpc_display_rrh_and_ipa( DEVBLK* pDEVBLK, MPC_TH* pMPC_TH, MPC_RRH* pMPC_RRH, BYTE bDir )
{
    MPC_PH*    pMPC_PH;
    MPC_IPA*   pMPC_IPA;
    BYTE*      pMPC_IPA_CMD;
    U32        uOffData;
    U32        uLenData;
    U16        uOffPH;
    int        iLenIPA;
    int        iLenCmd;

    // Display the MPC_RRH.
    FETCH_HW( uOffPH, pMPC_RRH->offph );
    mpc_display_stuff( pDEVBLK, "RRH", (BYTE*)pMPC_RRH, uOffPH, bDir );

    // Point to and display the MPC_PH.
    pMPC_PH = (MPC_PH*)((BYTE*)pMPC_RRH + uOffPH);
    mpc_display_stuff( pDEVBLK, "PH", (BYTE*)pMPC_PH, SIZE_PH, bDir );

    /* Point to and display the MPC_IPA (and commands, if any). */
    FETCH_F3( uLenData, pMPC_PH->lendata );
    FETCH_FW( uOffData, pMPC_PH->offdata );
    if( uLenData > sizeof(MPC_IPA) )
    {
        iLenIPA = sizeof(MPC_IPA);
        iLenCmd = uLenData - sizeof(MPC_IPA);
    }
    else
    {
        iLenIPA = uLenData;
        iLenCmd = 0;
    }
    pMPC_IPA = (MPC_IPA*)((BYTE*)pMPC_TH + uOffData);
    mpc_display_stuff( pDEVBLK, "IPA", (BYTE*)pMPC_IPA, iLenIPA, bDir );
    if( iLenCmd )
    {
        pMPC_IPA_CMD = (BYTE*)pMPC_IPA + iLenIPA;
        mpc_display_stuff( pDEVBLK, "Cmd", (BYTE*)pMPC_IPA_CMD, iLenCmd, bDir );
    }

    return;
}   /* End function  mpc_display_rrh_and_ipa() */
예제 #7
0
/*--------------------------------------------------------------------*/
DLL_EXPORT MPC_PUK*  mpc_point_puk( DEVBLK* pDEVBLK, MPC_TH* pMPC_TH, MPC_RRH* pMPC_RRH )
{
    MPC_PH*    pMPC_PH;
    MPC_PUK*   pMPC_PUK;
    U32        uOffData;
    U16        uOffPH;

    UNREFERENCED( pDEVBLK );

    // Point to the MPC_PH.
    FETCH_HW( uOffPH, pMPC_RRH->offph );
    pMPC_PH = (MPC_PH*)((BYTE*)pMPC_RRH + uOffPH);

    // Get the length of and point to the data referenced by the
    // MPC_PH. The data contain a MPC_PUK and one or more MPC_PUSs.
    FETCH_FW( uOffData, pMPC_PH->offdata );
    pMPC_PUK = (MPC_PUK*)((BYTE*)pMPC_TH + uOffData);

    return pMPC_PUK;
}   /* End function  mpc_point_puk() */
예제 #8
0
/* followed by a single MPC_PIX.                                      */
DLL_EXPORT void  mpc_display_rrh_and_pix( DEVBLK* pDEVBLK, MPC_TH* pMPC_TH, MPC_RRH* pMPC_RRH, BYTE bDir )
{
    MPC_PH*    pMPC_PH;
    MPC_PIX*   pMPC_PIX;
    U32        uOffData;
    U32        uLenData;
    U16        uOffPH;

    // Display the MPC_RRH.
    FETCH_HW( uOffPH, pMPC_RRH->offph );
    mpc_display_stuff( pDEVBLK, "RRH", (BYTE*)pMPC_RRH, uOffPH, bDir );

    // Point to and display the MPC_PH.
    pMPC_PH = (MPC_PH*)((BYTE*)pMPC_RRH + uOffPH);
    mpc_display_stuff( pDEVBLK, "PH", (BYTE*)pMPC_PH, SIZE_PH, bDir );

    // Point to and display the MPC_PIX.
    FETCH_F3( uLenData, pMPC_PH->lendata );
    FETCH_FW( uOffData, pMPC_PH->offdata );
    pMPC_PIX = (MPC_PIX*)((BYTE*)pMPC_TH + uOffData);
    mpc_display_stuff( pDEVBLK, "PIX", (BYTE*)pMPC_PIX, uLenData, bDir );

    return;
}   /* End function  mpc_display_rrh_and_pix() */
예제 #9
0
/*-------------------------------------------------------------------*/
static void ARCH_DEP(hwl_loadfile)(SCCB_HWL_BK *hwl_bk)
{
CREG sto;
U32  size;
int fd;

    fd = open (hwl_fn[hwl_bk->file], O_RDONLY|O_BINARY);
    if (fd < 0)
    {
        logmsg (_("HHCHL002I %s open error: %s\n"),
            hwl_fn[hwl_bk->file], strerror(errno));
        return;
    }
//  else
//      logmsg(_("HHCHL004I Loading %s\n"),hwl_fn[hwl_bk->file]);

    FETCH_FW(size,hwl_bk->size);

    /* Segment Table Origin */
    FETCH_DW(sto,hwl_bk->sto);
#if defined(FEATURE_ESAME)
    sto &= ASCE_TO;
#else /*!defined(FEATURE_ESAME)*/
    sto &= STD_STO;
#endif /*!defined(FEATURE_ESAME)*/

    for( ; ; sto += sizeof(sto))
    {
#if defined(FEATURE_ESAME)
    DBLWRD *ste;
#else /*!defined(FEATURE_ESAME)*/
    FWORD *ste;
#endif /*!defined(FEATURE_ESAME)*/
    CREG pto, pti;

        /* Fetch segment table entry and calculate Page Table Origin */
        if( sto >= sysblk.mainsize)
            goto eof;
#if defined(FEATURE_ESAME)
        ste = (DBLWRD*)(sysblk.mainstor + sto);
#else /*!defined(FEATURE_ESAME)*/
        ste = (FWORD*)(sysblk.mainstor + sto);
#endif /*!defined(FEATURE_ESAME)*/
        FETCH_W(pto, ste);
        if( pto & SEGTAB_INVALID )
            goto eof;
#if defined(FEATURE_ESAME)
        pto &= ZSEGTAB_PTO;
#else /*!defined(FEATURE_ESAME)*/
        pto &= SEGTAB_PTO;
#endif /*!defined(FEATURE_ESAME)*/

        for(pti = 0; pti < 256 ; pti++, pto += sizeof(pto))
        {
#if defined(FEATURE_ESAME)
        DBLWRD *pte;
#else /*!defined(FEATURE_ESAME)*/
        FWORD *pte;
#endif /*!defined(FEATURE_ESAME)*/
        CREG pgo;
        BYTE *page;

            /* Fetch Page Table Entry to get page origin */
            if( pto >= sysblk.mainsize)
                goto eof;
#if defined(FEATURE_ESAME)
            pte = (DBLWRD*)(sysblk.mainstor + pto);
#else /*!defined(FEATURE_ESAME)*/
            pte = (FWORD*)(sysblk.mainstor + pto);
#endif /*!defined(FEATURE_ESAME)*/
            FETCH_W(pgo, pte);
            if( pgo & PAGETAB_INVALID )
                goto eof;
#if defined(FEATURE_ESAME)
            pgo &= ZPGETAB_PFRA;
#else /*!defined(FEATURE_ESAME)*/
            pgo &= PAGETAB_PFRA;
#endif /*!defined(FEATURE_ESAME)*/

            /* Read page into main storage */
            if( pgo >= sysblk.mainsize)
                goto eof;
            page = sysblk.mainstor + pgo;
            if( !(size--) || !read(fd, page, STORAGE_KEY_PAGESIZE) ) 
                goto eof;
            STORAGE_KEY(pgo, &sysblk) |= (STORKEY_REF|STORKEY_CHANGE);
        }
    }
    eof:
    close(fd);
}
예제 #10
0
static void  CTCT_Write( DEVBLK* pDEVBLK,   U32   sCount,
                         BYTE*   pIOBuf,    BYTE* pUnitStat,
                         U32*    pResidual )
{
    PCTCIHDR   pFrame;                  // -> Frame header
    PCTCISEG   pSegment;                // -> Segment in buffer
    U16        sOffset;                 // Offset of next frame
    U16        sSegLen;                 // Current segment length
    U16        sDataLen;                // Length of IP Frame data
    int        iPos;                    // Offset into buffer
    U16        i;                       // Array subscript
    int        rc;                      // Return code
    BYTE       szStackID[33];           // VSE IP stack identity
    U32        iStackCmd;               // VSE IP stack command

    // Check that CCW count is sufficient to contain block header
    if( sCount < sizeof( CTCIHDR ) )
    {
        WRMSG(HHC00906, "E", SSID_TO_LCSS(pDEVBLK->ssid), pDEVBLK->devnum, sCount );

        pDEVBLK->sense[0] = SENSE_DC;
        *pUnitStat        = CSW_CE | CSW_DE | CSW_UC;
        return;
    }

    // Fix-up frame pointer
    pFrame = (PCTCIHDR)pIOBuf;

    // Extract the frame length from the header
    FETCH_HW( sOffset, pFrame->hwOffset );


    // Check for special VSE TCP/IP stack command packet
    if( sOffset == 0 && sCount == 40 )
    {
        // Extract the 32-byte stack identity string
        for( i = 0;
             i < sizeof( szStackID ) - 1 && i < sCount - 4;
             i++)
            szStackID[i] = guest_to_host( pIOBuf[i+4] );

        szStackID[i] = '\0';

        // Extract the stack command word
        FETCH_FW( iStackCmd, *((FWORD*)&pIOBuf[36]) );

        // Display stack command and discard the packet
        WRMSG(HHC00907, "I", SSID_TO_LCSS(pDEVBLK->ssid), pDEVBLK->devnum, szStackID, iStackCmd );

        *pUnitStat = CSW_CE | CSW_DE;
        *pResidual = 0;
        return;
    }

    // Check for special L/390 initialization packet
    if( sOffset == 0 )
    {
        // Return normal status and discard the packet
        *pUnitStat = CSW_CE | CSW_DE;
        *pResidual = 0;
        return;
    }

#if 0
    // Notes: It appears that TurboLinux has gotten sloppy in their
    //        ways. They are now giving us buffer sizes that are
    //        greater than the CCW count, but the segment size
    //        is within the count.
    // Check that the frame offset is valid
    if( sOffset < sizeof( CTCIHDR ) || sOffset > sCount )
    {
        logmsg( _("CTC101W %4.4X: Write buffer contains invalid "
                  "frame offset %u\n"),
                pDEVBLK->devnum, sOffset );

        pDEVBLK->sense[0] = SENSE_CR;
        *pUnitStat        = CSW_CE | CSW_DE | CSW_UC;
        return;
    }
#endif

    // Adjust the residual byte count
    *pResidual -= sizeof( CTCIHDR );

    // Process each segment in the buffer
    for( iPos  = sizeof( CTCIHDR );
         iPos  < sOffset;
         iPos += sSegLen )
    {
        // Check that the segment is fully contained within the block
        if( iPos + sizeof( CTCISEG ) > sOffset )
        {
            WRMSG(HHC00908, "E", SSID_TO_LCSS(pDEVBLK->ssid), pDEVBLK->devnum, iPos );

            pDEVBLK->sense[0] = SENSE_DC;
            *pUnitStat        = CSW_CE | CSW_DE | CSW_UC;
            return;
        }

        // Fix-up segment header in the I/O buffer
        pSegment = (PCTCISEG)(pIOBuf + iPos);

        // Extract the segment length from the segment header
        FETCH_HW( sSegLen, pSegment->hwLength );

        // Check that the segment length is valid
        if( ( sSegLen        < sizeof( CTCISEG ) ) ||
            ( (U32)iPos + sSegLen > sOffset      ) ||
            ( (U32)iPos + sSegLen > sCount       ) )
        {
            WRMSG(HHC00909, "E", SSID_TO_LCSS(pDEVBLK->ssid), pDEVBLK->devnum, sSegLen, iPos );

            pDEVBLK->sense[0] = SENSE_DC;
            *pUnitStat        = CSW_CE | CSW_DE | CSW_UC;
            return;
        }

        // Calculate length of IP frame data
        sDataLen = sSegLen - sizeof( CTCISEG );

        // Trace the IP packet before sending
        if( pDEVBLK->ccwtrace || pDEVBLK->ccwstep )
        {
            WRMSG(HHC00934, "I", SSID_TO_LCSS(pDEVBLK->ssid), pDEVBLK->devnum, pDEVBLK->filename );
            if( pDEVBLK->ccwtrace )
                packet_trace( pSegment->bData, sDataLen, '>' );
        }

        // Write the IP packet
        rc = write_socket( pDEVBLK->fd, pSegment->bData, sDataLen );

        if( rc < 0 )
        {
            WRMSG(HHC00936, "E", SSID_TO_LCSS(pDEVBLK->ssid), pDEVBLK->devnum, pDEVBLK->filename,
                    strerror( HSO_errno ) );

            pDEVBLK->sense[0] = SENSE_EC;
            *pUnitStat        = CSW_CE | CSW_DE | CSW_UC;
            return;
        }

        // Adjust the residual byte count
        *pResidual -= sSegLen;

        // We are done if current segment satisfies CCW count
        if( (U32)iPos + sSegLen == sCount )
        {
            *pResidual -= sSegLen;
            *pUnitStat = CSW_CE | CSW_DE;
            return;
        }
    }

    // Set unit status and residual byte count
    *pUnitStat = CSW_CE | CSW_DE;
    *pResidual = 0;
}
예제 #11
0
/* is followed by up to four MPC_PUSs.                                */
DLL_EXPORT void  mpc_display_rrh_and_puk( DEVBLK* pDEVBLK, MPC_TH* pMPC_TH, MPC_RRH* pMPC_RRH, BYTE bDir )
{
    MPC_PH*    pMPC_PH;
    MPC_PUK*   pMPC_PUK;
    MPC_PUS*   pMPC_PUS;
    int        iTotLenPUS;
    U32        uOffData;
    U16        uTotLenPUS;
    U16        uLenPUS;
    U16        uLenPUK;
    U16        uOffPH;

    // Display the MPC_RRH.
    FETCH_HW( uOffPH, pMPC_RRH->offph );
    mpc_display_stuff( pDEVBLK, "RRH", (BYTE*)pMPC_RRH, uOffPH, bDir );

    // Point to and display the MPC_PH.
    pMPC_PH = (MPC_PH*)((BYTE*)pMPC_RRH + uOffPH);
    mpc_display_stuff( pDEVBLK, "PH", (BYTE*)pMPC_PH, SIZE_PH, bDir );

    // Get the length of and point to the data referenced by the
    // MPC_PH. The data contain a MPC_PUK and one or more MPC_PUSs.
    FETCH_FW( uOffData, pMPC_PH->offdata );
    pMPC_PUK = (MPC_PUK*)((BYTE*)pMPC_TH + uOffData);

    // Display the MPC_PUK.
    FETCH_HW( uLenPUK, pMPC_PUK->length );
    mpc_display_stuff( pDEVBLK, "PUK", (BYTE*)pMPC_PUK, uLenPUK, bDir );

    // Get the total length of the following MPC_PUSs, then point to
    // the first MPC_PUS.
    FETCH_HW( uTotLenPUS, pMPC_PUK->lenpus );
    iTotLenPUS = uTotLenPUS;
    pMPC_PUS = (MPC_PUS*)((BYTE*)pMPC_PUK + uLenPUK);

    // Display all of the MPC_PUSs.
    while( iTotLenPUS > 0 )
    {
        // Ensure there are at least the first 4-bytes of the MPC_PUS.
        if( iTotLenPUS < 4 )
        {
            mpc_display_stuff( pDEVBLK, "???", (BYTE*)pMPC_PUS, iTotLenPUS, bDir );
            break;
        }

        // Get the length of the MPC_PUS.
        FETCH_HW( uLenPUS, pMPC_PUS->length );
        if( uLenPUS == 0 )                     /* Better safe than sorry */
        {
            mpc_display_stuff( pDEVBLK, "???", (BYTE*)pMPC_PUS, iTotLenPUS, bDir );
            break;
        }

        // Ensure there is the whole of the MPC_PUS.
        if( iTotLenPUS < uLenPUS )
        {
            mpc_display_stuff( pDEVBLK, "???", (BYTE*)pMPC_PUS, iTotLenPUS, bDir );
            break;
        }

        // Display the MPC_PUS.
        mpc_display_stuff( pDEVBLK, "PUS", (BYTE*)pMPC_PUS, uLenPUS, bDir );

        // Point to the next MPC_PUS
        pMPC_PUS = (MPC_PUS*)((BYTE*)pMPC_PUS + uLenPUS);
        iTotLenPUS -= uLenPUS;
    }

    return;
}   /* End function  mpc_display_rrh_and_puk() */
예제 #12
0
int main( int argc, char *argv[] )
{
    U64 nxtpos;                         /* file position of next read */
    U64 altpos;                         /* file position of alternate track */
    U64 orgpos;                         /* alternate track's file position of original track */
    U32 numbad = 0;                     /* Counts defective tracks */
    U32 reclaimed = 0;                  /* Counts reclaimed tracks */
    U32 remaining;                      /* Counts number of tracks to process */
    U32 total;                          /* Total number of tracks to process */

    int infile  = -1;                   /* Input  file descriptor integer */
    int outfile = -1;                   /* output file descriptor integer */
    int cyl;                            /* Cylinder number */
    int head;                           /* Head number */
    int track;                          /* Track number */
    int rc;                             /* Return code */

    U8 trackbuf[TRACKSIZE];             /* Primary track buffer */
    U8 alttrack[TRACKSIZE];             /* Alternate track buffer */

    U8 altmark[6] = { BAD_TRACK_SIG };  /* Defective track signature */
    U8 reclaim = 0;                     /* false: map, true: reclaim */

    /*----------------*/
    /* Initialization */
    /*----------------*/

    if (argc < 3 || argc > 4)
        return error( EINVAL, "invalid number of arguments" );

    if (1
        && strcmp( argv[1], "MAP"     ) != 0
        && strcmp( argv[1], "map"     ) != 0
        && strcmp( argv[1], "RECLAIM" ) != 0
        && strcmp( argv[1], "reclaim" ) != 0
    )
        return error( EINVAL, "invalid 'action'" );

    reclaim = ((strcmp( argv[1], "RECLAIM" ) == 0) ||
               (strcmp( argv[1], "reclaim" ) == 0));

    if (reclaim && argc < 4)
        return error( EINVAL, "missing outfile argument" );

    printf( "Run option = %s\n", argv[1] );

    printf( "Opening input file \"%s\"...\n", argv[2] );

    if ((infile = HOPEN( argv[2], O_RDONLY | O_BINARY )) < 0)
        return error( errno, "could not open input file" );

    /*------------------------------*/
    /* Read and inspect file header */
    /*------------------------------*/

    if ((rc = read(infile, trackbuf, FILEHDRSIZE)) <= 0 || rc != FILEHDRSIZE)
        return error( EIO, "I/O error reading header from input file" );

    if (memcmp(trackbuf, "CKD_P370", 8) != 0)
        return error(EINTR, "input file is no CKD dasd image");

    if (trackbuf[16] != 0x90)
        return error(EINTR, "input file is no 3390 dasd image");

    FETCH_FW( head, &trackbuf[8] );
    FETCH_FW( track, &trackbuf[12] );
    FETCH_HW( cyl, &trackbuf[18] );

    if (bswap_32(track) != TRACKSIZE)
        return error(EINTR, "input file uses an unsupported track size");

    printf("3390 DASD image: %d heads, %d cylinders\n\n", bswap_32(head), bswap_16(cyl));

    remaining = total = TRACKSPERCYL * bswap_16(cyl);

    /*-----------------------------------------------------------*/
    /* Open output file and copy file header (only on "reclaim") */
    /*-----------------------------------------------------------*/

    if (reclaim)
    {
        printf( "Opening output file \"%s\"...\n", argv[3] );

        if ((outfile = HOPEN( argv[3], O_CREAT | O_EXCL | O_WRONLY | O_BINARY,
            S_IRUSR | S_IWUSR | S_IRGRP )) < 0)
            return error( errno, "could not open output file" );

        if ((rc = write( outfile, trackbuf, FILEHDRSIZE )) < 0 || rc != FILEHDRSIZE)
            return error( EIO, "I/O error writing output file" );
    }


c:  /*---------------------------*/
    /* Start of copy tracks loop */
    /*---------------------------*/

    track = total - remaining;
    cyl   = CYLNUM ( track );
    head  = HEADNUM( track );

    if (!head)
        printf( "Inspecting cylinder %d...\r", cyl );

    /* Read next track */

    if ((rc = read( infile, trackbuf, TRACKSIZE )) <= 0 || rc != TRACKSIZE)
        return error( errno, "I/O error reading input file" );

    /*------------------*/
    /* Defective track? */
    /*------------------*/

    if (memcmp( &trackbuf[TRACKSIZE-16], altmark, 6 ) == 0)
    {
        numbad++;     /* Count defective tracks */

        if (reclaim)
            printf( "Reclaiming track %6d = Cyl %4d (%4.4X), Head %2d (%2.2X)...\n",
                track, cyl, cyl, head, head );
        else
            printf( "Track %6d = Cyl %4d (%4.4X), Head %2d (%2.2X) is flagged\nas being defective and has an alternate track assigned.\n",
                track, cyl, cyl, head, head );

        FETCH_DW( altpos, &trackbuf[ TRACKSIZE-8 ] );   /* get alternate track position */
nxtpos= lseek( infile,   0,      SEEK_CUR  );           /* save current file position */
        lseek( infile, altpos,   SEEK_SET  );           /* position to alternate */
        read ( infile, alttrack, TRACKSIZE );           /* read alternate track */
        lseek( infile, nxtpos,   SEEK_SET  );           /* restore original file position */
        FETCH_DW( orgpos, &alttrack[ TRACKSIZE-8 ] );   /* get original track position */


        /*----------------------------------------------*/
#if (DEBUGOPT & DEBUG_POSITIONS)
        {
            int alttrk   = POS2TRACK( altpos );
            int altcyl   = CYLNUM ( alttrk );
            int althead  = HEADNUM( alttrk );

            int orgtrk   = POS2TRACK( orgpos );
            int orgcyl   = CYLNUM ( orgtrk );
            int orghead  = HEADNUM( orgtrk );

            printf("\n");

            printf( "\taltpos = %llx ==> track %6d = Cyl %4d (%4.4X), Head %2d (%2.2X)\n",
                altpos, alttrk, altcyl, altcyl, althead, althead );

            printf( "\torgpos = %llx ==> track %6d = Cyl %4d (%4.4X), Head %2d (%2.2X)\n",
                orgpos, orgtrk, orgcyl, orgcyl, orghead, orghead );
        }
#endif

#if (DEBUGOPT & DEBUG_TRACKDATA)
        {
            char *dump = NULL;

            printf("\n");

            hexdumpe( "\tPRI:  ", &dump, trackbuf, 0, TRACKSIZE, orgpos, 4, 4 );
            if (dump) printf( "%s\n", dump );

            hexdumpe( "\tALT:  ", &dump, alttrack, 0, TRACKSIZE, altpos, 4, 4 );
            if (dump) printf( "%s", dump );

            if (dump) free( dump );
        }
#endif

#if (DEBUGOPT & DEBUG_BOTH) /* if EITHER debug option */
        printf("\n");       /* if EITHER debug option */
#endif
        /*----------------------------------------------*/


        if (reclaim)
        {
            /* Reclaim the original track: the alternate tracks's
               position of the original defective track must match,
               and the track header containing the cylinder and track
               numbers must also match.
            */
            if (orgpos == (nxtpos-TRACKSIZE) &&
                memcmp( &alttrack[0], &trackbuf[0], 16 ) == 0)
            {
                /* copy alternate track data to original track */
                memcpy( trackbuf, alttrack, TRACKSIZE );

                /* indicate original track is no longer defective */
                memset( &trackbuf[TRACKSIZE-16], 0, 16 );

                reclaimed++;    /* Count reclaimed tracks */
            }
            else
                fprintf( stderr, "\t*** ERROR *** Reclaim failed!\n\n" );
        }
    }

    /*----------------------------*/
    /* Write track to output file */
    /*----------------------------*/

    if (reclaim)
        if ((rc = write( outfile, trackbuf, TRACKSIZE )) < 0 || rc != TRACKSIZE)
            return error( EIO, "I/O error writing output file" );

    /*------------------------------*/
    /* Loop until all tracks copied */
    /*------------------------------*/

    if (--remaining)
        goto c;

    /*-----------------------*/
    /* Print totals and exit */
    /*-----------------------*/

    if (infile  > 0) close( infile  );
    if (outfile > 0) close( outfile );

    printf( "%d tracks (%d cylinders) read.\n",    total, CYLNUM(total) );
    if (reclaim)
    printf( "%d tracks (%d cylinders) written.\n", total, CYLNUM(total) );

    if (!reclaim)
        printf( "Image currently has %d defective tracks assigned to an alternate.\n", numbad );
    else
    {
        printf( "Image had %d defective tracks assigned to an alternate.\n", numbad );
        printf( "A total of %d defective tracks were reclaimed from their assigned alternate.\n", reclaimed );
        printf( "Reclaim %s.\n", reclaimed >= numbad ? "was successful" : "function FAILED" );
    }

    PAUSEIFBEINGDEBUGGED();

    return (0);
}
예제 #13
0
파일: ctc_ctci.c 프로젝트: hpham04/spinhawk
void  CTCI_Write( DEVBLK* pDEVBLK,   U16   sCount,
                  BYTE*   pIOBuf,    BYTE* pUnitStat,
                  U16*    pResidual )
{
    PCTCBLK    pCTCBLK  = (PCTCBLK)pDEVBLK->dev_data;
    PCTCIHDR   pFrame;                  // -> Frame header
    PCTCISEG   pSegment;                // -> Segment in buffer
    U16        sOffset;                 // Offset of next frame
    U16        sSegLen;                 // Current segment length
    U16        sDataLen;                // Length of IP Frame data
    int        iPos;                    // Offset into buffer
    U16        i;                       // Array subscript
    int        rc;                      // Return code
    BYTE       szStackID[33];           // VSE IP stack identity
    U32        iStackCmd;               // VSE IP stack command

    // Check that CCW count is sufficient to contain block header
    if( sCount < sizeof( CTCIHDR ) )
    {
        logmsg( _("HHCCT042E %4.4X: Write CCW count %u is invalid\n"),
                pDEVBLK->devnum, sCount );

        pDEVBLK->sense[0] = SENSE_DC;
        *pUnitStat        = CSW_CE | CSW_DE | CSW_UC;

        return;
    }

    // Fix-up frame pointer
    pFrame = (PCTCIHDR)pIOBuf;

    // Extract the frame length from the header
    FETCH_HW( sOffset, pFrame->hwOffset );

    // Check for special VSE TCP/IP stack command packet
    if( sOffset == 0 && sCount == 40 )
    {
        // Extract the 32-byte stack identity string
        for( i = 0;
             i < sizeof( szStackID ) - 1 && i < sCount - 4;
             i++)
            szStackID[i] = guest_to_host( pIOBuf[i+4] );
        szStackID[i] = '\0';

        // Extract the stack command word
        FETCH_FW( iStackCmd, *((FWORD*)&pIOBuf[36]) );

        // Display stack command and discard the packet
        logmsg( _("HHCCT043I %4.4X: Interface command: %s %8.8X\n"),
                pDEVBLK->devnum, szStackID, iStackCmd );

        *pUnitStat = CSW_CE | CSW_DE;
        *pResidual = 0;

        return;
    }

    // Check for special L/390 initialization packet
    if( sOffset == 0 )
    {
        // Return normal status and discard the packet
        *pUnitStat = CSW_CE | CSW_DE;
        *pResidual = 0;

        return;
    }

#if 0
    // Notes: It appears that TurboLinux has gotten sloppy in their
    //        ways. They are now giving us buffer sizes that are
    //        greater than the CCW count, but the segment size
    //        is within the count.
    // Check that the frame offset is valid
    if( sOffset < sizeof( CTCIHDR ) || sOffset > sCount )
    {
        logmsg( _("CTC101W %4.4X: Write buffer contains invalid "
                  "frame offset %u\n"),
                pDEVBLK->devnum, sOffset );

        pDEVBLK->sense[0] = SENSE_CR;
        *pUnitStat        = CSW_CE | CSW_DE | CSW_UC;

        return;
    }
#endif

    // Adjust the residual byte count
    *pResidual -= sizeof( CTCIHDR );

    // Process each segment in the buffer
    for( iPos  = sizeof( CTCIHDR );
         iPos  < sOffset;
         iPos += sSegLen )
    {
        // Check that the segment is fully contained within the block
        if( iPos + sizeof( CTCISEG ) > sOffset )
        {
            logmsg( _("HHCCT044E %4.4X: Write buffer contains incomplete "
                      "segment header at offset %4.4X\n"),
                    pDEVBLK->devnum, iPos );

            pDEVBLK->sense[0] = SENSE_DC;
            *pUnitStat        = CSW_CE | CSW_DE | CSW_UC;
            return;
        }

        // Fix-up segment header in the I/O buffer
        pSegment = (PCTCISEG)(pIOBuf + iPos);

        // Extract the segment length from the segment header
        FETCH_HW( sSegLen, pSegment->hwLength );

        // Check that the segment length is valid
        if( ( sSegLen        < sizeof( CTCISEG ) ) ||
            ( iPos + sSegLen > sOffset           ) ||
            ( iPos + sSegLen > sCount            ) )
        {
            logmsg( _("HHCCT045E %4.4X: Write buffer contains invalid "
                    "segment length %u at offset %4.4X\n"),
                    pDEVBLK->devnum, sSegLen, iPos );

            pDEVBLK->sense[0] = SENSE_DC;
            *pUnitStat        = CSW_CE | CSW_DE | CSW_UC;
            return;
        }

        // Calculate length of IP frame data
        sDataLen = sSegLen - sizeof( CTCISEG );

        // Trace the IP packet before sending to TUN device
        if( pCTCBLK->fDebug )
        {
            logmsg( _("HHCCT046I %4.4X: Sending packet to %s:\n"),
                    pDEVBLK->devnum, pCTCBLK->szTUNDevName );
            packet_trace( pSegment->bData, sDataLen );
        }

        // Write the IP packet to the TUN/TAP interface
        rc = TUNTAP_Write( pCTCBLK->fd, pSegment->bData, sDataLen );

        if( rc < 0 )
        {
            logmsg( _("HHCCT047E %4.4X: Error writing to %s: rc=%d errno=%d %s\n"),
                    pDEVBLK->devnum, pCTCBLK->szTUNDevName,
                    rc, errno, strerror(errno));
        }

        /* Kludge for Ubuntu 10.04 by Martin Truebner */
        if (rc == -1 && errno == 22) rc = 0;

        if (rc < 0)
        {
            pDEVBLK->sense[0] = SENSE_EC;
            *pUnitStat        = CSW_CE | CSW_DE | CSW_UC;
            return;
        }

        // Adjust the residual byte count
        *pResidual -= sSegLen;

        // We are done if current segment satisfies CCW count
        if( iPos + sSegLen == sCount )
        {
            *pResidual -= sSegLen;
            *pUnitStat = CSW_CE | CSW_DE;
            return;
        }
    }

    // Set unit status and residual byte count
    *pUnitStat = CSW_CE | CSW_DE;
    *pResidual = 0;
}