diff options
Diffstat (limited to 'src/include/ipxe/interface.h')
| -rw-r--r-- | src/include/ipxe/interface.h | 203 |
1 files changed, 182 insertions, 21 deletions
diff --git a/src/include/ipxe/interface.h b/src/include/ipxe/interface.h index 41041054c..49add3306 100644 --- a/src/include/ipxe/interface.h +++ b/src/include/ipxe/interface.h @@ -3,23 +3,116 @@ /** @file * - * Object communication interfaces + * Object interfaces * */ FILE_LICENCE ( GPL2_OR_LATER ); +#include <stddef.h> #include <ipxe/refcnt.h> -/** An object communication interface */ +/** An object interface operation */ +struct interface_operation { + /** Operation type */ + void *type; + /** Implementing method */ + void *func; +}; + +/** + * Define an object interface operation + * + * @v op_type Operation type + * @v object_type Implementing method's expected object type + * @v op_func Implementing method + * @ret op Object interface operation + */ +#define INTF_OP( op_type, object_type, op_func ) { \ + .type = op_type, \ + .func = ( ( ( ( typeof ( op_func ) * ) NULL ) == \ + ( ( op_type ## _TYPE ( object_type ) * ) NULL ) ) \ + ? op_func : op_func ), \ + } + +/** An object interface descriptor */ +struct interface_descriptor { + /** Offset of interface within containing object */ + size_t offset; + /** Number of interface operations */ + unsigned int num_op; + /** Object interface operations */ + struct interface_operation *op; + /** Offset to pass-through interface, if present */ + ssize_t passthru_offset; +}; + +#define intf_offset( object_type, intf ) \ + ( ( ( ( typeof ( ( ( object_type * ) NULL )->intf ) * ) NULL ) \ + == ( ( struct interface * ) NULL ) ) \ + ? offsetof ( object_type, intf ) \ + : offsetof ( object_type, intf ) ) + +/** + * Define an object interface descriptor + * + * @v object_type Containing object data type + * @v intf Interface name (i.e. field within object data type) + * @v operations Object interface operations array + * @ret desc Object interface descriptor + */ +#define INTF_DESC( object_type, intf, operations ) { \ + .offset = intf_offset ( object_type, intf ), \ + .op = operations, \ + .num_op = ( sizeof ( operations ) / \ + sizeof ( operations[0] ) ), \ + .passthru_offset = 0, \ + } + +/** + * Define an object interface descriptor with pass-through interface + * + * @v object_type Containing object data type + * @v intf Interface name (i.e. field within object data type) + * @v operations Object interface operations array + * @v passthru Pass-through interface name + * @ret desc Object interface descriptor + */ +#define INTF_DESC_PASSTHRU( object_type, intf, operations, passthru ) { \ + .offset = offsetof ( object_type, intf ), \ + .op = operations, \ + .num_op = ( sizeof ( operations ) / \ + sizeof ( operations[0] ) ), \ + .passthru_offset = ( intf_offset ( object_type, passthru ) - \ + intf_offset ( object_type, intf ) ), \ + } + +/** + * Define an object interface descriptor for a pure-interface object + * + * @v operations Object interface operations array + * @ret desc Object interface descriptor + * + * A pure-interface object is an object that consists solely of a + * single interface. + */ +#define INTF_DESC_PURE( operations ) { \ + .offset = 0, \ + .op = operations, \ + .num_op = ( sizeof ( operations ) / \ + sizeof ( operations[0] ) ), \ + .passthru_offset = 0, \ + } + +/** An object interface */ struct interface { - /** Destination interface + /** Destination object interface * - * When messages are sent via this interface, they will be - * delivered to the destination interface. + * When the containing object invokes an operation on this + * interface, it will be executed by the destination object. * * This pointer may never be NULL. When the interface is - * unplugged, it should point to a null interface. + * unplugged, it should point to the null interface. */ struct interface *dest; /** Reference counter @@ -28,31 +121,99 @@ struct interface { * object, this field may be NULL. */ struct refcnt *refcnt; + /** Interface descriptor */ + struct interface_descriptor *desc; }; +extern void intf_plug ( struct interface *intf, struct interface *dest ); +extern void intf_plug_plug ( struct interface *a, struct interface *b ); +extern void intf_unplug ( struct interface *intf ); +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_untyped ( struct interface *intf, void *type, + struct interface **dest ); + +extern void intf_close ( struct interface *intf, int rc ); +#define intf_close_TYPE( object_type ) \ + typeof ( void ( object_type, int rc ) ) + +extern void intf_shutdown ( struct interface *intf, int rc ); +extern void intf_restart ( struct interface *intf, int rc ); + +extern struct interface_descriptor null_intf_desc; +extern struct interface null_intf; + /** - * Increment reference count on an interface + * Initialise an object interface * - * @v intf Interface - * @ret intf Interface + * @v intf Object interface + * @v desc Object interface descriptor + * @v refcnt Containing object reference counter, or NULL */ -static inline __attribute__ (( always_inline )) struct interface * -intf_get ( struct interface *intf ) { - ref_get ( intf->refcnt ); - return intf; +static inline void intf_init ( struct interface *intf, + struct interface_descriptor *desc, + struct refcnt *refcnt ) { + intf->dest = &null_intf; + intf->refcnt = refcnt; + intf->desc = desc; } /** - * Decrement reference count on an interface + * Initialise a static object interface * - * @v intf Interface + * @v descriptor Object interface descriptor */ -static inline __attribute__ (( always_inline )) void -intf_put ( struct interface *intf ) { - ref_put ( intf->refcnt ); -} +#define INTF_INIT( descriptor ) { \ + .dest = &null_intf, \ + .refcnt = NULL, \ + .desc = &(descriptor), \ + } + +/** + * 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 + */ +#define intf_get_dest_op( intf, type, dest ) \ + ( ( type ## _TYPE ( void * ) * ) \ + intf_get_dest_op_untyped ( intf, type, dest ) ) + +/** + * Find debugging colourisation for an object interface + * + * @v intf Object interface + * @ret col Debugging colourisation + * + * Use as the first argument to DBGC() or equivalent macro. + */ +#define INTF_COL( intf ) intf_object ( intf ) + +/** printf() format string for INTF_DBG() */ +#define INTF_FMT "%p+%zx" -extern void plug ( struct interface *intf, struct interface *dest ); -extern void plug_plug ( struct interface *a, struct interface *b ); +/** + * printf() arguments for representing an object interface + * + * @v intf Object interface + * @ret args printf() argument list corresponding to INTF_FMT + */ +#define INTF_DBG( intf ) intf_object ( intf ), (intf)->desc->offset + +/** printf() format string for INTF_INTF_DBG() */ +#define INTF_INTF_FMT INTF_FMT "->" INTF_FMT + +/** + * printf() arguments for representing an object interface pair + * + * @v intf Object interface + * @v dest Destination object interface + * @ret args printf() argument list corresponding to INTF_INTF_FMT + */ +#define INTF_INTF_DBG( intf, dest ) INTF_DBG ( intf ), INTF_DBG ( dest ) #endif /* _IPXE_INTERFACE_H */ |
