Changes in uspace/drv/uhci-hcd/main.c [b375bb8:357a302] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-hcd/main.c
rb375bb8 r357a302 32 32 * @brief UHCI driver 33 33 */ 34 #include <d df/driver.h>35 #include < ddf/interrupt.h>36 #include <device/hw_res.h> 34 #include <driver.h> 35 #include <usb_iface.h> 36 37 37 #include <errno.h> 38 #include <str_error.h>39 38 40 #include <usb_iface.h>41 #include <usb/ddfiface.h>42 39 #include <usb/debug.h> 43 40 … … 49 46 #define NAME "uhci-hcd" 50 47 51 static int uhci_add_device(ddf_dev_t *device); 52 /*----------------------------------------------------------------------------*/ 48 static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle) 49 { 50 /* This shall be called only for the UHCI itself. */ 51 assert(dev->parent == NULL); 52 53 *handle = dev->handle; 54 return EOK; 55 } 56 57 static int usb_iface_get_address(device_t *dev, devman_handle_t handle, 58 usb_address_t *address) 59 { 60 assert(dev); 61 uhci_t *hc = dev_to_uhci(dev); 62 assert(hc); 63 64 usb_address_t addr = usb_address_keeping_find(&hc->address_manager, 65 handle); 66 if (addr < 0) { 67 return addr; 68 } 69 70 if (address != NULL) { 71 *address = addr; 72 } 73 74 return EOK; 75 } 76 77 static usb_iface_t hc_usb_iface = { 78 .get_hc_handle = usb_iface_get_hc_handle, 79 .get_address = usb_iface_get_address 80 }; 81 82 static device_ops_t uhci_ops = { 83 .interfaces[USB_DEV_IFACE] = &hc_usb_iface, 84 .interfaces[USBHC_DEV_IFACE] = &uhci_iface 85 }; 86 87 static int uhci_add_device(device_t *device) 88 { 89 assert(device); 90 91 usb_log_info("uhci_add_device() called\n"); 92 device->ops = &uhci_ops; 93 94 uintptr_t io_reg_base; 95 size_t io_reg_size; 96 int irq; 97 98 int rc = pci_get_my_registers(device, 99 &io_reg_base, &io_reg_size, &irq); 100 101 if (rc != EOK) { 102 usb_log_error("Failed(%d) to get I/O registers addresses for device:.\n", 103 rc, device->handle); 104 return rc; 105 } 106 107 usb_log_info("I/O regs at 0x%X (size %zu), IRQ %d.\n", 108 io_reg_base, io_reg_size, irq); 109 110 uhci_t *uhci_hc = malloc(sizeof(uhci_t)); 111 if (!uhci_hc) { 112 usb_log_error("Failed to allocaete memory for uhci hcd driver.\n"); 113 return ENOMEM; 114 } 115 116 int ret = uhci_init(uhci_hc, (void*)io_reg_base, io_reg_size); 117 if (ret != EOK) { 118 usb_log_error("Failed to init uhci-hcd.\n"); 119 return ret; 120 } 121 device_t *rh; 122 ret = setup_root_hub(&rh, device); 123 124 if (ret != EOK) { 125 usb_log_error("Failed to setup uhci root hub.\n"); 126 /* TODO: destroy uhci here */ 127 return ret; 128 } 129 130 ret = child_device_register(rh, device); 131 if (ret != EOK) { 132 usb_log_error("Failed to register root hub.\n"); 133 /* TODO: destroy uhci here */ 134 return ret; 135 } 136 137 device->driver_data = uhci_hc; 138 139 return EOK; 140 } 141 53 142 static driver_ops_t uhci_driver_ops = { 54 143 .add_device = uhci_add_device, 55 144 }; 56 /*----------------------------------------------------------------------------*/ 145 57 146 static driver_t uhci_driver = { 58 147 .name = NAME, 59 148 .driver_ops = &uhci_driver_ops 60 149 }; 61 /*----------------------------------------------------------------------------*/62 static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)63 {64 assert(dev);65 uhci_t *hc = dev_to_uhci(dev);66 uint16_t status = IPC_GET_ARG1(*call);67 assert(hc);68 uhci_interrupt(hc, status);69 }70 /*----------------------------------------------------------------------------*/71 static int uhci_add_device(ddf_dev_t *device)72 {73 assert(device);74 uhci_t *hcd = NULL;75 #define CHECK_RET_FREE_HC_RETURN(ret, message...) \76 if (ret != EOK) { \77 usb_log_error(message); \78 if (hcd != NULL) \79 free(hcd); \80 return ret; \81 }82 150 83 usb_log_info("uhci_add_device() called\n");84 85 uintptr_t io_reg_base = 0;86 size_t io_reg_size = 0;87 int irq = 0;88 89 int ret =90 pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq);91 CHECK_RET_FREE_HC_RETURN(ret,92 "Failed(%d) to get I/O addresses:.\n", ret, device->handle);93 usb_log_info("I/O regs at 0x%X (size %zu), IRQ %d.\n",94 io_reg_base, io_reg_size, irq);95 96 ret = pci_disable_legacy(device);97 CHECK_RET_FREE_HC_RETURN(ret,98 "Failed(%d) disable legacy USB: %s.\n", ret, str_error(ret));99 100 #if 0101 ret = pci_enable_interrupts(device);102 if (ret != EOK) {103 usb_log_warning(104 "Failed(%d) to enable interrupts, fall back to polling.\n",105 ret);106 }107 #endif108 109 hcd = malloc(sizeof(uhci_t));110 ret = (hcd != NULL) ? EOK : ENOMEM;111 CHECK_RET_FREE_HC_RETURN(ret,112 "Failed(%d) to allocate memory for uhci hcd.\n", ret);113 114 ret = uhci_init(hcd, device, (void*)io_reg_base, io_reg_size);115 CHECK_RET_FREE_HC_RETURN(ret, "Failed(%d) to init uhci-hcd.\n",116 ret);117 #undef CHECK_RET_FREE_HC_RETURN118 119 /*120 * We might free hcd, but that does not matter since no one121 * else would access driver_data anyway.122 */123 device->driver_data = hcd;124 125 ddf_fun_t *rh = NULL;126 #define CHECK_RET_FINI_FREE_RETURN(ret, message...) \127 if (ret != EOK) { \128 usb_log_error(message); \129 if (hcd != NULL) {\130 uhci_fini(hcd); \131 free(hcd); \132 } \133 if (rh != NULL) \134 free(rh); \135 return ret; \136 }137 138 /* It does no harm if we register this on polling */139 ret = register_interrupt_handler(device, irq, irq_handler,140 &hcd->interrupt_code);141 CHECK_RET_FINI_FREE_RETURN(ret,142 "Failed(%d) to register interrupt handler.\n", ret);143 144 ret = setup_root_hub(&rh, device);145 CHECK_RET_FINI_FREE_RETURN(ret,146 "Failed(%d) to setup UHCI root hub.\n", ret);147 rh->driver_data = hcd->ddf_instance;148 149 ret = ddf_fun_bind(rh);150 CHECK_RET_FINI_FREE_RETURN(ret,151 "Failed(%d) to register UHCI root hub.\n", ret);152 153 return EOK;154 #undef CHECK_RET_FINI_FREE_RETURN155 }156 /*----------------------------------------------------------------------------*/157 151 int main(int argc, char *argv[]) 158 152 { 159 sleep(3); 160 usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME); 153 /* 154 * Do some global initializations. 155 */ 156 sleep(5); 157 usb_log_enable(USB_LOG_LEVEL_INFO, NAME); 161 158 162 return d df_driver_main(&uhci_driver);159 return driver_main(&uhci_driver); 163 160 } 164 161 /**
Note:
See TracChangeset
for help on using the changeset viewer.