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.

interface.h 7.7KB

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