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 | } |