Changeset 224174f in mainline for uspace/drv/bus/usb/uhci/uhci.c
- Timestamp:
- 2013-07-11T13:16:57Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2b3e8840, b2c96093
- Parents:
- 990ab7d (diff), 3a67d63 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/uhci/uhci.c
r990ab7d r224174f 38 38 39 39 #include <errno.h> 40 #include <stdbool.h> 40 41 #include <str_error.h> 41 42 #include <ddf/interrupt.h> … … 149 150 int device_setup_uhci(ddf_dev_t *device) 150 151 { 152 bool ih_registered = false; 153 bool hc_inited = false; 154 bool fun_bound = false; 155 int rc; 156 151 157 if (!device) 152 158 return EBADMEM; … … 158 164 } 159 165 160 #define CHECK_RET_DEST_FREE_RETURN(ret, message...) \161 if (ret != EOK) { \162 if (instance->hc_fun) \163 ddf_fun_destroy(instance->hc_fun); \164 if (instance->rh_fun) {\165 ddf_fun_destroy(instance->rh_fun); \166 } \167 usb_log_error(message); \168 return ret; \169 } else (void)0170 171 instance->rh_fun = NULL;172 166 instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci_hc"); 173 int ret = (instance->hc_fun == NULL) ? ENOMEM : EOK; 174 CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI HC function.\n"); 167 if (instance->hc_fun == NULL) { 168 usb_log_error("Failed to create UHCI HC function.\n"); 169 rc = ENOMEM; 170 goto error; 171 } 172 175 173 ddf_fun_set_ops(instance->hc_fun, &hc_ops); 176 174 ddf_fun_data_implant(instance->hc_fun, &instance->hc.generic); 177 175 178 176 instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci_rh"); 179 ret = (instance->rh_fun == NULL) ? ENOMEM : EOK; 180 CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI RH function.\n"); 177 if (instance->rh_fun == NULL) { 178 usb_log_error("Failed to create UHCI RH function.\n"); 179 rc = ENOMEM; 180 goto error; 181 } 182 181 183 ddf_fun_set_ops(instance->rh_fun, &rh_ops); 182 184 ddf_fun_data_implant(instance->rh_fun, &instance->rh); … … 186 188 int irq = 0; 187 189 188 ret = get_my_registers(device, ®_base, ®_size, &irq); 189 CHECK_RET_DEST_FREE_RETURN(ret, 190 "Failed to get I/O addresses for %" PRIun ": %s.\n", 191 ddf_dev_get_handle(device), str_error(ret)); 190 rc = get_my_registers(device, ®_base, ®_size, &irq); 191 if (rc != EOK) { 192 usb_log_error("Failed to get I/O addresses for %" PRIun ": %s.\n", 193 ddf_dev_get_handle(device), str_error(rc)); 194 goto error; 195 } 192 196 usb_log_debug("I/O regs at 0x%p (size %zu), IRQ %d.\n", 193 197 (void *) reg_base, reg_size, irq); 194 198 195 ret = disable_legacy(device); 196 CHECK_RET_DEST_FREE_RETURN(ret, 197 "Failed to disable legacy USB: %s.\n", str_error(ret)); 198 199 const size_t ranges_count = hc_irq_pio_range_count(); 200 const size_t cmds_count = hc_irq_cmd_count(); 201 irq_pio_range_t irq_ranges[ranges_count]; 202 irq_cmd_t irq_cmds[cmds_count]; 203 ret = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds, 204 sizeof(irq_cmds), reg_base, reg_size); 205 CHECK_RET_DEST_FREE_RETURN(ret, 206 "Failed to generate IRQ commands: %s.\n", str_error(ret)); 207 208 irq_code_t irq_code = { 209 .rangecount = ranges_count, 210 .ranges = irq_ranges, 211 .cmdcount = cmds_count, 212 .cmds = irq_cmds 213 }; 214 215 /* Register handler to avoid interrupt lockup */ 216 ret = register_interrupt_handler(device, irq, irq_handler, &irq_code); 217 CHECK_RET_DEST_FREE_RETURN(ret, 218 "Failed to register interrupt handler: %s.\n", str_error(ret)); 199 rc = disable_legacy(device); 200 if (rc != EOK) { 201 usb_log_error("Failed to disable legacy USB: %s.\n", 202 str_error(rc)); 203 goto error; 204 } 205 206 rc = hc_register_irq_handler(device, reg_base, reg_size, irq, irq_handler); 207 if (rc != EOK) { 208 usb_log_error("Failed to register interrupt handler: %s.\n", 209 str_error(rc)); 210 goto error; 211 } 212 213 ih_registered = true; 219 214 220 215 bool interrupts = false; 221 r et= enable_interrupts(device);222 if (r et!= EOK) {216 rc = enable_interrupts(device); 217 if (rc != EOK) { 223 218 usb_log_warning("Failed to enable interrupts: %s." 224 " Falling back to polling.\n", str_error(r et));219 " Falling back to polling.\n", str_error(rc)); 225 220 } else { 226 221 usb_log_debug("Hw interrupts enabled.\n"); … … 228 223 } 229 224 230 ret = hc_init(&instance->hc, (void*)reg_base, reg_size, interrupts); 231 CHECK_RET_DEST_FREE_RETURN(ret, 232 "Failed to init uhci_hcd: %s.\n", str_error(ret)); 233 234 #define CHECK_RET_FINI_RETURN(ret, message...) \ 235 if (ret != EOK) { \ 236 hc_fini(&instance->hc); \ 237 CHECK_RET_DEST_FREE_RETURN(ret, message); \ 238 return ret; \ 239 } else (void)0 240 241 ret = ddf_fun_bind(instance->hc_fun); 242 CHECK_RET_FINI_RETURN(ret, "Failed to bind UHCI device function: %s.\n", 243 str_error(ret)); 244 245 ret = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY); 246 CHECK_RET_FINI_RETURN(ret, 247 "Failed to add UHCI to HC class: %s.\n", str_error(ret)); 248 249 ret = rh_init(&instance->rh, instance->rh_fun, 225 rc = hc_init(&instance->hc, (void*)reg_base, reg_size, interrupts); 226 if (rc != EOK) { 227 usb_log_error("Failed to init uhci_hcd: %s.\n", str_error(rc)); 228 goto error; 229 } 230 231 hc_inited = true; 232 233 rc = ddf_fun_bind(instance->hc_fun); 234 if (rc != EOK) { 235 usb_log_error("Failed to bind UHCI device function: %s.\n", 236 str_error(rc)); 237 goto error; 238 } 239 240 fun_bound = true; 241 242 rc = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY); 243 if (rc != EOK) { 244 usb_log_error("Failed to add UHCI to HC class: %s.\n", 245 str_error(rc)); 246 goto error; 247 } 248 249 rc = rh_init(&instance->rh, instance->rh_fun, 250 250 (uintptr_t)instance->hc.registers + 0x10, 4); 251 CHECK_RET_FINI_RETURN(ret, 252 "Failed to setup UHCI root hub: %s.\n", str_error(ret)); 253 254 ret = ddf_fun_bind(instance->rh_fun); 255 CHECK_RET_FINI_RETURN(ret, 256 "Failed to register UHCI root hub: %s.\n", str_error(ret)); 251 if (rc != EOK) { 252 usb_log_error("Failed to setup UHCI root hub: %s.\n", 253 str_error(rc)); 254 goto error; 255 } 256 257 rc = ddf_fun_bind(instance->rh_fun); 258 if (rc != EOK) { 259 usb_log_error("Failed to register UHCI root hub: %s.\n", 260 str_error(rc)); 261 goto error; 262 } 257 263 258 264 return EOK; 259 #undef CHECK_RET_FINI_RETURN 265 266 error: 267 if (fun_bound) 268 ddf_fun_unbind(instance->hc_fun); 269 if (hc_inited) 270 hc_fini(&instance->hc); 271 if (ih_registered) 272 unregister_interrupt_handler(device, irq); 273 if (instance->hc_fun != NULL) 274 ddf_fun_destroy(instance->hc_fun); 275 if (instance->rh_fun != NULL) { 276 ddf_fun_destroy(instance->rh_fun); 277 } 278 return rc; 260 279 } 261 280 /**
Note:
See TracChangeset
for help on using the changeset viewer.