Changes in uspace/drv/ohci/ohci.c [561112f:d2bff2f] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/ohci.c
r561112f rd2bff2f 44 44 #include "iface.h" 45 45 #include "pci.h" 46 #include "hc.h" 47 #include "root_hub.h" 48 49 typedef struct ohci { 50 ddf_fun_t *hc_fun; 51 ddf_fun_t *rh_fun; 52 53 hc_t hc; 54 rh_t rh; 55 } ohci_t; 56 57 static inline ohci_t * dev_to_ohci(ddf_dev_t *dev) 58 { 59 assert(dev); 60 assert(dev->driver_data); 61 return dev->driver_data; 62 } 46 63 47 64 /** IRQ handling callback, identifies device … … 53 70 static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call) 54 71 { 55 assert(dev); 56 hc_t *hc = &((ohci_t*)dev->driver_data)->hc; 57 uint16_t status = IPC_GET_ARG1(*call); 72 hc_t *hc = &dev_to_ohci(dev)->hc; 58 73 assert(hc); 74 const uint16_t status = IPC_GET_ARG1(*call); 59 75 hc_interrupt(hc, status); 60 76 } … … 70 86 { 71 87 assert(fun); 72 usb_device_keeper_t *manager = & ((ohci_t*)fun->dev->driver_data)->hc.manager;88 usb_device_keeper_t *manager = &dev_to_ohci(fun->dev)->hc.manager; 73 89 74 90 usb_address_t addr = usb_device_keeper_find(manager, handle); … … 93 109 ddf_fun_t *fun, devman_handle_t *handle) 94 110 { 95 assert(handle); 96 ddf_fun_t *hc_fun = ((ohci_t*)fun->dev->driver_data)->hc_fun; 97 assert(hc_fun != NULL); 98 99 *handle = hc_fun->handle; 111 assert(fun); 112 ddf_fun_t *hc_fun = dev_to_ohci(fun->dev)->hc_fun; 113 assert(hc_fun); 114 115 if (handle != NULL) 116 *handle = hc_fun->handle; 100 117 return EOK; 101 118 } 102 119 /*----------------------------------------------------------------------------*/ 103 /** This iface is generic for both RH and HC.*/120 /** Root hub USB interface */ 104 121 static usb_iface_t usb_iface = { 105 122 .get_hc_handle = usb_iface_get_hc_handle, … … 107 124 }; 108 125 /*----------------------------------------------------------------------------*/ 126 /** Standard USB HC options (HC interface) */ 109 127 static ddf_dev_ops_t hc_ops = { 110 128 .interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */ 111 129 }; 112 130 /*----------------------------------------------------------------------------*/ 131 /** Standard USB RH options (RH interface) */ 113 132 static ddf_dev_ops_t rh_ops = { 114 133 .interfaces[USB_DEV_IFACE] = &usb_iface, … … 117 136 /** Initialize hc and rh ddf structures and their respective drivers. 118 137 * 138 * @param[in] device DDF instance of the device to use. 119 139 * @param[in] instance OHCI structure to use. 120 * @param[in] device DDF instance of the device to use.121 140 * 122 141 * This function does all the preparatory work for hc and rh drivers: … … 126 145 * - registers interrupt handler 127 146 */ 128 int ohci_init(ohci_t *instance, ddf_dev_t *device) 129 { 130 assert(instance); 131 instance->hc_fun = NULL; 147 int device_setup_ohci(ddf_dev_t *device) 148 { 149 ohci_t *instance = malloc(sizeof(ohci_t)); 150 if (instance == NULL) { 151 usb_log_error("Failed to allocate OHCI driver.\n"); 152 return ENOMEM; 153 } 154 155 #define CHECK_RET_DEST_FREE_RETURN(ret, message...) \ 156 if (ret != EOK) { \ 157 if (instance->hc_fun) { \ 158 instance->hc_fun->ops = NULL; \ 159 instance->hc_fun->driver_data = NULL; \ 160 ddf_fun_destroy(instance->hc_fun); \ 161 } \ 162 if (instance->rh_fun) { \ 163 instance->rh_fun->ops = NULL; \ 164 instance->rh_fun->driver_data = NULL; \ 165 ddf_fun_destroy(instance->rh_fun); \ 166 } \ 167 free(instance); \ 168 usb_log_error(message); \ 169 return ret; \ 170 } else (void)0 171 132 172 instance->rh_fun = NULL; 133 #define CHECK_RET_DEST_FUN_RETURN(ret, message...) \ 134 if (ret != EOK) { \ 135 usb_log_error(message); \ 136 if (instance->hc_fun) \ 137 ddf_fun_destroy(instance->hc_fun); \ 138 if (instance->rh_fun) \ 139 ddf_fun_destroy(instance->rh_fun); \ 140 return ret; \ 141 } 142 143 uintptr_t mem_reg_base = 0; 144 size_t mem_reg_size = 0; 173 instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci-hc"); 174 int ret = instance->hc_fun ? EOK : ENOMEM; 175 CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create OHCI HC function.\n"); 176 instance->hc_fun->ops = &hc_ops; 177 instance->hc_fun->driver_data = &instance->hc; 178 179 instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci-rh"); 180 ret = instance->rh_fun ? EOK : ENOMEM; 181 CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create OHCI RH function.\n"); 182 instance->rh_fun->ops = &rh_ops; 183 184 uintptr_t reg_base = 0; 185 size_t reg_size = 0; 145 186 int irq = 0; 146 187 147 int ret = 148 pci_get_my_registers(device, &mem_reg_base, &mem_reg_size, &irq); 149 CHECK_RET_DEST_FUN_RETURN(ret, 188 ret = pci_get_my_registers(device, ®_base, ®_size, &irq); 189 CHECK_RET_DEST_FREE_RETURN(ret, 150 190 "Failed to get memory addresses for %" PRIun ": %s.\n", 151 191 device->handle, str_error(ret)); 152 192 usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n", 153 (void *) mem_reg_base, mem_reg_size, irq); 154 155 ret = pci_disable_legacy(device); 156 CHECK_RET_DEST_FUN_RETURN(ret, 157 "Failed(%d) to disable legacy USB: %s.\n", ret, str_error(ret)); 193 (void *) reg_base, reg_size, irq); 158 194 159 195 bool interrupts = false; 160 196 #ifdef CONFIG_USBHC_NO_INTERRUPTS 161 usb_log_warning("Interrupts disabled in OS config, " \197 usb_log_warning("Interrupts disabled in OS config, " 162 198 "falling back to polling.\n"); 163 199 #else … … 166 202 usb_log_warning("Failed to enable interrupts: %s.\n", 167 203 str_error(ret)); 168 usb_log_info("HW interrupts not available, " \204 usb_log_info("HW interrupts not available, " 169 205 "falling back to polling.\n"); 170 206 } else { … … 174 210 #endif 175 211 176 instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci-hc"); 177 ret = (instance->hc_fun == NULL) ? ENOMEM : EOK; 178 CHECK_RET_DEST_FUN_RETURN(ret, 179 "Failed(%d) to create HC function.\n", ret); 180 181 ret = hc_init(&instance->hc, instance->hc_fun, device, 182 mem_reg_base, mem_reg_size, interrupts); 183 CHECK_RET_DEST_FUN_RETURN(ret, "Failed(%d) to init ohci-hcd.\n", ret); 184 instance->hc_fun->ops = &hc_ops; 185 instance->hc_fun->driver_data = &instance->hc; 186 ret = ddf_fun_bind(instance->hc_fun); 187 CHECK_RET_DEST_FUN_RETURN(ret, 188 "Failed(%d) to bind OHCI device function: %s.\n", 189 ret, str_error(ret)); 190 #undef CHECK_RET_HC_RETURN 212 ret = hc_init(&instance->hc, reg_base, reg_size, interrupts); 213 CHECK_RET_DEST_FREE_RETURN(ret, "Failed(%d) to init ohci-hcd.\n", ret); 191 214 192 215 #define CHECK_RET_FINI_RETURN(ret, message...) \ 193 216 if (ret != EOK) { \ 194 usb_log_error(message); \195 if (instance->hc_fun) \196 ddf_fun_destroy(instance->hc_fun); \197 if (instance->rh_fun) \198 ddf_fun_destroy(instance->rh_fun); \199 217 hc_fini(&instance->hc); \ 200 return ret; \201 } 218 CHECK_RET_DEST_FREE_RETURN(ret, message); \ 219 } else (void)0 202 220 203 221 /* It does no harm if we register this on polling */ … … 207 225 "Failed(%d) to register interrupt handler.\n", ret); 208 226 209 instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci-rh"); 210 ret = (instance->rh_fun == NULL) ? ENOMEM : EOK; 227 ret = ddf_fun_bind(instance->hc_fun); 211 228 CHECK_RET_FINI_RETURN(ret, 212 "Failed(%d) to create root hub function.\n", ret); 213 229 "Failed(%d) to bind OHCI device function: %s.\n", 230 ret, str_error(ret)); 231 232 device->driver_data = instance; 233 234 hc_start_hw(&instance->hc); 214 235 hc_register_hub(&instance->hc, instance->rh_fun); 215 216 instance->rh_fun->ops = &rh_ops;217 instance->rh_fun->driver_data = NULL;218 ret = ddf_fun_bind(instance->rh_fun);219 CHECK_RET_FINI_RETURN(ret,220 "Failed(%d) to register OHCI root hub.\n", ret);221 222 236 return EOK; 237 238 #undef CHECK_RET_DEST_FUN_RETURN 223 239 #undef CHECK_RET_FINI_RETURN 224 240 }
Note:
See TracChangeset
for help on using the changeset viewer.