Writing Device Drivers

_init(9E)

The _init(9E) function initializes a loadable module and is called before any other routine in the loadable module.

In a SCSI HBA, the _init(9E) function must call scsi_hba_init(9F) to inform the framework of the existence of the HBA driver before calling mod_install(9F). If scsi_hba_init(9F) returns a nonzero value, _init(9E) should return this value. Otherwise, _init(9E) must return the value returned by mod_install(9F).

The driver should initialize any required global state before calling mod_install(9F).

If mod_install(9F) fails, the _init(9E) function must free any global resources allocated and must call scsi_hba_fini(9F) before returning.

The following code sample uses a global mutex to show how to allocate data that is global to all instances of a driver. The code declares global mutex and soft-state structure information. The global mutex and soft state are initialized during _init(9E).

	/*
 	 * Local static data
 	 */
 	static kmutex_t			isp_global_mutex;
 	static void					*isp_state;

The _init(9E) function in Example 14-1 shows how a SCSI HBA driver initializes a global mutex.


Example 14-1 SCSI HBA _init(9E) Function

	int
	_init(void)
	{
	  	  int     err;
	
	  	  if ((err = ddi_soft_state_init(&isp_state,
							sizeof (struct isp), 0)) != 0) {
					return (err);
		  }
	     if ((err = scsi_hba_init(&modlinkage)) == 0) {
	        			mutex_init(&isp_global_mutex, "isp global mutex",
				    	MUTEX_DRIVER, NULL);
	        			if ((err = mod_install(&modlinkage)) != 0) {
	            mutex_destroy(&isp_global_mutex);
	            scsi_hba_fini(&modlinkage);
					 ddi_soft_state_fini(&isp_state);	
	        		 }
			}
	    	return (err);
	}