Changeset cffa14e6 in mainline for uspace/drv/bus/usb/uhci
- Timestamp:
- 2013-07-24T17:27:56Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- db71e2a
- Parents:
- c442f63
- Location:
- uspace/drv/bus/usb/uhci
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/uhci/hc.c
rc442f63 rcffa14e6 90 90 static int hc_debug_checker(void *arg); 91 91 92 enum { 93 /** Number of PIO ranges used in IRQ code */ 94 hc_irq_pio_range_count = 95 sizeof(uhci_irq_pio_ranges) / sizeof(irq_pio_range_t), 96 97 /* Number of commands used in IRQ code */ 98 hc_irq_cmd_count = 99 sizeof(uhci_irq_commands) / sizeof(irq_cmd_t) 100 }; 92 93 /** Get number of PIO ranges used in IRQ code. 94 * @return Number of ranges. 95 */ 96 size_t hc_irq_pio_range_count(void) 97 { 98 return sizeof(uhci_irq_pio_ranges) / sizeof(irq_pio_range_t); 99 } 100 101 /** Get number of commands used in IRQ code. 102 * @return Number of commands. 103 */ 104 size_t hc_irq_cmd_count(void) 105 { 106 return sizeof(uhci_irq_commands) / sizeof(irq_cmd_t); 107 } 101 108 102 109 /** Generate IRQ code. … … 126 133 cmds[0].addr = ®isters->usbsts; 127 134 cmds[3].addr = ®isters->usbsts; 128 129 return EOK;130 }131 132 /** Register interrupt handler.133 *134 * @param[in] device Host controller DDF device135 * @param[in] reg_base Register range base136 * @param[in] reg_size Register range size137 * @param[in] irq Interrupt number138 * @paran[in] handler Interrupt handler139 *140 * @return EOK on success or negative error code141 */142 int hc_register_irq_handler(ddf_dev_t *device, uintptr_t reg_base, size_t reg_size,143 int irq, interrupt_handler_t handler)144 {145 int rc;146 irq_pio_range_t irq_ranges[hc_irq_pio_range_count];147 irq_cmd_t irq_cmds[hc_irq_cmd_count];148 rc = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds,149 sizeof(irq_cmds), reg_base, reg_size);150 if (rc != EOK) {151 usb_log_error("Failed to generate IRQ commands: %s.\n",152 str_error(rc));153 return rc;154 }155 156 irq_code_t irq_code = {157 .rangecount = hc_irq_pio_range_count,158 .ranges = irq_ranges,159 .cmdcount = hc_irq_cmd_count,160 .cmds = irq_cmds161 };162 163 /* Register handler to avoid interrupt lockup */164 rc = register_interrupt_handler(device, irq, handler, &irq_code);165 if (rc != EOK) {166 usb_log_error("Failed to register interrupt handler: %s.\n",167 str_error(rc));168 return rc;169 }170 135 171 136 return EOK; … … 244 209 { 245 210 assert(reg_size >= sizeof(uhci_regs_t)); 246 int rc; 211 int ret; 212 213 #define CHECK_RET_RETURN(ret, message...) \ 214 if (ret != EOK) { \ 215 usb_log_error(message); \ 216 return ret; \ 217 } else (void) 0 247 218 248 219 instance->hw_interrupts = interrupts; … … 251 222 /* allow access to hc control registers */ 252 223 uhci_regs_t *io; 253 rc = pio_enable(regs, reg_size, (void **)&io); 254 if (rc != EOK) { 255 usb_log_error("Failed to gain access to registers at %p: %s.\n", 256 io, str_error(rc)); 257 return rc; 258 } 259 224 ret = pio_enable(regs, reg_size, (void **)&io); 225 CHECK_RET_RETURN(ret, "Failed to gain access to registers at %p: %s.\n", 226 io, str_error(ret)); 260 227 instance->registers = io; 261 228 usb_log_debug( 262 229 "Device registers at %p (%zuB) accessible.\n", io, reg_size); 263 230 264 r c= hc_init_mem_structures(instance);265 if (rc != EOK) {266 usb_log_error("Failed to initialize UHCI memory structures: %s.\n",267 str_error(rc));268 return rc; 269 } 231 ret = hc_init_mem_structures(instance); 232 CHECK_RET_RETURN(ret, 233 "Failed to initialize UHCI memory structures: %s.\n", 234 str_error(ret)); 235 236 #undef CHECK_RET_RETURN 270 237 271 238 hcd_init(&instance->generic, USB_SPEED_FULL, … … 430 397 431 398 return EOK; 399 #undef CHECK_RET_CLEAR_RETURN 432 400 } 433 401 -
uspace/drv/bus/usb/uhci/hc.h
rc442f63 rcffa14e6 36 36 #define DRV_UHCI_HC_H 37 37 38 #include <ddf/interrupt.h>39 38 #include <fibril.h> 40 39 #include <usb/host/hcd.h> … … 120 119 } hc_t; 121 120 122 int hc_register_irq_handler(ddf_dev_t *, uintptr_t, size_t, int, interrupt_handler_t); 121 size_t hc_irq_pio_range_count(void); 122 size_t hc_irq_cmd_count(void); 123 123 int hc_get_irq_code(irq_pio_range_t [], size_t, irq_cmd_t [], size_t, uintptr_t, 124 124 size_t); -
uspace/drv/bus/usb/uhci/uhci.c
rc442f63 rcffa14e6 38 38 39 39 #include <errno.h> 40 #include <stdbool.h>41 40 #include <str_error.h> 42 41 #include <ddf/interrupt.h> … … 150 149 int device_setup_uhci(ddf_dev_t *device) 151 150 { 152 bool ih_registered = false;153 bool hc_inited = false;154 bool fun_bound = false;155 int rc;156 157 151 if (!device) 158 152 return EBADMEM; … … 164 158 } 165 159 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)0 170 171 instance->rh_fun = NULL; 166 172 instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci_hc"); 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 173 int ret = (instance->hc_fun == NULL) ? ENOMEM : EOK; 174 CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI HC function.\n"); 173 175 ddf_fun_set_ops(instance->hc_fun, &hc_ops); 174 176 ddf_fun_data_implant(instance->hc_fun, &instance->hc.generic); 175 177 176 178 instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci_rh"); 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 179 ret = (instance->rh_fun == NULL) ? ENOMEM : EOK; 180 CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI RH function.\n"); 183 181 ddf_fun_set_ops(instance->rh_fun, &rh_ops); 184 182 ddf_fun_data_implant(instance->rh_fun, &instance->rh); … … 188 186 int irq = 0; 189 187 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 } 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)); 196 192 usb_log_debug("I/O regs at 0x%p (size %zu), IRQ %d.\n", 197 193 (void *) reg_base, reg_size, irq); 198 194 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; 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)); 214 219 215 220 bool interrupts = false; 216 r c= enable_interrupts(device);217 if (r c!= EOK) {221 ret = enable_interrupts(device); 222 if (ret != EOK) { 218 223 usb_log_warning("Failed to enable interrupts: %s." 219 " Falling back to polling.\n", str_error(r c));224 " Falling back to polling.\n", str_error(ret)); 220 225 } else { 221 226 usb_log_debug("Hw interrupts enabled.\n"); … … 223 228 } 224 229 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, 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 250 (uintptr_t)instance->hc.registers + 0x10, 4); 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 } 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)); 263 257 264 258 return EOK; 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; 259 #undef CHECK_RET_FINI_RETURN 279 260 } 280 261 /**
Note:
See TracChangeset
for help on using the changeset viewer.
