source: mainline/uspace/lib/device/src/io/chardev_srv.c@ 241ab7e

serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 241ab7e was 5fc8244, checked in by Jiri Svoboda <jiri@…>, 4 years ago

Move device-related stuff out of libc to libdevice

Unfortunately, we need to keep clock_dev, which pulls in hw_res
and pio_window. clock_dev is used by time.c

  • Property mode set to 100644
File size: 4.2 KB
RevLine 
[75751db6]1/*
2 * Copyright (c) 2014 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libc
30 * @{
31 */
32/**
33 * @file
34 * @brief Character device server stub
35 */
36#include <errno.h>
37#include <io/chardev_srv.h>
38#include <ipc/chardev.h>
39#include <macros.h>
40#include <stdlib.h>
[8d2dd7f2]41#include <stddef.h>
[75751db6]42
43static chardev_srv_t *chardev_srv_create(chardev_srvs_t *);
44
[984a9ba]45static void chardev_read_srv(chardev_srv_t *srv, ipc_call_t *icall)
[75751db6]46{
[19ea61d]47 void *buf;
48 size_t size;
[677cad5]49 size_t nread;
[f2d88f3]50 chardev_flags_t flags;
[b7fd2a0]51 errno_t rc;
[19ea61d]52
[fafb8e5]53 flags = ipc_get_arg1(icall);
[f2d88f3]54
[984a9ba]55 ipc_call_t call;
56 if (!async_data_read_receive(&call, &size)) {
57 async_answer_0(icall, EINVAL);
[19ea61d]58 return;
59 }
60
61 buf = malloc(size);
62 if (buf == NULL) {
[984a9ba]63 async_answer_0(&call, ENOMEM);
64 async_answer_0(icall, ENOMEM);
[19ea61d]65 return;
66 }
[75751db6]67
68 if (srv->srvs->ops->read == NULL) {
[984a9ba]69 async_answer_0(&call, ENOTSUP);
70 async_answer_0(icall, ENOTSUP);
[19ea61d]71 free(buf);
[75751db6]72 return;
73 }
74
[f2d88f3]75 rc = srv->srvs->ops->read(srv, buf, size, &nread, flags);
[677cad5]76 if (rc != EOK && nread == 0) {
[984a9ba]77 async_answer_0(&call, rc);
78 async_answer_0(icall, rc);
[19ea61d]79 free(buf);
80 return;
[75751db6]81 }
[19ea61d]82
[984a9ba]83 async_data_read_finalize(&call, buf, nread);
[19ea61d]84
85 free(buf);
[984a9ba]86 async_answer_2(icall, EOK, (sysarg_t) rc, nread);
[75751db6]87}
88
[984a9ba]89static void chardev_write_srv(chardev_srv_t *srv, ipc_call_t *icall)
[75751db6]90{
[19ea61d]91 void *data;
92 size_t size;
[677cad5]93 size_t nwr;
[b7fd2a0]94 errno_t rc;
[75751db6]95
[19ea61d]96 rc = async_data_write_accept(&data, false, 0, 0, 0, &size);
97 if (rc != EOK) {
[984a9ba]98 async_answer_0(icall, rc);
[19ea61d]99 return;
100 }
101
[75751db6]102 if (srv->srvs->ops->write == NULL) {
[984a9ba]103 async_answer_0(icall, ENOTSUP);
[75751db6]104 return;
105 }
106
[677cad5]107 rc = srv->srvs->ops->write(srv, data, size, &nwr);
[19ea61d]108 free(data);
[677cad5]109 if (rc != EOK && nwr == 0) {
[984a9ba]110 async_answer_0(icall, rc);
[677cad5]111 return;
112 }
[19ea61d]113
[984a9ba]114 async_answer_2(icall, EOK, (sysarg_t) rc, nwr);
[75751db6]115}
116
117static chardev_srv_t *chardev_srv_create(chardev_srvs_t *srvs)
118{
119 chardev_srv_t *srv;
120
121 srv = calloc(1, sizeof(chardev_srv_t));
122 if (srv == NULL)
123 return NULL;
124
125 srv->srvs = srvs;
126 return srv;
127}
128
129void chardev_srvs_init(chardev_srvs_t *srvs)
130{
131 srvs->ops = NULL;
132 srvs->sarg = NULL;
133}
134
[984a9ba]135errno_t chardev_conn(ipc_call_t *icall, chardev_srvs_t *srvs)
[75751db6]136{
137 chardev_srv_t *srv;
[b7fd2a0]138 errno_t rc;
[75751db6]139
140 /* Accept the connection */
[beb83c1]141 async_accept_0(icall);
[75751db6]142
143 srv = chardev_srv_create(srvs);
144 if (srv == NULL)
145 return ENOMEM;
146
147 if (srvs->ops->open != NULL) {
148 rc = srvs->ops->open(srvs, srv);
149 if (rc != EOK)
150 return rc;
151 }
152
153 while (true) {
154 ipc_call_t call;
[984a9ba]155 async_get_call(&call);
[fafb8e5]156 sysarg_t method = ipc_get_imethod(&call);
[75751db6]157
158 if (!method) {
159 /* The other side has hung up */
[984a9ba]160 async_answer_0(&call, EOK);
[75751db6]161 break;
162 }
163
164 switch (method) {
165 case CHARDEV_READ:
[984a9ba]166 chardev_read_srv(srv, &call);
[75751db6]167 break;
168 case CHARDEV_WRITE:
[984a9ba]169 chardev_write_srv(srv, &call);
[75751db6]170 break;
171 default:
[74017ce]172 if (srv->srvs->ops->def_handler != NULL)
[984a9ba]173 srv->srvs->ops->def_handler(srv, &call);
[74017ce]174 else
[984a9ba]175 async_answer_0(&call, ENOTSUP);
[75751db6]176 }
177 }
178
179 if (srvs->ops->close != NULL)
180 rc = srvs->ops->close(srv);
181 else
182 rc = EOK;
183
184 free(srv);
185
186 return rc;
187}
188
189/** @}
190 */
Note: See TracBrowser for help on using the repository browser.