ChorusOS 5.0 Board Support Package Developer's Guide

Notification

As soon as a device failure is detected, a hardened driver will notify its clients that the device has failed. It will turn the arbitrary and uncontrolled error into a notification event. A nexus driver will notify its child drivers through the bus event handler invocation. A leaf device driver will then notify its clients through the device event mechanism provided by the device registry (svDeviceEvent()).


Note -

If a nexus driver also exports an extra (orthogonal) interface through the device registry, both mechanisms will be used.


The dec21x4x event handler, shown in code Example 13-3, illustrates how a hardened device driver should notify its clients. This handler is called from the bus driver. The fail() routine is called either from the event handler, or directly from the driver on failure detection.


Example 13-3 dec21x4x event handler

    /*
     * PCI bus event handlers.
     * The event handler is invoked by the parent bus driver when a bus
     * event occurs in the bus.
     *
     * The DEC21 driver always supports the PCI_SYS_SHUTDOWN and
     * PCI_DEV_SHUTDOWN events. The PCI_DEV_REMOVAL support is optional and
     * is provided only when DEC21_DEV_REMOVAL is defined.
     */
    static KnError
eventHandler (void* cookie, BusEvent event, void* arg)
{
    Dec21Data* dec21 = (Dec21Data*)cookie;
    KnError    res   = K_OK;

    switch (event) {

[...]

    case PCI_SYS_ERROR: {
        uint32_f csr5;
            /*
             * PCI_SYS_ERROR is considered a fatal bus error.
             * We first check if this event was caused by our device on the
             * PCI bus.
             * If positive, all bus accesses from the device are disabled,
             * thus, we put the device into failed mode.
             */
        if (arg) {
            csr5 = *((uint32_f*)arg);
        } else {
            csr5 = dec21->pciIoOps->load_32(dec21->pciIoId, CSR5);
        }
        if (csr5 & CSR5_FBE) {
            DKI_ERR(("%s: error -- Fatal bus error (csr5=0x%08x)\n",
                     dec21->path, csr5));
            fail(dec21);
        }
        break;
    }

    case PCI_INTR_DEFECTIVE: {
            /*
             * Our interrupt line is defective (stuck interrupt).
             * We put the device into failed mode.
             */
        DKI_ERR(("%s: error -- interrupt line is defective\n", 
                dec21->path));
        res = fail(dec21);
        break;
    }

    default:
        /*
         * Palette events are ignored
         */
        res = K_ENOTIMP;
    }

    return res;
}

Refer to Part III for details about bus and system event notification.