Changeset 5994cc3 in mainline for uspace/lib/usbhost/src/hcd.c


Ignore:
Timestamp:
2012-12-16T20:08:54Z (12 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9c7ed9c
Parents:
ddab093
Message:

libusbhost, ohci: Move more generic stuff to libusbhost.

File:
1 edited

Legend:

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

    rddab093 r5994cc3  
    3636#include <errno.h>
    3737#include <str_error.h>
     38#include <usb_iface.h>
    3839#include <usb/debug.h>
    3940
    4041#include <usb/host/hcd.h>
     42
     43typedef struct hc_dev {
     44        ddf_fun_t *hc_fun;
     45        ddf_fun_t *rh_fun;
     46} hc_dev_t;
     47
     48static hc_dev_t *dev_to_hc_dev(ddf_dev_t *dev)
     49{
     50        return ddf_dev_data_get(dev);
     51}
     52
     53hcd_t *dev_to_hcd(ddf_dev_t *dev)
     54{
     55        hc_dev_t *hc_dev = dev_to_hc_dev(dev);
     56        if (!hc_dev || !hc_dev->hc_fun) {
     57                usb_log_error("Invalid OHCI device.\n");
     58                return NULL;
     59        }
     60        return ddf_fun_data_get(hc_dev->hc_fun);
     61}
     62
     63typedef struct usb_dev {
     64        usb_address_t address;
     65        usb_speed_t speed;
     66        devman_handle_t handle;
     67} usb_dev_t;
     68
     69/** Get USB address assigned to root hub.
     70 *
     71 * @param[in] fun Root hub function.
     72 * @param[out] address Store the address here.
     73 * @return Error code.
     74 */
     75static int rh_get_my_address(ddf_fun_t *fun, usb_address_t *address)
     76{
     77        assert(fun);
     78        if (address != NULL) {
     79                usb_dev_t *usb_dev = ddf_fun_data_get(fun);
     80                *address = usb_dev->address;
     81        }
     82        return EOK;
     83}
     84
     85/** Gets handle of the respective hc (this device, hc function).
     86 *
     87 * @param[in] root_hub_fun Root hub function seeking hc handle.
     88 * @param[out] handle Place to write the handle.
     89 * @return Error code.
     90 */
     91static int rh_get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle)
     92{
     93        assert(fun);
     94
     95        if (handle != NULL) {
     96                usb_dev_t *usb_dev = ddf_fun_data_get(fun);
     97                *handle = usb_dev->handle;
     98        }
     99        return EOK;
     100}
     101
     102/** Root hub USB interface */
     103static usb_iface_t usb_iface = {
     104        .get_hc_handle = rh_get_hc_handle,
     105        .get_my_address = rh_get_my_address,
     106};
     107/** Standard USB RH options (RH interface) */
     108static ddf_dev_ops_t rh_ops = {
     109        .interfaces[USB_DEV_IFACE] = &usb_iface,
     110};
     111
     112/** Standard USB HC options (HC interface) */
     113static ddf_dev_ops_t hc_ops = {
     114        .interfaces[USBHC_DEV_IFACE] = &hcd_iface,
     115};
    41116
    42117/** Announce root hub to the DDF
     
    46121 * @return Error code
    47122 */
    48 int hcd_register_hub(hcd_t *instance, usb_address_t *address, ddf_fun_t *hub_fun)
     123int hcd_setup_hub(hcd_t *instance, usb_address_t *address, ddf_dev_t *device)
    49124{
    50125        assert(instance);
    51126        assert(address);
    52         assert(hub_fun);
    53 
    54         int ret = usb_device_manager_request_address(
    55             &instance->dev_manager, address, false,
    56             USB_SPEED_FULL);
     127        assert(device);
     128
     129        hc_dev_t *hc_dev = ddf_dev_data_get(device);
     130        hc_dev->rh_fun = ddf_fun_create(device, fun_inner, "rh");
     131        if (!hc_dev->rh_fun)
     132                return ENOMEM;
     133        usb_dev_t *rh = ddf_fun_data_alloc(hc_dev->rh_fun, sizeof(usb_dev_t));
     134        if (!rh) {
     135                ddf_fun_destroy(hc_dev->rh_fun);
     136                return ENOMEM;
     137        }
     138
     139
     140        int ret = usb_device_manager_request_address(&instance->dev_manager,
     141            address, false, USB_SPEED_FULL);
    57142        if (ret != EOK) {
    58143                usb_log_error("Failed to get root hub address: %s\n",
    59144                    str_error(ret));
     145                ddf_fun_destroy(hc_dev->rh_fun);
    60146                return ret;
    61147        }
     148
     149        rh->address = *address;
     150        rh->speed = USB_SPEED_FULL;
     151        rh->handle = ddf_fun_get_handle(hc_dev->hc_fun);
     152
     153        ddf_fun_set_ops(hc_dev->rh_fun, &rh_ops);
    62154
    63155#define CHECK_RET_UNREG_RETURN(ret, message...) \
     
    69161        usb_device_manager_release_address( \
    70162            &instance->dev_manager, *address); \
     163        ddf_fun_destroy(hc_dev->rh_fun); \
    71164        return ret; \
    72165} else (void)0
     
    80173            str_error(ret));
    81174
    82         ret = ddf_fun_add_match_id(hub_fun, "usb&class=hub", 100);
     175        ret = ddf_fun_add_match_id(hc_dev->rh_fun, "usb&class=hub", 100);
    83176        CHECK_RET_UNREG_RETURN(ret,
    84177            "Failed to add root hub match-id: %s.\n", str_error(ret));
    85178
    86         ret = ddf_fun_bind(hub_fun);
     179        ret = ddf_fun_bind(hc_dev->rh_fun);
    87180        CHECK_RET_UNREG_RETURN(ret,
    88181            "Failed to bind root hub function: %s.\n", str_error(ret));
    89182
    90183        ret = usb_device_manager_bind_address(&instance->dev_manager,
    91             *address, ddf_fun_get_handle(hub_fun));
     184            *address, ddf_fun_get_handle(hc_dev->rh_fun));
    92185        if (ret != EOK)
    93186                usb_log_warning("Failed to bind root hub address: %s.\n",
    94187                    str_error(ret));
    95188
     189
    96190        return EOK;
    97191#undef CHECK_RET_UNREG_RETURN
     192}
     193
     194/** Initialize hc structures.
     195 *
     196 * @param[in] device DDF instance of the device to use.
     197 *
     198 * This function does all the preparatory work for hc driver implementation.
     199 *  - gets device hw resources
     200 *  - disables OHCI legacy support
     201 *  - asks for interrupt
     202 *  - registers interrupt handler
     203 */
     204int hcd_setup_device(ddf_dev_t *device)
     205{
     206        if (device == NULL)
     207                return EBADMEM;
     208
     209        hc_dev_t *instance = ddf_dev_data_alloc(device, sizeof(hc_dev_t));
     210        if (instance == NULL) {
     211                usb_log_error("Failed to allocate OHCI driver.\n");
     212                return ENOMEM;
     213        }
     214
     215#define CHECK_RET_DEST_FREE_RETURN(ret, message...) \
     216if (ret != EOK) { \
     217        if (instance->hc_fun) { \
     218                ddf_fun_destroy(instance->hc_fun); \
     219        } \
     220        usb_log_error(message); \
     221        return ret; \
     222} else (void)0
     223
     224        instance->hc_fun = ddf_fun_create(device, fun_exposed, "hc");
     225        int ret = instance->hc_fun ? EOK : ENOMEM;
     226        CHECK_RET_DEST_FREE_RETURN(ret,
     227            "Failed to create OHCI HC function: %s.\n", str_error(ret));
     228        ddf_fun_set_ops(instance->hc_fun, &hc_ops);
     229        hcd_t *hcd = ddf_fun_data_alloc(instance->hc_fun, sizeof(hcd_t));
     230        ret = hcd ? EOK : ENOMEM;
     231        CHECK_RET_DEST_FREE_RETURN(ret,
     232            "Failed to allocate HCD structure: %s.\n", str_error(ret));
     233
     234        hcd_init(hcd, USB_SPEED_FULL, BANDWIDTH_AVAILABLE_USB11,
     235            bandwidth_count_usb11);
     236
     237        ret = ddf_fun_bind(instance->hc_fun);
     238        CHECK_RET_DEST_FREE_RETURN(ret,
     239            "Failed to bind OHCI device function: %s.\n", str_error(ret));
     240
     241#define CHECK_RET_UNBIND_FREE_RETURN(ret, message...) \
     242if (ret != EOK) { \
     243        ddf_fun_unbind(instance->hc_fun); \
     244        CHECK_RET_DEST_FREE_RETURN(ret, \
     245            "Failed to add OHCI to HC class: %s.\n", str_error(ret)); \
     246} else (void)0
     247        ret = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
     248        CHECK_RET_UNBIND_FREE_RETURN(ret,
     249            "Failed to add hc to category: %s\n", str_error(ret));
     250
     251        /* HC should be ok at this point (except it can't do anything) */
     252
     253        return EOK;
    98254}
    99255
Note: See TracChangeset for help on using the changeset viewer.