Changes in uspace/drv/char/ski-con/ski-con.c [7a6065c:676e833] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/char/ski-con/ski-con.c
r7a6065c r676e833 1 1 /* 2 2 * Copyright (c) 2005 Jakub Jermar 3 * Copyright (c) 201 7Jiri Svoboda3 * Copyright (c) 2011 Jiri Svoboda 4 4 * All rights reserved. 5 5 * … … 34 34 #include <ddf/log.h> 35 35 #include <errno.h> 36 #include <fibril.h> 37 #include <io/chardev.h> 36 #include <ipc/char.h> 38 37 #include <stdint.h> 39 38 #include <stdlib.h> 39 #include <thread.h> 40 40 #include <stdbool.h> 41 41 … … 46 46 #define POLL_INTERVAL 10000 47 47 48 static int ski_con_fibril(void *arg);48 static void ski_con_thread_impl(void *arg); 49 49 static int32_t ski_con_getchar(void); 50 50 static void ski_con_connection(ipc_callid_t, ipc_call_t *, void *); 51 51 52 static int ski_con_read(chardev_srv_t *, void *, size_t, size_t *);53 static int ski_con_write(chardev_srv_t *, const void *, size_t, size_t *);54 55 static chardev_ops_t ski_con_chardev_ops = {56 .read = ski_con_read,57 .write = ski_con_write58 };59 60 52 /** Add ski console device. */ 61 53 int ski_con_add(ski_con_t *con) 62 54 { 63 fid_t fid;55 thread_id_t tid; 64 56 ddf_fun_t *fun = NULL; 65 57 bool bound = false; 66 58 int rc; 67 68 circ_buf_init(&con->cbuf, con->buf, ski_con_buf_size, 1);69 fibril_mutex_initialize(&con->buf_lock);70 fibril_condvar_initialize(&con->buf_cv);71 59 72 60 fun = ddf_fun_create(con->dev, fun_exposed, "a"); … … 79 67 ddf_fun_set_conn_handler(fun, ski_con_connection); 80 68 81 chardev_srvs_init(&con->cds);82 con->cds.ops = &ski_con_chardev_ops;83 con->cds.sarg = con;84 85 69 rc = ddf_fun_bind(fun); 86 70 if (rc != EOK) { … … 91 75 bound = true; 92 76 93 fid = fibril_create(ski_con_fibril, con); 94 if (fid == 0) { 95 ddf_msg(LVL_ERROR, "Error creating fibril."); 96 rc = ENOMEM; 97 goto error; 98 } 99 100 fibril_add_ready(fid); 77 rc = thread_create(ski_con_thread_impl, con, "kbd_poll", &tid); 78 if (rc != 0) { 79 return rc; 80 } 81 101 82 return EOK; 102 83 error: … … 121 102 } 122 103 123 /** Poll Ski for keypresses. */124 static int ski_con_fibril(void *arg)104 /** Thread to poll Ski for keypresses. */ 105 static void ski_con_thread_impl(void *arg) 125 106 { 126 107 int32_t c; 127 108 ski_con_t *con = (ski_con_t *) arg; 128 int rc;129 109 130 110 while (1) { … … 134 114 break; 135 115 136 fibril_mutex_lock(&con->buf_lock); 137 138 rc = circ_buf_push(&con->cbuf, &c); 139 if (rc != EOK) 140 ddf_msg(LVL_ERROR, "Buffer overrun"); 141 142 fibril_mutex_unlock(&con->buf_lock); 143 fibril_condvar_broadcast(&con->buf_cv); 116 if (con->client_sess != NULL) { 117 async_exch_t *exch = async_exchange_begin(con->client_sess); 118 async_msg_1(exch, CHAR_NOTIF_BYTE, c); 119 async_exchange_end(exch); 120 } 144 121 } 145 122 146 fibril_usleep(POLL_INTERVAL); 147 } 148 149 return 0; 123 thread_usleep(POLL_INTERVAL); 124 } 150 125 } 151 126 … … 182 157 } 183 158 184 /** Read from Ski console device */185 static int ski_con_read(chardev_srv_t *srv, void *buf, size_t size,186 size_t *nread)187 {188 ski_con_t *con = (ski_con_t *) srv->srvs->sarg;189 size_t p;190 uint8_t *bp = (uint8_t *) buf;191 int rc;192 193 fibril_mutex_lock(&con->buf_lock);194 195 while (circ_buf_nused(&con->cbuf) == 0)196 fibril_condvar_wait(&con->buf_cv, &con->buf_lock);197 198 p = 0;199 while (p < size) {200 rc = circ_buf_pop(&con->cbuf, &bp[p]);201 if (rc != EOK)202 break;203 ++p;204 }205 206 fibril_mutex_unlock(&con->buf_lock);207 208 *nread = p;209 return EOK;210 }211 212 /** Write to Ski console device */213 static int ski_con_write(chardev_srv_t *srv, const void *data, size_t size,214 size_t *nwr)215 {216 ski_con_t *con = (ski_con_t *) srv->srvs->sarg;217 size_t i;218 uint8_t *dp = (uint8_t *) data;219 220 for (i = 0; i < size; i++)221 ski_con_putchar(con, dp[i]);222 223 *nwr = size;224 return EOK;225 }226 227 159 /** Character device connection handler. */ 228 160 static void ski_con_connection(ipc_callid_t iid, ipc_call_t *icall, 229 161 void *arg) 230 162 { 231 ski_con_t *con = (ski_con_t *) ddf_dev_data_get( 232 ddf_fun_get_dev((ddf_fun_t *) arg)); 233 234 chardev_conn(iid, icall, &con->cds); 163 ski_con_t *con; 164 165 /* Answer the IPC_M_CONNECT_ME_TO call. */ 166 async_answer_0(iid, EOK); 167 168 con = (ski_con_t *)ddf_dev_data_get(ddf_fun_get_dev((ddf_fun_t *)arg)); 169 170 while (true) { 171 ipc_call_t call; 172 ipc_callid_t callid = async_get_call(&call); 173 sysarg_t method = IPC_GET_IMETHOD(call); 174 175 if (!method) { 176 /* The other side has hung up. */ 177 async_answer_0(callid, EOK); 178 return; 179 } 180 181 async_sess_t *sess = 182 async_callback_receive_start(EXCHANGE_SERIALIZE, &call); 183 if (sess != NULL) { 184 if (con->client_sess == NULL) { 185 con->client_sess = sess; 186 async_answer_0(callid, EOK); 187 } else 188 async_answer_0(callid, ELIMIT); 189 } else { 190 switch (method) { 191 case CHAR_WRITE_BYTE: 192 ddf_msg(LVL_DEBUG, "Write %" PRIun " to device\n", 193 IPC_GET_ARG1(call)); 194 ski_con_putchar(con, (uint8_t) IPC_GET_ARG1(call)); 195 async_answer_0(callid, EOK); 196 break; 197 default: 198 async_answer_0(callid, EINVAL); 199 } 200 } 201 } 235 202 } 236 203
Note:
See TracChangeset
for help on using the changeset viewer.