xref: /illumos-gate/usr/src/uts/common/sys/1394/adapters/hci1394_tlist.h (revision a28480febf31f0e61debac062a55216a98a05a92)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright (c) 1999-2000 by Sun Microsystems, Inc.
24  * All rights reserved.
25  */
26 
27 #ifndef	_SYS_1394_ADAPTERS_HCI1394_TLIST_H
28 #define	_SYS_1394_ADAPTERS_HCI1394_TLIST_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 /*
33  * hci1394_tlist.h
34  *   This implements a timed double linked list.
35  *   This list supports:
36  *	- addition of node to the end of the list
37  *	- atomic deletion of node anywhere in list
38  *	- get and remove node from head of list
39  *	- enable/disable of timeout feature
40  *	- timeout feature, if enabled, will remove each node on the list which
41  *	  has been on the list for > timeout.  The callback provided will be
42  *	  called for each node removed. The worst case time is around
43  *	  timer_resolution after the timeout has occurred (i.e. if you set the
44  *	  timer resolution to 50uS and the timeout to 100uS, you could get the
45  *	  callback anywhere from 100uS to 150uS from when you added the node to
46  *	  the list.  This is a general statement and ignores things like
47  *	  interrupt latency, context switching, etc.  So if you see a time
48  *	  around 155uS, don't complain :-)
49  *	- The timer is only used when something is on the list
50  */
51 
52 #ifdef __cplusplus
53 extern "C" {
54 #endif
55 
56 #include <sys/types.h>
57 #include <sys/conf.h>
58 #include <sys/ddi.h>
59 #include <sys/sunddi.h>
60 #include <sys/time.h>
61 #include <sys/note.h>
62 
63 /*
64  * Node Information
65  *   This structure is used to track the information for a given node in the
66  *   linked list.  The node is added to the end of the linked list be calling
67  *   tlist_add().
68  */
69 typedef struct hci1394_tlist_node_s {
70 	/*
71 	 * Public Members
72 	 *  addr
73 	 *    generic address pointer.  This should be set to point to
74 	 *    whatever information you are using this node to track.
75 	 */
76 	void	*tln_addr;
77 
78 	/*
79 	 * Private Members
80 	 *   These are private.  They are only to be used in the tlist
81 	 *   implementation.  They are included in the header file so that we
82 	 *   do not have to alloc/free memory when something is added/deleted
83 	 *   from the tlist.
84 	 */
85 	boolean_t			tln_on_list;
86 	hrtime_t			tln_expire_time;
87 	struct hci1394_tlist_node_s	*tln_prev;
88 	struct hci1394_tlist_node_s	*tln_next;
89 } hci1394_tlist_node_t;
90 
91 
92 /*
93  * callback used in hci1394_tlist_timer_t.  This will be called when a node on
94  * the list expires.
95  */
96 typedef
97     void (*hci1394_tlist_callback_t)(hci1394_tlist_node_t *node, void *arg);
98 
99 
100 /*
101  * This structure is used if you are using the timeout feature of the linked
102  * list.
103  *   timeout
104  *	time in nS when a node should be considered to haved timed out.
105  *
106  *   timer_resolution
107  *	time in nS when the list should be checked for timeouts. It can be
108  *      varied from timeout to reduce the jitter in the callback.
109  *
110  *   callback
111  *	function to call on timeout.
112  *
113  *   callback_arg
114  *	user specified argument passed in callback
115  *
116  */
117 typedef struct hci1394_tlist_timer_s {
118 	hrtime_t			tlt_timeout;
119 	hrtime_t			tlt_timer_resolution;
120 	hci1394_tlist_callback_t	tlt_callback;
121 	void				*tlt_callback_arg;
122 } hci1394_tlist_timer_t;
123 
124 
125 /* State to determine if timeout is scheduled or not */
126 typedef enum {
127 	HCI1394_TLIST_TIMEOUT_OFF,
128 	HCI1394_TLIST_TIMEOUT_ON
129 } hci1394_tlist_timeout_state_t;
130 
131 
132 /* private structure used to keep track of the tlist */
133 typedef struct hci1394_tlist_s {
134 	/* head and tail of linked list */
135 	hci1394_tlist_node_t		*tl_head;
136 	hci1394_tlist_node_t		*tl_tail;
137 
138 	/* are we using timeout feature */
139 	boolean_t			tl_timer_enabled;
140 
141 	/* has timeout() been called */
142 	hci1394_tlist_timeout_state_t	tl_state;
143 
144 	/* id returned from timeout() */
145 	timeout_id_t			tl_timeout_id;
146 
147 	/* local copy of timer_info */
148 	hci1394_tlist_timer_t		tl_timer_info;
149 
150 	hci1394_drvinfo_t		*tl_drvinfo;
151 	kmutex_t			tl_mutex;
152 } hci1394_tlist_t;
153 
154 _NOTE(SCHEME_PROTECTS_DATA("Single thread modifies", \
155 	hci1394_tlist_s::tl_state \
156 	hci1394_tlist_s::tl_timeout_id \
157 	hci1394_tlist_s::tl_timer_info.tlt_timeout))
158 
159 /* handle passed back from init() and used for rest of functions */
160 typedef	struct hci1394_tlist_s	*hci1394_tlist_handle_t;
161 
162 
163 
164 void hci1394_tlist_init(hci1394_drvinfo_t *drvinfo,
165     hci1394_tlist_timer_t *timer, hci1394_tlist_handle_t *tlist_handle);
166 void hci1394_tlist_fini(hci1394_tlist_handle_t *tlist_handle);
167 
168 
169 void hci1394_tlist_add(hci1394_tlist_handle_t tlist_handle,
170     hci1394_tlist_node_t *node);
171 int hci1394_tlist_delete(hci1394_tlist_handle_t tlist_handle,
172     hci1394_tlist_node_t *node);
173 void hci1394_tlist_get(hci1394_tlist_handle_t tlist_handle,
174     hci1394_tlist_node_t **node);
175 void hci1394_tlist_peek(hci1394_tlist_handle_t tlist_handle,
176     hci1394_tlist_node_t **node);
177 
178 void hci1394_tlist_timeout_update(hci1394_tlist_handle_t tlist_handle,
179     hrtime_t timeout);
180 void hci1394_tlist_timeout_cancel(hci1394_tlist_handle_t tlist_handle);
181 
182 
183 #ifdef	__cplusplus
184 }
185 #endif
186 
187 #endif	/* _SYS_1394_ADAPTERS_HCI1394_TLIST_H */
188