HelenOS sources
This source file includes following definitions.
- usbmid_device_add
- destroy_interfaces
- usbmid_device_remove
- usbmid_device_gone
- usbmid_function_online
- usbmid_function_offline
- main
#include <errno.h>
#include <str_error.h>
#include <usb/debug.h>
#include <usb/classes/classes.h>
#include <usb/dev/request.h>
#include <usb/descriptor.h>
#include <usb/dev/pipes.h>
#include "usbmid.h"
static errno_t usbmid_device_add(usb_device_t *dev)
{
usb_log_info("Taking care of new MID `%s'.", usb_device_get_name(dev));
return usbmid_explore_device(dev);
}
static errno_t destroy_interfaces(usb_mid_t *usb_mid)
{
errno_t ret = EOK;
while (!list_empty(&usb_mid->interface_list)) {
link_t *item = list_first(&usb_mid->interface_list);
list_remove(item);
usbmid_interface_t *iface = usbmid_interface_from_link(item);
const errno_t pret = usbmid_interface_destroy(iface);
if (pret != EOK) {
usb_log_error("Failed to remove child `%s': %s",
ddf_fun_get_name(iface->fun), str_error(pret));
ret = pret;
}
}
return ret;
}
static errno_t usbmid_device_remove(usb_device_t *dev)
{
assert(dev);
usb_mid_t *usb_mid = usb_device_data_get(dev);
assert(usb_mid);
errno_t ret = ddf_fun_unbind(usb_mid->ctl_fun);
if (ret != EOK) {
usb_log_error("Failed to unbind USB MID ctl function: %s.",
str_error(ret));
return ret;
}
ddf_fun_destroy(usb_mid->ctl_fun);
list_foreach(usb_mid->interface_list, link, usbmid_interface_t, iface) {
usb_log_info("Removing child `%s'.",
ddf_fun_get_name(iface->fun));
errno_t pret = ddf_fun_offline(iface->fun);
if (pret != EOK) {
usb_log_warning("Failed to turn off child `%s': %s",
ddf_fun_get_name(iface->fun), str_error(pret));
}
}
return destroy_interfaces(usb_mid);
}
static errno_t usbmid_device_gone(usb_device_t *dev)
{
assert(dev);
usb_mid_t *usb_mid = usb_device_data_get(dev);
assert(usb_mid);
usb_log_info("USB MID gone: `%s'.", usb_device_get_name(dev));
errno_t ret = ddf_fun_unbind(usb_mid->ctl_fun);
if (ret != EOK) {
usb_log_error("Failed to unbind USB MID ctl function: %s.",
str_error(ret));
return ret;
}
ddf_fun_destroy(usb_mid->ctl_fun);
return destroy_interfaces(usb_mid);
}
static errno_t usbmid_function_online(ddf_fun_t *fun)
{
usb_device_t *usb_dev = ddf_dev_data_get(ddf_fun_get_dev(fun));
usb_mid_t *usb_mid = usb_device_data_get(usb_dev);
if (fun == usb_mid->ctl_fun)
return ENOTSUP;
return ddf_fun_online(fun);
}
static errno_t usbmid_function_offline(ddf_fun_t *fun)
{
usb_device_t *usb_dev = ddf_dev_data_get(ddf_fun_get_dev(fun));
usb_mid_t *usb_mid = usb_device_data_get(usb_dev);
if (fun == usb_mid->ctl_fun)
return ENOTSUP;
return ddf_fun_offline(fun);
}
static const usb_driver_ops_t mid_driver_ops = {
.device_add = usbmid_device_add,
.device_remove = usbmid_device_remove,
.device_gone = usbmid_device_gone,
.function_online = usbmid_function_online,
.function_offline = usbmid_function_offline
};
static const usb_driver_t mid_driver = {
.name = NAME,
.ops = &mid_driver_ops,
.endpoints = NULL
};
int main(int argc, char *argv[])
{
printf(NAME ": USB multi interface device driver.\n");
log_init(NAME);
return usb_driver_main(&mid_driver);
}
HelenOS homepage, sources at GitHub