Changeset 5994cc3 in mainline


Ignore:
Timestamp:
2012-12-16T20:08:54Z (11 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.

Location:
uspace
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/ohci/ohci.c

    rddab093 r5994cc3  
    4646#include "hc.h"
    4747
    48 typedef struct ohci {
    49         ddf_fun_t *hc_fun;
    50         ddf_fun_t *rh_fun;
    51 } ohci_t;
    5248
    53 static inline ohci_t *dev_to_ohci(ddf_dev_t *dev)
    54 {
    55         return ddf_dev_data_get(dev);
    56 }
    57 
    58 static inline hcd_t *dev_to_hcd(ddf_dev_t *dev)
    59 {
    60         ohci_t *ohci = dev_to_ohci(dev);
    61         if (!ohci || !ohci->hc_fun) {
    62                 usb_log_error("Invalid OHCI device.\n");
    63                 return NULL;
    64         }
    65         return ddf_fun_data_get(ohci->hc_fun);
    66 }
    67 
    68 static inline hc_t * dev_to_hc(ddf_dev_t *dev)
    69 {
    70         hcd_t *hcd = dev_to_hcd(dev);
    71         if (!hcd) {
    72                 usb_log_error("Invalid OHCI HCD");
    73                 return NULL;
    74         }
    75         return hcd->private_data;
    76 }
    7749
    7850/** IRQ handling callback, identifies device
     
    8557{
    8658        assert(dev);
    87         hc_t *hc = dev_to_hc(dev);
    88         if (!hc) {
     59        hcd_t *hcd = dev_to_hcd(dev);
     60        if (!hcd || !hcd->private_data) {
    8961                usb_log_warning("Interrupt on device that is not ready.\n");
    9062                return;
     
    9264
    9365        const uint16_t status = IPC_GET_ARG1(*call);
    94         hc_interrupt(hc, status);
     66        hc_interrupt(hcd->private_data, status);
    9567}
    96 
    97 /** Get USB address assigned to root hub.
    98  *
    99  * @param[in] fun Root hub function.
    100  * @param[out] address Store the address here.
    101  * @return Error code.
    102  */
    103 static int rh_get_my_address(ddf_fun_t *fun, usb_address_t *address)
    104 {
    105         assert(fun);
    106 
    107         if (address != NULL) {
    108                 hc_t *hc = dev_to_hc(ddf_fun_get_dev(fun));
    109                 assert(hc);
    110                 *address = hc->rh.address;
    111         }
    112 
    113         return EOK;
    114 }
    115 
    116 /** Gets handle of the respective hc (this device, hc function).
    117  *
    118  * @param[in] root_hub_fun Root hub function seeking hc handle.
    119  * @param[out] handle Place to write the handle.
    120  * @return Error code.
    121  */
    122 static int rh_get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle)
    123 {
    124         assert(fun);
    125 
    126         if (handle != NULL) {
    127                 ddf_fun_t *hc_fun = dev_to_ohci(ddf_fun_get_dev(fun))->hc_fun;
    128                 assert(hc_fun);
    129                 *handle = ddf_fun_get_handle(hc_fun);
    130         }
    131         return EOK;
    132 }
    133 
    134 /** Root hub USB interface */
    135 static usb_iface_t usb_iface = {
    136         .get_hc_handle = rh_get_hc_handle,
    137         .get_my_address = rh_get_my_address,
    138 };
    139 
    140 /** Standard USB HC options (HC interface) */
    141 static ddf_dev_ops_t hc_ops = {
    142         .interfaces[USBHC_DEV_IFACE] = &hcd_iface,
    143 };
    144 
    145 /** Standard USB RH options (RH interface) */
    146 static ddf_dev_ops_t rh_ops = {
    147         .interfaces[USB_DEV_IFACE] = &usb_iface,
    148 };
    14968
    15069/** Initialize hc and rh ddf structures and their respective drivers.
     
    15978 *  - registers interrupt handler
    16079 */
    161 static int device_setup_hcd(ddf_dev_t *device)
    162 {
    163         if (device == NULL)
    164                 return EBADMEM;
    165 
    166         ohci_t *instance = ddf_dev_data_alloc(device, sizeof(ohci_t));
    167         if (instance == NULL) {
    168                 usb_log_error("Failed to allocate OHCI driver.\n");
    169                 return ENOMEM;
    170         }
    171 
    172 #define CHECK_RET_DEST_FREE_RETURN(ret, message...) \
    173 if (ret != EOK) { \
    174         if (instance->hc_fun) { \
    175                 ddf_fun_destroy(instance->hc_fun); \
    176         } \
    177         usb_log_error(message); \
    178         return ret; \
    179 } else (void)0
    180 
    181         instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci_hc");
    182         int ret = instance->hc_fun ? EOK : ENOMEM;
    183         CHECK_RET_DEST_FREE_RETURN(ret,
    184             "Failed to create OHCI HC function: %s.\n", str_error(ret));
    185         ddf_fun_set_ops(instance->hc_fun, &hc_ops);
    186         hcd_t *hcd = ddf_fun_data_alloc(instance->hc_fun, sizeof(hcd_t));
    187         ret = hcd ? EOK : ENOMEM;
    188         CHECK_RET_DEST_FREE_RETURN(ret,
    189             "Failed to allocate HCD structure: %s.\n", str_error(ret));
    190 
    191         hcd_init(hcd, USB_SPEED_FULL, BANDWIDTH_AVAILABLE_USB11,
    192             bandwidth_count_usb11);
    193 
    194         ret = ddf_fun_bind(instance->hc_fun);
    195         CHECK_RET_DEST_FREE_RETURN(ret,
    196             "Failed to bind OHCI device function: %s.\n", str_error(ret));
    197 
    198 #define CHECK_RET_UNBIND_FREE_RETURN(ret, message...) \
    199 if (ret != EOK) { \
    200         ddf_fun_unbind(instance->hc_fun); \
    201         CHECK_RET_DEST_FREE_RETURN(ret, \
    202             "Failed to add OHCI to HC class: %s.\n", str_error(ret)); \
    203 } else (void)0
    204         ret = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
    205         CHECK_RET_UNBIND_FREE_RETURN(ret,
    206             "Failed to add hc to category: %s\n", str_error(ret));
    207 
    208         /* HC should be ok at this point (except it can't do anything) */
    209 
    210         return EOK;
    211 }
    212 
    21380int device_setup_ohci(ddf_dev_t *device)
    21481{
     
    264131        }
    265132
    266         ret = device_setup_hcd(device);
     133        ret = hcd_setup_device(device);
    267134        if (ret != EOK) {
    268135                unregister_interrupt_handler(device, irq);
     
    285152        CHECK_RET_CLEAN_RETURN(ret, "Failed to init hc: %s.\n", str_error(ret));
    286153
    287         ohci_t *ohci = dev_to_ohci(device);
    288 
    289154        hcd_set_implementation(dev_to_hcd(device), hc_impl,
    290155            hc_schedule, ohci_endpoint_init, ohci_endpoint_fini);
     156        ret = hcd_setup_hub(dev_to_hcd(device), &hc_impl->rh.address, device);
     157        CHECK_RET_CLEAN_RETURN(ret,
     158            "Failed to register OHCI root hub: %s.\n", str_error(ret));
    291159
    292 #define CHECK_RET_FINI_RETURN(ret, message...) \
    293 if (ret != EOK) { \
    294         hc_fini(hc_impl); \
    295         CHECK_RET_CLEAN_RETURN(ret, message); \
    296 } else (void)0
    297         ohci->rh_fun = ddf_fun_create(device, fun_inner, "ohci_rh");
    298         ret = ohci->rh_fun ? EOK : ENOMEM;
    299         CHECK_RET_FINI_RETURN(ret,
    300             "Failed to create OHCI RH function: %s.\n", str_error(ret));
    301         ddf_fun_set_ops(ohci->rh_fun, &rh_ops);
    302 
    303         ret = hcd_register_hub(dev_to_hcd(device), &hc_impl->rh.address, ohci->rh_fun);
    304         CHECK_RET_FINI_RETURN(ret,
    305             "Failed to register OHCI root hub: %s.\n", str_error(ret));
    306160        return ret;
    307161}
  • uspace/lib/usbhost/include/usb/host/hcd.h

    rddab093 r5994cc3  
    6767};
    6868
     69
    6970/** Initialize hcd_t structure.
    7071 * Initializes device and endpoint managers. Sets data and hook pointer to NULL.
     
    109110}
    110111
    111 int hcd_register_hub(hcd_t *instance, usb_address_t *address, ddf_fun_t *hub_fun);
     112int hcd_setup_device(ddf_dev_t *device);
     113int hcd_setup_hub(hcd_t *instance, usb_address_t *address, ddf_dev_t *dev);
    112114
     115hcd_t *dev_to_hcd(ddf_dev_t *dev);
    113116
    114117/** Data retrieve wrapper.
  • 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
  • uspace/lib/usbhost/src/iface.c

    rddab093 r5994cc3  
    215215        assert(hcd);
    216216        usb_log_debug("Address release %d.\n", address);
    217         usb_device_manager_release_address(&hcd->dev_manager, address);
    218217        usb_endpoint_manager_remove_address(&hcd->ep_manager, address,
    219218            unregister_helper_warn, hcd);
     219        usb_device_manager_release_address(&hcd->dev_manager, address);
    220220        return EOK;
    221221}
Note: See TracChangeset for help on using the changeset viewer.