Changes in uspace/drv/char/i8042/i8042.c [071a1ddb:cccd60c3] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/char/i8042/i8042.c
r071a1ddb rcccd60c3 2 2 * Copyright (c) 2001-2004 Jakub Jermar 3 3 * Copyright (c) 2006 Josef Cejka 4 * Copyright (c) 201 7Jiri Svoboda4 * Copyright (c) 2014 Jiri Svoboda 5 5 * Copyright (c) 2011 Jan Vesely 6 6 * All rights reserved. … … 39 39 */ 40 40 41 #include <adt/circ_buf.h>42 41 #include <ddf/log.h> 43 42 #include <ddf/interrupt.h> … … 68 67 69 68 static void i8042_char_conn(ipc_callid_t, ipc_call_t *, void *); 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 *);69 static int i8042_read(chardev_srv_t *, void *, size_t); 70 static int i8042_write(chardev_srv_t *, const void *, size_t); 72 71 73 72 static chardev_ops_t i8042_chardev_ops = { … … 122 121 * Write new data to the corresponding buffer. 123 122 * 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_call_t *call, ddf_dev_t *dev) 128 static void i8042_irq_handler(ipc_callid_t iid, ipc_call_t *call, 129 ddf_dev_t *dev) 129 130 { 130 131 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 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); 136 buffer_t *buffer = (status & i8042_AUX_DATA) ? 137 &controller->aux_buffer : &controller->kbd_buffer; 138 139 buffer_write(buffer, data); 147 140 } 148 141 … … 166 159 const size_t cmd_count = sizeof(i8042_cmds) / sizeof(irq_cmd_t); 167 160 irq_cmd_t cmds[cmd_count]; 168 ddf_fun_t *kbd_fun;169 ddf_fun_t *aux_fun;170 161 i8042_regs_t *ar; 171 162 172 163 int rc; 173 164 bool kbd_bound = false; 174 165 bool aux_bound = false; 166 167 dev->kbd_fun = NULL; 168 dev->aux_fun = NULL; 175 169 176 170 if (regs->size < sizeof(i8042_regs_t)) { … … 184 178 } 185 179 186 kbd_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2a");187 if ( kbd_fun == NULL) {180 dev->kbd_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2a"); 181 if (dev->kbd_fun == NULL) { 188 182 rc = ENOMEM; 189 183 goto error; 190 184 }; 191 185 192 dev->kbd = ddf_fun_data_alloc( kbd_fun, sizeof(i8042_port_t));186 dev->kbd = ddf_fun_data_alloc(dev->kbd_fun, sizeof(i8042_port_t)); 193 187 if (dev->kbd == NULL) { 194 188 rc = ENOMEM; … … 196 190 } 197 191 198 dev->kbd->fun = kbd_fun;199 192 dev->kbd->ctl = dev; 200 193 chardev_srvs_init(&dev->kbd->cds); 201 194 dev->kbd->cds.ops = &i8042_chardev_ops; 202 195 dev->kbd->cds.sarg = dev->kbd; 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); 196 197 rc = ddf_fun_add_match_id(dev->kbd_fun, "char/xtkbd", 90); 207 198 if (rc != EOK) 208 199 goto error; 209 200 210 aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b");211 if ( aux_fun == NULL) {201 dev->aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b"); 202 if (dev->aux_fun == NULL) { 212 203 rc = ENOMEM; 213 204 goto error; 214 205 } 215 206 216 dev->aux = ddf_fun_data_alloc( aux_fun, sizeof(i8042_port_t));207 dev->aux = ddf_fun_data_alloc(dev->aux_fun, sizeof(i8042_port_t)); 217 208 if (dev->aux == NULL) { 218 209 rc = ENOMEM; … … 220 211 } 221 212 222 dev->aux->fun = aux_fun;223 213 dev->aux->ctl = dev; 224 214 chardev_srvs_init(&dev->aux->cds); 225 215 dev->aux->cds.ops = &i8042_chardev_ops; 226 216 dev->aux->cds.sarg = dev->aux; 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); 217 218 rc = ddf_fun_add_match_id(dev->aux_fun, "char/ps2mouse", 90); 231 219 if (rc != EOK) 232 220 goto error; 233 221 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);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); 239 227 fibril_mutex_initialize(&dev->write_guard); 240 228 241 rc = ddf_fun_bind(dev->kbd ->fun);229 rc = ddf_fun_bind(dev->kbd_fun); 242 230 if (rc != EOK) { 243 231 ddf_msg(LVL_ERROR, "Failed to bind keyboard function: %s.", 244 ddf_fun_get_name(dev->kbd ->fun));232 ddf_fun_get_name(dev->kbd_fun)); 245 233 goto error; 246 234 } 247 235 kbd_bound = true; 248 236 249 rc = ddf_fun_bind(dev->aux ->fun);237 rc = ddf_fun_bind(dev->aux_fun); 250 238 if (rc != EOK) { 251 239 ddf_msg(LVL_ERROR, "Failed to bind aux function: %s.", 252 ddf_fun_get_name(dev->aux ->fun));240 ddf_fun_get_name(dev->aux_fun)); 253 241 goto error; 254 242 } … … 281 269 }; 282 270 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) {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; 287 275 ddf_msg(LVL_ERROR, "Failed set handler for kbd: %s.", 288 276 ddf_dev_get_name(ddf_dev)); … … 290 278 } 291 279 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) {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; 296 284 ddf_msg(LVL_ERROR, "Failed set handler for mouse: %s.", 297 285 ddf_dev_get_name(ddf_dev)); … … 329 317 error: 330 318 if (kbd_bound) 331 ddf_fun_unbind(dev->kbd ->fun);319 ddf_fun_unbind(dev->kbd_fun); 332 320 if (aux_bound) 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);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); 338 326 339 327 return rc; … … 345 333 * @param buffer Data source 346 334 * @param size Data 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) 335 * 336 * @return Bytes written. 337 * 338 */ 339 static int i8042_write(chardev_srv_t *srv, const void *data, size_t size) 354 340 { 355 341 i8042_port_t *port = (i8042_port_t *)srv->srvs->sarg; … … 371 357 372 358 fibril_mutex_unlock(&i8042->write_guard); 373 *nwr = size; 374 return EOK; 359 return size; 375 360 } 376 361 … … 380 365 * @param buffer Data place 381 366 * @param size Data place 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) 367 * 368 * @return Bytes read. 369 * 370 */ 371 static int i8042_read(chardev_srv_t *srv, void *dest, size_t size) 389 372 { 390 373 i8042_port_t *port = (i8042_port_t *)srv->srvs->sarg; 391 size_t p;374 i8042_t *i8042 = port->ctl; 392 375 uint8_t *destp = (uint8_t *)dest; 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; 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; 412 384 } 413 385
Note:
See TracChangeset
for help on using the changeset viewer.