Next | Prev | Up | Top | Contents | Index

STREAMS Driver Entry Points

The STREAMS driver entry points are listed in Table 2-4.

STREAMS Driver Entry Points
Driver Entry Points   
putsrvopenclose


put - Coordinate Message Passing Between Queues in a Stream

The primary task of the put routine is to coordinate the passing of messages from one queue to the next in a stream. The put routine is called by the preceding component (module, driver, or stream head) in the stream. put routines are designated write or read depending on the direction of message flow.

This entry point is required in all STREAMS drivers and modules.

Synopsis

drvput(register queue_t *q, register inblk_t *mp);

Usage

Both modules and drivers must have put routines for writing. Modules must have put routines for reading, but drivers do not really need them because their interrupt handlers can do the work intended for the read put routine. If immediate processing is desired when a message is passed to the put routine, it can either process the message or queue it so that the service routine can process it later. See srv(D2).

Note: The majority of STREAMS drivers are software drivers, however, and do not have interrupt handlers. The put routine must do at least one of the following when it receives a message:

Typically, the put routine switches on the message type, which is contained in mp->b_datap->db_type, taking different actions depending on the message type. For example, a put routine might process high-priority messages and queue normal messages.

The putq function can be used as a module's put routine when no special processing is required and all messages are to be queued for the service routine.

Notes

Although queue flushing can be done in the service routine, drivers and modules usually handle it in their put routines.

Return Values

Ignored

Synchronization Constraints

put routines do not have a user context and so may not call any function that sleeps.


srv - Service Routine

The srv (service) routine may be included in a STREAMS module or driver for a number of reasons. It provides greater control over the flow of messages in a stream by allowing the module or driver to reorder messages, defer the processing of some messages, or fragment and reassemble messages. The service routine also provides a way to recover from resource allocation failures.

Synopsis

drvsrv(register queue queue_t *q);

Usage

This entry point is optional and is valid for STREAMS drivers and modules only.

A message is first passed to a module's or driver's put(D2) routine, which may or may not process it. The put routine can place the message on the queue for processing by the service routine.

Once a message has been queued, the STREAMS scheduler calls the service routine at some later time. Drivers and modules should not depend on the order in which service procedures are run. This is an implementation-dependent characteristic. In particular, applications should not rely on service procedures running before returning to user-level processing.

Every STREAMS queue has limit values it uses to implement flow control (see queue(D4). High and low water marks are checked to stop and restart the flow of message processing. Flow control limits apply only between two adjacent queues with service routines. Flow control occurs by service routines following certain rules before passing messages along. By convention, high-priority messages are not affected by flow control.

STREAMS messages can be defined to have up to 256 different priorities to support some networking protocol requirements for multiple bands of data flow. At a minimum, a stream must distinguish between normal (priority band zero) messages and high-priority messages (such as M_IOCACK). High-priority messages are always placed at the head of the queue, after any other high-priority messages already queued. Next are messages from all included priority bands, which are queued in decreasing order of priority. Each priority band has its own flow control limits. By convention, if a band is stopped, all lower priority bands are also stopped.

Once a service routine is called by the STREAMS scheduler, it must provide for processing all messages on its queue, restarting itself if necessary. Message processing must continue until either the queue is empty, the stream is flow-controlled, or an allocation error occurs. Typically, the service routine switches on the message type contained in mp->b_datap->db_type, taking different actions depending on the message type.

Each STREAMS module and driver can have a read and write service routine. If a service routine is not needed (because the put routine processes all messages), a NULL pointer should be placed in the module's qinit(D4) structure.

If the service routine finishes running for any reason other than flow control or an empty queue, then it must explicitly arrange for its rescheduling. For example, if an allocation error occurs during the processing of a message, the service routine can put the message back on the queue with putbq and, before returning, arrange to have itself rescheduled at a later time. See qenable(D3), bufcall(D3), and itimeout(D3).

Notes

Service routines can be interrupted by put routines unless the processor interrupt level is raised.

Return Values

Ignored

Synchronization Constraints

Service routines do not have a user context and so may not call any function that sleeps.


Next | Prev | Up | Top | Contents | Index