Writing Device Drivers

GLDv2 Driver Requirements

GLDv2-based drivers must include the header file <sys/gld.h>.

GLDv2-based drivers must be linked with the -N“misc/gld” option:

%ld -r -N"misc/gld" xx.o -o xx

GLDv2 implements the following functions on behalf of the device-specific driver:

The mi_idname element of the module_info(9S) structure is a string that specifies the name of the driver. This string must exactly match the name of the driver module as defined in the file system.

The read-side qinit(9S) structure should specify the following elements:

qi_putp

NULL

qi_srvp

gld_rsrv

qi_qopen

gld_open

qi_qclose

gld_close

The write-side qinit(9S) structure should specify these elements:

qi_putp

gld_wput

qi_srvp

gld_wsrv

qi_qopen

NULL

qi_qclose

NULL

The devo_getinfo element of the dev_ops(9S) structure should specify gld_getinfo as the getinfo(9E) routine.

The driver's attach(9E) function associates the hardware-specific device driver with the GLDv2 facility. attach() then prepares the device and driver for use.

The attach(9E) function allocates a gld_mac_info(9S) structure using gld_mac_alloc(). The driver usually needs to save more information per device than is defined in the macinfo structure. The driver should allocate the additional required data structure and save a pointer to the structure in the gldm_private member of the gld_mac_info(9S) structure.

The attach(9E) routine must initialize the macinfo structure as described in the gld_mac_info(9S) man page. The attach() routine should then call gld_register() to link the driver with the GLDv2 module. The driver should map registers if necessary and be fully initialized and prepared to accept interrupts before calling gld_register(). The attach(9E) function should add interrupts but should not enable the device to generate these interrupts. The driver should reset the hardware before calling gld_register() to ensure the hardware is quiescent. A device must not be put into a state where the device might generate an interrupt before gld_register() is called. The device is started later when GLDv2 calls the driver's gldm_start() entry point, which is described in the gld(9E) man page. After gld_register() succeeds, the gld(9E) entry points might be called by GLDv2 at any time.

The attach(9E) routine should return DDI_SUCCESS if gld_register() succeeds. If gld_register() fails, DDI_FAILURE is returned. If a failure occurs, the attach(9E) routine should deallocate any resources that were allocated before gld_register() was called. The attach routine should then also return DDI_FAILURE. A failed macinfo structure should never be reused. Such a structure should be deallocated using gld_mac_free().

The detach(9E)function should attempt to unregister the driver from GLDv2 by calling gld_unregister(). For more information about gld_unregister(), see the gld(9F) man page. The detach(9E) routine can get a pointer to the needed gld_mac_info(9S) structure from the device's private data using ddi_get_driver_private(9F). gld_unregister() checks certain conditions that could require that the driver not be detached. If the checks fail, gld_unregister() returns DDI_FAILURE, in which case the driver's detach(9E) routine must leave the device operational and return DDI_FAILURE.

If the checks succeed, gld_unregister() ensures that the device interrupts are stopped. The driver's gldm_stop() routine is called if necessary. The driver is unlinked from the GLDv2 framework. gld_unregister() then returns DDI_SUCCESS. In this case, the detach(9E) routine should remove interrupts and use gld_mac_free() to deallocate any macinfo data structures that were allocated in the attach(9E) routine. The detach() routine should then return DDI_SUCCESS. The routine must remove the interrupt before calling gld_mac_free().