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 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 FILE_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  */
49 static 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  */
78 static 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  */
104 static struct xfer_buffer *
105 blktrans_buffer ( struct block_translator *blktrans ) {
106 
107  return &blktrans->xferbuf;
108 }
109 
110 /** Block device translator block device interface operations */
113 };
114 
115 /** Block device translator block device interface descriptor */
119 
120 /** Block device translator data transfer interface operations */
125 };
126 
127 /** Block device translator data transfer interface descriptor */
129  INTF_DESC_PASSTHRU ( struct block_translator, xfer,
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  */
140 int 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 }
An object interface operation.
Definition: interface.h:18
struct refcnt refcnt
Reference count.
Definition: blocktrans.h:21
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:250
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
Data transfer metadata.
Definition: xfer.h:23
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:279
unsigned int max_count
Maximum number of blocks per single transfer.
Definition: blockdev.h:24
static struct interface_descriptor blktrans_block_desc
Block device translator block device interface descriptor.
Definition: blocktrans.c:116
static void blktrans_close(struct block_translator *blktrans, int rc)
Close block device translator.
Definition: blocktrans.c:49
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:65
Error codes.
A data transfer buffer.
Definition: xferbuf.h:19
I/O buffers.
void block_capacity(struct interface *intf, struct block_device_capacity *capacity)
Report block device capacity.
Definition: blockdev.c:130
uint16_t size
Buffer size.
Definition: dwmac.h:14
#define DBGC(...)
Definition: compiler.h:505
Block device translator.
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
static void xferbuf_void_init(struct xfer_buffer *xferbuf)
Initialise void data transfer buffer.
Definition: xferbuf.h:96
Data transfer interfaces.
size_t len
Size of data.
Definition: xferbuf.h:23
#define ENOMEM
Not enough space.
Definition: errno.h:535
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:217
Assertions.
An object interface.
Definition: interface.h:125
A block device translator.
Definition: blocktrans.h:19
uint64_t blocks
Total number of blocks.
Definition: blockdev.h:20
static struct xfer_buffer * blktrans_buffer(struct block_translator *blktrans)
Get underlying data transfer buffer.
Definition: blocktrans.c:105
struct interface xfer
Data transfer interface.
Definition: blocktrans.h:25
An object interface descriptor.
Definition: interface.h:56
Block devices.
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:662
FILE_SECBOOT(PERMITTED)
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:33
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:195
static struct interface_descriptor blktrans_xfer_desc
Block device translator data transfer interface descriptor.
Definition: blocktrans.c:128
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_operation blktrans_xfer_operations[]
Block device translator data transfer interface operations.
Definition: blocktrans.c:121
int block_translate(struct interface *block, void *buffer, size_t size)
Insert block device translator.
Definition: blocktrans.c:140
static struct interface_operation blktrans_block_operations[]
Block device translator block device interface operations.
Definition: blocktrans.c:111
void intf_insert(struct interface *intf, struct interface *upper, struct interface *lower)
Insert a filter interface.
Definition: interface.c:402
Block device capacity.
Definition: blockdev.h:18
#define DBGC2(...)
Definition: compiler.h:522
uint8_t block[3][8]
DES-encrypted blocks.
Definition: mschapv2.h:12
struct xfer_buffer xferbuf
Data transfer buffer.
Definition: blocktrans.h:28
#define INTF_DESC_PASSTHRU(object_type, intf, operations, passthru)
Define an object interface descriptor with pass-through interface.
Definition: interface.h:98
size_t blksize
Block size.
Definition: blocktrans.h:30
uint8_t meta
Metadata flags.
Definition: ena.h:14
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:204
static void xferbuf_fixed_init(struct xfer_buffer *xferbuf, void *data, size_t len)
Initialise fixed-size data transfer buffer.
Definition: xferbuf.h:81
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
String functions.
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:107
size_t blksize
Block size.
Definition: blockdev.h:22
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
struct interface block
Block device interface.
Definition: blocktrans.h:23
A persistent I/O buffer.
Definition: iobuf.h:38