Changes in uspace/drv/bus/usb/uhci/uhci.c [56fd7cf:5b89d43b] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/uhci/uhci.c
r56fd7cf r5b89d43b 38 38 39 39 #include <errno.h> 40 #include <stdbool.h> 40 41 #include <str_error.h> 41 42 #include <ddf/interrupt.h> … … 131 132 }; 132 133 134 static pio_window_t *get_pio_window(ddf_fun_t *fun) 135 { 136 rh_t *rh = ddf_fun_data_get(fun); 137 138 if (rh == NULL) 139 return NULL; 140 return &rh->pio_window; 141 } 142 143 static pio_window_ops_t pio_window_iface = { 144 .get_pio_window = get_pio_window 145 }; 146 133 147 /** RH function support for uhci_rhd */ 134 148 static ddf_dev_ops_t rh_ops = { 135 149 .interfaces[USB_DEV_IFACE] = &usb_iface, 136 .interfaces[HW_RES_DEV_IFACE] = &hw_res_iface 150 .interfaces[HW_RES_DEV_IFACE] = &hw_res_iface, 151 .interfaces[PIO_WINDOW_DEV_IFACE] = &pio_window_iface 137 152 }; 138 153 … … 149 164 int device_setup_uhci(ddf_dev_t *device) 150 165 { 166 bool ih_registered = false; 167 bool hc_inited = false; 168 bool fun_bound = false; 169 int rc; 170 151 171 if (!device) 152 172 return EBADMEM; … … 158 178 } 159 179 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 180 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"); 181 if (instance->hc_fun == NULL) { 182 usb_log_error("Failed to create UHCI HC function.\n"); 183 rc = ENOMEM; 184 goto error; 185 } 186 175 187 ddf_fun_set_ops(instance->hc_fun, &hc_ops); 176 188 ddf_fun_data_implant(instance->hc_fun, &instance->hc.generic); 177 189 178 190 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"); 191 if (instance->rh_fun == NULL) { 192 usb_log_error("Failed to create UHCI RH function.\n"); 193 rc = ENOMEM; 194 goto error; 195 } 196 181 197 ddf_fun_set_ops(instance->rh_fun, &rh_ops); 182 198 ddf_fun_data_implant(instance->rh_fun, &instance->rh); 183 199 184 uintptr_t reg_base = 0; 185 size_t reg_size = 0; 200 addr_range_t regs; 186 201 int irq = 0; 187 202 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)); 192 usb_log_debug("I/O regs at 0x%p (size %zu), IRQ %d.\n", 193 (void *) reg_base, reg_size, irq); 194 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)); 203 rc = get_my_registers(device, ®s, &irq); 204 if (rc != EOK) { 205 usb_log_error("Failed to get I/O addresses for %" PRIun ": %s.\n", 206 ddf_dev_get_handle(device), str_error(rc)); 207 goto error; 208 } 209 usb_log_debug("I/O regs at %p (size %zu), IRQ %d.\n", 210 RNGABSPTR(regs), RNGSZ(regs), irq); 211 212 rc = disable_legacy(device); 213 if (rc != EOK) { 214 usb_log_error("Failed to disable legacy USB: %s.\n", 215 str_error(rc)); 216 goto error; 217 } 218 219 rc = hc_register_irq_handler(device, ®s, irq, irq_handler); 220 if (rc != EOK) { 221 usb_log_error("Failed to register interrupt handler: %s.\n", 222 str_error(rc)); 223 goto error; 224 } 225 226 ih_registered = true; 219 227 220 228 bool interrupts = false; 221 r et= enable_interrupts(device);222 if (r et!= EOK) {229 rc = enable_interrupts(device); 230 if (rc != EOK) { 223 231 usb_log_warning("Failed to enable interrupts: %s." 224 " Falling back to polling.\n", str_error(r et));232 " Falling back to polling.\n", str_error(rc)); 225 233 } else { 226 234 usb_log_debug("Hw interrupts enabled.\n"); … … 228 236 } 229 237 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, 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)); 238 rc = hc_init(&instance->hc, ®s, interrupts); 239 if (rc != EOK) { 240 usb_log_error("Failed to init uhci_hcd: %s.\n", str_error(rc)); 241 goto error; 242 } 243 244 hc_inited = true; 245 246 rc = ddf_fun_bind(instance->hc_fun); 247 if (rc != EOK) { 248 usb_log_error("Failed to bind UHCI device function: %s.\n", 249 str_error(rc)); 250 goto error; 251 } 252 253 fun_bound = true; 254 255 rc = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY); 256 if (rc != EOK) { 257 usb_log_error("Failed to add UHCI to HC class: %s.\n", 258 str_error(rc)); 259 goto error; 260 } 261 262 rc = rh_init(&instance->rh, instance->rh_fun, ®s, 0x10, 4); 263 if (rc != EOK) { 264 usb_log_error("Failed to setup UHCI root hub: %s.\n", 265 str_error(rc)); 266 goto error; 267 } 268 269 rc = ddf_fun_bind(instance->rh_fun); 270 if (rc != EOK) { 271 usb_log_error("Failed to register UHCI root hub: %s.\n", 272 str_error(rc)); 273 goto error; 274 } 257 275 258 276 return EOK; 259 #undef CHECK_RET_FINI_RETURN 277 278 error: 279 if (fun_bound) 280 ddf_fun_unbind(instance->hc_fun); 281 if (hc_inited) 282 hc_fini(&instance->hc); 283 if (ih_registered) 284 unregister_interrupt_handler(device, irq); 285 if (instance->hc_fun != NULL) 286 ddf_fun_destroy(instance->hc_fun); 287 if (instance->rh_fun != NULL) { 288 ddf_fun_destroy(instance->rh_fun); 289 } 290 return rc; 260 291 } 261 292 /**
Note:
See TracChangeset
for help on using the changeset viewer.