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.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  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. /** Original interface descriptor
  116. *
  117. * Used by intf_reinit().
  118. */
  119. struct interface_descriptor *original;
  120. };
  121. extern void intf_plug ( struct interface *intf, struct interface *dest );
  122. extern void intf_plug_plug ( struct interface *a, struct interface *b );
  123. extern void intf_unplug ( struct interface *intf );
  124. extern void intf_nullify ( struct interface *intf );
  125. extern struct interface * intf_get ( struct interface *intf );
  126. extern void intf_put ( struct interface *intf );
  127. extern void * __attribute__ (( pure )) intf_object ( struct interface *intf );
  128. extern void * intf_get_dest_op_no_passthru_untyped ( struct interface *intf,
  129. void *type,
  130. struct interface **dest );
  131. extern void * intf_get_dest_op_untyped ( struct interface *intf, void *type,
  132. struct interface **dest );
  133. extern void intf_close ( struct interface *intf, int rc );
  134. #define intf_close_TYPE( object_type ) \
  135. typeof ( void ( object_type, int rc ) )
  136. extern void intf_shutdown ( struct interface *intf, int rc );
  137. extern void intf_restart ( struct interface *intf, int rc );
  138. extern void intf_poke ( struct interface *intf,
  139. void ( type ) ( struct interface *intf ) );
  140. #define intf_poke_TYPE( object_type ) \
  141. typeof ( void ( object_type ) )
  142. extern struct interface_descriptor null_intf_desc;
  143. extern struct interface null_intf;
  144. /**
  145. * Initialise an object interface
  146. *
  147. * @v intf Object interface
  148. * @v desc Object interface descriptor
  149. * @v refcnt Containing object reference counter, or NULL
  150. */
  151. static inline void intf_init ( struct interface *intf,
  152. struct interface_descriptor *desc,
  153. struct refcnt *refcnt ) {
  154. intf->dest = &null_intf;
  155. intf->refcnt = refcnt;
  156. intf->desc = desc;
  157. intf->original = desc;
  158. }
  159. /**
  160. * Initialise a static object interface
  161. *
  162. * @v descriptor Object interface descriptor
  163. */
  164. #define INTF_INIT( descriptor ) { \
  165. .dest = &null_intf, \
  166. .refcnt = NULL, \
  167. .desc = &(descriptor), \
  168. .original = &(descriptor), \
  169. }
  170. /**
  171. * Get object interface destination and operation method (without pass-through)
  172. *
  173. * @v intf Object interface
  174. * @v type Operation type
  175. * @ret dest Destination interface
  176. * @ret func Implementing method, or NULL
  177. */
  178. #define intf_get_dest_op_no_passthru( intf, type, dest ) \
  179. ( ( type ## _TYPE ( void * ) * ) \
  180. intf_get_dest_op_no_passthru_untyped ( intf, type, dest ) )
  181. /**
  182. * Get object interface destination and operation method
  183. *
  184. * @v intf Object interface
  185. * @v type Operation type
  186. * @ret dest Destination interface
  187. * @ret func Implementing method, or NULL
  188. */
  189. #define intf_get_dest_op( intf, type, dest ) \
  190. ( ( type ## _TYPE ( void * ) * ) \
  191. intf_get_dest_op_untyped ( intf, type, dest ) )
  192. /**
  193. * Find debugging colourisation for an object interface
  194. *
  195. * @v intf Object interface
  196. * @ret col Debugging colourisation
  197. *
  198. * Use as the first argument to DBGC() or equivalent macro.
  199. */
  200. #define INTF_COL( intf ) intf_object ( intf )
  201. /** printf() format string for INTF_DBG() */
  202. #define INTF_FMT "%p+%zx"
  203. /**
  204. * printf() arguments for representing an object interface
  205. *
  206. * @v intf Object interface
  207. * @ret args printf() argument list corresponding to INTF_FMT
  208. */
  209. #define INTF_DBG( intf ) intf_object ( intf ), (intf)->desc->offset
  210. /** printf() format string for INTF_INTF_DBG() */
  211. #define INTF_INTF_FMT INTF_FMT "->" INTF_FMT
  212. /**
  213. * printf() arguments for representing an object interface pair
  214. *
  215. * @v intf Object interface
  216. * @v dest Destination object interface
  217. * @ret args printf() argument list corresponding to INTF_INTF_FMT
  218. */
  219. #define INTF_INTF_DBG( intf, dest ) INTF_DBG ( intf ), INTF_DBG ( dest )
  220. /**
  221. * Reinitialise an object interface
  222. *
  223. * @v intf Object interface
  224. */
  225. static inline void intf_reinit ( struct interface *intf ) {
  226. /* Restore original interface descriptor */
  227. intf->desc = intf->original;
  228. }
  229. #endif /* _IPXE_INTERFACE_H */