Changeset ac307b2 in mainline
- Timestamp:
- 2017-11-25T11:12:23Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 98cb5e0d
- Parents:
- f571ca49 (diff), 0851a3d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 1 added
- 5 deleted
- 36 edited
- 2 moved
Legend:
- Unmodified
- Added
- Removed
-
.gitignore
rf571ca49 rac307b2 248 248 uspace/dist/logo.tga 249 249 uspace/dist/srv/cdfs 250 uspace/dist/srv/chardev-test 250 251 uspace/dist/srv/clipboard 251 252 uspace/dist/srv/compositor … … 420 421 uspace/srv/ns/ns 421 422 uspace/srv/taskmon/taskmon 423 uspace/srv/test/chardev-test/chardev-test 422 424 uspace/srv/vfs/vfs 423 425 uspace/srv/volsrv/volsrv -
uspace/app/sportdmp/sportdmp.c
rf571ca49 rac307b2 27 27 */ 28 28 29 #include <char_dev_iface.h>30 29 #include <errno.h> 30 #include <io/chardev.h> 31 31 #include <io/serial.h> 32 32 #include <loc.h> 33 33 #include <stdio.h> 34 #include <stdlib.h> 34 35 35 36 #define BUF_SIZE 1 … … 44 45 sysarg_t baud = 9600; 45 46 service_id_t svc_id; 47 chardev_t *chardev; 46 48 serial_t *serial; 49 size_t nread; 47 50 48 51 int arg = 1; … … 119 122 } 120 123 124 rc = chardev_open(sess, &chardev); 125 if (rc != EOK) { 126 fprintf(stderr, "Failed opening character device\n"); 127 return 2; 128 } 129 121 130 rc = serial_open(sess, &serial); 122 131 if (rc != EOK) { … … 138 147 139 148 while (true) { 140 ssize_t read = char_dev_read(sess, buf, BUF_SIZE); 141 if (read < 0) { 142 fprintf(stderr, "Failed reading from serial device\n"); 149 rc = chardev_read(chardev, buf, BUF_SIZE, &nread); 150 for (size_t i = 0; i < nread; i++) { 151 printf("%02hhx ", buf[i]); 152 } 153 if (rc != EOK) { 154 fprintf(stderr, "\nFailed reading from serial device\n"); 143 155 break; 144 }145 ssize_t i;146 for (i = 0; i < read; i++) {147 printf("%02hhx ", buf[i]);148 156 } 149 157 fflush(stdout); … … 152 160 free(buf); 153 161 serial_close(serial); 162 chardev_close(chardev); 154 163 async_hangup(sess); 155 164 return 0; -
uspace/app/tester/Makefile
rf571ca49 rac307b2 68 68 mm/mapping1.c \ 69 69 mm/pager1.c \ 70 hw/misc/virtchar1.c \71 70 hw/serial/serial1.c \ 72 71 chardev/chardev1.c -
uspace/app/tester/hw/serial/serial1.c
rf571ca49 rac307b2 35 35 */ 36 36 37 #include < inttypes.h>37 #include <async.h> 38 38 #include <errno.h> 39 #include <io/chardev.h> 40 #include <io/serial.h> 41 #include <ipc/services.h> 42 #include <loc.h> 39 43 #include <stdlib.h> 40 44 #include <stdio.h> 41 45 #include <stddef.h> 42 #include < async.h>46 #include <str.h> 43 47 #include <thread.h> 44 #include <ipc/services.h>45 #include <loc.h>46 #include <char_dev_iface.h>47 #include <str.h>48 #include <io/serial.h>49 48 #include "../../tester.h" 50 49 … … 57 56 size_t cnt; 58 57 serial_t *serial; 58 chardev_t *chardev; 59 int rc; 60 size_t nread; 61 size_t nwritten; 59 62 60 63 if (test_argc < 1) … … 83 86 return "Failed connecting to serial device"; 84 87 88 res = chardev_open(sess, &chardev); 89 if (res != EOK) { 90 async_hangup(sess); 91 return "Failed opening serial port"; 92 } 93 85 94 res = serial_open(sess, &serial); 86 if (res != EOK) 95 if (res != EOK) { 96 chardev_close(chardev); 97 async_hangup(sess); 87 98 return "Failed opening serial port"; 99 } 88 100 89 101 char *buf = (char *) malloc(cnt + 1); 90 102 if (buf == NULL) { 103 chardev_close(chardev); 91 104 serial_close(serial); 92 105 async_hangup(sess); … … 103 116 if (res != EOK) { 104 117 free(buf); 118 chardev_close(chardev); 105 119 serial_close(serial); 106 120 async_hangup(sess); … … 111 125 if (EOK != res) { 112 126 free(buf); 127 chardev_close(chardev); 113 128 serial_close(serial); 114 129 async_hangup(sess); … … 121 136 size_t total = 0; 122 137 while (total < cnt) { 123 ssize_t read = char_dev_read(sess, buf, cnt - total);124 125 if (r ead < 0) {138 139 rc = chardev_read(chardev, buf, cnt - total, &nread); 140 if (rc != EOK) { 126 141 (void) serial_set_comm_props(serial, old_baud, 127 142 old_par, old_word_size, old_stop); 128 143 129 144 free(buf); 145 chardev_close(chardev); 130 146 serial_close(serial); 131 147 async_hangup(sess); … … 133 149 } 134 150 135 if ( (size_t)read > cnt - total) {151 if (nread > cnt - total) { 136 152 (void) serial_set_comm_props(serial, old_baud, 137 153 old_par, old_word_size, old_stop); 138 154 139 155 free(buf); 156 chardev_close(chardev); 140 157 serial_close(serial); 141 158 async_hangup(sess); … … 143 160 } 144 161 145 TPRINTF("Read %zd bytes\n", read);146 147 if ( read == 0)162 TPRINTF("Read %zd bytes\n", nread); 163 164 if (nread == 0) 148 165 thread_usleep(DEFAULT_SLEEP); 149 166 else { 150 buf[ read] = 0;167 buf[nread] = 0; 151 168 152 169 /* … … 154 171 * direction of data transfer. 155 172 */ 156 ssize_t written = char_dev_write(sess, buf, read); 157 158 if (written < 0) { 173 rc = chardev_write(chardev, buf, nread, &nwritten); 174 if (rc != EOK) { 159 175 (void) serial_set_comm_props(serial, old_baud, 160 176 old_par, old_word_size, old_stop); 161 177 162 178 free(buf); 179 chardev_close(chardev); 163 180 serial_close(serial); 164 181 async_hangup(sess); … … 166 183 } 167 184 168 if ( written !=read) {185 if (nwritten != nread) { 169 186 (void) serial_set_comm_props(serial, old_baud, 170 187 old_par, old_word_size, old_stop); 171 188 172 189 free(buf); 190 chardev_close(chardev); 173 191 serial_close(serial); 174 192 async_hangup(sess); … … 176 194 } 177 195 178 TPRINTF("Written %zd bytes\n", written);179 } 180 181 total += read;196 TPRINTF("Written %zd bytes\n", nwritten); 197 } 198 199 total += nread; 182 200 } 183 201 … … 185 203 186 204 size_t eot_size = str_size(EOT); 187 ssize_t written = char_dev_write(sess, (void *) EOT, eot_size);205 rc = chardev_write(chardev, (void *) EOT, eot_size, &nwritten); 188 206 189 207 (void) serial_set_comm_props(serial, old_baud, old_par, old_word_size, … … 191 209 192 210 free(buf); 211 chardev_close(chardev); 193 212 serial_close(serial); 194 213 async_hangup(sess); 195 214 196 if ( written < 0)215 if (rc != EOK) 197 216 return "Failed to write EOT banner to serial device"; 198 217 199 if ( (size_t)written != eot_size)218 if (nwritten != eot_size) 200 219 return "Written less data than the size of the EOT banner " 201 220 "to serial device"; -
uspace/app/tester/tester.c
rf571ca49 rac307b2 76 76 #include "mm/pager1.def" 77 77 #include "hw/serial/serial1.def" 78 #include "hw/misc/virtchar1.def"79 78 #include "chardev/chardev1.def" 80 79 {NULL, NULL, NULL, false} -
uspace/app/tester/tester.h
rf571ca49 rac307b2 108 108 extern const char *test_pager1(void); 109 109 extern const char *test_serial1(void); 110 extern const char *test_virtchar1(void);111 110 extern const char *test_devman1(void); 112 111 extern const char *test_devman2(void); -
uspace/drv/char/i8042/i8042.c
rf571ca49 rac307b2 2 2 * Copyright (c) 2001-2004 Jakub Jermar 3 3 * Copyright (c) 2006 Josef Cejka 4 * Copyright (c) 201 4Jiri Svoboda4 * Copyright (c) 2017 Jiri Svoboda 5 5 * Copyright (c) 2011 Jan Vesely 6 6 * All rights reserved. … … 39 39 */ 40 40 41 #include <adt/circ_buf.h> 41 42 #include <ddf/log.h> 42 43 #include <ddf/interrupt.h> … … 130 131 { 131 132 i8042_t *controller = ddf_dev_data_get(dev); 133 int rc; 132 134 133 135 const uint8_t status = IPC_GET_ARG1(*call); 134 136 const uint8_t data = IPC_GET_ARG2(*call); 135 137 136 buffer_t *buffer = (status & i8042_AUX_DATA) ? 137 &controller->aux_buffer : &controller->kbd_buffer; 138 139 buffer_write(buffer, data); 138 i8042_port_t *port = (status & i8042_AUX_DATA) ? 139 controller->aux : controller->kbd; 140 141 fibril_mutex_lock(&port->buf_lock); 142 143 rc = circ_buf_push(&port->cbuf, &data); 144 if (rc != EOK) 145 ddf_msg(LVL_ERROR, "Buffer overrun"); 146 147 fibril_mutex_unlock(&port->buf_lock); 148 fibril_condvar_broadcast(&port->buf_cv); 140 149 } 141 150 … … 159 168 const size_t cmd_count = sizeof(i8042_cmds) / sizeof(irq_cmd_t); 160 169 irq_cmd_t cmds[cmd_count]; 170 ddf_fun_t *kbd_fun; 171 ddf_fun_t *aux_fun; 161 172 i8042_regs_t *ar; 162 173 163 174 int rc; 164 175 bool kbd_bound = false; 165 176 bool aux_bound = false; 166 167 dev->kbd_fun = NULL;168 dev->aux_fun = NULL;169 177 170 178 if (regs->size < sizeof(i8042_regs_t)) { … … 178 186 } 179 187 180 dev->kbd_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2a");181 if ( dev->kbd_fun == NULL) {188 kbd_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2a"); 189 if (kbd_fun == NULL) { 182 190 rc = ENOMEM; 183 191 goto error; 184 192 }; 185 193 186 dev->kbd = ddf_fun_data_alloc( dev->kbd_fun, sizeof(i8042_port_t));194 dev->kbd = ddf_fun_data_alloc(kbd_fun, sizeof(i8042_port_t)); 187 195 if (dev->kbd == NULL) { 188 196 rc = ENOMEM; … … 190 198 } 191 199 200 dev->kbd->fun = kbd_fun; 192 201 dev->kbd->ctl = dev; 193 202 chardev_srvs_init(&dev->kbd->cds); 194 203 dev->kbd->cds.ops = &i8042_chardev_ops; 195 204 dev->kbd->cds.sarg = dev->kbd; 196 197 rc = ddf_fun_add_match_id(dev->kbd_fun, "char/xtkbd", 90); 205 fibril_mutex_initialize(&dev->kbd->buf_lock); 206 fibril_condvar_initialize(&dev->kbd->buf_cv); 207 208 rc = ddf_fun_add_match_id(dev->kbd->fun, "char/xtkbd", 90); 198 209 if (rc != EOK) 199 210 goto error; 200 211 201 dev->aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b");202 if ( dev->aux_fun == NULL) {212 aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b"); 213 if (aux_fun == NULL) { 203 214 rc = ENOMEM; 204 215 goto error; 205 216 } 206 217 207 dev->aux = ddf_fun_data_alloc( dev->aux_fun, sizeof(i8042_port_t));218 dev->aux = ddf_fun_data_alloc(aux_fun, sizeof(i8042_port_t)); 208 219 if (dev->aux == NULL) { 209 220 rc = ENOMEM; … … 211 222 } 212 223 224 dev->aux->fun = aux_fun; 213 225 dev->aux->ctl = dev; 214 226 chardev_srvs_init(&dev->aux->cds); 215 227 dev->aux->cds.ops = &i8042_chardev_ops; 216 228 dev->aux->cds.sarg = dev->aux; 217 218 rc = ddf_fun_add_match_id(dev->aux_fun, "char/ps2mouse", 90); 229 fibril_mutex_initialize(&dev->aux->buf_lock); 230 fibril_condvar_initialize(&dev->aux->buf_cv); 231 232 rc = ddf_fun_add_match_id(dev->aux->fun, "char/ps2mouse", 90); 219 233 if (rc != EOK) 220 234 goto error; 221 235 222 ddf_fun_set_conn_handler(dev->kbd _fun, i8042_char_conn);223 ddf_fun_set_conn_handler(dev->aux _fun, i8042_char_conn);224 225 buffer_init(&dev->kbd_buffer, dev->kbd_data, BUFFER_SIZE);226 buffer_init(&dev->aux_buffer, dev->aux_data, BUFFER_SIZE);236 ddf_fun_set_conn_handler(dev->kbd->fun, i8042_char_conn); 237 ddf_fun_set_conn_handler(dev->aux->fun, i8042_char_conn); 238 239 circ_buf_init(&dev->kbd->cbuf, dev->kbd->buf_data, BUFFER_SIZE, 1); 240 circ_buf_init(&dev->aux->cbuf, dev->aux->buf_data, BUFFER_SIZE, 1); 227 241 fibril_mutex_initialize(&dev->write_guard); 228 242 229 rc = ddf_fun_bind(dev->kbd _fun);243 rc = ddf_fun_bind(dev->kbd->fun); 230 244 if (rc != EOK) { 231 245 ddf_msg(LVL_ERROR, "Failed to bind keyboard function: %s.", 232 ddf_fun_get_name(dev->kbd _fun));246 ddf_fun_get_name(dev->kbd->fun)); 233 247 goto error; 234 248 } 235 249 kbd_bound = true; 236 250 237 rc = ddf_fun_bind(dev->aux _fun);251 rc = ddf_fun_bind(dev->aux->fun); 238 252 if (rc != EOK) { 239 253 ddf_msg(LVL_ERROR, "Failed to bind aux function: %s.", 240 ddf_fun_get_name(dev->aux _fun));254 ddf_fun_get_name(dev->aux->fun)); 241 255 goto error; 242 256 } … … 317 331 error: 318 332 if (kbd_bound) 319 ddf_fun_unbind(dev->kbd _fun);333 ddf_fun_unbind(dev->kbd->fun); 320 334 if (aux_bound) 321 ddf_fun_unbind(dev->aux _fun);322 if (dev->kbd _fun != NULL)323 ddf_fun_destroy(dev->kbd _fun);324 if (dev->aux _fun != NULL)325 ddf_fun_destroy(dev->aux _fun);335 ddf_fun_unbind(dev->aux->fun); 336 if (dev->kbd->fun != NULL) 337 ddf_fun_destroy(dev->kbd->fun); 338 if (dev->aux->fun != NULL) 339 ddf_fun_destroy(dev->aux->fun); 326 340 327 341 return rc; … … 377 391 { 378 392 i8042_port_t *port = (i8042_port_t *)srv->srvs->sarg; 379 i8042_t *i8042 = port->ctl;393 size_t p; 380 394 uint8_t *destp = (uint8_t *)dest; 381 395 int rc; 382 size_t i; 383 384 buffer_t *buffer = (port == i8042->aux) ? 385 &i8042->aux_buffer : &i8042->kbd_buffer; 386 387 for (i = 0; i < size; ++i) { 388 rc = buffer_read(buffer, destp, i == 0); 396 397 fibril_mutex_lock(&port->buf_lock); 398 399 while (circ_buf_nused(&port->cbuf) == 0) 400 fibril_condvar_wait(&port->buf_cv, &port->buf_lock); 401 402 p = 0; 403 while (p < size) { 404 rc = circ_buf_pop(&port->cbuf, &destp[p]); 389 405 if (rc != EOK) 390 406 break; 391 ++destp; 392 } 393 394 *nread = i; 407 ++p; 408 } 409 410 fibril_mutex_unlock(&port->buf_lock); 411 412 *nread = p; 395 413 return EOK; 396 414 } -
uspace/drv/char/i8042/i8042.h
rf571ca49 rac307b2 2 2 * Copyright (c) 2006 Josef Cejka 3 3 * Copyright (c) 2011 Jan Vesely 4 * Copyright (c) 2017 Jiri Svoboda 4 5 * All rights reserved. 5 6 * … … 40 41 #define i8042_H_ 41 42 43 #include <adt/circ_buf.h> 42 44 #include <io/chardev_srv.h> 43 45 #include <ddi.h> 44 46 #include <fibril_synch.h> 45 47 #include <ddf/driver.h> 46 #include "buffer.h"47 48 48 49 #define NAME "i8042" … … 59 60 /** i8042 Port. */ 60 61 typedef struct { 61 struct i8042 *ctl; /**< Controller */ 62 chardev_srvs_t cds; /**< Character device server data */ 62 /** Controller */ 63 struct i8042 *ctl; 64 /** Device function */ 65 ddf_fun_t *fun; 66 /** Character device server data */ 67 chardev_srvs_t cds; 68 /** Circular buffer */ 69 circ_buf_t cbuf; 70 /** Buffer data space */ 71 uint8_t buf_data[BUFFER_SIZE]; 72 /** Protect buffer */ 73 fibril_mutex_t buf_lock; 74 /** Signal new data in buffer */ 75 fibril_condvar_t buf_cv; 63 76 } i8042_port_t; 64 77 65 78 /** i8042 Controller. */ 66 79 typedef struct i8042 { 67 i8042_regs_t *regs; /**< I/O registers. */ 68 ddf_fun_t *kbd_fun; /**< Pirmary port device function. */ 69 ddf_fun_t *aux_fun; /**< Auxiliary port device function. */ 70 buffer_t kbd_buffer; /**< Primary port buffer. */ 71 buffer_t aux_buffer; /**< Aux. port buffer. */ 72 uint8_t aux_data[BUFFER_SIZE]; /**< Primary port buffer space. */ 73 uint8_t kbd_data[BUFFER_SIZE]; /**< Aux. port buffer space. */ 80 /**< I/O registers. */ 81 i8042_regs_t *regs; 82 /** Keyboard port */ 74 83 i8042_port_t *kbd; 84 /** AUX port */ 75 85 i8042_port_t *aux; 76 fibril_mutex_t write_guard; /**< Prevents simultanous port writes.*/ 86 /** Prevents simultanous port writes.*/ 87 fibril_mutex_t write_guard; 77 88 } i8042_t; 78 79 89 80 90 extern int i8042_init(i8042_t *, addr_range_t *, int, int, ddf_dev_t *); -
uspace/drv/char/msim-con/msim-con.c
rf571ca49 rac307b2 37 37 #include <ddi.h> 38 38 #include <errno.h> 39 #include <i pc/char.h>39 #include <io/chardev_srv.h> 40 40 41 41 #include "msim-con.h" 42 42 43 43 static void msim_con_connection(ipc_callid_t, ipc_call_t *, void *); 44 45 static int msim_con_read(chardev_srv_t *, void *, size_t, size_t *); 46 static int msim_con_write(chardev_srv_t *, const void *, size_t, size_t *); 47 48 static chardev_ops_t msim_con_chardev_ops = { 49 .read = msim_con_read, 50 .write = msim_con_write 51 }; 44 52 45 53 static irq_cmd_t msim_cmds_proto[] = { … … 58 66 msim_con_t *con = (msim_con_t *) arg; 59 67 uint8_t c; 68 int rc; 69 70 fibril_mutex_lock(&con->buf_lock); 60 71 61 72 c = IPC_GET_ARG2(*call); 62 63 if ( con->client_sess != NULL) {64 async_exch_t *exch = async_exchange_begin(con->client_sess);65 async_msg_1(exch, CHAR_NOTIF_BYTE, c); 66 async_exchange_end(exch);67 }73 rc = circ_buf_push(&con->cbuf, &c); 74 if (rc != EOK) 75 ddf_msg(LVL_ERROR, "Buffer overrun"); 76 77 fibril_mutex_unlock(&con->buf_lock); 78 fibril_condvar_broadcast(&con->buf_cv); 68 79 } 69 80 … … 75 86 irq_cmd_t *msim_cmds = NULL; 76 87 int rc; 88 89 circ_buf_init(&con->cbuf, con->buf, msim_con_buf_size, 1); 90 fibril_mutex_initialize(&con->buf_lock); 91 fibril_condvar_initialize(&con->buf_cv); 77 92 78 93 msim_cmds = malloc(sizeof(msim_cmds_proto)); … … 106 121 async_irq_subscribe(res->irq, msim_irq_handler, con, &con->irq_code); 107 122 subscribed = true; 123 124 chardev_srvs_init(&con->cds); 125 con->cds.ops = &msim_con_chardev_ops; 126 con->cds.sarg = con; 108 127 109 128 rc = ddf_fun_bind(fun); … … 140 159 } 141 160 161 /** Read from msim console device */ 162 static int msim_con_read(chardev_srv_t *srv, void *buf, size_t size, 163 size_t *nread) 164 { 165 msim_con_t *con = (msim_con_t *) srv->srvs->sarg; 166 size_t p; 167 uint8_t *bp = (uint8_t *) buf; 168 int rc; 169 170 fibril_mutex_lock(&con->buf_lock); 171 172 while (circ_buf_nused(&con->cbuf) == 0) 173 fibril_condvar_wait(&con->buf_cv, &con->buf_lock); 174 175 p = 0; 176 while (p < size) { 177 rc = circ_buf_pop(&con->cbuf, &bp[p]); 178 if (rc != EOK) 179 break; 180 ++p; 181 } 182 183 fibril_mutex_unlock(&con->buf_lock); 184 185 *nread = p; 186 return EOK; 187 } 188 189 /** Write to msim console device */ 190 static int msim_con_write(chardev_srv_t *srv, const void *data, size_t size, 191 size_t *nwr) 192 { 193 msim_con_t *con = (msim_con_t *) srv->srvs->sarg; 194 size_t i; 195 uint8_t *dp = (uint8_t *) data; 196 197 for (i = 0; i < size; i++) 198 msim_con_putchar(con, dp[i]); 199 200 *nwr = size; 201 return EOK; 202 } 203 142 204 /** Character device connection handler. */ 143 205 static void msim_con_connection(ipc_callid_t iid, ipc_call_t *icall, 144 206 void *arg) 145 207 { 146 msim_con_t *con; 147 148 /* Answer the IPC_M_CONNECT_ME_TO call. */ 149 async_answer_0(iid, EOK); 150 151 con = (msim_con_t *)ddf_dev_data_get(ddf_fun_get_dev((ddf_fun_t *)arg)); 152 153 while (true) { 154 ipc_call_t call; 155 ipc_callid_t callid = async_get_call(&call); 156 sysarg_t method = IPC_GET_IMETHOD(call); 157 158 if (!method) { 159 /* The other side has hung up. */ 160 async_answer_0(callid, EOK); 161 return; 162 } 163 164 async_sess_t *sess = 165 async_callback_receive_start(EXCHANGE_SERIALIZE, &call); 166 if (sess != NULL) { 167 if (con->client_sess == NULL) { 168 con->client_sess = sess; 169 async_answer_0(callid, EOK); 170 } else 171 async_answer_0(callid, ELIMIT); 172 } else { 173 switch (method) { 174 case CHAR_WRITE_BYTE: 175 ddf_msg(LVL_DEBUG, "Write %" PRIun " to device\n", 176 IPC_GET_ARG1(call)); 177 msim_con_putchar(con, (uint8_t) IPC_GET_ARG1(call)); 178 async_answer_0(callid, EOK); 179 break; 180 default: 181 async_answer_0(callid, EINVAL); 182 } 183 } 184 } 208 msim_con_t *con = (msim_con_t *) ddf_dev_data_get( 209 ddf_fun_get_dev((ddf_fun_t *) arg)); 210 211 chardev_conn(iid, icall, &con->cds); 185 212 } 186 213 -
uspace/drv/char/msim-con/msim-con.h
rf571ca49 rac307b2 36 36 #define MSIM_CON_H 37 37 38 #include <adt/circ_buf.h> 38 39 #include <async.h> 39 40 #include <ddf/driver.h> 41 #include <fibril_synch.h> 42 #include <io/chardev_srv.h> 40 43 #include <loc.h> 41 44 #include <stdint.h> 45 46 enum { 47 msim_con_buf_size = 64 48 }; 42 49 43 50 /** MSIM console resources */ … … 51 58 async_sess_t *client_sess; 52 59 ddf_dev_t *dev; 60 chardev_srvs_t cds; 53 61 msim_con_res_t res; 54 62 irq_pio_range_t irq_range[1]; 55 63 irq_code_t irq_code; 64 circ_buf_t cbuf; 65 uint8_t buf[msim_con_buf_size]; 66 fibril_mutex_t buf_lock; 67 fibril_condvar_t buf_cv; 56 68 } msim_con_t; 57 69 -
uspace/drv/char/ns8250/ns8250.c
rf571ca49 rac307b2 1 1 /* 2 2 * Copyright (c) 2010 Lenka Trochtova 3 * Copyright (c) 201 1Jiri Svoboda3 * Copyright (c) 2017 Jiri Svoboda 4 4 * All rights reserved. 5 5 * … … 53 53 #include <ddf/interrupt.h> 54 54 #include <ddf/log.h> 55 #include < ops/char_dev.h>55 #include <io/chardev_srv.h> 56 56 57 57 #include <device/hw_res.h> … … 153 153 /** DDF function node */ 154 154 ddf_fun_t *fun; 155 /** Character device service */ 156 chardev_srvs_t cds; 155 157 /** Parent session */ 156 158 async_sess_t *parent_sess; … … 189 191 } 190 192 193 /** Obtain soft-state structure from chardev srv */ 194 static ns8250_t *srv_ns8250(chardev_srv_t *srv) 195 { 196 return (ns8250_t *)srv->srvs->sarg; 197 } 198 199 191 200 /** Find out if there is some incoming data available on the serial port. 192 201 * … … 234 243 /** Read data from the serial port device. 235 244 * 236 * @param fun The serial port function245 * @param srv Server-side connection data 237 246 * @param buf The output buffer for read data. 238 247 * @param count The number of bytes to be read. 239 * 240 * @return The number of bytes actually read on success, negative 241 * error number otherwise. 242 */ 243 static int ns8250_read(ddf_fun_t *fun, char *buf, size_t count) 244 { 245 ns8250_t *ns = fun_ns8250(fun); 246 int ret = 0; 247 248 if (count == 0) return 0; 248 * @param nread Place to store number of bytes actually read 249 * 250 * @return EOK on success or non-zero error code 251 */ 252 static int ns8250_read(chardev_srv_t *srv, void *buf, size_t count, size_t *nread) 253 { 254 ns8250_t *ns = srv_ns8250(srv); 255 char *bp = (char *) buf; 256 size_t pos = 0; 257 258 if (count == 0) { 259 *nread = 0; 260 return EOK; 261 } 249 262 250 263 fibril_mutex_lock(&ns->mutex); 251 264 while (buf_is_empty(&ns->input_buffer)) 252 265 fibril_condvar_wait(&ns->input_buffer_available, &ns->mutex); 253 while (!buf_is_empty(&ns->input_buffer) && (size_t)ret< count) {254 b uf[ret] = (char)buf_pop_front(&ns->input_buffer);255 ret++;266 while (!buf_is_empty(&ns->input_buffer) && pos < count) { 267 bp[pos] = (char)buf_pop_front(&ns->input_buffer); 268 pos++; 256 269 } 257 270 fibril_mutex_unlock(&ns->mutex); 258 271 259 return ret; 272 *nread = pos; 273 return EOK; 260 274 } 261 275 … … 274 288 /** Write data to the serial port. 275 289 * 276 * @param fun The serial port function290 * @param srv Server-side connection data 277 291 * @param buf The data to be written 278 292 * @param count The number of bytes to be written 279 * @return Zero on success 280 */ 281 static int ns8250_write(ddf_fun_t *fun, char *buf, size_t count) 282 { 283 ns8250_t *ns = fun_ns8250(fun); 293 * @param nwritten Place to store number of bytes successfully written 294 * @return EOK on success or non-zero error code 295 */ 296 static int ns8250_write(chardev_srv_t *srv, const void *buf, size_t count, 297 size_t *nwritten) 298 { 299 ns8250_t *ns = srv_ns8250(srv); 284 300 size_t idx; 301 uint8_t *bp = (uint8_t *) buf; 285 302 286 303 for (idx = 0; idx < count; idx++) 287 ns8250_putchar(ns, (uint8_t) buf[idx]); 288 289 return count; 290 } 291 292 static ddf_dev_ops_t ns8250_dev_ops; 304 ns8250_putchar(ns, bp[idx]); 305 306 *nwritten = count; 307 return EOK; 308 } 309 310 static int ns8250_open(chardev_srvs_t *, chardev_srv_t *); 311 static int ns8250_close(chardev_srv_t *); 312 static void ns8250_default_handler(chardev_srv_t *, ipc_callid_t, ipc_call_t *); 293 313 294 314 /** The character interface's callbacks. */ 295 static char_dev_ops_t ns8250_char_dev_ops = { 296 .read = &ns8250_read, 297 .write = &ns8250_write 315 static chardev_ops_t ns8250_chardev_ops = { 316 .open = ns8250_open, 317 .close = ns8250_close, 318 .read = ns8250_read, 319 .write = ns8250_write, 320 .def_handler = ns8250_default_handler 298 321 }; 322 323 static void ns8250_char_conn(ipc_callid_t, ipc_call_t *, void *); 299 324 300 325 static int ns8250_dev_add(ddf_dev_t *dev); … … 872 897 } 873 898 874 /* Set device operations. */ 875 ddf_fun_set_ops(fun, &ns8250_dev_ops); 899 ddf_fun_set_conn_handler(fun, ns8250_char_conn); 900 901 chardev_srvs_init(&ns->cds); 902 ns->cds.ops = &ns8250_chardev_ops; 903 ns->cds.sarg = ns; 904 876 905 rc = ddf_fun_bind(fun); 877 906 if (rc != EOK) { … … 930 959 * device. 931 960 * 932 * @param dev The device. 933 */ 934 static int ns8250_open(ddf_fun_t *fun) 935 { 936 ns8250_t *ns = fun_ns8250(fun); 961 * @param srvs Service structure 962 * @param srv Server-side connection structure 963 */ 964 static int ns8250_open(chardev_srvs_t *srvs, chardev_srv_t *srv) 965 { 966 ns8250_t *ns = srv_ns8250(srv); 937 967 int res; 938 968 … … 954 984 * the device. 955 985 * 956 * @param dev The device.957 */ 958 static void ns8250_close(ddf_fun_t *fun)959 { 960 ns8250_t *data = fun_ns8250(fun);986 * @param srv Server-side connection structure 987 */ 988 static int ns8250_close(chardev_srv_t *srv) 989 { 990 ns8250_t *data = srv_ns8250(srv); 961 991 962 992 fibril_mutex_lock(&data->mutex); … … 968 998 969 999 fibril_mutex_unlock(&data->mutex); 1000 1001 return EOK; 970 1002 } 971 1003 … … 1034 1066 * Configure the parameters of the serial communication. 1035 1067 */ 1036 static void ns8250_default_handler( ddf_fun_t *fun, ipc_callid_t callid,1068 static void ns8250_default_handler(chardev_srv_t *srv, ipc_callid_t callid, 1037 1069 ipc_call_t *call) 1038 1070 { 1071 ns8250_t *ns8250 = srv_ns8250(srv); 1039 1072 sysarg_t method = IPC_GET_IMETHOD(*call); 1040 1073 int ret; … … 1043 1076 switch (method) { 1044 1077 case SERIAL_GET_COM_PROPS: 1045 ns8250_get_props( ddf_fun_get_dev(fun), &baud_rate, &parity, &word_length,1078 ns8250_get_props(ns8250->dev, &baud_rate, &parity, &word_length, 1046 1079 &stop_bits); 1047 1080 async_answer_4(callid, EOK, baud_rate, parity, word_length, … … 1054 1087 word_length = IPC_GET_ARG3(*call); 1055 1088 stop_bits = IPC_GET_ARG4(*call); 1056 ret = ns8250_set_props( ddf_fun_get_dev(fun), baud_rate, parity, word_length,1089 ret = ns8250_set_props(ns8250->dev, baud_rate, parity, word_length, 1057 1090 stop_bits); 1058 1091 async_answer_0(callid, ret); … … 1064 1097 } 1065 1098 1099 void ns8250_char_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg) 1100 { 1101 ns8250_t *ns8250 = fun_ns8250((ddf_fun_t *)arg); 1102 1103 chardev_conn(iid, icall, &ns8250->cds); 1104 } 1105 1066 1106 /** Initialize the serial port driver. 1067 1107 * … … 1072 1112 { 1073 1113 ddf_log_init(NAME); 1074 1075 ns8250_dev_ops.open = &ns8250_open;1076 ns8250_dev_ops.close = &ns8250_close;1077 1078 ns8250_dev_ops.interfaces[CHAR_DEV_IFACE] = &ns8250_char_dev_ops;1079 ns8250_dev_ops.default_handler = &ns8250_default_handler;1080 1114 } 1081 1115 -
uspace/drv/char/ski-con/ski-con.c
rf571ca49 rac307b2 1 1 /* 2 2 * Copyright (c) 2005 Jakub Jermar 3 * Copyright (c) 201 1Jiri Svoboda3 * Copyright (c) 2017 Jiri Svoboda 4 4 * All rights reserved. 5 5 * … … 34 34 #include <ddf/log.h> 35 35 #include <errno.h> 36 #include <ipc/char.h> 36 #include <fibril.h> 37 #include <io/chardev.h> 37 38 #include <stdint.h> 38 39 #include <stdlib.h> 39 #include <thread.h>40 40 #include <stdbool.h> 41 41 … … 46 46 #define POLL_INTERVAL 10000 47 47 48 static void ski_con_thread_impl(void *arg);48 static int ski_con_fibril(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_write 58 }; 59 52 60 /** Add ski console device. */ 53 61 int ski_con_add(ski_con_t *con) 54 62 { 55 thread_id_t tid;63 fid_t fid; 56 64 ddf_fun_t *fun = NULL; 57 65 bool bound = false; 58 66 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); 59 71 60 72 fun = ddf_fun_create(con->dev, fun_exposed, "a"); … … 67 79 ddf_fun_set_conn_handler(fun, ski_con_connection); 68 80 81 chardev_srvs_init(&con->cds); 82 con->cds.ops = &ski_con_chardev_ops; 83 con->cds.sarg = con; 84 69 85 rc = ddf_fun_bind(fun); 70 86 if (rc != EOK) { … … 75 91 bound = true; 76 92 77 rc = thread_create(ski_con_thread_impl, con, "kbd_poll", &tid); 78 if (rc != 0) { 79 return rc; 80 } 81 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); 82 101 return EOK; 83 102 error: … … 102 121 } 103 122 104 /** Thread to poll Ski for keypresses. */105 static void ski_con_thread_impl(void *arg)123 /** Poll Ski for keypresses. */ 124 static int ski_con_fibril(void *arg) 106 125 { 107 126 int32_t c; 108 127 ski_con_t *con = (ski_con_t *) arg; 128 int rc; 109 129 110 130 while (1) { … … 114 134 break; 115 135 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 } 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); 121 144 } 122 145 123 thread_usleep(POLL_INTERVAL); 124 } 146 fibril_usleep(POLL_INTERVAL); 147 } 148 149 return 0; 125 150 } 126 151 … … 157 182 } 158 183 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 159 227 /** Character device connection handler. */ 160 228 static void ski_con_connection(ipc_callid_t iid, ipc_call_t *icall, 161 229 void *arg) 162 230 { 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 } 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); 202 235 } 203 236 -
uspace/drv/char/ski-con/ski-con.h
rf571ca49 rac307b2 36 36 #define SKI_CON_H 37 37 38 #include <adt/circ_buf.h> 38 39 #include <async.h> 39 40 #include <ddf/driver.h> 41 #include <io/chardev_srv.h> 40 42 #include <loc.h> 41 43 #include <stdint.h> 44 45 enum { 46 ski_con_buf_size = 64 47 }; 42 48 43 49 /** Ski console */ … … 45 51 async_sess_t *client_sess; 46 52 ddf_dev_t *dev; 53 chardev_srvs_t cds; 54 circ_buf_t cbuf; 55 uint8_t buf[ski_con_buf_size]; 56 fibril_mutex_t buf_lock; 57 fibril_condvar_t buf_cv; 47 58 } ski_con_t; 48 59 -
uspace/drv/char/sun4v-con/sun4v-con.c
rf571ca49 rac307b2 1 1 /* 2 2 * Copyright (c) 2008 Pavel Rimsky 3 * Copyright (c) 201 1Jiri Svoboda3 * Copyright (c) 2017 Jiri Svoboda 4 4 * All rights reserved. 5 5 * … … 36 36 #include <ddi.h> 37 37 #include <errno.h> 38 #include <i pc/char.h>38 #include <io/chardev_srv.h> 39 39 #include <stdbool.h> 40 40 #include <thread.h> … … 62 62 static input_buffer_t input_buffer; 63 63 64 static void sun4v_thread_impl(void *arg); 64 static int sun4v_con_read(chardev_srv_t *, void *, size_t, size_t *); 65 static int sun4v_con_write(chardev_srv_t *, const void *, size_t, size_t *); 66 67 static chardev_ops_t sun4v_con_chardev_ops = { 68 .read = sun4v_con_read, 69 .write = sun4v_con_write 70 }; 65 71 66 72 static void sun4v_con_putchar(sun4v_con_t *con, uint8_t data) … … 86 92 } 87 93 94 chardev_srvs_init(&con->cds); 95 con->cds.ops = &sun4v_con_chardev_ops; 96 con->cds.sarg = con; 97 88 98 ddf_fun_set_conn_handler(fun, sun4v_con_connection); 89 99 … … 94 104 goto error; 95 105 } 96 97 thread_id_t tid;98 rc = thread_create(sun4v_thread_impl, con, "kbd_poll", &tid);99 if (rc != EOK)100 goto error;101 106 102 107 rc = ddf_fun_bind(fun); … … 131 136 } 132 137 133 /** 134 * Called regularly by the polling thread. Reads codes of all the 135 * pressed keys from the buffer. 136 */ 137 static void sun4v_key_pressed(sun4v_con_t *con) 138 /** Read from Sun4v console device */ 139 static int sun4v_con_read(chardev_srv_t *srv, void *buf, size_t size, 140 size_t *nread) 138 141 { 142 size_t p; 143 uint8_t *bp = (uint8_t *) buf; 139 144 char c; 140 145 141 while (input_buffer->read_ptr != input_buffer->write_ptr) { 146 while (input_buffer->read_ptr == input_buffer->write_ptr) 147 fibril_usleep(POLL_INTERVAL); 148 149 p = 0; 150 while (p < size && input_buffer->read_ptr != input_buffer->write_ptr) { 142 151 c = input_buffer->data[input_buffer->read_ptr]; 143 152 input_buffer->read_ptr = 144 153 ((input_buffer->read_ptr) + 1) % INPUT_BUFFER_SIZE; 145 if (con->client_sess != NULL) { 146 async_exch_t *exch = async_exchange_begin(con->client_sess); 147 async_msg_1(exch, CHAR_NOTIF_BYTE, c); 148 async_exchange_end(exch); 149 } 150 (void) c; 154 bp[p++] = c; 151 155 } 156 157 *nread = p; 158 return EOK; 152 159 } 153 160 154 /** 155 * Thread to poll Sun4v console for keypresses. 156 */ 157 static void sun4v_thread_impl(void *arg) 161 /** Write to Sun4v console device */ 162 static int sun4v_con_write(chardev_srv_t *srv, const void *data, size_t size, 163 size_t *nwr) 158 164 { 159 sun4v_con_t *con = (sun4v_con_t *) arg; 165 sun4v_con_t *con = (sun4v_con_t *) srv->srvs->sarg; 166 size_t i; 167 uint8_t *dp = (uint8_t *) data; 160 168 161 while (true) { 162 sun4v_key_pressed(con); 163 thread_usleep(POLL_INTERVAL); 164 } 169 for (i = 0; i < size; i++) 170 sun4v_con_putchar(con, dp[i]); 171 172 *nwr = size; 173 return EOK; 165 174 } 166 175 … … 169 178 void *arg) 170 179 { 171 sun4v_con_t *con; 180 sun4v_con_t *con = (sun4v_con_t *) ddf_dev_data_get( 181 ddf_fun_get_dev((ddf_fun_t *) arg)); 172 182 173 /* Answer the IPC_M_CONNECT_ME_TO call. */ 174 async_answer_0(iid, EOK); 175 176 con = (sun4v_con_t *)ddf_dev_data_get(ddf_fun_get_dev((ddf_fun_t *)arg)); 177 178 while (true) { 179 ipc_call_t call; 180 ipc_callid_t callid = async_get_call(&call); 181 sysarg_t method = IPC_GET_IMETHOD(call); 182 183 if (!method) { 184 /* The other side has hung up. */ 185 async_answer_0(callid, EOK); 186 return; 187 } 188 189 async_sess_t *sess = 190 async_callback_receive_start(EXCHANGE_SERIALIZE, &call); 191 if (sess != NULL) { 192 if (con->client_sess == NULL) { 193 con->client_sess = sess; 194 async_answer_0(callid, EOK); 195 } else 196 async_answer_0(callid, ELIMIT); 197 } else { 198 switch (method) { 199 case CHAR_WRITE_BYTE: 200 ddf_msg(LVL_DEBUG, "Write %" PRIun " to device\n", 201 IPC_GET_ARG1(call)); 202 sun4v_con_putchar(con, (uint8_t) IPC_GET_ARG1(call)); 203 async_answer_0(callid, EOK); 204 break; 205 default: 206 async_answer_0(callid, EINVAL); 207 } 208 } 209 } 183 chardev_conn(iid, icall, &con->cds); 210 184 } 211 185 -
uspace/drv/char/sun4v-con/sun4v-con.h
rf571ca49 rac307b2 38 38 #include <async.h> 39 39 #include <ddf/driver.h> 40 #include <io/chardev_srv.h> 40 41 #include <loc.h> 41 42 #include <stdint.h> … … 50 51 async_sess_t *client_sess; 51 52 ddf_dev_t *dev; 53 chardev_srvs_t cds; 52 54 sun4v_con_res_t res; 53 55 } sun4v_con_t; -
uspace/drv/root/virt/devices.def
rf571ca49 rac307b2 26 26 }, 27 27 { 28 .name = "null",29 .match_id = "virtual&test1"30 },31 {32 28 .name = "test3", 33 29 .match_id = "virtual&test3" -
uspace/drv/test/test1/Makefile
rf571ca49 rac307b2 32 32 33 33 SOURCES = \ 34 char.c \35 34 test1.c 36 35 -
uspace/drv/test/test1/test1.c
rf571ca49 rac307b2 177 177 ddf_fun_add_to_category(fun_a, "virtual"); 178 178 179 if (str_cmp(dev_name, "null") == 0) { 180 ddf_fun_set_ops(fun_a, &char_device_ops); 181 ddf_fun_add_to_category(fun_a, "virt-null"); 182 } else if (str_cmp(dev_name, "test1") == 0) { 179 if (str_cmp(dev_name, "test1") == 0) { 183 180 (void) register_fun_verbose(dev, 184 181 "cloning myself ;-)", "clone", -
uspace/drv/test/test1/test1.h
rf571ca49 rac307b2 36 36 #define NAME "test1" 37 37 38 extern ddf_dev_ops_t char_device_ops;39 40 38 #endif -
uspace/lib/c/Makefile
rf571ca49 rac307b2 143 143 generic/getopt.c \ 144 144 generic/adt/checksum.c \ 145 generic/adt/circ_buf.c \ 145 146 generic/adt/list.c \ 146 147 generic/adt/hash_table.c \ … … 181 182 182 183 TEST_SOURCES = \ 184 test/adt/circ_buf.c \ 183 185 test/fibril/timer.c \ 184 186 test/main.c \ -
uspace/lib/c/generic/io/chardev_srv.c
rf571ca49 rac307b2 169 169 break; 170 170 default: 171 async_answer_0(callid, EINVAL); 171 if (srv->srvs->ops->def_handler != NULL) 172 srv->srvs->ops->def_handler(srv, callid, &call); 173 else 174 async_answer_0(callid, ENOTSUP); 172 175 } 173 176 } -
uspace/lib/c/include/adt/circ_buf.h
rf571ca49 rac307b2 1 1 /* 2 * Copyright (c) 20 09Jiri Svoboda2 * Copyright (c) 2017 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @addtogroup libc ipc29 /** @addtogroup libc 30 30 * @{ 31 31 */ 32 /** @file 33 * @brief Character device interface. 32 /** @file Circular buffer 34 33 */ 35 34 36 #ifndef LIBC_ IPC_CHAR_H_37 #define LIBC_ IPC_CHAR_H_35 #ifndef LIBC_CIRC_BUF_H_ 36 #define LIBC_CIRC_BUF_H_ 38 37 39 #include < ipc/common.h>38 #include <stddef.h> 40 39 41 typedef enum { 42 CHAR_WRITE_BYTE = IPC_FIRST_USER_METHOD 43 } char_request_t; 40 /** Circular buffer */ 41 typedef struct { 42 /** Buffer */ 43 void *buf; 44 /** Number of buffer members */ 45 size_t nmemb; 46 /** Member size */ 47 size_t size; 48 /** Read position */ 49 size_t rp; 50 /** Write position */ 51 size_t wp; 52 /** Number of used entries */ 53 size_t nused; 54 } circ_buf_t; 44 55 45 typedef enum { 46 CHAR_NOTIF_BYTE = IPC_FIRST_USER_METHOD 47 } char_notif_t; 56 extern void circ_buf_init(circ_buf_t *, void *, size_t, size_t); 57 extern size_t circ_buf_nfree(circ_buf_t *); 58 extern size_t circ_buf_nused(circ_buf_t *); 59 extern int circ_buf_push(circ_buf_t *, const void *); 60 extern int circ_buf_pop(circ_buf_t *, void *); 48 61 49 62 #endif -
uspace/lib/c/include/io/chardev_srv.h
rf571ca49 rac307b2 61 61 int (*read)(chardev_srv_t *, void *, size_t, size_t *); 62 62 int (*write)(chardev_srv_t *, const void *, size_t, size_t *); 63 void (*def_handler)(chardev_srv_t *, ipc_callid_t, ipc_call_t *); 63 64 }; 64 65 -
uspace/lib/c/include/ipc/chardev.h
rf571ca49 rac307b2 41 41 typedef enum { 42 42 CHARDEV_READ = IPC_FIRST_USER_METHOD, 43 CHARDEV_WRITE 43 CHARDEV_WRITE, 44 44 } chardev_request_t; 45 46 enum { 47 CHARDEV_LIMIT = CHARDEV_WRITE + 1 48 }; 45 49 46 50 #endif -
uspace/lib/c/include/ipc/serial_ctl.h
rf571ca49 rac307b2 30 30 #define LIBC_IPC_SERIAL_CTL_H_ 31 31 32 #include <ipc/ dev_iface.h>32 #include <ipc/chardev.h> 33 33 34 34 /** IPC methods for getting/setting serial communication properties … … 41 41 */ 42 42 typedef enum { 43 SERIAL_GET_COM_PROPS = DEV_FIRST_CUSTOM_METHOD,43 SERIAL_GET_COM_PROPS = CHARDEV_LIMIT, 44 44 SERIAL_SET_COM_PROPS 45 45 } serial_ctl_t; -
uspace/lib/c/test/adt/circ_buf.c
rf571ca49 rac307b2 1 1 /* 2 * Copyright (c) 201 0 Vojtech Horky2 * Copyright (c) 2017 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @file 29 #include <adt/circ_buf.h> 30 #include <pcut/pcut.h> 31 32 PCUT_INIT 33 34 PCUT_TEST_SUITE(circ_buf); 35 36 enum { 37 buffer_size = 16 38 }; 39 40 static int buffer[buffer_size]; 41 42 /** Basic insertion/deletion test. 43 * 44 * Test initialization, emptiness, pushing buffer until it is full, 45 * then emptying it again. 30 46 */ 47 PCUT_TEST(push_pop) 48 { 49 circ_buf_t cbuf; 50 int i; 51 int j; 52 int rc; 31 53 32 #include <assert.h> 33 #include <errno.h> 34 #include <mem.h> 35 #include <ops/char_dev.h> 54 circ_buf_init(&cbuf, buffer, buffer_size, sizeof(int)); 36 55 37 #include "test1.h" 56 for (i = 0; i < buffer_size; i++) { 57 PCUT_ASSERT_INT_EQUALS(buffer_size - i, circ_buf_nfree(&cbuf)); 58 PCUT_ASSERT_INT_EQUALS(i, circ_buf_nused(&cbuf)); 59 rc = circ_buf_push(&cbuf, &i); 60 PCUT_ASSERT_ERRNO_VAL(EOK, rc); 61 } 38 62 39 static int impl_char_read(ddf_fun_t *fun, char *buf, size_t count) { 40 memset(buf, 0, count); 41 return count; 63 rc = circ_buf_push(&cbuf, &i); 64 PCUT_ASSERT_ERRNO_VAL(EAGAIN, rc); 65 66 for (i = 0; i < buffer_size; i++) { 67 PCUT_ASSERT_INT_EQUALS(i, circ_buf_nfree(&cbuf)); 68 PCUT_ASSERT_INT_EQUALS(buffer_size - i, circ_buf_nused(&cbuf)); 69 rc = circ_buf_pop(&cbuf, &j); 70 PCUT_ASSERT_ERRNO_VAL(EOK, rc); 71 PCUT_ASSERT_INT_EQUALS(i, j); 72 } 73 74 PCUT_ASSERT_INT_EQUALS(buffer_size, circ_buf_nfree(&cbuf)); 75 PCUT_ASSERT_INT_EQUALS(0, circ_buf_nused(&cbuf)); 76 77 rc = circ_buf_pop(&cbuf, &j); 78 PCUT_ASSERT_ERRNO_VAL(EAGAIN, rc); 42 79 } 43 80 44 static int imp_char_write(ddf_fun_t *fun, char *buf, size_t count) { 45 return count; 46 } 47 48 static char_dev_ops_t char_dev_ops = { 49 .read = &impl_char_read, 50 .write = &imp_char_write 51 }; 52 53 ddf_dev_ops_t char_device_ops = { 54 .interfaces[CHAR_DEV_IFACE] = &char_dev_ops 55 }; 56 81 PCUT_EXPORT(circ_buf); -
uspace/lib/c/test/main.c
rf571ca49 rac307b2 32 32 PCUT_INIT 33 33 34 PCUT_IMPORT(circ_buf); 34 35 PCUT_IMPORT(fibril_timer); 35 36 PCUT_IMPORT(odict); -
uspace/lib/drv/Makefile
rf571ca49 rac307b2 43 43 generic/remote_hw_res.c \ 44 44 generic/remote_pio_window.c \ 45 generic/remote_char_dev.c \46 45 generic/remote_nic.c \ 47 46 generic/remote_ieee80211.c \ -
uspace/lib/drv/generic/dev_iface.c
rf571ca49 rac307b2 42 42 #include "remote_hw_res.h" 43 43 #include "remote_pio_window.h" 44 #include "remote_char_dev.h"45 44 #include "remote_clock_dev.h" 46 45 #include "remote_led_dev.h" … … 62 61 [HW_RES_DEV_IFACE] = &remote_hw_res_iface, 63 62 [PIO_WINDOW_DEV_IFACE] = &remote_pio_window_iface, 64 [CHAR_DEV_IFACE] = &remote_char_dev_iface,65 63 [NIC_DEV_IFACE] = &remote_nic_iface, 66 64 [IEEE80211_DEV_IFACE] = &remote_ieee80211_iface, -
uspace/srv/hid/input/input.c
rf571ca49 rac307b2 37 37 */ 38 38 39 #include <adt/fifo.h> 39 40 #include <adt/list.h> 40 #include <stdbool.h> 41 #include <async.h> 42 #include <config.h> 43 #include <errno.h> 44 #include <fibril.h> 41 45 #include <fibril_synch.h> 46 #include <io/chardev.h> 47 #include <io/console.h> 48 #include <io/keycode.h> 42 49 #include <ipc/services.h> 43 50 #include <ipc/input.h> 44 #include <config.h> 51 #include <loc.h> 52 #include <ns.h> 53 #include <stdbool.h> 45 54 #include <stdio.h> 46 55 #include <stdlib.h> 47 #include <ns.h>48 #include <async.h>49 #include <errno.h>50 #include <adt/fifo.h>51 #include <io/console.h>52 #include <io/keycode.h>53 #include <loc.h>54 56 #include <str_error.h> 55 #include <char_dev_iface.h> 56 #include <fibril.h> 57 #include "layout.h" 57 58 #include "input.h" 58 59 #include "kbd.h" 59 60 #include "kbd_port.h" 60 61 #include "kbd_ctl.h" 62 #include "layout.h" 61 63 #include "mouse.h" 62 64 #include "mouse_proto.h" 63 65 #include "serial.h" 64 #include "input.h"65 66 66 67 #define NUM_LAYOUTS 4 … … 536 537 while (true) { 537 538 uint8_t data; 538 539 char_dev_read(sdev->sess, &data, sizeof(data)); 539 size_t nread; 540 541 chardev_read(sdev->chardev, &data, sizeof(data), &nread); 542 /* XXX Handle error */ 540 543 kbd_push_data(sdev->kdev, data); 541 544 } … … 552 555 { 553 556 bool match = false; 557 int rc; 554 558 555 559 serial_dev_t *sdev = serial_dev_new(); … … 559 563 sdev->kdev->svc_id = service_id; 560 564 561 intrc = loc_service_get_name(service_id, &sdev->kdev->svc_name);565 rc = loc_service_get_name(service_id, &sdev->kdev->svc_name); 562 566 if (rc != EOK) 563 567 goto fail; … … 582 586 sdev->sess = loc_service_connect(service_id, INTERFACE_DDF, 583 587 IPC_FLAG_BLOCKING); 588 589 rc = chardev_open(sdev->sess, &sdev->chardev); 590 if (rc != EOK) { 591 async_hangup(sdev->sess); 592 sdev->sess = NULL; 593 list_remove(&sdev->link); 594 goto fail; 595 } 584 596 585 597 fid_t fid = fibril_create(serial_consumer, sdev); -
uspace/srv/hid/input/port/chardev.c
rf571ca49 rac307b2 35 35 */ 36 36 37 #include <ipc/char.h>38 37 #include <async.h> 38 #include <errno.h> 39 #include <fibril.h> 40 #include <io/chardev.h> 39 41 #include <loc.h> 40 #include <errno.h>41 42 #include <stdio.h> 42 43 #include "../input.h" … … 44 45 #include "../kbd.h" 45 46 46 static void kbd_port_events(ipc_callid_t iid, ipc_call_t *icall, void *arg);47 static int kbd_port_fibril(void *); 47 48 48 49 static int chardev_port_init(kbd_dev_t *); 49 static void chardev_port_write(uint8_t data);50 static void chardev_port_write(uint8_t); 50 51 51 52 kbd_port_ops_t chardev_port = { … … 56 57 static kbd_dev_t *kbd_dev; 57 58 static async_sess_t *dev_sess; 59 static chardev_t *chardev; 58 60 59 61 /** List of devices to try connecting to. */ … … 70 72 { 71 73 service_id_t service_id; 72 async_exch_t *exch;73 74 unsigned int i; 75 fid_t fid; 74 76 int rc; 75 77 … … 96 98 } 97 99 98 exch = async_exchange_begin(dev_sess);99 if ( exch == NULL) {100 printf("%s: Failed starting exchange withdevice\n", NAME);100 rc = chardev_open(dev_sess, &chardev); 101 if (rc != EOK) { 102 printf("%s: Failed opening character device\n", NAME); 101 103 async_hangup(dev_sess); 102 104 return ENOMEM; 103 105 } 104 106 105 port_id_t port; 106 rc = async_create_callback_port(exch, INTERFACE_CHAR_CB, 0, 0, 107 kbd_port_events, NULL, &port); 108 109 async_exchange_end(exch); 110 111 if (rc != 0) { 112 printf("%s: Failed to create callback from device\n", NAME); 107 fid = fibril_create(kbd_port_fibril, NULL); 108 if (fid == 0) { 109 printf("%s: Failed creating fibril\n", NAME); 110 chardev_close(chardev); 113 111 async_hangup(dev_sess); 114 return -1;112 return ENOMEM; 115 113 } 114 115 fibril_add_ready(fid); 116 116 117 117 printf("%s: Found input device '%s'\n", NAME, in_devs[i]); … … 121 121 static void chardev_port_write(uint8_t data) 122 122 { 123 async_exch_t *exch = async_exchange_begin(dev_sess); 124 if (exch == NULL) { 125 printf("%s: Failed starting exchange with device\n", NAME); 123 int rc; 124 size_t nwr; 125 126 rc = chardev_write(chardev, &data, sizeof(data), &nwr); 127 if (rc != EOK || nwr != sizeof(data)) { 128 printf("%s: Failed writing to character device\n", NAME); 126 129 return; 127 }128 129 async_msg_1(exch, CHAR_WRITE_BYTE, data);130 async_exchange_end(exch);131 }132 133 static void kbd_port_events(ipc_callid_t iid, ipc_call_t *icall, void *arg)134 {135 /* Ignore parameters, the connection is already opened */136 while (true) {137 138 ipc_call_t call;139 ipc_callid_t callid = async_get_call(&call);140 141 if (!IPC_GET_IMETHOD(call)) {142 /* TODO: Handle hangup */143 return;144 }145 146 int retval = EOK;147 148 switch (IPC_GET_IMETHOD(call)) {149 case CHAR_NOTIF_BYTE:150 kbd_push_data(kbd_dev, IPC_GET_ARG1(call));151 break;152 default:153 retval = ENOENT;154 }155 async_answer_0(callid, retval);156 130 } 157 131 } 158 132 133 static int kbd_port_fibril(void *arg) 134 { 135 int rc; 136 size_t nread; 137 uint8_t b; 138 139 while (true) { 140 rc = chardev_read(chardev, &b, sizeof(b), &nread); 141 if (rc != EOK || nread != sizeof(b)) { 142 printf("%s: Error reading data", NAME); 143 continue; 144 } 145 146 kbd_push_data(kbd_dev, b); 147 } 148 149 return 0; 150 } 159 151 160 152 /** -
uspace/srv/hid/input/serial.h
rf571ca49 rac307b2 39 39 40 40 #include <async.h> 41 #include <io/chardev.h> 41 42 #include "kbd.h" 42 43 … … 45 46 link_t link; 46 47 async_sess_t *sess; 48 chardev_t *chardev; 47 49 } serial_dev_t; 48 50 -
uspace/srv/hid/isdv4_tablet/isdv4.c
rf571ca49 rac307b2 27 27 */ 28 28 29 #include <char_dev_iface.h>30 29 #include <errno.h> 30 #include <io/chardev.h> 31 #include <mem.h> 31 32 #include <stdbool.h> 32 33 #include <stdint.h> 33 34 #include <stdlib.h> 34 #include <mem.h>35 35 #include <thread.h> 36 36 … … 298 298 bool reading = true; 299 299 while (reading) { 300 ssize_t read = char_dev_read(state->sess, state->buf + state->buf_end, 301 state->buf_size - state->buf_end); 302 if (read < 0) 300 size_t nread; 301 int rc; 302 303 rc = chardev_read(state->chardev, state->buf + state->buf_end, 304 state->buf_size - state->buf_end, &nread); 305 if (rc != EOK && nread == 0) 303 306 return EIO; 304 state->buf_end += read;307 state->buf_end += nread; 305 308 306 309 size_t i = 0; … … 357 360 return EOK; 358 361 } 359 static bool write_command(async_sess_t *sess, uint8_t command) 360 { 361 return char_dev_write(sess, &command, 1) == 1; 362 363 static bool write_command(chardev_t *chardev, uint8_t command) 364 { 365 int rc; 366 size_t nwr; 367 368 rc = chardev_write(chardev, &command, 1, &nwr); 369 return rc == EOK; 362 370 } 363 371 … … 365 373 isdv4_event_fn event_fn) 366 374 { 375 chardev_t *chardev; 376 int rc; 377 378 rc = chardev_open(sess, &chardev); 379 if (rc != EOK) 380 return rc; 381 367 382 memset(state, 0, sizeof(isdv4_state_t)); 383 368 384 state->sess = sess; 385 state->chardev = chardev; 386 369 387 state->buf = malloc(BUF_SIZE); 370 if (state->buf == NULL) 388 if (state->buf == NULL) { 389 chardev_close(chardev); 371 390 return ENOMEM; 391 } 392 372 393 state->buf_size = BUF_SIZE; 373 394 state->emit_event_fn = event_fn; … … 377 398 int isdv4_init_tablet(isdv4_state_t *state) 378 399 { 379 if (!write_command(state-> sess, CMD_STOP))400 if (!write_command(state->chardev, CMD_STOP)) 380 401 return EIO; 381 402 … … 383 404 384 405 // FIXME: Read all possible garbage before sending commands 385 if (!write_command(state-> sess, CMD_QUERY_STYLUS))406 if (!write_command(state->chardev, CMD_QUERY_STYLUS)) 386 407 return EIO; 387 408 … … 390 411 return rc; 391 412 392 if (!write_command(state-> sess, CMD_QUERY_TOUCH))413 if (!write_command(state->chardev, CMD_QUERY_TOUCH)) 393 414 return EIO; 394 415 … … 397 418 return rc; 398 419 399 if (!write_command(state-> sess, CMD_START))420 if (!write_command(state->chardev, CMD_START)) 400 421 return EIO; 401 422 -
uspace/srv/hid/isdv4_tablet/isdv4.h
rf571ca49 rac307b2 31 31 32 32 #include <async.h> 33 #include <io/chardev.h> 33 34 34 35 typedef struct isdv4_event isdv4_event_t; … … 58 59 bool finger1_pressed; /* Reported as touch button 1 */ 59 60 60 /* Session tothe serial device */61 /** Session with the serial device */ 61 62 async_sess_t *sess; 63 /** Character device */ 64 chardev_t *chardev; 62 65 63 66 /* Receive buffer state */ … … 66 69 size_t buf_end; 67 70 68 /* Callbacks */71 /** Callbacks */ 69 72 isdv4_event_fn emit_event_fn; 70 73 } isdv4_state_t; -
uspace/srv/hid/output/port/chardev.c
rf571ca49 rac307b2 30 30 */ 31 31 32 #include <async.h> 33 #include <config.h> 34 #include <errno.h> 35 #include <fibril_synch.h> 36 #include <io/chardev.h> 37 #include <loc.h> 32 38 #include <stddef.h> 33 39 #include <stdint.h> 34 #include <char_dev_iface.h>35 40 #include <stdio.h> 36 41 #include <stdlib.h> 37 #include <async.h>38 #include <fibril_synch.h>39 #include <loc.h>40 #include <errno.h>41 42 #include <str.h> 42 #include <config.h>43 43 #include "../ctl/serial.h" 44 44 #include "../output.h" … … 48 48 49 49 static async_sess_t *sess; 50 static chardev_t *chardev; 50 51 static service_id_t serial_cat_id; 51 52 … … 57 58 { 58 59 uint8_t byte = (uint8_t) ch; 59 char_dev_write(sess, &byte, 1); 60 size_t nwr; 61 chardev_write(chardev, &byte, 1, &nwr); 62 /* XXX Handle error */ 60 63 } 61 64 62 65 static void chardev_control_puts(const char *str) 63 66 { 64 char_dev_write(sess, (void *) str, str_size(str)); 67 size_t nwr; 68 chardev_write(chardev, (void *) str, str_size(str), &nwr); 69 /* XXX Handle error */ 65 70 } 66 71 … … 126 131 return; 127 132 } 133 134 rc = chardev_open(sess, &chardev); 135 if (rc != EOK) { 136 fibril_mutex_unlock(&discovery_lock); 137 printf("%s: Failed opening character device\n", NAME); 138 return; 139 } 140 128 141 serial_init(chardev_putchar, chardev_control_puts); 129 142 -
uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c
rf571ca49 rac307b2 27 27 */ 28 28 29 /** @addtogroup driver_serial30 * @{31 */32 29 /** 33 30 * @file … … 37 34 */ 38 35 36 #include <async.h> 39 37 #include <ddi.h> 38 #include <errno.h> 39 #include <inttypes.h> 40 #include <io/chardev_srv.h> 40 41 #include <loc.h> 41 #include <ipc/char.h>42 #include <async.h>43 42 #include <stdio.h> 44 43 #include <stdlib.h> 45 44 #include <sysinfo.h> 46 #include <errno.h>47 #include <inttypes.h>48 45 #include "s3c24xx_uart.h" 49 46 … … 72 69 static void s3c24xx_uart_sendb(s3c24xx_uart_t *, uint8_t); 73 70 71 static int s3c24xx_uart_read(chardev_srv_t *, void *, size_t, size_t *); 72 static int s3c24xx_uart_write(chardev_srv_t *, const void *, size_t, size_t *); 73 74 static chardev_ops_t s3c24xx_uart_chardev_ops = { 75 .read = s3c24xx_uart_read, 76 .write = s3c24xx_uart_write 77 }; 78 74 79 int main(int argc, char *argv[]) 75 80 { 76 81 printf("%s: S3C24xx on-chip UART driver\n", NAME); 77 82 78 async_set_fallback_port_handler(s3c24xx_uart_connection, NULL);83 async_set_fallback_port_handler(s3c24xx_uart_connection, uart); 79 84 int rc = loc_server_register(NAME); 80 85 if (rc != EOK) { … … 111 116 void *arg) 112 117 { 113 /* Answer the IPC_M_CONNECT_ME_TO call. */ 114 async_answer_0(iid, EOK); 115 116 while (true) { 117 ipc_call_t call; 118 ipc_callid_t callid = async_get_call(&call); 119 sysarg_t method = IPC_GET_IMETHOD(call); 120 121 if (!method) { 122 /* The other side has hung up. */ 123 async_answer_0(callid, EOK); 124 return; 125 } 126 127 async_sess_t *sess = 128 async_callback_receive_start(EXCHANGE_SERIALIZE, &call); 129 if (sess != NULL) { 130 if (uart->client_sess == NULL) { 131 uart->client_sess = sess; 132 async_answer_0(callid, EOK); 133 } else 134 async_answer_0(callid, ELIMIT); 135 } else { 136 switch (method) { 137 case CHAR_WRITE_BYTE: 138 printf(NAME ": write %" PRIun " to device\n", 139 IPC_GET_ARG1(call)); 140 s3c24xx_uart_sendb(uart, (uint8_t) IPC_GET_ARG1(call)); 141 async_answer_0(callid, EOK); 142 break; 143 default: 144 async_answer_0(callid, EINVAL); 145 } 146 } 147 } 148 } 118 s3c24xx_uart_t *uart = (s3c24xx_uart_t *) arg; 119 120 chardev_conn(iid, icall, &uart->cds); 121 } 122 149 123 150 124 static void s3c24xx_uart_irq_handler(ipc_callid_t iid, ipc_call_t *call, 151 125 void *arg) 152 126 { 127 int rc; 128 153 129 (void) iid; 154 130 (void) call; … … 159 135 uint32_t status = pio_read_32(&uart->io->uerstat); 160 136 161 if (uart->client_sess != NULL) { 162 async_exch_t *exch = async_exchange_begin(uart->client_sess); 163 async_msg_1(exch, CHAR_NOTIF_BYTE, data); 164 async_exchange_end(exch); 165 } 137 fibril_mutex_lock(&uart->buf_lock); 138 139 rc = circ_buf_push(&uart->cbuf, &data); 140 if (rc != EOK) 141 printf(NAME ": Buffer overrun\n"); 142 143 fibril_mutex_unlock(&uart->buf_lock); 144 fibril_condvar_broadcast(&uart->buf_cv); 166 145 167 146 if (status != 0) … … 176 155 sysarg_t inr; 177 156 157 circ_buf_init(&uart->cbuf, uart->buf, s3c24xx_uart_buf_size, 1); 158 fibril_mutex_initialize(&uart->buf_lock); 159 fibril_condvar_initialize(&uart->buf_cv); 160 178 161 if (sysinfo_get_value("s3c24xx_uart.address.physical", 179 162 &uart->paddr) != EOK) … … 188 171 189 172 uart->io = vaddr; 190 uart->client_sess = NULL;191 173 192 174 printf(NAME ": device at physical address %p, inr %" PRIun ".\n", … … 203 185 pio_read_32(&uart->io->ucon) & ~UCON_RX_INT_LEVEL); 204 186 187 chardev_srvs_init(&uart->cds); 188 uart->cds.ops = &s3c24xx_uart_chardev_ops; 189 uart->cds.sarg = uart; 190 205 191 return EOK; 206 192 } … … 216 202 } 217 203 204 static int s3c24xx_uart_read(chardev_srv_t *srv, void *buf, size_t size, 205 size_t *nread) 206 { 207 s3c24xx_uart_t *uart = (s3c24xx_uart_t *) srv->srvs->sarg; 208 size_t p; 209 uint8_t *bp = (uint8_t *) buf; 210 int rc; 211 212 fibril_mutex_lock(&uart->buf_lock); 213 214 while (circ_buf_nused(&uart->cbuf) == 0) 215 fibril_condvar_wait(&uart->buf_cv, &uart->buf_lock); 216 217 p = 0; 218 while (p < size) { 219 rc = circ_buf_pop(&uart->cbuf, &bp[p]); 220 if (rc != EOK) 221 break; 222 ++p; 223 } 224 225 fibril_mutex_unlock(&uart->buf_lock); 226 227 *nread = p; 228 return EOK; 229 } 230 231 static int s3c24xx_uart_write(chardev_srv_t *srv, const void *data, size_t size, 232 size_t *nwr) 233 { 234 s3c24xx_uart_t *uart = (s3c24xx_uart_t *) srv->srvs->sarg; 235 size_t i; 236 uint8_t *dp = (uint8_t *) data; 237 238 for (i = 0; i < size; i++) 239 s3c24xx_uart_sendb(uart, dp[i]); 240 241 *nwr = size; 242 return EOK; 243 } 244 245 218 246 /** @} 219 247 */ -
uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.h
rf571ca49 rac307b2 38 38 #define S3C24XX_UART_H_ 39 39 40 #include <adt/circ_buf.h> 41 #include <async.h> 42 #include <fibril_synch.h> 43 #include <io/chardev_srv.h> 40 44 #include <stdint.h> 41 #include <async.h>42 45 43 46 /** S3C24xx UART I/O */ … … 76 79 #define UFCON_FIFO_ENABLE 0x01 77 80 81 enum { 82 s3c24xx_uart_buf_size = 64 83 }; 78 84 79 85 /** S3C24xx UART instance */ … … 85 91 s3c24xx_uart_io_t *io; 86 92 87 /** C allback session to the client*/88 async_sess_t *client_sess;93 /** Character device service */ 94 chardev_srvs_t cds; 89 95 90 96 /** Service ID */ 91 97 service_id_t service_id; 98 99 /** Circular buffer */ 100 circ_buf_t cbuf; 101 /** Buffer */ 102 uint8_t buf[s3c24xx_uart_buf_size]; 103 /** Buffer lock */ 104 fibril_mutex_t buf_lock; 105 /** Signal newly added data in buffer */ 106 fibril_condvar_t buf_cv; 92 107 } s3c24xx_uart_t; 93 108 -
uspace/srv/net/slip/slip.c
rf571ca49 rac307b2 40 40 #include <inet/addr.h> 41 41 #include <inet/iplink_srv.h> 42 #include < char_dev_iface.h>42 #include <io/chardev.h> 43 43 #include <io/log.h> 44 44 #include <errno.h> … … 96 96 } 97 97 98 static void write_flush( async_sess_t *sess)98 static void write_flush(chardev_t *chardev) 99 99 { 100 100 size_t written = 0; 101 101 102 102 while (slip_send_pending > 0) { 103 ssize_t size; 104 105 size = char_dev_write(sess, &slip_send_buf[written], 106 slip_send_pending); 107 if (size < 0) { 103 int rc; 104 size_t nwr; 105 106 rc = chardev_write(chardev, &slip_send_buf[written], 107 slip_send_pending, &nwr); 108 if (rc != EOK) { 108 109 log_msg(LOG_DEFAULT, LVL_ERROR, 109 "char_dev_write() returned %d", 110 (int) size); 110 "chardev_write() returned %d", rc); 111 111 slip_send_pending = 0; 112 112 break; 113 113 } 114 written += size;115 slip_send_pending -= size;116 } 117 } 118 119 static void write_buffered( async_sess_t *sess, uint8_t ch)114 written += nwr; 115 slip_send_pending -= nwr; 116 } 117 } 118 119 static void write_buffered(chardev_t *chardev, uint8_t ch) 120 120 { 121 121 if (slip_send_pending == sizeof(slip_send_buf)) 122 write_flush( sess);122 write_flush(chardev); 123 123 slip_send_buf[slip_send_pending++] = ch; 124 124 } … … 128 128 log_msg(LOG_DEFAULT, LVL_DEBUG, "slip_send()"); 129 129 130 async_sess_t *sess = (async_sess_t *) srv->arg;130 chardev_t *chardev = (chardev_t *) srv->arg; 131 131 uint8_t *data = sdu->data; 132 132 … … 136 136 * measure for dealing with previous possible noise on the line. 137 137 */ 138 write_buffered( sess, SLIP_END);138 write_buffered(chardev, SLIP_END); 139 139 140 140 for (size_t i = 0; i < sdu->size; i++) { 141 141 switch (data[i]) { 142 142 case SLIP_END: 143 write_buffered( sess, SLIP_ESC);144 write_buffered( sess, SLIP_ESC_END);143 write_buffered(chardev, SLIP_ESC); 144 write_buffered(chardev, SLIP_ESC_END); 145 145 break; 146 146 case SLIP_ESC: 147 write_buffered( sess, SLIP_ESC);148 write_buffered( sess, SLIP_ESC_ESC);147 write_buffered(chardev, SLIP_ESC); 148 write_buffered(chardev, SLIP_ESC_ESC); 149 149 break; 150 150 default: 151 write_buffered( sess, data[i]);151 write_buffered(chardev, data[i]); 152 152 break; 153 153 } 154 154 } 155 155 156 write_buffered( sess, SLIP_END);157 write_flush( sess);156 write_buffered(chardev, SLIP_END); 157 write_flush(chardev); 158 158 159 159 return EOK; … … 203 203 } 204 204 205 static uint8_t read_buffered( async_sess_t *sess)205 static uint8_t read_buffered(chardev_t *chardev) 206 206 { 207 207 while (slip_recv_pending == 0) { 208 ssize_t size; 209 210 size = char_dev_read(sess, slip_recv_buf, 211 sizeof(slip_recv_buf)); 212 if (size < 0) { 208 int rc; 209 size_t nread; 210 211 rc = chardev_read(chardev, slip_recv_buf, 212 sizeof(slip_recv_buf), &nread); 213 if (rc != EOK) { 213 214 log_msg(LOG_DEFAULT, LVL_ERROR, 214 "char_dev_read() returned %d", (int) size); 215 "char_dev_read() returned %d", rc); 216 } 217 218 if (nread == 0) 215 219 return SLIP_END; 216 } 217 slip_recv_pending = size;220 221 slip_recv_pending = nread; 218 222 slip_recv_read = 0; 219 223 } … … 224 228 static int slip_recv_fibril(void *arg) 225 229 { 226 async_sess_t *sess = (async_sess_t *) arg;230 chardev_t *chardev = (chardev_t *) arg; 227 231 static uint8_t recv_final[SLIP_MTU]; 228 232 iplink_recv_sdu_t sdu; … … 234 238 while (true) { 235 239 for (sdu.size = 0; sdu.size < sizeof(recv_final); /**/) { 236 ch = read_buffered( sess);240 ch = read_buffered(chardev); 237 241 switch (ch) { 238 242 case SLIP_END: … … 246 250 247 251 case SLIP_ESC: 248 ch = read_buffered( sess);252 ch = read_buffered(chardev); 249 253 if (ch == SLIP_ESC_END) { 250 254 recv_final[sdu.size++] = SLIP_END; 251 255 break; 252 } else if (ch == 256 } else if (ch == SLIP_ESC_ESC) { 253 257 recv_final[sdu.size++] = SLIP_ESC; 254 258 break; … … 295 299 async_sess_t *sess_in = NULL; 296 300 async_sess_t *sess_out = NULL; 301 chardev_t *chardev_in = NULL; 302 chardev_t *chardev_out = NULL; 297 303 fid_t fid; 298 304 int rc; … … 336 342 return ENOENT; 337 343 } 338 slip_iplink.arg = sess_out; 344 345 rc = chardev_open(sess_out, &chardev_out); 346 if (rc != EOK) { 347 log_msg(LOG_DEFAULT, LVL_ERROR, 348 "Failed opening character device."); 349 return ENOENT; 350 } 351 352 slip_iplink.arg = chardev_out; 339 353 340 354 sess_in = loc_service_connect(svcid, INTERFACE_DDF, 0); … … 347 361 } 348 362 363 rc = chardev_open(sess_in, &chardev_in); 364 if (rc != EOK) { 365 log_msg(LOG_DEFAULT, LVL_ERROR, 366 "Failed opening character device."); 367 return ENOENT; 368 } 369 349 370 rc = loc_service_register(linkstr, &linksid); 350 371 if (rc != EOK) { … … 363 384 } 364 385 365 fid = fibril_create(slip_recv_fibril, sess_in);386 fid = fibril_create(slip_recv_fibril, chardev_in); 366 387 if (!fid) { 367 388 log_msg(LOG_DEFAULT, LVL_ERROR, … … 375 396 376 397 fail: 398 chardev_close(chardev_out); 377 399 if (sess_out) 378 400 async_hangup(sess_out); 401 chardev_close(chardev_in); 379 402 if (sess_in) 380 403 async_hangup(sess_in);
Note:
See TracChangeset
for help on using the changeset viewer.