diff options
-rw-r--r-- | src/core/interface.c | 39 | ||||
-rw-r--r-- | src/core/xfer.c | 2 | ||||
-rw-r--r-- | src/include/ipxe/interface.h | 15 |
3 files changed, 46 insertions, 10 deletions
diff --git a/src/core/interface.c b/src/core/interface.c index f0c0ae64..c69875ea 100644 --- a/src/core/interface.c +++ b/src/core/interface.c @@ -151,29 +151,50 @@ static struct interface * intf_get_passthru ( struct interface *intf ) { } /** - * Get object interface destination and operation method + * Get object interface destination and operation method (without pass-through) * * @v intf Object interface * @v type Operation type * @ret dest Destination interface * @ret func Implementing method, or NULL */ -void * intf_get_dest_op_untyped ( struct interface *intf, void *type, - struct interface **dest ) { +void * intf_get_dest_op_no_passthru_untyped ( struct interface *intf, + void *type, + struct interface **dest ) { struct interface_descriptor *desc; struct interface_operation *op; unsigned int i; + *dest = intf_get ( intf->dest ); + desc = (*dest)->desc; + for ( i = desc->num_op, op = desc->op ; i ; i--, op++ ) { + if ( op->type == type ) + return op->func; + } + + return NULL; +} + +/** + * Get object interface destination and operation method + * + * @v intf Object interface + * @v type Operation type + * @ret dest Destination interface + * @ret func Implementing method, or NULL + */ +void * intf_get_dest_op_untyped ( struct interface *intf, void *type, + struct interface **dest ) { + void *func; + while ( 1 ) { + /* Search for an implementing method provided by the * current destination interface. */ - *dest = intf_get ( intf->dest ); - desc = (*dest)->desc; - for ( i = desc->num_op, op = desc->op ; i ; i--, op++ ) { - if ( op->type == type ) - return op->func; - } + func = intf_get_dest_op_no_passthru_untyped( intf, type, dest ); + if ( func ) + return func; /* Pass through to the underlying interface, if applicable */ if ( ! ( intf = intf_get_passthru ( *dest ) ) ) diff --git a/src/core/xfer.c b/src/core/xfer.c index 057ab8b3..dce245f9 100644 --- a/src/core/xfer.c +++ b/src/core/xfer.c @@ -56,7 +56,7 @@ static struct xfer_metadata dummy_metadata; int xfer_vredirect ( struct interface *intf, int type, va_list args ) { struct interface *dest; xfer_vredirect_TYPE ( void * ) *op = - intf_get_dest_op ( intf, xfer_vredirect, &dest ); + intf_get_dest_op_no_passthru ( intf, xfer_vredirect, &dest ); void *object = intf_object ( dest ); int rc; diff --git a/src/include/ipxe/interface.h b/src/include/ipxe/interface.h index 49add330..a474aaad 100644 --- a/src/include/ipxe/interface.h +++ b/src/include/ipxe/interface.h @@ -132,6 +132,9 @@ extern void intf_nullify ( struct interface *intf ); extern struct interface * intf_get ( struct interface *intf ); extern void intf_put ( struct interface *intf ); extern void * __attribute__ (( pure )) intf_object ( struct interface *intf ); +extern void * intf_get_dest_op_no_passthru_untyped ( struct interface *intf, + void *type, + struct interface **dest ); extern void * intf_get_dest_op_untyped ( struct interface *intf, void *type, struct interface **dest ); @@ -172,6 +175,18 @@ static inline void intf_init ( struct interface *intf, } /** + * Get object interface destination and operation method (without pass-through) + * + * @v intf Object interface + * @v type Operation type + * @ret dest Destination interface + * @ret func Implementing method, or NULL + */ +#define intf_get_dest_op_no_passthru( intf, type, dest ) \ + ( ( type ## _TYPE ( void * ) * ) \ + intf_get_dest_op_no_passthru_untyped ( intf, type, dest ) ) + +/** * Get object interface destination and operation method * * @v intf Object interface |