The prototype for the minidriver handler function is as follows:
int mdriver_handler(int state, void *data);
See the description for mdriver_add() for the definition of state and the data pointer variable.
For this sample driver, the source code for the handler function would look like this:
struct mini_data { uint16_t nstartup; uint16_t nstartupp; uint16_t nstartupf; uint16_t nkernel; uint16_t nprocess; uint16_t data_len; }; /* * Sample minidriver handler function for debug purposes * * Counts the number of calls for each state and * fills the data area with the current handler state */ int mini_data(int state, void *data) { uint8_t *dptr; struct mini_data *mdata; mdata = (struct mini_data *) data; dptr = (uint8_t *) (mdata + 1); /* on MDRIVER_INIT, set up the data area */ if (state == MDRIVER_INIT) { mdata->nstartup = 0; mdata->nstartupf = 0; mdata->nstartupp = 0; mdata->nkernel = 0; mdata->nprocess = 0; mdata->data_len = 0; } /* count the number of calls we get for each type */ if (state == MDRIVER_STARTUP) mdata->nstartup = mdata->nstartup + 1; else if (state == MDRIVER_STARTUP_PREPARE) mdata->nstartupp = mdata->nstartupp + 1; else if (state == MDRIVER_STARTUP_FINI) mdata->nstartupf = mdata->nstartupf + 1; else if (state == MDRIVER_KERNEL) mdata->nkernel = mdata->nkernel + 1; else if (state == MDRIVER_PROCESS) mdata->nprocess = mdata->nprocess + 1; else if (state == MDRIVER_INTR_ATTACH) { /* normally disable my interrupt */ return (1); } /* put the state information in the data area after the structure if we have room */ if (mdata->data_len < 60000 ) { dptr[mdata->data_len] = (uint8_t) state; mdata->data_len = mdata->data_len + 1; } return (0); }
In this example, the handler function stores call information, so a structure has been created to allow easier access to the data area.
Since the data area is set as 64 KB, we ensure that we don't write any data outside this area. If your handler function writes outside of its data space, a system failure can occur, and the operating system may not boot. Always be sure to properly bound memory reads and writes.
During the MDRIVER_INIT state, the data area is initialized. this is only called once. If your handler is called with MDRIVER_INTR_ATTACH, it returns a value of 1, requesting an exit of the handler. However, due to the asynchronous nature of the system, there might be several more invocations of the handler after it has indicated that it wants to stop.