Ignore:
File:
1 edited

Legend:

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

    raa05b29 r5153b58  
    6868/** Callback when a MID device is about to be removed from the host.
    6969 *
    70  * @param gen_dev Generic DDF device representing the removed device.
     70 * @param dev USB device representing the removed device.
    7171 * @return Error code.
    7272 */
     
    7474{
    7575        assert(dev);
    76         int ret = ENOTSUP;
    7776        usb_mid_t *usb_mid = dev->driver_data;
    7877        assert(usb_mid);
    7978
    80         /* Signal all interface functions */
    81         list_foreach(usb_mid->interface_list, item) {
     79        /* Remove ctl function */
     80        int ret = ddf_fun_unbind(usb_mid->ctl_fun);
     81        if (ret != EOK) {
     82                usb_log_error("Failed to unbind USB MID ctl function: %s.\n",
     83                    str_error(ret));
     84                return ret;
     85        }
     86        ddf_fun_destroy(usb_mid->ctl_fun);
     87
     88        /* Remove all children */
     89        while (!list_empty(&usb_mid->interface_list)) {
     90                link_t *item = list_first(&usb_mid->interface_list);
     91                list_remove(item);
     92
    8293                usbmid_interface_t *iface = usbmid_interface_from_link(item);
    8394
    84                 usb_log_info("Signaling remove to child for interface "
    85                     "%d (%s).\n", iface->interface_no,
     95                usb_log_info("Removing child for interface %d (%s).\n",
     96                    iface->interface_no,
    8697                    usb_str_class(iface->interface->interface_class));
    87                 // TODO cascade the call.
     98
     99                /* Tell the child to go off-line. */
     100                int pret = ddf_fun_offline(iface->fun);
     101                if (pret != EOK) {
     102                        usb_log_warning("Failed to turn off child for interface"
     103                            " %d (%s): %s\n", iface->interface_no,
     104                            usb_str_class(iface->interface->interface_class),
     105                            str_error(pret));
     106                        ret = pret;
     107                }
     108
     109                /* Now remove the child. */
     110                pret = usbmid_interface_destroy(iface);
     111                if (pret != EOK) {
     112                        usb_log_error("Failed to destroy child for interface "
     113                            "%d (%s): %s\n", iface->interface_no,
     114                            usb_str_class(iface->interface->interface_class),
     115                            str_error(pret));
     116                        ret = pret;
     117                }
    88118        }
    89119        return ret;
     
    92122/** Callback when a MID device was removed from the host.
    93123 *
    94  * @param gen_dev Generic DDF device representing the removed device.
     124 * @param dev USB device representing the removed device.
    95125 * @return Error code.
    96126 */
     
    98128{
    99129        assert(dev);
     130        usb_mid_t *usb_mid = dev->driver_data;
     131        assert(usb_mid);
     132
    100133        usb_log_info("USB MID gone: `%s'.\n", dev->ddf_dev->name);
    101134
    102135        /* Remove ctl function */
    103         usb_mid_t *usb_mid = dev->driver_data;
    104136        int ret = ddf_fun_unbind(usb_mid->ctl_fun);
    105137        if (ret != EOK) {
     
    117149                usbmid_interface_t *iface = usbmid_interface_from_link(item);
    118150
    119                 usb_log_info("Removing child for interface %d (%s).\n",
     151                usb_log_info("Child for interface %d (%s) gone.\n",
    120152                    iface->interface_no,
    121153                    usb_str_class(iface->interface->interface_class));
Note: See TracChangeset for help on using the changeset viewer.