Changeset 7191992 in mainline for uspace/lib/usbhost/src/ddf_helpers.c


Ignore:
Timestamp:
2014-01-02T19:49:35Z (10 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1a0fa29c
Parents:
7813516
Message:

libusbhost: Add more helper functions.

File:
1 edited

Legend:

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

    r7813516 r7191992  
    653653}
    654654
    655 
    656655//TODO: Move this to generic ddf?
    657656/** Call the parent driver with a request to enable interrupts
     
    701700}
    702701
    703 
    704702/** Register interrupt handler
    705703 *
     
    752750        return irq;
    753751}
     752
     753/** IRQ handling callback, forward status from call to diver structure.
     754 *
     755 * @param[in] dev DDF instance of the device to use.
     756 * @param[in] iid (Unused).
     757 * @param[in] call Pointer to the call from kernel.
     758 */
     759void ddf_hcd_gen_irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
     760{
     761        assert(dev);
     762        hcd_t *hcd = dev_to_hcd(dev);
     763        if (!hcd || !hcd->driver.irq_hook) {
     764                usb_log_error("Interrupt on not yet initialized device.\n");
     765                return;
     766        }
     767        const uint32_t status = IPC_GET_ARG1(*call);
     768        hcd->driver.irq_hook(hcd, status);
     769}
     770/** Initialize hc and rh DDF structures and their respective drivers.
     771 *
     772 * @param device DDF instance of the device to use
     773 * @param speed Maximum supported speed
     774 * @param bw Available bandwidth (arbitrary units)
     775 * @param bw_count Bandwidth computing function
     776 * @param irq_handler IRQ handling function
     777 * @param gen_irq_code Function to generate IRQ pseudocode
     778 *                     (it needs to return used irq number)
     779 * @param driver_init Function to initialize HC driver
     780 * @param driver_fini Function to cleanup HC driver
     781 * @return Error code
     782 *
     783 * This function does all the preparatory work for hc and rh drivers:
     784 *  - gets device's hw resources
     785 *  - attempts to enable interrupts
     786 *  - registers interrupt handler
     787 *  - calls driver specific initialization
     788 *  - registers root hub
     789 */
     790int ddf_hcd_device_setup_all(ddf_dev_t *device, usb_speed_t speed, size_t bw,
     791    bw_count_func_t bw_count,
     792    interrupt_handler_t irq_handler,
     793    int (*gen_irq_code)(irq_code_t *, const hw_res_list_parsed_t *hw_res),
     794    int (*driver_init)(hcd_t *, const hw_res_list_parsed_t *, bool),
     795    void (*driver_fini)(hcd_t *)
     796    )
     797{
     798        assert(device);
     799
     800        hw_res_list_parsed_t hw_res;
     801        int ret = hcd_ddf_get_registers(device, &hw_res);
     802        if (ret != EOK) {
     803                usb_log_error("Failed to get register memory addresses "
     804                    "for %" PRIun ": %s.\n", ddf_dev_get_handle(device),
     805                    str_error(ret));
     806                return ret;
     807        }
     808
     809        ret = hcd_ddf_setup_hc(device, speed, bw, bw_count);
     810        if (ret != EOK) {
     811                usb_log_error("Failed to setup generic HCD.\n");
     812                hw_res_list_parsed_clean(&hw_res);
     813                return ret;
     814        }
     815
     816        const int irq = hcd_ddf_setup_interrupts(device, &hw_res, irq_handler,
     817            gen_irq_code);
     818        if (irq < 0) {
     819                usb_log_warning("Failed to enable interrupts: %s."
     820                    " Falling back to polling.\n", str_error(irq));
     821        } else {
     822                usb_log_debug("Hw interrupts enabled.\n");
     823        }
     824
     825        /* Init hw driver */
     826        ret = driver_init(dev_to_hcd(device), &hw_res, !(irq < 0));
     827        hw_res_list_parsed_clean(&hw_res);
     828        if (ret != EOK) {
     829                usb_log_error("Failed to init uhci_hcd: %s.\n", str_error(ret));
     830                goto irq_unregister;
     831        }
     832
     833        /*
     834         * Creating root hub registers a new USB device so HC
     835         * needs to be ready at this time.
     836         */
     837        ret = hcd_ddf_setup_root_hub(device);
     838        if (ret != EOK) {
     839                usb_log_error("Failed to setup UHCI root hub: %s.\n",
     840                    str_error(ret));
     841                driver_fini(dev_to_hcd(device));
     842irq_unregister:
     843                /* Unregistering non-existent should be ok */
     844                unregister_interrupt_handler(device, irq);
     845                hcd_ddf_clean_hc(device);
     846        }
     847        return ret;
     848}
    754849/**
    755850 * @}
Note: See TracChangeset for help on using the changeset viewer.