Changes in uspace/drv/char/msim-con/msim-con.c [7de5f12:071a1ddb] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/char/msim-con/msim-con.c
r7de5f12 r071a1ddb 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" … … 43 43 static void msim_con_connection(ipc_callid_t, ipc_call_t *, void *); 44 44 45 static irq_pio_range_t msim_ranges[] = { 46 { 47 .base = 0, 48 .size = 1 49 } 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 50 51 }; 51 52 52 static irq_cmd_t msim_cmds [] = {53 static irq_cmd_t msim_cmds_proto[] = { 53 54 { 54 55 .cmd = CMD_PIO_READ_8, … … 61 62 }; 62 63 63 static irq_code_t msim_kbd = { 64 sizeof(msim_ranges) / sizeof(irq_pio_range_t), 65 msim_ranges, 66 sizeof(msim_cmds) / sizeof(irq_cmd_t), 67 msim_cmds 68 }; 69 70 static void msim_irq_handler(ipc_callid_t iid, ipc_call_t *call, void *arg) 64 static void msim_irq_handler(ipc_call_t *call, void *arg) 71 65 { 72 66 msim_con_t *con = (msim_con_t *) arg; 73 67 uint8_t c; 68 int rc; 69 70 fibril_mutex_lock(&con->buf_lock); 74 71 75 72 c = IPC_GET_ARG2(*call); 76 77 if ( con->client_sess != NULL) {78 async_exch_t *exch = async_exchange_begin(con->client_sess);79 async_msg_1(exch, CHAR_NOTIF_BYTE, c); 80 async_exchange_end(exch);81 }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); 82 79 } 83 80 … … 87 84 ddf_fun_t *fun = NULL; 88 85 bool subscribed = false; 86 irq_cmd_t *msim_cmds = NULL; 89 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); 92 93 msim_cmds = malloc(sizeof(msim_cmds_proto)); 94 if (msim_cmds == NULL) { 95 rc = ENOMEM; 96 goto error; 97 } 90 98 91 99 con->res = *res; … … 98 106 } 99 107 108 rc = pio_enable((void *)res->base, 1, (void **) &con->out_reg); 109 if (rc != EOK) { 110 ddf_msg(LVL_ERROR, "Error enabling I/O"); 111 goto error; 112 } 113 100 114 ddf_fun_set_conn_handler(fun, msim_con_connection); 101 115 102 msim_ranges[0].base = res->base; 116 con->irq_range[0].base = res->base; 117 con->irq_range[0].size = 1; 118 119 memcpy(msim_cmds, msim_cmds_proto, sizeof(msim_cmds_proto)); 103 120 msim_cmds[0].addr = (void *) res->base; 104 async_irq_subscribe(res->irq, msim_irq_handler, con, &msim_kbd); 121 122 con->irq_code.rangecount = 1; 123 con->irq_code.ranges = con->irq_range; 124 con->irq_code.cmdcount = sizeof(msim_cmds_proto) / sizeof(irq_cmd_t); 125 con->irq_code.cmds = msim_cmds; 126 127 async_irq_subscribe(res->irq, msim_irq_handler, con, &con->irq_code, NULL); 105 128 subscribed = true; 129 130 chardev_srvs_init(&con->cds); 131 con->cds.ops = &msim_con_chardev_ops; 132 con->cds.sarg = con; 106 133 107 134 rc = ddf_fun_bind(fun); … … 110 137 goto error; 111 138 } 139 140 ddf_fun_add_to_category(fun, "console"); 112 141 113 142 return EOK; … … 117 146 if (fun != NULL) 118 147 ddf_fun_destroy(fun); 148 free(msim_cmds); 119 149 120 150 return rc; … … 135 165 static void msim_con_putchar(msim_con_t *con, uint8_t ch) 136 166 { 167 pio_write_8(con->out_reg, ch); 168 } 169 170 /** Read from msim console device */ 171 static int msim_con_read(chardev_srv_t *srv, void *buf, size_t size, 172 size_t *nread) 173 { 174 msim_con_t *con = (msim_con_t *) srv->srvs->sarg; 175 size_t p; 176 uint8_t *bp = (uint8_t *) buf; 177 int rc; 178 179 fibril_mutex_lock(&con->buf_lock); 180 181 while (circ_buf_nused(&con->cbuf) == 0) 182 fibril_condvar_wait(&con->buf_cv, &con->buf_lock); 183 184 p = 0; 185 while (p < size) { 186 rc = circ_buf_pop(&con->cbuf, &bp[p]); 187 if (rc != EOK) 188 break; 189 ++p; 190 } 191 192 fibril_mutex_unlock(&con->buf_lock); 193 194 *nread = p; 195 return EOK; 196 } 197 198 /** Write to msim console device */ 199 static int msim_con_write(chardev_srv_t *srv, const void *data, size_t size, 200 size_t *nwr) 201 { 202 msim_con_t *con = (msim_con_t *) srv->srvs->sarg; 203 size_t i; 204 uint8_t *dp = (uint8_t *) data; 205 206 for (i = 0; i < size; i++) 207 msim_con_putchar(con, dp[i]); 208 209 *nwr = size; 210 return EOK; 137 211 } 138 212 … … 141 215 void *arg) 142 216 { 143 msim_con_t *con; 144 145 /* Answer the IPC_M_CONNECT_ME_TO call. */ 146 async_answer_0(iid, EOK); 147 148 con = (msim_con_t *)ddf_dev_data_get(ddf_fun_get_dev((ddf_fun_t *)arg)); 149 150 while (true) { 151 ipc_call_t call; 152 ipc_callid_t callid = async_get_call(&call); 153 sysarg_t method = IPC_GET_IMETHOD(call); 154 155 if (!method) { 156 /* The other side has hung up. */ 157 async_answer_0(callid, EOK); 158 return; 159 } 160 161 async_sess_t *sess = 162 async_callback_receive_start(EXCHANGE_SERIALIZE, &call); 163 if (sess != NULL) { 164 if (con->client_sess == NULL) { 165 con->client_sess = sess; 166 async_answer_0(callid, EOK); 167 } else 168 async_answer_0(callid, ELIMIT); 169 } else { 170 switch (method) { 171 case CHAR_WRITE_BYTE: 172 ddf_msg(LVL_DEBUG, "Write %" PRIun " to device\n", 173 IPC_GET_ARG1(call)); 174 msim_con_putchar(con, (uint8_t) IPC_GET_ARG1(call)); 175 async_answer_0(callid, EOK); 176 break; 177 default: 178 async_answer_0(callid, EINVAL); 179 } 180 } 181 } 217 msim_con_t *con = (msim_con_t *) ddf_dev_data_get( 218 ddf_fun_get_dev((ddf_fun_t *) arg)); 219 220 chardev_conn(iid, icall, &con->cds); 182 221 } 183 222
Note:
See TracChangeset
for help on using the changeset viewer.