src/ssx/occhw/occhw_async_ocb.c
// Collect FFDC for an OCB channel
//
// This is an internal API, called either due to an OCB error interrupt or a
// read/write error detected during the operation.  See the comments for
// OcbFfdc for a description of why this particular set of data is collected.
// The special channel number -1 is used to denote the direct bridge.
//
// OCB FFDC collection procedure:
//
// - Collect the OCBSCR<n> for indirect channels
//
// - Collect PUSH/PULL queue setup for indirect channels and disable the queues.
//
// - Collect the OCB FIR
//
// - Collect FFDC from the PLB (OCI) arbiter
//
// FFDC is only collected for the first error, until the error flag is reset.
Collect FFDC for an OCB channel
This is an internal API, called either due to an OCB error interrupt or a
read/write error detected during the operation.  See the comments for
OcbFfdc for a description of why this particular set of data is collected.
The special channel number -1 is used to denote the direct bridge.

OCB FFDC collection procedure.

Collect the OCBSCR for indirect channels

Collect PUSH/PULL queue setup for indirect channels and disable the queues.

Collect the OCB FIR

Collect FFDC from the PLB (OCI) arbiter

FFDC is only collected for the first error, until the error flag is reset.
Collect FFDC for an OCB channel This is an internal API called either due to an OCB error interrupt or a read / write error detected during the operation . See the comments for OcbFfdc for a description of why this particular set of data is collected . The special channel number - 1 is used to denote the direct bridge . OCB FFDC collection procedure . Collect the OCBSCR for indirect channels Collect PUSH / PULL queue setup for indirect channels and disable the queues . Collect the OCB FIR Collect FFDC from the PLB ( OCI ) arbiter FFDC is only collected for the first error until the error flag is reset .
static void
ocb_ffdc(int channel)
{
    OcbFfdc* ffdc;
    ocb_ocbshcsn_t ocbshcsn;
    ocb_ocbslcsn_t ocbslcsn;
    if (channel < 0)
    {
        ffdc = &(G_ocb_ffdc.bridge);
    }
    else
    {
        ffdc = &(G_ocb_ffdc.channel[channel]);
    }
    if (ffdc->error == 0)
    {
        if (channel < 0)
        {
            memset(ffdc, 0, sizeof(OcbFfdc));
        }
        else
        {
            ffdc->shbr.value = in32(OCB_OCBSHBRN(channel));
            ffdc->shcs.value = in32(OCB_OCBSHCSN(channel));
            ffdc->slbr.value = in32(OCB_OCBSLBRN(channel));
            ffdc->slcs.value = in32(OCB_OCBSLCSN(channel));
            ocbshcsn.value = ffdc->shcs.value;
            ocbshcsn.fields.push_enable = 0;
            out32(OCB_OCBSHCSN(channel), ocbshcsn.value);
            ocbslcsn.value = ffdc->slcs.value;
            ocbslcsn.fields.pull_enable = 0;
            out32(OCB_OCBSLCSN(channel), ocbslcsn.value);
        }
        oci_ffdc(&(ffdc->oci_ffdc), OCI_MASTER_ID_OCB);
        ffdc->error = 1;
    }
}
static void ocb_ffdc ( int channel ) { OcbFfdc * ffdc ; ocb_ocbshcsn_t ocbshcsn ; ocb_ocbslcsn_t ocbslcsn ; if ( channel < 0 ) { ffdc = & ( G_ocb_ffdc . bridge ) ; } else { ffdc = & ( G_ocb_ffdc . channel [ channel ] ) ; } if ( ffdc -> error == 0 ) { if ( channel < 0 ) { memset ( ffdc , 0 , sizeof ( OcbFfdc ) ) ; } else { ffdc -> shbr . value = in32 ( OCB_OCBSHBRN ( channel ) ) ; ffdc -> shcs . value = in32 ( OCB_OCBSHCSN ( channel ) ) ; ffdc -> slbr . value = in32 ( OCB_OCBSLBRN ( channel ) ) ; ffdc -> slcs . value = in32 ( OCB_OCBSLCSN ( channel ) ) ; ocbshcsn . value = ffdc -> shcs . value ; ocbshcsn . fields . push_enable = 0 ; out32 ( OCB_OCBSHCSN ( channel ) , ocbshcsn . value ) ; ocbslcsn . value = ffdc -> slcs . value ; ocbslcsn . fields . pull_enable = 0 ; out32 ( OCB_OCBSLCSN ( channel ) , ocbslcsn . value ) ; } oci_ffdc ( & ( ffdc -> oci_ffdc ) , OCI_MASTER_ID_OCB ) ; ffdc -> error = 1 ; } }
Collect FFDC for an OCB channel
This is an internal API, called either due to an OCB error interrupt or a
read/write error detected during the operation.
Collect FFDC for an OCB channel This is an internal API called either due to an OCB error interrupt or a read / write error detected during the operation .
//TODO: Need to get OCBCSRN another way besides scom //            getscom(OCB_OCBCSRN(channel), &(ffdc->csr.value)); //TODO: Need to get OCBLFIR another way //        getscom(OCB_OCCLFIR, &(ffdc->fir.value));