Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/usbmid/main.c

    rb7fd2a0 ra821f05  
    5151static errno_t usbmid_device_add(usb_device_t *dev)
    5252{
    53         usb_log_info("Taking care of new MID `%s'.\n", usb_device_get_name(dev));
     53        usb_log_info("Taking care of new MID `%s'.", usb_device_get_name(dev));
    5454
    5555        return usbmid_explore_device(dev);
     56}
     57
     58static errno_t destroy_interfaces(usb_mid_t *usb_mid)
     59{
     60        errno_t ret = EOK;
     61
     62        while (!list_empty(&usb_mid->interface_list)) {
     63                link_t *item = list_first(&usb_mid->interface_list);
     64                list_remove(item);
     65
     66                usbmid_interface_t *iface = usbmid_interface_from_link(item);
     67
     68                const errno_t pret = usbmid_interface_destroy(iface);
     69                if (pret != EOK) {
     70                        usb_log_error("Failed to remove child `%s': %s",
     71                            ddf_fun_get_name(iface->fun), str_error(pret));
     72                        ret = pret;
     73                }
     74        }
     75
     76        return ret;
    5677}
    5778
     
    7091        errno_t ret = ddf_fun_unbind(usb_mid->ctl_fun);
    7192        if (ret != EOK) {
    72                 usb_log_error("Failed to unbind USB MID ctl function: %s.\n",
     93                usb_log_error("Failed to unbind USB MID ctl function: %s.",
    7394                    str_error(ret));
    7495                return ret;
     
    7798
    7899        /* Remove all children */
    79         while (!list_empty(&usb_mid->interface_list)) {
    80                 link_t *item = list_first(&usb_mid->interface_list);
    81                 list_remove(item);
    82 
    83                 usbmid_interface_t *iface = usbmid_interface_from_link(item);
    84 
    85                 usb_log_info("Removing child `%s'.\n",
     100        list_foreach(usb_mid->interface_list, link, usbmid_interface_t, iface) {
     101                usb_log_info("Removing child `%s'.",
    86102                    ddf_fun_get_name(iface->fun));
    87103
    88                 /* Tell the child to go off-line. */
     104                /* Tell the child to go offline. */
    89105                errno_t pret = ddf_fun_offline(iface->fun);
    90106                if (pret != EOK) {
    91                         usb_log_warning("Failed to turn off child `%s': %s\n",
     107                        usb_log_warning("Failed to turn off child `%s': %s",
    92108                            ddf_fun_get_name(iface->fun), str_error(pret));
    93                         ret = pret;
    94                 }
    95 
    96                 /* Now remove the child. */
    97                 pret = usbmid_interface_destroy(iface);
    98                 if (pret != EOK) {
    99                         usb_log_error("Failed to destroy child `%s': %s\n",
    100                             ddf_fun_get_name(iface->fun), str_error(pret));
    101                         ret = pret;
    102109                }
    103110        }
    104         return ret;
     111
     112        return destroy_interfaces(usb_mid);
    105113}
    106114
     
    116124        assert(usb_mid);
    117125
    118         usb_log_info("USB MID gone: `%s'.\n", usb_device_get_name(dev));
     126        usb_log_info("USB MID gone: `%s'.", usb_device_get_name(dev));
    119127
    120128        /* Remove ctl function */
    121129        errno_t ret = ddf_fun_unbind(usb_mid->ctl_fun);
    122130        if (ret != EOK) {
    123                 usb_log_error("Failed to unbind USB MID ctl function: %s.\n",
     131                usb_log_error("Failed to unbind USB MID ctl function: %s.",
    124132                    str_error(ret));
    125133                return ret;
     
    127135        ddf_fun_destroy(usb_mid->ctl_fun);
    128136
    129         /* Now remove all other functions */
    130         while (!list_empty(&usb_mid->interface_list)) {
    131                 link_t *item = list_first(&usb_mid->interface_list);
    132                 list_remove(item);
     137        /* Destroy children and tell their drivers they are gone. */
     138        return destroy_interfaces(usb_mid);
     139}
    133140
    134                 usbmid_interface_t *iface = usbmid_interface_from_link(item);
     141static errno_t usbmid_function_online(ddf_fun_t *fun)
     142{
     143        usb_device_t *usb_dev = ddf_dev_data_get(ddf_fun_get_dev(fun));
     144        usb_mid_t *usb_mid = usb_device_data_get(usb_dev);
     145        if (fun == usb_mid->ctl_fun)
     146                return ENOTSUP;
    135147
    136                 usb_log_info("Child `%s' is gone.\n",
    137                     ddf_fun_get_name(iface->fun));
     148        return ddf_fun_online(fun);
     149}
    138150
    139                 const errno_t pret = usbmid_interface_destroy(iface);
    140                 if (pret != EOK) {
    141                         usb_log_error("Failed to remove child `%s': %s\n",
    142                             ddf_fun_get_name(iface->fun), str_error(pret));
    143                         ret = pret;
    144                 }
    145         }
    146         return ret;
     151static errno_t usbmid_function_offline(ddf_fun_t *fun)
     152{
     153        usb_device_t *usb_dev = ddf_dev_data_get(ddf_fun_get_dev(fun));
     154        usb_mid_t *usb_mid = usb_device_data_get(usb_dev);
     155        if (fun == usb_mid->ctl_fun)
     156                return ENOTSUP;
     157
     158        return ddf_fun_offline(fun);
    147159}
    148160
     
    150162static const usb_driver_ops_t mid_driver_ops = {
    151163        .device_add = usbmid_device_add,
    152         .device_rem = usbmid_device_remove,
     164        .device_remove = usbmid_device_remove,
    153165        .device_gone = usbmid_device_gone,
     166        .function_online = usbmid_function_online,
     167        .function_offline = usbmid_function_offline
    154168};
    155169
Note: See TracChangeset for help on using the changeset viewer.