Writing Device Drivers

open(9E)

int xxopen(dev_t *devp, int flag, int otyp, cred_t *credp)

The open(9E) entry point is used to gain access to a given device. The open(9E) routine of a block driver is called when a user thread issues an open(2) or mount(2) system call on a block special file associated with the minor device, or when a layered driver calls open(9E). See "File I/O" for more information.

The open(9E) entry point should check for the following:

Example 10-2 demonstrates a block driver open(9E) entry point.


Example 10-2 Block Driver open(9E) Routine

static int
xxopen(dev_t *devp, int flags, int otyp, cred_t *credp)
{
	   minor_t             instance;
	   struct xxstate			*xsp;

 	instance = getminor(*devp);
 	xsp = ddi_get_soft_state(statep, instance);
 	if (xsp == NULL)
		       return (ENXIO);
 	mutex_enter(&xsp->mu);
 	/*
	    * only honor FEXCL. If a regular open or a layered open
	    * is still outstanding on the device, the exclusive open
	    * must fail.
	    */
 	if ((flags & FEXCL) && (xsp->open || xsp->nlayered)) {
	   	mutex_exit(&xsp->mu);
	   	return (EAGAIN);
 	}
 	switch (otyp) {
	   case OTYP_LYR:
	   	  xsp->nlayered++;
	   	  break;
  	case OTYP_BLK:
	   	  xsp->open = 1;
	   	  break;
 	default:
	   	  mutex_exit(&xsp->mu);
	   	  return (EINVAL);
 	}
   mutex_exit(&xsp->mu);
  	return (0);
}

The otyp argument is used to specify the type of open on the device. OTYP_BLK is the typical open type for a block device. A device may be opened several times with otyp set to OTYP_BLK, although close(9E) will be called only once when the final close of type OTYP_BLK has occurred for the device. otyp is set to OTYP_LYR if the device is being used as a layered device. For every open of type OTYP_LYR, the layering driver issues a corresponding close of type OTYP_LYR. The example keeps track of each type of open so the driver can determine when the device is not being used in close(9E). See the open(9E) manual page for more details about the otyp argument.