Changes in / [71b0d4d4:2988aec7] in mainline
- Files:
-
- 38 deleted
- 37 edited
Legend:
- Unmodified
- Added
- Removed
-
HelenOS.config
r71b0d4d4 r2988aec7 89 89 @ "tmpfs" TMPFS image 90 90 @ "fat" FAT16 image 91 @ "ext 4fs" ext4image91 @ "ext2fs" EXT2 image 92 92 ! RDFMT (choice) 93 93 -
abi/include/syscall.h
r71b0d4d4 r2988aec7 63 63 SYS_PAGE_FIND_MAPPING, 64 64 65 SYS_IPC_CALL_SYNC_FAST, 66 SYS_IPC_CALL_SYNC_SLOW, 65 67 SYS_IPC_CALL_ASYNC_FAST, 66 68 SYS_IPC_CALL_ASYNC_SLOW, -
boot/Makefile
r71b0d4d4 r2988aec7 47 47 $(MKFAT) 1048576 $(DIST_PATH) $@ 48 48 endif 49 ifeq ($(RDFMT),ext 4fs)50 $(MKEXT 4) 1048576 $(DIST_PATH) $@49 ifeq ($(RDFMT),ext2fs) 50 $(MKEXT2) 1048576 $(DIST_PATH) $@ 51 51 endif 52 52 -
boot/Makefile.common
r71b0d4d4 r2988aec7 55 55 MKTMPFS = $(TOOLS_PATH)/mktmpfs.py 56 56 MKFAT = $(TOOLS_PATH)/mkfat.py 57 MKEXT 4 = $(TOOLS_PATH)/mkext4.py57 MKEXT2 = $(TOOLS_PATH)/mkext2.py 58 58 MKUIMAGE = $(TOOLS_PATH)/mkuimage.py 59 59 … … 84 84 endif 85 85 86 ifeq ($(RDFMT),ext 4fs)87 INIT_TASKS += $(USPACE_PATH)/srv/fs/ext 4fs/ext4fs86 ifeq ($(RDFMT),ext2fs) 87 INIT_TASKS += $(USPACE_PATH)/srv/fs/ext2fs/ext2fs 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 \109 108 $(USPACE_PATH)/srv/hid/remcons/remcons \ 110 109 $(USPACE_PATH)/srv/net/ethip/ethip \ … … 175 174 $(USPACE_PATH)/app/tester/tester \ 176 175 $(USPACE_PATH)/app/testread/testread \ 177 $(USPACE_PATH)/app/testwrit/testwrit \178 176 $(USPACE_PATH)/app/tetris/tetris \ 179 177 $(USPACE_PATH)/app/trace/trace \ -
kernel/generic/include/ipc/ipc.h
r71b0d4d4 r2988aec7 77 77 waitq_t wq; 78 78 79 /** Linkage for the list of task's synchronous answerboxes. */ 80 link_t sync_box_link; 81 79 82 /** Phones connected to this answerbox. */ 80 83 list_t connected_phones; … … 113 116 struct task *sender; 114 117 118 /* 119 * The caller box is different from sender->answerbox 120 * for synchronous calls. 121 */ 122 answerbox_t *callerbox; 123 115 124 /** Private data to internal IPC. */ 116 125 sysarg_t priv; … … 138 147 139 148 extern int ipc_call(phone_t *, call_t *); 149 extern int ipc_call_sync(phone_t *, call_t *); 140 150 extern call_t *ipc_wait_for_call(answerbox_t *, uint32_t, unsigned int); 141 151 extern int ipc_forward(call_t *, phone_t *, answerbox_t *, unsigned int); -
kernel/generic/include/ipc/sysipc.h
r71b0d4d4 r2988aec7 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 *); 42 45 extern sysarg_t sys_ipc_call_async_fast(sysarg_t, sysarg_t, sysarg_t, 43 46 sysarg_t, sysarg_t, sysarg_t); -
kernel/generic/include/proc/task.h
r71b0d4d4 r2988aec7 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. */ 96 97 event_t events[EVENT_TASK_END - EVENT_END]; 97 98 -
kernel/generic/src/ipc/ipc.c
r71b0d4d4 r2988aec7 71 71 { 72 72 memsetb(call, sizeof(*call), 0); 73 call->callerbox = &TASK->answerbox; 73 74 call->sender = TASK; 74 75 call->buffer = NULL; … … 119 120 irq_spinlock_initialize(&box->irq_lock, "ipc.box.irqlock"); 120 121 waitq_initialize(&box->wq); 122 link_initialize(&box->sync_box_link); 121 123 list_initialize(&box->connected_phones); 122 124 list_initialize(&box->calls); … … 161 163 } 162 164 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 so 180 * 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 the 198 * 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 163 208 /** Answer a message which was not dispatched and is not listed in any queue. 164 209 * … … 169 214 static void _ipc_answer_free_call(call_t *call, bool selflocked) 170 215 { 171 answerbox_t *callerbox = &call->sender->answerbox;216 answerbox_t *callerbox = call->callerbox; 172 217 bool do_lock = ((!selflocked) || callerbox != (&TASK->answerbox)); 173 218 … … 561 606 ipc_cleanup_call_list(&TASK->answerbox.calls); 562 607 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); 563 622 564 623 /* Wait for all answers to asynchronous calls to arrive */ -
kernel/generic/src/ipc/sysipc.c
r71b0d4d4 r2988aec7 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 than 621 * 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 will 629 * 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 beyond 650 * 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_UDEBUG 660 udebug_stoppable_begin(); 661 #endif 662 rc = ipc_call_sync(phone, call); 663 #ifdef CONFIG_UDEBUG 664 udebug_stoppable_end(); 665 #endif 666 667 if (rc != EOK) { 668 /* The call will be freed by ipc_cleanup(). */ 669 return rc; 670 } 671 672 process_answer(call); 673 } else 674 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 the 689 * 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_UDEBUG 713 udebug_stoppable_begin(); 714 #endif 715 rc = ipc_call_sync(phone, call); 716 #ifdef CONFIG_UDEBUG 717 udebug_stoppable_end(); 718 #endif 719 720 if (rc != EOK) { 721 /* The call will be freed by ipc_cleanup(). */ 722 return rc; 723 } 724 725 process_answer(call); 726 } else 727 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; 614 733 615 734 return 0; -
kernel/generic/src/proc/task.c
r71b0d4d4 r2988aec7 156 156 157 157 list_initialize(&task->threads); 158 list_initialize(&task->sync_boxes); 158 159 159 160 ipc_answerbox_init(&task->answerbox, task); -
kernel/generic/src/syscall/syscall.c
r71b0d4d4 r2988aec7 151 151 152 152 /* IPC related syscalls. */ 153 (syshandler_t) sys_ipc_call_sync_fast, 154 (syshandler_t) sys_ipc_call_sync_slow, 153 155 (syshandler_t) sys_ipc_call_async_fast, 154 156 (syshandler_t) sys_ipc_call_async_slow, -
uspace/Makefile
r71b0d4d4 r2988aec7 59 59 app/tester \ 60 60 app/testread \ 61 app/testwrit \62 61 app/tetris \ 63 62 app/trace \ … … 99 98 srv/fs/locfs \ 100 99 srv/fs/ext2fs \ 101 srv/fs/ext4fs \102 100 srv/hid/console \ 103 101 srv/hid/s3c24xx_ts \ … … 199 197 lib/nic \ 200 198 lib/ext2 \ 201 lib/ext4 \202 199 lib/usb \ 203 200 lib/usbhost \ -
uspace/Makefile.common
r71b0d4d4 r2988aec7 115 115 116 116 LIBEXT2_PREFIX = $(LIB_PREFIX)/ext2 117 LIBEXT4_PREFIX = $(LIB_PREFIX)/ext4118 117 119 118 LIBUSB_PREFIX = $(LIB_PREFIX)/usb -
uspace/app/trace/syscalls.c
r71b0d4d4 r2988aec7 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 }, 55 57 [SYS_IPC_CALL_ASYNC_FAST] = { "ipc_call_async_fast", 6, V_HASH }, 56 58 [SYS_IPC_CALL_ASYNC_SLOW] = { "ipc_call_async_slow", 2, V_HASH }, -
uspace/app/trace/trace.c
r71b0d4d4 r2988aec7 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 320 377 static void sc_ipc_wait(sysarg_t *sc_args, int sc_rc) 321 378 { … … 351 408 print_sc_args(sc_args, syscall_desc[sc_id].n_args); 352 409 } 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 } 353 418 } 354 419 … … 382 447 case SYS_IPC_CALL_ASYNC_SLOW: 383 448 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); 384 455 break; 385 456 case SYS_IPC_WAIT: -
uspace/drv/bus/usb/usbmast/main.c
r71b0d4d4 r2988aec7 37 37 #include <as.h> 38 38 #include <async.h> 39 #include < bd_srv.h>39 #include <ipc/bd.h> 40 40 #include <macros.h> 41 41 #include <usb/dev/driver.h> … … 81 81 static void usbmast_bd_connection(ipc_callid_t iid, ipc_call_t *icall, 82 82 void *arg); 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_blocks98 };99 100 static usbmast_fun_t *bd_srv_usbmast(bd_srv_t *bd)101 {102 return (usbmast_fun_t *)bd->arg;103 }104 83 105 84 /** Callback when a device is removed from the system. … … 240 219 mfun->lun = lun; 241 220 242 bd_srv_init(&mfun->bd);243 mfun->bd.ops = &usbmast_bd_ops;244 mfun->bd.arg = mfun;245 246 221 /* Set up a connection handler. */ 247 222 fun->conn_handler = usbmast_bd_connection; … … 309 284 { 310 285 usbmast_fun_t *mfun; 311 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 312 309 mfun = (usbmast_fun_t *) ((ddf_fun_t *)arg)->driver_data; 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 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 } 368 346 369 347 /** USB mass storage driver ops. */ -
uspace/drv/bus/usb/usbmast/usbmast.h
r71b0d4d4 r2988aec7 37 37 #define USBMAST_H_ 38 38 39 #include <bd_srv.h>40 39 #include <sys/types.h> 41 40 #include <usb/usb.h> … … 69 68 /** Block size in bytes */ 70 69 size_t block_size; 71 /** Block device server structure */72 bd_srv_t bd;73 70 } usbmast_fun_t; 74 71 -
uspace/lib/block/libblock.c
r71b0d4d4 r2988aec7 40 40 #include "../../srv/vfs/vfs.h" 41 41 #include <ipc/loc.h> 42 #include <ipc/bd.h> 42 43 #include <ipc/services.h> 43 44 #include <errno.h> … … 46 47 #include <as.h> 47 48 #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 bd_t *bd; 82 fibril_mutex_t comm_area_lock; 83 void *comm_area; 84 size_t comm_size; 83 85 void *bb_buf; 84 86 aoff64_t bb_addr; … … 87 89 } devcon_t; 88 90 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); 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 *); 91 95 static aoff64_t ba_ltop(devcon_t *, aoff64_t); 92 96 … … 108 112 109 113 static int devcon_add(service_id_t service_id, async_sess_t *sess, 110 size_t bsize, bd_t *bd)114 size_t bsize, void *comm_area, size_t comm_size) 111 115 { 112 116 devcon_t *devcon; 117 118 if (comm_size < bsize) 119 return EINVAL; 113 120 114 121 devcon = malloc(sizeof(devcon_t)); … … 119 126 devcon->service_id = service_id; 120 127 devcon->sess = sess; 121 devcon->bd = bd; 128 fibril_mutex_initialize(&devcon->comm_area_lock); 129 devcon->comm_area = comm_area; 130 devcon->comm_size = comm_size; 122 131 devcon->bb_buf = NULL; 123 132 devcon->bb_addr = 0; … … 149 158 size_t comm_size) 150 159 { 151 bd_t *bd; 152 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 153 165 async_sess_t *sess = loc_service_connect(mgmt, service_id, 154 166 IPC_FLAG_BLOCKING); 155 167 if (!sess) { 168 munmap(comm_area, comm_size); 156 169 return ENOENT; 157 170 } 158 171 159 int rc = bd_open(sess, &bd); 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 160 177 if (rc != EOK) { 178 munmap(comm_area, comm_size); 161 179 async_hangup(sess); 162 180 return rc; … … 164 182 165 183 size_t bsize; 166 rc = bd_get_block_size(bd, &bsize); 184 rc = get_block_size(sess, &bsize); 185 167 186 if (rc != EOK) { 168 bd_close(bd);187 munmap(comm_area, comm_size); 169 188 async_hangup(sess); 170 189 return rc; 171 190 } 172 191 173 rc = devcon_add(service_id, sess, bsize, bd);192 rc = devcon_add(service_id, sess, bsize, comm_area, comm_size); 174 193 if (rc != EOK) { 175 bd_close(bd);194 munmap(comm_area, comm_size); 176 195 async_hangup(sess); 177 196 return rc; … … 194 213 free(devcon->bb_buf); 195 214 196 bd_close(devcon->bd);215 munmap(devcon->comm_area, devcon->comm_size); 197 216 async_hangup(devcon->sess); 198 217 … … 214 233 return ENOMEM; 215 234 216 rc = read_blocks(devcon, 0, 1, bb_buf, devcon->pblock_size); 235 fibril_mutex_lock(&devcon->comm_area_lock); 236 rc = read_blocks(devcon, 0, 1); 217 237 if (rc != EOK) { 238 fibril_mutex_unlock(&devcon->comm_area_lock); 218 239 free(bb_buf); 219 240 return rc; 220 241 } 242 memcpy(bb_buf, devcon->comm_area, devcon->pblock_size); 243 fibril_mutex_unlock(&devcon->comm_area_lock); 221 244 222 245 devcon->bb_buf = bb_buf; … … 315 338 list_remove(&b->free_link); 316 339 if (b->dirty) { 317 rc = write_blocks(devcon, b->pba, cache->blocks_cluster,318 b->data, b->size);340 memcpy(devcon->comm_area, b->data, b->size); 341 rc = write_blocks(devcon, b->pba, cache->blocks_cluster); 319 342 if (rc != EOK) 320 343 return rc; … … 458 481 list_append(&b->free_link, &cache->free_list); 459 482 fibril_mutex_unlock(&cache->lock); 483 fibril_mutex_lock(&devcon->comm_area_lock); 484 memcpy(devcon->comm_area, b->data, b->size); 460 485 rc = write_blocks(devcon, b->pba, 461 cache->blocks_cluster, b->data, b->size); 486 cache->blocks_cluster); 487 fibril_mutex_unlock(&devcon->comm_area_lock); 462 488 if (rc != EOK) { 463 489 /* … … 529 555 * the new contents from the device. 530 556 */ 531 rc = read_blocks(devcon, b->pba, cache->blocks_cluster, 532 b->data, cache->lblock_size); 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); 533 561 if (rc != EOK) 534 562 b->toxic = true; … … 588 616 if (block->dirty && (block->refcnt == 1) && 589 617 (blocks_cached > CACHE_HI_WATERMARK || mode != CACHE_MODE_WB)) { 590 rc = write_blocks(devcon, block->pba, cache->blocks_cluster, 591 block->data, block->size); 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); 592 622 block->dirty = false; 593 623 } … … 658 688 * 659 689 * @param service_id Service ID of the block device. 660 * @param buf Buffer for holding one block661 690 * @param bufpos Pointer to the first unread valid offset within the 662 691 * communication buffer. … … 670 699 * @return EOK on success or a negative return code on failure. 671 700 */ 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)701 int block_seqread(service_id_t service_id, size_t *bufpos, size_t *buflen, 702 aoff64_t *pos, void *dst, size_t size) 674 703 { 675 704 size_t offset = 0; … … 682 711 block_size = devcon->pblock_size; 683 712 713 fibril_mutex_lock(&devcon->comm_area_lock); 684 714 while (left > 0) { 685 715 size_t rd; … … 695 725 * destination buffer. 696 726 */ 697 memcpy(dst + offset, buf+ *bufpos, rd);727 memcpy(dst + offset, devcon->comm_area + *bufpos, rd); 698 728 offset += rd; 699 729 *bufpos += rd; … … 706 736 int rc; 707 737 708 rc = read_blocks(devcon, *pos / block_size, 1, buf, 709 devcon->pblock_size); 738 rc = read_blocks(devcon, *pos / block_size, 1); 710 739 if (rc != EOK) { 740 fibril_mutex_unlock(&devcon->comm_area_lock); 711 741 return rc; 712 742 } … … 716 746 } 717 747 } 748 fibril_mutex_unlock(&devcon->comm_area_lock); 718 749 719 750 return EOK; … … 732 763 { 733 764 devcon_t *devcon; 765 int rc; 734 766 735 767 devcon = devcon_search(service_id); 736 768 assert(devcon); 737 738 return read_blocks(devcon, ba, cnt, buf, devcon->pblock_size * cnt); 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; 739 779 } 740 780 … … 752 792 { 753 793 devcon_t *devcon; 794 int rc; 754 795 755 796 devcon = devcon_search(service_id); 756 797 assert(devcon); 757 758 return write_blocks(devcon, ba, cnt, (void *)data, devcon->pblock_size * cnt); 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; 759 807 } 760 808 … … 772 820 devcon = devcon_search(service_id); 773 821 assert(devcon); 774 775 return bd_get_block_size(devcon->bd, bsize);822 823 return get_block_size(devcon->sess, bsize); 776 824 } 777 825 … … 788 836 assert(devcon); 789 837 790 return bd_get_num_blocks(devcon->bd, nblocks);838 return get_num_blocks(devcon->sess, nblocks); 791 839 } 792 840 … … 839 887 memcpy(data, buffer + offset, bytes); 840 888 free(buffer); 841 889 842 890 return EOK; 843 891 } … … 855 903 { 856 904 devcon_t *devcon = devcon_search(service_id); 905 assert(devcon); 906 857 907 toc_block_t *toc = NULL; 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 } 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); 871 926 872 927 return toc; … … 882 937 * @return EOK on success or negative error code on failure. 883 938 */ 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); 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 890 948 if (rc != EOK) { 891 949 printf("Error %d reading %zu blocks starting at block %" PRIuOFF64 … … 909 967 * @return EOK on success or negative error code on failure. 910 968 */ 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); 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 917 978 if (rc != EOK) { 918 979 printf("Error %d writing %zu blocks starting at block %" PRIuOFF64 … … 926 987 } 927 988 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 928 1020 /** Convert logical block address to physical block address. */ 929 1021 static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba) -
uspace/lib/block/libblock.h
r71b0d4d4 r2988aec7 122 122 extern int block_put(block_t *); 123 123 124 extern int block_seqread(service_id_t, void *, size_t *, size_t *, aoff64_t*,125 void *,size_t);124 extern int block_seqread(service_id_t, size_t *, size_t *, aoff64_t *, void *, 125 size_t); 126 126 127 127 extern int block_get_bsize(service_id_t, size_t *); -
uspace/lib/c/Makefile
r71b0d4d4 r2988aec7 62 62 generic/ddi.c \ 63 63 generic/as.c \ 64 generic/bd.c \65 generic/bd_srv.c \66 64 generic/cap.c \ 67 65 generic/cfg.c \ -
uspace/lib/c/generic/async.c
r71b0d4d4 r2988aec7 114 114 #include <stdlib.h> 115 115 #include <macros.h> 116 #include "private/libc.h"117 116 118 117 #define CLIENT_HASH_TABLE_BUCKETS 32 … … 2167 2166 int async_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags) 2168 2167 { 2169 return ipc_answer_3(callid, EOK, (sysarg_t) src, (sysarg_t) flags, 2170 (sysarg_t) __entry); 2168 return ipc_share_in_finalize(callid, src, flags); 2171 2169 } 2172 2170 … … 2235 2233 int async_share_out_finalize(ipc_callid_t callid, void **dst) 2236 2234 { 2237 return ipc_ answer_2(callid, EOK, (sysarg_t) __entry, (sysarg_t)dst);2235 return ipc_share_out_finalize(callid, dst); 2238 2236 } 2239 2237 … … 2319 2317 int async_data_read_finalize(ipc_callid_t callid, const void *src, size_t size) 2320 2318 { 2321 return ipc_ answer_2(callid, EOK, (sysarg_t) src, (sysarg_t)size);2319 return ipc_data_read_finalize(callid, src, size); 2322 2320 } 2323 2321 … … 2422 2420 int async_data_write_finalize(ipc_callid_t callid, void *dst, size_t size) 2423 2421 { 2424 return ipc_ answer_2(callid, EOK, (sysarg_t) dst, (sysarg_t)size);2422 return ipc_data_write_finalize(callid, dst, size); 2425 2423 } 2426 2424 -
uspace/lib/c/generic/ipc.c
r71b0d4d4 r2988aec7 48 48 #include <fibril.h> 49 49 #include <macros.h> 50 #include "private/libc.h" 50 51 51 52 /** … … 82 83 83 84 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() because 90 * 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 } 84 182 85 183 /** Send asynchronous message via syscall. … … 513 611 } 514 612 613 /** Request callback connection. 614 * 615 * The @a task_id and @a phonehash identifiers returned 616 * 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 will 624 * 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, the 684 * call should block. This has to be, however, implemented 685 * 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 515 707 /** Hang up a phone. 516 708 * … … 566 758 } 567 759 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_IN 789 * calls so that the user doesn't have to remember the meaning of each 790 * 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_OUT 823 * calls so that the user doesn't have to remember the meaning of each 824 * 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_READ 855 * calls so that the user doesn't have to remember the meaning of each 856 * 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 than 861 * 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_WRITE 889 * calls so that the user doesn't have to remember the meaning of each 890 * 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 568 904 /** Connect to a task specified by id. 569 905 * -
uspace/lib/c/generic/iplink_srv.c
r71b0d4d4 r2988aec7 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);144 141 async_answer_0(callid, EOK); 145 142 break; -
uspace/lib/c/include/ipc/ipc.h
r71b0d4d4 r2988aec7 48 48 typedef void (*ipc_async_callback_t)(void *, int, ipc_call_t *); 49 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 of 53 * arguments of payload and n denotes number of return values. Whenever 54 * 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 50 186 extern ipc_callid_t ipc_wait_cycle(ipc_call_t *, sysarg_t, unsigned int); 51 187 extern void ipc_poke(void); … … 118 254 sysarg_t, sysarg_t, void *, ipc_async_callback_t, bool); 119 255 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 120 262 extern int ipc_hangup(int); 121 263 … … 125 267 sysarg_t, sysarg_t, sysarg_t, unsigned int); 126 268 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 127 291 extern int ipc_connect_kbox(task_id_t); 128 292 -
uspace/srv/bd/ata_bd/ata_bd.c
r71b0d4d4 r2988aec7 51 51 #include <libarch/ddi.h> 52 52 #include <ddi.h> 53 #include <ipc/bd.h> 53 54 #include <async.h> 54 55 #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 ata_disk[MAX_DISKS];100 static disk_t 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 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 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); 116 109 static int ata_rcmd_read(int disk_id, uint64_t ba, size_t cnt, 117 110 void *buf); … … 134 127 unsigned timeout); 135 128 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_blocks144 };145 146 static disk_t *bd_srv_disk(bd_srv_t *bd)147 {148 return (disk_t *)bd->arg;149 }150 151 129 int main(int argc, char **argv) 152 130 { … … 183 161 fflush(stdout); 184 162 185 rc = disk_init(& ata_disk[i], i);163 rc = disk_init(&disk[i], i); 186 164 187 165 if (rc == EOK) { 188 disk_print_summary(& ata_disk[i]);166 disk_print_summary(&disk[i]); 189 167 } else { 190 168 printf("Not found.\n"); … … 196 174 for (i = 0; i < MAX_DISKS; i++) { 197 175 /* Skip unattached drives. */ 198 if ( ata_disk[i].present == false)176 if (disk[i].present == false) 199 177 continue; 200 178 201 179 snprintf(name, 16, "%s/ata%udisk%d", NAMESPACE, ctl_num, i); 202 rc = loc_service_register(name, & ata_disk[i].service_id);180 rc = loc_service_register(name, &disk[i].service_id); 203 181 if (rc != EOK) { 204 182 printf(NAME ": Unable to register device %s.\n", name); … … 239 217 case am_chs: 240 218 printf("CHS %u cylinders, %u heads, %u sectors", 241 d ->geom.cylinders, d->geom.heads,242 d ->geom.sectors);219 disk->geom.cylinders, disk->geom.heads, 220 disk->geom.sectors); 243 221 break; 244 222 case am_lba28: … … 295 273 static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 296 274 { 275 void *fs_va = NULL; 276 ipc_callid_t callid; 277 ipc_call_t call; 278 sysarg_t method; 297 279 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; 298 285 int disk_id, i; 299 286 … … 304 291 disk_id = -1; 305 292 for (i = 0; i < MAX_DISKS; i++) 306 if ( ata_disk[i].service_id == dsid)293 if (disk[i].service_id == dsid) 307 294 disk_id = i; 308 295 309 if (disk_id < 0 || ata_disk[disk_id].present == false) {296 if (disk_id < 0 || disk[disk_id].present == false) { 310 297 async_answer_0(iid, EINVAL); 311 298 return; 312 299 } 313 300 314 bd_conn(iid, icall, &ata_disk[disk_id].bd); 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 } 315 367 } 316 368 … … 332 384 unsigned i; 333 385 334 d->disk_id = disk_id;335 386 d->present = false; 336 387 fibril_mutex_initialize(&d->lock); 337 338 bd_srv_init(&d->bd);339 d->bd.ops = &ata_bd_ops;340 d->bd.arg = d;341 388 342 389 /* Try identify command. */ … … 467 514 } 468 515 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 479 516 /** Read multiple blocks from the device. */ 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); 517 static int ata_bd_read_blocks(int disk_id, uint64_t ba, size_t cnt, 518 void *buf) { 519 484 520 int rc; 485 521 486 if (size < cnt * disk->block_size)487 return EINVAL;488 489 522 while (cnt > 0) { 490 if (disk ->dev_type == ata_reg_dev)491 rc = ata_rcmd_read(disk ->disk_id, ba, 1, buf);523 if (disk[disk_id].dev_type == ata_reg_dev) 524 rc = ata_rcmd_read(disk_id, ba, 1, buf); 492 525 else 493 rc = ata_pcmd_read_12(disk ->disk_id, ba, 1, buf,494 disk ->block_size);526 rc = ata_pcmd_read_12(disk_id, ba, 1, buf, 527 disk[disk_id].block_size); 495 528 496 529 if (rc != EOK) … … 499 532 ++ba; 500 533 --cnt; 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); 534 buf += disk[disk_id].block_size; 535 } 536 537 return EOK; 513 538 } 514 539 515 540 /** Write multiple blocks to the device. */ 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); 541 static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt, 542 const void *buf) { 543 520 544 int rc; 521 545 522 if (disk ->dev_type != ata_reg_dev)546 if (disk[disk_id].dev_type != ata_reg_dev) 523 547 return ENOTSUP; 524 548 525 if (size < cnt * disk->block_size)526 return EINVAL;527 528 549 while (cnt > 0) { 529 rc = ata_rcmd_write(disk ->disk_id, ba, 1, buf);550 rc = ata_rcmd_write(disk_id, ba, 1, buf); 530 551 if (rc != EOK) 531 552 return rc; … … 533 554 ++ba; 534 555 --cnt; 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; 556 buf += disk[disk_id].block_size; 557 } 558 556 559 return EOK; 557 560 } … … 682 685 uint16_t val; 683 686 684 d = & ata_disk[dev_idx];687 d = &disk[dev_idx]; 685 688 fibril_mutex_lock(&d->lock); 686 689 … … 871 874 block_coord_t bc; 872 875 873 d = & ata_disk[disk_id];876 d = &disk[disk_id]; 874 877 875 878 /* Silence warning. */ … … 916 919 /* Read data from the device buffer. */ 917 920 918 for (i = 0; i < ata_disk[disk_id].block_size / 2; i++) {921 for (i = 0; i < disk[disk_id].block_size / 2; i++) { 919 922 data = pio_read_16(&cmd->data_port); 920 923 ((uint16_t *) buf)[i] = data; … … 947 950 block_coord_t bc; 948 951 949 d = & ata_disk[disk_id];952 d = &disk[disk_id]; 950 953 951 954 /* Silence warning. */ … … 992 995 /* Write data to the device buffer. */ 993 996 994 for (i = 0; i < d ->block_size / 2; i++) {997 for (i = 0; i < disk[disk_id].block_size / 2; i++) { 995 998 pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]); 996 999 } -
uspace/srv/bd/ata_bd/ata_bd.h
r71b0d4d4 r2988aec7 36 36 #define __ATA_BD_H__ 37 37 38 #include <bd_srv.h>39 38 #include <sys/types.h> 40 39 #include <fibril_synch.h> … … 118 117 fibril_mutex_t lock; 119 118 service_id_t service_id; 120 int disk_id;121 bd_srv_t bd;122 119 } disk_t; 123 120 -
uspace/srv/bd/file_bd/file_bd.c
r71b0d4d4 r2988aec7 41 41 #include <stdio.h> 42 42 #include <unistd.h> 43 #include <ipc/bd.h> 43 44 #include <async.h> 44 45 #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;65 64 static fibril_mutex_t dev_lock; 66 65 … … 68 67 static int file_bd_init(const char *fname); 69 68 static void file_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *); 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 }; 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); 86 71 87 72 int main(int argc, char **argv) … … 154 139 static int file_bd_init(const char *fname) 155 140 { 156 bd_srv_init(&bd_srv);157 bd_srv.ops = &file_bd_ops;158 159 141 async_set_client_connection(file_bd_connection); 160 142 int rc = loc_server_register(NAME); … … 188 170 static void file_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 189 171 { 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; 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 } 203 240 } 204 241 205 242 /** Read blocks from the device. */ 206 static int file_bd_read_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt, void *buf, 207 size_t size) 243 static int file_bd_read_blocks(uint64_t ba, size_t cnt, void *buf) 208 244 { 209 245 size_t n_rd; 210 246 int rc; 211 212 if (size < cnt * block_size)213 return EINVAL;214 247 215 248 /* Check whether access is within device address bounds. */ … … 246 279 247 280 /** Write blocks to the device. */ 248 static int file_bd_write_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt, 249 const void *buf, size_t size) 281 static int file_bd_write_blocks(uint64_t ba, size_t cnt, const void *buf) 250 282 { 251 283 size_t n_wr; 252 284 int rc; 253 254 if (size < cnt * block_size)255 return EINVAL;256 285 257 286 /* Check whether access is within device address bounds. */ … … 289 318 } 290 319 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 305 320 /** 306 321 * @} -
uspace/srv/bd/gxe_bd/gxe_bd.c
r71b0d4d4 r2988aec7 39 39 #include <libarch/ddi.h> 40 40 #include <ddi.h> 41 #include <ipc/bd.h> 41 42 #include <async.h> 42 43 #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 */68 67 typedef struct { 69 68 uint32_t offset_lo; … … 84 83 85 84 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;93 85 } gxe_bd_t; 94 86 87 95 88 static const size_t block_size = 512; 89 static size_t comm_size; 96 90 97 91 static uintptr_t dev_physical = 0x13000000; 98 static gxe_bd_ hw_t *dev;92 static gxe_bd_t *dev; 99 93 100 94 static service_id_t service_id[MAX_DISKS]; 101 95 102 96 static fibril_mutex_t dev_lock[MAX_DISKS]; 103 104 static gxe_bd_t gxe_bd[MAX_DISKS];105 97 106 98 static int gxe_bd_init(void); 107 99 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); 108 104 static int gxe_bd_read_block(int disk_id, uint64_t ba, void *buf); 109 105 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_blocks125 };126 127 static gxe_bd_t *bd_srv_gxe(bd_srv_t *bd)128 {129 return (gxe_bd_t *)bd->arg;130 }131 106 132 107 int main(int argc, char **argv) … … 155 130 156 131 void *vaddr; 157 rc = pio_enable((void *) dev_physical, sizeof(gxe_bd_ hw_t), &vaddr);132 rc = pio_enable((void *) dev_physical, sizeof(gxe_bd_t), &vaddr); 158 133 if (rc != EOK) { 159 134 printf("%s: Could not initialize device I/O space.\n", NAME); … … 165 140 for (unsigned int i = 0; i < MAX_DISKS; i++) { 166 141 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];171 142 172 143 snprintf(name, 16, "%s/disk%u", NAMESPACE, i); … … 186 157 static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 187 158 { 159 void *fs_va = NULL; 160 ipc_callid_t callid; 161 ipc_call_t call; 162 sysarg_t method; 188 163 service_id_t dsid; 164 unsigned int flags; 165 int retval; 166 uint64_t ba; 167 unsigned cnt; 189 168 int disk_id, i; 190 169 … … 203 182 } 204 183 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; 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 } 218 246 } 219 247 220 248 /** Read multiple blocks from the device. */ 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; 249 static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt, 250 void *buf) { 251 225 252 int rc; 226 227 if (size < cnt * block_size)228 return EINVAL;229 253 230 254 while (cnt > 0) { … … 242 266 243 267 /** Write multiple blocks to the device. */ 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; 268 static int gxe_bd_write_blocks(int disk_id, uint64_t ba, unsigned cnt, 269 const void *buf) { 270 248 271 int rc; 249 250 if (size < cnt * block_size)251 return EINVAL;252 272 253 273 while (cnt > 0) { … … 262 282 263 283 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;277 284 } 278 285 -
uspace/srv/bd/part/guid_part/guid_part.c
r71b0d4d4 r2988aec7 47 47 #include <stdlib.h> 48 48 #include <unistd.h> 49 #include <ipc/bd.h> 49 50 #include <async.h> 50 51 #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;87 85 /** Points to next partition structure. */ 88 86 struct part *next; … … 102 100 static void gpt_pte_to_part(const gpt_entry_t *pte, part_t *part); 103 101 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_blocks120 };121 122 static part_t *bd_srv_part(bd_srv_t *bd)123 {124 return (part_t *)bd->arg;125 }126 105 127 106 int main(int argc, char **argv) … … 325 304 } 326 305 327 bd_srv_init(&part->bd);328 part->bd.ops = &gpt_bd_ops;329 part->bd.arg = part;330 331 306 part->dsid = 0; 332 307 part->next = NULL; … … 335 310 static void gpt_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 336 311 { 312 size_t comm_size; 313 void *fs_va = NULL; 314 ipc_callid_t callid; 315 ipc_call_t call; 316 sysarg_t method; 337 317 service_id_t dh; 318 unsigned int flags; 319 int retval; 320 aoff64_t ba; 321 size_t cnt; 338 322 part_t *part; 339 323 … … 357 341 assert(part->present == true); 358 342 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; 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 } 372 401 } 373 402 374 403 /** Read blocks from partition. */ 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); 404 static int gpt_bd_read(part_t *p, aoff64_t ba, size_t cnt, void *buf) 405 { 379 406 aoff64_t gba; 380 381 if (cnt * block_size < size)382 return EINVAL;383 407 384 408 if (gpt_bsa_translate(p, ba, cnt, &gba) != EOK) … … 389 413 390 414 /** Write blocks to partition. */ 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); 415 static int gpt_bd_write(part_t *p, aoff64_t ba, size_t cnt, const void *buf) 416 { 395 417 aoff64_t gba; 396 397 if (cnt * block_size < size)398 return EINVAL;399 418 400 419 if (gpt_bsa_translate(p, ba, cnt, &gba) != EOK) … … 403 422 return block_write_direct(indev_sid, gba, cnt, buf); 404 423 } 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 422 424 423 425 /** Translate block segment address with range checking. */ -
uspace/srv/bd/part/mbr_part/mbr_part.c
r71b0d4d4 r2988aec7 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> 59 60 #include <async.h> 60 61 #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;104 102 /** Points to next partition structure. */ 105 103 struct part *next; … … 142 140 143 141 /** Partitioned device (inbound device) */ 144 static service_id_t inde v_sid;142 static service_id_t indef_sid; 145 143 146 144 /** List of partitions. This structure is an empty head. */ … … 152 150 static void mbr_pte_to_part(uint32_t base, const pt_entry_t *pte, part_t *part); 153 151 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_blocks170 };171 172 static part_t *bd_srv_part(bd_srv_t *bd)173 {174 return (part_t *)bd->arg;175 }176 155 177 156 int main(int argc, char **argv) … … 204 183 part_t *part; 205 184 206 rc = loc_service_get_id(dev_name, &inde v_sid, 0);185 rc = loc_service_get_id(dev_name, &indef_sid, 0); 207 186 if (rc != EOK) { 208 187 printf(NAME ": could not resolve device `%s'.\n", dev_name); … … 210 189 } 211 190 212 rc = block_init(EXCHANGE_SERIALIZE, inde v_sid, 2048);191 rc = block_init(EXCHANGE_SERIALIZE, indef_sid, 2048); 213 192 if (rc != EOK) { 214 193 printf(NAME ": could not init libblock.\n"); … … 218 197 /* Determine and verify block size. */ 219 198 220 rc = block_get_bsize(inde v_sid, &block_size);199 rc = block_get_bsize(indef_sid, &block_size); 221 200 if (rc != EOK) { 222 201 printf(NAME ": error getting block size.\n"); … … 302 281 */ 303 282 304 rc = block_read_direct(inde v_sid, 0, 1, brb);283 rc = block_read_direct(indef_sid, 0, 1, brb); 305 284 if (rc != EOK) { 306 285 printf(NAME ": Failed reading MBR block.\n"); … … 353 332 */ 354 333 ba = cp.start_addr; 355 rc = block_read_direct(inde v_sid, ba, 1, brb);334 rc = block_read_direct(indef_sid, ba, 1, brb); 356 335 if (rc != EOK) { 357 336 printf(NAME ": Failed reading EBR block at %" … … 402 381 part->present = (pte->ptype != PT_UNUSED) ? true : false; 403 382 404 bd_srv_init(&part->bd);405 part->bd.ops = &mbr_bd_ops;406 part->bd.arg = part;407 408 383 part->dsid = 0; 409 384 part->next = NULL; … … 412 387 static void mbr_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 413 388 { 389 size_t comm_size; 390 void *fs_va = NULL; 391 ipc_callid_t callid; 392 ipc_call_t call; 393 sysarg_t method; 414 394 service_id_t dh; 395 unsigned int flags; 396 int retval; 397 uint64_t ba; 398 size_t cnt; 415 399 part_t *part; 416 400 … … 433 417 434 418 assert(part->present == true); 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; 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 } 448 478 } 449 479 450 480 /** Read blocks from partition. */ 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; 481 static int mbr_bd_read(part_t *p, uint64_t ba, size_t cnt, void *buf) 482 { 483 uint64_t gba; 459 484 460 485 if (mbr_bsa_translate(p, ba, cnt, &gba) != EOK) 461 486 return ELIMIT; 462 487 463 return block_read_direct(inde v_sid, gba, cnt, buf);488 return block_read_direct(indef_sid, gba, cnt, buf); 464 489 } 465 490 466 491 /** Write blocks to partition. */ 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; 492 static int mbr_bd_write(part_t *p, uint64_t ba, size_t cnt, const void *buf) 493 { 494 uint64_t gba; 475 495 476 496 if (mbr_bsa_translate(p, ba, cnt, &gba) != EOK) 477 497 return ELIMIT; 478 498 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; 499 return block_write_direct(indef_sid, gba, cnt, buf); 496 500 } 497 501 -
uspace/srv/bd/rd/rd.c
r71b0d4d4 r2988aec7 43 43 #include <sysinfo.h> 44 44 #include <as.h> 45 #include <bd_srv.h>46 45 #include <ddi.h> 47 46 #include <align.h> … … 54 53 #include <stdio.h> 55 54 #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_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 *); 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); 76 72 77 73 /** This rwlock protects the ramdisk's data. … … 82 78 * 83 79 */ 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; 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 } 112 174 } 113 175 114 176 /** Read blocks from the device. */ 115 static int rd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, void *buf, 116 size_t size) 177 static int rd_read_blocks(uint64_t ba, size_t cnt, void *buf) 117 178 { 118 179 if ((ba + cnt) * block_size > rd_size) { … … 122 183 123 184 fibril_rwlock_read_lock(&rd_lock); 124 memcpy(buf, rd_addr + ba * block_size, min(block_size * cnt, size));185 memcpy(buf, rd_addr + ba * block_size, block_size * cnt); 125 186 fibril_rwlock_read_unlock(&rd_lock); 126 187 … … 129 190 130 191 /** Write blocks to the device. */ 131 static int rd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, 132 const void *buf, size_t size) 192 static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf) 133 193 { 134 194 if ((ba + cnt) * block_size > rd_size) { … … 138 198 139 199 fibril_rwlock_write_lock(&rd_lock); 140 memcpy(rd_addr + ba * block_size, buf, min(block_size * cnt, size));200 memcpy(rd_addr + ba * block_size, buf, block_size * cnt); 141 201 fibril_rwlock_write_unlock(&rd_lock); 142 202 … … 175 235 (void *) addr_phys, size); 176 236 177 bd_srv_init(&bd_srv); 178 bd_srv.ops = &rd_bd_ops; 179 180 async_set_client_connection(rd_client_conn); 237 async_set_client_connection(rd_connection); 181 238 ret = loc_server_register(NAME); 182 239 if (ret != EOK) { … … 197 254 } 198 255 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 213 256 int main(int argc, char **argv) 214 257 { -
uspace/srv/bd/sata_bd/sata_bd.c
r71b0d4d4 r2988aec7 38 38 39 39 #include <sys/types.h> 40 #include <bd_srv.h>41 40 #include <errno.h> 42 41 #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_blocks73 };74 75 static sata_bd_dev_t *bd_srv_sata(bd_srv_t *bd)76 {77 return (sata_bd_dev_t *)bd->arg;78 }79 58 80 59 /** Find SATA devices in device tree. … … 103 82 104 83 ahci_get_num_blocks(disk[disk_count].sess, &disk[disk_count].blocks); 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 84 110 85 printf("Device %s - %s , blocks: %lu, block_size: %lu\n", 111 86 disk[disk_count].dev_name, disk[disk_count].sata_dev_name, … … 166 141 static void sata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 167 142 { 143 void *fs_va = NULL; 144 ipc_callid_t callid; 145 ipc_call_t call; 146 sysarg_t method; 168 147 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; 169 154 int disk_id, i; 170 155 … … 183 168 } 184 169 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 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 } 242 227 243 228 int main(int argc, char **argv) -
uspace/srv/bd/sata_bd/sata_bd.h
r71b0d4d4 r2988aec7 38 38 #define SATA_DEV_NAME_LENGTH 256 39 39 40 #include <async.h> 41 #include <bd_srv.h> 40 #include <sys/types.h> 42 41 #include <loc.h> 43 #include <sys/types.h>44 42 45 43 /** SATA Block Device. */ 46 44 typedef struct { 47 /** Device name in device tree. */ 48 char *dev_name;49 /** SATA Device name. */ 50 char sata_dev_name[SATA_DEV_NAME_LENGTH]; 45 /** Device name in device tree. */ 46 char* dev_name; 47 /** SATA Device name. */ 48 char sata_dev_name[SATA_DEV_NAME_LENGTH]; 51 49 /** Session to device methods. */ 52 async_sess_t *sess;50 async_sess_t* sess; 53 51 /** Loc service id. */ 54 52 service_id_t service_id; 55 53 /** Number of blocks. */ 56 uint64_t blocks; 54 uint64_t blocks; 57 55 /** Size of block. */ 58 size_t block_size; 59 /** Block device server structure */ 60 bd_srv_t bd; 56 size_t block_size; 61 57 } sata_bd_dev_t; 62 58 -
uspace/srv/devman/devman.c
r71b0d4d4 r2988aec7 1052 1052 } 1053 1053 1054 1054 1055 /** Find the device node structure of the device witch has the specified handle. 1055 1056 * … … 1141 1142 fun->state = FUN_INIT; 1142 1143 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);1198 1186 } 1199 1187 -
uspace/srv/devman/devman.h
r71b0d4d4 r2988aec7 174 174 /** State */ 175 175 fun_state_t state; 176 /** Locked while performing reconfiguration operations */177 fibril_mutex_t busy_lock;178 176 179 177 /** The global unique identifier of the function */ … … 281 279 extern void dev_add_ref(dev_node_t *); 282 280 extern void dev_del_ref(dev_node_t *); 283 284 281 extern dev_node_t *find_dev_node_no_lock(dev_tree_t *tree, 285 282 devman_handle_t handle); … … 293 290 extern void fun_add_ref(fun_node_t *); 294 291 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 *);297 292 extern fun_node_t *find_fun_node_no_lock(dev_tree_t *tree, 298 293 devman_handle_t handle); -
uspace/srv/devman/main.c
r71b0d4d4 r2988aec7 432 432 433 433 fun_node_t *fun = create_fun_node(); 434 /* One reference for creation, one for us */435 fun_add_ref(fun);436 434 fun_add_ref(fun); 437 435 fun->ftype = ftype; 438 439 /*440 * We can lock the function here even when holding the tree because441 * we know it cannot be held by anyone else yet.442 */443 fun_busy_lock(fun);444 436 445 437 if (!insert_fun_node(&device_tree, fun, fun_name, pdev)) { 446 438 fibril_rwlock_write_unlock(&tree->rwlock); 447 439 dev_del_ref(pdev); 448 fun_busy_unlock(fun);449 fun_del_ref(fun);450 440 delete_fun_node(fun); 451 441 async_answer_0(callid, ENOMEM); … … 460 450 rc = online_function(fun); 461 451 if (rc != EOK) { 462 /* XXX Set some failed state? */ 463 fun_busy_unlock(fun); 464 fun_del_ref(fun); 452 /* XXX clean up */ 465 453 async_answer_0(callid, rc); 466 454 return; 467 455 } 468 469 fun_busy_unlock(fun);470 fun_del_ref(fun);471 456 472 457 /* Return device handle to parent's driver. */ … … 537 522 } 538 523 539 fun_busy_lock(fun);540 541 524 fibril_rwlock_read_lock(&device_tree.rwlock); 542 525 if (fun->dev == NULL || fun->dev->drv != drv) { 543 526 fibril_rwlock_read_unlock(&device_tree.rwlock); 544 fun_busy_unlock(fun);545 527 fun_del_ref(fun); 546 528 async_answer_0(iid, ENOENT); … … 551 533 rc = online_function(fun); 552 534 if (rc != EOK) { 553 fun_busy_unlock(fun);554 535 fun_del_ref(fun); 555 536 async_answer_0(iid, (sysarg_t) rc); … … 557 538 } 558 539 559 fun_busy_unlock(fun);560 540 fun_del_ref(fun); 561 541 … … 579 559 } 580 560 581 fun_busy_lock(fun);582 583 561 fibril_rwlock_write_lock(&device_tree.rwlock); 584 562 if (fun->dev == NULL || fun->dev->drv != drv) { 585 fun_busy_unlock(fun);586 563 fun_del_ref(fun); 587 564 async_answer_0(iid, ENOENT); … … 592 569 rc = offline_function(fun); 593 570 if (rc != EOK) { 594 fun_busy_unlock(fun);595 571 fun_del_ref(fun); 596 572 async_answer_0(iid, (sysarg_t) rc); … … 598 574 } 599 575 600 fun_busy_unlock(fun);601 576 fun_del_ref(fun); 602 577 async_answer_0(iid, (sysarg_t) EOK); … … 616 591 } 617 592 618 fun_busy_lock(fun);619 620 593 fibril_rwlock_write_lock(&tree->rwlock); 621 594 … … 625 598 if (fun->state == FUN_REMOVED) { 626 599 fibril_rwlock_write_unlock(&tree->rwlock); 627 fun_busy_unlock(fun);628 fun_del_ref(fun);629 600 async_answer_0(callid, ENOENT); 630 601 return; … … 667 638 if (gone_rc == EOK) 668 639 gone_rc = ENOTSUP; 669 fun_busy_unlock(fun);670 fun_del_ref(fun);671 640 async_answer_0(callid, gone_rc); 672 641 return; … … 695 664 "service."); 696 665 fibril_rwlock_write_unlock(&tree->rwlock); 697 fun_busy_unlock(fun);698 666 fun_del_ref(fun); 699 667 async_answer_0(callid, EIO); … … 705 673 remove_fun_node(&device_tree, fun); 706 674 fibril_rwlock_write_unlock(&tree->rwlock); 707 fun_busy_unlock(fun);708 675 709 676 /* Delete ref added when inserting function into tree */ -
uspace/srv/fs/tmpfs/tmpfs_dump.c
r71b0d4d4 r2988aec7 49 49 #define TMPFS_COMM_SIZE 1024 50 50 51 static uint8_t tmpfs_buf[TMPFS_COMM_SIZE];52 53 51 struct rdentry { 54 52 uint8_t type; … … 70 68 uint32_t size; 71 69 72 if (block_seqread(dsid, tmpfs_buf,bufpos, buflen, pos, &entry,70 if (block_seqread(dsid, bufpos, buflen, pos, &entry, 73 71 sizeof(entry)) != EOK) 74 72 return false; … … 90 88 } 91 89 92 if (block_seqread(dsid, tmpfs_buf,bufpos, buflen, pos, fname,90 if (block_seqread(dsid, bufpos, buflen, pos, fname, 93 91 entry.len) != EOK) { 94 92 (void) ops->destroy(fn); … … 106 104 free(fname); 107 105 108 if (block_seqread(dsid, tmpfs_buf,bufpos, buflen, pos, &size,106 if (block_seqread(dsid, bufpos, buflen, pos, &size, 109 107 sizeof(size)) != EOK) 110 108 return false; … … 118 116 119 117 nodep->size = size; 120 if (block_seqread(dsid, tmpfs_buf,bufpos, buflen, pos, nodep->data,118 if (block_seqread(dsid, bufpos, buflen, pos, nodep->data, 121 119 size) != EOK) 122 120 return false; … … 134 132 } 135 133 136 if (block_seqread(dsid, tmpfs_buf,bufpos, buflen, pos, fname,134 if (block_seqread(dsid, bufpos, buflen, pos, fname, 137 135 entry.len) != EOK) { 138 136 (void) ops->destroy(fn); … … 178 176 179 177 char tag[6]; 180 if (block_seqread(dsid, tmpfs_buf,&bufpos, &buflen, &pos, tag, 5) != EOK)178 if (block_seqread(dsid, &bufpos, &buflen, &pos, tag, 5) != EOK) 181 179 goto error; 182 180
Note:
See TracChangeset
for help on using the changeset viewer.