Changeset 7a6065c in mainline
- Timestamp:
- 2017-11-23T11:56:31Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 221176c1
- Parents:
- 74017ce
- git-author:
- Jiri Svoboda <jiri@…> (2017-11-22 19:55:36)
- git-committer:
- Jiri Svoboda <jiri@…> (2017-11-23 11:56:31)
- Location:
- uspace
- Files:
-
- 3 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified uspace/drv/char/msim-con/msim-con.c ¶
r74017ce r7a6065c 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 -
TabularUnified uspace/drv/char/msim-con/msim-con.h ¶
r74017ce r7a6065c 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 -
TabularUnified uspace/drv/char/ski-con/ski-con.c ¶
r74017ce r7a6065c 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 -
TabularUnified uspace/drv/char/ski-con/ski-con.h ¶
r74017ce r7a6065c 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 -
TabularUnified uspace/drv/char/sun4v-con/sun4v-con.c ¶
r74017ce r7a6065c 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 -
TabularUnified uspace/drv/char/sun4v-con/sun4v-con.h ¶
r74017ce r7a6065c 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; -
TabularUnified uspace/lib/c/Makefile ¶
r74017ce r7a6065c 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 \ -
TabularUnified uspace/lib/c/test/main.c ¶
r74017ce r7a6065c 32 32 PCUT_INIT 33 33 34 PCUT_IMPORT(circ_buf); 34 35 PCUT_IMPORT(fibril_timer); 35 36 PCUT_IMPORT(odict); -
TabularUnified uspace/srv/hid/input/port/chardev.c ¶
r74017ce r7a6065c 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 /** -
TabularUnified uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c ¶
r74017ce r7a6065c 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 */ -
TabularUnified uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.h ¶
r74017ce r7a6065c 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
Note:
See TracChangeset
for help on using the changeset viewer.