Changes in / [71b0d4d4:2988aec7] in mainline


Ignore:
Files:
38 deleted
37 edited

Legend:

Unmodified
Added
Removed
  • HelenOS.config

    r71b0d4d4 r2988aec7  
    8989@ "tmpfs" TMPFS image
    9090@ "fat" FAT16 image
    91 @ "ext4fs" ext4 image
     91@ "ext2fs" EXT2 image
    9292! RDFMT (choice)
    9393
  • abi/include/syscall.h

    r71b0d4d4 r2988aec7  
    6363        SYS_PAGE_FIND_MAPPING,
    6464       
     65        SYS_IPC_CALL_SYNC_FAST,
     66        SYS_IPC_CALL_SYNC_SLOW,
    6567        SYS_IPC_CALL_ASYNC_FAST,
    6668        SYS_IPC_CALL_ASYNC_SLOW,
  • boot/Makefile

    r71b0d4d4 r2988aec7  
    4747        $(MKFAT) 1048576 $(DIST_PATH) $@
    4848endif
    49 ifeq ($(RDFMT),ext4fs)
    50         $(MKEXT4) 1048576 $(DIST_PATH) $@
     49ifeq ($(RDFMT),ext2fs)
     50        $(MKEXT2) 1048576 $(DIST_PATH) $@
    5151endif
    5252
  • boot/Makefile.common

    r71b0d4d4 r2988aec7  
    5555MKTMPFS = $(TOOLS_PATH)/mktmpfs.py
    5656MKFAT = $(TOOLS_PATH)/mkfat.py
    57 MKEXT4 = $(TOOLS_PATH)/mkext4.py
     57MKEXT2 = $(TOOLS_PATH)/mkext2.py
    5858MKUIMAGE = $(TOOLS_PATH)/mkuimage.py
    5959
     
    8484endif
    8585
    86 ifeq ($(RDFMT),ext4fs)
    87         INIT_TASKS += $(USPACE_PATH)/srv/fs/ext4fs/ext4fs
     86ifeq ($(RDFMT),ext2fs)
     87        INIT_TASKS += $(USPACE_PATH)/srv/fs/ext2fs/ext2fs
    8888endif
    8989
     
    106106        $(USPACE_PATH)/srv/fs/exfat/exfat \
    107107        $(USPACE_PATH)/srv/fs/ext2fs/ext2fs \
    108         $(USPACE_PATH)/srv/fs/ext4fs/ext4fs \
    109108        $(USPACE_PATH)/srv/hid/remcons/remcons \
    110109        $(USPACE_PATH)/srv/net/ethip/ethip \
     
    175174        $(USPACE_PATH)/app/tester/tester \
    176175        $(USPACE_PATH)/app/testread/testread \
    177         $(USPACE_PATH)/app/testwrit/testwrit \
    178176        $(USPACE_PATH)/app/tetris/tetris \
    179177        $(USPACE_PATH)/app/trace/trace \
  • kernel/generic/include/ipc/ipc.h

    r71b0d4d4 r2988aec7  
    7777        waitq_t wq;
    7878       
     79        /** Linkage for the list of task's synchronous answerboxes. */
     80        link_t sync_box_link;
     81       
    7982        /** Phones connected to this answerbox. */
    8083        list_t connected_phones;
     
    113116        struct task *sender;
    114117       
     118        /*
     119         * The caller box is different from sender->answerbox
     120         * for synchronous calls.
     121         */
     122        answerbox_t *callerbox;
     123       
    115124        /** Private data to internal IPC. */
    116125        sysarg_t priv;
     
    138147
    139148extern int ipc_call(phone_t *, call_t *);
     149extern int ipc_call_sync(phone_t *, call_t *);
    140150extern call_t *ipc_wait_for_call(answerbox_t *, uint32_t, unsigned int);
    141151extern int ipc_forward(call_t *, phone_t *, answerbox_t *, unsigned int);
  • kernel/generic/include/ipc/sysipc.h

    r71b0d4d4 r2988aec7  
    4040#include <typedefs.h>
    4141
     42extern sysarg_t sys_ipc_call_sync_fast(sysarg_t, sysarg_t, sysarg_t,
     43    sysarg_t, sysarg_t, ipc_data_t *);
     44extern sysarg_t sys_ipc_call_sync_slow(sysarg_t, ipc_data_t *, ipc_data_t *);
    4245extern sysarg_t sys_ipc_call_async_fast(sysarg_t, sysarg_t, sysarg_t,
    4346    sysarg_t, sysarg_t, sysarg_t);
  • kernel/generic/include/proc/task.h

    r71b0d4d4 r2988aec7  
    9494        phone_t phones[IPC_MAX_PHONES];
    9595        stats_ipc_t ipc_info;   /**< IPC statistics */
     96        list_t sync_boxes;      /**< List of synchronous answerboxes. */
    9697        event_t events[EVENT_TASK_END - EVENT_END];
    9798       
  • kernel/generic/src/ipc/ipc.c

    r71b0d4d4 r2988aec7  
    7171{
    7272        memsetb(call, sizeof(*call), 0);
     73        call->callerbox = &TASK->answerbox;
    7374        call->sender = TASK;
    7475        call->buffer = NULL;
     
    119120        irq_spinlock_initialize(&box->irq_lock, "ipc.box.irqlock");
    120121        waitq_initialize(&box->wq);
     122        link_initialize(&box->sync_box_link);
    121123        list_initialize(&box->connected_phones);
    122124        list_initialize(&box->calls);
     
    161163}
    162164
     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 */
     173int 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
    163208/** Answer a message which was not dispatched and is not listed in any queue.
    164209 *
     
    169214static void _ipc_answer_free_call(call_t *call, bool selflocked)
    170215{
    171         answerbox_t *callerbox = &call->sender->answerbox;
     216        answerbox_t *callerbox = call->callerbox;
    172217        bool do_lock = ((!selflocked) || callerbox != (&TASK->answerbox));
    173218       
     
    561606        ipc_cleanup_call_list(&TASK->answerbox.calls);
    562607        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);
    563622       
    564623        /* Wait for all answers to asynchronous calls to arrive */
  • kernel/generic/src/ipc/sysipc.c

    r71b0d4d4 r2988aec7  
    612612                break;
    613613        }
     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 */
     635sysarg_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 */
     694sysarg_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;
    614733       
    615734        return 0;
  • kernel/generic/src/proc/task.c

    r71b0d4d4 r2988aec7  
    156156       
    157157        list_initialize(&task->threads);
     158        list_initialize(&task->sync_boxes);
    158159       
    159160        ipc_answerbox_init(&task->answerbox, task);
  • kernel/generic/src/syscall/syscall.c

    r71b0d4d4 r2988aec7  
    151151       
    152152        /* IPC related syscalls. */
     153        (syshandler_t) sys_ipc_call_sync_fast,
     154        (syshandler_t) sys_ipc_call_sync_slow,
    153155        (syshandler_t) sys_ipc_call_async_fast,
    154156        (syshandler_t) sys_ipc_call_async_slow,
  • uspace/Makefile

    r71b0d4d4 r2988aec7  
    5959        app/tester \
    6060        app/testread \
    61         app/testwrit \
    6261        app/tetris \
    6362        app/trace \
     
    9998        srv/fs/locfs \
    10099        srv/fs/ext2fs \
    101         srv/fs/ext4fs \
    102100        srv/hid/console \
    103101        srv/hid/s3c24xx_ts \
     
    199197        lib/nic \
    200198        lib/ext2 \
    201         lib/ext4 \
    202199        lib/usb \
    203200        lib/usbhost \
  • uspace/Makefile.common

    r71b0d4d4 r2988aec7  
    115115
    116116LIBEXT2_PREFIX = $(LIB_PREFIX)/ext2
    117 LIBEXT4_PREFIX = $(LIB_PREFIX)/ext4
    118117
    119118LIBUSB_PREFIX = $(LIB_PREFIX)/usb
  • uspace/app/trace/syscalls.c

    r71b0d4d4 r2988aec7  
    5353    [SYS_AS_AREA_DESTROY] = { "as_area_destroy",        1,      V_ERRNO },
    5454
     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 },
    5557    [SYS_IPC_CALL_ASYNC_FAST] = { "ipc_call_async_fast", 6,     V_HASH },
    5658    [SYS_IPC_CALL_ASYNC_SLOW] = { "ipc_call_async_slow", 2,     V_HASH },
  • uspace/app/trace/trace.c

    r71b0d4d4 r2988aec7  
    318318}
    319319
     320static 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
     343static 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
     360static 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
    320377static void sc_ipc_wait(sysarg_t *sc_args, int sc_rc)
    321378{
     
    351408                print_sc_args(sc_args, syscall_desc[sc_id].n_args);
    352409        }
     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        }
    353418}
    354419
     
    382447        case SYS_IPC_CALL_ASYNC_SLOW:
    383448                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);
    384455                break;
    385456        case SYS_IPC_WAIT:
  • uspace/drv/bus/usb/usbmast/main.c

    r71b0d4d4 r2988aec7  
    3737#include <as.h>
    3838#include <async.h>
    39 #include <bd_srv.h>
     39#include <ipc/bd.h>
    4040#include <macros.h>
    4141#include <usb/dev/driver.h>
     
    8181static void usbmast_bd_connection(ipc_callid_t iid, ipc_call_t *icall,
    8282    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_blocks
    98 };
    99 
    100 static usbmast_fun_t *bd_srv_usbmast(bd_srv_t *bd)
    101 {
    102         return (usbmast_fun_t *)bd->arg;
    103 }
    10483
    10584/** Callback when a device is removed from the system.
     
    240219        mfun->lun = lun;
    241220
    242         bd_srv_init(&mfun->bd);
    243         mfun->bd.ops = &usbmast_bd_ops;
    244         mfun->bd.arg = mfun;
    245 
    246221        /* Set up a connection handler. */
    247222        fun->conn_handler = usbmast_bd_connection;
     
    309284{
    310285        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       
    312309        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}
    368346
    369347/** USB mass storage driver ops. */
  • uspace/drv/bus/usb/usbmast/usbmast.h

    r71b0d4d4 r2988aec7  
    3737#define USBMAST_H_
    3838
    39 #include <bd_srv.h>
    4039#include <sys/types.h>
    4140#include <usb/usb.h>
     
    6968        /** Block size in bytes */
    7069        size_t block_size;
    71         /** Block device server structure */
    72         bd_srv_t bd;
    7370} usbmast_fun_t;
    7471
  • uspace/lib/block/libblock.c

    r71b0d4d4 r2988aec7  
    4040#include "../../srv/vfs/vfs.h"
    4141#include <ipc/loc.h>
     42#include <ipc/bd.h>
    4243#include <ipc/services.h>
    4344#include <errno.h>
     
    4647#include <as.h>
    4748#include <assert.h>
    48 #include <bd.h>
    4949#include <fibril_synch.h>
    5050#include <adt/list.h>
     
    8080        service_id_t service_id;
    8181        async_sess_t *sess;
    82         bd_t *bd;
     82        fibril_mutex_t comm_area_lock;
     83        void *comm_area;
     84        size_t comm_size;
    8385        void *bb_buf;
    8486        aoff64_t bb_addr;
     
    8789} devcon_t;
    8890
    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);
     91static int read_blocks(devcon_t *, aoff64_t, size_t);
     92static int write_blocks(devcon_t *, aoff64_t, size_t);
     93static int get_block_size(async_sess_t *, size_t *);
     94static int get_num_blocks(async_sess_t *, aoff64_t *);
    9195static aoff64_t ba_ltop(devcon_t *, aoff64_t);
    9296
     
    108112
    109113static 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)
    111115{
    112116        devcon_t *devcon;
     117       
     118        if (comm_size < bsize)
     119                return EINVAL;
    113120       
    114121        devcon = malloc(sizeof(devcon_t));
     
    119126        devcon->service_id = service_id;
    120127        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;
    122131        devcon->bb_buf = NULL;
    123132        devcon->bb_addr = 0;
     
    149158    size_t comm_size)
    150159{
    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       
    153165        async_sess_t *sess = loc_service_connect(mgmt, service_id,
    154166            IPC_FLAG_BLOCKING);
    155167        if (!sess) {
     168                munmap(comm_area, comm_size);
    156169                return ENOENT;
    157170        }
    158171       
    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       
    160177        if (rc != EOK) {
     178                munmap(comm_area, comm_size);
    161179                async_hangup(sess);
    162180                return rc;
     
    164182       
    165183        size_t bsize;
    166         rc = bd_get_block_size(bd, &bsize);
     184        rc = get_block_size(sess, &bsize);
     185       
    167186        if (rc != EOK) {
    168                 bd_close(bd);
     187                munmap(comm_area, comm_size);
    169188                async_hangup(sess);
    170189                return rc;
    171190        }
    172191       
    173         rc = devcon_add(service_id, sess, bsize, bd);
     192        rc = devcon_add(service_id, sess, bsize, comm_area, comm_size);
    174193        if (rc != EOK) {
    175                 bd_close(bd);
     194                munmap(comm_area, comm_size);
    176195                async_hangup(sess);
    177196                return rc;
     
    194213                free(devcon->bb_buf);
    195214       
    196         bd_close(devcon->bd);
     215        munmap(devcon->comm_area, devcon->comm_size);
    197216        async_hangup(devcon->sess);
    198217       
     
    214233                return ENOMEM;
    215234
    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);
    217237        if (rc != EOK) {
     238                fibril_mutex_unlock(&devcon->comm_area_lock);
    218239                free(bb_buf);
    219240                return rc;
    220241        }
     242        memcpy(bb_buf, devcon->comm_area, devcon->pblock_size);
     243        fibril_mutex_unlock(&devcon->comm_area_lock);
    221244
    222245        devcon->bb_buf = bb_buf;
     
    315338                list_remove(&b->free_link);
    316339                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);
    319342                        if (rc != EOK)
    320343                                return rc;
     
    458481                                list_append(&b->free_link, &cache->free_list);
    459482                                fibril_mutex_unlock(&cache->lock);
     483                                fibril_mutex_lock(&devcon->comm_area_lock);
     484                                memcpy(devcon->comm_area, b->data, b->size);
    460485                                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);
    462488                                if (rc != EOK) {
    463489                                        /*
     
    529555                         * the new contents from the device.
    530556                         */
    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);
    533561                        if (rc != EOK)
    534562                                b->toxic = true;
     
    588616        if (block->dirty && (block->refcnt == 1) &&
    589617            (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);
    592622                block->dirty = false;
    593623        }
     
    658688 *
    659689 * @param service_id    Service ID of the block device.
    660  * @param buf           Buffer for holding one block
    661690 * @param bufpos        Pointer to the first unread valid offset within the
    662691 *                      communication buffer.
     
    670699 * @return              EOK on success or a negative return code on failure.
    671700 */
    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)
     701int block_seqread(service_id_t service_id, size_t *bufpos, size_t *buflen,
     702    aoff64_t *pos, void *dst, size_t size)
    674703{
    675704        size_t offset = 0;
     
    682711        block_size = devcon->pblock_size;
    683712       
     713        fibril_mutex_lock(&devcon->comm_area_lock);
    684714        while (left > 0) {
    685715                size_t rd;
     
    695725                         * destination buffer.
    696726                         */
    697                         memcpy(dst + offset, buf + *bufpos, rd);
     727                        memcpy(dst + offset, devcon->comm_area + *bufpos, rd);
    698728                        offset += rd;
    699729                        *bufpos += rd;
     
    706736                        int rc;
    707737
    708                         rc = read_blocks(devcon, *pos / block_size, 1, buf,
    709                             devcon->pblock_size);
     738                        rc = read_blocks(devcon, *pos / block_size, 1);
    710739                        if (rc != EOK) {
     740                                fibril_mutex_unlock(&devcon->comm_area_lock);
    711741                                return rc;
    712742                        }
     
    716746                }
    717747        }
     748        fibril_mutex_unlock(&devcon->comm_area_lock);
    718749       
    719750        return EOK;
     
    732763{
    733764        devcon_t *devcon;
     765        int rc;
    734766
    735767        devcon = devcon_search(service_id);
    736768        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;
    739779}
    740780
     
    752792{
    753793        devcon_t *devcon;
     794        int rc;
    754795
    755796        devcon = devcon_search(service_id);
    756797        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;
    759807}
    760808
     
    772820        devcon = devcon_search(service_id);
    773821        assert(devcon);
    774 
    775         return bd_get_block_size(devcon->bd, bsize);
     822       
     823        return get_block_size(devcon->sess, bsize);
    776824}
    777825
     
    788836        assert(devcon);
    789837       
    790         return bd_get_num_blocks(devcon->bd, nblocks);
     838        return get_num_blocks(devcon->sess, nblocks);
    791839}
    792840
     
    839887        memcpy(data, buffer + offset, bytes);
    840888        free(buffer);
    841 
     889       
    842890        return EOK;
    843891}
     
    855903{
    856904        devcon_t *devcon = devcon_search(service_id);
     905        assert(devcon);
     906       
    857907        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);
    871926       
    872927        return toc;
     
    882937 * @return              EOK on success or negative error code on failure.
    883938 */
    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);
     939static 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       
    890948        if (rc != EOK) {
    891949                printf("Error %d reading %zu blocks starting at block %" PRIuOFF64
     
    909967 * @return              EOK on success or negative error code on failure.
    910968 */
    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);
     969static 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       
    917978        if (rc != EOK) {
    918979                printf("Error %d writing %zu blocks starting at block %" PRIuOFF64
     
    926987}
    927988
     989/** Get block size used by the device. */
     990static 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. */
     1005static 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
    9281020/** Convert logical block address to physical block address. */
    9291021static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba)
  • uspace/lib/block/libblock.h

    r71b0d4d4 r2988aec7  
    122122extern int block_put(block_t *);
    123123
    124 extern int block_seqread(service_id_t, void *, size_t *, size_t *, aoff64_t *,
    125     void *, size_t);
     124extern int block_seqread(service_id_t, size_t *, size_t *, aoff64_t *, void *,
     125    size_t);
    126126
    127127extern int block_get_bsize(service_id_t, size_t *);
  • uspace/lib/c/Makefile

    r71b0d4d4 r2988aec7  
    6262        generic/ddi.c \
    6363        generic/as.c \
    64         generic/bd.c \
    65         generic/bd_srv.c \
    6664        generic/cap.c \
    6765        generic/cfg.c \
  • uspace/lib/c/generic/async.c

    r71b0d4d4 r2988aec7  
    114114#include <stdlib.h>
    115115#include <macros.h>
    116 #include "private/libc.h"
    117116
    118117#define CLIENT_HASH_TABLE_BUCKETS  32
     
    21672166int async_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags)
    21682167{
    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);
    21712169}
    21722170
     
    22352233int async_share_out_finalize(ipc_callid_t callid, void **dst)
    22362234{
    2237         return ipc_answer_2(callid, EOK, (sysarg_t) __entry, (sysarg_t) dst);
     2235        return ipc_share_out_finalize(callid, dst);
    22382236}
    22392237
     
    23192317int async_data_read_finalize(ipc_callid_t callid, const void *src, size_t size)
    23202318{
    2321         return ipc_answer_2(callid, EOK, (sysarg_t) src, (sysarg_t) size);
     2319        return ipc_data_read_finalize(callid, src, size);
    23222320}
    23232321
     
    24222420int async_data_write_finalize(ipc_callid_t callid, void *dst, size_t size)
    24232421{
    2424         return ipc_answer_2(callid, EOK, (sysarg_t) dst, (sysarg_t) size);
     2422        return ipc_data_write_finalize(callid, dst, size);
    24252423}
    24262424
  • uspace/lib/c/generic/ipc.c

    r71b0d4d4 r2988aec7  
    4848#include <fibril.h>
    4949#include <macros.h>
     50#include "private/libc.h"
    5051
    5152/**
     
    8283
    8384static 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 */
     107int 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 */
     150int 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}
    84182
    85183/** Send asynchronous message via syscall.
     
    513611}
    514612
     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 */
     629int 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 */
     649int 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 */
     670int 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 */
     695int 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
    515707/** Hang up a phone.
    516708 *
     
    566758}
    567759
     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 */
     771int 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 */
     799int 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 */
     814int 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 */
     832int 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 */
     846int 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 */
     866int 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 */
     880int 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 */
     899int 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
    568904/** Connect to a task specified by id.
    569905 *
  • uspace/lib/c/generic/iplink_srv.c

    r71b0d4d4 r2988aec7  
    139139                if (!method) {
    140140                        /* The other side has hung up */
    141                         fibril_mutex_lock(&srv->lock);
    142                         srv->connected = false;
    143                         fibril_mutex_unlock(&srv->lock);
    144141                        async_answer_0(callid, EOK);
    145142                        break;
  • uspace/lib/c/include/ipc/ipc.h

    r71b0d4d4 r2988aec7  
    4848typedef void (*ipc_async_callback_t)(void *, int, ipc_call_t *);
    4949
     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
     179extern 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
     182extern 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
    50186extern ipc_callid_t ipc_wait_cycle(ipc_call_t *, sysarg_t, unsigned int);
    51187extern void ipc_poke(void);
     
    118254    sysarg_t, sysarg_t, void *, ipc_async_callback_t, bool);
    119255
     256extern int ipc_clone_establish(int);
     257extern int ipc_connect_to_me(int, sysarg_t, sysarg_t, sysarg_t, task_id_t *,
     258    sysarg_t *);
     259extern int ipc_connect_me_to(int, sysarg_t, sysarg_t, sysarg_t);
     260extern int ipc_connect_me_to_blocking(int, sysarg_t, sysarg_t, sysarg_t);
     261
    120262extern int ipc_hangup(int);
    121263
     
    125267    sysarg_t, sysarg_t, sysarg_t, unsigned int);
    126268
     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
     282extern int ipc_share_in_start(int, size_t, sysarg_t, unsigned int *, void **);
     283extern int ipc_share_in_finalize(ipc_callid_t, void *, unsigned int);
     284extern int ipc_share_out_start(int, void *, unsigned int);
     285extern int ipc_share_out_finalize(ipc_callid_t, void **);
     286extern int ipc_data_read_start(int, void *, size_t);
     287extern int ipc_data_read_finalize(ipc_callid_t, const void *, size_t);
     288extern int ipc_data_write_start(int, const void *, size_t);
     289extern int ipc_data_write_finalize(ipc_callid_t, void *, size_t);
     290
    127291extern int ipc_connect_kbox(task_id_t);
    128292
  • uspace/srv/bd/ata_bd/ata_bd.c

    r71b0d4d4 r2988aec7  
    5151#include <libarch/ddi.h>
    5252#include <ddi.h>
     53#include <ipc/bd.h>
    5354#include <async.h>
    5455#include <as.h>
    55 #include <bd_srv.h>
    5656#include <fibril_synch.h>
    5757#include <stdint.h>
     
    9898
    9999/** Per-disk state. */
    100 static disk_t ata_disk[MAX_DISKS];
     100static disk_t disk[MAX_DISKS];
    101101
    102102static void print_syntax(void);
    103103static int ata_bd_init(void);
    104104static 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 
     105static int ata_bd_read_blocks(int disk_id, uint64_t ba, size_t cnt,
     106    void *buf);
     107static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt,
     108    const void *buf);
    116109static int ata_rcmd_read(int disk_id, uint64_t ba, size_t cnt,
    117110    void *buf);
     
    134127    unsigned timeout);
    135128
    136 static bd_ops_t ata_bd_ops = {
    137         .open = ata_bd_open,
    138         .close = ata_bd_close,
    139         .read_blocks = ata_bd_read_blocks,
    140         .read_toc = ata_bd_read_toc,
    141         .write_blocks = ata_bd_write_blocks,
    142         .get_block_size = ata_bd_get_block_size,
    143         .get_num_blocks = ata_bd_get_num_blocks
    144 };
    145 
    146 static disk_t *bd_srv_disk(bd_srv_t *bd)
    147 {
    148         return (disk_t *)bd->arg;
    149 }
    150 
    151129int main(int argc, char **argv)
    152130{
     
    183161                fflush(stdout);
    184162
    185                 rc = disk_init(&ata_disk[i], i);
     163                rc = disk_init(&disk[i], i);
    186164
    187165                if (rc == EOK) {
    188                         disk_print_summary(&ata_disk[i]);
     166                        disk_print_summary(&disk[i]);
    189167                } else {
    190168                        printf("Not found.\n");
     
    196174        for (i = 0; i < MAX_DISKS; i++) {
    197175                /* Skip unattached drives. */
    198                 if (ata_disk[i].present == false)
     176                if (disk[i].present == false)
    199177                        continue;
    200178               
    201179                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);
    203181                if (rc != EOK) {
    204182                        printf(NAME ": Unable to register device %s.\n", name);
     
    239217                case am_chs:
    240218                        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);
    243221                        break;
    244222                case am_lba28:
     
    295273static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    296274{
     275        void *fs_va = NULL;
     276        ipc_callid_t callid;
     277        ipc_call_t call;
     278        sysarg_t method;
    297279        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;
    298285        int disk_id, i;
    299286
     
    304291        disk_id = -1;
    305292        for (i = 0; i < MAX_DISKS; i++)
    306                 if (ata_disk[i].service_id == dsid)
     293                if (disk[i].service_id == dsid)
    307294                        disk_id = i;
    308295
    309         if (disk_id < 0 || ata_disk[disk_id].present == false) {
     296        if (disk_id < 0 || disk[disk_id].present == false) {
    310297                async_answer_0(iid, EINVAL);
    311298                return;
    312299        }
    313300
    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        }
    315367}
    316368
     
    332384        unsigned i;
    333385
    334         d->disk_id = disk_id;
    335386        d->present = false;
    336387        fibril_mutex_initialize(&d->lock);
    337 
    338         bd_srv_init(&d->bd);
    339         d->bd.ops = &ata_bd_ops;
    340         d->bd.arg = d;
    341388
    342389        /* Try identify command. */
     
    467514}
    468515
    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 
    479516/** 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);
     517static int ata_bd_read_blocks(int disk_id, uint64_t ba, size_t cnt,
     518    void *buf) {
     519
    484520        int rc;
    485521
    486         if (size < cnt * disk->block_size)
    487                 return EINVAL;
    488 
    489522        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);
    492525                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);
    495528
    496529                if (rc != EOK)
     
    499532                ++ba;
    500533                --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;
    513538}
    514539
    515540/** 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);
     541static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt,
     542    const void *buf) {
     543
    520544        int rc;
    521545
    522         if (disk->dev_type != ata_reg_dev)
     546        if (disk[disk_id].dev_type != ata_reg_dev)
    523547                return ENOTSUP;
    524548
    525         if (size < cnt * disk->block_size)
    526                 return EINVAL;
    527 
    528549        while (cnt > 0) {
    529                 rc = ata_rcmd_write(disk->disk_id, ba, 1, buf);
     550                rc = ata_rcmd_write(disk_id, ba, 1, buf);
    530551                if (rc != EOK)
    531552                        return rc;
     
    533554                ++ba;
    534555                --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
    556559        return EOK;
    557560}
     
    682685        uint16_t val;
    683686
    684         d = &ata_disk[dev_idx];
     687        d = &disk[dev_idx];
    685688        fibril_mutex_lock(&d->lock);
    686689
     
    871874        block_coord_t bc;
    872875
    873         d = &ata_disk[disk_id];
     876        d = &disk[disk_id];
    874877       
    875878        /* Silence warning. */
     
    916919                /* Read data from the device buffer. */
    917920
    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++) {
    919922                        data = pio_read_16(&cmd->data_port);
    920923                        ((uint16_t *) buf)[i] = data;
     
    947950        block_coord_t bc;
    948951
    949         d = &ata_disk[disk_id];
     952        d = &disk[disk_id];
    950953       
    951954        /* Silence warning. */
     
    992995                /* Write data to the device buffer. */
    993996
    994                 for (i = 0; i < d->block_size / 2; i++) {
     997                for (i = 0; i < disk[disk_id].block_size / 2; i++) {
    995998                        pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]);
    996999                }
  • uspace/srv/bd/ata_bd/ata_bd.h

    r71b0d4d4 r2988aec7  
    3636#define __ATA_BD_H__
    3737
    38 #include <bd_srv.h>
    3938#include <sys/types.h>
    4039#include <fibril_synch.h>
     
    118117        fibril_mutex_t lock;
    119118        service_id_t service_id;
    120         int disk_id;
    121         bd_srv_t bd;
    122119} disk_t;
    123120
  • uspace/srv/bd/file_bd/file_bd.c

    r71b0d4d4 r2988aec7  
    4141#include <stdio.h>
    4242#include <unistd.h>
     43#include <ipc/bd.h>
    4344#include <async.h>
    4445#include <as.h>
    45 #include <bd_srv.h>
    4646#include <fibril_synch.h>
    4747#include <loc.h>
     
    6262
    6363static service_id_t service_id;
    64 static bd_srv_t bd_srv;
    6564static fibril_mutex_t dev_lock;
    6665
     
    6867static int file_bd_init(const char *fname);
    6968static 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 };
     69static int file_bd_read_blocks(uint64_t ba, size_t cnt, void *buf);
     70static int file_bd_write_blocks(uint64_t ba, size_t cnt, const void *buf);
    8671
    8772int main(int argc, char **argv)
     
    154139static int file_bd_init(const char *fname)
    155140{
    156         bd_srv_init(&bd_srv);
    157         bd_srv.ops = &file_bd_ops;
    158        
    159141        async_set_client_connection(file_bd_connection);
    160142        int rc = loc_server_register(NAME);
     
    188170static void file_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    189171{
    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        }
    203240}
    204241
    205242/** 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)
     243static int file_bd_read_blocks(uint64_t ba, size_t cnt, void *buf)
    208244{
    209245        size_t n_rd;
    210246        int rc;
    211 
    212         if (size < cnt * block_size)
    213                 return EINVAL;
    214247
    215248        /* Check whether access is within device address bounds. */
     
    246279
    247280/** 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)
     281static int file_bd_write_blocks(uint64_t ba, size_t cnt, const void *buf)
    250282{
    251283        size_t n_wr;
    252284        int rc;
    253 
    254         if (size < cnt * block_size)
    255                 return EINVAL;
    256285
    257286        /* Check whether access is within device address bounds. */
     
    289318}
    290319
    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 
    305320/**
    306321 * @}
  • uspace/srv/bd/gxe_bd/gxe_bd.c

    r71b0d4d4 r2988aec7  
    3939#include <libarch/ddi.h>
    4040#include <ddi.h>
     41#include <ipc/bd.h>
    4142#include <async.h>
    4243#include <as.h>
    43 #include <bd_srv.h>
    4444#include <fibril_synch.h>
    4545#include <loc.h>
     
    6565};
    6666
    67 /** GXE disk hardware registers */
    6867typedef struct {
    6968        uint32_t offset_lo;
     
    8483
    8584        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;
    9385} gxe_bd_t;
    9486
     87
    9588static const size_t block_size = 512;
     89static size_t comm_size;
    9690
    9791static uintptr_t dev_physical = 0x13000000;
    98 static gxe_bd_hw_t *dev;
     92static gxe_bd_t *dev;
    9993
    10094static service_id_t service_id[MAX_DISKS];
    10195
    10296static fibril_mutex_t dev_lock[MAX_DISKS];
    103 
    104 static gxe_bd_t gxe_bd[MAX_DISKS];
    10597
    10698static int gxe_bd_init(void);
    10799static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *);
     100static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt,
     101    void *buf);
     102static int gxe_bd_write_blocks(int disk_id, uint64_t ba, unsigned cnt,
     103    const void *buf);
    108104static int gxe_bd_read_block(int disk_id, uint64_t ba, void *buf);
    109105static int gxe_bd_write_block(int disk_id, uint64_t ba, const void *buf);
    110 
    111 static int gxe_bd_open(bd_srv_t *);
    112 static int gxe_bd_close(bd_srv_t *);
    113 static int gxe_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
    114 static int gxe_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t);
    115 static int gxe_bd_get_block_size(bd_srv_t *, size_t *);
    116 static int gxe_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
    117 
    118 static bd_ops_t gxe_bd_ops = {
    119         .open = gxe_bd_open,
    120         .close = gxe_bd_close,
    121         .read_blocks = gxe_bd_read_blocks,
    122         .write_blocks = gxe_bd_write_blocks,
    123         .get_block_size = gxe_bd_get_block_size,
    124         .get_num_blocks = gxe_bd_get_num_blocks
    125 };
    126 
    127 static gxe_bd_t *bd_srv_gxe(bd_srv_t *bd)
    128 {
    129         return (gxe_bd_t *)bd->arg;
    130 }
    131106
    132107int main(int argc, char **argv)
     
    155130       
    156131        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);
    158133        if (rc != EOK) {
    159134                printf("%s: Could not initialize device I/O space.\n", NAME);
     
    165140        for (unsigned int i = 0; i < MAX_DISKS; i++) {
    166141                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];
    171142               
    172143                snprintf(name, 16, "%s/disk%u", NAMESPACE, i);
     
    186157static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    187158{
     159        void *fs_va = NULL;
     160        ipc_callid_t callid;
     161        ipc_call_t call;
     162        sysarg_t method;
    188163        service_id_t dsid;
     164        unsigned int flags;
     165        int retval;
     166        uint64_t ba;
     167        unsigned cnt;
    189168        int disk_id, i;
    190169
     
    203182        }
    204183
    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        }
    218246}
    219247
    220248/** 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;
     249static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt,
     250    void *buf) {
     251
    225252        int rc;
    226 
    227         if (size < cnt * block_size)
    228                 return EINVAL;
    229253
    230254        while (cnt > 0) {
     
    242266
    243267/** 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;
     268static int gxe_bd_write_blocks(int disk_id, uint64_t ba, unsigned cnt,
     269    const void *buf) {
     270
    248271        int rc;
    249 
    250         if (size < cnt * block_size)
    251                 return EINVAL;
    252272
    253273        while (cnt > 0) {
     
    262282
    263283        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;
    277284}
    278285
  • uspace/srv/bd/part/guid_part/guid_part.c

    r71b0d4d4 r2988aec7  
    4747#include <stdlib.h>
    4848#include <unistd.h>
     49#include <ipc/bd.h>
    4950#include <async.h>
    5051#include <as.h>
    51 #include <bd_srv.h>
    5252#include <fibril_synch.h>
    5353#include <loc.h>
     
    8383        /** Service representing the partition (outbound device) */
    8484        service_id_t dsid;
    85         /** Block device server structure */
    86         bd_srv_t bd;
    8785        /** Points to next partition structure. */
    8886        struct part *next;
     
    102100static void gpt_pte_to_part(const gpt_entry_t *pte, part_t *part);
    103101static void gpt_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);
     102static int gpt_bd_read(part_t *p, aoff64_t ba, size_t cnt, void *buf);
     103static int gpt_bd_write(part_t *p, aoff64_t ba, size_t cnt, const void *buf);
    104104static int gpt_bsa_translate(part_t *p, aoff64_t ba, size_t cnt, aoff64_t *gba);
    105 
    106 static int gpt_bd_open(bd_srv_t *);
    107 static int gpt_bd_close(bd_srv_t *);
    108 static int gpt_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
    109 static int gpt_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t);
    110 static int gpt_bd_get_block_size(bd_srv_t *, size_t *);
    111 static int gpt_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
    112 
    113 static bd_ops_t gpt_bd_ops = {
    114         .open = gpt_bd_open,
    115         .close = gpt_bd_close,
    116         .read_blocks = gpt_bd_read_blocks,
    117         .write_blocks = gpt_bd_write_blocks,
    118         .get_block_size = gpt_bd_get_block_size,
    119         .get_num_blocks = gpt_bd_get_num_blocks
    120 };
    121 
    122 static part_t *bd_srv_part(bd_srv_t *bd)
    123 {
    124         return (part_t *)bd->arg;
    125 }
    126105
    127106int main(int argc, char **argv)
     
    325304        }
    326305
    327         bd_srv_init(&part->bd);
    328         part->bd.ops = &gpt_bd_ops;
    329         part->bd.arg = part;
    330 
    331306        part->dsid = 0;
    332307        part->next = NULL;
     
    335310static void gpt_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    336311{
     312        size_t comm_size;
     313        void *fs_va = NULL;
     314        ipc_callid_t callid;
     315        ipc_call_t call;
     316        sysarg_t method;
    337317        service_id_t dh;
     318        unsigned int flags;
     319        int retval;
     320        aoff64_t ba;
     321        size_t cnt;
    338322        part_t *part;
    339323
     
    357341        assert(part->present == true);
    358342
    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        }
    372401}
    373402
    374403/** 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);
     404static int gpt_bd_read(part_t *p, aoff64_t ba, size_t cnt, void *buf)
     405{
    379406        aoff64_t gba;
    380 
    381         if (cnt * block_size < size)
    382                 return EINVAL;
    383407
    384408        if (gpt_bsa_translate(p, ba, cnt, &gba) != EOK)
     
    389413
    390414/** 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);
     415static int gpt_bd_write(part_t *p, aoff64_t ba, size_t cnt, const void *buf)
     416{
    395417        aoff64_t gba;
    396 
    397         if (cnt * block_size < size)
    398                 return EINVAL;
    399418
    400419        if (gpt_bsa_translate(p, ba, cnt, &gba) != EOK)
     
    403422        return block_write_direct(indev_sid, gba, cnt, buf);
    404423}
    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 
    422424
    423425/** Translate block segment address with range checking. */
  • uspace/srv/bd/part/mbr_part/mbr_part.c

    r71b0d4d4 r2988aec7  
    4444 *
    4545 * Referemces:
    46  *
     46 *     
    4747 * The source of MBR structures for this driver have been the following
    4848 * Wikipedia articles:
     
    5757#include <stdlib.h>
    5858#include <unistd.h>
     59#include <ipc/bd.h>
    5960#include <async.h>
    6061#include <as.h>
    61 #include <bd_srv.h>
    6262#include <fibril_synch.h>
    6363#include <loc.h>
     
    100100        /** Device representing the partition (outbound device) */
    101101        service_id_t dsid;
    102         /** Block device server structure */
    103         bd_srv_t bd;
    104102        /** Points to next partition structure. */
    105103        struct part *next;
     
    142140
    143141/** Partitioned device (inbound device) */
    144 static service_id_t indev_sid;
     142static service_id_t indef_sid;
    145143
    146144/** List of partitions. This structure is an empty head. */
     
    152150static void mbr_pte_to_part(uint32_t base, const pt_entry_t *pte, part_t *part);
    153151static void mbr_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);
     152static int mbr_bd_read(part_t *p, uint64_t ba, size_t cnt, void *buf);
     153static int mbr_bd_write(part_t *p, uint64_t ba, size_t cnt, const void *buf);
    154154static int mbr_bsa_translate(part_t *p, uint64_t ba, size_t cnt, uint64_t *gba);
    155 
    156 static int mbr_bd_open(bd_srv_t *);
    157 static int mbr_bd_close(bd_srv_t *);
    158 static int mbr_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
    159 static int mbr_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t);
    160 static int mbr_bd_get_block_size(bd_srv_t *, size_t *);
    161 static int mbr_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
    162 
    163 static bd_ops_t mbr_bd_ops = {
    164         .open = mbr_bd_open,
    165         .close = mbr_bd_close,
    166         .read_blocks = mbr_bd_read_blocks,
    167         .write_blocks = mbr_bd_write_blocks,
    168         .get_block_size = mbr_bd_get_block_size,
    169         .get_num_blocks = mbr_bd_get_num_blocks
    170 };
    171 
    172 static part_t *bd_srv_part(bd_srv_t *bd)
    173 {
    174         return (part_t *)bd->arg;
    175 }
    176155
    177156int main(int argc, char **argv)
     
    204183        part_t *part;
    205184
    206         rc = loc_service_get_id(dev_name, &indev_sid, 0);
     185        rc = loc_service_get_id(dev_name, &indef_sid, 0);
    207186        if (rc != EOK) {
    208187                printf(NAME ": could not resolve device `%s'.\n", dev_name);
     
    210189        }
    211190
    212         rc = block_init(EXCHANGE_SERIALIZE, indev_sid, 2048);
     191        rc = block_init(EXCHANGE_SERIALIZE, indef_sid, 2048);
    213192        if (rc != EOK)  {
    214193                printf(NAME ": could not init libblock.\n");
     
    218197        /* Determine and verify block size. */
    219198
    220         rc = block_get_bsize(indev_sid, &block_size);
     199        rc = block_get_bsize(indef_sid, &block_size);
    221200        if (rc != EOK) {
    222201                printf(NAME ": error getting block size.\n");
     
    302281         */
    303282
    304         rc = block_read_direct(indev_sid, 0, 1, brb);
     283        rc = block_read_direct(indef_sid, 0, 1, brb);
    305284        if (rc != EOK) {
    306285                printf(NAME ": Failed reading MBR block.\n");
     
    353332                 */
    354333                ba = cp.start_addr;
    355                 rc = block_read_direct(indev_sid, ba, 1, brb);
     334                rc = block_read_direct(indef_sid, ba, 1, brb);
    356335                if (rc != EOK) {
    357336                        printf(NAME ": Failed reading EBR block at %"
     
    402381        part->present = (pte->ptype != PT_UNUSED) ? true : false;
    403382
    404         bd_srv_init(&part->bd);
    405         part->bd.ops = &mbr_bd_ops;
    406         part->bd.arg = part;
    407 
    408383        part->dsid = 0;
    409384        part->next = NULL;
     
    412387static void mbr_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    413388{
     389        size_t comm_size;
     390        void *fs_va = NULL;
     391        ipc_callid_t callid;
     392        ipc_call_t call;
     393        sysarg_t method;
    414394        service_id_t dh;
     395        unsigned int flags;
     396        int retval;
     397        uint64_t ba;
     398        size_t cnt;
    415399        part_t *part;
    416400
     
    433417
    434418        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        }
    448478}
    449479
    450480/** 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;
     481static int mbr_bd_read(part_t *p, uint64_t ba, size_t cnt, void *buf)
     482{
     483        uint64_t gba;
    459484
    460485        if (mbr_bsa_translate(p, ba, cnt, &gba) != EOK)
    461486                return ELIMIT;
    462487
    463         return block_read_direct(indev_sid, gba, cnt, buf);
     488        return block_read_direct(indef_sid, gba, cnt, buf);
    464489}
    465490
    466491/** 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;
     492static int mbr_bd_write(part_t *p, uint64_t ba, size_t cnt, const void *buf)
     493{
     494        uint64_t gba;
    475495
    476496        if (mbr_bsa_translate(p, ba, cnt, &gba) != EOK)
    477497                return ELIMIT;
    478498
    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);
    496500}
    497501
  • uspace/srv/bd/rd/rd.c

    r71b0d4d4 r2988aec7  
    4343#include <sysinfo.h>
    4444#include <as.h>
    45 #include <bd_srv.h>
    4645#include <ddi.h>
    4746#include <align.h>
     
    5453#include <stdio.h>
    5554#include <loc.h>
     55#include <ipc/bd.h>
    5656#include <macros.h>
    5757#include <inttypes.h>
     
    6868static const size_t block_size = 512;
    6969
    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 *);
     70static int rd_read_blocks(uint64_t ba, size_t cnt, void *buf);
     71static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf);
    7672
    7773/** This rwlock protects the ramdisk's data.
     
    8278 *
    8379 */
    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;
     80fibril_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 */
     87static 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        }
    112174}
    113175
    114176/** 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)
     177static int rd_read_blocks(uint64_t ba, size_t cnt, void *buf)
    117178{
    118179        if ((ba + cnt) * block_size > rd_size) {
     
    122183       
    123184        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);
    125186        fibril_rwlock_read_unlock(&rd_lock);
    126187       
     
    129190
    130191/** 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)
     192static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf)
    133193{
    134194        if ((ba + cnt) * block_size > rd_size) {
     
    138198       
    139199        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);
    141201        fibril_rwlock_write_unlock(&rd_lock);
    142202       
     
    175235            (void *) addr_phys, size);
    176236       
    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);
    181238        ret = loc_server_register(NAME);
    182239        if (ret != EOK) {
     
    197254}
    198255
    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 
    213256int main(int argc, char **argv)
    214257{
  • uspace/srv/bd/sata_bd/sata_bd.c

    r71b0d4d4 r2988aec7  
    3838
    3939#include <sys/types.h>
    40 #include <bd_srv.h>
    4140#include <errno.h>
    4241#include <stdio.h>
     42#include <ipc/bd.h>
    4343#include <str.h>
    4444#include <loc.h>
     
    5656static sata_bd_dev_t disk[MAXDISKS];
    5757static int disk_count;
    58 
    59 static int sata_bd_open(bd_srv_t *);
    60 static int sata_bd_close(bd_srv_t *);
    61 static int sata_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
    62 static int sata_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t);
    63 static int sata_bd_get_block_size(bd_srv_t *, size_t *);
    64 static int sata_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
    65 
    66 static bd_ops_t sata_bd_ops = {
    67         .open = sata_bd_open,
    68         .close = sata_bd_close,
    69         .read_blocks = sata_bd_read_blocks,
    70         .write_blocks = sata_bd_write_blocks,
    71         .get_block_size = sata_bd_get_block_size,
    72         .get_num_blocks = sata_bd_get_num_blocks
    73 };
    74 
    75 static sata_bd_dev_t *bd_srv_sata(bd_srv_t *bd)
    76 {
    77         return (sata_bd_dev_t *)bd->arg;
    78 }
    7958
    8059/** Find SATA devices in device tree.
     
    10382               
    10483                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                               
    11085                printf("Device %s - %s , blocks: %lu, block_size: %lu\n",
    11186                    disk[disk_count].dev_name, disk[disk_count].sata_dev_name,
     
    166141static void sata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    167142{
     143        void *fs_va = NULL;
     144        ipc_callid_t callid;
     145        ipc_call_t call;
     146        sysarg_t method;
    168147        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;
    169154        int disk_id, i;
    170155
     
    183168        }
    184169
    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}
    242227
    243228int main(int argc, char **argv)
  • uspace/srv/bd/sata_bd/sata_bd.h

    r71b0d4d4 r2988aec7  
    3838#define SATA_DEV_NAME_LENGTH 256
    3939
    40 #include <async.h>
    41 #include <bd_srv.h>
     40#include <sys/types.h>
    4241#include <loc.h>
    43 #include <sys/types.h>
    4442
    4543/** SATA Block Device. */
    4644typedef 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]; 
    5149        /** Session to device methods. */
    52         async_sess_t *sess;
     50        async_sess_t* sess;
    5351        /** Loc service id. */
    5452        service_id_t service_id;
    5553        /** Number of blocks. */
    56         uint64_t blocks;
     54        uint64_t blocks; 
    5755        /** Size of block. */
    58         size_t block_size;
    59         /** Block device server structure */
    60         bd_srv_t bd;
     56        size_t block_size;
    6157} sata_bd_dev_t;
    6258
  • uspace/srv/devman/devman.c

    r71b0d4d4 r2988aec7  
    10521052}
    10531053
     1054
    10541055/** Find the device node structure of the device witch has the specified handle.
    10551056 *
     
    11411142        fun->state = FUN_INIT;
    11421143        atomic_set(&fun->refcnt, 0);
    1143         fibril_mutex_initialize(&fun->busy_lock);
    11441144        link_initialize(&fun->dev_functions);
    11451145        list_initialize(&fun->match_ids.ids);
     
    11841184        if (atomic_predec(&fun->refcnt) == 0)
    11851185                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);
    11981186}
    11991187
  • uspace/srv/devman/devman.h

    r71b0d4d4 r2988aec7  
    174174        /** State */
    175175        fun_state_t state;
    176         /** Locked while performing reconfiguration operations */
    177         fibril_mutex_t busy_lock;
    178176       
    179177        /** The global unique identifier of the function */
     
    281279extern void dev_add_ref(dev_node_t *);
    282280extern void dev_del_ref(dev_node_t *);
    283 
    284281extern dev_node_t *find_dev_node_no_lock(dev_tree_t *tree,
    285282    devman_handle_t handle);
     
    293290extern void fun_add_ref(fun_node_t *);
    294291extern 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 *);
    297292extern fun_node_t *find_fun_node_no_lock(dev_tree_t *tree,
    298293    devman_handle_t handle);
  • uspace/srv/devman/main.c

    r71b0d4d4 r2988aec7  
    432432       
    433433        fun_node_t *fun = create_fun_node();
    434         /* One reference for creation, one for us */
    435         fun_add_ref(fun);
    436434        fun_add_ref(fun);
    437435        fun->ftype = ftype;
    438        
    439         /*
    440          * We can lock the function here even when holding the tree because
    441          * we know it cannot be held by anyone else yet.
    442          */
    443         fun_busy_lock(fun);
    444436       
    445437        if (!insert_fun_node(&device_tree, fun, fun_name, pdev)) {
    446438                fibril_rwlock_write_unlock(&tree->rwlock);
    447439                dev_del_ref(pdev);
    448                 fun_busy_unlock(fun);
    449                 fun_del_ref(fun);
    450440                delete_fun_node(fun);
    451441                async_answer_0(callid, ENOMEM);
     
    460450        rc = online_function(fun);
    461451        if (rc != EOK) {
    462                 /* XXX Set some failed state? */
    463                 fun_busy_unlock(fun);
    464                 fun_del_ref(fun);
     452                /* XXX clean up */
    465453                async_answer_0(callid, rc);
    466454                return;
    467455        }
    468        
    469         fun_busy_unlock(fun);
    470         fun_del_ref(fun);
    471456       
    472457        /* Return device handle to parent's driver. */
     
    537522        }
    538523       
    539         fun_busy_lock(fun);
    540        
    541524        fibril_rwlock_read_lock(&device_tree.rwlock);
    542525        if (fun->dev == NULL || fun->dev->drv != drv) {
    543526                fibril_rwlock_read_unlock(&device_tree.rwlock);
    544                 fun_busy_unlock(fun);
    545527                fun_del_ref(fun);
    546528                async_answer_0(iid, ENOENT);
     
    551533        rc = online_function(fun);
    552534        if (rc != EOK) {
    553                 fun_busy_unlock(fun);
    554535                fun_del_ref(fun);
    555536                async_answer_0(iid, (sysarg_t) rc);
     
    557538        }
    558539       
    559         fun_busy_unlock(fun);
    560540        fun_del_ref(fun);
    561541       
     
    579559        }
    580560       
    581         fun_busy_lock(fun);
    582        
    583561        fibril_rwlock_write_lock(&device_tree.rwlock);
    584562        if (fun->dev == NULL || fun->dev->drv != drv) {
    585                 fun_busy_unlock(fun);
    586563                fun_del_ref(fun);
    587564                async_answer_0(iid, ENOENT);
     
    592569        rc = offline_function(fun);
    593570        if (rc != EOK) {
    594                 fun_busy_unlock(fun);
    595571                fun_del_ref(fun);
    596572                async_answer_0(iid, (sysarg_t) rc);
     
    598574        }
    599575       
    600         fun_busy_unlock(fun);
    601576        fun_del_ref(fun);
    602577        async_answer_0(iid, (sysarg_t) EOK);
     
    616591        }
    617592       
    618         fun_busy_lock(fun);
    619        
    620593        fibril_rwlock_write_lock(&tree->rwlock);
    621594       
     
    625598        if (fun->state == FUN_REMOVED) {
    626599                fibril_rwlock_write_unlock(&tree->rwlock);
    627                 fun_busy_unlock(fun);
    628                 fun_del_ref(fun);
    629600                async_answer_0(callid, ENOENT);
    630601                return;
     
    667638                                if (gone_rc == EOK)
    668639                                        gone_rc = ENOTSUP;
    669                                 fun_busy_unlock(fun);
    670                                 fun_del_ref(fun);
    671640                                async_answer_0(callid, gone_rc);
    672641                                return;
     
    695664                                    "service.");
    696665                                fibril_rwlock_write_unlock(&tree->rwlock);
    697                                 fun_busy_unlock(fun);
    698666                                fun_del_ref(fun);
    699667                                async_answer_0(callid, EIO);
     
    705673        remove_fun_node(&device_tree, fun);
    706674        fibril_rwlock_write_unlock(&tree->rwlock);
    707         fun_busy_unlock(fun);
    708675       
    709676        /* Delete ref added when inserting function into tree */
  • uspace/srv/fs/tmpfs/tmpfs_dump.c

    r71b0d4d4 r2988aec7  
    4949#define TMPFS_COMM_SIZE         1024
    5050
    51 static uint8_t tmpfs_buf[TMPFS_COMM_SIZE];
    52 
    5351struct rdentry {
    5452        uint8_t type;
     
    7068                uint32_t size;
    7169               
    72                 if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, &entry,
     70                if (block_seqread(dsid, bufpos, buflen, pos, &entry,
    7371                    sizeof(entry)) != EOK)
    7472                        return false;
     
    9088                        }
    9189                       
    92                         if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, fname,
     90                        if (block_seqread(dsid, bufpos, buflen, pos, fname,
    9391                            entry.len) != EOK) {
    9492                                (void) ops->destroy(fn);
     
    106104                        free(fname);
    107105                       
    108                         if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, &size,
     106                        if (block_seqread(dsid, bufpos, buflen, pos, &size,
    109107                            sizeof(size)) != EOK)
    110108                                return false;
     
    118116                       
    119117                        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,
    121119                            size) != EOK)
    122120                                return false;
     
    134132                        }
    135133                       
    136                         if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, fname,
     134                        if (block_seqread(dsid, bufpos, buflen, pos, fname,
    137135                            entry.len) != EOK) {
    138136                                (void) ops->destroy(fn);
     
    178176       
    179177        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)
    181179                goto error;
    182180       
Note: See TracChangeset for help on using the changeset viewer.