These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / ipxe / src / core / interface.c
1 /*
2  * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26 #include <string.h>
27 #include <ipxe/interface.h>
28
29 /** @file
30  *
31  * Object interfaces
32  *
33  */
34
35 /*****************************************************************************
36  *
37  * The null interface
38  *
39  */
40
41 /**
42  * Close null interface
43  *
44  * @v intf              Null interface
45  * @v rc                Reason for close
46  */
47 static void null_intf_close ( struct interface *intf __unused,
48                               int rc __unused ) {
49
50         /* Do nothing.  In particular, do not call intf_restart(),
51          * since that would result in an infinite loop.
52          */
53 }
54
55 /** Null interface operations */
56 static struct interface_operation null_intf_op[] = {
57         INTF_OP ( intf_close, struct interface *, null_intf_close ),
58 };
59
60 /** Null interface descriptor */
61 struct interface_descriptor null_intf_desc =
62         INTF_DESC_PURE ( null_intf_op );
63
64 /** The null interface */
65 struct interface null_intf = INTF_INIT ( null_intf_desc );
66
67 /*****************************************************************************
68  *
69  * Object interface plumbing
70  *
71  */
72
73 /**
74  * Plug an object interface into a new destination object interface
75  *
76  * @v intf              Object interface
77  * @v dest              New destination object interface
78  *
79  * The reference to the existing destination interface is dropped, a
80  * reference to the new destination interface is obtained, and the
81  * interface is updated to point to the new destination interface.
82  *
83  * Note that there is no "unplug" call; instead you must plug the
84  * interface into a null interface.
85  */
86 void intf_plug ( struct interface *intf, struct interface *dest ) {
87         DBGC ( INTF_COL ( intf ),
88                "INTF " INTF_INTF_FMT " replug to " INTF_FMT "\n",
89                INTF_INTF_DBG ( intf, intf->dest ), INTF_DBG ( dest ) );
90         intf_get ( dest );
91         intf_put ( intf->dest );
92         intf->dest = dest;
93 }
94
95 /**
96  * Plug two object interfaces together
97  *
98  * @v a                 Object interface A
99  * @v b                 Object interface B
100  *
101  * Plugs interface A into interface B, and interface B into interface
102  * A.  (The basic plug() function is unidirectional; this function is
103  * merely a shorthand for two calls to plug(), hence the name.)
104  */
105 void intf_plug_plug ( struct interface *a, struct interface *b ) {
106         intf_plug ( a, b );
107         intf_plug ( b, a );
108 }
109
110 /**
111  * Unplug an object interface
112  *
113  * @v intf              Object interface
114  */
115 void intf_unplug ( struct interface *intf ) {
116         intf_plug ( intf, &null_intf );
117 }
118
119 /**
120  * Ignore all further operations on an object interface
121  *
122  * @v intf              Object interface
123  */
124 void intf_nullify ( struct interface *intf ) {
125         intf->desc = &null_intf_desc;
126 }
127
128 /**
129  * Increment reference count on an object interface
130  *
131  * @v intf              Object interface
132  * @ret intf            Object interface
133  */
134 struct interface * intf_get ( struct interface *intf ) {
135         ref_get ( intf->refcnt );
136         return intf;
137 }
138
139 /**
140  * Decrement reference count on an object interface
141  *
142  * @v intf              Object interface
143  */
144 void intf_put ( struct interface *intf ) {
145         ref_put ( intf->refcnt );
146 }
147
148 /**
149  * Get pointer to object containing object interface
150  *
151  * @v intf              Object interface
152  * @ret object          Containing object
153  */
154 void * intf_object ( struct interface *intf ) {
155         return ( ( ( void * ) intf ) - intf->desc->offset );
156 }
157
158 /**
159  * Get pass-through interface
160  *
161  * @v intf              Object interface
162  * @ret passthru        Pass-through interface, or NULL
163  */
164 static struct interface * intf_get_passthru ( struct interface *intf ) {
165         struct interface_descriptor *desc = intf->desc;
166
167         if ( desc->passthru_offset ) {
168                 return ( ( ( void * ) intf ) + desc->passthru_offset );
169         } else {
170                 return NULL;
171         }
172 }
173
174 /**
175  * Get object interface destination and operation method (without pass-through)
176  *
177  * @v intf              Object interface
178  * @v type              Operation type
179  * @ret dest            Destination interface
180  * @ret func            Implementing method, or NULL
181  */
182 void * intf_get_dest_op_no_passthru_untyped ( struct interface *intf,
183                                               void *type,
184                                               struct interface **dest ) {
185         struct interface_descriptor *desc;
186         struct interface_operation *op;
187         unsigned int i;
188
189         *dest = intf_get ( intf->dest );
190         desc = (*dest)->desc;
191         for ( i = desc->num_op, op = desc->op ; i ; i--, op++ ) {
192                 if ( op->type == type )
193                         return op->func;
194         }
195
196         return NULL;
197 }
198
199 /**
200  * Get object interface destination and operation method
201  *
202  * @v intf              Object interface
203  * @v type              Operation type
204  * @ret dest            Destination interface
205  * @ret func            Implementing method, or NULL
206  */
207 void * intf_get_dest_op_untyped ( struct interface *intf, void *type,
208                                   struct interface **dest ) {
209         void *func;
210
211         while ( 1 ) {
212
213                 /* Search for an implementing method provided by the
214                  * current destination interface.
215                  */
216                 func = intf_get_dest_op_no_passthru_untyped( intf, type, dest );
217                 if ( func )
218                         return func;
219
220                 /* Pass through to the underlying interface, if applicable */
221                 if ( ! ( intf = intf_get_passthru ( *dest ) ) )
222                         return NULL;
223                 intf_put ( *dest );
224         }
225 }
226
227 /*****************************************************************************
228  *
229  * Generic interface operations
230  *
231  */
232
233 /**
234  * Close an object interface
235  *
236  * @v intf              Object interface
237  * @v rc                Reason for close
238  *
239  * Note that this function merely informs the destination object that
240  * the interface is about to be closed; it doesn't actually disconnect
241  * the interface.  In most cases, you probably want to use
242  * intf_shutdown() or intf_restart() instead.
243  */
244 void intf_close ( struct interface *intf, int rc ) {
245         struct interface *dest;
246         intf_close_TYPE ( void * ) *op =
247                 intf_get_dest_op ( intf, intf_close, &dest );
248         void *object = intf_object ( dest );
249
250         DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " close (%s)\n",
251                INTF_INTF_DBG ( intf, dest ), strerror ( rc ) );
252
253         if ( op ) {
254                 op ( object, rc );
255         } else {
256                 /* Default is to restart the interface */
257                 intf_restart ( dest, rc );
258         }
259
260         intf_put ( dest );
261 }
262
263 /**
264  * Shut down an object interface
265  *
266  * @v intf              Object interface
267  * @v rc                Reason for close
268  *
269  * Blocks further operations from being received via the interface,
270  * executes a close operation on the destination interface, and
271  * unplugs the interface.
272  */
273 void intf_shutdown ( struct interface *intf, int rc ) {
274
275         DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " shutting down (%s)\n",
276                INTF_DBG ( intf ), strerror ( rc ) );
277
278         /* Block further operations */
279         intf_nullify ( intf );
280
281         /* Notify destination of close */
282         intf_close ( intf, rc );
283
284         /* Unplug interface */
285         intf_unplug ( intf );
286 }
287
288 /**
289  * Shut down and restart an object interface
290  *
291  * @v intf              Object interface
292  * @v rc                Reason for close
293  *
294  * Shuts down the interface, then unblocks operations that were
295  * blocked during shutdown.
296  */
297 void intf_restart ( struct interface *intf, int rc ) {
298         struct interface_descriptor *desc = intf->desc;
299
300         /* Shut down the interface */
301         intf_shutdown ( intf, rc );
302
303         DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " restarting\n",
304                INTF_DBG ( intf ) );
305
306         /* Restore the interface descriptor.  Must be done after
307          * shutdown (rather than inhibiting intf_shutdown() from
308          * nullifying the descriptor) in order to avoid a potential
309          * infinite loop as the intf_close() operations on each side
310          * of the link call each other recursively.
311          */
312         intf->desc = desc;
313 }
314
315 /**
316  * Poke an object interface
317  *
318  * @v intf              Object interface
319  * @v type              Operation type
320  *
321  * This is a helper function to implement methods which take no
322  * parameters and return nothing.
323  */
324 void intf_poke ( struct interface *intf,
325                  void ( type ) ( struct interface *intf ) ) {
326         struct interface *dest;
327         intf_poke_TYPE ( void * ) *op =
328                 intf_get_dest_op_untyped ( intf, type, &dest );
329         void *object = intf_object ( dest );
330
331         if ( op ) {
332                 op ( object );
333         } else {
334                 /* Default is to do nothing */
335         }
336
337         intf_put ( dest );
338 }