Rev 3521 | Rev 3531 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3521 | Rev 3530 | ||
---|---|---|---|
Line 36... | Line 36... | ||
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. |
Line 57... | Line 123... | ||
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) { |
Line 76... | Line 143... | ||
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; |
Line 99... | Line 166... | ||
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; |
Line 124... | Line 188... | ||
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 | } |