Changes in / [2988aec7:71b0d4d4] in mainline
- Files:
-
- 38 added
- 37 edited
Legend:
- Unmodified
- Added
- Removed
-
HelenOS.config
r2988aec7 r71b0d4d4 89 89 @ "tmpfs" TMPFS image 90 90 @ "fat" FAT16 image 91 @ "ext 2fs" EXT2image91 @ "ext4fs" ext4 image 92 92 ! RDFMT (choice) 93 93 -
abi/include/syscall.h
r2988aec7 r71b0d4d4 63 63 SYS_PAGE_FIND_MAPPING, 64 64 65 SYS_IPC_CALL_SYNC_FAST,66 SYS_IPC_CALL_SYNC_SLOW,67 65 SYS_IPC_CALL_ASYNC_FAST, 68 66 SYS_IPC_CALL_ASYNC_SLOW, -
boot/Makefile
r2988aec7 r71b0d4d4 47 47 $(MKFAT) 1048576 $(DIST_PATH) $@ 48 48 endif 49 ifeq ($(RDFMT),ext 2fs)50 $(MKEXT 2) 1048576 $(DIST_PATH) $@49 ifeq ($(RDFMT),ext4fs) 50 $(MKEXT4) 1048576 $(DIST_PATH) $@ 51 51 endif 52 52 -
boot/Makefile.common
r2988aec7 r71b0d4d4 55 55 MKTMPFS = $(TOOLS_PATH)/mktmpfs.py 56 56 MKFAT = $(TOOLS_PATH)/mkfat.py 57 MKEXT 2 = $(TOOLS_PATH)/mkext2.py57 MKEXT4 = $(TOOLS_PATH)/mkext4.py 58 58 MKUIMAGE = $(TOOLS_PATH)/mkuimage.py 59 59 … … 84 84 endif 85 85 86 ifeq ($(RDFMT),ext 2fs)87 INIT_TASKS += $(USPACE_PATH)/srv/fs/ext 2fs/ext2fs86 ifeq ($(RDFMT),ext4fs) 87 INIT_TASKS += $(USPACE_PATH)/srv/fs/ext4fs/ext4fs 88 88 endif 89 89 … … 106 106 $(USPACE_PATH)/srv/fs/exfat/exfat \ 107 107 $(USPACE_PATH)/srv/fs/ext2fs/ext2fs \ 108 $(USPACE_PATH)/srv/fs/ext4fs/ext4fs \ 108 109 $(USPACE_PATH)/srv/hid/remcons/remcons \ 109 110 $(USPACE_PATH)/srv/net/ethip/ethip \ … … 174 175 $(USPACE_PATH)/app/tester/tester \ 175 176 $(USPACE_PATH)/app/testread/testread \ 177 $(USPACE_PATH)/app/testwrit/testwrit \ 176 178 $(USPACE_PATH)/app/tetris/tetris \ 177 179 $(USPACE_PATH)/app/trace/trace \ -
kernel/generic/include/ipc/ipc.h
r2988aec7 r71b0d4d4 77 77 waitq_t wq; 78 78 79 /** Linkage for the list of task's synchronous answerboxes. */80 link_t sync_box_link;81 82 79 /** Phones connected to this answerbox. */ 83 80 list_t connected_phones; … … 116 113 struct task *sender; 117 114 118 /*119 * The caller box is different from sender->answerbox120 * for synchronous calls.121 */122 answerbox_t *callerbox;123 124 115 /** Private data to internal IPC. */ 125 116 sysarg_t priv; … … 147 138 148 139 extern int ipc_call(phone_t *, call_t *); 149 extern int ipc_call_sync(phone_t *, call_t *);150 140 extern call_t *ipc_wait_for_call(answerbox_t *, uint32_t, unsigned int); 151 141 extern int ipc_forward(call_t *, phone_t *, answerbox_t *, unsigned int); -
kernel/generic/include/ipc/sysipc.h
r2988aec7 r71b0d4d4 40 40 #include <typedefs.h> 41 41 42 extern sysarg_t sys_ipc_call_sync_fast(sysarg_t, sysarg_t, sysarg_t,43 sysarg_t, sysarg_t, ipc_data_t *);44 extern sysarg_t sys_ipc_call_sync_slow(sysarg_t, ipc_data_t *, ipc_data_t *);45 42 extern sysarg_t sys_ipc_call_async_fast(sysarg_t, sysarg_t, sysarg_t, 46 43 sysarg_t, sysarg_t, sysarg_t); -
kernel/generic/include/proc/task.h
r2988aec7 r71b0d4d4 94 94 phone_t phones[IPC_MAX_PHONES]; 95 95 stats_ipc_t ipc_info; /**< IPC statistics */ 96 list_t sync_boxes; /**< List of synchronous answerboxes. */97 96 event_t events[EVENT_TASK_END - EVENT_END]; 98 97 -
kernel/generic/src/ipc/ipc.c
r2988aec7 r71b0d4d4 71 71 { 72 72 memsetb(call, sizeof(*call), 0); 73 call->callerbox = &TASK->answerbox;74 73 call->sender = TASK; 75 74 call->buffer = NULL; … … 120 119 irq_spinlock_initialize(&box->irq_lock, "ipc.box.irqlock"); 121 120 waitq_initialize(&box->wq); 122 link_initialize(&box->sync_box_link);123 121 list_initialize(&box->connected_phones); 124 122 list_initialize(&box->calls); … … 163 161 } 164 162 165 /** Helper function to facilitate synchronous calls.166 *167 * @param phone Destination kernel phone structure.168 * @param request Call structure with request.169 *170 * @return EOK on success or EINTR if the sleep was interrupted.171 *172 */173 int ipc_call_sync(phone_t *phone, call_t *request)174 {175 answerbox_t *sync_box = slab_alloc(ipc_answerbox_slab, 0);176 ipc_answerbox_init(sync_box, TASK);177 178 /*179 * Put the answerbox on the TASK's list of synchronous answerboxes so180 * that it can be cleaned up if the call is interrupted.181 */182 irq_spinlock_lock(&TASK->lock, true);183 list_append(&sync_box->sync_box_link, &TASK->sync_boxes);184 irq_spinlock_unlock(&TASK->lock, true);185 186 /* We will receive data in a special box. */187 request->callerbox = sync_box;188 189 ipc_call(phone, request);190 if (!ipc_wait_for_call(sync_box, SYNCH_NO_TIMEOUT,191 SYNCH_FLAGS_INTERRUPTIBLE)) {192 /* The answerbox and the call will be freed by ipc_cleanup(). */193 return EINTR;194 }195 196 /*197 * The answer arrived without interruption so we can remove the198 * answerbox from the TASK's list of synchronous answerboxes.199 */200 irq_spinlock_lock(&TASK->lock, true);201 list_remove(&sync_box->sync_box_link);202 irq_spinlock_unlock(&TASK->lock, true);203 204 slab_free(ipc_answerbox_slab, sync_box);205 return EOK;206 }207 208 163 /** Answer a message which was not dispatched and is not listed in any queue. 209 164 * … … 214 169 static void _ipc_answer_free_call(call_t *call, bool selflocked) 215 170 { 216 answerbox_t *callerbox = call->callerbox;171 answerbox_t *callerbox = &call->sender->answerbox; 217 172 bool do_lock = ((!selflocked) || callerbox != (&TASK->answerbox)); 218 173 … … 606 561 ipc_cleanup_call_list(&TASK->answerbox.calls); 607 562 irq_spinlock_unlock(&TASK->answerbox.lock, true); 608 609 /* Wait for all answers to interrupted synchronous calls to arrive */610 ipl_t ipl = interrupts_disable();611 while (!list_empty(&TASK->sync_boxes)) {612 answerbox_t *box = list_get_instance(613 list_first(&TASK->sync_boxes), answerbox_t, sync_box_link);614 615 list_remove(&box->sync_box_link);616 call_t *call = ipc_wait_for_call(box, SYNCH_NO_TIMEOUT,617 SYNCH_FLAGS_NONE);618 ipc_call_free(call);619 slab_free(ipc_answerbox_slab, box);620 }621 interrupts_restore(ipl);622 563 623 564 /* Wait for all answers to asynchronous calls to arrive */ -
kernel/generic/src/ipc/sysipc.c
r2988aec7 r71b0d4d4 612 612 break; 613 613 } 614 615 return 0;616 }617 618 /** Make a fast call over IPC, wait for reply and return to user.619 *620 * This function can handle only three arguments of payload, but is faster than621 * the generic function (i.e. sys_ipc_call_sync_slow()).622 *623 * @param phoneid Phone handle for the call.624 * @param imethod Interface and method of the call.625 * @param arg1 Service-defined payload argument.626 * @param arg2 Service-defined payload argument.627 * @param arg3 Service-defined payload argument.628 * @param data Address of user-space structure where the reply call will629 * be stored.630 *631 * @return 0 on success.632 * @return ENOENT if there is no such phone handle.633 *634 */635 sysarg_t sys_ipc_call_sync_fast(sysarg_t phoneid, sysarg_t imethod,636 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, ipc_data_t *data)637 {638 phone_t *phone;639 if (phone_get(phoneid, &phone) != EOK)640 return ENOENT;641 642 call_t *call = ipc_call_alloc(0);643 IPC_SET_IMETHOD(call->data, imethod);644 IPC_SET_ARG1(call->data, arg1);645 IPC_SET_ARG2(call->data, arg2);646 IPC_SET_ARG3(call->data, arg3);647 648 /*649 * To achieve deterministic behavior, zero out arguments that are beyond650 * the limits of the fast version.651 */652 IPC_SET_ARG4(call->data, 0);653 IPC_SET_ARG5(call->data, 0);654 655 int res = request_preprocess(call, phone);656 int rc;657 658 if (!res) {659 #ifdef CONFIG_UDEBUG660 udebug_stoppable_begin();661 #endif662 rc = ipc_call_sync(phone, call);663 #ifdef CONFIG_UDEBUG664 udebug_stoppable_end();665 #endif666 667 if (rc != EOK) {668 /* The call will be freed by ipc_cleanup(). */669 return rc;670 }671 672 process_answer(call);673 } else674 IPC_SET_RETVAL(call->data, res);675 676 rc = STRUCT_TO_USPACE(&data->args, &call->data.args);677 ipc_call_free(call);678 if (rc != 0)679 return rc;680 681 return 0;682 }683 684 /** Make a synchronous IPC call allowing to transmit the entire payload.685 *686 * @param phoneid Phone handle for the call.687 * @param request User-space address of call data with the request.688 * @param reply User-space address of call data where to store the689 * answer.690 *691 * @return Zero on success or an error code.692 *693 */694 sysarg_t sys_ipc_call_sync_slow(sysarg_t phoneid, ipc_data_t *request,695 ipc_data_t *reply)696 {697 phone_t *phone;698 if (phone_get(phoneid, &phone) != EOK)699 return ENOENT;700 701 call_t *call = ipc_call_alloc(0);702 int rc = copy_from_uspace(&call->data.args, &request->args,703 sizeof(call->data.args));704 if (rc != 0) {705 ipc_call_free(call);706 return (sysarg_t) rc;707 }708 709 int res = request_preprocess(call, phone);710 711 if (!res) {712 #ifdef CONFIG_UDEBUG713 udebug_stoppable_begin();714 #endif715 rc = ipc_call_sync(phone, call);716 #ifdef CONFIG_UDEBUG717 udebug_stoppable_end();718 #endif719 720 if (rc != EOK) {721 /* The call will be freed by ipc_cleanup(). */722 return rc;723 }724 725 process_answer(call);726 } else727 IPC_SET_RETVAL(call->data, res);728 729 rc = STRUCT_TO_USPACE(&reply->args, &call->data.args);730 ipc_call_free(call);731 if (rc != 0)732 return rc;733 614 734 615 return 0; -
kernel/generic/src/proc/task.c
r2988aec7 r71b0d4d4 156 156 157 157 list_initialize(&task->threads); 158 list_initialize(&task->sync_boxes);159 158 160 159 ipc_answerbox_init(&task->answerbox, task); -
kernel/generic/src/syscall/syscall.c
r2988aec7 r71b0d4d4 151 151 152 152 /* IPC related syscalls. */ 153 (syshandler_t) sys_ipc_call_sync_fast,154 (syshandler_t) sys_ipc_call_sync_slow,155 153 (syshandler_t) sys_ipc_call_async_fast, 156 154 (syshandler_t) sys_ipc_call_async_slow, -
uspace/Makefile
r2988aec7 r71b0d4d4 59 59 app/tester \ 60 60 app/testread \ 61 app/testwrit \ 61 62 app/tetris \ 62 63 app/trace \ … … 98 99 srv/fs/locfs \ 99 100 srv/fs/ext2fs \ 101 srv/fs/ext4fs \ 100 102 srv/hid/console \ 101 103 srv/hid/s3c24xx_ts \ … … 197 199 lib/nic \ 198 200 lib/ext2 \ 201 lib/ext4 \ 199 202 lib/usb \ 200 203 lib/usbhost \ -
uspace/Makefile.common
r2988aec7 r71b0d4d4 115 115 116 116 LIBEXT2_PREFIX = $(LIB_PREFIX)/ext2 117 LIBEXT4_PREFIX = $(LIB_PREFIX)/ext4 117 118 118 119 LIBUSB_PREFIX = $(LIB_PREFIX)/usb -
uspace/app/trace/syscalls.c
r2988aec7 r71b0d4d4 53 53 [SYS_AS_AREA_DESTROY] = { "as_area_destroy", 1, V_ERRNO }, 54 54 55 [SYS_IPC_CALL_SYNC_FAST] = { "ipc_call_sync_fast", 6, V_ERRNO },56 [SYS_IPC_CALL_SYNC_SLOW] = { "ipc_call_sync_slow", 3, V_ERRNO },57 55 [SYS_IPC_CALL_ASYNC_FAST] = { "ipc_call_async_fast", 6, V_HASH }, 58 56 [SYS_IPC_CALL_ASYNC_SLOW] = { "ipc_call_async_slow", 2, V_HASH }, -
uspace/app/trace/trace.c
r2988aec7 r71b0d4d4 318 318 } 319 319 320 static void sc_ipc_call_sync_fast(sysarg_t *sc_args)321 {322 ipc_call_t question, reply;323 int rc;324 int phoneid;325 326 phoneid = sc_args[0];327 328 IPC_SET_IMETHOD(question, sc_args[1]);329 IPC_SET_ARG1(question, sc_args[2]);330 IPC_SET_ARG2(question, sc_args[3]);331 IPC_SET_ARG3(question, sc_args[4]);332 IPC_SET_ARG4(question, 0);333 IPC_SET_ARG5(question, 0);334 335 memset(&reply, 0, sizeof(reply));336 rc = udebug_mem_read(sess, &reply.args, sc_args[5], sizeof(reply.args));337 if (rc < 0)338 return;339 340 ipcp_call_sync(phoneid, &question, &reply);341 }342 343 static void sc_ipc_call_sync_slow_b(unsigned thread_id, sysarg_t *sc_args)344 {345 ipc_call_t question;346 int rc;347 348 memset(&question, 0, sizeof(question));349 rc = udebug_mem_read(sess, &question.args, sc_args[1],350 sizeof(question.args));351 352 if (rc < 0) {353 printf("Error: mem_read->%d\n", rc);354 return;355 }356 357 thread_ipc_req[thread_id] = question;358 }359 360 static void sc_ipc_call_sync_slow_e(unsigned thread_id, sysarg_t *sc_args)361 {362 ipc_call_t reply;363 int rc;364 365 memset(&reply, 0, sizeof(reply));366 rc = udebug_mem_read(sess, &reply.args, sc_args[2],367 sizeof(reply.args));368 369 if (rc < 0) {370 printf("Error: mem_read->%d\n", rc);371 return;372 }373 374 ipcp_call_sync(sc_args[0], &thread_ipc_req[thread_id], &reply);375 }376 377 320 static void sc_ipc_wait(sysarg_t *sc_args, int sc_rc) 378 321 { … … 408 351 print_sc_args(sc_args, syscall_desc[sc_id].n_args); 409 352 } 410 411 switch (sc_id) {412 case SYS_IPC_CALL_SYNC_SLOW:413 sc_ipc_call_sync_slow_b(thread_id, sc_args);414 break;415 default:416 break;417 }418 353 } 419 354 … … 447 382 case SYS_IPC_CALL_ASYNC_SLOW: 448 383 sc_ipc_call_async_slow(sc_args, sc_rc); 449 break;450 case SYS_IPC_CALL_SYNC_FAST:451 sc_ipc_call_sync_fast(sc_args);452 break;453 case SYS_IPC_CALL_SYNC_SLOW:454 sc_ipc_call_sync_slow_e(thread_id, sc_args);455 384 break; 456 385 case SYS_IPC_WAIT: -
uspace/drv/bus/usb/usbmast/main.c
r2988aec7 r71b0d4d4 37 37 #include <as.h> 38 38 #include <async.h> 39 #include < ipc/bd.h>39 #include <bd_srv.h> 40 40 #include <macros.h> 41 41 #include <usb/dev/driver.h> … … 82 82 void *arg); 83 83 84 static int usbmast_bd_open(bd_srv_t *); 85 static int usbmast_bd_close(bd_srv_t *); 86 static int usbmast_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t); 87 static int usbmast_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t); 88 static int usbmast_bd_get_block_size(bd_srv_t *, size_t *); 89 static int usbmast_bd_get_num_blocks(bd_srv_t *, aoff64_t *); 90 91 static bd_ops_t usbmast_bd_ops = { 92 .open = usbmast_bd_open, 93 .close = usbmast_bd_close, 94 .read_blocks = usbmast_bd_read_blocks, 95 .write_blocks = usbmast_bd_write_blocks, 96 .get_block_size = usbmast_bd_get_block_size, 97 .get_num_blocks = usbmast_bd_get_num_blocks 98 }; 99 100 static usbmast_fun_t *bd_srv_usbmast(bd_srv_t *bd) 101 { 102 return (usbmast_fun_t *)bd->arg; 103 } 104 84 105 /** Callback when a device is removed from the system. 85 106 * … … 219 240 mfun->lun = lun; 220 241 242 bd_srv_init(&mfun->bd); 243 mfun->bd.ops = &usbmast_bd_ops; 244 mfun->bd.arg = mfun; 245 221 246 /* Set up a connection handler. */ 222 247 fun->conn_handler = usbmast_bd_connection; … … 284 309 { 285 310 usbmast_fun_t *mfun; 286 void *comm_buf = NULL; 287 size_t comm_size; 288 ipc_callid_t callid; 289 ipc_call_t call; 290 unsigned int flags; 291 sysarg_t method; 292 uint64_t ba; 293 size_t cnt; 294 int retval; 295 296 async_answer_0(iid, EOK); 297 298 if (!async_share_out_receive(&callid, &comm_size, &flags)) { 299 async_answer_0(callid, EHANGUP); 300 return; 301 } 302 303 (void) async_share_out_finalize(callid, &comm_buf); 304 if (comm_buf == AS_MAP_FAILED) { 305 async_answer_0(callid, EHANGUP); 306 return; 307 } 308 311 309 312 mfun = (usbmast_fun_t *) ((ddf_fun_t *)arg)->driver_data; 310 311 while (true) { 312 callid = async_get_call(&call); 313 method = IPC_GET_IMETHOD(call); 314 315 if (!method) { 316 /* The other side hung up. */ 317 async_answer_0(callid, EOK); 318 return; 319 } 320 321 switch (method) { 322 case BD_GET_BLOCK_SIZE: 323 async_answer_1(callid, EOK, mfun->block_size); 324 break; 325 case BD_GET_NUM_BLOCKS: 326 async_answer_2(callid, EOK, LOWER32(mfun->nblocks), 327 UPPER32(mfun->nblocks)); 328 break; 329 case BD_READ_BLOCKS: 330 ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call)); 331 cnt = IPC_GET_ARG3(call); 332 retval = usbmast_read(mfun, ba, cnt, comm_buf); 333 async_answer_0(callid, retval); 334 break; 335 case BD_WRITE_BLOCKS: 336 ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call)); 337 cnt = IPC_GET_ARG3(call); 338 retval = usbmast_write(mfun, ba, cnt, comm_buf); 339 async_answer_0(callid, retval); 340 break; 341 default: 342 async_answer_0(callid, EINVAL); 343 } 344 } 345 } 313 bd_conn(iid, icall, &mfun->bd); 314 } 315 316 /** Open device. */ 317 static int usbmast_bd_open(bd_srv_t *bd) 318 { 319 return EOK; 320 } 321 322 /** Close device. */ 323 static int usbmast_bd_close(bd_srv_t *bd) 324 { 325 return EOK; 326 } 327 328 /** Read blocks from the device. */ 329 static int usbmast_bd_read_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt, void *buf, 330 size_t size) 331 { 332 usbmast_fun_t *mfun = bd_srv_usbmast(bd); 333 334 if (size < cnt * mfun->block_size) 335 return EINVAL; 336 337 return usbmast_read(mfun, ba, cnt, buf); 338 } 339 340 /** Write blocks to the device. */ 341 static int usbmast_bd_write_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt, 342 const void *buf, size_t size) 343 { 344 usbmast_fun_t *mfun = bd_srv_usbmast(bd); 345 346 if (size < cnt * mfun->block_size) 347 return EINVAL; 348 349 return usbmast_write(mfun, ba, cnt, buf); 350 } 351 352 /** Get device block size. */ 353 static int usbmast_bd_get_block_size(bd_srv_t *bd, size_t *rsize) 354 { 355 usbmast_fun_t *mfun = bd_srv_usbmast(bd); 356 *rsize = mfun->block_size; 357 return EOK; 358 } 359 360 /** Get number of blocks on device. */ 361 static int usbmast_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb) 362 { 363 usbmast_fun_t *mfun = bd_srv_usbmast(bd); 364 *rnb = mfun->nblocks; 365 return EOK; 366 } 367 346 368 347 369 /** USB mass storage driver ops. */ -
uspace/drv/bus/usb/usbmast/usbmast.h
r2988aec7 r71b0d4d4 37 37 #define USBMAST_H_ 38 38 39 #include <bd_srv.h> 39 40 #include <sys/types.h> 40 41 #include <usb/usb.h> … … 68 69 /** Block size in bytes */ 69 70 size_t block_size; 71 /** Block device server structure */ 72 bd_srv_t bd; 70 73 } usbmast_fun_t; 71 74 -
uspace/lib/block/libblock.c
r2988aec7 r71b0d4d4 40 40 #include "../../srv/vfs/vfs.h" 41 41 #include <ipc/loc.h> 42 #include <ipc/bd.h>43 42 #include <ipc/services.h> 44 43 #include <errno.h> … … 47 46 #include <as.h> 48 47 #include <assert.h> 48 #include <bd.h> 49 49 #include <fibril_synch.h> 50 50 #include <adt/list.h> … … 80 80 service_id_t service_id; 81 81 async_sess_t *sess; 82 fibril_mutex_t comm_area_lock; 83 void *comm_area; 84 size_t comm_size; 82 bd_t *bd; 85 83 void *bb_buf; 86 84 aoff64_t bb_addr; … … 89 87 } devcon_t; 90 88 91 static int read_blocks(devcon_t *, aoff64_t, size_t); 92 static int write_blocks(devcon_t *, aoff64_t, size_t); 93 static int get_block_size(async_sess_t *, size_t *); 94 static int get_num_blocks(async_sess_t *, aoff64_t *); 89 static int read_blocks(devcon_t *, aoff64_t, size_t, void *, size_t); 90 static int write_blocks(devcon_t *, aoff64_t, size_t, void *, size_t); 95 91 static aoff64_t ba_ltop(devcon_t *, aoff64_t); 96 92 … … 112 108 113 109 static int devcon_add(service_id_t service_id, async_sess_t *sess, 114 size_t bsize, void *comm_area, size_t comm_size)110 size_t bsize, bd_t *bd) 115 111 { 116 112 devcon_t *devcon; 117 118 if (comm_size < bsize)119 return EINVAL;120 113 121 114 devcon = malloc(sizeof(devcon_t)); … … 126 119 devcon->service_id = service_id; 127 120 devcon->sess = sess; 128 fibril_mutex_initialize(&devcon->comm_area_lock); 129 devcon->comm_area = comm_area; 130 devcon->comm_size = comm_size; 121 devcon->bd = bd; 131 122 devcon->bb_buf = NULL; 132 123 devcon->bb_addr = 0; … … 158 149 size_t comm_size) 159 150 { 160 void *comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE, 161 MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); 162 if (!comm_area) 163 return ENOMEM; 164 151 bd_t *bd; 152 165 153 async_sess_t *sess = loc_service_connect(mgmt, service_id, 166 154 IPC_FLAG_BLOCKING); 167 155 if (!sess) { 168 munmap(comm_area, comm_size);169 156 return ENOENT; 170 157 } 171 158 172 async_exch_t *exch = async_exchange_begin(sess); 173 int rc = async_share_out_start(exch, comm_area, 174 AS_AREA_READ | AS_AREA_WRITE); 175 async_exchange_end(exch); 176 159 int rc = bd_open(sess, &bd); 177 160 if (rc != EOK) { 178 munmap(comm_area, comm_size);179 161 async_hangup(sess); 180 162 return rc; … … 182 164 183 165 size_t bsize; 184 rc = get_block_size(sess, &bsize); 185 166 rc = bd_get_block_size(bd, &bsize); 186 167 if (rc != EOK) { 187 munmap(comm_area, comm_size);168 bd_close(bd); 188 169 async_hangup(sess); 189 170 return rc; 190 171 } 191 172 192 rc = devcon_add(service_id, sess, bsize, comm_area, comm_size);173 rc = devcon_add(service_id, sess, bsize, bd); 193 174 if (rc != EOK) { 194 munmap(comm_area, comm_size);175 bd_close(bd); 195 176 async_hangup(sess); 196 177 return rc; … … 213 194 free(devcon->bb_buf); 214 195 215 munmap(devcon->comm_area, devcon->comm_size);196 bd_close(devcon->bd); 216 197 async_hangup(devcon->sess); 217 198 … … 233 214 return ENOMEM; 234 215 235 fibril_mutex_lock(&devcon->comm_area_lock); 236 rc = read_blocks(devcon, 0, 1); 216 rc = read_blocks(devcon, 0, 1, bb_buf, devcon->pblock_size); 237 217 if (rc != EOK) { 238 fibril_mutex_unlock(&devcon->comm_area_lock);239 218 free(bb_buf); 240 219 return rc; 241 220 } 242 memcpy(bb_buf, devcon->comm_area, devcon->pblock_size);243 fibril_mutex_unlock(&devcon->comm_area_lock);244 221 245 222 devcon->bb_buf = bb_buf; … … 338 315 list_remove(&b->free_link); 339 316 if (b->dirty) { 340 memcpy(devcon->comm_area, b->data, b->size);341 rc = write_blocks(devcon, b->pba, cache->blocks_cluster);317 rc = write_blocks(devcon, b->pba, cache->blocks_cluster, 318 b->data, b->size); 342 319 if (rc != EOK) 343 320 return rc; … … 481 458 list_append(&b->free_link, &cache->free_list); 482 459 fibril_mutex_unlock(&cache->lock); 483 fibril_mutex_lock(&devcon->comm_area_lock);484 memcpy(devcon->comm_area, b->data, b->size);485 460 rc = write_blocks(devcon, b->pba, 486 cache->blocks_cluster); 487 fibril_mutex_unlock(&devcon->comm_area_lock); 461 cache->blocks_cluster, b->data, b->size); 488 462 if (rc != EOK) { 489 463 /* … … 555 529 * the new contents from the device. 556 530 */ 557 fibril_mutex_lock(&devcon->comm_area_lock); 558 rc = read_blocks(devcon, b->pba, cache->blocks_cluster); 559 memcpy(b->data, devcon->comm_area, cache->lblock_size); 560 fibril_mutex_unlock(&devcon->comm_area_lock); 531 rc = read_blocks(devcon, b->pba, cache->blocks_cluster, 532 b->data, cache->lblock_size); 561 533 if (rc != EOK) 562 534 b->toxic = true; … … 616 588 if (block->dirty && (block->refcnt == 1) && 617 589 (blocks_cached > CACHE_HI_WATERMARK || mode != CACHE_MODE_WB)) { 618 fibril_mutex_lock(&devcon->comm_area_lock); 619 memcpy(devcon->comm_area, block->data, block->size); 620 rc = write_blocks(devcon, block->pba, cache->blocks_cluster); 621 fibril_mutex_unlock(&devcon->comm_area_lock); 590 rc = write_blocks(devcon, block->pba, cache->blocks_cluster, 591 block->data, block->size); 622 592 block->dirty = false; 623 593 } … … 688 658 * 689 659 * @param service_id Service ID of the block device. 660 * @param buf Buffer for holding one block 690 661 * @param bufpos Pointer to the first unread valid offset within the 691 662 * communication buffer. … … 699 670 * @return EOK on success or a negative return code on failure. 700 671 */ 701 int block_seqread(service_id_t service_id, size_t *bufpos, size_t *buflen,702 aoff64_t *pos, void *dst, size_t size)672 int block_seqread(service_id_t service_id, void *buf, size_t *bufpos, 673 size_t *buflen, aoff64_t *pos, void *dst, size_t size) 703 674 { 704 675 size_t offset = 0; … … 711 682 block_size = devcon->pblock_size; 712 683 713 fibril_mutex_lock(&devcon->comm_area_lock);714 684 while (left > 0) { 715 685 size_t rd; … … 725 695 * destination buffer. 726 696 */ 727 memcpy(dst + offset, devcon->comm_area+ *bufpos, rd);697 memcpy(dst + offset, buf + *bufpos, rd); 728 698 offset += rd; 729 699 *bufpos += rd; … … 736 706 int rc; 737 707 738 rc = read_blocks(devcon, *pos / block_size, 1); 708 rc = read_blocks(devcon, *pos / block_size, 1, buf, 709 devcon->pblock_size); 739 710 if (rc != EOK) { 740 fibril_mutex_unlock(&devcon->comm_area_lock);741 711 return rc; 742 712 } … … 746 716 } 747 717 } 748 fibril_mutex_unlock(&devcon->comm_area_lock);749 718 750 719 return EOK; … … 763 732 { 764 733 devcon_t *devcon; 765 int rc;766 734 767 735 devcon = devcon_search(service_id); 768 736 assert(devcon); 769 770 fibril_mutex_lock(&devcon->comm_area_lock); 771 772 rc = read_blocks(devcon, ba, cnt); 773 if (rc == EOK) 774 memcpy(buf, devcon->comm_area, devcon->pblock_size * cnt); 775 776 fibril_mutex_unlock(&devcon->comm_area_lock); 777 778 return rc; 737 738 return read_blocks(devcon, ba, cnt, buf, devcon->pblock_size * cnt); 779 739 } 780 740 … … 792 752 { 793 753 devcon_t *devcon; 794 int rc;795 754 796 755 devcon = devcon_search(service_id); 797 756 assert(devcon); 798 799 fibril_mutex_lock(&devcon->comm_area_lock); 800 801 memcpy(devcon->comm_area, data, devcon->pblock_size * cnt); 802 rc = write_blocks(devcon, ba, cnt); 803 804 fibril_mutex_unlock(&devcon->comm_area_lock); 805 806 return rc; 757 758 return write_blocks(devcon, ba, cnt, (void *)data, devcon->pblock_size * cnt); 807 759 } 808 760 … … 820 772 devcon = devcon_search(service_id); 821 773 assert(devcon); 822 823 return get_block_size(devcon->sess, bsize);774 775 return bd_get_block_size(devcon->bd, bsize); 824 776 } 825 777 … … 836 788 assert(devcon); 837 789 838 return get_num_blocks(devcon->sess, nblocks);790 return bd_get_num_blocks(devcon->bd, nblocks); 839 791 } 840 792 … … 887 839 memcpy(data, buffer + offset, bytes); 888 840 free(buffer); 889 841 890 842 return EOK; 891 843 } … … 903 855 { 904 856 devcon_t *devcon = devcon_search(service_id); 905 assert(devcon);906 907 857 toc_block_t *toc = NULL; 908 909 fibril_mutex_lock(&devcon->comm_area_lock); 910 911 async_exch_t *exch = async_exchange_begin(devcon->sess); 912 int rc = async_req_1_0(exch, BD_READ_TOC, session); 913 async_exchange_end(exch); 914 915 if (rc == EOK) { 916 toc = (toc_block_t *) malloc(sizeof(toc_block_t)); 917 if (toc != NULL) { 918 memset(toc, 0, sizeof(toc_block_t)); 919 memcpy(toc, devcon->comm_area, 920 min(devcon->pblock_size, sizeof(toc_block_t))); 921 } 922 } 923 924 925 fibril_mutex_unlock(&devcon->comm_area_lock); 858 int rc; 859 860 assert(devcon); 861 862 toc = (toc_block_t *) malloc(sizeof(toc_block_t)); 863 if (toc == NULL) 864 return NULL; 865 866 rc = bd_read_toc(devcon->bd, session, toc, sizeof(toc_block_t)); 867 if (rc != EOK) { 868 free(toc); 869 return NULL; 870 } 926 871 927 872 return toc; … … 937 882 * @return EOK on success or negative error code on failure. 938 883 */ 939 static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt) 940 { 941 assert(devcon); 942 943 async_exch_t *exch = async_exchange_begin(devcon->sess); 944 int rc = async_req_3_0(exch, BD_READ_BLOCKS, LOWER32(ba), 945 UPPER32(ba), cnt); 946 async_exchange_end(exch); 947 884 static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt, void *buf, 885 size_t size) 886 { 887 assert(devcon); 888 889 int rc = bd_read_blocks(devcon->bd, ba, cnt, buf, size); 948 890 if (rc != EOK) { 949 891 printf("Error %d reading %zu blocks starting at block %" PRIuOFF64 … … 967 909 * @return EOK on success or negative error code on failure. 968 910 */ 969 static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt) 970 { 971 assert(devcon); 972 973 async_exch_t *exch = async_exchange_begin(devcon->sess); 974 int rc = async_req_3_0(exch, BD_WRITE_BLOCKS, LOWER32(ba), 975 UPPER32(ba), cnt); 976 async_exchange_end(exch); 977 911 static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt, void *data, 912 size_t size) 913 { 914 assert(devcon); 915 916 int rc = bd_write_blocks(devcon->bd, ba, cnt, data, size); 978 917 if (rc != EOK) { 979 918 printf("Error %d writing %zu blocks starting at block %" PRIuOFF64 … … 987 926 } 988 927 989 /** Get block size used by the device. */990 static int get_block_size(async_sess_t *sess, size_t *bsize)991 {992 sysarg_t bs;993 994 async_exch_t *exch = async_exchange_begin(sess);995 int rc = async_req_0_1(exch, BD_GET_BLOCK_SIZE, &bs);996 async_exchange_end(exch);997 998 if (rc == EOK)999 *bsize = (size_t) bs;1000 1001 return rc;1002 }1003 1004 /** Get total number of blocks on block device. */1005 static int get_num_blocks(async_sess_t *sess, aoff64_t *nblocks)1006 {1007 sysarg_t nb_l;1008 sysarg_t nb_h;1009 1010 async_exch_t *exch = async_exchange_begin(sess);1011 int rc = async_req_0_2(exch, BD_GET_NUM_BLOCKS, &nb_l, &nb_h);1012 async_exchange_end(exch);1013 1014 if (rc == EOK)1015 *nblocks = (aoff64_t) MERGE_LOUP32(nb_l, nb_h);1016 1017 return rc;1018 }1019 1020 928 /** Convert logical block address to physical block address. */ 1021 929 static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba) -
uspace/lib/block/libblock.h
r2988aec7 r71b0d4d4 122 122 extern int block_put(block_t *); 123 123 124 extern int block_seqread(service_id_t, size_t *, size_t *, aoff64_t *, void*,125 size_t);124 extern int block_seqread(service_id_t, void *, size_t *, size_t *, aoff64_t *, 125 void *, size_t); 126 126 127 127 extern int block_get_bsize(service_id_t, size_t *); -
uspace/lib/c/Makefile
r2988aec7 r71b0d4d4 62 62 generic/ddi.c \ 63 63 generic/as.c \ 64 generic/bd.c \ 65 generic/bd_srv.c \ 64 66 generic/cap.c \ 65 67 generic/cfg.c \ -
uspace/lib/c/generic/async.c
r2988aec7 r71b0d4d4 114 114 #include <stdlib.h> 115 115 #include <macros.h> 116 #include "private/libc.h" 116 117 117 118 #define CLIENT_HASH_TABLE_BUCKETS 32 … … 2166 2167 int async_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags) 2167 2168 { 2168 return ipc_share_in_finalize(callid, src, flags); 2169 return ipc_answer_3(callid, EOK, (sysarg_t) src, (sysarg_t) flags, 2170 (sysarg_t) __entry); 2169 2171 } 2170 2172 … … 2233 2235 int async_share_out_finalize(ipc_callid_t callid, void **dst) 2234 2236 { 2235 return ipc_ share_out_finalize(callid,dst);2237 return ipc_answer_2(callid, EOK, (sysarg_t) __entry, (sysarg_t) dst); 2236 2238 } 2237 2239 … … 2317 2319 int async_data_read_finalize(ipc_callid_t callid, const void *src, size_t size) 2318 2320 { 2319 return ipc_ data_read_finalize(callid, src,size);2321 return ipc_answer_2(callid, EOK, (sysarg_t) src, (sysarg_t) size); 2320 2322 } 2321 2323 … … 2420 2422 int async_data_write_finalize(ipc_callid_t callid, void *dst, size_t size) 2421 2423 { 2422 return ipc_ data_write_finalize(callid, dst,size);2424 return ipc_answer_2(callid, EOK, (sysarg_t) dst, (sysarg_t) size); 2423 2425 } 2424 2426 -
uspace/lib/c/generic/ipc.c
r2988aec7 r71b0d4d4 48 48 #include <fibril.h> 49 49 #include <macros.h> 50 #include "private/libc.h"51 50 52 51 /** … … 83 82 84 83 static atomic_t ipc_futex = FUTEX_INITIALIZER; 85 86 /** Fast synchronous call.87 *88 * Only three payload arguments can be passed using this function. However,89 * this function is faster than the generic ipc_call_sync_slow() because90 * the payload is passed directly in registers.91 *92 * @param phoneid Phone handle for the call.93 * @param method Requested method.94 * @param arg1 Service-defined payload argument.95 * @param arg2 Service-defined payload argument.96 * @param arg3 Service-defined payload argument.97 * @param result1 If non-NULL, the return ARG1 will be stored there.98 * @param result2 If non-NULL, the return ARG2 will be stored there.99 * @param result3 If non-NULL, the return ARG3 will be stored there.100 * @param result4 If non-NULL, the return ARG4 will be stored there.101 * @param result5 If non-NULL, the return ARG5 will be stored there.102 *103 * @return Negative values representing IPC errors.104 * @return Otherwise the RETVAL of the answer.105 *106 */107 int ipc_call_sync_fast(int phoneid, sysarg_t method, sysarg_t arg1,108 sysarg_t arg2, sysarg_t arg3, sysarg_t *result1, sysarg_t *result2,109 sysarg_t *result3, sysarg_t *result4, sysarg_t *result5)110 {111 ipc_call_t resdata;112 int callres = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid, method, arg1,113 arg2, arg3, (sysarg_t) &resdata);114 if (callres)115 return callres;116 117 if (result1)118 *result1 = IPC_GET_ARG1(resdata);119 if (result2)120 *result2 = IPC_GET_ARG2(resdata);121 if (result3)122 *result3 = IPC_GET_ARG3(resdata);123 if (result4)124 *result4 = IPC_GET_ARG4(resdata);125 if (result5)126 *result5 = IPC_GET_ARG5(resdata);127 128 return IPC_GET_RETVAL(resdata);129 }130 131 /** Synchronous call transmitting 5 arguments of payload.132 *133 * @param phoneid Phone handle for the call.134 * @param imethod Requested interface and method.135 * @param arg1 Service-defined payload argument.136 * @param arg2 Service-defined payload argument.137 * @param arg3 Service-defined payload argument.138 * @param arg4 Service-defined payload argument.139 * @param arg5 Service-defined payload argument.140 * @param result1 If non-NULL, storage for the first return argument.141 * @param result2 If non-NULL, storage for the second return argument.142 * @param result3 If non-NULL, storage for the third return argument.143 * @param result4 If non-NULL, storage for the fourth return argument.144 * @param result5 If non-NULL, storage for the fifth return argument.145 *146 * @return Negative values representing IPC errors.147 * @return Otherwise the RETVAL of the answer.148 *149 */150 int ipc_call_sync_slow(int phoneid, sysarg_t imethod, sysarg_t arg1,151 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,152 sysarg_t *result1, sysarg_t *result2, sysarg_t *result3, sysarg_t *result4,153 sysarg_t *result5)154 {155 ipc_call_t data;156 157 IPC_SET_IMETHOD(data, imethod);158 IPC_SET_ARG1(data, arg1);159 IPC_SET_ARG2(data, arg2);160 IPC_SET_ARG3(data, arg3);161 IPC_SET_ARG4(data, arg4);162 IPC_SET_ARG5(data, arg5);163 164 int callres = __SYSCALL3(SYS_IPC_CALL_SYNC_SLOW, phoneid,165 (sysarg_t) &data, (sysarg_t) &data);166 if (callres)167 return callres;168 169 if (result1)170 *result1 = IPC_GET_ARG1(data);171 if (result2)172 *result2 = IPC_GET_ARG2(data);173 if (result3)174 *result3 = IPC_GET_ARG3(data);175 if (result4)176 *result4 = IPC_GET_ARG4(data);177 if (result5)178 *result5 = IPC_GET_ARG5(data);179 180 return IPC_GET_RETVAL(data);181 }182 84 183 85 /** Send asynchronous message via syscall. … … 611 513 } 612 514 613 /** Request callback connection.614 *615 * The @a task_id and @a phonehash identifiers returned616 * by the kernel can be used for connection tracking.617 *618 * @param phoneid Phone handle used for contacting the other side.619 * @param arg1 User defined argument.620 * @param arg2 User defined argument.621 * @param arg3 User defined argument.622 * @param task_id Identifier of the client task.623 * @param phonehash Opaque identifier of the phone that will624 * be used for incoming calls.625 *626 * @return Zero on success or a negative error code.627 *628 */629 int ipc_connect_to_me(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,630 task_id_t *task_id, sysarg_t *phonehash)631 {632 ipc_call_t data;633 int rc = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid,634 IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, (sysarg_t) &data);635 if (rc == EOK) {636 *task_id = data.in_task_id;637 *phonehash = IPC_GET_ARG5(data);638 }639 return rc;640 }641 642 /** Request cloned connection.643 *644 * @param phoneid Phone handle used for contacting the other side.645 *646 * @return Cloned phone handle on success or a negative error code.647 *648 */649 int ipc_clone_establish(int phoneid)650 {651 sysarg_t newphid;652 int res = ipc_call_sync_0_5(phoneid, IPC_M_CLONE_ESTABLISH, NULL,653 NULL, NULL, NULL, &newphid);654 if (res)655 return res;656 657 return newphid;658 }659 660 /** Request new connection.661 *662 * @param phoneid Phone handle used for contacting the other side.663 * @param arg1 User defined argument.664 * @param arg2 User defined argument.665 * @param arg3 User defined argument.666 *667 * @return New phone handle on success or a negative error code.668 *669 */670 int ipc_connect_me_to(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)671 {672 sysarg_t newphid;673 int res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,674 NULL, NULL, NULL, NULL, &newphid);675 if (res)676 return res;677 678 return newphid;679 }680 681 /** Request new connection (blocking)682 *683 * If the connection is not available at the moment, the684 * call should block. This has to be, however, implemented685 * on the server side.686 *687 * @param phoneid Phone handle used for contacting the other side.688 * @param arg1 User defined argument.689 * @param arg2 User defined argument.690 * @param arg3 User defined argument.691 *692 * @return New phone handle on success or a negative error code.693 *694 */695 int ipc_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2,696 sysarg_t arg3)697 {698 sysarg_t newphid;699 int res = ipc_call_sync_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,700 IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid);701 if (res)702 return res;703 704 return newphid;705 }706 707 515 /** Hang up a phone. 708 516 * … … 758 566 } 759 567 760 /** Wrapper for IPC_M_SHARE_IN calls.761 *762 * @param phoneid Phone that will be used to contact the receiving side.763 * @param size Size of the destination address space area.764 * @param arg User defined argument.765 * @param flags Storage for received flags. Can be NULL.766 * @param dst Destination address space area base. Cannot be NULL.767 *768 * @return Zero on success or a negative error code from errno.h.769 *770 */771 int ipc_share_in_start(int phoneid, size_t size, sysarg_t arg,772 unsigned int *flags, void **dst)773 {774 sysarg_t _flags = 0;775 sysarg_t _dst = (sysarg_t) -1;776 int res = ipc_call_sync_2_4(phoneid, IPC_M_SHARE_IN, (sysarg_t) size,777 arg, NULL, &_flags, NULL, &_dst);778 779 if (flags)780 *flags = (unsigned int) _flags;781 782 *dst = (void *) _dst;783 return res;784 }785 786 /** Wrapper for answering the IPC_M_SHARE_IN calls.787 *788 * This wrapper only makes it more comfortable to answer IPC_M_SHARE_IN789 * calls so that the user doesn't have to remember the meaning of each790 * IPC argument.791 *792 * @param callid Hash of the IPC_M_DATA_READ call to answer.793 * @param src Source address space base.794 * @param flags Flags to be used for sharing. Bits can be only cleared.795 *796 * @return Zero on success or a value from @ref errno.h on failure.797 *798 */799 int ipc_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags)800 {801 return ipc_answer_3(callid, EOK, (sysarg_t) src, (sysarg_t) flags,802 (sysarg_t) __entry);803 }804 805 /** Wrapper for IPC_M_SHARE_OUT calls.806 *807 * @param phoneid Phone that will be used to contact the receiving side.808 * @param src Source address space area base address.809 * @param flags Flags to be used for sharing. Bits can be only cleared.810 *811 * @return Zero on success or a negative error code from errno.h.812 *813 */814 int ipc_share_out_start(int phoneid, void *src, unsigned int flags)815 {816 return ipc_call_sync_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0,817 (sysarg_t) flags);818 }819 820 /** Wrapper for answering the IPC_M_SHARE_OUT calls.821 *822 * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT823 * calls so that the user doesn't have to remember the meaning of each824 * IPC argument.825 *826 * @param callid Hash of the IPC_M_DATA_WRITE call to answer.827 * @param dst Destination address space area base address.828 *829 * @return Zero on success or a value from @ref errno.h on failure.830 *831 */832 int ipc_share_out_finalize(ipc_callid_t callid, void **dst)833 {834 return ipc_answer_2(callid, EOK, (sysarg_t) __entry, (sysarg_t) dst);835 }836 837 /** Wrapper for IPC_M_DATA_READ calls.838 *839 * @param phoneid Phone that will be used to contact the receiving side.840 * @param dst Address of the beginning of the destination buffer.841 * @param size Size of the destination buffer.842 *843 * @return Zero on success or a negative error code from errno.h.844 *845 */846 int ipc_data_read_start(int phoneid, void *dst, size_t size)847 {848 return ipc_call_sync_2_0(phoneid, IPC_M_DATA_READ, (sysarg_t) dst,849 (sysarg_t) size);850 }851 852 /** Wrapper for answering the IPC_M_DATA_READ calls.853 *854 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ855 * calls so that the user doesn't have to remember the meaning of each856 * IPC argument.857 *858 * @param callid Hash of the IPC_M_DATA_READ call to answer.859 * @param src Source address for the IPC_M_DATA_READ call.860 * @param size Size for the IPC_M_DATA_READ call. Can be smaller than861 * the maximum size announced by the sender.862 *863 * @return Zero on success or a value from @ref errno.h on failure.864 *865 */866 int ipc_data_read_finalize(ipc_callid_t callid, const void *src, size_t size)867 {868 return ipc_answer_2(callid, EOK, (sysarg_t) src, (sysarg_t) size);869 }870 871 /** Wrapper for IPC_M_DATA_WRITE calls.872 *873 * @param phoneid Phone that will be used to contact the receiving side.874 * @param src Address of the beginning of the source buffer.875 * @param size Size of the source buffer.876 *877 * @return Zero on success or a negative error code from errno.h.878 *879 */880 int ipc_data_write_start(int phoneid, const void *src, size_t size)881 {882 return ipc_call_sync_2_0(phoneid, IPC_M_DATA_WRITE, (sysarg_t) src,883 (sysarg_t) size);884 }885 886 /** Wrapper for answering the IPC_M_DATA_WRITE calls.887 *888 * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE889 * calls so that the user doesn't have to remember the meaning of each890 * IPC argument.891 *892 * @param callid Hash of the IPC_M_DATA_WRITE call to answer.893 * @param dst Final destination address for the IPC_M_DATA_WRITE call.894 * @param size Final size for the IPC_M_DATA_WRITE call.895 *896 * @return Zero on success or a value from @ref errno.h on failure.897 *898 */899 int ipc_data_write_finalize(ipc_callid_t callid, void *dst, size_t size)900 {901 return ipc_answer_2(callid, EOK, (sysarg_t) dst, (sysarg_t) size);902 }903 904 568 /** Connect to a task specified by id. 905 569 * -
uspace/lib/c/generic/iplink_srv.c
r2988aec7 r71b0d4d4 139 139 if (!method) { 140 140 /* The other side has hung up */ 141 fibril_mutex_lock(&srv->lock); 142 srv->connected = false; 143 fibril_mutex_unlock(&srv->lock); 141 144 async_answer_0(callid, EOK); 142 145 break; -
uspace/lib/c/include/ipc/ipc.h
r2988aec7 r71b0d4d4 47 47 48 48 typedef void (*ipc_async_callback_t)(void *, int, ipc_call_t *); 49 50 /*51 * User-friendly wrappers for ipc_call_sync_fast() and ipc_call_sync_slow().52 * They are in the form ipc_call_sync_m_n(), where m denotes the number of53 * arguments of payload and n denotes number of return values. Whenever54 * possible, the fast version is used.55 */56 57 #define ipc_call_sync_0_0(phoneid, method) \58 ipc_call_sync_fast((phoneid), (method), 0, 0, 0, 0, 0, 0, 0, 0)59 #define ipc_call_sync_0_1(phoneid, method, res1) \60 ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), 0, 0, 0, 0)61 #define ipc_call_sync_0_2(phoneid, method, res1, res2) \62 ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), 0, 0, 0)63 #define ipc_call_sync_0_3(phoneid, method, res1, res2, res3) \64 ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \65 0, 0)66 #define ipc_call_sync_0_4(phoneid, method, res1, res2, res3, res4) \67 ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \68 (res4), 0)69 #define ipc_call_sync_0_5(phoneid, method, res1, res2, res3, res4, res5) \70 ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \71 (res4), (res5))72 73 #define ipc_call_sync_1_0(phoneid, method, arg1) \74 ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, 0, 0, 0, 0, 0)75 #define ipc_call_sync_1_1(phoneid, method, arg1, res1) \76 ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), 0, 0, 0, 0)77 #define ipc_call_sync_1_2(phoneid, method, arg1, res1, res2) \78 ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), 0, \79 0, 0)80 #define ipc_call_sync_1_3(phoneid, method, arg1, res1, res2, res3) \81 ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \82 (res3), 0, 0)83 #define ipc_call_sync_1_4(phoneid, method, arg1, res1, res2, res3, res4) \84 ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \85 (res3), (res4), 0)86 #define ipc_call_sync_1_5(phoneid, method, arg1, res1, res2, res3, res4, \87 res5) \88 ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \89 (res3), (res4), (res5))90 91 #define ipc_call_sync_2_0(phoneid, method, arg1, arg2) \92 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, 0, 0, 0, \93 0, 0)94 #define ipc_call_sync_2_1(phoneid, method, arg1, arg2, res1) \95 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), 0, 0, \96 0, 0)97 #define ipc_call_sync_2_2(phoneid, method, arg1, arg2, res1, res2) \98 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \99 (res2), 0, 0, 0)100 #define ipc_call_sync_2_3(phoneid, method, arg1, arg2, res1, res2, res3) \101 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \102 (res2), (res3), 0, 0)103 #define ipc_call_sync_2_4(phoneid, method, arg1, arg2, res1, res2, res3, \104 res4) \105 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \106 (res2), (res3), (res4), 0)107 #define ipc_call_sync_2_5(phoneid, method, arg1, arg2, res1, res2, res3, \108 res4, res5)\109 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \110 (res2), (res3), (res4), (res5))111 112 #define ipc_call_sync_3_0(phoneid, method, arg1, arg2, arg3) \113 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, 0, 0, \114 0, 0)115 #define ipc_call_sync_3_1(phoneid, method, arg1, arg2, arg3, res1) \116 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), (res1), \117 0, 0, 0, 0)118 #define ipc_call_sync_3_2(phoneid, method, arg1, arg2, arg3, res1, res2) \119 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), (res1), \120 (res2), 0, 0, 0)121 #define ipc_call_sync_3_3(phoneid, method, arg1, arg2, arg3, res1, res2, \122 res3) \123 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), \124 (res1), (res2), (res3), 0, 0)125 #define ipc_call_sync_3_4(phoneid, method, arg1, arg2, arg3, res1, res2, \126 res3, res4) \127 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), \128 (res1), (res2), (res3), (res4), 0)129 #define ipc_call_sync_3_5(phoneid, method, arg1, arg2, arg3, res1, res2, \130 res3, res4, res5) \131 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), \132 (res1), (res2), (res3), (res4), (res5))133 134 #define ipc_call_sync_4_0(phoneid, method, arg1, arg2, arg3, arg4) \135 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \136 0, 0, 0, 0, 0)137 #define ipc_call_sync_4_1(phoneid, method, arg1, arg2, arg3, arg4, res1) \138 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \139 (res1), 0, 0, 0, 0)140 #define ipc_call_sync_4_2(phoneid, method, arg1, arg2, arg3, arg4, res1, res2) \141 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \142 (res1), (res2), 0, 0, 0)143 #define ipc_call_sync_4_3(phoneid, method, arg1, arg2, arg3, arg4, res1, res2, \144 res3) \145 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \146 (arg4), 0, (res1), (res2), (res3), 0, 0)147 #define ipc_call_sync_4_4(phoneid, method, arg1, arg2, arg3, arg4, res1, res2, \148 res3, res4) \149 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \150 (arg4), 0, (res1), (res2), (res3), (res4), 0)151 #define ipc_call_sync_4_5(phoneid, method, arg1, arg2, arg3, arg4, res1, res2, \152 res3, res4, res5) \153 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \154 (arg4), 0, (res1), (res2), (res3), (res4), (res5))155 156 #define ipc_call_sync_5_0(phoneid, method, arg1, arg2, arg3, arg4, arg5) \157 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \158 (arg5), 0, 0, 0, 0, 0)159 #define ipc_call_sync_5_1(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1) \160 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \161 (arg5), (res1), 0, 0, 0, 0)162 #define ipc_call_sync_5_2(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1, \163 res2) \164 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \165 (arg4), (arg5), (res1), (res2), 0, 0, 0)166 #define ipc_call_sync_5_3(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1, \167 res2, res3) \168 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \169 (arg4), (arg5), (res1), (res2), (res3), 0, 0)170 #define ipc_call_sync_5_4(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1, \171 res2, res3, res4) \172 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \173 (arg4), (arg5), (res1), (res2), (res3), (res4), 0)174 #define ipc_call_sync_5_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1, \175 res2, res3, res4, res5) \176 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \177 (arg4), (arg5), (res1), (res2), (res3), (res4), (res5))178 179 extern int ipc_call_sync_fast(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,180 sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);181 182 extern int ipc_call_sync_slow(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,183 sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *,184 sysarg_t *);185 49 186 50 extern ipc_callid_t ipc_wait_cycle(ipc_call_t *, sysarg_t, unsigned int); … … 254 118 sysarg_t, sysarg_t, void *, ipc_async_callback_t, bool); 255 119 256 extern int ipc_clone_establish(int);257 extern int ipc_connect_to_me(int, sysarg_t, sysarg_t, sysarg_t, task_id_t *,258 sysarg_t *);259 extern int ipc_connect_me_to(int, sysarg_t, sysarg_t, sysarg_t);260 extern int ipc_connect_me_to_blocking(int, sysarg_t, sysarg_t, sysarg_t);261 262 120 extern int ipc_hangup(int); 263 121 … … 267 125 sysarg_t, sysarg_t, sysarg_t, unsigned int); 268 126 269 /*270 * User-friendly wrappers for ipc_share_in_start().271 */272 273 #define ipc_share_in_start_0_0(phoneid, size, dst) \274 ipc_share_in_start((phoneid), (size), 0, NULL, (dst))275 #define ipc_share_in_start_0_1(phoneid, size, flags, dst) \276 ipc_share_in_start((phoneid), (size), 0, (flags), (dst))277 #define ipc_share_in_start_1_0(phoneid, size, arg, dst) \278 ipc_share_in_start((phoneid), (size), (arg), NULL, (dst))279 #define ipc_share_in_start_1_1(phoneid, size, arg, flags, dst) \280 ipc_share_in_start((phoneid), (size), (arg), (flags), (dst))281 282 extern int ipc_share_in_start(int, size_t, sysarg_t, unsigned int *, void **);283 extern int ipc_share_in_finalize(ipc_callid_t, void *, unsigned int);284 extern int ipc_share_out_start(int, void *, unsigned int);285 extern int ipc_share_out_finalize(ipc_callid_t, void **);286 extern int ipc_data_read_start(int, void *, size_t);287 extern int ipc_data_read_finalize(ipc_callid_t, const void *, size_t);288 extern int ipc_data_write_start(int, const void *, size_t);289 extern int ipc_data_write_finalize(ipc_callid_t, void *, size_t);290 291 127 extern int ipc_connect_kbox(task_id_t); 292 128 -
uspace/srv/bd/ata_bd/ata_bd.c
r2988aec7 r71b0d4d4 51 51 #include <libarch/ddi.h> 52 52 #include <ddi.h> 53 #include <ipc/bd.h>54 53 #include <async.h> 55 54 #include <as.h> 55 #include <bd_srv.h> 56 56 #include <fibril_synch.h> 57 57 #include <stdint.h> … … 98 98 99 99 /** Per-disk state. */ 100 static disk_t disk[MAX_DISKS];100 static disk_t ata_disk[MAX_DISKS]; 101 101 102 102 static void print_syntax(void); 103 103 static int ata_bd_init(void); 104 104 static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *); 105 static int ata_bd_read_blocks(int disk_id, uint64_t ba, size_t cnt, 106 void *buf); 107 static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt, 108 const void *buf); 105 106 static int ata_bd_open(bd_srv_t *); 107 static int ata_bd_close(bd_srv_t *); 108 static int ata_bd_read_blocks(bd_srv_t *, uint64_t ba, size_t cnt, void *buf, 109 size_t); 110 static int ata_bd_read_toc(bd_srv_t *, uint8_t session, void *buf, size_t); 111 static int ata_bd_write_blocks(bd_srv_t *, uint64_t ba, size_t cnt, 112 const void *buf, size_t); 113 static int ata_bd_get_block_size(bd_srv_t *, size_t *); 114 static int ata_bd_get_num_blocks(bd_srv_t *, aoff64_t *); 115 109 116 static int ata_rcmd_read(int disk_id, uint64_t ba, size_t cnt, 110 117 void *buf); … … 127 134 unsigned timeout); 128 135 136 static bd_ops_t ata_bd_ops = { 137 .open = ata_bd_open, 138 .close = ata_bd_close, 139 .read_blocks = ata_bd_read_blocks, 140 .read_toc = ata_bd_read_toc, 141 .write_blocks = ata_bd_write_blocks, 142 .get_block_size = ata_bd_get_block_size, 143 .get_num_blocks = ata_bd_get_num_blocks 144 }; 145 146 static disk_t *bd_srv_disk(bd_srv_t *bd) 147 { 148 return (disk_t *)bd->arg; 149 } 150 129 151 int main(int argc, char **argv) 130 152 { … … 161 183 fflush(stdout); 162 184 163 rc = disk_init(& disk[i], i);185 rc = disk_init(&ata_disk[i], i); 164 186 165 187 if (rc == EOK) { 166 disk_print_summary(& disk[i]);188 disk_print_summary(&ata_disk[i]); 167 189 } else { 168 190 printf("Not found.\n"); … … 174 196 for (i = 0; i < MAX_DISKS; i++) { 175 197 /* Skip unattached drives. */ 176 if ( disk[i].present == false)198 if (ata_disk[i].present == false) 177 199 continue; 178 200 179 201 snprintf(name, 16, "%s/ata%udisk%d", NAMESPACE, ctl_num, i); 180 rc = loc_service_register(name, & disk[i].service_id);202 rc = loc_service_register(name, &ata_disk[i].service_id); 181 203 if (rc != EOK) { 182 204 printf(NAME ": Unable to register device %s.\n", name); … … 217 239 case am_chs: 218 240 printf("CHS %u cylinders, %u heads, %u sectors", 219 d isk->geom.cylinders, disk->geom.heads,220 d isk->geom.sectors);241 d->geom.cylinders, d->geom.heads, 242 d->geom.sectors); 221 243 break; 222 244 case am_lba28: … … 273 295 static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 274 296 { 275 void *fs_va = NULL;276 ipc_callid_t callid;277 ipc_call_t call;278 sysarg_t method;279 297 service_id_t dsid; 280 size_t comm_size; /**< Size of the communication area. */281 unsigned int flags;282 int retval;283 uint64_t ba;284 size_t cnt;285 298 int disk_id, i; 286 299 … … 291 304 disk_id = -1; 292 305 for (i = 0; i < MAX_DISKS; i++) 293 if ( disk[i].service_id == dsid)306 if (ata_disk[i].service_id == dsid) 294 307 disk_id = i; 295 308 296 if (disk_id < 0 || disk[disk_id].present == false) {309 if (disk_id < 0 || ata_disk[disk_id].present == false) { 297 310 async_answer_0(iid, EINVAL); 298 311 return; 299 312 } 300 313 301 /* Answer the IPC_M_CONNECT_ME_TO call. */ 302 async_answer_0(iid, EOK); 303 304 if (!async_share_out_receive(&callid, &comm_size, &flags)) { 305 async_answer_0(callid, EHANGUP); 306 return; 307 } 308 309 (void) async_share_out_finalize(callid, &fs_va); 310 if (fs_va == AS_MAP_FAILED) { 311 async_answer_0(callid, EHANGUP); 312 return; 313 } 314 315 while (true) { 316 callid = async_get_call(&call); 317 method = IPC_GET_IMETHOD(call); 318 319 if (!method) { 320 /* The other side has hung up. */ 321 async_answer_0(callid, EOK); 322 return; 323 } 324 325 switch (method) { 326 case BD_READ_BLOCKS: 327 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 328 IPC_GET_ARG2(call)); 329 cnt = IPC_GET_ARG3(call); 330 if (cnt * disk[disk_id].block_size > comm_size) { 331 retval = ELIMIT; 332 break; 333 } 334 retval = ata_bd_read_blocks(disk_id, ba, cnt, fs_va); 335 break; 336 case BD_WRITE_BLOCKS: 337 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 338 IPC_GET_ARG2(call)); 339 cnt = IPC_GET_ARG3(call); 340 if (cnt * disk[disk_id].block_size > comm_size) { 341 retval = ELIMIT; 342 break; 343 } 344 retval = ata_bd_write_blocks(disk_id, ba, cnt, fs_va); 345 break; 346 case BD_GET_BLOCK_SIZE: 347 async_answer_1(callid, EOK, disk[disk_id].block_size); 348 continue; 349 case BD_GET_NUM_BLOCKS: 350 async_answer_2(callid, EOK, LOWER32(disk[disk_id].blocks), 351 UPPER32(disk[disk_id].blocks)); 352 continue; 353 case BD_READ_TOC: 354 cnt = IPC_GET_ARG1(call); 355 if (disk[disk_id].dev_type == ata_pkt_dev) 356 retval = ata_pcmd_read_toc(disk_id, cnt, fs_va, 357 disk[disk_id].block_size); 358 else 359 retval = EINVAL; 360 break; 361 default: 362 retval = EINVAL; 363 break; 364 } 365 async_answer_0(callid, retval); 366 } 314 bd_conn(iid, icall, &ata_disk[disk_id].bd); 367 315 } 368 316 … … 384 332 unsigned i; 385 333 334 d->disk_id = disk_id; 386 335 d->present = false; 387 336 fibril_mutex_initialize(&d->lock); 337 338 bd_srv_init(&d->bd); 339 d->bd.ops = &ata_bd_ops; 340 d->bd.arg = d; 388 341 389 342 /* Try identify command. */ … … 514 467 } 515 468 469 static int ata_bd_open(bd_srv_t *bd) 470 { 471 return EOK; 472 } 473 474 static int ata_bd_close(bd_srv_t *bd) 475 { 476 return EOK; 477 } 478 516 479 /** Read multiple blocks from the device. */ 517 static int ata_bd_read_blocks(int disk_id, uint64_t ba, size_t cnt, 518 void *buf) { 519 480 static int ata_bd_read_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt, 481 void *buf, size_t size) 482 { 483 disk_t *disk = bd_srv_disk(bd); 520 484 int rc; 521 485 486 if (size < cnt * disk->block_size) 487 return EINVAL; 488 522 489 while (cnt > 0) { 523 if (disk [disk_id].dev_type == ata_reg_dev)524 rc = ata_rcmd_read(disk _id, ba, 1, buf);490 if (disk->dev_type == ata_reg_dev) 491 rc = ata_rcmd_read(disk->disk_id, ba, 1, buf); 525 492 else 526 rc = ata_pcmd_read_12(disk _id, ba, 1, buf,527 disk [disk_id].block_size);493 rc = ata_pcmd_read_12(disk->disk_id, ba, 1, buf, 494 disk->block_size); 528 495 529 496 if (rc != EOK) … … 532 499 ++ba; 533 500 --cnt; 534 buf += disk[disk_id].block_size; 535 } 536 537 return EOK; 501 buf += disk->block_size; 502 } 503 504 return EOK; 505 } 506 507 /** Read TOC from device. */ 508 static int ata_bd_read_toc(bd_srv_t *bd, uint8_t session, void *buf, size_t size) 509 { 510 disk_t *disk = bd_srv_disk(bd); 511 512 return ata_pcmd_read_toc(disk->disk_id, session, buf, size); 538 513 } 539 514 540 515 /** Write multiple blocks to the device. */ 541 static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt, 542 const void *buf) { 543 516 static int ata_bd_write_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt, 517 const void *buf, size_t size) 518 { 519 disk_t *disk = bd_srv_disk(bd); 544 520 int rc; 545 521 546 if (disk [disk_id].dev_type != ata_reg_dev)522 if (disk->dev_type != ata_reg_dev) 547 523 return ENOTSUP; 548 524 525 if (size < cnt * disk->block_size) 526 return EINVAL; 527 549 528 while (cnt > 0) { 550 rc = ata_rcmd_write(disk _id, ba, 1, buf);529 rc = ata_rcmd_write(disk->disk_id, ba, 1, buf); 551 530 if (rc != EOK) 552 531 return rc; … … 554 533 ++ba; 555 534 --cnt; 556 buf += disk[disk_id].block_size; 557 } 558 535 buf += disk->block_size; 536 } 537 538 return EOK; 539 } 540 541 /** Get device block size. */ 542 static int ata_bd_get_block_size(bd_srv_t *bd, size_t *rbsize) 543 { 544 disk_t *disk = bd_srv_disk(bd); 545 546 *rbsize = disk->block_size; 547 return EOK; 548 } 549 550 /** Get device number of blocks. */ 551 static int ata_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb) 552 { 553 disk_t *disk = bd_srv_disk(bd); 554 555 *rnb = disk->blocks; 559 556 return EOK; 560 557 } … … 685 682 uint16_t val; 686 683 687 d = & disk[dev_idx];684 d = &ata_disk[dev_idx]; 688 685 fibril_mutex_lock(&d->lock); 689 686 … … 874 871 block_coord_t bc; 875 872 876 d = & disk[disk_id];873 d = &ata_disk[disk_id]; 877 874 878 875 /* Silence warning. */ … … 919 916 /* Read data from the device buffer. */ 920 917 921 for (i = 0; i < disk[disk_id].block_size / 2; i++) {918 for (i = 0; i < ata_disk[disk_id].block_size / 2; i++) { 922 919 data = pio_read_16(&cmd->data_port); 923 920 ((uint16_t *) buf)[i] = data; … … 950 947 block_coord_t bc; 951 948 952 d = & disk[disk_id];949 d = &ata_disk[disk_id]; 953 950 954 951 /* Silence warning. */ … … 995 992 /* Write data to the device buffer. */ 996 993 997 for (i = 0; i < d isk[disk_id].block_size / 2; i++) {994 for (i = 0; i < d->block_size / 2; i++) { 998 995 pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]); 999 996 } -
uspace/srv/bd/ata_bd/ata_bd.h
r2988aec7 r71b0d4d4 36 36 #define __ATA_BD_H__ 37 37 38 #include <bd_srv.h> 38 39 #include <sys/types.h> 39 40 #include <fibril_synch.h> … … 117 118 fibril_mutex_t lock; 118 119 service_id_t service_id; 120 int disk_id; 121 bd_srv_t bd; 119 122 } disk_t; 120 123 -
uspace/srv/bd/file_bd/file_bd.c
r2988aec7 r71b0d4d4 41 41 #include <stdio.h> 42 42 #include <unistd.h> 43 #include <ipc/bd.h>44 43 #include <async.h> 45 44 #include <as.h> 45 #include <bd_srv.h> 46 46 #include <fibril_synch.h> 47 47 #include <loc.h> … … 62 62 63 63 static service_id_t service_id; 64 static bd_srv_t bd_srv; 64 65 static fibril_mutex_t dev_lock; 65 66 … … 67 68 static int file_bd_init(const char *fname); 68 69 static void file_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *); 69 static int file_bd_read_blocks(uint64_t ba, size_t cnt, void *buf); 70 static int file_bd_write_blocks(uint64_t ba, size_t cnt, const void *buf); 70 71 static int file_bd_open(bd_srv_t *); 72 static int file_bd_close(bd_srv_t *); 73 static int file_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t); 74 static int file_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t); 75 static int file_bd_get_block_size(bd_srv_t *, size_t *); 76 static int file_bd_get_num_blocks(bd_srv_t *, aoff64_t *); 77 78 static bd_ops_t file_bd_ops = { 79 .open = file_bd_open, 80 .close = file_bd_close, 81 .read_blocks = file_bd_read_blocks, 82 .write_blocks = file_bd_write_blocks, 83 .get_block_size = file_bd_get_block_size, 84 .get_num_blocks = file_bd_get_num_blocks 85 }; 71 86 72 87 int main(int argc, char **argv) … … 139 154 static int file_bd_init(const char *fname) 140 155 { 156 bd_srv_init(&bd_srv); 157 bd_srv.ops = &file_bd_ops; 158 141 159 async_set_client_connection(file_bd_connection); 142 160 int rc = loc_server_register(NAME); … … 170 188 static void file_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 171 189 { 172 void *fs_va = NULL; 173 ipc_callid_t callid; 174 ipc_call_t call; 175 sysarg_t method; 176 size_t comm_size; 177 unsigned int flags; 178 int retval; 179 uint64_t ba; 180 size_t cnt; 181 182 /* Answer the IPC_M_CONNECT_ME_TO call. */ 183 async_answer_0(iid, EOK); 184 185 if (!async_share_out_receive(&callid, &comm_size, &flags)) { 186 async_answer_0(callid, EHANGUP); 187 return; 188 } 189 190 (void) async_share_out_finalize(callid, &fs_va); 191 if (fs_va == AS_MAP_FAILED) { 192 async_answer_0(callid, EHANGUP); 193 return; 194 } 195 196 while (true) { 197 callid = async_get_call(&call); 198 method = IPC_GET_IMETHOD(call); 199 200 if (!method) { 201 /* The other side has hung up. */ 202 async_answer_0(callid, EOK); 203 return; 204 } 205 206 switch (method) { 207 case BD_READ_BLOCKS: 208 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 209 IPC_GET_ARG2(call)); 210 cnt = IPC_GET_ARG3(call); 211 if (cnt * block_size > comm_size) { 212 retval = ELIMIT; 213 break; 214 } 215 retval = file_bd_read_blocks(ba, cnt, fs_va); 216 break; 217 case BD_WRITE_BLOCKS: 218 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 219 IPC_GET_ARG2(call)); 220 cnt = IPC_GET_ARG3(call); 221 if (cnt * block_size > comm_size) { 222 retval = ELIMIT; 223 break; 224 } 225 retval = file_bd_write_blocks(ba, cnt, fs_va); 226 break; 227 case BD_GET_BLOCK_SIZE: 228 async_answer_1(callid, EOK, block_size); 229 continue; 230 case BD_GET_NUM_BLOCKS: 231 async_answer_2(callid, EOK, LOWER32(num_blocks), 232 UPPER32(num_blocks)); 233 continue; 234 default: 235 retval = EINVAL; 236 break; 237 } 238 async_answer_0(callid, retval); 239 } 190 bd_conn(iid, icall, &bd_srv); 191 } 192 193 /** Open device. */ 194 static int file_bd_open(bd_srv_t *bd) 195 { 196 return EOK; 197 } 198 199 /** Close device. */ 200 static int file_bd_close(bd_srv_t *bd) 201 { 202 return EOK; 240 203 } 241 204 242 205 /** Read blocks from the device. */ 243 static int file_bd_read_blocks(uint64_t ba, size_t cnt, void *buf) 206 static int file_bd_read_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt, void *buf, 207 size_t size) 244 208 { 245 209 size_t n_rd; 246 210 int rc; 211 212 if (size < cnt * block_size) 213 return EINVAL; 247 214 248 215 /* Check whether access is within device address bounds. */ … … 279 246 280 247 /** Write blocks to the device. */ 281 static int file_bd_write_blocks(uint64_t ba, size_t cnt, const void *buf) 248 static int file_bd_write_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt, 249 const void *buf, size_t size) 282 250 { 283 251 size_t n_wr; 284 252 int rc; 253 254 if (size < cnt * block_size) 255 return EINVAL; 285 256 286 257 /* Check whether access is within device address bounds. */ … … 318 289 } 319 290 291 /** Get device block size. */ 292 static int file_bd_get_block_size(bd_srv_t *bd, size_t *rsize) 293 { 294 *rsize = block_size; 295 return EOK; 296 } 297 298 /** Get number of blocks on device. */ 299 static int file_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb) 300 { 301 *rnb = num_blocks; 302 return EOK; 303 } 304 320 305 /** 321 306 * @} -
uspace/srv/bd/gxe_bd/gxe_bd.c
r2988aec7 r71b0d4d4 39 39 #include <libarch/ddi.h> 40 40 #include <ddi.h> 41 #include <ipc/bd.h>42 41 #include <async.h> 43 42 #include <as.h> 43 #include <bd_srv.h> 44 44 #include <fibril_synch.h> 45 45 #include <loc.h> … … 65 65 }; 66 66 67 /** GXE disk hardware registers */ 67 68 typedef struct { 68 69 uint32_t offset_lo; … … 83 84 84 85 uint8_t buffer[512]; 86 } gxe_bd_hw_t; 87 88 /** GXE block device soft state */ 89 typedef struct { 90 /** Block device server structure */ 91 bd_srv_t bd; 92 int disk_id; 85 93 } gxe_bd_t; 86 94 87 88 95 static const size_t block_size = 512; 89 static size_t comm_size;90 96 91 97 static uintptr_t dev_physical = 0x13000000; 92 static gxe_bd_ t *dev;98 static gxe_bd_hw_t *dev; 93 99 94 100 static service_id_t service_id[MAX_DISKS]; 95 101 96 102 static fibril_mutex_t dev_lock[MAX_DISKS]; 103 104 static gxe_bd_t gxe_bd[MAX_DISKS]; 97 105 98 106 static int gxe_bd_init(void); 99 107 static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *); 100 static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt,101 void *buf);102 static int gxe_bd_write_blocks(int disk_id, uint64_t ba, unsigned cnt,103 const void *buf);104 108 static int gxe_bd_read_block(int disk_id, uint64_t ba, void *buf); 105 109 static int gxe_bd_write_block(int disk_id, uint64_t ba, const void *buf); 110 111 static int gxe_bd_open(bd_srv_t *); 112 static int gxe_bd_close(bd_srv_t *); 113 static int gxe_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t); 114 static int gxe_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t); 115 static int gxe_bd_get_block_size(bd_srv_t *, size_t *); 116 static int gxe_bd_get_num_blocks(bd_srv_t *, aoff64_t *); 117 118 static bd_ops_t gxe_bd_ops = { 119 .open = gxe_bd_open, 120 .close = gxe_bd_close, 121 .read_blocks = gxe_bd_read_blocks, 122 .write_blocks = gxe_bd_write_blocks, 123 .get_block_size = gxe_bd_get_block_size, 124 .get_num_blocks = gxe_bd_get_num_blocks 125 }; 126 127 static gxe_bd_t *bd_srv_gxe(bd_srv_t *bd) 128 { 129 return (gxe_bd_t *)bd->arg; 130 } 106 131 107 132 int main(int argc, char **argv) … … 130 155 131 156 void *vaddr; 132 rc = pio_enable((void *) dev_physical, sizeof(gxe_bd_ t), &vaddr);157 rc = pio_enable((void *) dev_physical, sizeof(gxe_bd_hw_t), &vaddr); 133 158 if (rc != EOK) { 134 159 printf("%s: Could not initialize device I/O space.\n", NAME); … … 140 165 for (unsigned int i = 0; i < MAX_DISKS; i++) { 141 166 char name[16]; 167 168 bd_srv_init(&gxe_bd[i].bd); 169 gxe_bd[i].bd.ops = &gxe_bd_ops; 170 gxe_bd[i].bd.arg = (void *)&gxe_bd[i]; 142 171 143 172 snprintf(name, 16, "%s/disk%u", NAMESPACE, i); … … 157 186 static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 158 187 { 159 void *fs_va = NULL;160 ipc_callid_t callid;161 ipc_call_t call;162 sysarg_t method;163 188 service_id_t dsid; 164 unsigned int flags;165 int retval;166 uint64_t ba;167 unsigned cnt;168 189 int disk_id, i; 169 190 … … 182 203 } 183 204 184 /* Answer the IPC_M_CONNECT_ME_TO call. */ 185 async_answer_0(iid, EOK); 186 187 if (!async_share_out_receive(&callid, &comm_size, &flags)) { 188 async_answer_0(callid, EHANGUP); 189 return; 190 } 191 192 if (comm_size < block_size) { 193 async_answer_0(callid, EHANGUP); 194 return; 195 } 196 197 (void) async_share_out_finalize(callid, &fs_va); 198 if (fs_va == AS_MAP_FAILED) { 199 async_answer_0(callid, EHANGUP); 200 return; 201 } 202 203 while (true) { 204 callid = async_get_call(&call); 205 method = IPC_GET_IMETHOD(call); 206 207 if (!method) { 208 /* The other side has hung up. */ 209 async_answer_0(callid, EOK); 210 return; 211 } 212 213 switch (method) { 214 case BD_READ_BLOCKS: 215 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 216 IPC_GET_ARG2(call)); 217 cnt = IPC_GET_ARG3(call); 218 if (cnt * block_size > comm_size) { 219 retval = ELIMIT; 220 break; 221 } 222 retval = gxe_bd_read_blocks(disk_id, ba, cnt, fs_va); 223 break; 224 case BD_WRITE_BLOCKS: 225 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 226 IPC_GET_ARG2(call)); 227 cnt = IPC_GET_ARG3(call); 228 if (cnt * block_size > comm_size) { 229 retval = ELIMIT; 230 break; 231 } 232 retval = gxe_bd_write_blocks(disk_id, ba, cnt, fs_va); 233 break; 234 case BD_GET_BLOCK_SIZE: 235 async_answer_1(callid, EOK, block_size); 236 continue; 237 case BD_GET_NUM_BLOCKS: 238 retval = ENOTSUP; 239 break; 240 default: 241 retval = EINVAL; 242 break; 243 } 244 async_answer_0(callid, retval); 245 } 205 bd_conn(iid, icall, &gxe_bd[disk_id].bd); 206 } 207 208 /** Open device. */ 209 static int gxe_bd_open(bd_srv_t *bd) 210 { 211 return EOK; 212 } 213 214 /** Close device. */ 215 static int gxe_bd_close(bd_srv_t *bd) 216 { 217 return EOK; 246 218 } 247 219 248 220 /** Read multiple blocks from the device. */ 249 static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt, 250 void *buf) { 251 221 static int gxe_bd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, 222 void *buf, size_t size) 223 { 224 int disk_id = bd_srv_gxe(bd)->disk_id; 252 225 int rc; 226 227 if (size < cnt * block_size) 228 return EINVAL; 253 229 254 230 while (cnt > 0) { … … 266 242 267 243 /** Write multiple blocks to the device. */ 268 static int gxe_bd_write_blocks(int disk_id, uint64_t ba, unsigned cnt, 269 const void *buf) { 270 244 static int gxe_bd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, 245 const void *buf, size_t size) 246 { 247 int disk_id = bd_srv_gxe(bd)->disk_id; 271 248 int rc; 249 250 if (size < cnt * block_size) 251 return EINVAL; 272 252 273 253 while (cnt > 0) { … … 282 262 283 263 return EOK; 264 } 265 266 /** Get device block size. */ 267 static int gxe_bd_get_block_size(bd_srv_t *bd, size_t *rsize) 268 { 269 *rsize = block_size; 270 return EOK; 271 } 272 273 /** Get number of blocks on device. */ 274 static int gxe_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb) 275 { 276 return ENOTSUP; 284 277 } 285 278 -
uspace/srv/bd/part/guid_part/guid_part.c
r2988aec7 r71b0d4d4 47 47 #include <stdlib.h> 48 48 #include <unistd.h> 49 #include <ipc/bd.h>50 49 #include <async.h> 51 50 #include <as.h> 51 #include <bd_srv.h> 52 52 #include <fibril_synch.h> 53 53 #include <loc.h> … … 83 83 /** Service representing the partition (outbound device) */ 84 84 service_id_t dsid; 85 /** Block device server structure */ 86 bd_srv_t bd; 85 87 /** Points to next partition structure. */ 86 88 struct part *next; … … 100 102 static void gpt_pte_to_part(const gpt_entry_t *pte, part_t *part); 101 103 static void gpt_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg); 102 static int gpt_bd_read(part_t *p, aoff64_t ba, size_t cnt, void *buf);103 static int gpt_bd_write(part_t *p, aoff64_t ba, size_t cnt, const void *buf);104 104 static int gpt_bsa_translate(part_t *p, aoff64_t ba, size_t cnt, aoff64_t *gba); 105 106 static int gpt_bd_open(bd_srv_t *); 107 static int gpt_bd_close(bd_srv_t *); 108 static int gpt_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t); 109 static int gpt_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t); 110 static int gpt_bd_get_block_size(bd_srv_t *, size_t *); 111 static int gpt_bd_get_num_blocks(bd_srv_t *, aoff64_t *); 112 113 static bd_ops_t gpt_bd_ops = { 114 .open = gpt_bd_open, 115 .close = gpt_bd_close, 116 .read_blocks = gpt_bd_read_blocks, 117 .write_blocks = gpt_bd_write_blocks, 118 .get_block_size = gpt_bd_get_block_size, 119 .get_num_blocks = gpt_bd_get_num_blocks 120 }; 121 122 static part_t *bd_srv_part(bd_srv_t *bd) 123 { 124 return (part_t *)bd->arg; 125 } 105 126 106 127 int main(int argc, char **argv) … … 304 325 } 305 326 327 bd_srv_init(&part->bd); 328 part->bd.ops = &gpt_bd_ops; 329 part->bd.arg = part; 330 306 331 part->dsid = 0; 307 332 part->next = NULL; … … 310 335 static void gpt_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 311 336 { 312 size_t comm_size;313 void *fs_va = NULL;314 ipc_callid_t callid;315 ipc_call_t call;316 sysarg_t method;317 337 service_id_t dh; 318 unsigned int flags;319 int retval;320 aoff64_t ba;321 size_t cnt;322 338 part_t *part; 323 339 … … 341 357 assert(part->present == true); 342 358 343 /* Answer the IPC_M_CONNECT_ME_TO call. */ 344 async_answer_0(iid, EOK); 345 346 if (!async_share_out_receive(&callid, &comm_size, &flags)) { 347 async_answer_0(callid, EHANGUP); 348 return; 349 } 350 351 (void) async_share_out_finalize(callid, &fs_va); 352 if (fs_va == AS_MAP_FAILED) { 353 async_answer_0(callid, EHANGUP); 354 return; 355 } 356 357 while (true) { 358 callid = async_get_call(&call); 359 method = IPC_GET_IMETHOD(call); 360 361 if (!method) { 362 /* The other side has hung up. */ 363 async_answer_0(callid, EOK); 364 return; 365 } 366 367 switch (method) { 368 case BD_READ_BLOCKS: 369 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 370 IPC_GET_ARG2(call)); 371 cnt = IPC_GET_ARG3(call); 372 if (cnt * block_size > comm_size) { 373 retval = ELIMIT; 374 break; 375 } 376 retval = gpt_bd_read(part, ba, cnt, fs_va); 377 break; 378 case BD_WRITE_BLOCKS: 379 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 380 IPC_GET_ARG2(call)); 381 cnt = IPC_GET_ARG3(call); 382 if (cnt * block_size > comm_size) { 383 retval = ELIMIT; 384 break; 385 } 386 retval = gpt_bd_write(part, ba, cnt, fs_va); 387 break; 388 case BD_GET_BLOCK_SIZE: 389 async_answer_1(callid, EOK, block_size); 390 continue; 391 case BD_GET_NUM_BLOCKS: 392 async_answer_2(callid, EOK, LOWER32(part->length), 393 UPPER32(part->length)); 394 continue; 395 default: 396 retval = EINVAL; 397 break; 398 } 399 async_answer_0(callid, retval); 400 } 359 bd_conn(iid, icall, &part->bd); 360 } 361 362 /** Open device. */ 363 static int gpt_bd_open(bd_srv_t *bd) 364 { 365 return EOK; 366 } 367 368 /** Close device. */ 369 static int gpt_bd_close(bd_srv_t *bd) 370 { 371 return EOK; 401 372 } 402 373 403 374 /** Read blocks from partition. */ 404 static int gpt_bd_read(part_t *p, aoff64_t ba, size_t cnt, void *buf) 405 { 375 static int gpt_bd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, void *buf, 376 size_t size) 377 { 378 part_t *p = bd_srv_part(bd); 406 379 aoff64_t gba; 380 381 if (cnt * block_size < size) 382 return EINVAL; 407 383 408 384 if (gpt_bsa_translate(p, ba, cnt, &gba) != EOK) … … 413 389 414 390 /** Write blocks to partition. */ 415 static int gpt_bd_write(part_t *p, aoff64_t ba, size_t cnt, const void *buf) 416 { 391 static int gpt_bd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, 392 const void *buf, size_t size) 393 { 394 part_t *p = bd_srv_part(bd); 417 395 aoff64_t gba; 396 397 if (cnt * block_size < size) 398 return EINVAL; 418 399 419 400 if (gpt_bsa_translate(p, ba, cnt, &gba) != EOK) … … 422 403 return block_write_direct(indev_sid, gba, cnt, buf); 423 404 } 405 406 /** Get device block size. */ 407 static int gpt_bd_get_block_size(bd_srv_t *bd, size_t *rsize) 408 { 409 *rsize = block_size; 410 return EOK; 411 } 412 413 /** Get number of blocks on device. */ 414 static int gpt_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb) 415 { 416 part_t *part = bd_srv_part(bd); 417 418 *rnb = part->length; 419 return EOK; 420 } 421 424 422 425 423 /** Translate block segment address with range checking. */ -
uspace/srv/bd/part/mbr_part/mbr_part.c
r2988aec7 r71b0d4d4 44 44 * 45 45 * Referemces: 46 * 46 * 47 47 * The source of MBR structures for this driver have been the following 48 48 * Wikipedia articles: … … 57 57 #include <stdlib.h> 58 58 #include <unistd.h> 59 #include <ipc/bd.h>60 59 #include <async.h> 61 60 #include <as.h> 61 #include <bd_srv.h> 62 62 #include <fibril_synch.h> 63 63 #include <loc.h> … … 100 100 /** Device representing the partition (outbound device) */ 101 101 service_id_t dsid; 102 /** Block device server structure */ 103 bd_srv_t bd; 102 104 /** Points to next partition structure. */ 103 105 struct part *next; … … 140 142 141 143 /** Partitioned device (inbound device) */ 142 static service_id_t inde f_sid;144 static service_id_t indev_sid; 143 145 144 146 /** List of partitions. This structure is an empty head. */ … … 150 152 static void mbr_pte_to_part(uint32_t base, const pt_entry_t *pte, part_t *part); 151 153 static void mbr_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg); 152 static int mbr_bd_read(part_t *p, uint64_t ba, size_t cnt, void *buf);153 static int mbr_bd_write(part_t *p, uint64_t ba, size_t cnt, const void *buf);154 154 static int mbr_bsa_translate(part_t *p, uint64_t ba, size_t cnt, uint64_t *gba); 155 156 static int mbr_bd_open(bd_srv_t *); 157 static int mbr_bd_close(bd_srv_t *); 158 static int mbr_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t); 159 static int mbr_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t); 160 static int mbr_bd_get_block_size(bd_srv_t *, size_t *); 161 static int mbr_bd_get_num_blocks(bd_srv_t *, aoff64_t *); 162 163 static bd_ops_t mbr_bd_ops = { 164 .open = mbr_bd_open, 165 .close = mbr_bd_close, 166 .read_blocks = mbr_bd_read_blocks, 167 .write_blocks = mbr_bd_write_blocks, 168 .get_block_size = mbr_bd_get_block_size, 169 .get_num_blocks = mbr_bd_get_num_blocks 170 }; 171 172 static part_t *bd_srv_part(bd_srv_t *bd) 173 { 174 return (part_t *)bd->arg; 175 } 155 176 156 177 int main(int argc, char **argv) … … 183 204 part_t *part; 184 205 185 rc = loc_service_get_id(dev_name, &inde f_sid, 0);206 rc = loc_service_get_id(dev_name, &indev_sid, 0); 186 207 if (rc != EOK) { 187 208 printf(NAME ": could not resolve device `%s'.\n", dev_name); … … 189 210 } 190 211 191 rc = block_init(EXCHANGE_SERIALIZE, inde f_sid, 2048);212 rc = block_init(EXCHANGE_SERIALIZE, indev_sid, 2048); 192 213 if (rc != EOK) { 193 214 printf(NAME ": could not init libblock.\n"); … … 197 218 /* Determine and verify block size. */ 198 219 199 rc = block_get_bsize(inde f_sid, &block_size);220 rc = block_get_bsize(indev_sid, &block_size); 200 221 if (rc != EOK) { 201 222 printf(NAME ": error getting block size.\n"); … … 281 302 */ 282 303 283 rc = block_read_direct(inde f_sid, 0, 1, brb);304 rc = block_read_direct(indev_sid, 0, 1, brb); 284 305 if (rc != EOK) { 285 306 printf(NAME ": Failed reading MBR block.\n"); … … 332 353 */ 333 354 ba = cp.start_addr; 334 rc = block_read_direct(inde f_sid, ba, 1, brb);355 rc = block_read_direct(indev_sid, ba, 1, brb); 335 356 if (rc != EOK) { 336 357 printf(NAME ": Failed reading EBR block at %" … … 381 402 part->present = (pte->ptype != PT_UNUSED) ? true : false; 382 403 404 bd_srv_init(&part->bd); 405 part->bd.ops = &mbr_bd_ops; 406 part->bd.arg = part; 407 383 408 part->dsid = 0; 384 409 part->next = NULL; … … 387 412 static void mbr_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 388 413 { 389 size_t comm_size;390 void *fs_va = NULL;391 ipc_callid_t callid;392 ipc_call_t call;393 sysarg_t method;394 414 service_id_t dh; 395 unsigned int flags;396 int retval;397 uint64_t ba;398 size_t cnt;399 415 part_t *part; 400 416 … … 417 433 418 434 assert(part->present == true); 419 420 /* Answer the IPC_M_CONNECT_ME_TO call. */ 421 async_answer_0(iid, EOK); 422 423 if (!async_share_out_receive(&callid, &comm_size, &flags)) { 424 async_answer_0(callid, EHANGUP); 425 return; 426 } 427 428 (void) async_share_out_finalize(callid, &fs_va); 429 if (fs_va == AS_MAP_FAILED) { 430 async_answer_0(callid, EHANGUP); 431 return; 432 } 433 434 while (1) { 435 callid = async_get_call(&call); 436 method = IPC_GET_IMETHOD(call); 437 438 if (!method) { 439 /* The other side has hung up. */ 440 async_answer_0(callid, EOK); 441 return; 442 } 443 444 switch (method) { 445 case BD_READ_BLOCKS: 446 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 447 IPC_GET_ARG2(call)); 448 cnt = IPC_GET_ARG3(call); 449 if (cnt * block_size > comm_size) { 450 retval = ELIMIT; 451 break; 452 } 453 retval = mbr_bd_read(part, ba, cnt, fs_va); 454 break; 455 case BD_WRITE_BLOCKS: 456 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 457 IPC_GET_ARG2(call)); 458 cnt = IPC_GET_ARG3(call); 459 if (cnt * block_size > comm_size) { 460 retval = ELIMIT; 461 break; 462 } 463 retval = mbr_bd_write(part, ba, cnt, fs_va); 464 break; 465 case BD_GET_BLOCK_SIZE: 466 async_answer_1(callid, EOK, block_size); 467 continue; 468 case BD_GET_NUM_BLOCKS: 469 async_answer_2(callid, EOK, LOWER32(part->length), 470 UPPER32(part->length)); 471 continue; 472 default: 473 retval = EINVAL; 474 break; 475 } 476 async_answer_0(callid, retval); 477 } 435 bd_conn(iid, icall, &part->bd); 436 } 437 438 /** Open device. */ 439 static int mbr_bd_open(bd_srv_t *bd) 440 { 441 return EOK; 442 } 443 444 /** Close device. */ 445 static int mbr_bd_close(bd_srv_t *bd) 446 { 447 return EOK; 478 448 } 479 449 480 450 /** Read blocks from partition. */ 481 static int mbr_bd_read(part_t *p, uint64_t ba, size_t cnt, void *buf) 482 { 483 uint64_t gba; 451 static int mbr_bd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, void *buf, 452 size_t size) 453 { 454 part_t *p = bd_srv_part(bd); 455 aoff64_t gba; 456 457 if (cnt * block_size < size) 458 return EINVAL; 484 459 485 460 if (mbr_bsa_translate(p, ba, cnt, &gba) != EOK) 486 461 return ELIMIT; 487 462 488 return block_read_direct(inde f_sid, gba, cnt, buf);463 return block_read_direct(indev_sid, gba, cnt, buf); 489 464 } 490 465 491 466 /** Write blocks to partition. */ 492 static int mbr_bd_write(part_t *p, uint64_t ba, size_t cnt, const void *buf) 493 { 494 uint64_t gba; 467 static int mbr_bd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, 468 const void *buf, size_t size) 469 { 470 part_t *p = bd_srv_part(bd); 471 aoff64_t gba; 472 473 if (cnt * block_size < size) 474 return EINVAL; 495 475 496 476 if (mbr_bsa_translate(p, ba, cnt, &gba) != EOK) 497 477 return ELIMIT; 498 478 499 return block_write_direct(indef_sid, gba, cnt, buf); 479 return block_write_direct(indev_sid, gba, cnt, buf); 480 } 481 482 /** Get device block size. */ 483 static int mbr_bd_get_block_size(bd_srv_t *bd, size_t *rsize) 484 { 485 *rsize = block_size; 486 return EOK; 487 } 488 489 /** Get number of blocks on device. */ 490 static int mbr_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb) 491 { 492 part_t *part = bd_srv_part(bd); 493 494 *rnb = part->length; 495 return EOK; 500 496 } 501 497 -
uspace/srv/bd/rd/rd.c
r2988aec7 r71b0d4d4 43 43 #include <sysinfo.h> 44 44 #include <as.h> 45 #include <bd_srv.h> 45 46 #include <ddi.h> 46 47 #include <align.h> … … 53 54 #include <stdio.h> 54 55 #include <loc.h> 55 #include <ipc/bd.h>56 56 #include <macros.h> 57 57 #include <inttypes.h> … … 68 68 static const size_t block_size = 512; 69 69 70 static int rd_read_blocks(uint64_t ba, size_t cnt, void *buf); 71 static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf); 70 static int rd_open(bd_srv_t *); 71 static int rd_close(bd_srv_t *); 72 static int rd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t); 73 static int rd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t); 74 static int rd_get_block_size(bd_srv_t *, size_t *); 75 static int rd_get_num_blocks(bd_srv_t *, aoff64_t *); 72 76 73 77 /** This rwlock protects the ramdisk's data. … … 78 82 * 79 83 */ 80 fibril_rwlock_t rd_lock; 81 82 /** Handle one connection to ramdisk. 83 * 84 * @param iid Hash of the request that opened the connection. 85 * @param icall Call data of the request that opened the connection. 86 */ 87 static void rd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 88 { 89 ipc_callid_t callid; 90 ipc_call_t call; 91 int retval; 92 void *fs_va = NULL; 93 uint64_t ba; 94 size_t cnt; 95 size_t comm_size; 96 97 /* 98 * Answer the first IPC_M_CONNECT_ME_TO call. 99 */ 100 async_answer_0(iid, EOK); 101 102 /* 103 * Now we wait for the client to send us its communication as_area. 104 */ 105 unsigned int flags; 106 if (async_share_out_receive(&callid, &comm_size, &flags)) { 107 (void) async_share_out_finalize(callid, &fs_va); 108 if (fs_va == AS_MAP_FAILED) { 109 async_answer_0(callid, EHANGUP); 110 return; 111 } 112 } else { 113 /* 114 * The client doesn't speak the same protocol. 115 * At this point we can't handle protocol variations. 116 * Close the connection. 117 */ 118 async_answer_0(callid, EHANGUP); 119 return; 120 } 121 122 while (true) { 123 callid = async_get_call(&call); 124 125 if (!IPC_GET_IMETHOD(call)) { 126 /* 127 * The other side has hung up. 128 * Exit the fibril. 129 */ 130 async_answer_0(callid, EOK); 131 return; 132 } 133 134 switch (IPC_GET_IMETHOD(call)) { 135 case BD_READ_BLOCKS: 136 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 137 IPC_GET_ARG2(call)); 138 cnt = IPC_GET_ARG3(call); 139 if (cnt * block_size > comm_size) { 140 retval = ELIMIT; 141 break; 142 } 143 retval = rd_read_blocks(ba, cnt, fs_va); 144 break; 145 case BD_WRITE_BLOCKS: 146 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 147 IPC_GET_ARG2(call)); 148 cnt = IPC_GET_ARG3(call); 149 if (cnt * block_size > comm_size) { 150 retval = ELIMIT; 151 break; 152 } 153 retval = rd_write_blocks(ba, cnt, fs_va); 154 break; 155 case BD_GET_BLOCK_SIZE: 156 async_answer_1(callid, EOK, block_size); 157 continue; 158 case BD_GET_NUM_BLOCKS: 159 async_answer_2(callid, EOK, LOWER32(rd_size / block_size), 160 UPPER32(rd_size / block_size)); 161 continue; 162 default: 163 /* 164 * The client doesn't speak the same protocol. 165 * Instead of closing the connection, we just ignore 166 * the call. This can be useful if the client uses a 167 * newer version of the protocol. 168 */ 169 retval = EINVAL; 170 break; 171 } 172 async_answer_0(callid, retval); 173 } 84 static fibril_rwlock_t rd_lock; 85 86 static bd_ops_t rd_bd_ops = { 87 .open = rd_open, 88 .close = rd_close, 89 .read_blocks = rd_read_blocks, 90 .write_blocks = rd_write_blocks, 91 .get_block_size = rd_get_block_size, 92 .get_num_blocks = rd_get_num_blocks 93 }; 94 95 static bd_srv_t bd_srv; 96 97 static void rd_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg) 98 { 99 bd_conn(iid, icall, &bd_srv); 100 } 101 102 /** Open device. */ 103 static int rd_open(bd_srv_t *bd) 104 { 105 return EOK; 106 } 107 108 /** Close device. */ 109 static int rd_close(bd_srv_t *bd) 110 { 111 return EOK; 174 112 } 175 113 176 114 /** Read blocks from the device. */ 177 static int rd_read_blocks(uint64_t ba, size_t cnt, void *buf) 115 static int rd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, void *buf, 116 size_t size) 178 117 { 179 118 if ((ba + cnt) * block_size > rd_size) { … … 183 122 184 123 fibril_rwlock_read_lock(&rd_lock); 185 memcpy(buf, rd_addr + ba * block_size, block_size * cnt);124 memcpy(buf, rd_addr + ba * block_size, min(block_size * cnt, size)); 186 125 fibril_rwlock_read_unlock(&rd_lock); 187 126 … … 190 129 191 130 /** Write blocks to the device. */ 192 static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf) 131 static int rd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, 132 const void *buf, size_t size) 193 133 { 194 134 if ((ba + cnt) * block_size > rd_size) { … … 198 138 199 139 fibril_rwlock_write_lock(&rd_lock); 200 memcpy(rd_addr + ba * block_size, buf, block_size * cnt);140 memcpy(rd_addr + ba * block_size, buf, min(block_size * cnt, size)); 201 141 fibril_rwlock_write_unlock(&rd_lock); 202 142 … … 235 175 (void *) addr_phys, size); 236 176 237 async_set_client_connection(rd_connection); 177 bd_srv_init(&bd_srv); 178 bd_srv.ops = &rd_bd_ops; 179 180 async_set_client_connection(rd_client_conn); 238 181 ret = loc_server_register(NAME); 239 182 if (ret != EOK) { … … 254 197 } 255 198 199 /** Get device block size. */ 200 static int rd_get_block_size(bd_srv_t *bd, size_t *rsize) 201 { 202 *rsize = block_size; 203 return EOK; 204 } 205 206 /** Get number of blocks on device. */ 207 static int rd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb) 208 { 209 *rnb = rd_size / block_size; 210 return EOK; 211 } 212 256 213 int main(int argc, char **argv) 257 214 { -
uspace/srv/bd/sata_bd/sata_bd.c
r2988aec7 r71b0d4d4 38 38 39 39 #include <sys/types.h> 40 #include <bd_srv.h> 40 41 #include <errno.h> 41 42 #include <stdio.h> 42 #include <ipc/bd.h>43 43 #include <str.h> 44 44 #include <loc.h> … … 56 56 static sata_bd_dev_t disk[MAXDISKS]; 57 57 static int disk_count; 58 59 static int sata_bd_open(bd_srv_t *); 60 static int sata_bd_close(bd_srv_t *); 61 static int sata_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t); 62 static int sata_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t); 63 static int sata_bd_get_block_size(bd_srv_t *, size_t *); 64 static int sata_bd_get_num_blocks(bd_srv_t *, aoff64_t *); 65 66 static bd_ops_t sata_bd_ops = { 67 .open = sata_bd_open, 68 .close = sata_bd_close, 69 .read_blocks = sata_bd_read_blocks, 70 .write_blocks = sata_bd_write_blocks, 71 .get_block_size = sata_bd_get_block_size, 72 .get_num_blocks = sata_bd_get_num_blocks 73 }; 74 75 static sata_bd_dev_t *bd_srv_sata(bd_srv_t *bd) 76 { 77 return (sata_bd_dev_t *)bd->arg; 78 } 58 79 59 80 /** Find SATA devices in device tree. … … 82 103 83 104 ahci_get_num_blocks(disk[disk_count].sess, &disk[disk_count].blocks); 84 105 106 bd_srv_init(&disk[disk_count].bd); 107 disk[disk_count].bd.ops = &sata_bd_ops; 108 disk[disk_count].bd.arg = &disk[disk_count]; 109 85 110 printf("Device %s - %s , blocks: %lu, block_size: %lu\n", 86 111 disk[disk_count].dev_name, disk[disk_count].sata_dev_name, … … 141 166 static void sata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 142 167 { 143 void *fs_va = NULL;144 ipc_callid_t callid;145 ipc_call_t call;146 sysarg_t method;147 168 service_id_t dsid; 148 /* Size of the communication area. */149 size_t comm_size;150 unsigned int flags;151 int retval = 0;152 uint64_t ba;153 size_t cnt;154 169 int disk_id, i; 155 170 … … 168 183 } 169 184 170 /* Answer the IPC_M_CONNECT_ME_TO call. */171 async_answer_0(iid, EOK); 172 173 if (!async_share_out_receive(&callid, &comm_size, &flags)) { 174 async_answer_0(callid, EHANGUP); 175 return; 176 }177 178 (void) async_share_out_finalize(callid, &fs_va); 179 if (fs_va == (void *) -1) { 180 async_answer_0(callid, EHANGUP); 181 return; 182 }183 184 while (true) { 185 callid = async_get_call(&call); 186 method = IPC_GET_IMETHOD(call); 187 188 if (!method){189 /* The other side has hung up. */190 async_answer_0(callid, EOK); 191 return;192 }193 194 switch (method) {195 case BD_READ_BLOCKS: 196 ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call)); 197 cnt = IPC_GET_ARG3(call); 198 if (cnt * disk[disk_id].block_size > comm_size) { 199 retval = ELIMIT; 200 break; 201 }202 retval = ahci_read_blocks(disk[disk_id].sess, ba, cnt, fs_va); 203 break;204 case BD_WRITE_BLOCKS:205 ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call)); 206 cnt = IPC_GET_ARG3(call);207 if (cnt * disk[disk_id].block_size > comm_size) { 208 retval = ELIMIT; 209 break; 210 } 211 retval = ahci_write_blocks(disk[disk_id].sess, ba, cnt, fs_va); 212 break;213 case BD_GET_BLOCK_SIZE: 214 async_answer_1(callid, EOK, disk[disk_id].block_size);215 continue;216 case BD_GET_NUM_BLOCKS: 217 async_answer_2(callid, EOK, LOWER32(disk[disk_id].blocks), 218 UPPER32(disk[disk_id].blocks)); 219 break; 220 default: 221 retval = EINVAL;222 break; 223 }224 async_answer_0(callid, retval);225 226 } 185 bd_conn(iid, icall, &disk[disk_id].bd); 186 } 187 188 /** Open device. */ 189 static int sata_bd_open(bd_srv_t *bd) 190 { 191 return EOK; 192 } 193 194 /** Close device. */ 195 static int sata_bd_close(bd_srv_t *bd) 196 { 197 return EOK; 198 } 199 200 /** Read blocks from partition. */ 201 static int sata_bd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, void *buf, 202 size_t size) 203 { 204 sata_bd_dev_t *sbd = bd_srv_sata(bd); 205 206 if (size < cnt * sbd->block_size) 207 return EINVAL; 208 209 return ahci_read_blocks(sbd->sess, ba, cnt, buf); 210 } 211 212 /** Write blocks to partition. */ 213 static int sata_bd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, 214 const void *buf, size_t size) 215 { 216 sata_bd_dev_t *sbd = bd_srv_sata(bd); 217 218 if (size < cnt * sbd->block_size) 219 return EINVAL; 220 221 return ahci_write_blocks(sbd->sess, ba, cnt, (void *)buf); 222 } 223 224 /** Get device block size. */ 225 static int sata_bd_get_block_size(bd_srv_t *bd, size_t *rsize) 226 { 227 sata_bd_dev_t *sbd = bd_srv_sata(bd); 228 229 *rsize = sbd->block_size; 230 return EOK; 231 } 232 233 /** Get number of blocks on device. */ 234 static int sata_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb) 235 { 236 sata_bd_dev_t *sbd = bd_srv_sata(bd); 237 238 *rnb = sbd->blocks; 239 return EOK; 240 } 241 227 242 228 243 int main(int argc, char **argv) -
uspace/srv/bd/sata_bd/sata_bd.h
r2988aec7 r71b0d4d4 38 38 #define SATA_DEV_NAME_LENGTH 256 39 39 40 #include <async.h> 41 #include <bd_srv.h> 42 #include <loc.h> 40 43 #include <sys/types.h> 41 #include <loc.h>42 44 43 45 /** SATA Block Device. */ 44 46 typedef struct { 45 /** Device name in device tree. */ 46 char * dev_name;47 /** SATA Device name. */ 48 char sata_dev_name[SATA_DEV_NAME_LENGTH]; 47 /** Device name in device tree. */ 48 char *dev_name; 49 /** SATA Device name. */ 50 char sata_dev_name[SATA_DEV_NAME_LENGTH]; 49 51 /** Session to device methods. */ 50 async_sess_t * sess;52 async_sess_t *sess; 51 53 /** Loc service id. */ 52 54 service_id_t service_id; 53 55 /** Number of blocks. */ 54 uint64_t blocks; 56 uint64_t blocks; 55 57 /** Size of block. */ 56 size_t block_size; 58 size_t block_size; 59 /** Block device server structure */ 60 bd_srv_t bd; 57 61 } sata_bd_dev_t; 58 62 -
uspace/srv/devman/devman.c
r2988aec7 r71b0d4d4 1052 1052 } 1053 1053 1054 1055 1054 /** Find the device node structure of the device witch has the specified handle. 1056 1055 * … … 1142 1141 fun->state = FUN_INIT; 1143 1142 atomic_set(&fun->refcnt, 0); 1143 fibril_mutex_initialize(&fun->busy_lock); 1144 1144 link_initialize(&fun->dev_functions); 1145 1145 list_initialize(&fun->match_ids.ids); … … 1184 1184 if (atomic_predec(&fun->refcnt) == 0) 1185 1185 delete_fun_node(fun); 1186 } 1187 1188 /** Make function busy for reconfiguration operations. */ 1189 void fun_busy_lock(fun_node_t *fun) 1190 { 1191 fibril_mutex_lock(&fun->busy_lock); 1192 } 1193 1194 /** Mark end of reconfiguration operation. */ 1195 void fun_busy_unlock(fun_node_t *fun) 1196 { 1197 fibril_mutex_unlock(&fun->busy_lock); 1186 1198 } 1187 1199 -
uspace/srv/devman/devman.h
r2988aec7 r71b0d4d4 174 174 /** State */ 175 175 fun_state_t state; 176 /** Locked while performing reconfiguration operations */ 177 fibril_mutex_t busy_lock; 176 178 177 179 /** The global unique identifier of the function */ … … 279 281 extern void dev_add_ref(dev_node_t *); 280 282 extern void dev_del_ref(dev_node_t *); 283 281 284 extern dev_node_t *find_dev_node_no_lock(dev_tree_t *tree, 282 285 devman_handle_t handle); … … 290 293 extern void fun_add_ref(fun_node_t *); 291 294 extern void fun_del_ref(fun_node_t *); 295 extern void fun_busy_lock(fun_node_t *); 296 extern void fun_busy_unlock(fun_node_t *); 292 297 extern fun_node_t *find_fun_node_no_lock(dev_tree_t *tree, 293 298 devman_handle_t handle); -
uspace/srv/devman/main.c
r2988aec7 r71b0d4d4 432 432 433 433 fun_node_t *fun = create_fun_node(); 434 /* One reference for creation, one for us */ 435 fun_add_ref(fun); 434 436 fun_add_ref(fun); 435 437 fun->ftype = ftype; 438 439 /* 440 * We can lock the function here even when holding the tree because 441 * we know it cannot be held by anyone else yet. 442 */ 443 fun_busy_lock(fun); 436 444 437 445 if (!insert_fun_node(&device_tree, fun, fun_name, pdev)) { 438 446 fibril_rwlock_write_unlock(&tree->rwlock); 439 447 dev_del_ref(pdev); 448 fun_busy_unlock(fun); 449 fun_del_ref(fun); 440 450 delete_fun_node(fun); 441 451 async_answer_0(callid, ENOMEM); … … 450 460 rc = online_function(fun); 451 461 if (rc != EOK) { 452 /* XXX clean up */ 462 /* XXX Set some failed state? */ 463 fun_busy_unlock(fun); 464 fun_del_ref(fun); 453 465 async_answer_0(callid, rc); 454 466 return; 455 467 } 468 469 fun_busy_unlock(fun); 470 fun_del_ref(fun); 456 471 457 472 /* Return device handle to parent's driver. */ … … 522 537 } 523 538 539 fun_busy_lock(fun); 540 524 541 fibril_rwlock_read_lock(&device_tree.rwlock); 525 542 if (fun->dev == NULL || fun->dev->drv != drv) { 526 543 fibril_rwlock_read_unlock(&device_tree.rwlock); 544 fun_busy_unlock(fun); 527 545 fun_del_ref(fun); 528 546 async_answer_0(iid, ENOENT); … … 533 551 rc = online_function(fun); 534 552 if (rc != EOK) { 553 fun_busy_unlock(fun); 535 554 fun_del_ref(fun); 536 555 async_answer_0(iid, (sysarg_t) rc); … … 538 557 } 539 558 559 fun_busy_unlock(fun); 540 560 fun_del_ref(fun); 541 561 … … 559 579 } 560 580 581 fun_busy_lock(fun); 582 561 583 fibril_rwlock_write_lock(&device_tree.rwlock); 562 584 if (fun->dev == NULL || fun->dev->drv != drv) { 585 fun_busy_unlock(fun); 563 586 fun_del_ref(fun); 564 587 async_answer_0(iid, ENOENT); … … 569 592 rc = offline_function(fun); 570 593 if (rc != EOK) { 594 fun_busy_unlock(fun); 571 595 fun_del_ref(fun); 572 596 async_answer_0(iid, (sysarg_t) rc); … … 574 598 } 575 599 600 fun_busy_unlock(fun); 576 601 fun_del_ref(fun); 577 602 async_answer_0(iid, (sysarg_t) EOK); … … 591 616 } 592 617 618 fun_busy_lock(fun); 619 593 620 fibril_rwlock_write_lock(&tree->rwlock); 594 621 … … 598 625 if (fun->state == FUN_REMOVED) { 599 626 fibril_rwlock_write_unlock(&tree->rwlock); 627 fun_busy_unlock(fun); 628 fun_del_ref(fun); 600 629 async_answer_0(callid, ENOENT); 601 630 return; … … 638 667 if (gone_rc == EOK) 639 668 gone_rc = ENOTSUP; 669 fun_busy_unlock(fun); 670 fun_del_ref(fun); 640 671 async_answer_0(callid, gone_rc); 641 672 return; … … 664 695 "service."); 665 696 fibril_rwlock_write_unlock(&tree->rwlock); 697 fun_busy_unlock(fun); 666 698 fun_del_ref(fun); 667 699 async_answer_0(callid, EIO); … … 673 705 remove_fun_node(&device_tree, fun); 674 706 fibril_rwlock_write_unlock(&tree->rwlock); 707 fun_busy_unlock(fun); 675 708 676 709 /* Delete ref added when inserting function into tree */ -
uspace/srv/fs/tmpfs/tmpfs_dump.c
r2988aec7 r71b0d4d4 49 49 #define TMPFS_COMM_SIZE 1024 50 50 51 static uint8_t tmpfs_buf[TMPFS_COMM_SIZE]; 52 51 53 struct rdentry { 52 54 uint8_t type; … … 68 70 uint32_t size; 69 71 70 if (block_seqread(dsid, bufpos, buflen, pos, &entry,72 if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, &entry, 71 73 sizeof(entry)) != EOK) 72 74 return false; … … 88 90 } 89 91 90 if (block_seqread(dsid, bufpos, buflen, pos, fname,92 if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, fname, 91 93 entry.len) != EOK) { 92 94 (void) ops->destroy(fn); … … 104 106 free(fname); 105 107 106 if (block_seqread(dsid, bufpos, buflen, pos, &size,108 if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, &size, 107 109 sizeof(size)) != EOK) 108 110 return false; … … 116 118 117 119 nodep->size = size; 118 if (block_seqread(dsid, bufpos, buflen, pos, nodep->data,120 if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, nodep->data, 119 121 size) != EOK) 120 122 return false; … … 132 134 } 133 135 134 if (block_seqread(dsid, bufpos, buflen, pos, fname,136 if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, fname, 135 137 entry.len) != EOK) { 136 138 (void) ops->destroy(fn); … … 176 178 177 179 char tag[6]; 178 if (block_seqread(dsid, &bufpos, &buflen, &pos, tag, 5) != EOK)180 if (block_seqread(dsid, tmpfs_buf, &bufpos, &buflen, &pos, tag, 5) != EOK) 179 181 goto error; 180 182
Note:
See TracChangeset
for help on using the changeset viewer.