Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/char/i8042/i8042.c

    r56fd7cf r8486c07  
    3939 */
    4040
     41#include <devman.h>
    4142#include <device/hw_res.h>
    4243#include <ddi.h>
     
    139140};
    140141
    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 
    147142/** Wait until it is safe to write to the device. */
    148143static void wait_ready(i8042_t *dev)
     
    164159    ipc_call_t *call)
    165160{
    166         i8042_t *controller = dev_i8042(dev);
     161        if ((!dev) || (!dev->driver_data))
     162                return;
     163       
     164        i8042_t *controller = dev->driver_data;
    167165       
    168166        const uint8_t status = IPC_GET_ARG1(*call);
     
    190188    int irq_mouse, ddf_dev_t *ddf_dev)
    191189{
    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         }
     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;
    214198       
    215199        dev->kbd_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2a");
    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;
     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        }
    224208       
    225209        dev->aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b");
    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);
     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;
    237226       
    238227        buffer_init(&dev->kbd_buffer, dev->kbd_data, BUFFER_SIZE);
     
    240229        fibril_mutex_initialize(&dev->write_guard);
    241230       
    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;
     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));
    257238       
    258239        /* Disable kbd and aux */
     
    266247                (void) pio_read_8(&dev->regs->data);
    267248
     249        const size_t range_count = sizeof(i8042_ranges) /
     250            sizeof(irq_pio_range_t);
     251        irq_pio_range_t ranges[range_count];
    268252        memcpy(ranges, i8042_ranges, sizeof(i8042_ranges));
    269253        ranges[0].base = (uintptr_t) regs;
    270254
     255        const size_t cmd_count = sizeof(i8042_cmds) / sizeof(irq_cmd_t);
     256        irq_cmd_t cmds[cmd_count];
    271257        memcpy(cmds, i8042_cmds, sizeof(i8042_cmds));
    272258        cmds[0].addr = (void *) &(((i8042_regs_t *) regs)->status);
     
    280266        };
    281267       
    282         rc = register_interrupt_handler(ddf_dev, irq_kbd, i8042_irq_handler,
     268        ret = register_interrupt_handler(ddf_dev, irq_kbd, i8042_irq_handler,
    283269            &irq_code);
    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,
     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,
    291274            &irq_code);
    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         }
     275        CHECK_RET_UNBIND_DESTROY(ret, "Failed set handler for mouse: %s.",
     276            str_error(ret));
    297277       
    298278        /* Enable interrupts */
    299         async_sess_t *parent_sess = ddf_dev_parent_sess_get(ddf_dev);
    300         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.");
    301284       
    302285        const bool enabled = hw_res_enable_interrupt(parent_sess);
    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         }
     286        async_hangup(parent_sess);
     287        ret = enabled ? EOK : EIO;
     288        CHECK_RET_UNBIND_DESTROY(ret, "Failed to enable interrupts: %s.");
    309289       
    310290        /* Enable port interrupts. */
     
    316296       
    317297        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;
    329298}
    330299
     
    346315static int i8042_write(ddf_fun_t *fun, char *buffer, size_t size)
    347316{
    348         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;
    349321        fibril_mutex_lock(&controller->write_guard);
    350322       
     
    375347static int i8042_read(ddf_fun_t *fun, char *data, size_t size)
    376348{
    377         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;
    378353        buffer_t *buffer = (fun == controller->aux_fun) ?
    379354            &controller->aux_buffer : &controller->kbd_buffer;
Note: See TracChangeset for help on using the changeset viewer.