Changeset c53007f in mainline
- Timestamp:
- 2013-07-07T11:53:22Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d930980
- Parents:
- f83666c
- Location:
- uspace/drv/bus/usb
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/uhci/hc.c
rf83666c rc53007f 90 90 static int hc_debug_checker(void *arg); 91 91 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 } 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 }; 108 101 109 102 /** Generate IRQ code. … … 133 126 cmds[0].addr = ®isters->usbsts; 134 127 cmds[3].addr = ®isters->usbsts; 128 129 return EOK; 130 } 131 132 /** Register interrupt handler. 133 * 134 * @param[in] device Host controller DDF device 135 * @param[in] reg_base Register range base 136 * @param[in] reg_size Register range size 137 * @param[in] irq Interrupt number 138 * @paran[in] handler Interrupt handler 139 * 140 * @return EOK on success or negative error code 141 */ 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_cmds 161 }; 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 } 135 170 136 171 return EOK; … … 209 244 { 210 245 assert(reg_size >= sizeof(uhci_regs_t)); 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 246 int rc; 218 247 219 248 instance->hw_interrupts = interrupts; … … 222 251 /* allow access to hc control registers */ 223 252 uhci_regs_t *io; 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)); 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 227 260 instance->registers = io; 228 261 usb_log_debug( 229 262 "Device registers at %p (%zuB) accessible.\n", io, reg_size); 230 263 231 r et= hc_init_mem_structures(instance);232 CHECK_RET_RETURN(ret,233 234 str_error(ret));235 236 #undef CHECK_RET_RETURN 264 rc = 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 } 237 270 238 271 hcd_init(&instance->generic, USB_SPEED_FULL, -
uspace/drv/bus/usb/uhci/hc.h
rf83666c rc53007f 36 36 #define DRV_UHCI_HC_H 37 37 38 #include <ddf/interrupt.h> 38 39 #include <fibril.h> 39 40 #include <usb/host/hcd.h> … … 119 120 } hc_t; 120 121 121 size_t hc_irq_pio_range_count(void); 122 size_t hc_irq_cmd_count(void); 122 int hc_register_irq_handler(ddf_dev_t *, uintptr_t, size_t, int, interrupt_handler_t); 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
rf83666c rc53007f 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 /** -
uspace/drv/bus/usb/uhcirh/main.c
rf83666c rc53007f 93 93 size_t io_size = 0; 94 94 uhci_root_hub_t *rh = NULL; 95 int r et = EOK;95 int rc; 96 96 97 #define CHECK_RET_FREE_RH_RETURN(ret, message...) \ 98 if (ret != EOK) { \ 99 usb_log_error(message); \ 100 return ret; \ 101 } else (void)0 97 rc = hc_get_my_registers(device, &io_regs, &io_size); 98 if (rc != EOK) { 99 usb_log_error( "Failed to get registers from HC: %s.\n", 100 str_error(rc)); 101 return rc; 102 } 102 103 103 ret = hc_get_my_registers(device, &io_regs, &io_size);104 CHECK_RET_FREE_RH_RETURN(ret,105 "Failed to get registers from HC: %s.\n", str_error(ret));106 104 usb_log_debug("I/O regs at %p (size %zuB).\n", 107 105 (void *) io_regs, io_size); 108 106 109 107 rh = ddf_dev_data_alloc(device, sizeof(uhci_root_hub_t)); 110 ret = (rh == NULL) ? ENOMEM : EOK; 111 CHECK_RET_FREE_RH_RETURN(ret, 112 "Failed to allocate rh driver instance.\n"); 108 if (rh == NULL) { 109 usb_log_error("Failed to allocate rh driver instance.\n"); 110 return ENOMEM; 111 } 113 112 114 ret = uhci_root_hub_init(rh, (void*)io_regs, io_size, device); 115 CHECK_RET_FREE_RH_RETURN(ret, 116 "Failed(%d) to initialize rh driver instance: %s.\n", 117 ret, str_error(ret)); 113 rc = uhci_root_hub_init(rh, (void*)io_regs, io_size, device); 114 if (rc != EOK) { 115 usb_log_error("Failed(%d) to initialize rh driver instance: " 116 "%s.\n", rc, str_error(rc)); 117 return rc; 118 } 118 119 119 120 usb_log_info("Controlling root hub '%s' (%" PRIun ").\n", 120 121 ddf_dev_get_name(device), ddf_dev_get_handle(device)); 122 121 123 return EOK; 122 124 } -
uspace/drv/bus/usb/uhcirh/port.c
rf83666c rc53007f 150 150 { 151 151 uhci_port_t *instance = port; 152 int rc; 152 153 assert(instance); 153 154 154 155 unsigned allowed_failures = MAX_ERROR_COUNT; 155 #define CHECK_RET_FAIL(ret, msg...) \156 if (ret != EOK) { \157 usb_log_error(msg); \158 if (!(allowed_failures-- > 0)) { \159 usb_log_fatal( \160 "Maximum number of failures reached, " \161 "bailing out.\n"); \162 return ret; \163 } \164 continue; \165 } else (void)0166 156 167 157 while (1) { … … 182 172 instance->id_string, port_status); 183 173 184 int ret = usb_hc_connection_open(&instance->hc_connection); 185 CHECK_RET_FAIL(ret, "%s: Failed to connect to HC %s.\n", 186 instance->id_string, str_error(ret)); 174 rc = usb_hc_connection_open(&instance->hc_connection); 175 if (rc != EOK) { 176 usb_log_error("%s: Failed to connect to HC %s.\n", 177 instance->id_string, str_error(rc)); 178 if (!(allowed_failures-- > 0)) 179 goto fatal_error; 180 continue; 181 } 187 182 188 183 /* Remove any old device */ … … 204 199 } 205 200 206 ret = usb_hc_connection_close(&instance->hc_connection); 207 CHECK_RET_FAIL(ret, "%s: Failed to disconnect from hc: %s.\n", 208 instance->id_string, str_error(ret)); 209 } 210 return EOK; 201 rc = usb_hc_connection_close(&instance->hc_connection); 202 if (rc != EOK) { 203 usb_log_error("%s: Failed to disconnect from HC %s.\n", 204 instance->id_string, str_error(rc)); 205 if (!(allowed_failures-- > 0)) 206 goto fatal_error; 207 continue; 208 } 209 } 210 211 return EOK; 212 213 fatal_error: 214 usb_log_fatal("Maximum number of failures reached, bailing out.\n"); 215 return rc; 211 216 } 212 217
Note:
See TracChangeset
for help on using the changeset viewer.