|
|
The cmos_devmgt_req and cmos_final_cleanup_req entry points are required to interact with the Management Agent, as defined earlier in the code under ``Management metalanguage operations vector''. They are the driver-side counterpart functions of udi_devmgmt_req(3udi) and udi_final_cleanup_req(3udi), respectively. The UDI environment executes the associated driver-side function after calling one of the above, passing appropriate data to the driver for it to respond to the request.
static void cmos_devmgmt_req( udi_mgmt_cb_t *cb, udi_ubit8_t mgmt_op, udi_ubit8_t parent_id) { cmos_region_data_t *rdata = cb->gcb.context;switch (mgmt_op) { case UDI_DMGMT_UNBIND: #if DO_INTERRUPTS /* Detach interrupts here... */ #endif /* Keep a link back to this CB for use in the ack. */ rdata->bus_bind_cb->gcb.initiator_context = cb;
/* Do the metalanguage-specific unbind. */ udi_bus_unbind_req(rdata->bus_bind_cb); break; default: udi_devmgmt_ack(cb, 0, UDI_OK); } }
After setting the region data structure to the context element of the
control block passed from the environment, the driver switches on the
mgmt_op
argument.
If the operation requested is UDI_DMGMT_UNBIND,
then the driver needs to send a
udi_bus_unbind_req(3udi)
back to the environment to begin the unbind operation, as well as free
any remaining resources (some resources may be left open by some
drivers until the udi_final_cleanup_req is executed by the
environment).
udi_bus_unbind_req requires a udi_bus_bind_cb_t structure.
The driver sets the initiator_context
field of bus_bind_cb
in the region data structure to the control block passed to the driver,
to indicate the parent context of the call.
It then passes rdata->bus_bind_cb
back to the environment
via udi_bus_unbind_req.
Then, the driver sends a UDI_OK status back to the environment via udi_devmgmt_ack(3udi).
Once the environment completes the unbinding of the driver, it calls udi_final_cleanup_req(3udi) and the corresponding channel operation in the driver, cmos_final_cleanup_req:
static void cmos_final_cleanup_req(udi_mgmt_cb_t *cb) { /* * We have nothing to free that wasn't already freed by * unbinding children and parents. */ udi_final_cleanup_ack(cb); }
The purpose of the cmos_final_cleanup_req routine is to provide an entry point for the UDI environment to call when unbinding the device, and the management channel is the only channel left to unbind. This allows the driver the oppportunity to free any resources still held and perform any other cleanup necessary before the driver is finally unbound from the environment.
In the case of the udi_cmos driver, all resources have already been freed when the other channels (the parent GIO channel and the child bus channel) were unbound, so the driver just passes the control block it gets from the environment back via udi_final_cleanup_ack(3udi). This is the last operation the driver performs before it is removed from the system.
See also: Device Management Operations in the UDI Core Specification.