You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. #ifndef _IPXE_INTERFACE_H
  2. #define _IPXE_INTERFACE_H
  3. /** @file
  4. *
  5. * Object interfaces
  6. *
  7. */
  8. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  9. #include <stddef.h>
  10. #include <ipxe/refcnt.h>
  11. /** An object interface operation */
  12. struct interface_operation {
  13. /** Operation type */
  14. void *type;
  15. /** Implementing method */
  16. void *func;
  17. };
  18. /**
  19. * Define an object interface operation
  20. *
  21. * @v op_type Operation type
  22. * @v object_type Implementing method's expected object type
  23. * @v op_func Implementing method
  24. * @ret op Object interface operation
  25. */
  26. #define INTF_OP( op_type, object_type, op_func ) { \
  27. .type = op_type, \
  28. .func = ( ( ( ( typeof ( op_func ) * ) NULL ) == \
  29. ( ( op_type ## _TYPE ( object_type ) * ) NULL ) ) \
  30. ? op_func : op_func ), \
  31. }
  32. /** An object interface descriptor */
  33. struct interface_descriptor {
  34. /** Offset of interface within containing object */
  35. size_t offset;
  36. /** Number of interface operations */
  37. unsigned int num_op;
  38. /** Object interface operations */
  39. struct interface_operation *op;
  40. /** Offset to pass-through interface, if present */
  41. ssize_t passthru_offset;
  42. };
  43. #define intf_offset( object_type, intf ) \
  44. ( ( ( ( typeof ( ( ( object_type * ) NULL )->intf ) * ) NULL ) \
  45. == ( ( struct interface * ) NULL ) ) \
  46. ? offsetof ( object_type, intf ) \
  47. : offsetof ( object_type, intf ) )
  48. /**
  49. * Define an object interface descriptor
  50. *
  51. * @v object_type Containing object data type
  52. * @v intf Interface name (i.e. field within object data type)
  53. * @v operations Object interface operations array
  54. * @ret desc Object interface descriptor
  55. */
  56. #define INTF_DESC( object_type, intf, operations ) { \
  57. .offset = intf_offset ( object_type, intf ), \
  58. .op = operations, \
  59. .num_op = ( sizeof ( operations ) / \
  60. sizeof ( operations[0] ) ), \
  61. .passthru_offset = 0, \
  62. }
  63. /**
  64. * Define an object interface descriptor with pass-through interface
  65. *
  66. * @v object_type Containing object data type
  67. * @v intf Interface name (i.e. field within object data type)
  68. * @v operations Object interface operations array
  69. * @v passthru Pass-through interface name
  70. * @ret desc Object interface descriptor
  71. */
  72. #define INTF_DESC_PASSTHRU( object_type, intf, operations, passthru ) { \
  73. .offset = offsetof ( object_type, intf ), \
  74. .op = operations, \
  75. .num_op = ( sizeof ( operations ) / \
  76. sizeof ( operations[0] ) ), \
  77. .passthru_offset = ( intf_offset ( object_type, passthru ) - \
  78. intf_offset ( object_type, intf ) ), \
  79. }
  80. /**
  81. * Define an object interface descriptor for a pure-interface object
  82. *
  83. * @v operations Object interface operations array
  84. * @ret desc Object interface descriptor
  85. *
  86. * A pure-interface object is an object that consists solely of a
  87. * single interface.
  88. */
  89. #define INTF_DESC_PURE( operations ) { \
  90. .offset = 0, \
  91. .op = operations, \
  92. .num_op = ( sizeof ( operations ) / \
  93. sizeof ( operations[0] ) ), \
  94. .passthru_offset = 0, \
  95. }
  96. /** An object interface */
  97. struct interface {
  98. /** Destination object interface
  99. *
  100. * When the containing object invokes an operation on this
  101. * interface, it will be executed by the destination object.
  102. *
  103. * This pointer may never be NULL. When the interface is
  104. * unplugged, it should point to the null interface.
  105. */
  106. struct interface *dest;
  107. /** Reference counter
  108. *
  109. * If this interface is not part of a reference-counted
  110. * object, this field may be NULL.
  111. */
  112. struct refcnt *refcnt;
  113. /** Interface descriptor */
  114. struct interface_descriptor *desc;
  115. };
  116. extern void intf_plug ( struct interface *intf, struct interface *dest );
  117. extern void intf_plug_plug ( struct interface *a, struct interface *b );
  118. extern void intf_unplug ( struct interface *intf );
  119. extern void intf_nullify ( struct interface *intf );
  120. extern struct interface * intf_get ( struct interface *intf );
  121. extern void intf_put ( struct interface *intf );
  122. extern void * __attribute__ (( pure )) intf_object ( struct interface *intf );
  123. extern void * intf_get_dest_op_no_passthru_untyped ( struct interface *intf,
  124. void *type,
  125. struct interface **dest );
  126. extern void * intf_get_dest_op_untyped ( struct interface *intf, void *type,
  127. struct interface **dest );
  128. extern void intf_close ( struct interface *intf, int rc );
  129. #define intf_close_TYPE( object_type ) \
  130. typeof ( void ( object_type, int rc ) )
  131. extern void intf_shutdown ( struct interface *intf, int rc );
  132. extern void intf_restart ( struct interface *intf, int rc );
  133. extern void intf_poke ( struct interface *intf,
  134. void ( type ) ( struct interface *intf ) );
  135. #define intf_poke_TYPE( object_type ) \
  136. typeof ( void ( object_type ) )
  137. extern struct interface_descriptor null_intf_desc;
  138. extern struct interface null_intf;
  139. /**
  140. * Initialise an object interface
  141. *
  142. * @v intf Object interface
  143. * @v desc Object interface descriptor
  144. * @v refcnt Containing object reference counter, or NULL
  145. */
  146. static inline void intf_init ( struct interface *intf,
  147. struct interface_descriptor *desc,
  148. struct refcnt *refcnt ) {
  149. intf->dest = &null_intf;
  150. intf->refcnt = refcnt;
  151. intf->desc = desc;
  152. }
  153. /**
  154. * Initialise a static object interface
  155. *
  156. * @v descriptor Object interface descriptor
  157. */
  158. #define INTF_INIT( descriptor ) { \
  159. .dest = &null_intf, \
  160. .refcnt = NULL, \
  161. .desc = &(descriptor), \
  162. }
  163. /**
  164. * Get object interface destination and operation method (without pass-through)
  165. *
  166. * @v intf Object interface
  167. * @v type Operation type
  168. * @ret dest Destination interface
  169. * @ret func Implementing method, or NULL
  170. */
  171. #define intf_get_dest_op_no_passthru( intf, type, dest ) \
  172. ( ( type ## _TYPE ( void * ) * ) \
  173. intf_get_dest_op_no_passthru_untyped ( intf, type, dest ) )
  174. /**
  175. * Get object interface destination and operation method
  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. #define intf_get_dest_op( intf, type, dest ) \
  183. ( ( type ## _TYPE ( void * ) * ) \
  184. intf_get_dest_op_untyped ( intf, type, dest ) )
  185. /**
  186. * Find debugging colourisation for an object interface
  187. *
  188. * @v intf Object interface
  189. * @ret col Debugging colourisation
  190. *
  191. * Use as the first argument to DBGC() or equivalent macro.
  192. */
  193. #define INTF_COL( intf ) intf_object ( intf )
  194. /** printf() format string for INTF_DBG() */
  195. #define INTF_FMT "%p+%zx"
  196. /**
  197. * printf() arguments for representing an object interface
  198. *
  199. * @v intf Object interface
  200. * @ret args printf() argument list corresponding to INTF_FMT
  201. */
  202. #define INTF_DBG( intf ) intf_object ( intf ), (intf)->desc->offset
  203. /** printf() format string for INTF_INTF_DBG() */
  204. #define INTF_INTF_FMT INTF_FMT "->" INTF_FMT
  205. /**
  206. * printf() arguments for representing an object interface pair
  207. *
  208. * @v intf Object interface
  209. * @v dest Destination object interface
  210. * @ret args printf() argument list corresponding to INTF_INTF_FMT
  211. */
  212. #define INTF_INTF_DBG( intf, dest ) INTF_DBG ( intf ), INTF_DBG ( dest )
  213. #endif /* _IPXE_INTERFACE_H */