/** * Connect to the parent's driver and get HW resources list in parsed format. * Note: this function should be called only from add_device handler, therefore * we don't need to use locks. * * @param nic_data * @param[out] resources Parsed lists of resources. * * @return EOK or negative error code */ int nic_get_resources(nic_t *nic_data, hw_res_list_parsed_t *resources) { ddf_dev_t *dev = nic_data->dev; async_sess_t *parent_sess; /* Connect to the parent's driver. */ parent_sess = ddf_dev_parent_sess_create(dev, EXCHANGE_SERIALIZE); if (parent_sess == NULL) return EPARTY; return hw_res_get_list_parsed(parent_sess, resources, 0); }
/** Initialize keyboard driver structure. * * @param kbd Keyboard driver structure to initialize. * @param dev DDF device structure. * * Connects to parent, creates keyboard function, starts polling fibril. * */ int at_kbd_init(at_kbd_t *kbd, ddf_dev_t *dev) { assert(kbd); assert(dev); kbd->client_sess = NULL; kbd->parent_sess = ddf_dev_parent_sess_create(dev); if (!kbd->parent_sess) { ddf_msg(LVL_ERROR, "Failed creating parent session."); return EIO; } kbd->kbd_fun = ddf_fun_create(dev, fun_exposed, "kbd"); if (!kbd->kbd_fun) { ddf_msg(LVL_ERROR, "Failed creating function 'kbd'."); return ENOMEM; } ddf_fun_set_ops(kbd->kbd_fun, &kbd_ops); int ret = ddf_fun_bind(kbd->kbd_fun); if (ret != EOK) { ddf_msg(LVL_ERROR, "Failed binding function 'kbd'."); ddf_fun_destroy(kbd->kbd_fun); return EEXIST; } ret = ddf_fun_add_to_category(kbd->kbd_fun, "keyboard"); if (ret != EOK) { ddf_msg(LVL_ERROR, "Failed adding function 'kbd' to category " "'keyboard'."); ddf_fun_unbind(kbd->kbd_fun); ddf_fun_destroy(kbd->kbd_fun); return ENOMEM; } kbd->polling_fibril = fibril_create(polling, kbd); if (!kbd->polling_fibril) { ddf_msg(LVL_ERROR, "Failed creating polling fibril."); ddf_fun_unbind(kbd->kbd_fun); ddf_fun_destroy(kbd->kbd_fun); return ENOMEM; } fibril_add_ready(kbd->polling_fibril); return EOK; }
/** Get address of I/O registers. * * @param[in] dev Device asking for the addresses. * @param[out] io_reg_address Base address of the memory range. * @param[out] io_reg_size Size of the memory range. * @param[out] kbd_irq Primary port IRQ. * @param[out] mouse_irq Auxiliary port IRQ. * * @return Error code. * */ static int get_my_registers(ddf_dev_t *dev, uintptr_t *io_reg_address, size_t *io_reg_size, int *kbd_irq, int *mouse_irq) { assert(dev); async_sess_t *parent_sess = ddf_dev_parent_sess_create( dev, EXCHANGE_SERIALIZE); if (parent_sess == NULL) return ENOMEM; hw_res_list_parsed_t hw_resources; hw_res_list_parsed_init(&hw_resources); const int ret = hw_res_get_list_parsed(parent_sess, &hw_resources, 0); if (ret != EOK) return ret; if ((hw_resources.irqs.count != 2) || (hw_resources.io_ranges.count != 1)) { hw_res_list_parsed_clean(&hw_resources); return EINVAL; } if (io_reg_address) *io_reg_address = hw_resources.io_ranges.ranges[0].address; if (io_reg_size) *io_reg_size = hw_resources.io_ranges.ranges[0].size; if (kbd_irq) *kbd_irq = hw_resources.irqs.irqs[0]; if (mouse_irq) *mouse_irq = hw_resources.irqs.irqs[1]; hw_res_list_parsed_clean(&hw_resources); return EOK; }
/** Initialize keyboard driver structure. * @param kbd Keyboard driver structure to initialize. * @param dev DDF device structure. * * Connects to parent, creates mouse function, starts polling fibril. */ int xt_kbd_init(xt_kbd_t *kbd, ddf_dev_t *dev) { assert(kbd); assert(dev); kbd->client_sess = NULL; kbd->parent_sess = ddf_dev_parent_sess_create(dev, EXCHANGE_SERIALIZE); if (!kbd->parent_sess) return ENOMEM; kbd->kbd_fun = ddf_fun_create(dev, fun_exposed, "kbd"); if (!kbd->kbd_fun) { return ENOMEM; } ddf_fun_set_ops(kbd->kbd_fun, &kbd_ops); int ret = ddf_fun_bind(kbd->kbd_fun); if (ret != EOK) { ddf_fun_destroy(kbd->kbd_fun); return ENOMEM; } ret = ddf_fun_add_to_category(kbd->kbd_fun, "keyboard"); if (ret != EOK) { ddf_fun_unbind(kbd->kbd_fun); ddf_fun_destroy(kbd->kbd_fun); return ENOMEM; } kbd->polling_fibril = fibril_create(polling, kbd); if (!kbd->polling_fibril) { ddf_fun_unbind(kbd->kbd_fun); ddf_fun_destroy(kbd->kbd_fun); return ENOMEM; } fibril_add_ready(kbd->polling_fibril); return EOK; }