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.

xfer.c 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. /*
  2. * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. #include <string.h>
  19. #include <errno.h>
  20. #include <gpxe/xfer.h>
  21. /** @file
  22. *
  23. * Data transfer interfaces
  24. *
  25. */
  26. /**
  27. * Close data transfer interface
  28. *
  29. * @v xfer Data transfer interface
  30. * @v rc Reason for close
  31. */
  32. void xfer_close ( struct xfer_interface *xfer, int rc ) {
  33. struct xfer_interface *dest = xfer_get_dest ( xfer );
  34. dest->op->close ( dest, rc );
  35. xfer_unplug ( xfer );
  36. xfer_put ( dest );
  37. }
  38. /**
  39. * Send redirection event
  40. *
  41. * @v xfer Data transfer interface
  42. * @v type New location type
  43. * @v args Remaining arguments depend upon location type
  44. * @ret rc Return status code
  45. */
  46. int xfer_vredirect ( struct xfer_interface *xfer, int type, va_list args ) {
  47. struct xfer_interface *dest = xfer_get_dest ( xfer );
  48. int rc;
  49. rc = dest->op->vredirect ( dest, type, args );
  50. xfer_put ( dest );
  51. return rc;
  52. }
  53. /**
  54. * Send redirection event
  55. *
  56. * @v xfer Data transfer interface
  57. * @v type New location type
  58. * @v ... Remaining arguments depend upon location type
  59. * @ret rc Return status code
  60. */
  61. int xfer_redirect ( struct xfer_interface *xfer, int type, ... ) {
  62. va_list args;
  63. int rc;
  64. va_start ( args, type );
  65. rc = xfer_vredirect ( xfer, type, args );
  66. va_end ( args );
  67. return rc;
  68. }
  69. /**
  70. * Request data
  71. *
  72. * @v xfer Data transfer interface
  73. * @v offset Offset to new position
  74. * @v whence Basis for new position
  75. * @v len Length of requested data
  76. * @ret rc Return status code
  77. */
  78. int xfer_request ( struct xfer_interface *xfer, off_t offset, int whence,
  79. size_t len ) {
  80. struct xfer_interface *dest = xfer_get_dest ( xfer );
  81. int rc;
  82. rc = dest->op->request ( dest, offset, whence, len );
  83. xfer_put ( dest );
  84. return rc;
  85. }
  86. /**
  87. * Request all data
  88. *
  89. * @v xfer Data transfer interface
  90. * @ret rc Return status code
  91. */
  92. int xfer_request_all ( struct xfer_interface *xfer ) {
  93. return xfer_request ( xfer, 0, SEEK_SET, ~( ( size_t ) 0 ) );
  94. }
  95. /**
  96. * Seek to position
  97. *
  98. * @v xfer Data transfer interface
  99. * @v offset Offset to new position
  100. * @v whence Basis for new position
  101. * @ret rc Return status code
  102. */
  103. int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence ) {
  104. struct xfer_interface *dest = xfer_get_dest ( xfer );
  105. int rc;
  106. rc = dest->op->seek ( dest, offset, whence );
  107. xfer_put ( dest );
  108. return rc;
  109. }
  110. /**
  111. * Allocate I/O buffer
  112. *
  113. * @v xfer Data transfer interface
  114. * @v len I/O buffer payload length
  115. * @ret iobuf I/O buffer
  116. */
  117. struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer, size_t len ) {
  118. struct xfer_interface *dest = xfer_get_dest ( xfer );
  119. struct io_buffer *iobuf;
  120. iobuf = dest->op->alloc_iob ( dest, len );
  121. xfer_put ( dest );
  122. return iobuf;
  123. }
  124. /**
  125. * Deliver datagram
  126. *
  127. * @v xfer Data transfer interface
  128. * @v iobuf Datagram I/O buffer
  129. * @ret rc Return status code
  130. */
  131. int xfer_deliver_iob ( struct xfer_interface *xfer, struct io_buffer *iobuf ) {
  132. struct xfer_interface *dest = xfer_get_dest ( xfer );
  133. int rc;
  134. rc = dest->op->deliver_iob ( dest, iobuf );
  135. xfer_put ( dest );
  136. return rc;
  137. }
  138. /**
  139. * Deliver datagram as raw data
  140. *
  141. * @v xfer Data transfer interface
  142. * @v iobuf Datagram I/O buffer
  143. * @ret rc Return status code
  144. */
  145. int xfer_deliver_raw ( struct xfer_interface *xfer,
  146. const void *data, size_t len ) {
  147. struct xfer_interface *dest = xfer_get_dest ( xfer );
  148. int rc;
  149. rc = dest->op->deliver_raw ( dest, data, len );
  150. xfer_put ( dest );
  151. return rc;
  152. }
  153. /****************************************************************************
  154. *
  155. * Helper methods
  156. *
  157. * These functions are designed to be used as methods in the
  158. * xfer_interface_operations table.
  159. *
  160. */
  161. /**
  162. * Ignore close() event
  163. *
  164. * @v xfer Data transfer interface
  165. * @v rc Reason for close
  166. */
  167. void ignore_xfer_close ( struct xfer_interface *xfer __unused,
  168. int rc __unused ) {
  169. /* Nothing to do */
  170. }
  171. /**
  172. * Ignore vredirect() event
  173. *
  174. * @v xfer Data transfer interface
  175. * @v type New location type
  176. * @v args Remaining arguments depend upon location type
  177. * @ret rc Return status code
  178. */
  179. int ignore_xfer_vredirect ( struct xfer_interface *xfer __unused,
  180. int type __unused, va_list args __unused ) {
  181. return 0;
  182. }
  183. /**
  184. * Ignore request() event
  185. *
  186. * @v xfer Data transfer interface
  187. * @v offset Offset to new position
  188. * @v whence Basis for new position
  189. * @v len Length of requested data
  190. * @ret rc Return status code
  191. */
  192. int ignore_xfer_request ( struct xfer_interface *xfer __unused,
  193. off_t offset __unused, int whence __unused,
  194. size_t len __unused ) {
  195. return 0;
  196. }
  197. /**
  198. * Ignore seek() event
  199. *
  200. * @v xfer Data transfer interface
  201. * @v offset Offset to new position
  202. * @v whence Basis for new position
  203. * @ret rc Return status code
  204. */
  205. int ignore_xfer_seek ( struct xfer_interface *xfer __unused,
  206. off_t offset __unused, int whence __unused ) {
  207. return 0;
  208. }
  209. /**
  210. * Allocate I/O buffer
  211. *
  212. * @v xfer Data transfer interface
  213. * @v len I/O buffer payload length
  214. * @ret iobuf I/O buffer
  215. */
  216. struct io_buffer *
  217. default_xfer_alloc_iob ( struct xfer_interface *xfer __unused, size_t len ) {
  218. return alloc_iob ( len );
  219. }
  220. /**
  221. * Deliver datagram as raw data
  222. *
  223. * @v xfer Data transfer interface
  224. * @v iobuf Datagram I/O buffer
  225. * @ret rc Return status code
  226. *
  227. * This function is intended to be used as the deliver() method for
  228. * data transfer interfaces that prefer to handle raw data.
  229. */
  230. int xfer_deliver_as_raw ( struct xfer_interface *xfer,
  231. struct io_buffer *iobuf ) {
  232. int rc;
  233. rc = xfer->op->deliver_raw ( xfer, iobuf->data, iob_len ( iobuf ) );
  234. free_iob ( iobuf );
  235. return rc;
  236. }
  237. /**
  238. * Deliver datagram as I/O buffer
  239. *
  240. * @v xfer Data transfer interface
  241. * @v data Data buffer
  242. * @v len Length of data buffer
  243. * @ret rc Return status code
  244. *
  245. * This function is intended to be used as the deliver_raw() method
  246. * for data transfer interfaces that prefer to handle I/O buffers.
  247. */
  248. int xfer_deliver_as_iob ( struct xfer_interface *xfer,
  249. const void *data, size_t len ) {
  250. struct io_buffer *iobuf;
  251. iobuf = xfer->op->alloc_iob ( xfer, len );
  252. if ( ! iobuf )
  253. return -ENOMEM;
  254. memcpy ( iob_put ( iobuf, len ), data, len );
  255. return xfer->op->deliver_iob ( xfer, iobuf );
  256. }
  257. /**
  258. * Ignore datagram as raw data event
  259. *
  260. * @v xfer Data transfer interface
  261. * @v data Data buffer
  262. * @v len Length of data buffer
  263. * @ret rc Return status code
  264. */
  265. int ignore_xfer_deliver_raw ( struct xfer_interface *xfer,
  266. const void *data __unused, size_t len ) {
  267. DBGC ( xfer, "XFER %p %zd bytes delivered %s\n", xfer, len,
  268. ( ( xfer == &null_xfer ) ?
  269. "before connection" : "after termination" ) );
  270. return 0;
  271. }
  272. /** Null data transfer interface operations */
  273. struct xfer_interface_operations null_xfer_ops = {
  274. .close = ignore_xfer_close,
  275. .vredirect = ignore_xfer_vredirect,
  276. .request = ignore_xfer_request,
  277. .seek = ignore_xfer_seek,
  278. .alloc_iob = default_xfer_alloc_iob,
  279. .deliver_iob = xfer_deliver_as_raw,
  280. .deliver_raw = ignore_xfer_deliver_raw,
  281. };
  282. /**
  283. * Null data transfer interface
  284. *
  285. * This is the interface to which data transfer interfaces are
  286. * connected when unplugged. It will never generate messages, and
  287. * will silently absorb all received messages.
  288. */
  289. struct xfer_interface null_xfer = {
  290. .intf = {
  291. .dest = &null_xfer.intf,
  292. .refcnt = NULL,
  293. },
  294. .op = &null_xfer_ops,
  295. };