Changeset 48bcf49 in mainline for kernel/generic/src/ipc


Ignore:
Timestamp:
2017-09-28T22:08:15Z (8 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6636fb19
Parents:
dd20cbb
Message:

Introduce reference-counted kobjects

Capabilities are thus reduced to task-local names for references to kobjects.

Location:
kernel/generic/src/ipc
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/ipc/ipc.c

    rdd20cbb r48bcf49  
    154154/** Connect a phone to an answerbox.
    155155 *
    156  * @param phone Initialized phone structure.
    157  * @param box   Initialized answerbox structure.
    158  * @return      True if the phone was connected, false otherwise.
     156 * This function must be passed a reference to phone->kobject.
     157 *
     158 * @param phone  Initialized phone structure.
     159 * @param box    Initialized answerbox structure.
     160 * @return       True if the phone was connected, false otherwise.
    159161 */
    160162bool ipc_phone_connect(phone_t *phone, answerbox_t *box)
     
    169171                phone->state = IPC_PHONE_CONNECTED;
    170172                phone->callee = box;
     173                /* Pass phone->kobject reference to box->connected_phones */
    171174                list_append(&phone->link, &box->connected_phones);
    172175        }
     
    174177        irq_spinlock_unlock(&box->lock, true);
    175178        mutex_unlock(&phone->lock);
     179
     180        if (!active) {
     181                /* We still have phone->kobject's reference; drop it */
     182                kobject_put(phone->kobject);
     183        }
    176184
    177185        return active;
     
    191199        phone->state = IPC_PHONE_FREE;
    192200        atomic_set(&phone->active_calls, 0);
     201        phone->kobject = NULL;
    193202}
    194203
     
    456465                list_remove(&phone->link);
    457466                irq_spinlock_unlock(&box->lock, true);
     467
     468                /* Drop the answerbox reference */
     469                kobject_put(phone->kobject);
    458470               
    459471                call_t *call = ipc_call_alloc(0);
     
    658670
    659671                        task_release(phone->caller);
     672
     673                        kobject_put(phone->kobject);
    660674                       
    661675                        /* Must start again */
     
    664678               
    665679                mutex_unlock(&phone->lock);
     680                kobject_put(phone->kobject);
    666681        }
    667682       
     
    734749static bool phone_cap_wait_cb(cap_t *cap, void *arg)
    735750{
    736         phone_t *phone = (phone_t *) cap->kobject;
     751        phone_t *phone = cap->kobject->phone;
    737752        bool *restart = (bool *) arg;
    738753
     
    790805         */
    791806        restart = false;
    792         if (caps_apply_to_type(TASK, CAP_TYPE_PHONE, phone_cap_wait_cb,
    793             &restart)) {
     807        if (caps_apply_to_kobject_type(TASK, KOBJECT_TYPE_PHONE,
     808            phone_cap_wait_cb, &restart)) {
    794809                /* Got into cleanup */
    795810                return;
     
    810825static bool phone_cap_cleanup_cb(cap_t *cap, void *arg)
    811826{
    812         phone_t *phone = (phone_t *) cap->kobject;
    813         ipc_phone_hangup(phone);
     827        ipc_phone_hangup(cap->kobject->phone);
    814828        return true;
    815829}
     
    840854
    841855        /* Disconnect all our phones ('ipc_phone_hangup') */
    842         caps_apply_to_type(TASK, CAP_TYPE_PHONE, phone_cap_cleanup_cb, NULL);
     856        caps_apply_to_kobject_type(TASK, KOBJECT_TYPE_PHONE,
     857            phone_cap_cleanup_cb, NULL);
    843858       
    844859        /* Unsubscribe from any event notifications. */
     
    846861       
    847862        /* Disconnect all connected IRQs */
    848         caps_apply_to_type(TASK, CAP_TYPE_IRQ, irq_cap_cleanup_cb, NULL);
     863        caps_apply_to_kobject_type(TASK, KOBJECT_TYPE_IRQ, irq_cap_cleanup_cb,
     864            NULL);
    849865       
    850866        /* Disconnect all phones connected to our regular answerbox */
     
    912928static bool print_task_phone_cb(cap_t *cap, void *arg)
    913929{
    914         phone_t *phone = (phone_t *) cap->kobject;
     930        phone_t *phone = cap->kobject->phone;
    915931
    916932        mutex_lock(&phone->lock);
     
    963979        printf("[phone cap] [calls] [state\n");
    964980       
    965         caps_apply_to_type(task, CAP_TYPE_PHONE, print_task_phone_cb, NULL);
     981        caps_apply_to_kobject_type(task, KOBJECT_TYPE_PHONE,
     982            print_task_phone_cb, NULL);
    966983       
    967984        irq_spinlock_lock(&task->lock, true);
  • kernel/generic/src/ipc/ipcrsc.c

    rdd20cbb r48bcf49  
    164164}
    165165
    166 /** Get phone from the current task by capability handle.
    167  *
    168  * @param handle  Phone capability handle.
    169  * @param phone   Place to store pointer to phone.
    170  *
    171  * @return  Address of the phone kernel object.
    172  * @return  NULL if the capability is invalid.
    173  *
    174  */
    175 phone_t *phone_get(task_t *task, int handle)
    176 {
    177         phone_t *phone;
    178 
    179         caps_lock(task);
    180         cap_t *cap = cap_get(task, handle, CAP_TYPE_PHONE);
    181         phone = (phone_t *) cap->kobject;
    182         caps_unlock(task);
    183         if (!cap)
    184                 return NULL;
    185        
    186         return phone;
    187 }
    188 
    189 phone_t *phone_get_current(int handle)
    190 {
    191         return phone_get(TASK, handle);
    192 }
    193 
    194 static bool phone_can_reclaim(cap_t *cap)
    195 {
    196         assert(cap->type == CAP_TYPE_PHONE);
    197 
    198         phone_t *phone = (phone_t *) cap->kobject;
    199 
    200         return (phone->state == IPC_PHONE_HUNGUP) &&
    201             (atomic_get(&phone->active_calls) == 0);
    202 }
     166static bool phone_reclaim(kobject_t *kobj)
     167{
     168        bool gc = false;
     169
     170        mutex_lock(&kobj->phone->lock);
     171        if (kobj->phone->state == IPC_PHONE_HUNGUP &&
     172            atomic_get(&kobj->phone->active_calls) == 0)
     173                gc = true;
     174        mutex_unlock(&kobj->phone->lock);
     175
     176        return gc;
     177}
     178
     179static void phone_destroy(void *arg)
     180{
     181        phone_t *phone = (phone_t *) arg;
     182        slab_free(phone_slab, phone);
     183}
     184
     185static kobject_ops_t phone_kobject_ops = {
     186        .reclaim = phone_reclaim,
     187        .destroy = phone_destroy
     188};
     189
    203190
    204191/** Allocate new phone in the specified task.
     
    209196 * @return  Negative error code if a new capability cannot be allocated.
    210197 */
    211 int phone_alloc(task_t *task)
    212 {
    213         int handle = cap_alloc(task);
     198cap_handle_t phone_alloc(task_t *task)
     199{
     200        cap_handle_t handle = cap_alloc(task);
    214201        if (handle >= 0) {
    215202                phone_t *phone = slab_alloc(phone_slab, FRAME_ATOMIC);
     
    218205                        return ENOMEM;
    219206                }
    220                
     207                kobject_t *kobject = malloc(sizeof(kobject_t), FRAME_ATOMIC);
     208                if (!kobject) {
     209                        cap_free(TASK, handle);
     210                        slab_free(phone_slab, phone);
     211                        return ENOMEM;
     212                }
     213
    221214                ipc_phone_init(phone, task);
    222215                phone->state = IPC_PHONE_CONNECTING;
     216
     217                kobject_initialize(kobject, KOBJECT_TYPE_PHONE, phone,
     218                    &phone_kobject_ops);
     219                phone->kobject = kobject;
    223220               
    224                 // FIXME: phase this out eventually
    225                 mutex_lock(&task->cap_info->lock);
    226                 cap_t *cap = cap_get(task, handle, CAP_TYPE_ALLOCATED);
    227                 cap->can_reclaim = phone_can_reclaim;
    228                 mutex_unlock(&task->cap_info->lock);
    229 
    230                 cap_publish(task, handle, CAP_TYPE_PHONE, phone);
     221                cap_publish(task, handle, kobject);
    231222        }
    232223       
     
    241232 *
    242233 */
    243 void phone_dealloc(int handle)
    244 {
    245         cap_t *cap = cap_unpublish(TASK, handle, CAP_TYPE_PHONE);
    246         assert(cap);
    247        
    248         phone_t *phone = (phone_t *) cap->kobject;
    249        
    250         assert(phone);
    251         assert(phone->state == IPC_PHONE_CONNECTING);
    252        
    253         slab_free(phone_slab, phone);
     234void phone_dealloc(cap_handle_t handle)
     235{
     236        kobject_t *kobj = cap_unpublish(TASK, handle, KOBJECT_TYPE_PHONE);
     237        if (!kobj)
     238                return;
     239       
     240        assert(kobj->phone);
     241        assert(kobj->phone->state == IPC_PHONE_CONNECTING);
     242       
     243        kobject_put(kobj);
    254244        cap_free(TASK, handle);
    255245}
     
    260250 * @param box     Answerbox to which to connect the phone.
    261251 * @return        True if the phone was connected, false otherwise.
    262  *
    263  * The procedure _enforces_ that the user first marks the phone busy (e.g. via
    264  * phone_alloc) and then connects the phone, otherwise race condition may
    265  * appear.
    266  *
    267  */
    268 bool phone_connect(int handle, answerbox_t *box)
    269 {
    270         phone_t *phone = phone_get_current(handle);
    271        
    272         assert(phone);
    273         assert(phone->state == IPC_PHONE_CONNECTING);
    274        
    275         return ipc_phone_connect(phone, box);
     252 */
     253bool phone_connect(cap_handle_t handle, answerbox_t *box)
     254{
     255        kobject_t *phone_obj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
     256        if (!phone_obj)
     257                return false;
     258       
     259        assert(phone_obj->phone->state == IPC_PHONE_CONNECTING);
     260       
     261        /* Hand over phone_obj reference to the answerbox */
     262        return ipc_phone_connect(phone_obj->phone, box);
    276263}
    277264
  • kernel/generic/src/ipc/irq.c

    rdd20cbb r48bcf49  
    271271}
    272272
     273static void irq_destroy(void *arg)
     274{
     275        irq_t *irq = (irq_t *) arg;
     276
     277        /* Free up the IRQ code and associated structures. */
     278        code_free(irq->notif_cfg.code);
     279        slab_free(irq_slab, irq);
     280}
     281
     282static kobject_ops_t irq_kobject_ops = {
     283        .destroy = irq_destroy
     284};
     285
    273286/** Subscribe an answerbox as a receiving end for IRQ notifications.
    274287 *
     
    304317         * Allocate and populate the IRQ kernel object.
    305318         */
    306         int handle = cap_alloc(TASK);
     319        cap_handle_t handle = cap_alloc(TASK);
    307320        if (handle < 0)
    308321                return handle;
     
    311324        if (!irq) {
    312325                cap_free(TASK, handle);
     326                return ENOMEM;
     327        }
     328
     329        kobject_t *kobject = malloc(sizeof(kobject_t), FRAME_ATOMIC);
     330        if (!kobject) {
     331                cap_free(TASK, handle);
     332                slab_free(irq_slab, irq);
    313333                return ENOMEM;
    314334        }
     
    330350        irq_spinlock_lock(&irq->lock, false);
    331351       
     352        irq->notif_cfg.hashed_in = true;
    332353        hash_table_insert(&irq_uspace_hash_table, key, &irq->link);
    333354       
     
    335356        irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
    336357
    337         cap_publish(TASK, handle, CAP_TYPE_IRQ, irq);
     358        kobject_initialize(kobject, KOBJECT_TYPE_IRQ, irq, &irq_kobject_ops);
     359        cap_publish(TASK, handle, kobject);
    338360       
    339361        return handle;
     
    350372int ipc_irq_unsubscribe(answerbox_t *box, int handle)
    351373{
    352         cap_t *cap = cap_unpublish(TASK, handle, CAP_TYPE_IRQ);
    353         if (!cap)
     374        kobject_t *kobj = cap_unpublish(TASK, handle, KOBJECT_TYPE_IRQ);
     375        if (!kobj)
    354376                return ENOENT;
    355377       
    356         irq_t *irq = (irq_t *) cap->kobject;
    357        
     378        assert(kobj->irq->notif_cfg.answerbox == box);
     379
    358380        irq_spinlock_lock(&irq_uspace_hash_table_lock, true);
    359         irq_spinlock_lock(&irq->lock, false);
    360        
    361         assert(irq->notif_cfg.answerbox == box);
    362        
    363         /* Remove the IRQ from the uspace IRQ hash table. */
    364         hash_table_remove_item(&irq_uspace_hash_table, &irq->link);
    365        
    366         /* irq->lock unlocked by the hash table remove_callback */
     381        irq_spinlock_lock(&kobj->irq->lock, false);
     382       
     383        if (kobj->irq->notif_cfg.hashed_in) {
     384                /* Remove the IRQ from the uspace IRQ hash table. */
     385                hash_table_remove_item(&irq_uspace_hash_table,
     386                    &kobj->irq->link);
     387                kobj->irq->notif_cfg.hashed_in = false;
     388        }
     389
     390        /* kobj->irq->lock unlocked by the hash table remove_callback */
    367391        irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
    368        
    369         /* Free up the IRQ code and associated structures. */
    370         code_free(irq->notif_cfg.code);
    371        
    372         /* Free up the IRQ capability and the underlying kernel object. */
    373         slab_free(irq_slab, cap->kobject);
     392
     393        kobject_put(kobj);
    374394        cap_free(TASK, handle);
    375395       
  • kernel/generic/src/ipc/kbox.c

    rdd20cbb r48bcf49  
    206206 * cleanup code.
    207207 *
    208  * @return Phone capability on success, or negative error code.
     208 * @return Phone capability handle on success, or negative error code.
    209209 *
    210210 */
     
    236236        }
    237237       
    238         int cap = phone_alloc(TASK);
    239         if (cap < 0) {
    240                 mutex_unlock(&task->kb.cleanup_lock);
    241                 return ELIMIT;
    242         }
    243        
     238        cap_handle_t phone_handle = phone_alloc(TASK);
     239        if (phone_handle < 0) {
     240                mutex_unlock(&task->kb.cleanup_lock);
     241                return phone_handle;
     242        }
     243       
     244        kobject_t *phone_obj = kobject_get(TASK, phone_handle,
     245            KOBJECT_TYPE_PHONE);
    244246        /* Connect the newly allocated phone to the kbox */
    245         (void) ipc_phone_connect(phone_get_current(cap), &task->kb.box);
     247        /* Hand over phone_obj's reference to ipc_phone_connect() */
     248        (void) ipc_phone_connect(phone_obj->phone, &task->kb.box);
    246249       
    247250        if (task->kb.thread != NULL) {
    248251                mutex_unlock(&task->kb.cleanup_lock);
    249                 return cap;
     252                return phone_handle;
    250253        }
    251254       
     
    263266        mutex_unlock(&task->kb.cleanup_lock);
    264267       
    265         return cap;
     268        return phone_handle;
    266269}
    267270
  • kernel/generic/src/ipc/ops/conctmeto.c

    rdd20cbb r48bcf49  
    11/*
    22 * Copyright (c) 2006 Ondrej Palkovsky
    3  * Copyright (c) 2012 Jakub Jermar 
     3 * Copyright (c) 2012 Jakub Jermar
    44 * All rights reserved.
    55 *
     
    4242static int request_preprocess(call_t *call, phone_t *phone)
    4343{
    44         int cap = phone_alloc(TASK);
     44        cap_handle_t phone_handle = phone_alloc(TASK);
    4545
    4646        /* Remember the phone capability or the error. */
    47         call->priv = cap;
    48         if (cap < 0)
    49                 return ELIMIT;
    50                
     47        call->priv = phone_handle;
     48        if (phone_handle < 0)
     49                return phone_handle;
     50
    5151        /* Set arg5 for server */
    52         IPC_SET_ARG5(call->data, (sysarg_t) phone_get_current(cap));
     52        kobject_t *phone_obj = kobject_get(TASK, phone_handle,
     53            KOBJECT_TYPE_PHONE);
     54        /* Hand over phone_obj's reference to ARG5 */
     55        IPC_SET_ARG5(call->data, (sysarg_t) phone_obj->phone);
    5356
    5457        return EOK;
     
    5760static int request_forget(call_t *call)
    5861{
    59         phone_dealloc(call->priv);
     62        cap_handle_t phone_handle = (cap_handle_t) call->priv;
     63        phone_dealloc(phone_handle);
     64        /* Hand over reference from ARG5 to phone->kobject */
     65        phone_t *phone = (phone_t *) IPC_GET_ARG5(call->data);
     66        /* Drop phone_obj's reference */
     67        kobject_put(phone->kobject);
    6068        return EOK;
    6169}
     
    6371static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
    6472{
     73        /* Hand over reference from ARG5 to phone */
    6574        phone_t *phone = (phone_t *) IPC_GET_ARG5(*olddata);
    6675
    6776        /* If the user accepted call, connect */
    68         if (IPC_GET_RETVAL(answer->data) == EOK)
     77        if (IPC_GET_RETVAL(answer->data) == EOK) {
     78                /* Hand over reference from phone to the answerbox */
    6979                (void) ipc_phone_connect(phone, &TASK->answerbox);
     80        } else {
     81                kobject_put(phone->kobject);
     82        }
    7083
    7184        return EOK;
     
    7487static int answer_process(call_t *answer)
    7588{
    76         int cap = (int) answer->priv;
     89        cap_handle_t phone_handle = (cap_handle_t) answer->priv;
    7790
    7891        if (IPC_GET_RETVAL(answer->data)) {
    79                 if (cap >= 0) {
     92                if (phone_handle >= 0) {
    8093                        /*
    8194                         * The phone was indeed allocated and now needs
    8295                         * to be deallocated.
    8396                         */
    84                         phone_dealloc(cap);
     97                        phone_dealloc(phone_handle);
    8598                }
    8699        } else {
    87                 IPC_SET_ARG5(answer->data, cap);
     100                IPC_SET_ARG5(answer->data, phone_handle);
    88101        }
    89102       
  • kernel/generic/src/ipc/ops/concttome.c

    rdd20cbb r48bcf49  
    11/*
    22 * Copyright (c) 2006 Ondrej Palkovsky
    3  * Copyright (c) 2012 Jakub Jermar 
     3 * Copyright (c) 2012 Jakub Jermar
    44 * All rights reserved.
    55 *
     
    4242static int request_process(call_t *call, answerbox_t *box)
    4343{
    44         int cap = phone_alloc(TASK);
     44        cap_handle_t phone_handle = phone_alloc(TASK);
    4545
    46         IPC_SET_ARG5(call->data, cap);
     46        IPC_SET_ARG5(call->data, phone_handle);
    4747       
    4848        return EOK;
     
    5151static int answer_cleanup(call_t *answer, ipc_data_t *olddata)
    5252{
    53         int cap = (int) IPC_GET_ARG5(*olddata);
     53        cap_handle_t phone_handle = (cap_handle_t) IPC_GET_ARG5(*olddata);
    5454
    55         if (cap >= 0)
    56                 phone_dealloc(cap);
     55        if (phone_handle >= 0)
     56                phone_dealloc(phone_handle);
    5757
    5858        return EOK;
     
    6161static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
    6262{
    63         int cap = (int) IPC_GET_ARG5(*olddata);
     63        cap_handle_t phone_handle = (cap_handle_t) IPC_GET_ARG5(*olddata);
    6464
    6565        if (IPC_GET_RETVAL(answer->data) != EOK) {
    6666                /* The connection was not accepted */
    6767                answer_cleanup(answer, olddata);
    68         } else if (cap >= 0) {
     68        } else if (phone_handle >= 0) {
    6969                /* The connection was accepted */
    70                 if (phone_connect(cap, &answer->sender->answerbox)) {
    71                         /* Set 'phone hash' as arg5 of response */
     70                if (phone_connect(phone_handle, &answer->sender->answerbox)) {
     71                        /* Set 'phone hash' as ARG5 of response */
     72                        kobject_t *phone_obj = kobject_get(TASK, phone_handle,
     73                            KOBJECT_TYPE_PHONE);
    7274                        IPC_SET_ARG5(answer->data,
    73                             (sysarg_t) phone_get_current(cap));
     75                            (sysarg_t) phone_obj->phone);
     76                        kobject_put(phone_obj);
    7477                } else {
    7578                        /* The answerbox is shutting down. */
  • kernel/generic/src/ipc/ops/stchngath.c

    rdd20cbb r48bcf49  
    4545        task_t *other_task_s;
    4646
    47         phone_t *sender_phone = phone_get_current(IPC_GET_ARG5(call->data));
    48         if (!sender_phone)
     47        kobject_t *sender_obj = kobject_get(TASK, IPC_GET_ARG5(call->data),
     48            KOBJECT_TYPE_PHONE);
     49        if (!sender_obj)
    4950                return ENOENT;
    5051
    51         mutex_lock(&sender_phone->lock);
    52         if (sender_phone->state != IPC_PHONE_CONNECTED) {
    53                 mutex_unlock(&sender_phone->lock);
     52        mutex_lock(&sender_obj->phone->lock);
     53        if (sender_obj->phone->state != IPC_PHONE_CONNECTED) {
     54                mutex_unlock(&sender_obj->phone->lock);
     55                kobject_put(sender_obj);
    5456                return EINVAL;
    5557        }
    5658
    57         other_task_s = sender_phone->callee->task;
     59        other_task_s = sender_obj->phone->callee->task;
    5860
    59         mutex_unlock(&sender_phone->lock);
     61        mutex_unlock(&sender_obj->phone->lock);
    6062
    6163        /* Remember the third party task hash. */
    6264        IPC_SET_ARG5(call->data, (sysarg_t) other_task_s);
    6365
     66        kobject_put(sender_obj);
    6467        return EOK;
    6568}
     
    7174        if (!IPC_GET_RETVAL(answer->data)) {
    7275                /* The recipient authorized the change of state. */
    73                 phone_t *recipient_phone;
    7476                task_t *other_task_s;
    7577                task_t *other_task_r;
    7678
    77                 recipient_phone = phone_get_current(IPC_GET_ARG1(answer->data));
    78                 if (!recipient_phone) {
     79                kobject_t *recipient_obj = kobject_get(TASK,
     80                    IPC_GET_ARG1(answer->data), KOBJECT_TYPE_PHONE);
     81                if (!recipient_obj) {
    7982                        IPC_SET_RETVAL(answer->data, ENOENT);
    8083                        return ENOENT;
    8184                }
    8285
    83                 mutex_lock(&recipient_phone->lock);
    84                 if (recipient_phone->state != IPC_PHONE_CONNECTED) {
    85                         mutex_unlock(&recipient_phone->lock);
     86                mutex_lock(&recipient_obj->phone->lock);
     87                if (recipient_obj->phone->state != IPC_PHONE_CONNECTED) {
     88                        mutex_unlock(&recipient_obj->phone->lock);
    8689                        IPC_SET_RETVAL(answer->data, EINVAL);
     90                        kobject_put(recipient_obj);
    8791                        return EINVAL;
    8892                }
    8993
    90                 other_task_r = recipient_phone->callee->task;
     94                other_task_r = recipient_obj->phone->callee->task;
    9195                other_task_s = (task_t *) IPC_GET_ARG5(*olddata);
    9296
     
    109113                }
    110114
    111                 mutex_unlock(&recipient_phone->lock);
     115                mutex_unlock(&recipient_obj->phone->lock);
     116                kobject_put(recipient_obj);
    112117        }
    113118
  • kernel/generic/src/ipc/sysipc.c

    rdd20cbb r48bcf49  
    260260/** Make a call over IPC and wait for reply.
    261261 *
    262  * @param phone_cap    Phone capability for the call.
     262 * @param handle       Phone capability handle for the call.
    263263 * @param data[inout]  Structure with request/reply data.
    264264 * @param priv         Value to be stored in call->priv.
     
    268268 *
    269269 */
    270 int ipc_req_internal(int phone_cap, ipc_data_t *data, sysarg_t priv)
    271 {
    272         phone_t *phone = phone_get_current(phone_cap);
    273         if (!phone)
     270int ipc_req_internal(cap_handle_t handle, ipc_data_t *data, sysarg_t priv)
     271{
     272        kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
     273        if (!kobj->phone)
    274274                return ENOENT;
    275275       
     
    278278        memcpy(call->data.args, data->args, sizeof(data->args));
    279279       
    280         int rc = request_preprocess(call, phone);
     280        int rc = request_preprocess(call, kobj->phone);
    281281        if (!rc) {
    282282#ifdef CONFIG_UDEBUG
     
    285285
    286286                ipc_call_hold(call);
    287                 rc = ipc_call_sync(phone, call);
     287                rc = ipc_call_sync(kobj->phone, call);
    288288                spinlock_lock(&call->forget_lock);
    289289                bool forgotten = call->forget;
     
    312312                                assert(rc == EINTR);
    313313                        }
    314                         return rc;     
     314                        kobject_put(kobj);
     315                        return rc;
    315316                }
    316317
     
    321322        memcpy(data->args, call->data.args, sizeof(data->args));
    322323        ipc_call_free(call);
     324        kobject_put(kobj);
    323325       
    324326        return EOK;
     
    346348 * the generic function sys_ipc_call_async_slow().
    347349 *
    348  * @param phone_cap  Phone capability for the call.
    349  * @param imethod    Interface and method of the call.
    350  * @param arg1       Service-defined payload argument.
    351  * @param arg2       Service-defined payload argument.
    352  * @param arg3       Service-defined payload argument.
    353  * @param arg4       Service-defined payload argument.
     350 * @param handle   Phone capability handle for the call.
     351 * @param imethod  Interface and method of the call.
     352 * @param arg1     Service-defined payload argument.
     353 * @param arg2     Service-defined payload argument.
     354 * @param arg3     Service-defined payload argument.
     355 * @param arg4     Service-defined payload argument.
    354356 *
    355357 * @return Call hash on success.
     
    359361 *
    360362 */
    361 sysarg_t sys_ipc_call_async_fast(sysarg_t phone_cap, sysarg_t imethod,
     363sysarg_t sys_ipc_call_async_fast(sysarg_t handle, sysarg_t imethod,
    362364    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
    363365{
    364         phone_t *phone = phone_get_current(phone_cap);
    365         if (!phone)
     366        kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
     367        if (!kobj)
    366368                return IPC_CALLRET_FATAL;
    367369       
    368         if (check_call_limit(phone))
     370        if (check_call_limit(kobj->phone)) {
     371                kobject_put(kobj);
    369372                return IPC_CALLRET_TEMPORARY;
     373        }
    370374       
    371375        call_t *call = ipc_call_alloc(0);
     
    382386        IPC_SET_ARG5(call->data, 0);
    383387       
    384         int res = request_preprocess(call, phone);
     388        int res = request_preprocess(call, kobj->phone);
    385389       
    386390        if (!res)
    387                 ipc_call(phone, call);
     391                ipc_call(kobj->phone, call);
    388392        else
    389                 ipc_backsend_err(phone, call, res);
    390        
     393                ipc_backsend_err(kobj->phone, call, res);
     394       
     395        kobject_put(kobj);
    391396        return (sysarg_t) call;
    392397}
     
    394399/** Make an asynchronous IPC call allowing to transmit the entire payload.
    395400 *
    396  * @param phone_cap  Phone capability for the call.
    397  * @param data       Userspace address of call data with the request.
     401 * @param handle  Phone capability for the call.
     402 * @param data    Userspace address of call data with the request.
    398403 *
    399404 * @return See sys_ipc_call_async_fast().
    400405 *
    401406 */
    402 sysarg_t sys_ipc_call_async_slow(sysarg_t phone_cap, ipc_data_t *data)
    403 {
    404         phone_t *phone = phone_get_current(phone_cap);
    405         if (!phone)
     407sysarg_t sys_ipc_call_async_slow(sysarg_t handle, ipc_data_t *data)
     408{
     409        kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
     410        if (!kobj)
    406411                return IPC_CALLRET_FATAL;
    407412
    408         if (check_call_limit(phone))
     413        if (check_call_limit(kobj->phone)) {
     414                kobject_put(kobj);
    409415                return IPC_CALLRET_TEMPORARY;
     416        }
    410417
    411418        call_t *call = ipc_call_alloc(0);
     
    414421        if (rc != 0) {
    415422                ipc_call_free(call);
     423                kobject_put(kobj);
    416424                return (sysarg_t) rc;
    417425        }
    418426       
    419         int res = request_preprocess(call, phone);
     427        int res = request_preprocess(call, kobj->phone);
    420428       
    421429        if (!res)
    422                 ipc_call(phone, call);
     430                ipc_call(kobj->phone, call);
    423431        else
    424                 ipc_backsend_err(phone, call, res);
    425        
     432                ipc_backsend_err(kobj->phone, call, res);
     433       
     434        kobject_put(kobj);
    426435        return (sysarg_t) call;
    427436}
     
    431440 * Common code for both the fast and the slow version.
    432441 *
    433  * @param callid     Hash of the call to forward.
    434  * @param phone_cap  Phone capability to use for forwarding.
    435  * @param imethod    New interface and method to use for the forwarded call.
    436  * @param arg1       New value of the first argument for the forwarded call.
    437  * @param arg2       New value of the second argument for the forwarded call.
    438  * @param arg3       New value of the third argument for the forwarded call.
    439  * @param arg4       New value of the fourth argument for the forwarded call.
    440  * @param arg5       New value of the fifth argument for the forwarded call.
    441  * @param mode       Flags that specify mode of the forward operation.
    442  * @param slow       If true, arg3, arg4 and arg5 are considered. Otherwise
    443  *                   the function considers only the fast version arguments:
    444  *                   i.e. arg1 and arg2.
     442 * @param callid   Hash of the call to forward.
     443 * @param handle   Phone capability to use for forwarding.
     444 * @param imethod  New interface and method to use for the forwarded call.
     445 * @param arg1     New value of the first argument for the forwarded call.
     446 * @param arg2     New value of the second argument for the forwarded call.
     447 * @param arg3     New value of the third argument for the forwarded call.
     448 * @param arg4     New value of the fourth argument for the forwarded call.
     449 * @param arg5     New value of the fifth argument for the forwarded call.
     450 * @param mode     Flags that specify mode of the forward operation.
     451 * @param slow     If true, arg3, arg4 and arg5 are considered. Otherwise
     452 *                 the function considers only the fast version arguments:
     453 *                 i.e. arg1 and arg2.
    445454 *
    446455 * @return 0 on succes, otherwise an error code.
     
    449458 *
    450459 */
    451 static sysarg_t sys_ipc_forward_common(sysarg_t callid, sysarg_t phone_cap,
     460static sysarg_t sys_ipc_forward_common(sysarg_t callid, sysarg_t handle,
    452461    sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
    453462    sysarg_t arg4, sysarg_t arg5, unsigned int mode, bool slow)
     
    465474        int rc;
    466475
    467         phone_t *phone = phone_get_current(phone_cap);
    468         if (!phone) {
     476        kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
     477        if (!kobj) {
    469478                rc = ENOENT;
    470479                goto error;
     
    512521        }
    513522       
    514         rc = ipc_forward(call, phone, &TASK->answerbox, mode);
     523        rc = ipc_forward(call, kobj->phone, &TASK->answerbox, mode);
    515524        if (rc != EOK) {
    516525                after_forward = true;
     
    518527        }
    519528
     529        kobject_put(kobj);
    520530        return EOK;
    521531
     
    528538                ipc_answer(&TASK->answerbox, call);
    529539
     540        if (kobj)
     541                kobject_put(kobj);
    530542        return rc;
    531543}
     
    540552 * arguments are not set and these values are ignored.
    541553 *
    542  * @param callid  Hash of the call to forward.
    543  * @param phoneid Phone handle to use for forwarding.
    544  * @param imethod New interface and method to use for the forwarded call.
    545  * @param arg1    New value of the first argument for the forwarded call.
    546  * @param arg2    New value of the second argument for the forwarded call.
    547  * @param mode    Flags that specify mode of the forward operation.
     554 * @param callid   Hash of the call to forward.
     555 * @param handle  Phone handle to use for forwarding.
     556 * @param imethod  New interface and method to use for the forwarded call.
     557 * @param arg1     New value of the first argument for the forwarded call.
     558 * @param arg2     New value of the second argument for the forwarded call.
     559 * @param mode     Flags that specify mode of the forward operation.
    548560 *
    549561 * @return 0 on succes, otherwise an error code.
    550562 *
    551563 */
    552 sysarg_t sys_ipc_forward_fast(sysarg_t callid, sysarg_t phoneid,
     564sysarg_t sys_ipc_forward_fast(sysarg_t callid, sysarg_t handle,
    553565    sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, unsigned int mode)
    554566{
    555         return sys_ipc_forward_common(callid, phoneid, imethod, arg1, arg2, 0, 0,
     567        return sys_ipc_forward_common(callid, handle, imethod, arg1, arg2, 0, 0,
    556568            0, mode, false);
    557569}
     
    567579 *
    568580 * @param callid  Hash of the call to forward.
    569  * @param phoneid Phone handle to use for forwarding.
     581 * @param handle Phone handle to use for forwarding.
    570582 * @param data    Userspace address of the new IPC data.
    571583 * @param mode    Flags that specify mode of the forward operation.
     
    574586 *
    575587 */
    576 sysarg_t sys_ipc_forward_slow(sysarg_t callid, sysarg_t phoneid,
     588sysarg_t sys_ipc_forward_slow(sysarg_t callid, sysarg_t handle,
    577589    ipc_data_t *data, unsigned int mode)
    578590{
     
    583595                return (sysarg_t) rc;
    584596       
    585         return sys_ipc_forward_common(callid, phoneid,
     597        return sys_ipc_forward_common(callid, handle,
    586598            IPC_GET_IMETHOD(newdata), IPC_GET_ARG1(newdata),
    587599            IPC_GET_ARG2(newdata), IPC_GET_ARG3(newdata),
     
    681693/** Hang up a phone.
    682694 *
    683  * @param phone_cap  Phone capability of the phone to be hung up.
     695 * @param handle  Phone capability handle of the phone to be hung up.
    684696 *
    685697 * @return 0 on success or an error code.
    686698 *
    687699 */
    688 sysarg_t sys_ipc_hangup(sysarg_t phone_cap)
    689 {
    690         phone_t *phone = phone_get_current(phone_cap);
    691         if (!phone)
     700sysarg_t sys_ipc_hangup(sysarg_t handle)
     701{
     702        kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
     703        if (!kobj)
    692704                return ENOENT;
    693705       
    694         if (ipc_phone_hangup(phone))
     706        if (ipc_phone_hangup(kobj->phone)) {
     707                kobject_put(kobj);
    695708                return -1;
    696        
     709        }
     710       
     711        kobject_put(kobj);
    697712        return 0;
    698713}
Note: See TracChangeset for help on using the changeset viewer.