Changes in uspace/drv/char/msim-con/msim-con.c [071a1ddb:7de5f12] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/char/msim-con/msim-con.c
r071a1ddb r7de5f12 37 37 #include <ddi.h> 38 38 #include <errno.h> 39 #include <i o/chardev_srv.h>39 #include <ipc/char.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 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 45 static irq_pio_range_t msim_ranges[] = { 46 { 47 .base = 0, 48 .size = 1 49 } 51 50 }; 52 51 53 static irq_cmd_t msim_cmds _proto[] = {52 static irq_cmd_t msim_cmds[] = { 54 53 { 55 54 .cmd = CMD_PIO_READ_8, … … 62 61 }; 63 62 64 static void msim_irq_handler(ipc_call_t *call, void *arg) 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) 65 71 { 66 72 msim_con_t *con = (msim_con_t *) arg; 67 73 uint8_t c; 68 int rc;69 70 fibril_mutex_lock(&con->buf_lock);71 74 72 75 c = IPC_GET_ARG2(*call); 73 rc = circ_buf_push(&con->cbuf, &c);74 if (rc != EOK)75 ddf_msg(LVL_ERROR, "Buffer overrun");76 76 77 fibril_mutex_unlock(&con->buf_lock); 78 fibril_condvar_broadcast(&con->buf_cv); 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 } 79 82 } 80 83 … … 84 87 ddf_fun_t *fun = NULL; 85 88 bool subscribed = false; 86 irq_cmd_t *msim_cmds = NULL;87 89 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 }98 90 99 91 con->res = *res; … … 106 98 } 107 99 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 114 100 ddf_fun_set_conn_handler(fun, msim_con_connection); 115 101 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)); 102 msim_ranges[0].base = res->base; 120 103 msim_cmds[0].addr = (void *) res->base; 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); 104 async_irq_subscribe(res->irq, msim_irq_handler, con, &msim_kbd); 128 105 subscribed = true; 129 130 chardev_srvs_init(&con->cds);131 con->cds.ops = &msim_con_chardev_ops;132 con->cds.sarg = con;133 106 134 107 rc = ddf_fun_bind(fun); … … 138 111 } 139 112 140 ddf_fun_add_to_category(fun, "console");141 142 113 return EOK; 143 114 error: … … 146 117 if (fun != NULL) 147 118 ddf_fun_destroy(fun); 148 free(msim_cmds);149 119 150 120 return rc; … … 165 135 static void msim_con_putchar(msim_con_t *con, uint8_t ch) 166 136 { 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;211 137 } 212 138 … … 215 141 void *arg) 216 142 { 217 msim_con_t *con = (msim_con_t *) ddf_dev_data_get( 218 ddf_fun_get_dev((ddf_fun_t *) arg)); 143 msim_con_t *con; 219 144 220 chardev_conn(iid, icall, &con->cds); 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 } 221 182 } 222 183
Note:
See TracChangeset
for help on using the changeset viewer.