Changes in uspace/drv/bus/usb/ohci/ohci.c [56fd7cf:8820544] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/ohci.c
r56fd7cf r8820544 34 34 */ 35 35 36 /* XXX Fix this */37 #define _DDF_DATA_IMPLANT38 39 36 #include <errno.h> 40 37 #include <str_error.h> … … 62 59 /** IRQ handling callback, identifies device 63 60 * 64 * @param[in] dev DDF instance of the device to use.65 61 * @param[in] iid (Unused). 66 62 * @param[in] call Pointer to the call that represents interrupt. 67 */ 68 static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call) 63 * @param[in] dev DDF instance of the device to use. 64 * 65 */ 66 static void irq_handler(ipc_callid_t iid, ipc_call_t *call, ddf_dev_t *dev) 69 67 { 70 68 assert(dev); 71 69 72 70 ohci_t *ohci = dev_to_ohci(dev); 73 71 if (!ohci) { … … 75 73 return; 76 74 } 75 77 76 const uint16_t status = IPC_GET_ARG1(*call); 78 77 hc_interrupt(&ohci->hc, status); … … 143 142 int device_setup_ohci(ddf_dev_t *device) 144 143 { 144 bool ih_registered = false; 145 bool hc_inited = false; 146 int rc; 147 145 148 if (device == NULL) 146 149 return EBADMEM; … … 152 155 } 153 156 154 #define CHECK_RET_DEST_FREE_RETURN(ret, message...) \155 if (ret != EOK) { \156 if (instance->hc_fun) { \157 ddf_fun_destroy(instance->hc_fun); \158 } \159 if (instance->rh_fun) { \160 ddf_fun_destroy(instance->rh_fun); \161 } \162 usb_log_error(message); \163 return ret; \164 } else (void)0165 166 157 instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci_hc"); 167 int ret = instance->hc_fun ? EOK : ENOMEM; 168 CHECK_RET_DEST_FREE_RETURN(ret, 169 "Failed to create OHCI HC function: %s.\n", str_error(ret)); 158 if (instance->hc_fun == NULL) { 159 usb_log_error("Failed to create OHCI HC function: %s.\n", 160 str_error(ENOMEM)); 161 rc = ENOMEM; 162 goto error; 163 } 164 170 165 ddf_fun_set_ops(instance->hc_fun, &hc_ops); 171 ddf_fun_data_implant(instance->hc_fun, &instance->hc);172 166 173 167 instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci_rh"); 174 ret = instance->rh_fun ? EOK : ENOMEM; 175 CHECK_RET_DEST_FREE_RETURN(ret, 176 "Failed to create OHCI RH function: %s.\n", str_error(ret)); 168 if (instance->rh_fun == NULL) { 169 usb_log_error("Failed to create OHCI RH function: %s.\n", 170 str_error(ENOMEM)); 171 rc = ENOMEM; 172 goto error; 173 } 174 177 175 ddf_fun_set_ops(instance->rh_fun, &rh_ops); 178 176 179 uintptr_t reg_base = 0; 180 size_t reg_size = 0; 177 addr_range_t regs; 181 178 int irq = 0; 182 179 183 ret = get_my_registers(device, ®_base, ®_size, &irq); 184 CHECK_RET_DEST_FREE_RETURN(ret, 185 "Failed to get register memory addresses for %" PRIun ": %s.\n", 186 ddf_dev_get_handle(device), str_error(ret)); 180 rc = get_my_registers(device, ®s, &irq); 181 if (rc != EOK) { 182 usb_log_error("Failed to get register memory addresses " 183 "for %" PRIun ": %s.\n", ddf_dev_get_handle(device), 184 str_error(rc)); 185 goto error; 186 } 187 187 188 usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n", 188 (void *) reg_base, reg_size, irq); 189 190 const size_t ranges_count = hc_irq_pio_range_count(); 191 const size_t cmds_count = hc_irq_cmd_count(); 192 irq_pio_range_t irq_ranges[ranges_count]; 193 irq_cmd_t irq_cmds[cmds_count]; 194 irq_code_t irq_code = { 195 .rangecount = ranges_count, 196 .ranges = irq_ranges, 197 .cmdcount = cmds_count, 198 .cmds = irq_cmds 199 }; 200 201 ret = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds, 202 sizeof(irq_cmds), reg_base, reg_size); 203 CHECK_RET_DEST_FREE_RETURN(ret, 204 "Failed to generate IRQ code: %s.\n", str_error(ret)); 205 206 207 /* Register handler to avoid interrupt lockup */ 208 ret = register_interrupt_handler(device, irq, irq_handler, &irq_code); 209 CHECK_RET_DEST_FREE_RETURN(ret, 210 "Failed to register interrupt handler: %s.\n", str_error(ret)); 189 RNGABSPTR(regs), RNGSZ(regs), irq); 190 191 rc = hc_register_irq_handler(device, ®s, irq, irq_handler); 192 if (rc != EOK) { 193 usb_log_error("Failed to register interrupt handler: %s.\n", 194 str_error(rc)); 195 goto error; 196 } 197 198 ih_registered = true; 211 199 212 200 /* Try to enable interrupts */ 213 201 bool interrupts = false; 214 r et= enable_interrupts(device);215 if (r et!= EOK) {202 rc = enable_interrupts(device); 203 if (rc != EOK) { 216 204 usb_log_warning("Failed to enable interrupts: %s." 217 " Falling back to polling\n", str_error(r et));205 " Falling back to polling\n", str_error(rc)); 218 206 /* We don't need that handler */ 219 207 unregister_interrupt_handler(device, irq); 208 ih_registered = false; 220 209 } else { 221 210 usb_log_debug("Hw interrupts enabled.\n"); … … 223 212 } 224 213 225 ret = hc_init(&instance->hc, reg_base, reg_size, interrupts); 226 CHECK_RET_DEST_FREE_RETURN(ret, 227 "Failed to init ohci_hcd: %s.\n", str_error(ret)); 228 229 #define CHECK_RET_FINI_RETURN(ret, message...) \ 230 if (ret != EOK) { \ 231 hc_fini(&instance->hc); \ 232 unregister_interrupt_handler(device, irq); \ 233 CHECK_RET_DEST_FREE_RETURN(ret, message); \ 234 } else (void)0 235 236 237 ret = ddf_fun_bind(instance->hc_fun); 238 CHECK_RET_FINI_RETURN(ret, 239 "Failed to bind OHCI device function: %s.\n", str_error(ret)); 240 241 ret = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY); 242 CHECK_RET_FINI_RETURN(ret, 243 "Failed to add OHCI to HC class: %s.\n", str_error(ret)); 244 245 ret = hc_register_hub(&instance->hc, instance->rh_fun); 246 CHECK_RET_FINI_RETURN(ret, 247 "Failed to register OHCI root hub: %s.\n", str_error(ret)); 248 return ret; 249 250 #undef CHECK_RET_FINI_RETURN 214 rc = hc_init(&instance->hc, instance->hc_fun, ®s, interrupts); 215 if (rc != EOK) { 216 usb_log_error("Failed to init ohci_hcd: %s.\n", str_error(rc)); 217 goto error; 218 } 219 220 hc_inited = true; 221 222 rc = ddf_fun_bind(instance->hc_fun); 223 if (rc != EOK) { 224 usb_log_error("Failed to bind OHCI device function: %s.\n", 225 str_error(rc)); 226 goto error; 227 } 228 229 rc = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY); 230 if (rc != EOK) { 231 usb_log_error("Failed to add OHCI to HC category: %s.\n", 232 str_error(rc)); 233 goto error; 234 } 235 236 rc = hc_register_hub(&instance->hc, instance->rh_fun); 237 if (rc != EOK) { 238 usb_log_error("Failed to register OHCI root hub: %s.\n", 239 str_error(rc)); 240 goto error; 241 } 242 243 return EOK; 244 245 error: 246 if (hc_inited) 247 hc_fini(&instance->hc); 248 if (ih_registered) 249 unregister_interrupt_handler(device, irq); 250 if (instance->hc_fun != NULL) 251 ddf_fun_destroy(instance->hc_fun); 252 if (instance->rh_fun != NULL) 253 ddf_fun_destroy(instance->rh_fun); 254 return rc; 251 255 } 252 256 /**
Note:
See TracChangeset
for help on using the changeset viewer.