This section provides the syntax and description for the GLDv2 service routines.
gld_mac_info_t *gld_mac_alloc(dev_info_t *dip);
gld_mac_alloc() allocates a new gld_mac_info(9S) structure and returns a pointer to the structure. Some of the GLDv2-private elements of the structure might be initialized before gld_mac_alloc() returns. All other elements are initialized to zero. The device driver must initialize some structure members, as described in the gld_mac_info(9S) man page, before passing the pointer to the gld_mac_info structure to gld_register().
void gld_mac_free(gld_mac_info_t *macinfo);
gld_mac_free() frees a gld_mac_info(9S) structure previously allocated by gld_mac_alloc().
int gld_register(dev_info_t *dip, char *name, gld_mac_info_t *macinfo);
gld_register() is called from the device driver's attach(9E) routine. gld_register() links the GLDv2-based device driver with the GLDv2 framework. Before calling gld_register(), the device driver's attach(9E) routine uses gld_mac_alloc() to allocate a gld_mac_info(9S) structure, and then initializes several structure elements. See gld_mac_info(9S) for more information. A successful call to gld_register() performs the following actions:
Links the device-specific driver with the GLDv2 system
Sets the device-specific driver's private data pointer, using ddi_set_driver_private(9F) to point to the macinfo structure
Creates the minor device node
The device interface name passed to gld_register() must exactly match the name of the driver module as that name exists in the file system.
The driver's attach(9E) routine should return DDI_SUCCESS if gld_register() succeeds. If gld_register() does not return DDI_SUCCESS, the attach(9E) routine should deallocate any allocated resources before calling gld_register(), and then return DDI_FAILURE.
int gld_unregister(gld_mac_info_t *macinfo);
gld_unregister() is called by the device driver's detach(9E) function, and if successful, performs the following tasks:
Ensures that the device's interrupts are stopped, calling the driver's gldm_stop() routine if necessary
Removes the minor device node
Unlinks the device-specific driver from the GLDv2 system
If gld_unregister() returns DDI_SUCCESS, the detach(9E) routine should deallocate any data structures allocated in the attach(9E) routine, using gld_mac_free() to deallocate the macinfo structure, and return DDI_SUCCESS. If gld_unregister() does not return DDI_SUCCESS, the driver's detach(9E) routine must leave the device operational and return DDI_FAILURE.
void gld_recv(gld_mac_info_t *macinfo, mblk_t *mp);
gld_recv() is called by the driver's interrupt handler to pass a received packet upstream. The driver must construct and pass a STREAMS M_DATA message containing the raw packet. gld_recv() determines which STREAMS queues should receive a copy of the packet, duplicating the packet if necessary. gld_recv() then formats a DL_UNITDATA_IND message, if required, and passes the data up all appropriate streams.
The driver should avoid holding mutex or other locks during the call to gld_recv(). In particular, locks that could be taken by a transmit thread must not be held during a call to gld_recv(). The interrupt thread that calls gld_recv() in some cases carries out processing that includes sending an outgoing packet. Transmission of the packet results in a call to the driver's gldm_send() routine. If gldm_send() tries to acquire a mutex that is held by gldm_intr() when gld_recv() is called, a panic occurs due to a recursive mutex entry. If other driver entry points attempt to acquire a mutex that the driver holds across a call to gld_recv(), deadlock can result.
void gld_sched(gld_mac_info_t *macinfo);
gld_sched() is called by the device driver to reschedule stalled outbound packets. Whenever the driver's gldm_send() routine returns GLD_NORESOURCES, the driver must call gld_sched() to inform the GLDv2 framework to retry previously unsendable packets. gld_sched() should be called as soon as possible after resources become available so that GLDv2 resumes passing outbound packets to the driver's gldm_send() routine. (If the driver's gldm_stop() routine is called, the driver need not retry until GLD_NORESOURCES is returned from gldm_send(). However, extra calls to gld_sched() do not cause incorrect operation.)
gld_intr() is GLDv2's main interrupt handler. Normally, gld_intr() is specified as the interrupt routine in the device driver's call to ddi_add_intr(9F). The argument to the interrupt handler is specified as int_handler_arg in the call to ddi_add_intr(9F). This argument must be a pointer to the gld_mac_info(9S) structure. gld_intr(), when appropriate, calls the device driver's gldm_intr() function, passing that pointer to the gld_mac_info(9S) structure. However, to use a high-level interrupt, the driver must provide its own high-level interrupt handler and trigger a soft interrupt from within the handler. In this case, gld_intr() would normally be specified as the soft interrupt handler in the call to ddi_add_softintr(). gld_intr() returns a value that is appropriate for an interrupt handler.