source: mainline/uspace/lib/libblock/libblock.c@ 7858bc5f

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 7858bc5f was 7858bc5f, checked in by Jakub Jermar <jakub@…>, 17 years ago

Setup communication parameters with the block device in block_init(). The file
system now doesn't know anything about the communication with the block device.
Rename blockread() to block_read(). The boot block is now read only once. The file
system can get access it using the block_bb_get() function.

  • Property mode set to 100644
File size: 5.1 KB
Line 
1/*
2 * Copyright (c) 2008 Jakub Jermar
3 * Copyright (c) 2008 Martin Decky
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup libblock
31 * @{
32 */
33/**
34 * @file
35 * @brief
36 */
37
38#include "libblock.h"
39#include "../../srv/vfs/vfs.h"
40#include "../../srv/rd/rd.h"
41#include <ipc/devmap.h>
42#include <ipc/services.h>
43#include <errno.h>
44#include <sys/mman.h>
45#include <async.h>
46#include <ipc/ipc.h>
47#include <as.h>
48#include <assert.h>
49
50static int dev_phone = -1; /* FIXME */
51static void *dev_buffer = NULL; /* FIXME */
52static size_t dev_buffer_len = 0; /* FIXME */
53static void *bblock = NULL; /* FIXME */
54
55int
56block_init(dev_handle_t dev_handle, size_t com_size, off_t bb_off,
57 size_t bb_size)
58{
59 int rc;
60
61 bblock = malloc(bb_size);
62 if (!bblock)
63 return ENOMEM;
64 dev_buffer_len = com_size;
65 dev_buffer = mmap(NULL, com_size, PROTO_READ | PROTO_WRITE,
66 MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
67 if (!dev_buffer) {
68 free(bblock);
69 return ENOMEM;
70 }
71 dev_phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
72 DEVMAP_CONNECT_TO_DEVICE, dev_handle);
73
74 if (dev_phone < 0) {
75 free(bblock);
76 munmap(dev_buffer, com_size);
77 return dev_phone;
78 }
79
80 rc = ipc_share_out_start(dev_phone, dev_buffer,
81 AS_AREA_READ | AS_AREA_WRITE);
82 if (rc != EOK) {
83 ipc_hangup(dev_phone);
84 free(bblock);
85 munmap(dev_buffer, com_size);
86 return rc;
87 }
88 off_t bufpos = 0;
89 size_t buflen = 0;
90 if (!block_read(dev_handle, &bufpos, &buflen, &bb_off,
91 bblock, bb_size, bb_size)) {
92 ipc_hangup(dev_phone);
93 free(bblock);
94 munmap(dev_buffer, com_size);
95 return EIO; /* XXX real error code */
96 }
97 return EOK;
98}
99
100void block_fini(dev_handle_t dev_handle)
101{
102 /* XXX */
103 free(bblock);
104 munmap(dev_buffer, dev_buffer_len);
105 ipc_hangup(dev_phone);
106}
107
108void *block_bb_get(dev_handle_t dev_handle)
109{
110 /* XXX */
111 return bblock;
112}
113
114/** Read data from a block device.
115 *
116 * @param dev_handle Device handle of the block device.
117 * @param bufpos Pointer to the first unread valid offset within the
118 * communication buffer.
119 * @param buflen Pointer to the number of unread bytes that are ready in
120 * the communication buffer.
121 * @param pos Device position to be read.
122 * @param dst Destination buffer.
123 * @param size Size of the destination buffer.
124 * @param block_size Block size to be used for the transfer.
125 *
126 * @return True on success, false on failure.
127 */
128bool
129block_read(int dev_handle, off_t *bufpos, size_t *buflen, off_t *pos, void *dst,
130 size_t size, size_t block_size)
131{
132 off_t offset = 0;
133 size_t left = size;
134
135 while (left > 0) {
136 size_t rd;
137
138 if (*bufpos + left < *buflen)
139 rd = left;
140 else
141 rd = *buflen - *bufpos;
142
143 if (rd > 0) {
144 /*
145 * Copy the contents of the communication buffer to the
146 * destination buffer.
147 */
148 memcpy(dst + offset, dev_buffer + *bufpos, rd);
149 offset += rd;
150 *bufpos += rd;
151 *pos += rd;
152 left -= rd;
153 }
154
155 if (*bufpos == *buflen) {
156 /* Refill the communication buffer with a new block. */
157 ipcarg_t retval;
158 int rc = async_req_2_1(dev_phone, RD_READ_BLOCK,
159 *pos / block_size, block_size, &retval);
160 if ((rc != EOK) || (retval != EOK))
161 return false;
162
163 *bufpos = 0;
164 *buflen = block_size;
165 }
166 }
167
168 return true;
169}
170
171block_t *block_get(dev_handle_t dev_handle, off_t offset, size_t bs)
172{
173 /* FIXME */
174 block_t *b;
175 off_t bufpos = 0;
176 size_t buflen = 0;
177 off_t pos = offset * bs;
178
179 assert(dev_phone != -1);
180 assert(dev_buffer);
181
182 b = malloc(sizeof(block_t));
183 if (!b)
184 return NULL;
185
186 b->data = malloc(bs);
187 if (!b->data) {
188 free(b);
189 return NULL;
190 }
191 b->size = bs;
192
193 if (!block_read(dev_handle, &bufpos, &buflen, &pos, b->data,
194 bs, bs)) {
195 free(b->data);
196 free(b);
197 return NULL;
198 }
199
200 return b;
201}
202
203void block_put(block_t *block)
204{
205 /* FIXME */
206 free(block->data);
207 free(block);
208}
209
210/** @}
211 */
Note: See TracBrowser for help on using the repository browser.