Changeset 916bf1a in mainline
- Timestamp:
- 2008-10-28T17:49:23Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0d974d8
- Parents:
- 7858bc5f
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libblock/libblock.c
r7858bc5f r916bf1a 47 47 #include <as.h> 48 48 #include <assert.h> 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 */ 49 #include <futex.h> 50 #include <libadt/list.h> 51 52 /** Lock protecting the device connection list */ 53 static futex_t dcl_lock = FUTEX_INITIALIZER; 54 /** Device connection list head. */ 55 static LIST_INITIALIZE(dcl_head); 56 57 typedef struct { 58 link_t link; 59 int dev_handle; 60 int dev_phone; 61 void *com_area; 62 size_t com_size; 63 void *bb_buf; 64 off_t bb_off; 65 size_t bb_size; 66 } devcon_t; 67 68 static devcon_t *devcon_search(dev_handle_t dev_handle) 69 { 70 link_t *cur; 71 72 futex_down(&dcl_lock); 73 for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) { 74 devcon_t *devcon = list_get_instance(cur, devcon_t, link); 75 if (devcon->dev_handle == dev_handle) { 76 futex_up(&dcl_lock); 77 return devcon; 78 } 79 } 80 futex_up(&dcl_lock); 81 return NULL; 82 } 83 84 static int devcon_add(dev_handle_t dev_handle, int dev_phone, void *com_area, 85 size_t com_size, void *bb_buf, off_t bb_off, size_t bb_size) 86 { 87 link_t *cur; 88 devcon_t *devcon; 89 90 devcon = malloc(sizeof(devcon_t)); 91 if (!devcon) 92 return ENOMEM; 93 94 link_initialize(&devcon->link); 95 devcon->dev_handle = dev_handle; 96 devcon->dev_phone = dev_phone; 97 devcon->com_area = com_area; 98 devcon->com_size = com_size; 99 devcon->bb_buf = bb_buf; 100 devcon->bb_off = bb_off; 101 devcon->bb_size = bb_size; 102 103 futex_down(&dcl_lock); 104 for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) { 105 devcon_t *d = list_get_instance(cur, devcon_t, link); 106 if (d->dev_handle == dev_handle) { 107 futex_up(&dcl_lock); 108 free(devcon); 109 return EEXIST; 110 } 111 } 112 list_append(&devcon->link, &dcl_head); 113 futex_up(&dcl_lock); 114 return EOK; 115 } 116 117 static void devcon_remove(devcon_t *devcon) 118 { 119 futex_down(&dcl_lock); 120 list_remove(&devcon->link); 121 futex_up(&dcl_lock); 122 } 54 123 55 124 int … … 58 127 { 59 128 int rc; 60 61 bblock = malloc(bb_size); 62 if (!bblock) 129 int dev_phone; 130 void *com_area; 131 void *bb_buf; 132 133 bb_buf = malloc(bb_size); 134 if (!bb_buf) 63 135 return ENOMEM; 64 dev_buffer_len = com_size;65 dev_buffer= mmap(NULL, com_size, PROTO_READ | PROTO_WRITE,136 137 com_area = mmap(NULL, com_size, PROTO_READ | PROTO_WRITE, 66 138 MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); 67 if (! dev_buffer) {68 free(bb lock);139 if (!com_area) { 140 free(bb_buf); 69 141 return ENOMEM; 70 142 } … … 73 145 74 146 if (dev_phone < 0) { 75 free(bb lock);76 munmap( dev_buffer, com_size);147 free(bb_buf); 148 munmap(com_area, com_size); 77 149 return dev_phone; 78 150 } 79 151 80 rc = ipc_share_out_start(dev_phone, dev_buffer,152 rc = ipc_share_out_start(dev_phone, com_area, 81 153 AS_AREA_READ | AS_AREA_WRITE); 82 154 if (rc != EOK) { 155 free(bb_buf); 156 munmap(com_area, com_size); 83 157 ipc_hangup(dev_phone); 84 free(bblock);85 munmap(dev_buffer, com_size);86 158 return rc; 87 159 } 160 161 rc = devcon_add(dev_handle, dev_phone, com_area, com_size, bb_buf, 162 bb_off, bb_size); 163 if (rc != EOK) { 164 free(bb_buf); 165 munmap(com_area, com_size); 166 ipc_hangup(dev_phone); 167 return rc; 168 } 169 88 170 off_t bufpos = 0; 89 171 size_t buflen = 0; 90 172 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); 173 bb_buf, bb_size, bb_size)) { 174 block_fini(dev_handle); 95 175 return EIO; /* XXX real error code */ 96 176 } 177 97 178 return EOK; 98 179 } … … 100 181 void block_fini(dev_handle_t dev_handle) 101 182 { 102 /* XXX */ 103 free(bblock); 104 munmap(dev_buffer, dev_buffer_len); 105 ipc_hangup(dev_phone); 183 devcon_t *devcon = devcon_search(dev_handle); 184 assert(devcon); 185 186 devcon_remove(devcon); 187 188 free(devcon->bb_buf); 189 munmap(devcon->com_area, devcon->com_size); 190 ipc_hangup(devcon->dev_phone); 191 192 free(devcon); 106 193 } 107 194 108 195 void *block_bb_get(dev_handle_t dev_handle) 109 196 { 110 /* XXX */ 111 return bblock; 197 devcon_t *devcon = devcon_search(dev_handle); 198 assert(devcon); 199 return devcon->bb_buf; 112 200 } 113 201 … … 132 220 off_t offset = 0; 133 221 size_t left = size; 222 devcon_t *devcon = devcon_search(dev_handle); 223 assert(devcon); 134 224 135 225 while (left > 0) { … … 146 236 * destination buffer. 147 237 */ 148 memcpy(dst + offset, dev _buffer+ *bufpos, rd);238 memcpy(dst + offset, devcon->com_area + *bufpos, rd); 149 239 offset += rd; 150 240 *bufpos += rd; … … 156 246 /* Refill the communication buffer with a new block. */ 157 247 ipcarg_t retval; 158 int rc = async_req_2_1(dev _phone, RD_READ_BLOCK,248 int rc = async_req_2_1(devcon->dev_phone, RD_READ_BLOCK, 159 249 *pos / block_size, block_size, &retval); 160 250 if ((rc != EOK) || (retval != EOK)) … … 177 267 off_t pos = offset * bs; 178 268 179 assert(dev_phone != -1);180 assert(dev_buffer);181 182 269 b = malloc(sizeof(block_t)); 183 270 if (!b)
Note:
See TracChangeset
for help on using the changeset viewer.