00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00036 #include <errno.h>
00037 #include <str_error.h>
00038 #include <stdlib.h>
00039 #include <usb_iface.h>
00040 #include <usb/ddfiface.h>
00041 #include <usb/dev/pipes.h>
00042 #include <usb/classes/classes.h>
00043 #include <usb/dev/recognise.h>
00044 #include "usbmid.h"
00045
00047 static int usb_iface_get_address_impl(ddf_fun_t *fun, devman_handle_t handle,
00048 usb_address_t *address)
00049 {
00050 return usb_iface_get_address_hub_impl(fun, handle, address);
00051 }
00052
00054 static int usb_iface_get_interface_impl(ddf_fun_t *fun, devman_handle_t handle,
00055 int *iface_no)
00056 {
00057 assert(fun);
00058
00059 usbmid_interface_t *iface = fun->driver_data;
00060 assert(iface);
00061
00062 if (iface_no != NULL) {
00063 *iface_no = iface->interface_no;
00064 }
00065
00066 return EOK;
00067 }
00068
00070 static usb_iface_t child_usb_iface = {
00071 .get_hc_handle = usb_iface_get_hc_handle_hub_child_impl,
00072 .get_address = usb_iface_get_address_impl,
00073 .get_interface = usb_iface_get_interface_impl
00074 };
00075
00077 static ddf_dev_ops_t child_device_ops = {
00078 .interfaces[USB_DEV_IFACE] = &child_usb_iface
00079 };
00080
00081
00090 int usbmid_spawn_interface_child(usb_device_t *parent,
00091 usbmid_interface_t *iface,
00092 const usb_standard_device_descriptor_t *device_descriptor,
00093 const usb_standard_interface_descriptor_t *interface_descriptor)
00094 {
00095 ddf_fun_t *child = NULL;
00096 char *child_name = NULL;
00097 int rc;
00098
00099
00100
00101
00102
00103
00104 rc = asprintf(&child_name, "%s%d",
00105 usb_str_class(interface_descriptor->interface_class),
00106 (int) interface_descriptor->interface_number);
00107 if (rc < 0) {
00108 goto error_leave;
00109 }
00110
00111
00112 child = ddf_fun_create(parent->ddf_dev, fun_inner, child_name);
00113 if (child == NULL) {
00114 rc = ENOMEM;
00115 goto error_leave;
00116 }
00117
00118 iface->fun = child;
00119
00120 child->driver_data = iface;
00121 child->ops = &child_device_ops;
00122
00123 rc = usb_device_create_match_ids_from_interface(device_descriptor,
00124 interface_descriptor,
00125 &child->match_ids);
00126 if (rc != EOK) {
00127 goto error_leave;
00128 }
00129
00130 rc = ddf_fun_bind(child);
00131 if (rc != EOK) {
00132 goto error_leave;
00133 }
00134
00135 return EOK;
00136
00137 error_leave:
00138 if (child != NULL) {
00139 child->name = NULL;
00140
00141 ddf_fun_destroy(child);
00142 }
00143 if (child_name != NULL) {
00144 free(child_name);
00145 }
00146
00147 return rc;
00148 }
00149