mirror of https://github.com/ipxe/ipxe.git
				
				
				
			[xferbuf] Add xfer_buffer() to provide direct access to underlying buffer
Allow data transfer buffer users to provide direct access to their underlying data transfer buffer. Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/38/head
							parent
							
								
									cbbd6b761e
								
							
						
					
					
						commit
						07b0d4fa30
					
				|  | @ -283,3 +283,42 @@ struct xfer_buffer_operations xferbuf_umalloc_operations = { | ||||||
| 	.write = xferbuf_umalloc_write, | 	.write = xferbuf_umalloc_write, | ||||||
| 	.read = xferbuf_umalloc_read, | 	.read = xferbuf_umalloc_read, | ||||||
| }; | }; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Get underlying data transfer buffer | ||||||
|  |  * | ||||||
|  |  * @v interface		Data transfer interface | ||||||
|  |  * @ret xferbuf		Data transfer buffer, or NULL on error | ||||||
|  |  * | ||||||
|  |  * This call will check that the xfer_buffer() handler belongs to the | ||||||
|  |  * destination interface which also provides xfer_deliver() for this | ||||||
|  |  * interface. | ||||||
|  |  * | ||||||
|  |  * This is done to prevent accidental accesses to a data transfer | ||||||
|  |  * buffer which may be located behind a non-transparent datapath via a | ||||||
|  |  * series of pass-through interfaces. | ||||||
|  |  */ | ||||||
|  | struct xfer_buffer * xfer_buffer ( struct interface *intf ) { | ||||||
|  | 	struct interface *dest; | ||||||
|  | 	xfer_buffer_TYPE ( void * ) *op = | ||||||
|  | 		intf_get_dest_op ( intf, xfer_buffer, &dest ); | ||||||
|  | 	void *object = intf_object ( dest ); | ||||||
|  | 	struct interface *xfer_deliver_dest; | ||||||
|  | 	struct xfer_buffer *xferbuf; | ||||||
|  | 
 | ||||||
|  | 	/* Check that this operation is provided by the same interface
 | ||||||
|  | 	 * which handles xfer_deliver(). | ||||||
|  | 	 */ | ||||||
|  | 	intf_get_dest_op ( intf, xfer_deliver, &xfer_deliver_dest ); | ||||||
|  | 
 | ||||||
|  | 	if ( op && ( dest == xfer_deliver_dest ) ) { | ||||||
|  | 		xferbuf = op ( object ); | ||||||
|  | 	} else { | ||||||
|  | 		/* Default is to not have a data transfer buffer */ | ||||||
|  | 		xferbuf = NULL; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	intf_put ( xfer_deliver_dest ); | ||||||
|  | 	intf_put ( dest ); | ||||||
|  | 	return xferbuf; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -12,6 +12,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <ipxe/iobuf.h> | #include <ipxe/iobuf.h> | ||||||
| #include <ipxe/uaccess.h> | #include <ipxe/uaccess.h> | ||||||
|  | #include <ipxe/interface.h> | ||||||
| #include <ipxe/xfer.h> | #include <ipxe/xfer.h> | ||||||
| 
 | 
 | ||||||
| /** A data transfer buffer */ | /** A data transfer buffer */ | ||||||
|  | @ -97,4 +98,8 @@ extern int xferbuf_deliver ( struct xfer_buffer *xferbuf, | ||||||
| 			     struct io_buffer *iobuf, | 			     struct io_buffer *iobuf, | ||||||
| 			     struct xfer_metadata *meta ); | 			     struct xfer_metadata *meta ); | ||||||
| 
 | 
 | ||||||
|  | extern struct xfer_buffer * xfer_buffer ( struct interface *intf ); | ||||||
|  | #define xfer_buffer_TYPE( object_type ) \ | ||||||
|  | 	typeof ( struct xfer_buffer * ( object_type ) ) | ||||||
|  | 
 | ||||||
| #endif /* _IPXE_XFERBUF_H */ | #endif /* _IPXE_XFERBUF_H */ | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue