source: mainline/uspace/srv/hid/input/ctl/kbdev.c@ cc574511

lfn serial ticket/834-toolchain-update topic/fix-logger-deadlock topic/msim-upgrade topic/simplify-dev-export
Last change on this file since cc574511 was cc574511, checked in by Jiri Svoboda <jiri@…>, 15 years ago

Basic category support in location service. Devman adds device services
to categories. Switch over input server device discovery from using
/dev/class to loc categories.

  • Property mode set to 100644
File size: 4.6 KB
Line 
1/*
2 * Copyright (c) 2011 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 kbd_ctl
30 * @ingroup input
31 * @{
32 */
33/**
34 * @file
35 * @brief Keyboard device connector controller driver.
36 */
37
38#include <async.h>
39#include <bool.h>
40#include <errno.h>
41#include <fcntl.h>
42#include <gsp.h>
43#include <io/console.h>
44#include <io/keycode.h>
45#include <ipc/kbdev.h>
46#include <input.h>
47#include <kbd.h>
48#include <kbd_ctl.h>
49#include <kbd_port.h>
50#include <loc.h>
51#include <stdlib.h>
52#include <sys/typefmt.h>
53#include <vfs/vfs_sess.h>
54
55
56static int kbdev_ctl_init(kbd_dev_t *);
57static void kbdev_ctl_set_ind(kbd_dev_t *, unsigned int);
58
59static void kbdev_callback_conn(ipc_callid_t, ipc_call_t *, void *arg);
60
61kbd_ctl_ops_t kbdev_ctl = {
62 .parse = NULL,
63 .init = kbdev_ctl_init,
64 .set_ind = kbdev_ctl_set_ind
65};
66
67/** Kbdev softstate */
68typedef struct {
69 /** Link to generic keyboard device */
70 kbd_dev_t *kbd_dev;
71
72 /** Session with kbdev device */
73 async_sess_t *sess;
74} kbdev_t;
75
76static kbdev_t *kbdev_new(kbd_dev_t *kdev)
77{
78 kbdev_t *kbdev;
79
80 kbdev = calloc(1, sizeof(kbdev_t));
81 if (kbdev == NULL)
82 return NULL;
83
84 kbdev->kbd_dev = kdev;
85
86 return kbdev;
87}
88
89static void kbdev_destroy(kbdev_t *kbdev)
90{
91 if (kbdev->sess != NULL)
92 async_hangup(kbdev->sess);
93 free(kbdev);
94}
95
96static int kbdev_ctl_init(kbd_dev_t *kdev)
97{
98 async_sess_t *sess;
99 async_exch_t *exch;
100 kbdev_t *kbdev;
101 char *svc_name;
102 int rc;
103
104 if (asprintf(&svc_name, "devname%" PRIun, kdev->service_id) > 0)
105 svc_name = (char *) "unknown";
106
107 sess = loc_service_connect(EXCHANGE_SERIALIZE, kdev->service_id, 0);
108 if (sess == NULL) {
109 printf("%s: Failed starting session with '%s.'\n", NAME,
110 svc_name);
111 return -1;
112 }
113
114 kbdev = kbdev_new(kdev);
115 if (kbdev == NULL) {
116 printf("%s: Failed allocating device structure for '%s'.\n",
117 NAME, svc_name);
118 return -1;
119 }
120
121 kbdev->sess = sess;
122
123 exch = async_exchange_begin(sess);
124 if (exch == NULL) {
125 printf("%s: Failed starting exchange with '%s'.\n", NAME,
126 svc_name);
127 kbdev_destroy(kbdev);
128 return -1;
129 }
130
131 rc = async_connect_to_me(exch, 0, 0, 0, kbdev_callback_conn, kbdev);
132 if (rc != EOK) {
133 printf("%s: Failed creating callback connection from '%s'.\n",
134 NAME, svc_name);
135 async_exchange_end(exch);
136 kbdev_destroy(kbdev);
137 return -1;
138 }
139
140 async_exchange_end(exch);
141
142 kdev->ctl_private = (void *) kbdev;
143 return 0;
144}
145
146static void kbdev_ctl_set_ind(kbd_dev_t *kdev, unsigned mods)
147{
148 async_sess_t *sess;
149 async_exch_t *exch;
150
151 sess = ((kbdev_t *) kdev->ctl_private)->sess;
152
153 exch = async_exchange_begin(sess);
154 if (!exch)
155 return;
156
157 async_msg_1(exch, KBDEV_SET_IND, mods);
158 async_exchange_end(exch);
159}
160
161static void kbdev_callback_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
162{
163 kbdev_t *kbdev;
164 int retval;
165 int type, key;
166
167 /* Kbdev device structure */
168 kbdev = arg;
169
170 while (true) {
171 ipc_call_t call;
172 ipc_callid_t callid;
173
174 callid = async_get_call(&call);
175 if (!IPC_GET_IMETHOD(call)) {
176 /* XXX Handle hangup */
177 return;
178 }
179
180 switch (IPC_GET_IMETHOD(call)) {
181 case KBDEV_EVENT:
182 /* Got event from keyboard device */
183 retval = 0;
184 type = IPC_GET_ARG1(call);
185 key = IPC_GET_ARG2(call);
186 kbd_push_event(kbdev->kbd_dev, type, key);
187 break;
188 default:
189 retval = ENOTSUP;
190 break;
191 }
192
193 async_answer_0(callid, retval);
194 }
195}
196
197/**
198 * @}
199 */
Note: See TracBrowser for help on using the repository browser.