aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/interface.c39
-rw-r--r--src/core/xfer.c2
-rw-r--r--src/include/ipxe/interface.h15
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