Ignore:
Timestamp:
2017-09-30T06:29:42Z (7 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
300f4c4
Parents:
d076f16 (diff), 6636fb19 (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.
Message:

Merge support for capabilities from lp:~jakub/helenos/caps

This commit introduces capabilities as task-local names for references to kernel
objects. Kernel objects are reference-counted wrappers for a select group of
objects allocated in and by the kernel that can be made accessible to userspace
in a controlled way via integer handles.

So far, a kernel object encapsulates either an irq_t or a phone_t.

Support for the former lead to the removal of kernel-assigned devnos and
unsecure deregistration of IRQs in which a random task was able to unregister
some other task's IRQ.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usbhost/src/ddf_helpers.c

    rd076f16 r91b60499  
    748748 * @param[in] gen_irq_code IRQ code generator.
    749749 *
    750  * @return EOK on success or negative error code
     750 * @return IRQ capability handle on success.
     751 * @return Negative error code.
    751752 */
    752753int hcd_ddf_setup_interrupts(ddf_dev_t *device,
     
    770771
    771772        /* Register handler to avoid interrupt lockup */
    772         int ret = register_interrupt_handler(device, irq, handler, &irq_code);
     773        const int irq_cap = register_interrupt_handler(device, irq, handler,
     774            &irq_code);
    773775        irq_code_clean(&irq_code);
     776        if (irq_cap < 0) {
     777                usb_log_error("Failed to register interrupt handler: %s.\n",
     778                    str_error(irq_cap));
     779                return irq_cap;
     780        }
     781
     782        /* Enable interrupts */
     783        int ret = hcd_ddf_enable_interrupts(device);
    774784        if (ret != EOK) {
    775785                usb_log_error("Failed to register interrupt handler: %s.\n",
    776786                    str_error(ret));
    777                 return ret;
    778         }
    779 
    780         /* Enable interrupts */
    781         ret = hcd_ddf_enable_interrupts(device);
    782         if (ret != EOK) {
    783                 usb_log_error("Failed to register interrupt handler: %s.\n",
    784                     str_error(ret));
    785                 unregister_interrupt_handler(device, irq);
    786                 return ret;
    787         }
    788         assert(irq > 0);
    789         return irq;
     787                unregister_interrupt_handler(device, irq_cap);
     788                return ret;
     789        }
     790        return irq_cap;
    790791}
    791792
     
    882883        interrupt_handler_t *irq_handler =
    883884            driver->irq_handler ? driver->irq_handler : ddf_hcd_gen_irq_handler;
    884         const int irq = hcd_ddf_setup_interrupts(device, &hw_res, irq_handler,
    885             driver->irq_code_gen);
    886         if (!(irq < 0)) {
     885        const int irq_cap = hcd_ddf_setup_interrupts(device, &hw_res,
     886            irq_handler, driver->irq_code_gen);
     887        bool irqs_enabled = !(irq_cap < 0);
     888        if (irqs_enabled) {
    887889                usb_log_debug("Hw interrupts enabled.\n");
    888890        }
     
    899901        /* Init hw driver */
    900902        hcd_t *hcd = dev_to_hcd(device);
    901         ret = driver->init(hcd, &hw_res, !(irq < 0));
     903        ret = driver->init(hcd, &hw_res, irqs_enabled);
    902904        hw_res_list_parsed_clean(&hw_res);
    903905        if (ret != EOK) {
     
    907909
    908910        /* Need working irq replacement to setup root hub */
    909         if ((irq < 0) && hcd->ops.status_hook) {
     911        if (!irqs_enabled && hcd->ops.status_hook) {
    910912                hcd->polling_fibril = fibril_create(interrupt_polling, hcd);
    911913                if (hcd->polling_fibril == 0) {
     
    916918                fibril_add_ready(hcd->polling_fibril);
    917919                usb_log_warning("Failed to enable interrupts: %s."
    918                     " Falling back to polling.\n", str_error(irq));
     920                    " Falling back to polling.\n", str_error(irq_cap));
    919921        }
    920922
     
    930932irq_unregister:
    931933                /* Unregistering non-existent should be ok */
    932                 unregister_interrupt_handler(device, irq);
     934                unregister_interrupt_handler(device, irq_cap);
    933935                hcd_ddf_clean_hc(device);
    934936                return ret;
Note: See TracChangeset for help on using the changeset viewer.