/*	@(#)ndis.h 20.12 93/06/28 SMI	*/

/*
 *	(c) Copyright 1989 Sun Microsystems, Inc. Sun design patents 
 *	pending in the U.S. and foreign countries. See LEGAL NOTICE 
 *	file for terms of the license.
 */

/*
 * Ndis.h - Private header file for the dispatcher part of the notifier.
 * The dispatcher is responsible for actual delivery of notifications
 * to clients.  It maintains a list of clients with notifications pending.
 * It maintains a per client queue of conditions that have already happened.
 */

#ifndef	NDIS_DEFINED
#define	NDIS_DEFINED

/*
********************** Dispatcher Loop Notes ****************************
Each dispatcher client has a queue of conditions pending notification.
This is a scenario of actually doing the notification:

0) A condition is queued up by the detector.  If the condition is
immediate or asynchronous, it is delivered now.  Otherwise, the
condition is queued up on the client's queue.  Queuing up a client
event sets a dispatcher flag (see NDIS_EVENT_QUEUED below).

1) Later, the scheduler is called with a list of clients that have
non-empty queues.  This list is compiled by linearly sweeping the
dispatcher's client list.  Typically, this list is one or two clients
long.

2) The arguments for a client's prioritizer call are compiled.  The
arguments are initialized to empty (6 assignments).  The condition
queue is traversed and the appropriate entries are made in the arguments.
Typically, the queue is one or two entries long.  NDIS_EVENT_QUEUED
is reset.  The call to the prioritizer is made, usually this is the
default prioritizer.

3) The default prioritizer does 6 comparisions everytime to notice
the general area of notification required.  It sometimes iterates over
the non-zero bit fields to find out the specifics of what to notify.

4) A notify_* (say input) call is made.  The dispatcher needs to turn
the client handle in to a queue pointer, search the queue, remove the
queue entry and make the notification.  Any of these steps can generate
an error or ignored condition.

5) If NDIS_EVENT_QUEUED is set after returning from a prioritizer,
go back to step 2 if client is not NULL.  Otherwise, the scheduler
goes on to the next client after NULLing out the client slot that
he is done running.

Reentrant usage of data structures (client list, client queues,
NDIS_EVENT_QUEUED) is done by only changing them during normal
synchronous processing.  Also, these data structures are not relied
upon to be unchanged between calls out to clients.


********************** Public Interface Supporting *********************
The public programming interface that the dispatcher supports follows:

notify_set_scheduler_func

notify_input
notify_output
notify_exception
notify_itimer
notify_signal
notify_wait3
notify_event

notify_client

prioritizer_func
scheduler_func
input_func
output_func
exception_func
itimer_func
signal_func
wait3_func
destroy_func
event_func

notify_get_scheduler_func
*/

/*
 * Dispatcher global data.  The dispatcher uses ndis_/NDIS_ name prefices.
 */
extern	u_int	ndis_flags;		/* Flags */
#define	NDIS_EVENT_QUEUED	0x01	/* A safe client event has been queued
					   and therefore notify_client should
					   try rerunning the currently running
					   prioritizer (if any) */
#define	NDIS_CLIENT_FLUSHED	0x02	/* A notify_flush_pending was done.
					   If in the middle of a call out of the
					   dispatcher, ignore TBD */

extern	NTFY_CLIENT *ndis_clients;	/* Clients with notifications pending */
extern	NTFY_CLIENT *ndis_client_latest;/* Latest Notify_client=>NTFY_CLIENT
					   conversion success: for fast lookup
					   (nulled if client flushed) */

extern	Notify_value (*ndis_scheduler)(); /* The scheduler */
extern	Notify_value ndis_default_scheduler(); /* The default scheduler */
extern	Notify_value ndis_special_client_scheduler(); /* The special client scheduler */
extern	Notify_value ndis_default_prioritizer(); /* Default prioritizer */

/*
 * The following is part of the private interface to the dispatcher
 * that the detector calls:
 */
extern	Notify_error ndis_enqueue();	/* Detector calls to q notification
					   (takes a ntfy_client followed by a
					   ntfy_condition) */
extern  Notify_error ndis_dispatch();	/* Dispatch to all clients according
					   to the scheduler */

void	ndis_flush_condition();		/* Flush condition from dispatcher q
					   (Notify_client client,
					    NTFY_TYPE type, NTFY_DATA data,
					    int use_data) */
void	ndis_flush_wait3();		/* Flush all conditions for pid
					   (Notify_client client, int pid) */
#endif

