source: mainline/kernel/generic/src/ipc/ops/conctmeto.c@ 6ff23ff

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 6ff23ff was eadaeae8, checked in by Jakub Jermar <jakub@…>, 8 years ago

Make capability handles type-safe

Define distinct pointer types for the handles of the supported
capability types and use them instead of integer handles. This makes it
virtually impossible to pass a non-handle or a handle of different type
instead of the proper handle. Also turn cap_handle_t into an "untyped"
capability handle that can be assigned to and from the "typed" handles.

This commit also fixes a bug in msim-con driver, which wrongly used the
IRQ number instead of the IRQ capability handle to unregister the IRQ.

This commit also fixes the wrong use of the capability handle instead
of error code in libusbhost.

  • Property mode set to 100644
File size: 4.2 KB
Line 
1/*
2 * Copyright (c) 2006 Ondrej Palkovsky
3 * Copyright (c) 2012 Jakub Jermar
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup genericipc
31 * @{
32 */
33/** @file
34 */
35
36#include <ipc/sysipc_ops.h>
37#include <ipc/ipc.h>
38#include <ipc/ipcrsc.h>
39#include <abi/errno.h>
40#include <arch.h>
41
42static errno_t request_preprocess(call_t *call, phone_t *phone)
43{
44 /*
45 * Create the new phone and capability, but don't publish them yet.
46 * That will be done once the phone is connected.
47 */
48 cap_phone_handle_t phone_handle;
49 kobject_t *phone_obj;
50 errno_t rc = phone_alloc(TASK, false, &phone_handle, &phone_obj);
51 if (rc != EOK) {
52 call->priv = -1;
53 return rc;
54 }
55
56 /* Hand over phone_obj's reference to ARG5 */
57 IPC_SET_ARG5(call->data, (sysarg_t) phone_obj->phone);
58
59 /* Remember the handle */
60 call->priv = CAP_HANDLE_RAW(phone_handle);
61
62 return EOK;
63}
64
65static errno_t request_forget(call_t *call)
66{
67 cap_phone_handle_t phone_handle = (cap_handle_t) call->priv;
68
69 if (CAP_HANDLE_RAW(phone_handle) < 0)
70 return EOK;
71
72 /* Hand over reference from ARG5 to phone->kobject */
73 phone_t *phone = (phone_t *) IPC_GET_ARG5(call->data);
74 /* Drop phone->kobject's reference */
75 kobject_put(phone->kobject);
76 cap_free(TASK, phone_handle);
77
78 return EOK;
79}
80
81static errno_t answer_preprocess(call_t *answer, ipc_data_t *olddata)
82{
83 /* Hand over reference from ARG5 to phone */
84 phone_t *phone = (phone_t *) IPC_GET_ARG5(*olddata);
85
86 /*
87 * Get an extra reference and pass it in the answer data.
88 */
89 kobject_add_ref(phone->kobject);
90 IPC_SET_ARG5(answer->data, (sysarg_t) phone);
91
92 /* If the user accepted the call, connect */
93 if (IPC_GET_RETVAL(answer->data) == EOK) {
94 /* Hand over reference from phone to the answerbox */
95 (void) ipc_phone_connect(phone, &TASK->answerbox);
96 } else {
97 kobject_put(phone->kobject);
98 }
99
100 return EOK;
101}
102
103static errno_t answer_process(call_t *answer)
104{
105 cap_phone_handle_t phone_handle = (cap_handle_t) answer->priv;
106 phone_t *phone = (phone_t *) IPC_GET_ARG5(answer->data);
107
108 if (IPC_GET_RETVAL(answer->data)) {
109 if (CAP_HANDLE_RAW(phone_handle) >= 0) {
110 /*
111 * Cleanup the unpublished capability and drop
112 * phone->kobject's reference.
113 */
114 kobject_put(phone->kobject);
115 cap_free(TASK, phone_handle);
116 }
117 } else {
118 /*
119 * Publish the capability. Publishing the capability this late
120 * is important for ipc_cleanup() where we want to have a
121 * capability for each phone that wasn't hung up by the user.
122 */
123 cap_publish(TASK, phone_handle, phone->kobject);
124
125 IPC_SET_ARG5(answer->data, CAP_HANDLE_RAW(phone_handle));
126 }
127
128 return EOK;
129}
130
131sysipc_ops_t ipc_m_connect_me_to_ops = {
132 .request_preprocess = request_preprocess,
133 .request_forget = request_forget,
134 .request_process = null_request_process,
135 .answer_cleanup = null_answer_cleanup,
136 .answer_preprocess = answer_preprocess,
137 .answer_process = answer_process,
138};
139
140/** @}
141 */
Note: See TracBrowser for help on using the repository browser.