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 /*
31  * hci1394_tlist.h
32  *   This implements a timed double linked list.
33  *   This list supports:
34  *	- addition of node to the end of the list
35  *	- atomic deletion of node anywhere in list
36  *	- get and remove node from head of list
37  *	- enable/disable of timeout feature
38  *	- timeout feature, if enabled, will remove each node on the list which
39  *	  has been on the list for > timeout.  The callback provided will be
40  *	  called for each node removed. The worst case time is around
41  *	  timer_resolution after the timeout has occurred (i.e. if you set the
42  *	  timer resolution to 50uS and the timeout to 100uS, you could get the
43  *	  callback anywhere from 100uS to 150uS from when you added the node to
44  *	  the list.  This is a general statement and ignores things like
45  *	  interrupt latency, context switching, etc.  So if you see a time
46  *	  around 155uS, don't complain :-)
47  *	- The timer is only used when something is on the list
48  */
49 
50 #ifdef __cplusplus
51 extern "C" {
52 #endif
53 
54 #include <sys/types.h>
55 #include <sys/conf.h>
56 #include <sys/ddi.h>
57 #include <sys/sunddi.h>
58 #include <sys/time.h>
59 #include <sys/note.h>
60 
61 /*
62  * Node Information
63  *   This structure is used to track the information for a given node in the
64  *   linked list.  The node is added to the end of the linked list be calling
65  *   tlist_add().
66  */
67 typedef struct hci1394_tlist_node_s {
68 	/*
69 	 * Public Members
70 	 *  addr
71 	 *    generic address pointer.  This should be set to point to
72 	 *    whatever information you are using this node to track.
73 	 */
74 	void	*tln_addr;
75 
76 	/*
77 	 * Private Members
78 	 *   These are private.  They are only to be used in the tlist
79 	 *   implementation.  They are included in the header file so that we
80 	 *   do not have to alloc/free memory when something is added/deleted
81 	 *   from the tlist.
82 	 */
83 	boolean_t			tln_on_list;
84 	hrtime_t			tln_expire_time;
85 	struct hci1394_tlist_node_s	*tln_prev;
86 	struct hci1394_tlist_node_s	*tln_next;
87 } hci1394_tlist_node_t;
88 
89 
90 /*
91  * callback used in hci1394_tlist_timer_t.  This will be called when a node on
92  * the list expires.
93  */
94 typedef
95     void (*hci1394_tlist_callback_t)(hci1394_tlist_node_t *node, void *arg);
96 
97 
98 /*
99  * This structure is used if you are using the timeout feature of the linked
100  * list.
101  *   timeout
102  *	time in nS when a node should be considered to haved timed out.
103  *
104  *   timer_resolution
105  *	time in nS when the list should be checked for timeouts. It can be
106  *      varied from timeout to reduce the jitter in the callback.
107  *
108  *   callback
109  *	function to call on timeout.
110  *
111  *   callback_arg
112  *	user specified argument passed in callback
113  *
114  */
115 typedef struct hci1394_tlist_timer_s {
116 	hrtime_t			tlt_timeout;
117 	hrtime_t			tlt_timer_resolution;
118 	hci1394_tlist_callback_t	tlt_callback;
119 	void				*tlt_callback_arg;
120 } hci1394_tlist_timer_t;
121 
122 
123 /* State to determine if timeout is scheduled or not */
124 typedef enum {
125 	HCI1394_TLIST_TIMEOUT_OFF,
126 	HCI1394_TLIST_TIMEOUT_ON
127 } hci1394_tlist_timeout_state_t;
128 
129 
130 /* private structure used to keep track of the tlist */
131 typedef struct hci1394_tlist_s {
132 	/* head and tail of linked list */
133 	hci1394_tlist_node_t		*tl_head;
134 	hci1394_tlist_node_t		*tl_tail;
135 
136 	/* are we using timeout feature */
137 	boolean_t			tl_timer_enabled;
138 
139 	/* has timeout() been called */
140 	hci1394_tlist_timeout_state_t	tl_state;
141 
142 	/* id returned from timeout() */
143 	timeout_id_t			tl_timeout_id;
144 
145 	/* local copy of timer_info */
146 	hci1394_tlist_timer_t		tl_timer_info;
147 
148 	hci1394_drvinfo_t		*tl_drvinfo;
149 	kmutex_t			tl_mutex;
150 } hci1394_tlist_t;
151 
152 _NOTE(SCHEME_PROTECTS_DATA("Single thread modifies", \
153 	hci1394_tlist_s::tl_state \
154 	hci1394_tlist_s::tl_timeout_id \
155 	hci1394_tlist_s::tl_timer_info.tlt_timeout))
156 
157 /* handle passed back from init() and used for rest of functions */
158 typedef	struct hci1394_tlist_s	*hci1394_tlist_handle_t;
159 
160 
161 
162 void hci1394_tlist_init(hci1394_drvinfo_t *drvinfo,
163     hci1394_tlist_timer_t *timer, hci1394_tlist_handle_t *tlist_handle);
164 void hci1394_tlist_fini(hci1394_tlist_handle_t *tlist_handle);
165 
166 
167 void hci1394_tlist_add(hci1394_tlist_handle_t tlist_handle,
168     hci1394_tlist_node_t *node);
169 int hci1394_tlist_delete(hci1394_tlist_handle_t tlist_handle,
170     hci1394_tlist_node_t *node);
171 void hci1394_tlist_get(hci1394_tlist_handle_t tlist_handle,
172     hci1394_tlist_node_t **node);
173 void hci1394_tlist_peek(hci1394_tlist_handle_t tlist_handle,
174     hci1394_tlist_node_t **node);
175 
176 void hci1394_tlist_timeout_update(hci1394_tlist_handle_t tlist_handle,
177     hrtime_t timeout);
178 void hci1394_tlist_timeout_cancel(hci1394_tlist_handle_t tlist_handle);
179 
180 
181 #ifdef	__cplusplus
182 }
183 #endif
184 
185 #endif	/* _SYS_1394_ADAPTERS_HCI1394_TLIST_H */
186