Changeset 7eaeec1 in mainline for uspace/drv/char/i8042/i8042.c
- Timestamp:
- 2012-08-20T21:27:38Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6a97f2e
- Parents:
- f3a37e28 (diff), dd13349 (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
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/char/i8042/i8042.c
rf3a37e28 r7eaeec1 39 39 */ 40 40 41 #include <devman.h>42 41 #include <device/hw_res.h> 43 42 #include <ddi.h> … … 140 139 }; 141 140 141 /** Get i8042 soft state from device node. */ 142 static i8042_t *dev_i8042(ddf_dev_t *dev) 143 { 144 return ddf_dev_data_get(dev); 145 } 146 142 147 /** Wait until it is safe to write to the device. */ 143 148 static void wait_ready(i8042_t *dev) … … 159 164 ipc_call_t *call) 160 165 { 161 if ((!dev) || (!dev->driver_data)) 162 return; 163 164 i8042_t *controller = dev->driver_data; 166 i8042_t *controller = dev_i8042(dev); 165 167 166 168 const uint8_t status = IPC_GET_ARG1(*call); … … 188 190 int irq_mouse, ddf_dev_t *ddf_dev) 189 191 { 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; 192 const size_t range_count = sizeof(i8042_ranges) / 193 sizeof(irq_pio_range_t); 194 irq_pio_range_t ranges[range_count]; 195 const size_t cmd_count = sizeof(i8042_cmds) / sizeof(irq_cmd_t); 196 irq_cmd_t cmds[cmd_count]; 197 198 int rc; 199 bool kbd_bound = false; 200 bool aux_bound = false; 201 202 dev->kbd_fun = NULL; 203 dev->aux_fun = NULL; 204 205 if (reg_size < sizeof(i8042_regs_t)) { 206 rc = EINVAL; 207 goto error; 208 } 209 210 if (pio_enable(regs, sizeof(i8042_regs_t), (void **) &dev->regs) != 0) { 211 rc = EIO; 212 goto error; 213 } 198 214 199 215 dev->kbd_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2a"); 200 if ( !dev->kbd_fun)201 r eturnENOMEM;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 }216 if (dev->kbd_fun == NULL) { 217 rc = ENOMEM; 218 goto error; 219 }; 220 221 rc = ddf_fun_add_match_id(dev->kbd_fun, "char/xtkbd", 90); 222 if (rc != EOK) 223 goto error; 208 224 209 225 dev->aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b"); 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; 226 if (dev->aux_fun == NULL) { 227 rc = ENOMEM; 228 goto error; 229 } 230 231 rc = ddf_fun_add_match_id(dev->aux_fun, "char/ps2mouse", 90); 232 if (rc != EOK) 233 goto error; 234 235 ddf_fun_set_ops(dev->kbd_fun, &ops); 236 ddf_fun_set_ops(dev->aux_fun, &ops); 226 237 227 238 buffer_init(&dev->kbd_buffer, dev->kbd_data, BUFFER_SIZE); … … 229 240 fibril_mutex_initialize(&dev->write_guard); 230 241 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)); 242 rc = ddf_fun_bind(dev->kbd_fun); 243 if (rc != EOK) { 244 ddf_msg(LVL_ERROR, "Failed to bind keyboard function: %s.", 245 ddf_fun_get_name(dev->kbd_fun)); 246 goto error; 247 } 248 kbd_bound = true; 249 250 rc = ddf_fun_bind(dev->aux_fun); 251 if (rc != EOK) { 252 ddf_msg(LVL_ERROR, "Failed to bind aux function: %s.", 253 ddf_fun_get_name(dev->aux_fun)); 254 goto error; 255 } 256 aux_bound = true; 238 257 239 258 /* Disable kbd and aux */ … … 247 266 (void) pio_read_8(&dev->regs->data); 248 267 249 const size_t range_count = sizeof(i8042_ranges) /250 sizeof(irq_pio_range_t);251 irq_pio_range_t ranges[range_count];252 268 memcpy(ranges, i8042_ranges, sizeof(i8042_ranges)); 253 269 ranges[0].base = (uintptr_t) regs; 254 270 255 const size_t cmd_count = sizeof(i8042_cmds) / sizeof(irq_cmd_t);256 irq_cmd_t cmds[cmd_count];257 271 memcpy(cmds, i8042_cmds, sizeof(i8042_cmds)); 258 272 cmds[0].addr = (void *) &(((i8042_regs_t *) regs)->status); … … 266 280 }; 267 281 268 r et= register_interrupt_handler(ddf_dev, irq_kbd, i8042_irq_handler,282 rc = register_interrupt_handler(ddf_dev, irq_kbd, i8042_irq_handler, 269 283 &irq_code); 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, 284 if (rc != EOK) { 285 ddf_msg(LVL_ERROR, "Failed set handler for kbd: %s.", 286 ddf_dev_get_name(ddf_dev)); 287 goto error; 288 } 289 290 rc = register_interrupt_handler(ddf_dev, irq_mouse, i8042_irq_handler, 274 291 &irq_code); 275 CHECK_RET_UNBIND_DESTROY(ret, "Failed set handler for mouse: %s.", 276 str_error(ret)); 292 if (rc != EOK) { 293 ddf_msg(LVL_ERROR, "Failed set handler for mouse: %s.", 294 ddf_dev_get_name(ddf_dev)); 295 goto error; 296 } 277 297 278 298 /* Enable interrupts */ 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."); 299 async_sess_t *parent_sess = ddf_dev_parent_sess_get(ddf_dev); 300 assert(parent_sess != NULL); 284 301 285 302 const bool enabled = hw_res_enable_interrupt(parent_sess); 286 async_hangup(parent_sess); 287 ret = enabled ? EOK : EIO; 288 CHECK_RET_UNBIND_DESTROY(ret, "Failed to enable interrupts: %s."); 303 if (!enabled) { 304 log_msg(LVL_ERROR, "Failed to enable interrupts: %s.", 305 ddf_dev_get_name(ddf_dev)); 306 rc = EIO; 307 goto error; 308 } 289 309 290 310 /* Enable port interrupts. */ … … 296 316 297 317 return EOK; 318 error: 319 if (kbd_bound) 320 ddf_fun_unbind(dev->kbd_fun); 321 if (aux_bound) 322 ddf_fun_unbind(dev->aux_fun); 323 if (dev->kbd_fun != NULL) 324 ddf_fun_destroy(dev->kbd_fun); 325 if (dev->aux_fun != NULL) 326 ddf_fun_destroy(dev->aux_fun); 327 328 return rc; 298 329 } 299 330 … … 315 346 static int i8042_write(ddf_fun_t *fun, char *buffer, size_t size) 316 347 { 317 assert(fun); 318 assert(fun->driver_data); 319 320 i8042_t *controller = fun->driver_data; 348 i8042_t *controller = dev_i8042(ddf_fun_get_dev(fun)); 321 349 fibril_mutex_lock(&controller->write_guard); 322 350 … … 347 375 static int i8042_read(ddf_fun_t *fun, char *data, size_t size) 348 376 { 349 assert(fun); 350 assert(fun->driver_data); 351 352 i8042_t *controller = fun->driver_data; 377 i8042_t *controller = dev_i8042(ddf_fun_get_dev(fun)); 353 378 buffer_t *buffer = (fun == controller->aux_fun) ? 354 379 &controller->aux_buffer : &controller->kbd_buffer;
Note:
See TracChangeset
for help on using the changeset viewer.