Changes in uspace/drv/char/i8042/i8042.c [1ae74c6:9d58539] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/char/i8042/i8042.c
r1ae74c6 r9d58539 39 39 */ 40 40 41 #include <devman.h> 41 42 #include <device/hw_res.h> 42 43 #include <ddi.h> 44 #include <libarch/ddi.h> 43 45 #include <errno.h> 44 46 #include <str_error.h> … … 118 120 }, 119 121 { 120 .cmd = CMD_ AND,122 .cmd = CMD_BTEST, 121 123 .value = i8042_OUTPUT_FULL, 122 124 .srcarg = 1, … … 138 140 }; 139 141 140 /** Get i8042 soft state from device node. */141 static i8042_t *dev_i8042(ddf_dev_t *dev)142 {143 return ddf_dev_data_get(dev);144 }145 146 142 /** Wait until it is safe to write to the device. */ 147 143 static void wait_ready(i8042_t *dev) … … 163 159 ipc_call_t *call) 164 160 { 165 i8042_t *controller = dev_i8042(dev); 161 if ((!dev) || (!dev->driver_data)) 162 return; 163 164 i8042_t *controller = dev->driver_data; 166 165 167 166 const uint8_t status = IPC_GET_ARG1(*call); … … 189 188 int irq_mouse, ddf_dev_t *ddf_dev) 190 189 { 191 const size_t range_count = sizeof(i8042_ranges) / 192 sizeof(irq_pio_range_t); 193 irq_pio_range_t ranges[range_count]; 194 const size_t cmd_count = sizeof(i8042_cmds) / sizeof(irq_cmd_t); 195 irq_cmd_t cmds[cmd_count]; 196 197 int rc; 198 bool kbd_bound = false; 199 bool aux_bound = false; 200 201 dev->kbd_fun = NULL; 202 dev->aux_fun = NULL; 203 204 if (reg_size < sizeof(i8042_regs_t)) { 205 rc = EINVAL; 206 goto error; 207 } 208 209 if (pio_enable(regs, sizeof(i8042_regs_t), (void **) &dev->regs) != 0) { 210 rc = EIO; 211 goto error; 212 } 190 assert(ddf_dev); 191 assert(dev); 192 193 if (reg_size < sizeof(i8042_regs_t)) 194 return EINVAL; 195 196 if (pio_enable(regs, sizeof(i8042_regs_t), (void **) &dev->regs) != 0) 197 return -1; 213 198 214 199 dev->kbd_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2a"); 215 if ( dev->kbd_fun == NULL) {216 r c =ENOMEM;217 goto error;218 };219 220 rc = ddf_fun_add_match_id(dev->kbd_fun, "char/xtkbd", 90);221 if (rc != EOK)222 goto error;200 if (!dev->kbd_fun) 201 return ENOMEM; 202 203 int ret = ddf_fun_add_match_id(dev->kbd_fun, "char/xtkbd", 90); 204 if (ret != EOK) { 205 ddf_fun_destroy(dev->kbd_fun); 206 return ret; 207 } 223 208 224 209 dev->aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b"); 225 if (dev->aux_fun == NULL) { 226 rc = ENOMEM; 227 goto error; 228 } 229 230 rc = ddf_fun_add_match_id(dev->aux_fun, "char/ps2mouse", 90); 231 if (rc != EOK) 232 goto error; 233 234 ddf_fun_set_ops(dev->kbd_fun, &ops); 235 ddf_fun_set_ops(dev->aux_fun, &ops); 210 if (!dev->aux_fun) { 211 ddf_fun_destroy(dev->kbd_fun); 212 return ENOMEM; 213 } 214 215 ret = ddf_fun_add_match_id(dev->aux_fun, "char/ps2mouse", 90); 216 if (ret != EOK) { 217 ddf_fun_destroy(dev->kbd_fun); 218 ddf_fun_destroy(dev->aux_fun); 219 return ret; 220 } 221 222 dev->kbd_fun->ops = &ops; 223 dev->aux_fun->ops = &ops; 224 dev->kbd_fun->driver_data = dev; 225 dev->aux_fun->driver_data = dev; 236 226 237 227 buffer_init(&dev->kbd_buffer, dev->kbd_data, BUFFER_SIZE); … … 239 229 fibril_mutex_initialize(&dev->write_guard); 240 230 241 rc = ddf_fun_bind(dev->kbd_fun); 242 if (rc != EOK) { 243 ddf_msg(LVL_ERROR, "Failed to bind keyboard function: %s.", 244 ddf_fun_get_name(dev->kbd_fun)); 245 goto error; 246 } 247 kbd_bound = true; 248 249 rc = ddf_fun_bind(dev->aux_fun); 250 if (rc != EOK) { 251 ddf_msg(LVL_ERROR, "Failed to bind aux function: %s.", 252 ddf_fun_get_name(dev->aux_fun)); 253 goto error; 254 } 255 aux_bound = true; 231 ret = ddf_fun_bind(dev->kbd_fun); 232 CHECK_RET_DESTROY(ret, "Failed to bind keyboard function: %s.", 233 str_error(ret)); 234 235 ret = ddf_fun_bind(dev->aux_fun); 236 CHECK_RET_DESTROY(ret, "Failed to bind mouse function: %s.", 237 str_error(ret)); 256 238 257 239 /* Disable kbd and aux */ … … 265 247 (void) pio_read_8(&dev->regs->data); 266 248 249 const size_t range_count = sizeof(i8042_ranges) / 250 sizeof(irq_pio_range_t); 251 irq_pio_range_t ranges[range_count]; 267 252 memcpy(ranges, i8042_ranges, sizeof(i8042_ranges)); 268 253 ranges[0].base = (uintptr_t) regs; 269 254 255 const size_t cmd_count = sizeof(i8042_cmds) / sizeof(irq_cmd_t); 256 irq_cmd_t cmds[cmd_count]; 270 257 memcpy(cmds, i8042_cmds, sizeof(i8042_cmds)); 271 258 cmds[0].addr = (void *) &(((i8042_regs_t *) regs)->status); … … 279 266 }; 280 267 281 r c= register_interrupt_handler(ddf_dev, irq_kbd, i8042_irq_handler,268 ret = register_interrupt_handler(ddf_dev, irq_kbd, i8042_irq_handler, 282 269 &irq_code); 283 if (rc != EOK) { 284 ddf_msg(LVL_ERROR, "Failed set handler for kbd: %s.", 285 ddf_dev_get_name(ddf_dev)); 286 goto error; 287 } 288 289 rc = register_interrupt_handler(ddf_dev, irq_mouse, i8042_irq_handler, 270 CHECK_RET_UNBIND_DESTROY(ret, "Failed set handler for kbd: %s.", 271 str_error(ret)); 272 273 ret = register_interrupt_handler(ddf_dev, irq_mouse, i8042_irq_handler, 290 274 &irq_code); 291 if (rc != EOK) { 292 ddf_msg(LVL_ERROR, "Failed set handler for mouse: %s.", 293 ddf_dev_get_name(ddf_dev)); 294 goto error; 295 } 275 CHECK_RET_UNBIND_DESTROY(ret, "Failed set handler for mouse: %s.", 276 str_error(ret)); 296 277 297 278 /* Enable interrupts */ 298 async_sess_t *parent_sess = ddf_dev_parent_sess_get(ddf_dev); 299 assert(parent_sess != NULL); 279 async_sess_t *parent_sess = 280 devman_parent_device_connect(EXCHANGE_SERIALIZE, ddf_dev->handle, 281 IPC_FLAG_BLOCKING); 282 ret = parent_sess ? EOK : ENOMEM; 283 CHECK_RET_UNBIND_DESTROY(ret, "Failed to create parent connection."); 300 284 301 285 const bool enabled = hw_res_enable_interrupt(parent_sess); 302 if (!enabled) { 303 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to enable interrupts: %s.", 304 ddf_dev_get_name(ddf_dev)); 305 rc = EIO; 306 goto error; 307 } 286 async_hangup(parent_sess); 287 ret = enabled ? EOK : EIO; 288 CHECK_RET_UNBIND_DESTROY(ret, "Failed to enable interrupts: %s."); 308 289 309 290 /* Enable port interrupts. */ … … 315 296 316 297 return EOK; 317 error:318 if (kbd_bound)319 ddf_fun_unbind(dev->kbd_fun);320 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);326 327 return rc;328 298 } 329 299 … … 345 315 static int i8042_write(ddf_fun_t *fun, char *buffer, size_t size) 346 316 { 347 i8042_t *controller = dev_i8042(ddf_fun_get_dev(fun)); 317 assert(fun); 318 assert(fun->driver_data); 319 320 i8042_t *controller = fun->driver_data; 348 321 fibril_mutex_lock(&controller->write_guard); 349 322 … … 374 347 static int i8042_read(ddf_fun_t *fun, char *data, size_t size) 375 348 { 376 i8042_t *controller = dev_i8042(ddf_fun_get_dev(fun)); 349 assert(fun); 350 assert(fun->driver_data); 351 352 i8042_t *controller = fun->driver_data; 377 353 buffer_t *buffer = (fun == controller->aux_fun) ? 378 354 &controller->aux_buffer : &controller->kbd_buffer;
Note:
See TracChangeset
for help on using the changeset viewer.