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
00035 #include <ddf/driver.h>
00036 #include <ddf/interrupt.h>
00037 #include <device/hw_res.h>
00038 #include <errno.h>
00039 #include <str_error.h>
00040
00041 #include <usb_iface.h>
00042 #include <usb/ddfiface.h>
00043 #include <usb/debug.h>
00044
00045 #include "pci.h"
00046 #include "ehci.h"
00047
00048 static int ehci_add_device(ddf_dev_t *device);
00049
00050 static driver_ops_t ehci_driver_ops = {
00051 .add_device = ehci_add_device,
00052 };
00053
00054 static driver_t ehci_driver = {
00055 .name = NAME,
00056 .driver_ops = &ehci_driver_ops
00057 };
00058 static ddf_dev_ops_t hc_ops = {
00059 .interfaces[USBHC_DEV_IFACE] = &ehci_hc_iface,
00060 };
00061
00062
00068 static int ehci_add_device(ddf_dev_t *device)
00069 {
00070 assert(device);
00071 #define CHECK_RET_RETURN(ret, message...) \
00072 if (ret != EOK) { \
00073 usb_log_error(message); \
00074 return ret; \
00075 }
00076
00077 uintptr_t reg_base = 0;
00078 size_t reg_size = 0;
00079 int irq = 0;
00080
00081 int ret = pci_get_my_registers(device, ®_base, ®_size, &irq);
00082 CHECK_RET_RETURN(ret,
00083 "Failed to get memory addresses for %" PRIun ": %s.\n",
00084 device->handle, str_error(ret));
00085 usb_log_info("Memory mapped regs at 0x%" PRIxn " (size %zu), IRQ %d.\n",
00086 reg_base, reg_size, irq);
00087
00088 ret = pci_disable_legacy(device, reg_base, reg_size, irq);
00089 CHECK_RET_RETURN(ret,
00090 "Failed to disable legacy USB: %s.\n", str_error(ret));
00091
00092 ddf_fun_t *hc_fun = ddf_fun_create(device, fun_exposed, "ehci-hc");
00093 if (hc_fun == NULL) {
00094 usb_log_error("Failed to create EHCI function.\n");
00095 return ENOMEM;
00096 }
00097 hc_fun->ops = &hc_ops;
00098
00099 ret = ddf_fun_bind(hc_fun);
00100 CHECK_RET_RETURN(ret,
00101 "Failed to bind EHCI function: %s.\n",
00102 str_error(ret));
00103 ret = ddf_fun_add_to_class(hc_fun, USB_HC_DDF_CLASS_NAME);
00104 CHECK_RET_RETURN(ret,
00105 "Failed to add EHCI to HC class: %s.\n",
00106 str_error(ret));
00107
00108 usb_log_info("Controlling new EHCI device `%s' (handle %" PRIun ").\n",
00109 device->name, device->handle);
00110
00111 return EOK;
00112 #undef CHECK_RET_RETURN
00113 }
00114
00123 int main(int argc, char *argv[])
00124 {
00125 usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
00126 return ddf_driver_main(&ehci_driver);
00127 }