Subversion Repositories HelenOS

Rev

Rev 3521 | Rev 3531 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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