Changes in uspace/drv/char/ski-con/ski-con.c [39026d7c:676e833] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/char/ski-con/ski-con.c
r39026d7c 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 * … … 31 31 */ 32 32 33 #include <async.h>34 33 #include <ddf/driver.h> 35 34 #include <ddf/log.h> 36 35 #include <errno.h> 37 #include <fibril.h> 38 #include <io/chardev.h> 36 #include <ipc/char.h> 39 37 #include <stdint.h> 40 38 #include <stdlib.h> 39 #include <thread.h> 41 40 #include <stdbool.h> 42 41 … … 44 43 45 44 #define SKI_GETCHAR 21 46 #define SKI_PUTCHAR 3147 45 48 46 #define POLL_INTERVAL 10000 49 47 50 static int ski_con_fibril(void *arg);48 static void ski_con_thread_impl(void *arg); 51 49 static int32_t ski_con_getchar(void); 52 50 static void ski_con_connection(ipc_callid_t, ipc_call_t *, void *); 53 51 54 static int ski_con_read(chardev_srv_t *, void *, size_t, size_t *);55 static int ski_con_write(chardev_srv_t *, const void *, size_t, size_t *);56 57 static chardev_ops_t ski_con_chardev_ops = {58 .read = ski_con_read,59 .write = ski_con_write60 };61 62 static void ski_con_putchar(ski_con_t *con, char ch); /* XXX */63 64 52 /** Add ski console device. */ 65 53 int ski_con_add(ski_con_t *con) 66 54 { 67 fid_t fid;55 thread_id_t tid; 68 56 ddf_fun_t *fun = NULL; 69 57 bool bound = false; 70 58 int rc; 71 72 circ_buf_init(&con->cbuf, con->buf, ski_con_buf_size, 1);73 fibril_mutex_initialize(&con->buf_lock);74 fibril_condvar_initialize(&con->buf_cv);75 59 76 60 fun = ddf_fun_create(con->dev, fun_exposed, "a"); … … 83 67 ddf_fun_set_conn_handler(fun, ski_con_connection); 84 68 85 chardev_srvs_init(&con->cds);86 con->cds.ops = &ski_con_chardev_ops;87 con->cds.sarg = con;88 89 69 rc = ddf_fun_bind(fun); 90 70 if (rc != EOK) { … … 93 73 } 94 74 95 ddf_fun_add_to_category(fun, "console");96 97 75 bound = true; 98 76 99 fid = fibril_create(ski_con_fibril, con); 100 if (fid == 0) { 101 ddf_msg(LVL_ERROR, "Error creating fibril."); 102 rc = ENOMEM; 103 goto error; 104 } 105 106 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 107 82 return EOK; 108 83 error: … … 127 102 } 128 103 129 /** Poll Ski for keypresses. */130 static int ski_con_fibril(void *arg)104 /** Thread to poll Ski for keypresses. */ 105 static void ski_con_thread_impl(void *arg) 131 106 { 132 107 int32_t c; 133 108 ski_con_t *con = (ski_con_t *) arg; 134 int rc;135 109 136 110 while (1) { … … 140 114 break; 141 115 142 fibril_mutex_lock(&con->buf_lock); 143 144 rc = circ_buf_push(&con->cbuf, &c); 145 if (rc != EOK) 146 ddf_msg(LVL_ERROR, "Buffer overrun"); 147 148 fibril_mutex_unlock(&con->buf_lock); 149 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 } 150 121 } 151 122 152 async_usleep(POLL_INTERVAL); 153 } 154 155 return 0; 123 thread_usleep(POLL_INTERVAL); 124 } 156 125 } 157 126 … … 183 152 } 184 153 185 186 /** Display character on ski debug console187 *188 * Use SSC (Simulator System Call) to189 * display character on debug console.190 *191 * @param c Character to be printed.192 *193 */194 154 static void ski_con_putchar(ski_con_t *con, char ch) 195 155 { 196 if (ch == '\n') 197 ski_con_putchar(con, '\r'); 198 199 #ifdef UARCH_ia64 200 asm volatile ( 201 "mov r15 = %0\n" 202 "mov r32 = %1\n" /* r32 is in0 */ 203 "break 0x80000\n" /* modifies r8 */ 204 : 205 : "i" (SKI_PUTCHAR), "r" (ch) 206 : "r15", "in0", "r8" 207 ); 208 #else 209 (void) ch; 210 #endif 211 } 212 213 /** Read from Ski console device */ 214 static int ski_con_read(chardev_srv_t *srv, void *buf, size_t size, 215 size_t *nread) 216 { 217 ski_con_t *con = (ski_con_t *) srv->srvs->sarg; 218 size_t p; 219 uint8_t *bp = (uint8_t *) buf; 220 int rc; 221 222 fibril_mutex_lock(&con->buf_lock); 223 224 while (circ_buf_nused(&con->cbuf) == 0) 225 fibril_condvar_wait(&con->buf_cv, &con->buf_lock); 226 227 p = 0; 228 while (p < size) { 229 rc = circ_buf_pop(&con->cbuf, &bp[p]); 230 if (rc != EOK) 231 break; 232 ++p; 233 } 234 235 fibril_mutex_unlock(&con->buf_lock); 236 237 *nread = p; 238 return EOK; 239 } 240 241 /** Write to Ski console device */ 242 static int ski_con_write(chardev_srv_t *srv, const void *data, size_t size, 243 size_t *nwr) 244 { 245 ski_con_t *con = (ski_con_t *) srv->srvs->sarg; 246 size_t i; 247 uint8_t *dp = (uint8_t *) data; 248 249 for (i = 0; i < size; i++) 250 ski_con_putchar(con, dp[i]); 251 252 *nwr = size; 253 return EOK; 156 254 157 } 255 158 … … 258 161 void *arg) 259 162 { 260 ski_con_t *con = (ski_con_t *) ddf_dev_data_get( 261 ddf_fun_get_dev((ddf_fun_t *) arg)); 262 263 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 } 264 202 } 265 203
Note:
See TracChangeset
for help on using the changeset viewer.