iPXE
blocktrans.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2015 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., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27/**
28 * @file
29 *
30 * Block device translator
31 *
32 */
33
34#include <stdlib.h>
35#include <string.h>
36#include <errno.h>
37#include <assert.h>
38#include <ipxe/iobuf.h>
39#include <ipxe/xfer.h>
40#include <ipxe/blockdev.h>
41#include <ipxe/blocktrans.h>
42
43/**
44 * Close block device translator
45 *
46 * @v blktrans Block device translator
47 * @v rc Reason for close
48 */
49static void blktrans_close ( struct block_translator *blktrans, int rc ) {
50 struct block_device_capacity capacity;
51
52 /* Report block device capacity, if applicable */
53 if ( ( rc == 0 ) && ( blktrans->blksize ) ) {
54
55 /* Construct block device capacity */
56 capacity.blocks =
57 ( blktrans->xferbuf.len / blktrans->blksize );
58 capacity.blksize = blktrans->blksize;
59 capacity.max_count = -1U;
60
61 /* Report block device capacity */
62 block_capacity ( &blktrans->block, &capacity );
63 }
64
65 /* Shut down interfaces */
66 intf_shutdown ( &blktrans->xfer, rc );
67 intf_shutdown ( &blktrans->block, rc );
68}
69
70/**
71 * Deliver data
72 *
73 * @v blktrans Block device translator
74 * @v iobuf I/O buffer
75 * @v meta Data transfer metadata
76 * @ret rc Return status code
77 */
78static int blktrans_deliver ( struct block_translator *blktrans,
79 struct io_buffer *iobuf,
80 struct xfer_metadata *meta ) {
81 int rc;
82
83 /* Deliver to buffer */
84 if ( ( rc = xferbuf_deliver ( &blktrans->xferbuf, iob_disown ( iobuf ),
85 meta ) ) != 0 ) {
86 DBGC ( blktrans, "BLKTRANS %p could not deliver: %s\n",
87 blktrans, strerror ( rc ) );
88 goto err;
89 }
90
91 return 0;
92
93 err:
94 blktrans_close ( blktrans, rc );
95 return rc;
96}
97
98/**
99 * Get underlying data transfer buffer
100 *
101 * @v blktrans Block device translator
102 * @ret xferbuf Data transfer buffer
103 */
104static struct xfer_buffer *
105blktrans_buffer ( struct block_translator *blktrans ) {
106
107 return &blktrans->xferbuf;
108}
109
110/** Block device translator block device interface operations */
114
115/** Block device translator block device interface descriptor */
119
120/** Block device translator data transfer interface operations */
126
127/** Block device translator data transfer interface descriptor */
131
132/**
133 * Insert block device translator
134 *
135 * @v block Block device interface
136 * @v buffer Data buffer (or NULL)
137 * @v size Length of data buffer, or block size
138 * @ret rc Return status code
139 */
140int block_translate ( struct interface *block, void *buffer, size_t size ) {
141 struct block_translator *blktrans;
142 int rc;
143
144 /* Allocate and initialise structure */
145 blktrans = zalloc ( sizeof ( *blktrans ) );
146 if ( ! blktrans ) {
147 rc = -ENOMEM;
148 goto err_alloc;
149 }
150 ref_init ( &blktrans->refcnt, NULL );
151 intf_init ( &blktrans->block, &blktrans_block_desc, &blktrans->refcnt );
152 intf_init ( &blktrans->xfer, &blktrans_xfer_desc, &blktrans->refcnt );
153 if ( buffer ) {
154 xferbuf_fixed_init ( &blktrans->xferbuf, buffer, size );
155 } else {
156 xferbuf_void_init ( &blktrans->xferbuf );
157 blktrans->blksize = size;
158 }
159
160 /* Attach to interfaces, mortalise self, and return */
161 intf_insert ( block, &blktrans->block, &blktrans->xfer );
162 ref_put ( &blktrans->refcnt );
163
164 DBGC2 ( blktrans, "BLKTRANS %p created", blktrans );
165 if ( buffer ) {
166 DBGC2 ( blktrans, " for %#lx+%#zx",
167 virt_to_phys ( buffer ), size );
168 }
169 DBGC2 ( blktrans, "\n" );
170 return 0;
171
172 ref_put ( &blktrans->refcnt );
173 err_alloc:
174 return rc;
175}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
Assertions.
void block_capacity(struct interface *intf, struct block_device_capacity *capacity)
Report block device capacity.
Definition blockdev.c:130
Block devices.
static struct interface_operation blktrans_xfer_operations[]
Block device translator data transfer interface operations.
Definition blocktrans.c:121
static void blktrans_close(struct block_translator *blktrans, int rc)
Close block device translator.
Definition blocktrans.c:49
static struct interface_descriptor blktrans_xfer_desc
Block device translator data transfer interface descriptor.
Definition blocktrans.c:128
static struct interface_operation blktrans_block_operations[]
Block device translator block device interface operations.
Definition blocktrans.c:111
static struct xfer_buffer * blktrans_buffer(struct block_translator *blktrans)
Get underlying data transfer buffer.
Definition blocktrans.c:105
int block_translate(struct interface *block, void *buffer, size_t size)
Insert block device translator.
Definition blocktrans.c:140
static int blktrans_deliver(struct block_translator *blktrans, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver data.
Definition blocktrans.c:78
static struct interface_descriptor blktrans_block_desc
Block device translator block device interface descriptor.
Definition blocktrans.c:116
Block device translator.
uint8_t meta
Metadata flags.
Definition ena.h:3
Error codes.
#define DBGC2(...)
Definition compiler.h:522
#define DBGC(...)
Definition compiler.h:505
uint16_t size
Buffer size.
Definition dwmac.h:3
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition netvsc.h:5
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define ENOMEM
Not enough space.
Definition errno.h:535
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
String functions.
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition interface.c:250
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition interface.c:279
void intf_insert(struct interface *intf, struct interface *upper, struct interface *lower)
Insert a filter interface.
Definition interface.c:402
#define INTF_DESC_PASSTHRU(object_type, intf, operations, passthru)
Define an object interface descriptor with pass-through interface.
Definition interface.h:98
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition interface.h:204
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition interface.h:33
I/O buffers.
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:217
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
uint8_t block[3][8]
DES-encrypted blocks.
Definition mschapv2.h:1
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
Block device capacity.
Definition blockdev.h:18
uint64_t blocks
Total number of blocks.
Definition blockdev.h:20
unsigned int max_count
Maximum number of blocks per single transfer.
Definition blockdev.h:24
size_t blksize
Block size.
Definition blockdev.h:22
A block device translator.
Definition blocktrans.h:19
struct interface xfer
Data transfer interface.
Definition blocktrans.h:25
size_t blksize
Block size.
Definition blocktrans.h:30
struct xfer_buffer xferbuf
Data transfer buffer.
Definition blocktrans.h:28
struct refcnt refcnt
Reference count.
Definition blocktrans.h:21
struct interface block
Block device interface.
Definition blocktrans.h:23
An object interface descriptor.
Definition interface.h:56
An object interface operation.
Definition interface.h:18
An object interface.
Definition interface.h:125
A persistent I/O buffer.
Definition iobuf.h:38
A data transfer buffer.
Definition xferbuf.h:19
size_t len
Size of data.
Definition xferbuf.h:23
Data transfer metadata.
Definition xfer.h:23
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition xfer.c:195
Data transfer interfaces.
int xferbuf_deliver(struct xfer_buffer *xferbuf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Add received data to data transfer buffer.
Definition xferbuf.c:175
static void xferbuf_fixed_init(struct xfer_buffer *xferbuf, void *data, size_t len)
Initialise fixed-size data transfer buffer.
Definition xferbuf.h:81
static void xferbuf_void_init(struct xfer_buffer *xferbuf)
Initialise void data transfer buffer.
Definition xferbuf.h:96