Changeset 132ab5d1 in mainline for uspace/drv/char/i8042/i8042.c
- Timestamp:
- 2018-01-30T03:20:45Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 5a6cc679
- Parents:
- 8bfb163 (diff), 6a5d05b (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
-
uspace/drv/char/i8042/i8042.c (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/char/i8042/i8042.c
r8bfb163 r132ab5d1 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> … … 67 68 68 69 static void i8042_char_conn(ipc_callid_t, ipc_call_t *, void *); 69 static int i8042_read(chardev_srv_t *, void *, size_t );70 static int i8042_write(chardev_srv_t *, const void *, size_t );70 static int i8042_read(chardev_srv_t *, void *, size_t, size_t *); 71 static int i8042_write(chardev_srv_t *, const void *, size_t, size_t *); 71 72 72 73 static chardev_ops_t i8042_chardev_ops = { … … 121 122 * Write new data to the corresponding buffer. 122 123 * 123 * @param iid Call id.124 124 * @param call pointerr to call data. 125 125 * @param dev Device that caued the interrupt. 126 126 * 127 127 */ 128 static void i8042_irq_handler(ipc_callid_t iid, ipc_call_t *call, 129 ddf_dev_t *dev) 128 static void i8042_irq_handler(ipc_call_t *call, ddf_dev_t *dev) 130 129 { 131 130 i8042_t *controller = ddf_dev_data_get(dev); 131 int rc; 132 132 133 133 const uint8_t status = IPC_GET_ARG1(*call); 134 134 const uint8_t data = IPC_GET_ARG2(*call); 135 135 136 buffer_t *buffer = (status & i8042_AUX_DATA) ? 137 &controller->aux_buffer : &controller->kbd_buffer; 138 139 buffer_write(buffer, data); 136 i8042_port_t *port = (status & i8042_AUX_DATA) ? 137 controller->aux : controller->kbd; 138 139 fibril_mutex_lock(&port->buf_lock); 140 141 rc = circ_buf_push(&port->cbuf, &data); 142 if (rc != EOK) 143 ddf_msg(LVL_ERROR, "Buffer overrun"); 144 145 fibril_mutex_unlock(&port->buf_lock); 146 fibril_condvar_broadcast(&port->buf_cv); 140 147 } 141 148 … … 159 166 const size_t cmd_count = sizeof(i8042_cmds) / sizeof(irq_cmd_t); 160 167 irq_cmd_t cmds[cmd_count]; 168 ddf_fun_t *kbd_fun; 169 ddf_fun_t *aux_fun; 161 170 i8042_regs_t *ar; 162 171 163 172 int rc; 164 173 bool kbd_bound = false; 165 174 bool aux_bound = false; 166 167 dev->kbd_fun = NULL;168 dev->aux_fun = NULL;169 175 170 176 if (regs->size < sizeof(i8042_regs_t)) { … … 178 184 } 179 185 180 dev->kbd_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2a");181 if ( dev->kbd_fun == NULL) {186 kbd_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2a"); 187 if (kbd_fun == NULL) { 182 188 rc = ENOMEM; 183 189 goto error; 184 190 }; 185 191 186 dev->kbd = ddf_fun_data_alloc( dev->kbd_fun, sizeof(i8042_port_t));192 dev->kbd = ddf_fun_data_alloc(kbd_fun, sizeof(i8042_port_t)); 187 193 if (dev->kbd == NULL) { 188 194 rc = ENOMEM; … … 190 196 } 191 197 198 dev->kbd->fun = kbd_fun; 192 199 dev->kbd->ctl = dev; 193 200 chardev_srvs_init(&dev->kbd->cds); 194 201 dev->kbd->cds.ops = &i8042_chardev_ops; 195 202 dev->kbd->cds.sarg = dev->kbd; 196 197 rc = ddf_fun_add_match_id(dev->kbd_fun, "char/xtkbd", 90); 203 fibril_mutex_initialize(&dev->kbd->buf_lock); 204 fibril_condvar_initialize(&dev->kbd->buf_cv); 205 206 rc = ddf_fun_add_match_id(dev->kbd->fun, "char/xtkbd", 90); 198 207 if (rc != EOK) 199 208 goto error; 200 209 201 dev->aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b");202 if ( dev->aux_fun == NULL) {210 aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b"); 211 if (aux_fun == NULL) { 203 212 rc = ENOMEM; 204 213 goto error; 205 214 } 206 215 207 dev->aux = ddf_fun_data_alloc( dev->aux_fun, sizeof(i8042_port_t));216 dev->aux = ddf_fun_data_alloc(aux_fun, sizeof(i8042_port_t)); 208 217 if (dev->aux == NULL) { 209 218 rc = ENOMEM; … … 211 220 } 212 221 222 dev->aux->fun = aux_fun; 213 223 dev->aux->ctl = dev; 214 224 chardev_srvs_init(&dev->aux->cds); 215 225 dev->aux->cds.ops = &i8042_chardev_ops; 216 226 dev->aux->cds.sarg = dev->aux; 217 218 rc = ddf_fun_add_match_id(dev->aux_fun, "char/ps2mouse", 90); 227 fibril_mutex_initialize(&dev->aux->buf_lock); 228 fibril_condvar_initialize(&dev->aux->buf_cv); 229 230 rc = ddf_fun_add_match_id(dev->aux->fun, "char/ps2mouse", 90); 219 231 if (rc != EOK) 220 232 goto error; 221 233 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);234 ddf_fun_set_conn_handler(dev->kbd->fun, i8042_char_conn); 235 ddf_fun_set_conn_handler(dev->aux->fun, i8042_char_conn); 236 237 circ_buf_init(&dev->kbd->cbuf, dev->kbd->buf_data, BUFFER_SIZE, 1); 238 circ_buf_init(&dev->aux->cbuf, dev->aux->buf_data, BUFFER_SIZE, 1); 227 239 fibril_mutex_initialize(&dev->write_guard); 228 240 229 rc = ddf_fun_bind(dev->kbd _fun);241 rc = ddf_fun_bind(dev->kbd->fun); 230 242 if (rc != EOK) { 231 243 ddf_msg(LVL_ERROR, "Failed to bind keyboard function: %s.", 232 ddf_fun_get_name(dev->kbd _fun));244 ddf_fun_get_name(dev->kbd->fun)); 233 245 goto error; 234 246 } 235 247 kbd_bound = true; 236 248 237 rc = ddf_fun_bind(dev->aux _fun);249 rc = ddf_fun_bind(dev->aux->fun); 238 250 if (rc != EOK) { 239 251 ddf_msg(LVL_ERROR, "Failed to bind aux function: %s.", 240 ddf_fun_get_name(dev->aux _fun));252 ddf_fun_get_name(dev->aux->fun)); 241 253 goto error; 242 254 } … … 269 281 }; 270 282 271 const int irq_kbd_cap = register_interrupt_handler(ddf_dev, irq_kbd,272 i8042_irq_handler, &irq_code);273 if (irq_kbd_cap < 0) {274 rc = irq_kbd_cap;283 int irq_kbd_cap; 284 rc = register_interrupt_handler(ddf_dev, irq_kbd, 285 i8042_irq_handler, &irq_code, &irq_kbd_cap); 286 if (rc != EOK) { 275 287 ddf_msg(LVL_ERROR, "Failed set handler for kbd: %s.", 276 288 ddf_dev_get_name(ddf_dev)); … … 278 290 } 279 291 280 const int irq_mouse_cap = register_interrupt_handler(ddf_dev, irq_mouse,281 i8042_irq_handler, &irq_code);282 if (irq_mouse_cap < 0) {283 rc = irq_mouse_cap;292 int irq_mouse_cap; 293 rc = register_interrupt_handler(ddf_dev, irq_mouse, 294 i8042_irq_handler, &irq_code, &irq_mouse_cap); 295 if (rc != EOK) { 284 296 ddf_msg(LVL_ERROR, "Failed set handler for mouse: %s.", 285 297 ddf_dev_get_name(ddf_dev)); … … 317 329 error: 318 330 if (kbd_bound) 319 ddf_fun_unbind(dev->kbd _fun);331 ddf_fun_unbind(dev->kbd->fun); 320 332 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);333 ddf_fun_unbind(dev->aux->fun); 334 if (dev->kbd->fun != NULL) 335 ddf_fun_destroy(dev->kbd->fun); 336 if (dev->aux->fun != NULL) 337 ddf_fun_destroy(dev->aux->fun); 326 338 327 339 return rc; … … 333 345 * @param buffer Data source 334 346 * @param size Data size 335 * 336 * @return Bytes written. 337 * 338 */ 339 static int i8042_write(chardev_srv_t *srv, const void *data, size_t size) 347 * @param nwr Place to store number of bytes successfully written 348 * 349 * @return EOK on success or non-zero error code 350 * 351 */ 352 static int i8042_write(chardev_srv_t *srv, const void *data, size_t size, 353 size_t *nwr) 340 354 { 341 355 i8042_port_t *port = (i8042_port_t *)srv->srvs->sarg; … … 357 371 358 372 fibril_mutex_unlock(&i8042->write_guard); 359 return size; 373 *nwr = size; 374 return EOK; 360 375 } 361 376 … … 365 380 * @param buffer Data place 366 381 * @param size Data place size 367 * 368 * @return Bytes read. 369 * 370 */ 371 static int i8042_read(chardev_srv_t *srv, void *dest, size_t size) 382 * @param nread Place to store number of bytes successfully read 383 * 384 * @return EOK on success or non-zero error code 385 * 386 */ 387 static int i8042_read(chardev_srv_t *srv, void *dest, size_t size, 388 size_t *nread) 372 389 { 373 390 i8042_port_t *port = (i8042_port_t *)srv->srvs->sarg; 374 i8042_t *i8042 = port->ctl;391 size_t p; 375 392 uint8_t *destp = (uint8_t *)dest; 376 377 buffer_t *buffer = (port == i8042->aux) ? 378 &i8042->aux_buffer : &i8042->kbd_buffer; 379 380 for (size_t i = 0; i < size; ++i) 381 *destp++ = buffer_read(buffer); 382 383 return size; 393 int rc; 394 395 fibril_mutex_lock(&port->buf_lock); 396 397 while (circ_buf_nused(&port->cbuf) == 0) 398 fibril_condvar_wait(&port->buf_cv, &port->buf_lock); 399 400 p = 0; 401 while (p < size) { 402 rc = circ_buf_pop(&port->cbuf, &destp[p]); 403 if (rc != EOK) 404 break; 405 ++p; 406 } 407 408 fibril_mutex_unlock(&port->buf_lock); 409 410 *nread = p; 411 return EOK; 384 412 } 385 413
Note:
See TracChangeset
for help on using the changeset viewer.
