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 <devmap.h>
00037 #include <async.h>
00038 #include <unistd.h>
00039 #include <stdlib.h>
00040 #include <sysinfo.h>
00041 #include <stdio.h>
00042 #include <errno.h>
00043 #include <str_error.h>
00044 #include <ddf/driver.h>
00045
00046 #include <usb/usb.h>
00047 #include <usb/ddfiface.h>
00048 #include <usb_iface.h>
00049 #include "vhcd.h"
00050 #include "hub.h"
00051 #include "conn.h"
00052
00053 static ddf_dev_ops_t vhc_ops = {
00054 .interfaces[USBHC_DEV_IFACE] = &vhc_iface,
00055 .interfaces[USB_DEV_IFACE] = &vhc_usb_iface,
00056 .close = on_client_close,
00057 .default_handler = default_connection_handler
00058 };
00059
00060 static int vhc_add_device(ddf_dev_t *dev)
00061 {
00062 static int vhc_count = 0;
00063 int rc;
00064
00065 if (vhc_count > 0) {
00066 return ELIMIT;
00067 }
00068
00069 vhc_data_t *data = malloc(sizeof(vhc_data_t));
00070 if (data == NULL) {
00071 usb_log_fatal("Failed to allocate memory.\n");
00072 return ENOMEM;
00073 }
00074 data->magic = 0xDEADBEEF;
00075 rc = usb_endpoint_manager_init(&data->ep_manager, (size_t) -1);
00076 if (rc != EOK) {
00077 usb_log_fatal("Failed to initialize endpoint manager.\n");
00078 free(data);
00079 return rc;
00080 }
00081 usb_device_keeper_init(&data->dev_keeper);
00082
00083 ddf_fun_t *hc = ddf_fun_create(dev, fun_exposed, "hc");
00084 if (hc == NULL) {
00085 usb_log_fatal("Failed to create device function.\n");
00086 free(data);
00087 return ENOMEM;
00088 }
00089
00090 hc->ops = &vhc_ops;
00091 list_initialize(&data->devices);
00092 fibril_mutex_initialize(&data->guard);
00093 data->hub = &virtual_hub_device;
00094 data->hc_fun = hc;
00095
00096 dev->driver_data = data;
00097
00098 rc = ddf_fun_bind(hc);
00099 if (rc != EOK) {
00100 usb_log_fatal("Failed to bind HC function: %s.\n",
00101 str_error(rc));
00102 free(data);
00103 return rc;
00104 }
00105
00106 rc = ddf_fun_add_to_class(hc, USB_HC_DDF_CLASS_NAME);
00107 if (rc != EOK) {
00108 usb_log_fatal("Failed to add function to HC class: %s.\n",
00109 str_error(rc));
00110 free(data);
00111 return rc;
00112 }
00113
00114 virtual_hub_device_init(hc);
00115
00116 usb_log_info("Virtual USB host controller ready (dev %zu, hc %zu).\n",
00117 (size_t) dev->handle, (size_t) hc->handle);
00118
00119
00120
00121 rc = vhc_virtdev_plug_hub(data, data->hub, NULL);
00122 if (rc != EOK) {
00123 usb_log_fatal("Failed to plug root hub: %s.\n", str_error(rc));
00124 free(data);
00125 return rc;
00126 }
00127
00128 return EOK;
00129 }
00130
00131 static driver_ops_t vhc_driver_ops = {
00132 .add_device = vhc_add_device,
00133 };
00134
00135 static driver_t vhc_driver = {
00136 .name = NAME,
00137 .driver_ops = &vhc_driver_ops
00138 };
00139
00140
00141 int main(int argc, char * argv[])
00142 {
00143 usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
00144
00145 printf(NAME ": virtual USB host controller driver.\n");
00146
00147 return ddf_driver_main(&vhc_driver);
00148 }
00149
00150