|
|
int prefixopen(queue_t *q, dev_t *devp, int oflag, int sflag, cred_t *crp);
int prefixopen(queue_t *q, dev_t *devp, int oflag, int sflag;
See open(D2mdi) for MDI specific usage information.
The open routine may perform any of the following general functions, depending on the type of device and the service provided:
The open routine should verify that the minor portion of the device number (pre-DDI 8 and ODDI) or channel (DDI 8) is valid, that the type of access requested by oflag is appropriate for the device, and, for DDI drivers, check permissions using the user credentials pointed to by crp (see drv_priv(D3)).
Support of cloning is optional and is most often used by pseudo-drivers rather than hardware drivers. Cloning is the process of the driver selecting an unused device for the user. It eliminates the need to poll many devices when looking for an unused one. In DDI 8, the driver can achieve a clone effect by storing a channel handle, returned from the drv_open(D3) function, in the *clone_chanp argument and returning ECLONE. This causes the kernel to open the driver and channel indicated by the channel handle and use it in place of the initial driver channel for this open. If ECLONE is not returned, the *clone_chan argument is ignored.
$maxchan value set in the driver's Node(DSP/4dsp) file and the drv_maxchan member of the drvinfo(D4) structure determines the number of device nodes needed per instance of a device. Drivers that use open redirection should create one channel for the initial open plus one for each clone channel.
For STREAMS drivers and modules, the open routine is called with interrupts blocked from all STREAMS devices. If the driver sets stream head options by sending an M_SETOPTS message upstream from the open routine, then the changes are guaranteed to take effect when the system call completes.
For STREAMS drivers and modules, for a given device number (queue), only one instance of the open( ) routine can be running at any given time. However, multiple opens on any two different device numbers (queues) can be running concurrently. It is the responsibility of the driver or module to synchronize access to its private data structures in this case. For clone opens, multiple clone opens can run concurrently, and it is the driver's responsibility to synchronize access to its private data structures, as well as allocation and deallocation of device numbers.
For STREAMS drivers, all calls to the open( ) and close( ) entry point routines are mutually serialized, even for multithreaded drivers.
In ODDI and DDI versions prior to 8, STREAMS drivers implement cloning behavior by changing the device number pointed to by devp. A driver may designate certain minor devices as special clone entry points into the driver. When these are opened, the driver searches for an unused device and returns the new device number by changing the value of the device number to which devp points. Both the major device number and the minor device number can be changed, although usually just the minor number is changed. The major number is only changed when the clone controls more than one device. Using this method of cloning, a STREAMS driver never sees the sflag argument set to CLONEOPEN.
Another method of performing clone opens (again, only for ODDI and DDI versions prior to 8) does use the CLONEOPEN flag. In this method, STREAMS drivers take advantage of a special driver known as the ``clone driver''. This frees the driver from having to reserve special minors for the clone entry points. Here, the device node is actually that of the clone driver (the major number is the major number from the clone driver and the minor number is the major number from the real driver.) When the clone driver is opened, it calls the real driver open routine with sflag set to CLONEOPEN.
In DDI 8, cloning (or ``open redirection'') works differently than in previous versions. There is no longer a CLONEOPEN flag or even an sflag argument to open(D2). DDI 8 drivers cannot use the clone driver; they are responsible for performing their own open redirection. A DDI 8 driver's open entry point routine checks if a particular channel number (the ``clone channel'') was requested. Each driver selects its own clone channel number or numbers. See the open(D2) manual page and the ``Clone device'' in HDK Technical Reference article for details about how to implement open redirection.
drv_flags
member of the
drvinfo(D4)
structure.
If a kernel module wants to act
as both a STREAMS module and a STREAMS driver,
it must call
drv_attach(D3)
from its
_load(D2str)
routine twice; once with D_MOD set, and once without.
The unit number information that is extracted from the minor number in ODDI and pre-DDI 8 drivers is available in the idata pointer for DDI 8 and later drivers. The operating mode that was extracted from the minor number can be extracted from the channel number.
``Clone device'' in HDK Technical Reference