Exemplo n.º 1
0
static int ARCH_DEP(chsc_get_sch_desc) (CHSC_REQ *chsc_req, CHSC_RSP *chsc_rsp)
{
U16 req_len, sch, f_sch, l_sch, rsp_len, lcss;

CHSC_REQ4 *chsc_req4 = (CHSC_REQ4 *)(chsc_req);
CHSC_RSP4 *chsc_rsp4 = (CHSC_RSP4 *)(chsc_rsp+1);

    FETCH_HW(f_sch,chsc_req4->f_sch);
    FETCH_HW(l_sch,chsc_req4->l_sch);
    FETCH_HW(lcss,chsc_req4->ssidfmt);
    lcss &= CHSC_REQ4_SSID;
    lcss >>= 4;

    /* Fetch length of request field */
    FETCH_HW(req_len, chsc_req4->length);

    rsp_len = sizeof(CHSC_RSP) + ((1 + l_sch - f_sch) * sizeof(CHSC_RSP4));

    if(l_sch < f_sch
      || rsp_len > (0x1000 - req_len)) {
        /* Set response field length */
        STORE_HW(chsc_rsp->length,sizeof(CHSC_RSP));
        /* Store request error */
        STORE_HW(chsc_rsp->rsp,CHSC_REQ_ERRREQ);
        /* No reaon code */
        STORE_FW(chsc_rsp->info,0);
        return 0;
    }

    for(sch = f_sch; sch <= l_sch; sch++, chsc_rsp4++)
    {
    DEVBLK *dev;
        memset(chsc_rsp4, 0, sizeof(CHSC_RSP4) );
        if((dev = find_device_by_subchan((LCSS_TO_SSID(lcss) << 16)|sch)))
        {
            int n;
            chsc_rsp4->sch_val = 1;
            if(dev->pmcw.flag5 & PMCW5_V)
                chsc_rsp4->dev_val = 1;
            chsc_rsp4->st = (dev->pmcw.flag25 & PMCW25_TYPE) >> 5;
            chsc_rsp4->unit_addr = dev->devnum & 0xff;
            STORE_HW(chsc_rsp4->devno,dev->devnum);
            chsc_rsp4->path_mask = dev->pmcw.pim;
            STORE_HW(chsc_rsp4->sch, sch);
            memcpy(chsc_rsp4->chpid, dev->pmcw.chpid, 8);
            if(dev->fla[0])
                chsc_rsp4->fla_valid_mask = dev->pmcw.pim;
            for(n = 0; n < 7; n++)
                if(dev->pmcw.pim & (0x80 >> n))
                    STORE_HW(chsc_rsp4->fla[n], dev->fla[n]);
        }
    }
Exemplo n.º 2
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() */
Exemplo n.º 3
0
static int ARCH_DEP(chsc_get_conf_info) (CHSC_REQ *chsc_req, CHSC_RSP *chsc_rsp)
{
U16 req_len, rsp_len;

CHSC_REQ12 *chsc_req12 = (CHSC_REQ12 *)(chsc_req);
CHSC_RSP12 *chsc_rsp12 = (CHSC_RSP12 *)(chsc_rsp+1);

    /* Fetch length of request field */
    FETCH_HW(req_len, chsc_req12->length);

    rsp_len = sizeof(CHSC_RSP) + sizeof(CHSC_RSP12);

    memset(chsc_rsp12, 0, sizeof(CHSC_RSP12) );

    STORE_HW(chsc_rsp12->len1,80);
    STORE_FW(chsc_rsp12->info1,0x10);
    STORE_FW(chsc_rsp12->info2,0x10);
    STORE_FW(chsc_rsp12->info3,0xFF);
 
    STORE_FW(chsc_rsp12->test,0xE3C5E2E3);

    /* Store response length */
    STORE_HW(chsc_rsp->length,rsp_len);

    /* Store request OK */
    STORE_HW(chsc_rsp->rsp,CHSC_REQ_OK);

    /* No reaon code */
    STORE_FW(chsc_rsp->info,0);

    return 0;

}
Exemplo n.º 4
0
/* the first MPC_PUS of the required type will ever be returned.      */
DLL_EXPORT MPC_PUS*  mpc_point_pus( DEVBLK* pDEVBLK, MPC_PUK* pMPC_PUK, BYTE bType )
{
    MPC_PUS*   pMPC_PUS;
    int        iTotLenPUS;
    U16        uTotLenPUS;
    U16        uLenPUS;
    U16        uLenPUK;

    UNREFERENCED( pDEVBLK );

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

    /* Find the required MPC_PUS. */
    while( iTotLenPUS > 0 )
    {
        /* Ensure there are at least the first 4-bytes of an MPC_PUS. */
        if( iTotLenPUS < 4 )
            return NULL;

        /* Get the length of the MPC_PUS. */
        FETCH_HW( uLenPUS, pMPC_PUS->length );
        if( uLenPUS == 0 )                  /* Better safe than sorry */
            return NULL;

        /* Ensure there is the whole of the MPC_PUS. */
        if( iTotLenPUS < uLenPUS )
            return NULL;

        /* Check for the required MPC_PUS. */
        if( pMPC_PUS->type == bType )
            return pMPC_PUS;

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

    return NULL;
}   /* End function  mpc_point_pus() */
Exemplo n.º 5
0
/*--------------------------------------------------------------------*/
DLL_EXPORT void  mpc_display_rrh( DEVBLK* pDEVBLK, MPC_RRH* pMPC_RRH, BYTE bDir )
{
    U16    uOffPH;

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

    return;
}   /* End function  mpc_display_rrh() */
Exemplo n.º 6
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() */
Exemplo n.º 7
0
int ARCH_DEP(chsc_get_sch_desc) (CHSC_REQ *chsc_req, CHSC_RSP *chsc_rsp)
{
    U16 req_len, sch, f_sch, l_sch, rsp_len;

    CHSC_REQ4 *chsc_req4 = (CHSC_REQ4 *)(chsc_req);
    CHSC_RSP4 *chsc_rsp4 = (CHSC_RSP4 *)(chsc_rsp);

#if 0
{ U16 resv1, resv2, resv3;
    FETCH_HW(resv1,chsc_req4->resv1);
    FETCH_HW(resv2,chsc_req4->resv2);
    FETCH_HW(resv3,chsc_req4->resv3);
    logmsg(D_("chsc_get_sch_desc: resv1=%4.4X resv2=%4.4X resv3=%4.4X\n"),resv1,resv2,resv3);
}
#endif

    FETCH_HW(f_sch,chsc_req4->f_sch);
    FETCH_HW(l_sch,chsc_req4->l_sch);
    
    /* Fetch length of request field */
    FETCH_HW(req_len, chsc_req4->length);

    rsp_len = sizeof(CHSC_RSP) + ((1 + l_sch - f_sch) * sizeof(CHSC_RSP4));

    if(l_sch < f_sch 
      || rsp_len > (0x1000 - req_len)) {
        /* Set response field length */
        STORE_HW(chsc_rsp->length,sizeof(CHSC_RSP));
        /* Store request error */
        STORE_HW(chsc_rsp->rsp,CHSC_REQ_ERRREQ);
        /* No reaon code */
        STORE_FW(chsc_rsp->info,0);
        return 0;
    }

    for(sch = f_sch; sch <= l_sch; sch++, chsc_rsp4++)
    {
    DEVBLK *dev;
        memset(chsc_rsp4, 0x00, sizeof(CHSC_RSP4) );
// ZZ FIXME:  Dunno how to put the proper lcss id in here...
        if((dev = find_device_by_subchan(0x00010000|sch)))
        {
            chsc_rsp4->sch_val = 1;
            if(dev->pmcw.flag5 & PMCW5_V)
                chsc_rsp4->dev_val = 1;
            chsc_rsp4->st = (dev->pmcw.flag25 & PMCW25_TYPE) >> 5;
            chsc_rsp4->unit_addr = dev->devnum & 0xff;
            STORE_HW(chsc_rsp4->devno,dev->devnum);
            chsc_rsp4->path_mask = dev->pmcw.pim;
            STORE_HW(chsc_rsp4->sch, sch);
            memcpy(chsc_rsp4->chpid, dev->pmcw.chpid, 8);
        }
    }
Exemplo n.º 8
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() */
Exemplo n.º 9
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() */
Exemplo n.º 10
0
/*-------------------------------------------------------------------*/
void ARCH_DEP(sclp_scedio_event) (SCCB_HEADER *sccb)
{
SCCB_EVD_HDR    *evd_hdr = (SCCB_EVD_HDR*)(sccb + 1);
U16 sccb_len;
U16 evd_len;

    if( ARCH_DEP(scedio_request)(SCLP_READ_EVENT_DATA, evd_hdr) )
    {
        /* Update SCCB length field if variable request */
        if (sccb->type & SCCB_TYPE_VARIABLE)
        {
            FETCH_HW(evd_len, evd_hdr->totlen);
            sccb_len = evd_len + sizeof(SCCB_HEADER);
            STORE_HW(sccb->length, sccb_len);
            sccb->type &= ~SCCB_TYPE_VARIABLE;
        }

        /* Set response code X'0020' in SCCB header */
        sccb->reas = SCCB_REAS_NONE;
        sccb->resp = SCCB_RESP_COMPLETE;
    }

}
Exemplo n.º 11
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() */
Exemplo n.º 12
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() */
Exemplo n.º 13
0
/*-------------------------------------------------------------------*/
static int 
find_input_record (BYTE *buf, BYTE **ppbuf, int *plen,
                BYTE *pkl, BYTE **pkp, U16 *pdl, BYTE **pdp,
                U32 *pcc, U32 *phh, BYTE *prn)
{
H30CKD_RECHDR  *hrec;                   /* Input record header       */
U16             dlen;                   /* Data length               */
BYTE            klen;                   /* Key length                */
int             n;                      /* Integer work area         */

    UNREFERENCED(buf);

    /* End of track if not enough bytes remain in buffer */
    if (*plen < H30CKD_RECHDR_SIZE) return 1;

    /* Point to record header */
    hrec = (H30CKD_RECHDR*)(*ppbuf);
     
    /* End of track if record header is all zero */
    if (memcmp(*ppbuf, twelvehex00, 12) == 0) return 1;

    /* Extract the key length and data length */
    klen = hrec->klen;
    FETCH_HW (dlen, hrec->dlen);

    /* Check that the reserved bytes are all zero */
    if (memcmp(hrec->resv00, twelvehex00, sizeof(hrec->resv00)) != 0)
        return 2;

    /* Check that the key and data do not overflow the buffer */
    if (*plen < H30CKD_RECHDR_SIZE + klen + dlen)
        return 3;

    /* Return the cylinder, head, and record number */
    FETCH_HW (*pcc, hrec->cyl);
    FETCH_HW (*phh, hrec->head);
    *prn = hrec->rec;

    /* Point past the record header to the key */
    *plen -= H30CKD_RECHDR_SIZE;
    *ppbuf += H30CKD_RECHDR_SIZE;

    /* Return the key length and key pointer */
    *pkl = klen;
    *pkp = *ppbuf;

    /* Point past the key to the data */
    *plen -= klen;
    *ppbuf += klen;

    /* Return the data length and data pointer */
    *pdl = dlen;
    *pdp = *ppbuf;
     
    /* Point past the data to the next record header */
    *plen -= dlen;
    *ppbuf += dlen;

    /* Ensure next header starts on a fullword boundary */
    if ((klen + dlen) & 3)
    {
        n = 4 - ((klen + dlen) % 4);
        *plen -= n;
        *ppbuf += n;
    }

    /* Issue progress message */
   #if 0
    fprintf (stderr,
        "+%4.4X cyl=%4.4X head=%4.4X rec=%2.2X"
        " kl=%2.2X dl=%4.4X trkbal=%d\n",
        (BYTE*)hrec-buf, *pcc, *phh, *prn, klen, dlen, *plen);
   #endif

    return 0;
} /* end function find_input_record */
Exemplo n.º 14
0
/*-------------------------------------------------------------------*/
int ARCH_DEP(mssf_call) (int r1, int r2, REGS *regs)
{
U32     spccb_absolute_addr;            /* Absolute addr of SPCCB    */
U32     mssf_command;                   /* MSSF command word         */
U32               spccblen;            /* Length of SPCCB            */
SPCCB_HEADER      *spccb;              /* -> SPCCB header            */
SPCCB_CONFIG_INFO *spccbconfig;        /* -> SPCCB CONFIG info       */
SPCCB_CPU_INFO    *spccbcpu;           /* -> SPCCB CPU information   */
SPCCB_CHP_STATUS  *spccbchp;           /* -> SPCCB channel path info */
U16               offset;              /* Offset from start of SPCCB */
int               i;                   /* loop counter               */
DEVBLK            *dev;                /* Device block pointer       */

    /* R1 contains the real address of the SPCCB */
    spccb_absolute_addr = APPLY_PREFIXING (regs->GR_L(r1), regs->PX);

    /* R2 contains the service-processor-command word */
    mssf_command = regs->GR_L(r2);

    /* Program check if SPCCB is not on a doubleword boundary */
    if ( spccb_absolute_addr & 0x00000007 )
        ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);

    /* Program check if SPCCB is outside main storage */
    if ( spccb_absolute_addr > regs->mainlim )
        ARCH_DEP(program_interrupt) (regs, PGM_ADDRESSING_EXCEPTION);

//  /*debug*/logmsg("MSSF call %8.8X SPCCB=%8.8X\n",
//  /*debug*/       mssf_command, spccb_absolute_addr);

    /* Point to Service Processor Command Control Block */
    spccb = (SPCCB_HEADER*)(regs->mainstor + spccb_absolute_addr);

    /* Load SPCCB length from header */
    FETCH_HW(spccblen,spccb->length);

    /* Mark page referenced */
    STORAGE_KEY(spccb_absolute_addr, regs) |= STORKEY_REF;

    /* Program check if end of SPCCB falls outside main storage */
    if ( sysblk.mainsize - spccblen < spccb_absolute_addr )
        ARCH_DEP(program_interrupt) (regs, PGM_ADDRESSING_EXCEPTION);

    /* Obtain the interrupt lock */
    OBTAIN_INTLOCK(regs);

    /* If a service signal is pending then we cannot process the request */
    if( IS_IC_SERVSIG && (sysblk.servparm & SERVSIG_ADDR)) {
        RELEASE_INTLOCK(regs);
        return 2;   /* Service Processor Busy */
    }

    if( spccb_absolute_addr & 0x7ffff800 ) {
        spccb->resp[0] = SPCCB_REAS_NOT2KALIGN;
        spccb->resp[1] = SPCCB_RESP_NOT2KALIGN;
    } else
        /* Test MSSF command word */
        switch (mssf_command) {

        case MSSF_READ_CONFIG_INFO:

            /* Set response code X'01F0' if SPCCB length
               is insufficient to contain CONFIG info */
            if ( spccblen < 64 )
            {
                spccb->resp[0] = SPCCB_REAS_BADLENGTH;
                spccb->resp[1] = SPCCB_RESP_BADLENGTH;
            break;
            }

            /* Point to SPCCB data area following SPCCB header */
            spccbconfig = (SPCCB_CONFIG_INFO*)(spccb+1);
            memset (spccbconfig, 0, sizeof(SPCCB_CONFIG_INFO));

            /* Set main storage size in SPCCB */
            spccbconfig->totstori = sysblk.mainsize >> 20;
            spccbconfig->storisiz = 1;
            spccbconfig->hex04 = 0x04;
            spccbconfig->hex01 = 0x01;

            /* Set CPU array count and offset in SPCCB */
            STORE_HW(spccbconfig->toticpu,sysblk.maxcpu);
            offset = sizeof(SPCCB_HEADER) + sizeof(SPCCB_CONFIG_INFO);
            STORE_HW(spccbconfig->officpu,offset);

            /* Set HSA array count and offset in SPCCB */
            STORE_HW(spccbconfig->tothsa,0);
            offset += (U16)(sizeof(SPCCB_CPU_INFO) * sysblk.maxcpu);
            STORE_HW(spccbconfig->offhsa,offset);

            /* Move IPL load parameter to SPCCB */
            get_loadparm (spccbconfig->loadparm);

            /* Build the CPU information array after the SCP info */
            spccbcpu = (SPCCB_CPU_INFO*)(spccbconfig+1);
            for (i = 0; i < sysblk.maxcpu; i++, spccbcpu++)
            {
                memset( spccbcpu, 0, sizeof(SPCCB_CPU_INFO) );
                spccbcpu->cpuaddr = i;
                spccbcpu->todid = 0;
            }

            /* Set response code X'0010' in SPCCB header */
            spccb->resp[0] = SPCCB_REAS_COMPLETE;
            spccb->resp[1] = SPCCB_RESP_COMPLETE;

            break;

        case MSSF_READ_CHP_STATUS:

            /* Set response code X'0300' if SPCCB length
               is insufficient to contain channel path info */
            if ( spccblen < sizeof(SPCCB_HEADER) + sizeof(SPCCB_CHP_STATUS))
            {
                spccb->resp[0] = SPCCB_REAS_BADLENGTH;
                spccb->resp[1] = SPCCB_RESP_BADLENGTH;
                break;
            }

            /* Point to SPCCB data area following SPCCB header */
            spccbchp = (SPCCB_CHP_STATUS*)(spccb+1);
            memset( spccbchp, 0, sizeof(SPCCB_CHP_STATUS) );

            /* Identify CHPIDs used */
            for (dev = sysblk.firstdev; dev != NULL; dev = dev->nextdev)
            {
                for (i = 0; i < 8; i++)
                {
                    if( ((0x80 >> i) & dev->pmcw.pim) )
                    {
                    BYTE chpid;
                        chpid = dev->pmcw.chpid[i];
                        spccbchp->installed[chpid / 8] |= 0x80 >> (chpid % 8);
                        spccbchp->assigned[chpid / 8] |= 0x80 >> (chpid % 8);
                        spccbchp->configured[chpid / 8] |= 0x80 >> (chpid % 8);
                    }
               }
            }

            /* Set response code X'0010' in SPCCB header */
            spccb->resp[0] = SPCCB_REAS_COMPLETE;
            spccb->resp[1] = SPCCB_RESP_COMPLETE;

            break;

        default:
            PTT(PTT_CL_ERR,"*DIAG080",regs->GR_L(r1),regs->GR_L(r2),regs->psw.IA_L);
            /* Set response code X'06F0' for invalid MSSF command */
            spccb->resp[0] = SPCCB_REAS_UNASSIGNED;
            spccb->resp[1] = SPCCB_RESP_UNASSIGNED;

            break;

        } /* end switch(mssf_command) */

    /* Mark page changed */
    STORAGE_KEY(spccb_absolute_addr, regs) |= STORKEY_CHANGE;

    /* Set service signal external interrupt pending */
    sysblk.servparm &= ~SERVSIG_ADDR;
    sysblk.servparm |= spccb_absolute_addr;
    ON_IC_SERVSIG; 

    /* Release the interrupt lock */
    RELEASE_INTLOCK(regs);

    /* Return condition code 0: Command initiated */
    return 0;

} /* end function mssf_call */
Exemplo n.º 15
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);
}
Exemplo n.º 16
0
/*-------------------------------------------------------------------*/
static IFD 
open_input_image (char *ifname, U16 *devt, U32 *vcyls,
                U32 *itrkl, BYTE **itrkb, BYTE *volser)
{
int             rc;                     /* Return code               */
H30CKD_TRKHDR   h30trkhdr;              /* Input track header        */
IFD             ifd;                    /* Input file descriptor     */
int             len;                    /* Length of input           */
U16             code;                   /* Device type code          */
U16             dt;                     /* Device type               */
U32             cyls;                   /* Device size (pri+alt cyls)*/
U32             alts;                   /* Number of alternate cyls  */
BYTE           *itrkbuf;                /* -> Input track buffer     */
U32             itrklen;                /* Input track length        */
BYTE           *pbuf;                   /* Current byte in input buf */
BYTE            klen;                   /* Key length                */
U16             dlen;                   /* Data length               */
BYTE           *kptr;                   /* -> Key in input buffer    */
BYTE           *dptr;                   /* -> Data in input buffer   */
U32             cyl;                    /* Cylinder number           */
U32             head;                   /* Head number               */
BYTE            rec;                    /* Record number             */
char            pathname[MAX_PATH];     /* file path in host format  */

    hostpath(pathname, (char *)ifname, sizeof(pathname));

    /* Open the HDR-30 CKD image file */
  #if defined(HAVE_LIBZ)
    if (strcmp(ifname, "-") == 0)
        ifd = gzdopen (STDIN_FILENO, "rb");
    else
        ifd = gzopen (pathname, "rb");

    if (ifd == NULL)
    {
        fprintf (stderr,
                "Cannot open %s: %s\n",
                ifname,
                errno == 0 ? "gzopen error" : strerror(errno));
        EXIT(3);
    }
  #else /*!defined(HAVE_LIBZ)*/
    if (strcmp(ifname, "-") == 0)
        ifd = STDIN_FILENO;
    else
    {
        ifd = hopen(pathname, O_RDONLY | O_BINARY);

        if (ifd < 0)
        {
            fprintf (stderr,
                    "Cannot open %s: %s\n",
                    ifname, strerror(errno));
            EXIT(3);
        }
    }
  #endif /*!defined(HAVE_LIBZ)*/

    /* Read the first track header */
    read_input_data (ifd, ifname, (BYTE*)&h30trkhdr,
                    H30CKD_TRKHDR_SIZE, 0);

  #if !defined(HAVE_LIBZ)
    /* Reject input if compressed and we lack gzip support */
    if (memcmp(h30trkhdr.devcode, gz_magic_id, sizeof(gz_magic_id)) == 0) 
    {
        fprintf (stderr,
                "Input file %s appears to be a .gz file\n"
                "but this program was compiled without compression support\n",
                ifname);
        EXIT(3);
    }
  #endif /*!defined(HAVE_LIBZ)*/

    /* Reject input if it is already in CKD or CCKD format */
    if (memcmp((BYTE*)&h30trkhdr, ckd_ident, sizeof(ckd_ident)) == 0)
    {
        fprintf (stderr,
                "Input file %s is already in CKD format, use dasdcopy\n",
                ifname);
        EXIT(3);
    }

    /* Extract the device type code from the track header */
    FETCH_HW (code, h30trkhdr.devcode);

    /* Determine the input device type and size from the device code */
    switch (code) {
    case 0x01: dt=0x3330; cyls=411; alts=7; break;      /* 3330      */
    case 0x02: dt=0x3330; cyls=815; alts=7; break;      /* 3330-11   */
    case 0x03: dt=0x3340; cyls=351; alts=1; break;      /* 3340-35   */
    case 0x04: dt=0x3340; cyls=701; alts=1; break;      /* 3340-70   */
    case 0x05: dt=0x3350; cyls=562; alts=7; break;      /* 3350      */
    case 0x06: dt=0x3375; cyls=962; alts=3; break;      /* 3375      */
    case 0x08: dt=0x3380; cyls=888; alts=3; break;      /* 3380-A,D,J*/
    case 0x09: dt=0x3380; cyls=1774; alts=4; break;     /* 3380-E    */
    case 0x0A: dt=0x3380; cyls=2660; alts=5; break;     /* 3380-K    */
    case 0x0B: dt=0x3390; cyls=1117; alts=4; break;     /* 3390-1    */
    case 0x0C: dt=0x3390; cyls=2230; alts=4; break;     /* 3390-2    */
    case 0x0D: dt=0x3390; cyls=3343; alts=4; break;     /* 3390-3    */
    case 0x12: dt=0x2314; cyls=203; alts=3; break;      /* 2314      */
    case 0x13: dt=0x3390; cyls=10038; alts=21; break;   /* 3390-9    */
    case 0x14: dt=0x9345; cyls=1454; alts=14; break;    /* 9345-1    */
    case 0x15: dt=0x9345; cyls=2170; alts=14; break;    /* 9345-2    */
    default:
        fprintf (stderr,
                "Unknown device code %4.4X" \
                " at offset 00000000 in input file %s\n",
                code, ifname);
        EXIT(3);
    } /* end switch(code) */

    /* Use the device type to determine the input image track size */
    switch (dt) {
    case 0x2314: itrklen = 0x2000; break;
    case 0x3330: itrklen = 0x3400; break;
    case 0x3340: itrklen = 0x2400; break;
    case 0x3350: itrklen = 0x4C00; break;
    case 0x3375: itrklen = 0x9000; break;
    case 0x3380: itrklen = 0xBC00; break;
    case 0x3390: itrklen = 0xE400; break;
    case 0x9345: itrklen = 0xBC00; break;
    default:
        fprintf (stderr, "Unknown device type: %4.4X\n", dt);
        EXIT(3);
    } /* end switch(dt) */

    /* Obtain the input track buffer */
    itrkbuf = malloc (itrklen);
    if (itrkbuf == NULL)
    {
        fprintf (stderr,
                "Cannot obtain storage for input track buffer: %s\n",
                strerror(errno));
        EXIT(3);
    }

    /* Copy the first track header to the input track buffer */
    memcpy (itrkbuf, &h30trkhdr, H30CKD_TRKHDR_SIZE);

    /* Read the remainder of the first track into the buffer */
    read_input_data (ifd, ifname,
                     itrkbuf + H30CKD_TRKHDR_SIZE,
                     itrklen - H30CKD_TRKHDR_SIZE,
                     H30CKD_TRKHDR_SIZE);

    /* Initialize the volume serial number */
    strcpy ((char *)volser, "(NONE)");

    /* Search for volume label in record 3 of first track */
    pbuf = itrkbuf + H30CKD_TRKHDR_SIZE;
    len = itrklen - H30CKD_TRKHDR_SIZE;
    while (1)
    {
        /* Find next input record */
        rc = find_input_record (itrkbuf, &pbuf, &len,
                &klen, &kptr, &dlen, &dptr,
                &cyl, &head, &rec);
     
        /* Give up if error or end of track */
        if (rc != 0) break;

        /* Process when record 3 is found */
        if (cyl == 0 && head == 0 && rec == 3)
        {
            /* Extract volser if it is a volume label */
            if (klen == 4 && memcmp(kptr, ebcdicvol1, 4) == 0
            && dlen == 80 && memcmp(dptr, ebcdicvol1, 4) == 0)
                make_asciiz ((char *)volser, 7, dptr+4, 6);
            break;
        }
    } /* end while */

    /* Set output variables and return the input file descriptor */
    *devt = dt;
    *vcyls = cyls - alts;
    *itrkl = itrklen;
    *itrkb = itrkbuf;
    return ifd;

} /* end function open_input_image */
Exemplo n.º 17
0
/*-------------------------------------------------------------------*/
static void
convert_ckd_file (IFD ifd, char *ifname, int itrklen, BYTE *itrkbuf,
                int repl, int quiet,
                char *ofname, int fseqn, U16 devtype, U32 heads,
                U32 trksize, BYTE *obuf, U32 start, U32 end,
                U32 volcyls, BYTE *volser)
{
int             rc;                     /* Return code               */
int             ofd;                    /* Output file descriptor    */
CKDDASD_DEVHDR  devhdr;                 /* Output device header      */
CKDDASD_TRKHDR *trkhdr;                 /* -> Output track header    */
CKDDASD_RECHDR *rechdr;                 /* -> Output record header   */
U32             cyl;                    /* Cylinder number           */
U32             head;                   /* Head number               */
int             fileseq;                /* CKD header sequence number*/
int             highcyl;                /* CKD header high cyl number*/
BYTE           *opos;                   /* -> Byte in output buffer  */
BYTE            klen;                   /* Key length                */
U16             dlen;                   /* Data length               */
BYTE            rec;                    /* Record number             */
BYTE           *iptr;                   /* -> Byte in input buffer   */
BYTE           *kptr;                   /* -> Key in input buffer    */
BYTE           *dptr;                   /* -> Data in input buffer   */
int             ilen;                   /* Bytes left in input buffer*/
H30CKD_TRKHDR  *ith;                    /* -> Input track header     */
U32             ihc, ihh;               /* Input trk header cyl,head */
U32             offset;                 /* Current input file offset */
char            pathname[MAX_PATH];     /* file path in host format  */

    UNREFERENCED(volser);

    /* Set file sequence number to zero if this is the only file */
    if (fseqn == 1 && end + 1 == volcyls)
        fileseq = 0;
    else
        fileseq = fseqn;

    /* Set high cylinder number to zero if this is the last file */
    if (end + 1 == volcyls)
        highcyl = 0;
    else
        highcyl = end;

    /* Create the AWSCKD image file */
    hostpath(pathname, (char *)ofname, sizeof(pathname));
    ofd = hopen(pathname,
                O_WRONLY | O_CREAT | O_BINARY | (repl ? 0 : O_EXCL),
                S_IRUSR | S_IWUSR | S_IRGRP);

    if (ofd < 0)
    {
        fprintf (stderr, "%s open error: %s\n",
                ofname, strerror(errno));
        EXIT(8);
    }

    /* Create the device header */
    memset(&devhdr, 0, CKDDASD_DEVHDR_SIZE);
    memcpy(devhdr.devid, "CKD_P370", 8);
    devhdr.heads[3] = (heads >> 24) & 0xFF;
    devhdr.heads[2] = (heads >> 16) & 0xFF;
    devhdr.heads[1] = (heads >> 8) & 0xFF;
    devhdr.heads[0] = heads & 0xFF;
    devhdr.trksize[3] = (trksize >> 24) & 0xFF;
    devhdr.trksize[2] = (trksize >> 16) & 0xFF;
    devhdr.trksize[1] = (trksize >> 8) & 0xFF;
    devhdr.trksize[0] = trksize & 0xFF;
    devhdr.devtype = devtype & 0xFF;
    devhdr.fileseq = fileseq;
    devhdr.highcyl[1] = (highcyl >> 8) & 0xFF;
    devhdr.highcyl[0] = highcyl & 0xFF;

    /* Write the device header */
    rc = write (ofd, &devhdr, CKDDASD_DEVHDR_SIZE);
    if (rc < CKDDASD_DEVHDR_SIZE)
    {
        fprintf (stderr, "%s device header write error: %s\n",
                ofname, errno ? strerror(errno) : "incomplete");
        EXIT(1);
    }

    /* Write each cylinder */
    for (cyl = start; cyl <= end; cyl++)
    {
        /* Display progress message every 10 cylinders */
        if ((cyl % 10) == 0)
        {
#ifdef EXTERNALGUI
            if (extgui)
                fprintf (stderr, "CYL=%u\n", cyl);
            else
#endif /*EXTERNALGUI*/
            if (quiet == 0)
                fprintf (stderr, "Writing cylinder %u\r", cyl);
        }

        for (head = 0; head < heads; head++)
        {
            /* Calculate the current offset in the file */
            offset = ((cyl*heads)+head)*itrklen;

            /* Read the input track image (except cyl 0 head 0 
               already read by the open_input_image procedure) */
            if (cyl > 0 || head > 0)
            {
                read_input_data (ifd, ifname,
                                 itrkbuf, itrklen,
                                 offset);
            } /* end if(cyl>0||head>0) */

            /* Validate the track header */
            ith = (H30CKD_TRKHDR*)itrkbuf;
            FETCH_HW (ihc, ith->cyl);
            FETCH_HW (ihh, ith->head);
            if (ihc != cyl || ihh != head)
            {
                fprintf (stderr,
                        "Invalid track header found at offset %8.8X\n"
                        "in input file %s\n"
                        "Expected cyl=%4.4X head=%4.4X\n"
                        "   Found cyl=%4.4X head=%4.4X\n",
                        offset, ifname,
                        cyl, head, ihc, ihh);
                EXIT(8);
            }
             
            /* Clear the output track image to zeroes */
            memset (obuf, 0, trksize);

            /* Build the output track header */
            trkhdr = (CKDDASD_TRKHDR*)obuf;
            trkhdr->bin = 0;
            STORE_HW (trkhdr->cyl, cyl);
            STORE_HW (trkhdr->head, head);
            opos = obuf + CKDDASD_TRKHDR_SIZE;

            /* Copy each record from the input buffer */
            iptr = itrkbuf + H30CKD_TRKHDR_SIZE;
            ilen = itrklen - H30CKD_TRKHDR_SIZE;
            while (1)
            {
                /* Locate the next input record */
                rc = find_input_record (itrkbuf, &iptr, &ilen,
                        &klen, &kptr, &dlen, &dptr,
                        &ihc, &ihh, &rec);

                /* Exit at end of track */
                if (rc == 1) break;

                /* Error if invalid record header detected */
                if (rc > 1)
                {
                    fprintf (stderr,
                            "Invalid record header (reason %d)\n"
                            "at offset %4.4X"
                            " in track at cyl %4.4X head %4.4X\n"
                            "at offset %8.8X in input file %s\n",
                            rc, (unsigned int)(iptr-itrkbuf), cyl, head,
                            offset, ifname);
                    EXIT(9);
                }

                /* Build AWSCKD record header in output buffer */
                rechdr = (CKDDASD_RECHDR*)opos;
                opos += CKDDASD_RECHDR_SIZE;
                STORE_HW (rechdr->cyl, ihc);
                STORE_HW (rechdr->head, ihh);
                rechdr->rec = rec;
                rechdr->klen = klen;
                STORE_HW (rechdr->dlen, dlen);

                /* Copy key and data to output buffer */
                if (klen != 0)
                {
                    memcpy (opos, kptr, klen);
                    opos += klen;
                }
                if (dlen != 0)
                {
                    memcpy (opos, dptr, dlen);
                    opos += dlen;
                }

            } /* end while */

            /* Build the end of track marker */
            memcpy (opos, eighthexFF, 8);

            /* Write the track to the file */
            rc = write (ofd, obuf, trksize);
            if (rc < 0 || (U32)rc < trksize)
            {
                fprintf (stderr,
                        "%s cylinder %u head %u write error: %s\n",
                        ofname, cyl, head,
                        errno ? strerror(errno) : "incomplete");
                EXIT(1);
            }

        } /* end for(head) */

    } /* end for(cyl) */

    /* Close the AWSCKD image file */
    rc = close (ofd);
    if (rc < 0)
    {
        fprintf (stderr, "%s close error: %s\n",
                ofname, strerror(errno));
        EXIT(10);
    }

    /* Display completion message */
    fprintf (stderr,
            "%u cylinders successfully written to file %s\n",
            cyl - start, ofname);

} /* end function convert_ckd_file */
Exemplo n.º 18
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;
}
Exemplo n.º 19
0
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;
}