Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com
Answertopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions
Privacy Policy

  




 

 

Writing Device Drivers
Previous Next

GLD Service Routines

This section provides the syntax and description for the GLD service routines.

gld_mac_alloc() Function

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().

gld_mac_free() Function

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().

gld_register() Function

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

  • Returns DDI_SUCCESS

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.

gld_unregister() Function

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

  • Returns DDI_SUCCESS

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.

gld_recv() Function

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.

gld_sched() Function

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() Function

uint_t gld_intr(caddr_t);

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.

Previous Next

 
 
  Published under the terms fo the Public Documentation License Version 1.01. Design by Interspire