Changes in / [f66ca57f:affaf2e] in mainline


Ignore:
Files:
38 added
37 edited

Legend:

Unmodified
Added
Removed
  • HelenOS.config

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

    rf66ca57f raffaf2e  
    6363        SYS_PAGE_FIND_MAPPING,
    6464       
    65         SYS_IPC_CALL_SYNC_FAST,
    66         SYS_IPC_CALL_SYNC_SLOW,
    6765        SYS_IPC_CALL_ASYNC_FAST,
    6866        SYS_IPC_CALL_ASYNC_SLOW,
  • boot/Makefile

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

    rf66ca57f raffaf2e  
    5555MKTMPFS = $(TOOLS_PATH)/mktmpfs.py
    5656MKFAT = $(TOOLS_PATH)/mkfat.py
    57 MKEXT2 = $(TOOLS_PATH)/mkext2.py
     57MKEXT4 = $(TOOLS_PATH)/mkext4.py
    5858MKUIMAGE = $(TOOLS_PATH)/mkuimage.py
    5959
     
    8484endif
    8585
    86 ifeq ($(RDFMT),ext2fs)
    87         INIT_TASKS += $(USPACE_PATH)/srv/fs/ext2fs/ext2fs
     86ifeq ($(RDFMT),ext4fs)
     87        INIT_TASKS += $(USPACE_PATH)/srv/fs/ext4fs/ext4fs
    8888endif
    8989
     
    106106        $(USPACE_PATH)/srv/fs/exfat/exfat \
    107107        $(USPACE_PATH)/srv/fs/ext2fs/ext2fs \
     108        $(USPACE_PATH)/srv/fs/ext4fs/ext4fs \
    108109        $(USPACE_PATH)/srv/hid/remcons/remcons \
    109110        $(USPACE_PATH)/srv/hid/isdv4_tablet/isdv4_tablet \
     
    174175        $(USPACE_PATH)/app/tester/tester \
    175176        $(USPACE_PATH)/app/testread/testread \
     177        $(USPACE_PATH)/app/testwrit/testwrit \
    176178        $(USPACE_PATH)/app/tetris/tetris \
    177179        $(USPACE_PATH)/app/trace/trace \
  • kernel/generic/include/ipc/ipc.h

    rf66ca57f raffaf2e  
    7777        waitq_t wq;
    7878       
    79         /** Linkage for the list of task's synchronous answerboxes. */
    80         link_t sync_box_link;
    81        
    8279        /** Phones connected to this answerbox. */
    8380        list_t connected_phones;
     
    116113        struct task *sender;
    117114       
    118         /*
    119          * The caller box is different from sender->answerbox
    120          * for synchronous calls.
    121          */
    122         answerbox_t *callerbox;
    123        
    124115        /** Private data to internal IPC. */
    125116        sysarg_t priv;
     
    147138
    148139extern int ipc_call(phone_t *, call_t *);
    149 extern int ipc_call_sync(phone_t *, call_t *);
    150140extern call_t *ipc_wait_for_call(answerbox_t *, uint32_t, unsigned int);
    151141extern int ipc_forward(call_t *, phone_t *, answerbox_t *, unsigned int);
  • kernel/generic/include/ipc/sysipc.h

    rf66ca57f raffaf2e  
    4040#include <typedefs.h>
    4141
    42 extern sysarg_t sys_ipc_call_sync_fast(sysarg_t, sysarg_t, sysarg_t,
    43     sysarg_t, sysarg_t, ipc_data_t *);
    44 extern sysarg_t sys_ipc_call_sync_slow(sysarg_t, ipc_data_t *, ipc_data_t *);
    4542extern sysarg_t sys_ipc_call_async_fast(sysarg_t, sysarg_t, sysarg_t,
    4643    sysarg_t, sysarg_t, sysarg_t);
  • kernel/generic/include/proc/task.h

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

    rf66ca57f raffaf2e  
    7171{
    7272        memsetb(call, sizeof(*call), 0);
    73         call->callerbox = &TASK->answerbox;
    7473        call->sender = TASK;
    7574        call->buffer = NULL;
     
    120119        irq_spinlock_initialize(&box->irq_lock, "ipc.box.irqlock");
    121120        waitq_initialize(&box->wq);
    122         link_initialize(&box->sync_box_link);
    123121        list_initialize(&box->connected_phones);
    124122        list_initialize(&box->calls);
     
    163161}
    164162
    165 /** Helper function to facilitate synchronous calls.
    166  *
    167  * @param phone   Destination kernel phone structure.
    168  * @param request Call structure with request.
    169  *
    170  * @return EOK on success or EINTR if the sleep was interrupted.
    171  *
    172  */
    173 int ipc_call_sync(phone_t *phone, call_t *request)
    174 {
    175         answerbox_t *sync_box = slab_alloc(ipc_answerbox_slab, 0);
    176         ipc_answerbox_init(sync_box, TASK);
    177        
    178         /*
    179          * Put the answerbox on the TASK's list of synchronous answerboxes so
    180          * that it can be cleaned up if the call is interrupted.
    181          */
    182         irq_spinlock_lock(&TASK->lock, true);
    183         list_append(&sync_box->sync_box_link, &TASK->sync_boxes);
    184         irq_spinlock_unlock(&TASK->lock, true);
    185        
    186         /* We will receive data in a special box. */
    187         request->callerbox = sync_box;
    188        
    189         ipc_call(phone, request);
    190         if (!ipc_wait_for_call(sync_box, SYNCH_NO_TIMEOUT,
    191             SYNCH_FLAGS_INTERRUPTIBLE)) {
    192                 /* The answerbox and the call will be freed by ipc_cleanup(). */
    193                 return EINTR;
    194         }
    195        
    196         /*
    197          * The answer arrived without interruption so we can remove the
    198          * answerbox from the TASK's list of synchronous answerboxes.
    199          */
    200         irq_spinlock_lock(&TASK->lock, true);
    201         list_remove(&sync_box->sync_box_link);
    202         irq_spinlock_unlock(&TASK->lock, true);
    203        
    204         slab_free(ipc_answerbox_slab, sync_box);
    205         return EOK;
    206 }
    207 
    208163/** Answer a message which was not dispatched and is not listed in any queue.
    209164 *
     
    214169static void _ipc_answer_free_call(call_t *call, bool selflocked)
    215170{
    216         answerbox_t *callerbox = call->callerbox;
     171        answerbox_t *callerbox = &call->sender->answerbox;
    217172        bool do_lock = ((!selflocked) || callerbox != (&TASK->answerbox));
    218173       
     
    606561        ipc_cleanup_call_list(&TASK->answerbox.calls);
    607562        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);
    622563       
    623564        /* Wait for all answers to asynchronous calls to arrive */
  • kernel/generic/src/ipc/sysipc.c

    rf66ca57f raffaf2e  
    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  */
    635 sysarg_t sys_ipc_call_sync_fast(sysarg_t phoneid, sysarg_t imethod,
    636     sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, ipc_data_t *data)
    637 {
    638         phone_t *phone;
    639         if (phone_get(phoneid, &phone) != EOK)
    640                 return ENOENT;
    641        
    642         call_t *call = ipc_call_alloc(0);
    643         IPC_SET_IMETHOD(call->data, imethod);
    644         IPC_SET_ARG1(call->data, arg1);
    645         IPC_SET_ARG2(call->data, arg2);
    646         IPC_SET_ARG3(call->data, arg3);
    647        
    648         /*
    649          * To achieve deterministic behavior, zero out arguments that are beyond
    650          * the limits of the fast version.
    651          */
    652         IPC_SET_ARG4(call->data, 0);
    653         IPC_SET_ARG5(call->data, 0);
    654        
    655         int res = request_preprocess(call, phone);
    656         int rc;
    657        
    658         if (!res) {
    659 #ifdef CONFIG_UDEBUG
    660                 udebug_stoppable_begin();
    661 #endif
    662                 rc = ipc_call_sync(phone, call);
    663 #ifdef CONFIG_UDEBUG
    664                 udebug_stoppable_end();
    665 #endif
    666                
    667                 if (rc != EOK) {
    668                         /* The call will be freed by ipc_cleanup(). */
    669                         return rc;
    670                 }
    671                
    672                 process_answer(call);
    673         } else
    674                 IPC_SET_RETVAL(call->data, res);
    675        
    676         rc = STRUCT_TO_USPACE(&data->args, &call->data.args);
    677         ipc_call_free(call);
    678         if (rc != 0)
    679                 return rc;
    680        
    681         return 0;
    682 }
    683 
    684 /** Make a synchronous IPC call allowing to transmit the entire payload.
    685  *
    686  * @param phoneid Phone handle for the call.
    687  * @param request User-space address of call data with the request.
    688  * @param reply   User-space address of call data where to store the
    689  *                answer.
    690  *
    691  * @return Zero on success or an error code.
    692  *
    693  */
    694 sysarg_t sys_ipc_call_sync_slow(sysarg_t phoneid, ipc_data_t *request,
    695     ipc_data_t *reply)
    696 {
    697         phone_t *phone;
    698         if (phone_get(phoneid, &phone) != EOK)
    699                 return ENOENT;
    700        
    701         call_t *call = ipc_call_alloc(0);
    702         int rc = copy_from_uspace(&call->data.args, &request->args,
    703             sizeof(call->data.args));
    704         if (rc != 0) {
    705                 ipc_call_free(call);
    706                 return (sysarg_t) rc;
    707         }
    708        
    709         int res = request_preprocess(call, phone);
    710        
    711         if (!res) {
    712 #ifdef CONFIG_UDEBUG
    713                 udebug_stoppable_begin();
    714 #endif
    715                 rc = ipc_call_sync(phone, call);
    716 #ifdef CONFIG_UDEBUG
    717                 udebug_stoppable_end();
    718 #endif
    719                
    720                 if (rc != EOK) {
    721                         /* The call will be freed by ipc_cleanup(). */
    722                         return rc;
    723                 }
    724                
    725                 process_answer(call);
    726         } else
    727                 IPC_SET_RETVAL(call->data, res);
    728        
    729         rc = STRUCT_TO_USPACE(&reply->args, &call->data.args);
    730         ipc_call_free(call);
    731         if (rc != 0)
    732                 return rc;
    733614       
    734615        return 0;
  • kernel/generic/src/proc/task.c

    rf66ca57f raffaf2e  
    156156       
    157157        list_initialize(&task->threads);
    158         list_initialize(&task->sync_boxes);
    159158       
    160159        ipc_answerbox_init(&task->answerbox, task);
  • kernel/generic/src/syscall/syscall.c

    rf66ca57f raffaf2e  
    151151       
    152152        /* IPC related syscalls. */
    153         (syshandler_t) sys_ipc_call_sync_fast,
    154         (syshandler_t) sys_ipc_call_sync_slow,
    155153        (syshandler_t) sys_ipc_call_async_fast,
    156154        (syshandler_t) sys_ipc_call_async_slow,
  • uspace/Makefile

    rf66ca57f raffaf2e  
    5858        app/tester \
    5959        app/testread \
     60        app/testwrit \
    6061        app/tetris \
    6162        app/trace \
     
    9798        srv/fs/locfs \
    9899        srv/fs/ext2fs \
     100        srv/fs/ext4fs \
    99101        srv/hid/console \
    100102        srv/hid/s3c24xx_ts \
     
    197199        lib/nic \
    198200        lib/ext2 \
     201        lib/ext4 \
    199202        lib/usb \
    200203        lib/usbhost \
  • uspace/Makefile.common

    rf66ca57f raffaf2e  
    115115
    116116LIBEXT2_PREFIX = $(LIB_PREFIX)/ext2
     117LIBEXT4_PREFIX = $(LIB_PREFIX)/ext4
    117118
    118119LIBUSB_PREFIX = $(LIB_PREFIX)/usb
  • uspace/app/trace/syscalls.c

    rf66ca57f raffaf2e  
    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 },
    5755    [SYS_IPC_CALL_ASYNC_FAST] = { "ipc_call_async_fast", 6,     V_HASH },
    5856    [SYS_IPC_CALL_ASYNC_SLOW] = { "ipc_call_async_slow", 2,     V_HASH },
  • uspace/app/trace/trace.c

    rf66ca57f raffaf2e  
    318318}
    319319
    320 static void sc_ipc_call_sync_fast(sysarg_t *sc_args)
    321 {
    322         ipc_call_t question, reply;
    323         int rc;
    324         int phoneid;
    325 
    326         phoneid = sc_args[0];
    327 
    328         IPC_SET_IMETHOD(question, sc_args[1]);
    329         IPC_SET_ARG1(question, sc_args[2]);
    330         IPC_SET_ARG2(question, sc_args[3]);
    331         IPC_SET_ARG3(question, sc_args[4]);
    332         IPC_SET_ARG4(question, 0);
    333         IPC_SET_ARG5(question, 0);
    334 
    335         memset(&reply, 0, sizeof(reply));
    336         rc = udebug_mem_read(sess, &reply.args, sc_args[5], sizeof(reply.args));
    337         if (rc < 0)
    338                 return;
    339        
    340         ipcp_call_sync(phoneid, &question, &reply);
    341 }
    342 
    343 static void sc_ipc_call_sync_slow_b(unsigned thread_id, sysarg_t *sc_args)
    344 {
    345         ipc_call_t question;
    346         int rc;
    347 
    348         memset(&question, 0, sizeof(question));
    349         rc = udebug_mem_read(sess, &question.args, sc_args[1],
    350             sizeof(question.args));
    351 
    352         if (rc < 0) {
    353                 printf("Error: mem_read->%d\n", rc);
    354                 return;
    355         }
    356 
    357         thread_ipc_req[thread_id] = question;
    358 }
    359 
    360 static void sc_ipc_call_sync_slow_e(unsigned thread_id, sysarg_t *sc_args)
    361 {
    362         ipc_call_t reply;
    363         int rc;
    364 
    365         memset(&reply, 0, sizeof(reply));
    366         rc = udebug_mem_read(sess, &reply.args, sc_args[2],
    367             sizeof(reply.args));
    368 
    369         if (rc < 0) {
    370                 printf("Error: mem_read->%d\n", rc);
    371                 return;
    372         }
    373 
    374         ipcp_call_sync(sc_args[0], &thread_ipc_req[thread_id], &reply);
    375 }
    376 
    377320static void sc_ipc_wait(sysarg_t *sc_args, int sc_rc)
    378321{
     
    408351                print_sc_args(sc_args, syscall_desc[sc_id].n_args);
    409352        }
    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         }
    418353}
    419354
     
    447382        case SYS_IPC_CALL_ASYNC_SLOW:
    448383                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);
    455384                break;
    456385        case SYS_IPC_WAIT:
  • uspace/drv/bus/usb/usbmast/main.c

    rf66ca57f raffaf2e  
    3737#include <as.h>
    3838#include <async.h>
    39 #include <ipc/bd.h>
     39#include <bd_srv.h>
    4040#include <macros.h>
    4141#include <usb/dev/driver.h>
     
    8282    void *arg);
    8383
     84static int usbmast_bd_open(bd_srvs_t *, bd_srv_t *);
     85static int usbmast_bd_close(bd_srv_t *);
     86static int usbmast_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
     87static int usbmast_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t);
     88static int usbmast_bd_get_block_size(bd_srv_t *, size_t *);
     89static int usbmast_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
     90
     91static 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
     100static usbmast_fun_t *bd_srv_usbmast(bd_srv_t *bd)
     101{
     102        return (usbmast_fun_t *)bd->srvs->sarg;
     103}
     104
    84105/** Callback when a device is removed from the system.
    85106 *
     
    219240        mfun->lun = lun;
    220241
     242        bd_srvs_init(&mfun->bds);
     243        mfun->bds.ops = &usbmast_bd_ops;
     244        mfun->bds.sarg = mfun;
     245
    221246        /* Set up a connection handler. */
    222247        fun->conn_handler = usbmast_bd_connection;
     
    284309{
    285310        usbmast_fun_t *mfun;
    286         void *comm_buf = NULL;
    287         size_t comm_size;
    288         ipc_callid_t callid;
    289         ipc_call_t call;
    290         unsigned int flags;
    291         sysarg_t method;
    292         uint64_t ba;
    293         size_t cnt;
    294         int retval;
    295 
    296         async_answer_0(iid, EOK);
    297 
    298         if (!async_share_out_receive(&callid, &comm_size, &flags)) {
    299                 async_answer_0(callid, EHANGUP);
    300                 return;
    301         }
    302        
    303         (void) async_share_out_finalize(callid, &comm_buf);
    304         if (comm_buf == AS_MAP_FAILED) {
    305                 async_answer_0(callid, EHANGUP);
    306                 return;
    307         }
    308        
     311
    309312        mfun = (usbmast_fun_t *) ((ddf_fun_t *)arg)->driver_data;
    310 
    311         while (true) {
    312                 callid = async_get_call(&call);
    313                 method = IPC_GET_IMETHOD(call);
    314 
    315                 if (!method) {
    316                         /* The other side hung up. */
    317                         async_answer_0(callid, EOK);
    318                         return;
    319                 }
    320 
    321                 switch (method) {
    322                 case BD_GET_BLOCK_SIZE:
    323                         async_answer_1(callid, EOK, mfun->block_size);
    324                         break;
    325                 case BD_GET_NUM_BLOCKS:
    326                         async_answer_2(callid, EOK, LOWER32(mfun->nblocks),
    327                             UPPER32(mfun->nblocks));
    328                         break;
    329                 case BD_READ_BLOCKS:
    330                         ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
    331                         cnt = IPC_GET_ARG3(call);
    332                         retval = usbmast_read(mfun, ba, cnt, comm_buf);
    333                         async_answer_0(callid, retval);
    334                         break;
    335                 case BD_WRITE_BLOCKS:
    336                         ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
    337                         cnt = IPC_GET_ARG3(call);
    338                         retval = usbmast_write(mfun, ba, cnt, comm_buf);
    339                         async_answer_0(callid, retval);
    340                         break;
    341                 default:
    342                         async_answer_0(callid, EINVAL);
    343                 }
    344         }
    345 }
     313        bd_conn(iid, icall, &mfun->bds);
     314}
     315
     316/** Open device. */
     317static int usbmast_bd_open(bd_srvs_t *bds, bd_srv_t *bd)
     318{
     319        return EOK;
     320}
     321
     322/** Close device. */
     323static int usbmast_bd_close(bd_srv_t *bd)
     324{
     325        return EOK;
     326}
     327
     328/** Read blocks from the device. */
     329static 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. */
     341static 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. */
     353static 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. */
     361static 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
    346368
    347369/** USB mass storage driver ops. */
  • uspace/drv/bus/usb/usbmast/usbmast.h

    rf66ca57f raffaf2e  
    3737#define USBMAST_H_
    3838
     39#include <bd_srv.h>
    3940#include <sys/types.h>
    4041#include <usb/usb.h>
     
    6869        /** Block size in bytes */
    6970        size_t block_size;
     71        /** Block device service structure */
     72        bd_srvs_t bds;
    7073} usbmast_fun_t;
    7174
  • uspace/lib/block/libblock.c

    rf66ca57f raffaf2e  
    4040#include "../../srv/vfs/vfs.h"
    4141#include <ipc/loc.h>
    42 #include <ipc/bd.h>
    4342#include <ipc/services.h>
    4443#include <errno.h>
     
    4746#include <as.h>
    4847#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         fibril_mutex_t comm_area_lock;
    83         void *comm_area;
    84         size_t comm_size;
     82        bd_t *bd;
    8583        void *bb_buf;
    8684        aoff64_t bb_addr;
     
    8987} devcon_t;
    9088
    91 static int read_blocks(devcon_t *, aoff64_t, size_t);
    92 static int write_blocks(devcon_t *, aoff64_t, size_t);
    93 static int get_block_size(async_sess_t *, size_t *);
    94 static int get_num_blocks(async_sess_t *, aoff64_t *);
     89static int read_blocks(devcon_t *, aoff64_t, size_t, void *, size_t);
     90static int write_blocks(devcon_t *, aoff64_t, size_t, void *, size_t);
    9591static aoff64_t ba_ltop(devcon_t *, aoff64_t);
    9692
     
    112108
    113109static int devcon_add(service_id_t service_id, async_sess_t *sess,
    114     size_t bsize, void *comm_area, size_t comm_size)
     110    size_t bsize, bd_t *bd)
    115111{
    116112        devcon_t *devcon;
    117        
    118         if (comm_size < bsize)
    119                 return EINVAL;
    120113       
    121114        devcon = malloc(sizeof(devcon_t));
     
    126119        devcon->service_id = service_id;
    127120        devcon->sess = sess;
    128         fibril_mutex_initialize(&devcon->comm_area_lock);
    129         devcon->comm_area = comm_area;
    130         devcon->comm_size = comm_size;
     121        devcon->bd = bd;
    131122        devcon->bb_buf = NULL;
    132123        devcon->bb_addr = 0;
     
    158149    size_t comm_size)
    159150{
    160         void *comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE,
    161             MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
    162         if (!comm_area)
    163                 return ENOMEM;
    164        
     151        bd_t *bd;
     152
    165153        async_sess_t *sess = loc_service_connect(mgmt, service_id,
    166154            IPC_FLAG_BLOCKING);
    167155        if (!sess) {
    168                 munmap(comm_area, comm_size);
    169156                return ENOENT;
    170157        }
    171158       
    172         async_exch_t *exch = async_exchange_begin(sess);
    173         int rc = async_share_out_start(exch, comm_area,
    174             AS_AREA_READ | AS_AREA_WRITE);
    175         async_exchange_end(exch);
    176        
     159        int rc = bd_open(sess, &bd);
    177160        if (rc != EOK) {
    178                 munmap(comm_area, comm_size);
    179161                async_hangup(sess);
    180162                return rc;
     
    182164       
    183165        size_t bsize;
    184         rc = get_block_size(sess, &bsize);
    185        
     166        rc = bd_get_block_size(bd, &bsize);
    186167        if (rc != EOK) {
    187                 munmap(comm_area, comm_size);
     168                bd_close(bd);
    188169                async_hangup(sess);
    189170                return rc;
    190171        }
    191172       
    192         rc = devcon_add(service_id, sess, bsize, comm_area, comm_size);
     173        rc = devcon_add(service_id, sess, bsize, bd);
    193174        if (rc != EOK) {
    194                 munmap(comm_area, comm_size);
     175                bd_close(bd);
    195176                async_hangup(sess);
    196177                return rc;
     
    213194                free(devcon->bb_buf);
    214195       
    215         munmap(devcon->comm_area, devcon->comm_size);
     196        bd_close(devcon->bd);
    216197        async_hangup(devcon->sess);
    217198       
     
    233214                return ENOMEM;
    234215
    235         fibril_mutex_lock(&devcon->comm_area_lock);
    236         rc = read_blocks(devcon, 0, 1);
     216        rc = read_blocks(devcon, 0, 1, bb_buf, devcon->pblock_size);
    237217        if (rc != EOK) {
    238                 fibril_mutex_unlock(&devcon->comm_area_lock);
    239218                free(bb_buf);
    240219                return rc;
    241220        }
    242         memcpy(bb_buf, devcon->comm_area, devcon->pblock_size);
    243         fibril_mutex_unlock(&devcon->comm_area_lock);
    244221
    245222        devcon->bb_buf = bb_buf;
     
    338315                list_remove(&b->free_link);
    339316                if (b->dirty) {
    340                         memcpy(devcon->comm_area, b->data, b->size);
    341                         rc = write_blocks(devcon, b->pba, cache->blocks_cluster);
     317                        rc = write_blocks(devcon, b->pba, cache->blocks_cluster,
     318                            b->data, b->size);
    342319                        if (rc != EOK)
    343320                                return rc;
     
    481458                                list_append(&b->free_link, &cache->free_list);
    482459                                fibril_mutex_unlock(&cache->lock);
    483                                 fibril_mutex_lock(&devcon->comm_area_lock);
    484                                 memcpy(devcon->comm_area, b->data, b->size);
    485460                                rc = write_blocks(devcon, b->pba,
    486                                     cache->blocks_cluster);
    487                                 fibril_mutex_unlock(&devcon->comm_area_lock);
     461                                    cache->blocks_cluster, b->data, b->size);
    488462                                if (rc != EOK) {
    489463                                        /*
     
    555529                         * the new contents from the device.
    556530                         */
    557                         fibril_mutex_lock(&devcon->comm_area_lock);
    558                         rc = read_blocks(devcon, b->pba, cache->blocks_cluster);
    559                         memcpy(b->data, devcon->comm_area, cache->lblock_size);
    560                         fibril_mutex_unlock(&devcon->comm_area_lock);
     531                        rc = read_blocks(devcon, b->pba, cache->blocks_cluster,
     532                            b->data, cache->lblock_size);
    561533                        if (rc != EOK)
    562534                                b->toxic = true;
     
    616588        if (block->dirty && (block->refcnt == 1) &&
    617589            (blocks_cached > CACHE_HI_WATERMARK || mode != CACHE_MODE_WB)) {
    618                 fibril_mutex_lock(&devcon->comm_area_lock);
    619                 memcpy(devcon->comm_area, block->data, block->size);
    620                 rc = write_blocks(devcon, block->pba, cache->blocks_cluster);
    621                 fibril_mutex_unlock(&devcon->comm_area_lock);
     590                rc = write_blocks(devcon, block->pba, cache->blocks_cluster,
     591                    block->data, block->size);
    622592                block->dirty = false;
    623593        }
     
    688658 *
    689659 * @param service_id    Service ID of the block device.
     660 * @param buf           Buffer for holding one block
    690661 * @param bufpos        Pointer to the first unread valid offset within the
    691662 *                      communication buffer.
     
    699670 * @return              EOK on success or a negative return code on failure.
    700671 */
    701 int block_seqread(service_id_t service_id, size_t *bufpos, size_t *buflen,
    702     aoff64_t *pos, void *dst, size_t size)
     672int block_seqread(service_id_t service_id, void *buf, size_t *bufpos,
     673    size_t *buflen, aoff64_t *pos, void *dst, size_t size)
    703674{
    704675        size_t offset = 0;
     
    711682        block_size = devcon->pblock_size;
    712683       
    713         fibril_mutex_lock(&devcon->comm_area_lock);
    714684        while (left > 0) {
    715685                size_t rd;
     
    725695                         * destination buffer.
    726696                         */
    727                         memcpy(dst + offset, devcon->comm_area + *bufpos, rd);
     697                        memcpy(dst + offset, buf + *bufpos, rd);
    728698                        offset += rd;
    729699                        *bufpos += rd;
     
    736706                        int rc;
    737707
    738                         rc = read_blocks(devcon, *pos / block_size, 1);
     708                        rc = read_blocks(devcon, *pos / block_size, 1, buf,
     709                            devcon->pblock_size);
    739710                        if (rc != EOK) {
    740                                 fibril_mutex_unlock(&devcon->comm_area_lock);
    741711                                return rc;
    742712                        }
     
    746716                }
    747717        }
    748         fibril_mutex_unlock(&devcon->comm_area_lock);
    749718       
    750719        return EOK;
     
    763732{
    764733        devcon_t *devcon;
    765         int rc;
    766734
    767735        devcon = devcon_search(service_id);
    768736        assert(devcon);
    769        
    770         fibril_mutex_lock(&devcon->comm_area_lock);
    771 
    772         rc = read_blocks(devcon, ba, cnt);
    773         if (rc == EOK)
    774                 memcpy(buf, devcon->comm_area, devcon->pblock_size * cnt);
    775 
    776         fibril_mutex_unlock(&devcon->comm_area_lock);
    777 
    778         return rc;
     737
     738        return read_blocks(devcon, ba, cnt, buf, devcon->pblock_size * cnt);
    779739}
    780740
     
    792752{
    793753        devcon_t *devcon;
    794         int rc;
    795754
    796755        devcon = devcon_search(service_id);
    797756        assert(devcon);
    798        
    799         fibril_mutex_lock(&devcon->comm_area_lock);
    800 
    801         memcpy(devcon->comm_area, data, devcon->pblock_size * cnt);
    802         rc = write_blocks(devcon, ba, cnt);
    803 
    804         fibril_mutex_unlock(&devcon->comm_area_lock);
    805 
    806         return rc;
     757
     758        return write_blocks(devcon, ba, cnt, (void *)data, devcon->pblock_size * cnt);
    807759}
    808760
     
    820772        devcon = devcon_search(service_id);
    821773        assert(devcon);
    822        
    823         return get_block_size(devcon->sess, bsize);
     774
     775        return bd_get_block_size(devcon->bd, bsize);
    824776}
    825777
     
    836788        assert(devcon);
    837789       
    838         return get_num_blocks(devcon->sess, nblocks);
     790        return bd_get_num_blocks(devcon->bd, nblocks);
    839791}
    840792
     
    887839        memcpy(data, buffer + offset, bytes);
    888840        free(buffer);
    889        
     841
    890842        return EOK;
    891843}
     
    903855{
    904856        devcon_t *devcon = devcon_search(service_id);
    905         assert(devcon);
    906        
    907857        toc_block_t *toc = NULL;
    908        
    909         fibril_mutex_lock(&devcon->comm_area_lock);
    910        
    911         async_exch_t *exch = async_exchange_begin(devcon->sess);
    912         int rc = async_req_1_0(exch, BD_READ_TOC, session);
    913         async_exchange_end(exch);
    914        
    915         if (rc == EOK) {
    916                 toc = (toc_block_t *) malloc(sizeof(toc_block_t));
    917                 if (toc != NULL) {
    918                         memset(toc, 0, sizeof(toc_block_t));
    919                         memcpy(toc, devcon->comm_area,
    920                             min(devcon->pblock_size, sizeof(toc_block_t)));
    921                 }
    922         }
    923        
    924        
    925         fibril_mutex_unlock(&devcon->comm_area_lock);
     858        int rc;
     859       
     860        assert(devcon);
     861       
     862        toc = (toc_block_t *) malloc(sizeof(toc_block_t));
     863        if (toc == NULL)
     864                return NULL;
     865       
     866        rc = bd_read_toc(devcon->bd, session, toc, sizeof(toc_block_t));
     867        if (rc != EOK) {
     868                free(toc);
     869                return NULL;
     870        }
    926871       
    927872        return toc;
     
    937882 * @return              EOK on success or negative error code on failure.
    938883 */
    939 static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
    940 {
    941         assert(devcon);
    942        
    943         async_exch_t *exch = async_exchange_begin(devcon->sess);
    944         int rc = async_req_3_0(exch, BD_READ_BLOCKS, LOWER32(ba),
    945             UPPER32(ba), cnt);
    946         async_exchange_end(exch);
    947        
     884static 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);
    948890        if (rc != EOK) {
    949891                printf("Error %d reading %zu blocks starting at block %" PRIuOFF64
     
    967909 * @return              EOK on success or negative error code on failure.
    968910 */
    969 static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
    970 {
    971         assert(devcon);
    972        
    973         async_exch_t *exch = async_exchange_begin(devcon->sess);
    974         int rc = async_req_3_0(exch, BD_WRITE_BLOCKS, LOWER32(ba),
    975             UPPER32(ba), cnt);
    976         async_exchange_end(exch);
    977        
     911static 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);
    978917        if (rc != EOK) {
    979918                printf("Error %d writing %zu blocks starting at block %" PRIuOFF64
     
    987926}
    988927
    989 /** Get block size used by the device. */
    990 static int get_block_size(async_sess_t *sess, size_t *bsize)
    991 {
    992         sysarg_t bs;
    993        
    994         async_exch_t *exch = async_exchange_begin(sess);
    995         int rc = async_req_0_1(exch, BD_GET_BLOCK_SIZE, &bs);
    996         async_exchange_end(exch);
    997        
    998         if (rc == EOK)
    999                 *bsize = (size_t) bs;
    1000        
    1001         return rc;
    1002 }
    1003 
    1004 /** Get total number of blocks on block device. */
    1005 static int get_num_blocks(async_sess_t *sess, aoff64_t *nblocks)
    1006 {
    1007         sysarg_t nb_l;
    1008         sysarg_t nb_h;
    1009        
    1010         async_exch_t *exch = async_exchange_begin(sess);
    1011         int rc = async_req_0_2(exch, BD_GET_NUM_BLOCKS, &nb_l, &nb_h);
    1012         async_exchange_end(exch);
    1013        
    1014         if (rc == EOK)
    1015                 *nblocks = (aoff64_t) MERGE_LOUP32(nb_l, nb_h);
    1016        
    1017         return rc;
    1018 }
    1019 
    1020928/** Convert logical block address to physical block address. */
    1021929static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba)
  • uspace/lib/block/libblock.h

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

    rf66ca57f raffaf2e  
    6262        generic/ddi.c \
    6363        generic/as.c \
     64        generic/bd.c \
     65        generic/bd_srv.c \
    6466        generic/cap.c \
    6567        generic/cfg.c \
  • uspace/lib/c/generic/async.c

    rf66ca57f raffaf2e  
    114114#include <stdlib.h>
    115115#include <macros.h>
     116#include "private/libc.h"
    116117
    117118#define CLIENT_HASH_TABLE_BUCKETS  32
     
    21662167int async_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags)
    21672168{
    2168         return ipc_share_in_finalize(callid, src, flags);
     2169        return ipc_answer_3(callid, EOK, (sysarg_t) src, (sysarg_t) flags,
     2170            (sysarg_t) __entry);
    21692171}
    21702172
     
    22332235int async_share_out_finalize(ipc_callid_t callid, void **dst)
    22342236{
    2235         return ipc_share_out_finalize(callid, dst);
     2237        return ipc_answer_2(callid, EOK, (sysarg_t) __entry, (sysarg_t) dst);
    22362238}
    22372239
     
    23172319int async_data_read_finalize(ipc_callid_t callid, const void *src, size_t size)
    23182320{
    2319         return ipc_data_read_finalize(callid, src, size);
     2321        return ipc_answer_2(callid, EOK, (sysarg_t) src, (sysarg_t) size);
    23202322}
    23212323
     
    24202422int async_data_write_finalize(ipc_callid_t callid, void *dst, size_t size)
    24212423{
    2422         return ipc_data_write_finalize(callid, dst, size);
     2424        return ipc_answer_2(callid, EOK, (sysarg_t) dst, (sysarg_t) size);
    24232425}
    24242426
  • uspace/lib/c/generic/ipc.c

    rf66ca57f raffaf2e  
    4848#include <fibril.h>
    4949#include <macros.h>
    50 #include "private/libc.h"
    5150
    5251/**
     
    8382
    8483static atomic_t ipc_futex = FUTEX_INITIALIZER;
    85 
    86 /** Fast synchronous call.
    87  *
    88  * Only three payload arguments can be passed using this function. However,
    89  * this function is faster than the generic ipc_call_sync_slow() because
    90  * the payload is passed directly in registers.
    91  *
    92  * @param phoneid Phone handle for the call.
    93  * @param method  Requested method.
    94  * @param arg1    Service-defined payload argument.
    95  * @param arg2    Service-defined payload argument.
    96  * @param arg3    Service-defined payload argument.
    97  * @param result1 If non-NULL, the return ARG1 will be stored there.
    98  * @param result2 If non-NULL, the return ARG2 will be stored there.
    99  * @param result3 If non-NULL, the return ARG3 will be stored there.
    100  * @param result4 If non-NULL, the return ARG4 will be stored there.
    101  * @param result5 If non-NULL, the return ARG5 will be stored there.
    102  *
    103  * @return Negative values representing IPC errors.
    104  * @return Otherwise the RETVAL of the answer.
    105  *
    106  */
    107 int ipc_call_sync_fast(int phoneid, sysarg_t method, sysarg_t arg1,
    108     sysarg_t arg2, sysarg_t arg3, sysarg_t *result1, sysarg_t *result2,
    109     sysarg_t *result3, sysarg_t *result4, sysarg_t *result5)
    110 {
    111         ipc_call_t resdata;
    112         int callres = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid, method, arg1,
    113             arg2, arg3, (sysarg_t) &resdata);
    114         if (callres)
    115                 return callres;
    116        
    117         if (result1)
    118                 *result1 = IPC_GET_ARG1(resdata);
    119         if (result2)
    120                 *result2 = IPC_GET_ARG2(resdata);
    121         if (result3)
    122                 *result3 = IPC_GET_ARG3(resdata);
    123         if (result4)
    124                 *result4 = IPC_GET_ARG4(resdata);
    125         if (result5)
    126                 *result5 = IPC_GET_ARG5(resdata);
    127        
    128         return IPC_GET_RETVAL(resdata);
    129 }
    130 
    131 /** Synchronous call transmitting 5 arguments of payload.
    132  *
    133  * @param phoneid Phone handle for the call.
    134  * @param imethod Requested interface and method.
    135  * @param arg1    Service-defined payload argument.
    136  * @param arg2    Service-defined payload argument.
    137  * @param arg3    Service-defined payload argument.
    138  * @param arg4    Service-defined payload argument.
    139  * @param arg5    Service-defined payload argument.
    140  * @param result1 If non-NULL, storage for the first return argument.
    141  * @param result2 If non-NULL, storage for the second return argument.
    142  * @param result3 If non-NULL, storage for the third return argument.
    143  * @param result4 If non-NULL, storage for the fourth return argument.
    144  * @param result5 If non-NULL, storage for the fifth return argument.
    145  *
    146  * @return Negative values representing IPC errors.
    147  * @return Otherwise the RETVAL of the answer.
    148  *
    149  */
    150 int ipc_call_sync_slow(int phoneid, sysarg_t imethod, sysarg_t arg1,
    151     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
    152     sysarg_t *result1, sysarg_t *result2, sysarg_t *result3, sysarg_t *result4,
    153     sysarg_t *result5)
    154 {
    155         ipc_call_t data;
    156        
    157         IPC_SET_IMETHOD(data, imethod);
    158         IPC_SET_ARG1(data, arg1);
    159         IPC_SET_ARG2(data, arg2);
    160         IPC_SET_ARG3(data, arg3);
    161         IPC_SET_ARG4(data, arg4);
    162         IPC_SET_ARG5(data, arg5);
    163        
    164         int callres = __SYSCALL3(SYS_IPC_CALL_SYNC_SLOW, phoneid,
    165             (sysarg_t) &data, (sysarg_t) &data);
    166         if (callres)
    167                 return callres;
    168        
    169         if (result1)
    170                 *result1 = IPC_GET_ARG1(data);
    171         if (result2)
    172                 *result2 = IPC_GET_ARG2(data);
    173         if (result3)
    174                 *result3 = IPC_GET_ARG3(data);
    175         if (result4)
    176                 *result4 = IPC_GET_ARG4(data);
    177         if (result5)
    178                 *result5 = IPC_GET_ARG5(data);
    179        
    180         return IPC_GET_RETVAL(data);
    181 }
    18284
    18385/** Send asynchronous message via syscall.
     
    611513}
    612514
    613 /** Request callback connection.
    614  *
    615  * The @a task_id and @a phonehash identifiers returned
    616  * by the kernel can be used for connection tracking.
    617  *
    618  * @param phoneid   Phone handle used for contacting the other side.
    619  * @param arg1      User defined argument.
    620  * @param arg2      User defined argument.
    621  * @param arg3      User defined argument.
    622  * @param task_id   Identifier of the client task.
    623  * @param phonehash Opaque identifier of the phone that will
    624  *                  be used for incoming calls.
    625  *
    626  * @return Zero on success or a negative error code.
    627  *
    628  */
    629 int ipc_connect_to_me(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
    630     task_id_t *task_id, sysarg_t *phonehash)
    631 {
    632         ipc_call_t data;
    633         int rc = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid,
    634             IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, (sysarg_t) &data);
    635         if (rc == EOK) {
    636                 *task_id = data.in_task_id;
    637                 *phonehash = IPC_GET_ARG5(data);
    638         }       
    639         return rc;
    640 }
    641 
    642 /** Request cloned connection.
    643  *
    644  * @param phoneid Phone handle used for contacting the other side.
    645  *
    646  * @return Cloned phone handle on success or a negative error code.
    647  *
    648  */
    649 int ipc_clone_establish(int phoneid)
    650 {
    651         sysarg_t newphid;
    652         int res = ipc_call_sync_0_5(phoneid, IPC_M_CLONE_ESTABLISH, NULL,
    653             NULL, NULL, NULL, &newphid);
    654         if (res)
    655                 return res;
    656        
    657         return newphid;
    658 }
    659 
    660 /** Request new connection.
    661  *
    662  * @param phoneid Phone handle used for contacting the other side.
    663  * @param arg1    User defined argument.
    664  * @param arg2    User defined argument.
    665  * @param arg3    User defined argument.
    666  *
    667  * @return New phone handle on success or a negative error code.
    668  *
    669  */
    670 int ipc_connect_me_to(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
    671 {
    672         sysarg_t newphid;
    673         int res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
    674             NULL, NULL, NULL, NULL, &newphid);
    675         if (res)
    676                 return res;
    677        
    678         return newphid;
    679 }
    680 
    681 /** Request new connection (blocking)
    682  *
    683  * If the connection is not available at the moment, the
    684  * call should block. This has to be, however, implemented
    685  * on the server side.
    686  *
    687  * @param phoneid Phone handle used for contacting the other side.
    688  * @param arg1    User defined argument.
    689  * @param arg2    User defined argument.
    690  * @param arg3    User defined argument.
    691  *
    692  * @return New phone handle on success or a negative error code.
    693  *
    694  */
    695 int ipc_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2,
    696     sysarg_t arg3)
    697 {
    698         sysarg_t newphid;
    699         int res = ipc_call_sync_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
    700             IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid);
    701         if (res)
    702                 return res;
    703        
    704         return newphid;
    705 }
    706 
    707515/** Hang up a phone.
    708516 *
     
    758566}
    759567
    760 /** Wrapper for IPC_M_SHARE_IN calls.
    761  *
    762  * @param phoneid Phone that will be used to contact the receiving side.
    763  * @param size    Size of the destination address space area.
    764  * @param arg     User defined argument.
    765  * @param flags   Storage for received flags. Can be NULL.
    766  * @param dst     Destination address space area base. Cannot be NULL.
    767  *
    768  * @return Zero on success or a negative error code from errno.h.
    769  *
    770  */
    771 int ipc_share_in_start(int phoneid, size_t size, sysarg_t arg,
    772     unsigned int *flags, void **dst)
    773 {
    774         sysarg_t _flags = 0;
    775         sysarg_t _dst = (sysarg_t) -1;
    776         int res = ipc_call_sync_2_4(phoneid, IPC_M_SHARE_IN, (sysarg_t) size,
    777             arg, NULL, &_flags, NULL, &_dst);
    778        
    779         if (flags)
    780                 *flags = (unsigned int) _flags;
    781        
    782         *dst = (void *) _dst;
    783         return res;
    784 }
    785 
    786 /** Wrapper for answering the IPC_M_SHARE_IN calls.
    787  *
    788  * This wrapper only makes it more comfortable to answer IPC_M_SHARE_IN
    789  * calls so that the user doesn't have to remember the meaning of each
    790  * IPC argument.
    791  *
    792  * @param callid Hash of the IPC_M_DATA_READ call to answer.
    793  * @param src    Source address space base.
    794  * @param flags Flags to be used for sharing. Bits can be only cleared.
    795  *
    796  * @return Zero on success or a value from @ref errno.h on failure.
    797  *
    798  */
    799 int ipc_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags)
    800 {
    801         return ipc_answer_3(callid, EOK, (sysarg_t) src, (sysarg_t) flags,
    802             (sysarg_t) __entry);
    803 }
    804 
    805 /** Wrapper for IPC_M_SHARE_OUT calls.
    806  *
    807  * @param phoneid Phone that will be used to contact the receiving side.
    808  * @param src     Source address space area base address.
    809  * @param flags   Flags to be used for sharing. Bits can be only cleared.
    810  *
    811  * @return Zero on success or a negative error code from errno.h.
    812  *
    813  */
    814 int ipc_share_out_start(int phoneid, void *src, unsigned int flags)
    815 {
    816         return ipc_call_sync_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0,
    817             (sysarg_t) flags);
    818 }
    819 
    820 /** Wrapper for answering the IPC_M_SHARE_OUT calls.
    821  *
    822  * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT
    823  * calls so that the user doesn't have to remember the meaning of each
    824  * IPC argument.
    825  *
    826  * @param callid Hash of the IPC_M_DATA_WRITE call to answer.
    827  * @param dst    Destination address space area base address.
    828  *
    829  * @return Zero on success or a value from @ref errno.h on failure.
    830  *
    831  */
    832 int ipc_share_out_finalize(ipc_callid_t callid, void **dst)
    833 {
    834         return ipc_answer_2(callid, EOK, (sysarg_t) __entry, (sysarg_t) dst);
    835 }
    836 
    837 /** Wrapper for IPC_M_DATA_READ calls.
    838  *
    839  * @param phoneid Phone that will be used to contact the receiving side.
    840  * @param dst     Address of the beginning of the destination buffer.
    841  * @param size    Size of the destination buffer.
    842  *
    843  * @return Zero on success or a negative error code from errno.h.
    844  *
    845  */
    846 int ipc_data_read_start(int phoneid, void *dst, size_t size)
    847 {
    848         return ipc_call_sync_2_0(phoneid, IPC_M_DATA_READ, (sysarg_t) dst,
    849             (sysarg_t) size);
    850 }
    851 
    852 /** Wrapper for answering the IPC_M_DATA_READ calls.
    853  *
    854  * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ
    855  * calls so that the user doesn't have to remember the meaning of each
    856  * IPC argument.
    857  *
    858  * @param callid Hash of the IPC_M_DATA_READ call to answer.
    859  * @param src    Source address for the IPC_M_DATA_READ call.
    860  * @param size   Size for the IPC_M_DATA_READ call. Can be smaller than
    861  *               the maximum size announced by the sender.
    862  *
    863  * @return Zero on success or a value from @ref errno.h on failure.
    864  *
    865  */
    866 int ipc_data_read_finalize(ipc_callid_t callid, const void *src, size_t size)
    867 {
    868         return ipc_answer_2(callid, EOK, (sysarg_t) src, (sysarg_t) size);
    869 }
    870 
    871 /** Wrapper for IPC_M_DATA_WRITE calls.
    872  *
    873  * @param phoneid Phone that will be used to contact the receiving side.
    874  * @param src     Address of the beginning of the source buffer.
    875  * @param size    Size of the source buffer.
    876  *
    877  * @return Zero on success or a negative error code from errno.h.
    878  *
    879  */
    880 int ipc_data_write_start(int phoneid, const void *src, size_t size)
    881 {
    882         return ipc_call_sync_2_0(phoneid, IPC_M_DATA_WRITE, (sysarg_t) src,
    883             (sysarg_t) size);
    884 }
    885 
    886 /** Wrapper for answering the IPC_M_DATA_WRITE calls.
    887  *
    888  * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE
    889  * calls so that the user doesn't have to remember the meaning of each
    890  * IPC argument.
    891  *
    892  * @param callid Hash of the IPC_M_DATA_WRITE call to answer.
    893  * @param dst    Final destination address for the IPC_M_DATA_WRITE call.
    894  * @param size   Final size for the IPC_M_DATA_WRITE call.
    895  *
    896  * @return Zero on success or a value from @ref errno.h on failure.
    897  *
    898  */
    899 int ipc_data_write_finalize(ipc_callid_t callid, void *dst, size_t size)
    900 {
    901         return ipc_answer_2(callid, EOK, (sysarg_t) dst, (sysarg_t) size);
    902 }
    903 
    904568/** Connect to a task specified by id.
    905569 *
  • uspace/lib/c/generic/iplink_srv.c

    rf66ca57f raffaf2e  
    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);
    141144                        async_answer_0(callid, EOK);
    142145                        break;
  • uspace/lib/c/include/ipc/ipc.h

    rf66ca57f raffaf2e  
    4747
    4848typedef void (*ipc_async_callback_t)(void *, int, ipc_call_t *);
    49 
    50 /*
    51  * User-friendly wrappers for ipc_call_sync_fast() and ipc_call_sync_slow().
    52  * They are in the form ipc_call_sync_m_n(), where m denotes the number of
    53  * arguments of payload and n denotes number of return values. Whenever
    54  * possible, the fast version is used.
    55  */
    56 
    57 #define ipc_call_sync_0_0(phoneid, method) \
    58         ipc_call_sync_fast((phoneid), (method), 0, 0, 0, 0, 0, 0, 0, 0)
    59 #define ipc_call_sync_0_1(phoneid, method, res1) \
    60         ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), 0, 0, 0, 0)
    61 #define ipc_call_sync_0_2(phoneid, method, res1, res2) \
    62         ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), 0, 0, 0)
    63 #define ipc_call_sync_0_3(phoneid, method, res1, res2, res3) \
    64         ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \
    65             0, 0)
    66 #define ipc_call_sync_0_4(phoneid, method, res1, res2, res3, res4) \
    67         ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \
    68             (res4), 0)
    69 #define ipc_call_sync_0_5(phoneid, method, res1, res2, res3, res4, res5) \
    70         ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \
    71             (res4), (res5))
    72 
    73 #define ipc_call_sync_1_0(phoneid, method, arg1) \
    74         ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, 0, 0, 0, 0, 0)
    75 #define ipc_call_sync_1_1(phoneid, method, arg1, res1) \
    76         ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), 0, 0, 0, 0)
    77 #define ipc_call_sync_1_2(phoneid, method, arg1, res1, res2) \
    78         ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), 0, \
    79             0, 0)
    80 #define ipc_call_sync_1_3(phoneid, method, arg1, res1, res2, res3) \
    81         ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \
    82             (res3), 0, 0)
    83 #define ipc_call_sync_1_4(phoneid, method, arg1, res1, res2, res3, res4) \
    84         ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \
    85             (res3), (res4), 0)
    86 #define ipc_call_sync_1_5(phoneid, method, arg1, res1, res2, res3, res4, \
    87     res5) \
    88         ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \
    89             (res3), (res4), (res5))
    90 
    91 #define ipc_call_sync_2_0(phoneid, method, arg1, arg2) \
    92         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, 0, 0, 0, \
    93             0, 0)
    94 #define ipc_call_sync_2_1(phoneid, method, arg1, arg2, res1) \
    95         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), 0, 0, \
    96             0, 0)
    97 #define ipc_call_sync_2_2(phoneid, method, arg1, arg2, res1, res2) \
    98         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
    99             (res2), 0, 0, 0)
    100 #define ipc_call_sync_2_3(phoneid, method, arg1, arg2, res1, res2, res3) \
    101         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
    102             (res2), (res3), 0, 0)
    103 #define ipc_call_sync_2_4(phoneid, method, arg1, arg2, res1, res2, res3, \
    104     res4) \
    105         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
    106             (res2), (res3), (res4), 0)
    107 #define ipc_call_sync_2_5(phoneid, method, arg1, arg2, res1, res2, res3, \
    108     res4, res5)\
    109         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
    110             (res2), (res3), (res4), (res5))
    111 
    112 #define ipc_call_sync_3_0(phoneid, method, arg1, arg2, arg3) \
    113         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, 0, 0, \
    114             0, 0)
    115 #define ipc_call_sync_3_1(phoneid, method, arg1, arg2, arg3, res1) \
    116         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), (res1), \
    117             0, 0, 0, 0)
    118 #define ipc_call_sync_3_2(phoneid, method, arg1, arg2, arg3, res1, res2) \
    119         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), (res1), \
    120             (res2), 0, 0, 0)
    121 #define ipc_call_sync_3_3(phoneid, method, arg1, arg2, arg3, res1, res2, \
    122     res3) \
    123         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), \
    124             (res1), (res2), (res3), 0, 0)
    125 #define ipc_call_sync_3_4(phoneid, method, arg1, arg2, arg3, res1, res2, \
    126     res3, res4) \
    127         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), \
    128             (res1), (res2), (res3), (res4), 0)
    129 #define ipc_call_sync_3_5(phoneid, method, arg1, arg2, arg3, res1, res2, \
    130     res3, res4, res5) \
    131         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), \
    132             (res1), (res2), (res3), (res4), (res5))
    133 
    134 #define ipc_call_sync_4_0(phoneid, method, arg1, arg2, arg3, arg4) \
    135         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \
    136             0, 0, 0, 0, 0)
    137 #define ipc_call_sync_4_1(phoneid, method, arg1, arg2, arg3, arg4, res1) \
    138         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \
    139             (res1), 0, 0, 0, 0)
    140 #define ipc_call_sync_4_2(phoneid, method, arg1, arg2, arg3, arg4, res1, res2) \
    141         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \
    142             (res1), (res2), 0, 0, 0)
    143 #define ipc_call_sync_4_3(phoneid, method, arg1, arg2, arg3, arg4, res1, res2, \
    144     res3) \
    145         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
    146             (arg4), 0, (res1), (res2), (res3), 0, 0)
    147 #define ipc_call_sync_4_4(phoneid, method, arg1, arg2, arg3, arg4, res1, res2, \
    148     res3, res4) \
    149         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
    150             (arg4), 0, (res1), (res2), (res3), (res4), 0)
    151 #define ipc_call_sync_4_5(phoneid, method, arg1, arg2, arg3, arg4, res1, res2, \
    152     res3, res4, res5) \
    153         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
    154             (arg4), 0, (res1), (res2), (res3), (res4), (res5))
    155 
    156 #define ipc_call_sync_5_0(phoneid, method, arg1, arg2, arg3, arg4, arg5) \
    157         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
    158             (arg5), 0, 0, 0, 0, 0)
    159 #define ipc_call_sync_5_1(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1) \
    160         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
    161             (arg5), (res1), 0, 0, 0, 0)
    162 #define ipc_call_sync_5_2(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1, \
    163     res2) \
    164         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
    165             (arg4), (arg5), (res1), (res2), 0, 0, 0)
    166 #define ipc_call_sync_5_3(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1, \
    167     res2, res3) \
    168         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
    169             (arg4), (arg5), (res1), (res2), (res3), 0, 0)
    170 #define ipc_call_sync_5_4(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1, \
    171     res2, res3, res4) \
    172         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
    173             (arg4), (arg5), (res1), (res2), (res3), (res4), 0)
    174 #define ipc_call_sync_5_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1, \
    175     res2, res3, res4, res5) \
    176         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
    177             (arg4), (arg5), (res1), (res2), (res3), (res4), (res5))
    178 
    179 extern int ipc_call_sync_fast(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
    180     sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
    181 
    182 extern int ipc_call_sync_slow(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
    183     sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *,
    184     sysarg_t *);
    18549
    18650extern ipc_callid_t ipc_wait_cycle(ipc_call_t *, sysarg_t, unsigned int);
     
    254118    sysarg_t, sysarg_t, void *, ipc_async_callback_t, bool);
    255119
    256 extern int ipc_clone_establish(int);
    257 extern int ipc_connect_to_me(int, sysarg_t, sysarg_t, sysarg_t, task_id_t *,
    258     sysarg_t *);
    259 extern int ipc_connect_me_to(int, sysarg_t, sysarg_t, sysarg_t);
    260 extern int ipc_connect_me_to_blocking(int, sysarg_t, sysarg_t, sysarg_t);
    261 
    262120extern int ipc_hangup(int);
    263121
     
    267125    sysarg_t, sysarg_t, sysarg_t, unsigned int);
    268126
    269 /*
    270  * User-friendly wrappers for ipc_share_in_start().
    271  */
    272 
    273 #define ipc_share_in_start_0_0(phoneid, size, dst) \
    274         ipc_share_in_start((phoneid), (size), 0, NULL, (dst))
    275 #define ipc_share_in_start_0_1(phoneid, size, flags, dst) \
    276         ipc_share_in_start((phoneid), (size), 0, (flags), (dst))
    277 #define ipc_share_in_start_1_0(phoneid, size, arg, dst) \
    278         ipc_share_in_start((phoneid), (size), (arg), NULL, (dst))
    279 #define ipc_share_in_start_1_1(phoneid, size, arg, flags, dst) \
    280         ipc_share_in_start((phoneid), (size), (arg), (flags), (dst))
    281 
    282 extern int ipc_share_in_start(int, size_t, sysarg_t, unsigned int *, void **);
    283 extern int ipc_share_in_finalize(ipc_callid_t, void *, unsigned int);
    284 extern int ipc_share_out_start(int, void *, unsigned int);
    285 extern int ipc_share_out_finalize(ipc_callid_t, void **);
    286 extern int ipc_data_read_start(int, void *, size_t);
    287 extern int ipc_data_read_finalize(ipc_callid_t, const void *, size_t);
    288 extern int ipc_data_write_start(int, const void *, size_t);
    289 extern int ipc_data_write_finalize(ipc_callid_t, void *, size_t);
    290 
    291127extern int ipc_connect_kbox(task_id_t);
    292128
  • uspace/srv/bd/ata_bd/ata_bd.c

    rf66ca57f raffaf2e  
    5151#include <libarch/ddi.h>
    5252#include <ddi.h>
    53 #include <ipc/bd.h>
    5453#include <async.h>
    5554#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 disk[MAX_DISKS];
     100static disk_t ata_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 static int ata_bd_read_blocks(int disk_id, uint64_t ba, size_t cnt,
    106     void *buf);
    107 static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt,
    108     const void *buf);
     105
     106static int ata_bd_open(bd_srvs_t *, bd_srv_t *);
     107static int ata_bd_close(bd_srv_t *);
     108static int ata_bd_read_blocks(bd_srv_t *, uint64_t ba, size_t cnt, void *buf,
     109    size_t);
     110static int ata_bd_read_toc(bd_srv_t *, uint8_t session, void *buf, size_t);
     111static int ata_bd_write_blocks(bd_srv_t *, uint64_t ba, size_t cnt,
     112    const void *buf, size_t);
     113static int ata_bd_get_block_size(bd_srv_t *, size_t *);
     114static int ata_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
     115
    109116static int ata_rcmd_read(int disk_id, uint64_t ba, size_t cnt,
    110117    void *buf);
     
    127134    unsigned timeout);
    128135
     136static 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
     146static disk_t *bd_srv_disk(bd_srv_t *bd)
     147{
     148        return (disk_t *)bd->srvs->sarg;
     149}
     150
    129151int main(int argc, char **argv)
    130152{
     
    161183                fflush(stdout);
    162184
    163                 rc = disk_init(&disk[i], i);
     185                rc = disk_init(&ata_disk[i], i);
    164186
    165187                if (rc == EOK) {
    166                         disk_print_summary(&disk[i]);
     188                        disk_print_summary(&ata_disk[i]);
    167189                } else {
    168190                        printf("Not found.\n");
     
    174196        for (i = 0; i < MAX_DISKS; i++) {
    175197                /* Skip unattached drives. */
    176                 if (disk[i].present == false)
     198                if (ata_disk[i].present == false)
    177199                        continue;
    178200               
    179201                snprintf(name, 16, "%s/ata%udisk%d", NAMESPACE, ctl_num, i);
    180                 rc = loc_service_register(name, &disk[i].service_id);
     202                rc = loc_service_register(name, &ata_disk[i].service_id);
    181203                if (rc != EOK) {
    182204                        printf(NAME ": Unable to register device %s.\n", name);
     
    217239                case am_chs:
    218240                        printf("CHS %u cylinders, %u heads, %u sectors",
    219                             disk->geom.cylinders, disk->geom.heads,
    220                             disk->geom.sectors);
     241                            d->geom.cylinders, d->geom.heads,
     242                            d->geom.sectors);
    221243                        break;
    222244                case am_lba28:
     
    273295static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    274296{
    275         void *fs_va = NULL;
    276         ipc_callid_t callid;
    277         ipc_call_t call;
    278         sysarg_t method;
    279297        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;
    285298        int disk_id, i;
    286299
     
    291304        disk_id = -1;
    292305        for (i = 0; i < MAX_DISKS; i++)
    293                 if (disk[i].service_id == dsid)
     306                if (ata_disk[i].service_id == dsid)
    294307                        disk_id = i;
    295308
    296         if (disk_id < 0 || disk[disk_id].present == false) {
     309        if (disk_id < 0 || ata_disk[disk_id].present == false) {
    297310                async_answer_0(iid, EINVAL);
    298311                return;
    299312        }
    300313
    301         /* Answer the IPC_M_CONNECT_ME_TO call. */
    302         async_answer_0(iid, EOK);
    303 
    304         if (!async_share_out_receive(&callid, &comm_size, &flags)) {
    305                 async_answer_0(callid, EHANGUP);
    306                 return;
    307         }
    308 
    309         (void) async_share_out_finalize(callid, &fs_va);
    310         if (fs_va == AS_MAP_FAILED) {
    311                 async_answer_0(callid, EHANGUP);
    312                 return;
    313         }
    314 
    315         while (true) {
    316                 callid = async_get_call(&call);
    317                 method = IPC_GET_IMETHOD(call);
    318                
    319                 if (!method) {
    320                         /* The other side has hung up. */
    321                         async_answer_0(callid, EOK);
    322                         return;
    323                 }
    324                
    325                 switch (method) {
    326                 case BD_READ_BLOCKS:
    327                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    328                             IPC_GET_ARG2(call));
    329                         cnt = IPC_GET_ARG3(call);
    330                         if (cnt * disk[disk_id].block_size > comm_size) {
    331                                 retval = ELIMIT;
    332                                 break;
    333                         }
    334                         retval = ata_bd_read_blocks(disk_id, ba, cnt, fs_va);
    335                         break;
    336                 case BD_WRITE_BLOCKS:
    337                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    338                             IPC_GET_ARG2(call));
    339                         cnt = IPC_GET_ARG3(call);
    340                         if (cnt * disk[disk_id].block_size > comm_size) {
    341                                 retval = ELIMIT;
    342                                 break;
    343                         }
    344                         retval = ata_bd_write_blocks(disk_id, ba, cnt, fs_va);
    345                         break;
    346                 case BD_GET_BLOCK_SIZE:
    347                         async_answer_1(callid, EOK, disk[disk_id].block_size);
    348                         continue;
    349                 case BD_GET_NUM_BLOCKS:
    350                         async_answer_2(callid, EOK, LOWER32(disk[disk_id].blocks),
    351                             UPPER32(disk[disk_id].blocks));
    352                         continue;
    353                 case BD_READ_TOC:
    354                         cnt = IPC_GET_ARG1(call);
    355                         if (disk[disk_id].dev_type == ata_pkt_dev)
    356                                 retval = ata_pcmd_read_toc(disk_id, cnt, fs_va,
    357                                     disk[disk_id].block_size);
    358                         else
    359                                 retval = EINVAL;
    360                         break;
    361                 default:
    362                         retval = EINVAL;
    363                         break;
    364                 }
    365                 async_answer_0(callid, retval);
    366         }
     314        bd_conn(iid, icall, &ata_disk[disk_id].bds);
    367315}
    368316
     
    384332        unsigned i;
    385333
     334        d->disk_id = disk_id;
    386335        d->present = false;
    387336        fibril_mutex_initialize(&d->lock);
     337
     338        bd_srvs_init(&d->bds);
     339        d->bds.ops = &ata_bd_ops;
     340        d->bds.sarg = d;
    388341
    389342        /* Try identify command. */
     
    514467}
    515468
     469static int ata_bd_open(bd_srvs_t *bds, bd_srv_t *bd)
     470{
     471        return EOK;
     472}
     473
     474static int ata_bd_close(bd_srv_t *bd)
     475{
     476        return EOK;
     477}
     478
    516479/** Read multiple blocks from the device. */
    517 static int ata_bd_read_blocks(int disk_id, uint64_t ba, size_t cnt,
    518     void *buf) {
    519 
     480static 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);
    520484        int rc;
    521485
     486        if (size < cnt * disk->block_size)
     487                return EINVAL;
     488
    522489        while (cnt > 0) {
    523                 if (disk[disk_id].dev_type == ata_reg_dev)
    524                         rc = ata_rcmd_read(disk_id, ba, 1, buf);
     490                if (disk->dev_type == ata_reg_dev)
     491                        rc = ata_rcmd_read(disk->disk_id, ba, 1, buf);
    525492                else
    526                         rc = ata_pcmd_read_12(disk_id, ba, 1, buf,
    527                             disk[disk_id].block_size);
     493                        rc = ata_pcmd_read_12(disk->disk_id, ba, 1, buf,
     494                            disk->block_size);
    528495
    529496                if (rc != EOK)
     
    532499                ++ba;
    533500                --cnt;
    534                 buf += disk[disk_id].block_size;
    535         }
    536 
    537         return EOK;
     501                buf += disk->block_size;
     502        }
     503
     504        return EOK;
     505}
     506
     507/** Read TOC from device. */
     508static 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);
    538513}
    539514
    540515/** Write multiple blocks to the device. */
    541 static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt,
    542     const void *buf) {
    543 
     516static 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);
    544520        int rc;
    545521
    546         if (disk[disk_id].dev_type != ata_reg_dev)
     522        if (disk->dev_type != ata_reg_dev)
    547523                return ENOTSUP;
    548524
     525        if (size < cnt * disk->block_size)
     526                return EINVAL;
     527
    549528        while (cnt > 0) {
    550                 rc = ata_rcmd_write(disk_id, ba, 1, buf);
     529                rc = ata_rcmd_write(disk->disk_id, ba, 1, buf);
    551530                if (rc != EOK)
    552531                        return rc;
     
    554533                ++ba;
    555534                --cnt;
    556                 buf += disk[disk_id].block_size;
    557         }
    558 
     535                buf += disk->block_size;
     536        }
     537
     538        return EOK;
     539}
     540
     541/** Get device block size. */
     542static 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. */
     551static 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;
    559556        return EOK;
    560557}
     
    685682        uint16_t val;
    686683
    687         d = &disk[dev_idx];
     684        d = &ata_disk[dev_idx];
    688685        fibril_mutex_lock(&d->lock);
    689686
     
    874871        block_coord_t bc;
    875872
    876         d = &disk[disk_id];
     873        d = &ata_disk[disk_id];
    877874       
    878875        /* Silence warning. */
     
    919916                /* Read data from the device buffer. */
    920917
    921                 for (i = 0; i < disk[disk_id].block_size / 2; i++) {
     918                for (i = 0; i < ata_disk[disk_id].block_size / 2; i++) {
    922919                        data = pio_read_16(&cmd->data_port);
    923920                        ((uint16_t *) buf)[i] = data;
     
    950947        block_coord_t bc;
    951948
    952         d = &disk[disk_id];
     949        d = &ata_disk[disk_id];
    953950       
    954951        /* Silence warning. */
     
    995992                /* Write data to the device buffer. */
    996993
    997                 for (i = 0; i < disk[disk_id].block_size / 2; i++) {
     994                for (i = 0; i < d->block_size / 2; i++) {
    998995                        pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]);
    999996                }
  • uspace/srv/bd/ata_bd/ata_bd.h

    rf66ca57f raffaf2e  
    3636#define __ATA_BD_H__
    3737
     38#include <bd_srv.h>
    3839#include <sys/types.h>
    3940#include <fibril_synch.h>
     
    117118        fibril_mutex_t lock;
    118119        service_id_t service_id;
     120        int disk_id;
     121        bd_srvs_t bds;
    119122} disk_t;
    120123
  • uspace/srv/bd/file_bd/file_bd.c

    rf66ca57f raffaf2e  
    4141#include <stdio.h>
    4242#include <unistd.h>
    43 #include <ipc/bd.h>
    4443#include <async.h>
    4544#include <as.h>
     45#include <bd_srv.h>
    4646#include <fibril_synch.h>
    4747#include <loc.h>
     
    6262
    6363static service_id_t service_id;
     64static bd_srvs_t bd_srvs;
    6465static fibril_mutex_t dev_lock;
    6566
     
    6768static int file_bd_init(const char *fname);
    6869static void file_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *);
    69 static int file_bd_read_blocks(uint64_t ba, size_t cnt, void *buf);
    70 static int file_bd_write_blocks(uint64_t ba, size_t cnt, const void *buf);
     70
     71static int file_bd_open(bd_srvs_t *, bd_srv_t *);
     72static int file_bd_close(bd_srv_t *);
     73static int file_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
     74static int file_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t);
     75static int file_bd_get_block_size(bd_srv_t *, size_t *);
     76static int file_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
     77
     78static 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};
    7186
    7287int main(int argc, char **argv)
     
    139154static int file_bd_init(const char *fname)
    140155{
     156        bd_srvs_init(&bd_srvs);
     157        bd_srvs.ops = &file_bd_ops;
     158       
    141159        async_set_client_connection(file_bd_connection);
    142160        int rc = loc_server_register(NAME);
     
    170188static void file_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    171189{
    172         void *fs_va = NULL;
    173         ipc_callid_t callid;
    174         ipc_call_t call;
    175         sysarg_t method;
    176         size_t comm_size;
    177         unsigned int flags;
    178         int retval;
    179         uint64_t ba;
    180         size_t cnt;
    181 
    182         /* Answer the IPC_M_CONNECT_ME_TO call. */
    183         async_answer_0(iid, EOK);
    184 
    185         if (!async_share_out_receive(&callid, &comm_size, &flags)) {
    186                 async_answer_0(callid, EHANGUP);
    187                 return;
    188         }
    189 
    190         (void) async_share_out_finalize(callid, &fs_va);
    191         if (fs_va == AS_MAP_FAILED) {
    192                 async_answer_0(callid, EHANGUP);
    193                 return;
    194         }
    195 
    196         while (true) {
    197                 callid = async_get_call(&call);
    198                 method = IPC_GET_IMETHOD(call);
    199                
    200                 if (!method) {
    201                         /* The other side has hung up. */
    202                         async_answer_0(callid, EOK);
    203                         return;
    204                 }
    205                
    206                 switch (method) {
    207                 case BD_READ_BLOCKS:
    208                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    209                             IPC_GET_ARG2(call));
    210                         cnt = IPC_GET_ARG3(call);
    211                         if (cnt * block_size > comm_size) {
    212                                 retval = ELIMIT;
    213                                 break;
    214                         }
    215                         retval = file_bd_read_blocks(ba, cnt, fs_va);
    216                         break;
    217                 case BD_WRITE_BLOCKS:
    218                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    219                             IPC_GET_ARG2(call));
    220                         cnt = IPC_GET_ARG3(call);
    221                         if (cnt * block_size > comm_size) {
    222                                 retval = ELIMIT;
    223                                 break;
    224                         }
    225                         retval = file_bd_write_blocks(ba, cnt, fs_va);
    226                         break;
    227                 case BD_GET_BLOCK_SIZE:
    228                         async_answer_1(callid, EOK, block_size);
    229                         continue;
    230                 case BD_GET_NUM_BLOCKS:
    231                         async_answer_2(callid, EOK, LOWER32(num_blocks),
    232                             UPPER32(num_blocks));
    233                         continue;
    234                 default:
    235                         retval = EINVAL;
    236                         break;
    237                 }
    238                 async_answer_0(callid, retval);
    239         }
     190        bd_conn(iid, icall, &bd_srvs);
     191}
     192
     193/** Open device. */
     194static int file_bd_open(bd_srvs_t *bds, bd_srv_t *bd)
     195{
     196        return EOK;
     197}
     198
     199/** Close device. */
     200static int file_bd_close(bd_srv_t *bd)
     201{
     202        return EOK;
    240203}
    241204
    242205/** Read blocks from the device. */
    243 static int file_bd_read_blocks(uint64_t ba, size_t cnt, void *buf)
     206static int file_bd_read_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt, void *buf,
     207    size_t size)
    244208{
    245209        size_t n_rd;
    246210        int rc;
     211
     212        if (size < cnt * block_size)
     213                return EINVAL;
    247214
    248215        /* Check whether access is within device address bounds. */
     
    279246
    280247/** Write blocks to the device. */
    281 static int file_bd_write_blocks(uint64_t ba, size_t cnt, const void *buf)
     248static int file_bd_write_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt,
     249    const void *buf, size_t size)
    282250{
    283251        size_t n_wr;
    284252        int rc;
     253
     254        if (size < cnt * block_size)
     255                return EINVAL;
    285256
    286257        /* Check whether access is within device address bounds. */
     
    318289}
    319290
     291/** Get device block size. */
     292static 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. */
     299static int file_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb)
     300{
     301        *rnb = num_blocks;
     302        return EOK;
     303}
     304
    320305/**
    321306 * @}
  • uspace/srv/bd/gxe_bd/gxe_bd.c

    rf66ca57f raffaf2e  
    3939#include <libarch/ddi.h>
    4040#include <ddi.h>
    41 #include <ipc/bd.h>
    4241#include <async.h>
    4342#include <as.h>
     43#include <bd_srv.h>
    4444#include <fibril_synch.h>
    4545#include <loc.h>
     
    6565};
    6666
     67/** GXE disk hardware registers */
    6768typedef struct {
    6869        uint32_t offset_lo;
     
    8384
    8485        uint8_t buffer[512];
     86} gxe_bd_hw_t;
     87
     88/** GXE block device soft state */
     89typedef struct {
     90        /** Block device service structure */
     91        bd_srvs_t bds;
     92        int disk_id;
    8593} gxe_bd_t;
    8694
    87 
    8895static const size_t block_size = 512;
    89 static size_t comm_size;
    9096
    9197static uintptr_t dev_physical = 0x13000000;
    92 static gxe_bd_t *dev;
     98static gxe_bd_hw_t *dev;
    9399
    94100static service_id_t service_id[MAX_DISKS];
    95101
    96102static fibril_mutex_t dev_lock[MAX_DISKS];
     103
     104static gxe_bd_t gxe_bd[MAX_DISKS];
    97105
    98106static int gxe_bd_init(void);
    99107static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *);
    100 static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt,
    101     void *buf);
    102 static int gxe_bd_write_blocks(int disk_id, uint64_t ba, unsigned cnt,
    103     const void *buf);
    104108static int gxe_bd_read_block(int disk_id, uint64_t ba, void *buf);
    105109static int gxe_bd_write_block(int disk_id, uint64_t ba, const void *buf);
     110
     111static int gxe_bd_open(bd_srvs_t *, bd_srv_t *);
     112static int gxe_bd_close(bd_srv_t *);
     113static int gxe_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
     114static int gxe_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t);
     115static int gxe_bd_get_block_size(bd_srv_t *, size_t *);
     116static int gxe_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
     117
     118static 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
     127static gxe_bd_t *bd_srv_gxe(bd_srv_t *bd)
     128{
     129        return (gxe_bd_t *)bd->srvs->sarg;
     130}
    106131
    107132int main(int argc, char **argv)
     
    130155       
    131156        void *vaddr;
    132         rc = pio_enable((void *) dev_physical, sizeof(gxe_bd_t), &vaddr);
     157        rc = pio_enable((void *) dev_physical, sizeof(gxe_bd_hw_t), &vaddr);
    133158        if (rc != EOK) {
    134159                printf("%s: Could not initialize device I/O space.\n", NAME);
     
    140165        for (unsigned int i = 0; i < MAX_DISKS; i++) {
    141166                char name[16];
     167               
     168                bd_srvs_init(&gxe_bd[i].bds);
     169                gxe_bd[i].bds.ops = &gxe_bd_ops;
     170                gxe_bd[i].bds.sarg = (void *)&gxe_bd[i];
    142171               
    143172                snprintf(name, 16, "%s/disk%u", NAMESPACE, i);
     
    157186static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    158187{
    159         void *fs_va = NULL;
    160         ipc_callid_t callid;
    161         ipc_call_t call;
    162         sysarg_t method;
    163188        service_id_t dsid;
    164         unsigned int flags;
    165         int retval;
    166         uint64_t ba;
    167         unsigned cnt;
    168189        int disk_id, i;
    169190
     
    182203        }
    183204
    184         /* Answer the IPC_M_CONNECT_ME_TO call. */
    185         async_answer_0(iid, EOK);
    186 
    187         if (!async_share_out_receive(&callid, &comm_size, &flags)) {
    188                 async_answer_0(callid, EHANGUP);
    189                 return;
    190         }
    191 
    192         if (comm_size < block_size) {
    193                 async_answer_0(callid, EHANGUP);
    194                 return;
    195         }
    196 
    197         (void) async_share_out_finalize(callid, &fs_va);
    198         if (fs_va == AS_MAP_FAILED) {
    199                 async_answer_0(callid, EHANGUP);
    200                 return;
    201         }
    202 
    203         while (true) {
    204                 callid = async_get_call(&call);
    205                 method = IPC_GET_IMETHOD(call);
    206                
    207                 if (!method) {
    208                         /* The other side has hung up. */
    209                         async_answer_0(callid, EOK);
    210                         return;
    211                 }
    212                
    213                 switch (method) {
    214                 case BD_READ_BLOCKS:
    215                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    216                             IPC_GET_ARG2(call));
    217                         cnt = IPC_GET_ARG3(call);
    218                         if (cnt * block_size > comm_size) {
    219                                 retval = ELIMIT;
    220                                 break;
    221                         }
    222                         retval = gxe_bd_read_blocks(disk_id, ba, cnt, fs_va);
    223                         break;
    224                 case BD_WRITE_BLOCKS:
    225                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    226                             IPC_GET_ARG2(call));
    227                         cnt = IPC_GET_ARG3(call);
    228                         if (cnt * block_size > comm_size) {
    229                                 retval = ELIMIT;
    230                                 break;
    231                         }
    232                         retval = gxe_bd_write_blocks(disk_id, ba, cnt, fs_va);
    233                         break;
    234                 case BD_GET_BLOCK_SIZE:
    235                         async_answer_1(callid, EOK, block_size);
    236                         continue;
    237                 case BD_GET_NUM_BLOCKS:
    238                         retval = ENOTSUP;
    239                         break;
    240                 default:
    241                         retval = EINVAL;
    242                         break;
    243                 }
    244                 async_answer_0(callid, retval);
    245         }
     205        bd_conn(iid, icall, &gxe_bd[disk_id].bds);
     206}
     207
     208/** Open device. */
     209static int gxe_bd_open(bd_srvs_t *bds, bd_srv_t *bd)
     210{
     211        return EOK;
     212}
     213
     214/** Close device. */
     215static int gxe_bd_close(bd_srv_t *bd)
     216{
     217        return EOK;
    246218}
    247219
    248220/** Read multiple blocks from the device. */
    249 static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt,
    250     void *buf) {
    251 
     221static 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;
    252225        int rc;
     226
     227        if (size < cnt * block_size)
     228                return EINVAL;
    253229
    254230        while (cnt > 0) {
     
    266242
    267243/** Write multiple blocks to the device. */
    268 static int gxe_bd_write_blocks(int disk_id, uint64_t ba, unsigned cnt,
    269     const void *buf) {
    270 
     244static 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;
    271248        int rc;
     249
     250        if (size < cnt * block_size)
     251                return EINVAL;
    272252
    273253        while (cnt > 0) {
     
    282262
    283263        return EOK;
     264}
     265
     266/** Get device block size. */
     267static 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. */
     274static int gxe_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb)
     275{
     276        return ENOTSUP;
    284277}
    285278
  • uspace/srv/bd/part/guid_part/guid_part.c

    rf66ca57f raffaf2e  
    4747#include <stdlib.h>
    4848#include <unistd.h>
    49 #include <ipc/bd.h>
    5049#include <async.h>
    5150#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 service structure */
     86        bd_srvs_t bds;
    8587        /** Points to next partition structure. */
    8688        struct part *next;
     
    100102static void gpt_pte_to_part(const gpt_entry_t *pte, part_t *part);
    101103static void gpt_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);
    102 static int gpt_bd_read(part_t *p, aoff64_t ba, size_t cnt, void *buf);
    103 static int gpt_bd_write(part_t *p, aoff64_t ba, size_t cnt, const void *buf);
    104104static int gpt_bsa_translate(part_t *p, aoff64_t ba, size_t cnt, aoff64_t *gba);
     105
     106static int gpt_bd_open(bd_srvs_t *, bd_srv_t *);
     107static int gpt_bd_close(bd_srv_t *);
     108static int gpt_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
     109static int gpt_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t);
     110static int gpt_bd_get_block_size(bd_srv_t *, size_t *);
     111static int gpt_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
     112
     113static 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
     122static part_t *bd_srv_part(bd_srv_t *bd)
     123{
     124        return (part_t *)bd->srvs->sarg;
     125}
    105126
    106127int main(int argc, char **argv)
     
    304325        }
    305326
     327        bd_srvs_init(&part->bds);
     328        part->bds.ops = &gpt_bd_ops;
     329        part->bds.sarg = part;
     330
    306331        part->dsid = 0;
    307332        part->next = NULL;
     
    310335static void gpt_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    311336{
    312         size_t comm_size;
    313         void *fs_va = NULL;
    314         ipc_callid_t callid;
    315         ipc_call_t call;
    316         sysarg_t method;
    317337        service_id_t dh;
    318         unsigned int flags;
    319         int retval;
    320         aoff64_t ba;
    321         size_t cnt;
    322338        part_t *part;
    323339
     
    341357        assert(part->present == true);
    342358
    343         /* Answer the IPC_M_CONNECT_ME_TO call. */
    344         async_answer_0(iid, EOK);
    345 
    346         if (!async_share_out_receive(&callid, &comm_size, &flags)) {
    347                 async_answer_0(callid, EHANGUP);
    348                 return;
    349         }
    350 
    351         (void) async_share_out_finalize(callid, &fs_va);
    352         if (fs_va == AS_MAP_FAILED) {
    353                 async_answer_0(callid, EHANGUP);
    354                 return;
    355         }
    356 
    357         while (true) {
    358                 callid = async_get_call(&call);
    359                 method = IPC_GET_IMETHOD(call);
    360                
    361                 if (!method) {
    362                         /* The other side has hung up. */
    363                         async_answer_0(callid, EOK);
    364                         return;
    365                 }
    366                
    367                 switch (method) {
    368                 case BD_READ_BLOCKS:
    369                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    370                             IPC_GET_ARG2(call));
    371                         cnt = IPC_GET_ARG3(call);
    372                         if (cnt * block_size > comm_size) {
    373                                 retval = ELIMIT;
    374                                 break;
    375                         }
    376                         retval = gpt_bd_read(part, ba, cnt, fs_va);
    377                         break;
    378                 case BD_WRITE_BLOCKS:
    379                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    380                             IPC_GET_ARG2(call));
    381                         cnt = IPC_GET_ARG3(call);
    382                         if (cnt * block_size > comm_size) {
    383                                 retval = ELIMIT;
    384                                 break;
    385                         }
    386                         retval = gpt_bd_write(part, ba, cnt, fs_va);
    387                         break;
    388                 case BD_GET_BLOCK_SIZE:
    389                         async_answer_1(callid, EOK, block_size);
    390                         continue;
    391                 case BD_GET_NUM_BLOCKS:
    392                         async_answer_2(callid, EOK, LOWER32(part->length),
    393                             UPPER32(part->length));
    394                         continue;
    395                 default:
    396                         retval = EINVAL;
    397                         break;
    398                 }
    399                 async_answer_0(callid, retval);
    400         }
     359        bd_conn(iid, icall, &part->bds);
     360}
     361
     362/** Open device. */
     363static int gpt_bd_open(bd_srvs_t *bds, bd_srv_t *bd)
     364{
     365        return EOK;
     366}
     367
     368/** Close device. */
     369static int gpt_bd_close(bd_srv_t *bd)
     370{
     371        return EOK;
    401372}
    402373
    403374/** Read blocks from partition. */
    404 static int gpt_bd_read(part_t *p, aoff64_t ba, size_t cnt, void *buf)
    405 {
     375static 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);
    406379        aoff64_t gba;
     380
     381        if (cnt * block_size < size)
     382                return EINVAL;
    407383
    408384        if (gpt_bsa_translate(p, ba, cnt, &gba) != EOK)
     
    413389
    414390/** Write blocks to partition. */
    415 static int gpt_bd_write(part_t *p, aoff64_t ba, size_t cnt, const void *buf)
    416 {
     391static 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);
    417395        aoff64_t gba;
     396
     397        if (cnt * block_size < size)
     398                return EINVAL;
    418399
    419400        if (gpt_bsa_translate(p, ba, cnt, &gba) != EOK)
     
    422403        return block_write_direct(indev_sid, gba, cnt, buf);
    423404}
     405
     406/** Get device block size. */
     407static 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. */
     414static 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
    424422
    425423/** Translate block segment address with range checking. */
  • uspace/srv/bd/part/mbr_part/mbr_part.c

    rf66ca57f raffaf2e  
    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>
    6059#include <async.h>
    6160#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 service sturcture */
     103        bd_srvs_t bds;
    102104        /** Points to next partition structure. */
    103105        struct part *next;
     
    140142
    141143/** Partitioned device (inbound device) */
    142 static service_id_t indef_sid;
     144static service_id_t indev_sid;
    143145
    144146/** List of partitions. This structure is an empty head. */
     
    150152static void mbr_pte_to_part(uint32_t base, const pt_entry_t *pte, part_t *part);
    151153static void mbr_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);
    152 static int mbr_bd_read(part_t *p, uint64_t ba, size_t cnt, void *buf);
    153 static int mbr_bd_write(part_t *p, uint64_t ba, size_t cnt, const void *buf);
    154154static int mbr_bsa_translate(part_t *p, uint64_t ba, size_t cnt, uint64_t *gba);
     155
     156static int mbr_bd_open(bd_srvs_t *, bd_srv_t *);
     157static int mbr_bd_close(bd_srv_t *);
     158static int mbr_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
     159static int mbr_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t);
     160static int mbr_bd_get_block_size(bd_srv_t *, size_t *);
     161static int mbr_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
     162
     163static 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
     172static part_t *bd_srv_part(bd_srv_t *bd)
     173{
     174        return (part_t *)bd->srvs->sarg;
     175}
    155176
    156177int main(int argc, char **argv)
     
    183204        part_t *part;
    184205
    185         rc = loc_service_get_id(dev_name, &indef_sid, 0);
     206        rc = loc_service_get_id(dev_name, &indev_sid, 0);
    186207        if (rc != EOK) {
    187208                printf(NAME ": could not resolve device `%s'.\n", dev_name);
     
    189210        }
    190211
    191         rc = block_init(EXCHANGE_SERIALIZE, indef_sid, 2048);
     212        rc = block_init(EXCHANGE_SERIALIZE, indev_sid, 2048);
    192213        if (rc != EOK)  {
    193214                printf(NAME ": could not init libblock.\n");
     
    197218        /* Determine and verify block size. */
    198219
    199         rc = block_get_bsize(indef_sid, &block_size);
     220        rc = block_get_bsize(indev_sid, &block_size);
    200221        if (rc != EOK) {
    201222                printf(NAME ": error getting block size.\n");
     
    281302         */
    282303
    283         rc = block_read_direct(indef_sid, 0, 1, brb);
     304        rc = block_read_direct(indev_sid, 0, 1, brb);
    284305        if (rc != EOK) {
    285306                printf(NAME ": Failed reading MBR block.\n");
     
    332353                 */
    333354                ba = cp.start_addr;
    334                 rc = block_read_direct(indef_sid, ba, 1, brb);
     355                rc = block_read_direct(indev_sid, ba, 1, brb);
    335356                if (rc != EOK) {
    336357                        printf(NAME ": Failed reading EBR block at %"
     
    381402        part->present = (pte->ptype != PT_UNUSED) ? true : false;
    382403
     404        bd_srvs_init(&part->bds);
     405        part->bds.ops = &mbr_bd_ops;
     406        part->bds.sarg = part;
     407
    383408        part->dsid = 0;
    384409        part->next = NULL;
     
    387412static void mbr_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    388413{
    389         size_t comm_size;
    390         void *fs_va = NULL;
    391         ipc_callid_t callid;
    392         ipc_call_t call;
    393         sysarg_t method;
    394414        service_id_t dh;
    395         unsigned int flags;
    396         int retval;
    397         uint64_t ba;
    398         size_t cnt;
    399415        part_t *part;
    400416
     
    417433
    418434        assert(part->present == true);
    419 
    420         /* Answer the IPC_M_CONNECT_ME_TO call. */
    421         async_answer_0(iid, EOK);
    422 
    423         if (!async_share_out_receive(&callid, &comm_size, &flags)) {
    424                 async_answer_0(callid, EHANGUP);
    425                 return;
    426         }
    427 
    428         (void) async_share_out_finalize(callid, &fs_va);
    429         if (fs_va == AS_MAP_FAILED) {
    430                 async_answer_0(callid, EHANGUP);
    431                 return;
    432         }
    433 
    434         while (1) {
    435                 callid = async_get_call(&call);
    436                 method = IPC_GET_IMETHOD(call);
    437                
    438                 if (!method) {
    439                         /* The other side has hung up. */
    440                         async_answer_0(callid, EOK);
    441                         return;
    442                 }
    443                
    444                 switch (method) {
    445                 case BD_READ_BLOCKS:
    446                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    447                             IPC_GET_ARG2(call));
    448                         cnt = IPC_GET_ARG3(call);
    449                         if (cnt * block_size > comm_size) {
    450                                 retval = ELIMIT;
    451                                 break;
    452                         }
    453                         retval = mbr_bd_read(part, ba, cnt, fs_va);
    454                         break;
    455                 case BD_WRITE_BLOCKS:
    456                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    457                             IPC_GET_ARG2(call));
    458                         cnt = IPC_GET_ARG3(call);
    459                         if (cnt * block_size > comm_size) {
    460                                 retval = ELIMIT;
    461                                 break;
    462                         }
    463                         retval = mbr_bd_write(part, ba, cnt, fs_va);
    464                         break;
    465                 case BD_GET_BLOCK_SIZE:
    466                         async_answer_1(callid, EOK, block_size);
    467                         continue;
    468                 case BD_GET_NUM_BLOCKS:
    469                         async_answer_2(callid, EOK, LOWER32(part->length),
    470                             UPPER32(part->length));
    471                         continue;
    472                 default:
    473                         retval = EINVAL;
    474                         break;
    475                 }
    476                 async_answer_0(callid, retval);
    477         }
     435        bd_conn(iid, icall, &part->bds);
     436}
     437
     438/** Open device. */
     439static int mbr_bd_open(bd_srvs_t *bds, bd_srv_t *bd)
     440{
     441        return EOK;
     442}
     443
     444/** Close device. */
     445static int mbr_bd_close(bd_srv_t *bd)
     446{
     447        return EOK;
    478448}
    479449
    480450/** Read blocks from partition. */
    481 static int mbr_bd_read(part_t *p, uint64_t ba, size_t cnt, void *buf)
    482 {
    483         uint64_t gba;
     451static 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;
    484459
    485460        if (mbr_bsa_translate(p, ba, cnt, &gba) != EOK)
    486461                return ELIMIT;
    487462
    488         return block_read_direct(indef_sid, gba, cnt, buf);
     463        return block_read_direct(indev_sid, gba, cnt, buf);
    489464}
    490465
    491466/** Write blocks to partition. */
    492 static int mbr_bd_write(part_t *p, uint64_t ba, size_t cnt, const void *buf)
    493 {
    494         uint64_t gba;
     467static 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;
    495475
    496476        if (mbr_bsa_translate(p, ba, cnt, &gba) != EOK)
    497477                return ELIMIT;
    498478
    499         return block_write_direct(indef_sid, gba, cnt, buf);
     479        return block_write_direct(indev_sid, gba, cnt, buf);
     480}
     481
     482/** Get device block size. */
     483static 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. */
     490static 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;
    500496}
    501497
  • uspace/srv/bd/rd/rd.c

    rf66ca57f raffaf2e  
    4343#include <sysinfo.h>
    4444#include <as.h>
     45#include <bd_srv.h>
    4546#include <ddi.h>
    4647#include <align.h>
     
    5354#include <stdio.h>
    5455#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_read_blocks(uint64_t ba, size_t cnt, void *buf);
    71 static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf);
     70static int rd_open(bd_srvs_t *, bd_srv_t *);
     71static int rd_close(bd_srv_t *);
     72static int rd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
     73static int rd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t);
     74static int rd_get_block_size(bd_srv_t *, size_t *);
     75static int rd_get_num_blocks(bd_srv_t *, aoff64_t *);
    7276
    7377/** This rwlock protects the ramdisk's data.
     
    7882 *
    7983 */
    80 fibril_rwlock_t rd_lock;
    81 
    82 /** Handle one connection to ramdisk.
    83  *
    84  * @param iid   Hash of the request that opened the connection.
    85  * @param icall Call data of the request that opened the connection.
    86  */
    87 static void rd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    88 {
    89         ipc_callid_t callid;
    90         ipc_call_t call;
    91         int retval;
    92         void *fs_va = NULL;
    93         uint64_t ba;
    94         size_t cnt;
    95         size_t comm_size;
    96        
    97         /*
    98          * Answer the first IPC_M_CONNECT_ME_TO call.
    99          */
    100         async_answer_0(iid, EOK);
    101        
    102         /*
    103          * Now we wait for the client to send us its communication as_area.
    104          */
    105         unsigned int flags;
    106         if (async_share_out_receive(&callid, &comm_size, &flags)) {
    107                 (void) async_share_out_finalize(callid, &fs_va);
    108                 if (fs_va == AS_MAP_FAILED) {
    109                         async_answer_0(callid, EHANGUP);
    110                         return;
    111                 }
    112         } else {
    113                 /*
    114                  * The client doesn't speak the same protocol.
    115                  * At this point we can't handle protocol variations.
    116                  * Close the connection.
    117                  */
    118                 async_answer_0(callid, EHANGUP);
    119                 return;
    120         }
    121        
    122         while (true) {
    123                 callid = async_get_call(&call);
    124                
    125                 if (!IPC_GET_IMETHOD(call)) {
    126                         /*
    127                          * The other side has hung up.
    128                          * Exit the fibril.
    129                          */
    130                         async_answer_0(callid, EOK);
    131                         return;
    132                 }
    133                
    134                 switch (IPC_GET_IMETHOD(call)) {
    135                 case BD_READ_BLOCKS:
    136                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    137                             IPC_GET_ARG2(call));
    138                         cnt = IPC_GET_ARG3(call);
    139                         if (cnt * block_size > comm_size) {
    140                                 retval = ELIMIT;
    141                                 break;
    142                         }
    143                         retval = rd_read_blocks(ba, cnt, fs_va);
    144                         break;
    145                 case BD_WRITE_BLOCKS:
    146                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    147                             IPC_GET_ARG2(call));
    148                         cnt = IPC_GET_ARG3(call);
    149                         if (cnt * block_size > comm_size) {
    150                                 retval = ELIMIT;
    151                                 break;
    152                         }
    153                         retval = rd_write_blocks(ba, cnt, fs_va);
    154                         break;
    155                 case BD_GET_BLOCK_SIZE:
    156                         async_answer_1(callid, EOK, block_size);
    157                         continue;
    158                 case BD_GET_NUM_BLOCKS:
    159                         async_answer_2(callid, EOK, LOWER32(rd_size / block_size),
    160                             UPPER32(rd_size / block_size));
    161                         continue;
    162                 default:
    163                         /*
    164                          * The client doesn't speak the same protocol.
    165                          * Instead of closing the connection, we just ignore
    166                          * the call. This can be useful if the client uses a
    167                          * newer version of the protocol.
    168                          */
    169                         retval = EINVAL;
    170                         break;
    171                 }
    172                 async_answer_0(callid, retval);
    173         }
     84static fibril_rwlock_t rd_lock;
     85
     86static 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
     95static bd_srvs_t bd_srvs;
     96
     97static void rd_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     98{
     99        bd_conn(iid, icall, &bd_srvs);
     100}
     101
     102/** Open device. */
     103static int rd_open(bd_srvs_t *bds, bd_srv_t *bd)
     104{
     105        return EOK;
     106}
     107
     108/** Close device. */
     109static int rd_close(bd_srv_t *bd)
     110{
     111        return EOK;
    174112}
    175113
    176114/** Read blocks from the device. */
    177 static int rd_read_blocks(uint64_t ba, size_t cnt, void *buf)
     115static int rd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, void *buf,
     116    size_t size)
    178117{
    179118        if ((ba + cnt) * block_size > rd_size) {
     
    183122       
    184123        fibril_rwlock_read_lock(&rd_lock);
    185         memcpy(buf, rd_addr + ba * block_size, block_size * cnt);
     124        memcpy(buf, rd_addr + ba * block_size, min(block_size * cnt, size));
    186125        fibril_rwlock_read_unlock(&rd_lock);
    187126       
     
    190129
    191130/** Write blocks to the device. */
    192 static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf)
     131static int rd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt,
     132    const void *buf, size_t size)
    193133{
    194134        if ((ba + cnt) * block_size > rd_size) {
     
    198138       
    199139        fibril_rwlock_write_lock(&rd_lock);
    200         memcpy(rd_addr + ba * block_size, buf, block_size * cnt);
     140        memcpy(rd_addr + ba * block_size, buf, min(block_size * cnt, size));
    201141        fibril_rwlock_write_unlock(&rd_lock);
    202142       
     
    235175            (void *) addr_phys, size);
    236176       
    237         async_set_client_connection(rd_connection);
     177        bd_srvs_init(&bd_srvs);
     178        bd_srvs.ops = &rd_bd_ops;
     179       
     180        async_set_client_connection(rd_client_conn);
    238181        ret = loc_server_register(NAME);
    239182        if (ret != EOK) {
     
    254197}
    255198
     199/** Get device block size. */
     200static 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. */
     207static int rd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb)
     208{
     209        *rnb = rd_size / block_size;
     210        return EOK;
     211}
     212
    256213int main(int argc, char **argv)
    257214{
  • uspace/srv/bd/sata_bd/sata_bd.c

    rf66ca57f raffaf2e  
    3838
    3939#include <sys/types.h>
     40#include <bd_srv.h>
    4041#include <errno.h>
    4142#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
     59static int sata_bd_open(bd_srvs_t *, bd_srv_t *);
     60static int sata_bd_close(bd_srv_t *);
     61static int sata_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
     62static int sata_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t);
     63static int sata_bd_get_block_size(bd_srv_t *, size_t *);
     64static int sata_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
     65
     66static 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
     75static sata_bd_dev_t *bd_srv_sata(bd_srv_t *bd)
     76{
     77        return (sata_bd_dev_t *)bd->srvs->sarg;
     78}
    5879
    5980/** Find SATA devices in device tree.
     
    82103               
    83104                ahci_get_num_blocks(disk[disk_count].sess, &disk[disk_count].blocks);
    84                                
     105               
     106                bd_srvs_init(&disk[disk_count].bds);
     107                disk[disk_count].bds.ops = &sata_bd_ops;
     108                disk[disk_count].bds.sarg = &disk[disk_count];
     109               
    85110                printf("Device %s - %s , blocks: %lu, block_size: %lu\n",
    86111                    disk[disk_count].dev_name, disk[disk_count].sata_dev_name,
     
    141166static void sata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    142167{
    143         void *fs_va = NULL;
    144         ipc_callid_t callid;
    145         ipc_call_t call;
    146         sysarg_t method;
    147168        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;
    154169        int disk_id, i;
    155170
     
    168183        }
    169184
    170         /* Answer the IPC_M_CONNECT_ME_TO call. */
    171         async_answer_0(iid, EOK);
    172 
    173         if (!async_share_out_receive(&callid, &comm_size, &flags)) {
    174                 async_answer_0(callid, EHANGUP);
    175                 return;
    176         }
    177 
    178         (void) async_share_out_finalize(callid, &fs_va);
    179         if (fs_va == (void *) -1) {
    180                 async_answer_0(callid, EHANGUP);
    181                 return;
    182         }
    183 
    184         while (true) {
    185                 callid = async_get_call(&call);
    186                 method = IPC_GET_IMETHOD(call);
    187                
    188                 if (!method) {
    189                         /* The other side has hung up. */
    190                         async_answer_0(callid, EOK);
    191                         return;
    192                 }
    193                
    194                 switch (method) {
    195                         case BD_READ_BLOCKS:
    196                                 ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
    197                                 cnt = IPC_GET_ARG3(call);
    198                                 if (cnt * disk[disk_id].block_size > comm_size) {
    199                                         retval = ELIMIT;
    200                                         break;
    201                                 }
    202                                 retval = ahci_read_blocks(disk[disk_id].sess, ba, cnt, fs_va);
    203                                 break;
    204                         case BD_WRITE_BLOCKS:
    205                                 ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
    206                                 cnt = IPC_GET_ARG3(call);
    207                                 if (cnt * disk[disk_id].block_size > comm_size) {
    208                                         retval = ELIMIT;
    209                                         break;
    210                                 }
    211                                 retval = ahci_write_blocks(disk[disk_id].sess, ba, cnt, fs_va);
    212                                 break;
    213                         case BD_GET_BLOCK_SIZE:
    214                                 async_answer_1(callid, EOK, disk[disk_id].block_size);
    215                                 continue;
    216                         case BD_GET_NUM_BLOCKS:
    217                                 async_answer_2(callid, EOK, LOWER32(disk[disk_id].blocks),
    218                                     UPPER32(disk[disk_id].blocks));
    219                                 break;
    220                         default:
    221                                 retval = EINVAL;
    222                                 break;
    223                         }
    224                 async_answer_0(callid, retval);
    225         }
    226 }
     185        bd_conn(iid, icall, &disk[disk_id].bds);
     186}
     187
     188/** Open device. */
     189static int sata_bd_open(bd_srvs_t *bds, bd_srv_t *bd)
     190{
     191        return EOK;
     192}
     193
     194/** Close device. */
     195static int sata_bd_close(bd_srv_t *bd)
     196{
     197        return EOK;
     198}
     199
     200/** Read blocks from partition. */
     201static 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. */
     213static 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. */
     225static 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. */
     234static 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
    227242
    228243int main(int argc, char **argv)
  • uspace/srv/bd/sata_bd/sata_bd.h

    rf66ca57f raffaf2e  
    3838#define SATA_DEV_NAME_LENGTH 256
    3939
     40#include <async.h>
     41#include <bd_srv.h>
     42#include <loc.h>
    4043#include <sys/types.h>
    41 #include <loc.h>
    4244
    4345/** SATA Block Device. */
    4446typedef struct {
    45         /** Device name in device tree. */ 
    46         char* dev_name;
    47         /** SATA Device name. */ 
    48         char sata_dev_name[SATA_DEV_NAME_LENGTH]; 
     47        /** Device name in device tree. */
     48        char *dev_name;
     49        /** SATA Device name. */
     50        char sata_dev_name[SATA_DEV_NAME_LENGTH];
    4951        /** Session to device methods. */
    50         async_sess_t* sess;
     52        async_sess_t *sess;
    5153        /** Loc service id. */
    5254        service_id_t service_id;
    5355        /** Number of blocks. */
    54         uint64_t blocks; 
     56        uint64_t blocks;
    5557        /** Size of block. */
    56         size_t block_size;
     58        size_t block_size;
     59        /** Block device server structure */
     60        bd_srvs_t bds;
    5761} sata_bd_dev_t;
    5862
  • uspace/srv/devman/devman.c

    rf66ca57f raffaf2e  
    10521052}
    10531053
    1054 
    10551054/** Find the device node structure of the device witch has the specified handle.
    10561055 *
     
    11421141        fun->state = FUN_INIT;
    11431142        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. */
     1189void fun_busy_lock(fun_node_t *fun)
     1190{
     1191        fibril_mutex_lock(&fun->busy_lock);
     1192}
     1193
     1194/** Mark end of reconfiguration operation. */
     1195void fun_busy_unlock(fun_node_t *fun)
     1196{
     1197        fibril_mutex_unlock(&fun->busy_lock);
    11861198}
    11871199
  • uspace/srv/devman/devman.h

    rf66ca57f raffaf2e  
    174174        /** State */
    175175        fun_state_t state;
     176        /** Locked while performing reconfiguration operations */
     177        fibril_mutex_t busy_lock;
    176178       
    177179        /** The global unique identifier of the function */
     
    279281extern void dev_add_ref(dev_node_t *);
    280282extern void dev_del_ref(dev_node_t *);
     283
    281284extern dev_node_t *find_dev_node_no_lock(dev_tree_t *tree,
    282285    devman_handle_t handle);
     
    290293extern void fun_add_ref(fun_node_t *);
    291294extern void fun_del_ref(fun_node_t *);
     295extern void fun_busy_lock(fun_node_t *);
     296extern void fun_busy_unlock(fun_node_t *);
    292297extern fun_node_t *find_fun_node_no_lock(dev_tree_t *tree,
    293298    devman_handle_t handle);
  • uspace/srv/devman/main.c

    rf66ca57f raffaf2e  
    432432       
    433433        fun_node_t *fun = create_fun_node();
     434        /* One reference for creation, one for us */
     435        fun_add_ref(fun);
    434436        fun_add_ref(fun);
    435437        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);
    436444       
    437445        if (!insert_fun_node(&device_tree, fun, fun_name, pdev)) {
    438446                fibril_rwlock_write_unlock(&tree->rwlock);
    439447                dev_del_ref(pdev);
     448                fun_busy_unlock(fun);
     449                fun_del_ref(fun);
    440450                delete_fun_node(fun);
    441451                async_answer_0(callid, ENOMEM);
     
    450460        rc = online_function(fun);
    451461        if (rc != EOK) {
    452                 /* XXX clean up */
     462                /* XXX Set some failed state? */
     463                fun_busy_unlock(fun);
     464                fun_del_ref(fun);
    453465                async_answer_0(callid, rc);
    454466                return;
    455467        }
     468       
     469        fun_busy_unlock(fun);
     470        fun_del_ref(fun);
    456471       
    457472        /* Return device handle to parent's driver. */
     
    522537        }
    523538       
     539        fun_busy_lock(fun);
     540       
    524541        fibril_rwlock_read_lock(&device_tree.rwlock);
    525542        if (fun->dev == NULL || fun->dev->drv != drv) {
    526543                fibril_rwlock_read_unlock(&device_tree.rwlock);
     544                fun_busy_unlock(fun);
    527545                fun_del_ref(fun);
    528546                async_answer_0(iid, ENOENT);
     
    533551        rc = online_function(fun);
    534552        if (rc != EOK) {
     553                fun_busy_unlock(fun);
    535554                fun_del_ref(fun);
    536555                async_answer_0(iid, (sysarg_t) rc);
     
    538557        }
    539558       
     559        fun_busy_unlock(fun);
    540560        fun_del_ref(fun);
    541561       
     
    559579        }
    560580       
     581        fun_busy_lock(fun);
     582       
    561583        fibril_rwlock_write_lock(&device_tree.rwlock);
    562584        if (fun->dev == NULL || fun->dev->drv != drv) {
     585                fun_busy_unlock(fun);
    563586                fun_del_ref(fun);
    564587                async_answer_0(iid, ENOENT);
     
    569592        rc = offline_function(fun);
    570593        if (rc != EOK) {
     594                fun_busy_unlock(fun);
    571595                fun_del_ref(fun);
    572596                async_answer_0(iid, (sysarg_t) rc);
     
    574598        }
    575599       
     600        fun_busy_unlock(fun);
    576601        fun_del_ref(fun);
    577602        async_answer_0(iid, (sysarg_t) EOK);
     
    591616        }
    592617       
     618        fun_busy_lock(fun);
     619       
    593620        fibril_rwlock_write_lock(&tree->rwlock);
    594621       
     
    598625        if (fun->state == FUN_REMOVED) {
    599626                fibril_rwlock_write_unlock(&tree->rwlock);
     627                fun_busy_unlock(fun);
     628                fun_del_ref(fun);
    600629                async_answer_0(callid, ENOENT);
    601630                return;
     
    638667                                if (gone_rc == EOK)
    639668                                        gone_rc = ENOTSUP;
     669                                fun_busy_unlock(fun);
     670                                fun_del_ref(fun);
    640671                                async_answer_0(callid, gone_rc);
    641672                                return;
     
    664695                                    "service.");
    665696                                fibril_rwlock_write_unlock(&tree->rwlock);
     697                                fun_busy_unlock(fun);
    666698                                fun_del_ref(fun);
    667699                                async_answer_0(callid, EIO);
     
    673705        remove_fun_node(&device_tree, fun);
    674706        fibril_rwlock_write_unlock(&tree->rwlock);
     707        fun_busy_unlock(fun);
    675708       
    676709        /* Delete ref added when inserting function into tree */
  • uspace/srv/fs/tmpfs/tmpfs_dump.c

    rf66ca57f raffaf2e  
    4949#define TMPFS_COMM_SIZE         1024
    5050
     51static uint8_t tmpfs_buf[TMPFS_COMM_SIZE];
     52
    5153struct rdentry {
    5254        uint8_t type;
     
    6870                uint32_t size;
    6971               
    70                 if (block_seqread(dsid, bufpos, buflen, pos, &entry,
     72                if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, &entry,
    7173                    sizeof(entry)) != EOK)
    7274                        return false;
     
    8890                        }
    8991                       
    90                         if (block_seqread(dsid, bufpos, buflen, pos, fname,
     92                        if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, fname,
    9193                            entry.len) != EOK) {
    9294                                (void) ops->destroy(fn);
     
    104106                        free(fname);
    105107                       
    106                         if (block_seqread(dsid, bufpos, buflen, pos, &size,
     108                        if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, &size,
    107109                            sizeof(size)) != EOK)
    108110                                return false;
     
    116118                       
    117119                        nodep->size = size;
    118                         if (block_seqread(dsid, bufpos, buflen, pos, nodep->data,
     120                        if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, nodep->data,
    119121                            size) != EOK)
    120122                                return false;
     
    132134                        }
    133135                       
    134                         if (block_seqread(dsid, bufpos, buflen, pos, fname,
     136                        if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, fname,
    135137                            entry.len) != EOK) {
    136138                                (void) ops->destroy(fn);
     
    176178       
    177179        char tag[6];
    178         if (block_seqread(dsid, &bufpos, &buflen, &pos, tag, 5) != EOK)
     180        if (block_seqread(dsid, tmpfs_buf, &bufpos, &buflen, &pos, tag, 5) != EOK)
    179181                goto error;
    180182       
Note: See TracChangeset for help on using the changeset viewer.