GLD Service Routines
This section provides the syntax and description for the GLD 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 GLD-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
GLD-based device driver with the GLD 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 GLD 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 GLD 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 GLD framework to retry previously unsendable packets. gld_sched() should be called as
soon as possible after resources become available so that GLD 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 GLD'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.