Changeset ac307b2 in mainline for uspace/drv/char/msim-con/msim-con.c
- Timestamp:
- 2017-11-25T11:12:23Z (6 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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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
Note:
See TracChangeset
for help on using the changeset viewer.