Changeset 224174f in mainline for uspace/drv/bus/usb/ohci/hc.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/ohci/hc.c
r990ab7d r224174f 35 35 36 36 #include <errno.h> 37 #include <stdbool.h> 37 38 #include <str_error.h> 38 39 #include <adt/list.h> … … 83 84 }; 84 85 86 enum { 87 /** Number of PIO ranges used in IRQ code */ 88 hc_irq_pio_range_count = 89 sizeof(ohci_pio_ranges) / sizeof(irq_pio_range_t), 90 91 /** Number of commands used in IRQ code */ 92 hc_irq_cmd_count = 93 sizeof(ohci_irq_commands) / sizeof(irq_cmd_t) 94 }; 95 85 96 static void hc_gain_control(hc_t *instance); 86 97 static void hc_start(hc_t *instance); … … 89 100 static int interrupt_emulator(hc_t *instance); 90 101 static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch); 91 92 /** Get number of PIO ranges used in IRQ code.93 * @return Number of ranges.94 */95 size_t hc_irq_pio_range_count(void)96 {97 return sizeof(ohci_pio_ranges) / sizeof(irq_pio_range_t);98 }99 100 /** Get number of commands used in IRQ code.101 * @return Number of commands.102 */103 size_t hc_irq_cmd_count(void)104 {105 return sizeof(ohci_irq_commands) / sizeof(irq_cmd_t);106 }107 102 108 103 /** Generate IRQ code. … … 137 132 } 138 133 134 /** Register interrupt handler. 135 * 136 * @param[in] device Host controller DDF device 137 * @param[in] reg_base Register range base 138 * @param[in] reg_size Register range size 139 * @param[in] irq Interrupt number 140 * @paran[in] handler Interrupt handler 141 * 142 * @return EOK on success or negative error code 143 */ 144 int hc_register_irq_handler(ddf_dev_t *device, uintptr_t reg_base, size_t reg_size, 145 int irq, interrupt_handler_t handler) 146 { 147 int rc; 148 149 irq_pio_range_t irq_ranges[hc_irq_pio_range_count]; 150 irq_cmd_t irq_cmds[hc_irq_cmd_count]; 151 152 irq_code_t irq_code = { 153 .rangecount = hc_irq_pio_range_count, 154 .ranges = irq_ranges, 155 .cmdcount = hc_irq_cmd_count, 156 .cmds = irq_cmds 157 }; 158 159 rc = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds, 160 sizeof(irq_cmds), reg_base, reg_size); 161 if (rc != EOK) { 162 usb_log_error("Failed to generate IRQ code: %s.\n", 163 str_error(rc)); 164 return rc; 165 } 166 167 /* Register handler to avoid interrupt lockup */ 168 rc = register_interrupt_handler(device, irq, handler, &irq_code); 169 if (rc != EOK) { 170 usb_log_error("Failed to register interrupt handler: %s.\n", 171 str_error(rc)); 172 return rc; 173 } 174 175 return EOK; 176 } 177 139 178 /** Announce OHCI root hub to the DDF 140 179 * … … 145 184 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun) 146 185 { 186 bool addr_reqd = false; 187 bool ep_added = false; 188 bool fun_bound = false; 189 int rc; 190 147 191 assert(instance); 148 192 assert(hub_fun); … … 150 194 /* Try to get address 1 for root hub. */ 151 195 instance->rh.address = 1; 152 int ret= usb_device_manager_request_address(196 rc = usb_device_manager_request_address( 153 197 &instance->generic.dev_manager, &instance->rh.address, false, 154 198 USB_SPEED_FULL); 155 if (r et!= EOK) {199 if (rc != EOK) { 156 200 usb_log_error("Failed to get OHCI root hub address: %s\n", 157 str_error(ret)); 158 return ret; 159 } 160 161 #define CHECK_RET_UNREG_RETURN(ret, message...) \ 162 if (ret != EOK) { \ 163 usb_log_error(message); \ 164 usb_endpoint_manager_remove_ep( \ 165 &instance->generic.ep_manager, instance->rh.address, 0, \ 166 USB_DIRECTION_BOTH, NULL, NULL); \ 167 usb_device_manager_release_address( \ 168 &instance->generic.dev_manager, instance->rh.address); \ 169 return ret; \ 170 } else (void)0 171 172 ret = usb_endpoint_manager_add_ep( 201 str_error(rc)); 202 goto error; 203 } 204 205 addr_reqd = true; 206 207 rc = usb_endpoint_manager_add_ep( 173 208 &instance->generic.ep_manager, instance->rh.address, 0, 174 209 USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64, 175 210 0, NULL, NULL); 176 CHECK_RET_UNREG_RETURN(ret, 177 "Failed to register root hub control endpoint: %s.\n", 178 str_error(ret)); 179 180 ret = ddf_fun_add_match_id(hub_fun, "usb&class=hub", 100); 181 CHECK_RET_UNREG_RETURN(ret, 182 "Failed to add root hub match-id: %s.\n", str_error(ret)); 183 184 ret = ddf_fun_bind(hub_fun); 185 CHECK_RET_UNREG_RETURN(ret, 186 "Failed to bind root hub function: %s.\n", str_error(ret)); 187 188 ret = usb_device_manager_bind_address(&instance->generic.dev_manager, 211 if (rc != EOK) { 212 usb_log_error("Failed to register root hub control endpoint: %s.\n", 213 str_error(rc)); 214 goto error; 215 } 216 217 ep_added = true; 218 219 rc = ddf_fun_add_match_id(hub_fun, "usb&class=hub", 100); 220 if (rc != EOK) { 221 usb_log_error("Failed to add root hub match-id: %s.\n", 222 str_error(rc)); 223 goto error; 224 } 225 226 rc = ddf_fun_bind(hub_fun); 227 if (rc != EOK) { 228 usb_log_error("Failed to bind root hub function: %s.\n", 229 str_error(rc)); 230 goto error; 231 } 232 233 fun_bound = true; 234 235 rc = usb_device_manager_bind_address(&instance->generic.dev_manager, 189 236 instance->rh.address, ddf_fun_get_handle(hub_fun)); 190 if (r et != EOK)237 if (rc != EOK) { 191 238 usb_log_warning("Failed to bind root hub address: %s.\n", 192 str_error(ret)); 193 194 return EOK; 195 #undef CHECK_RET_RELEASE 239 str_error(rc)); 240 } 241 242 return EOK; 243 error: 244 if (fun_bound) 245 ddf_fun_unbind(hub_fun); 246 if (ep_added) { 247 usb_endpoint_manager_remove_ep( 248 &instance->generic.ep_manager, instance->rh.address, 0, 249 USB_DIRECTION_BOTH, NULL, NULL); 250 } 251 if (addr_reqd) { 252 usb_device_manager_release_address( 253 &instance->generic.dev_manager, instance->rh.address); 254 } 255 return rc; 196 256 } 197 257 … … 208 268 assert(instance); 209 269 210 #define CHECK_RET_RETURN(ret, message...) \ 211 if (ret != EOK) { \ 212 usb_log_error(message); \ 213 return ret; \ 214 } else (void)0 215 216 int ret = 270 int rc = 217 271 pio_enable((void*)regs, reg_size, (void**)&instance->registers); 218 CHECK_RET_RETURN(ret, 219 "Failed to gain access to device registers: %s.\n", str_error(ret)); 272 if (rc != EOK) { 273 usb_log_error("Failed to gain access to device registers: %s.\n", 274 str_error(rc)); 275 return rc; 276 } 220 277 221 278 list_initialize(&instance->pending_batches); … … 228 285 instance->generic.ep_remove_hook = ohci_endpoint_fini; 229 286 230 ret = hc_init_memory(instance); 231 CHECK_RET_RETURN(ret, "Failed to create OHCI memory structures: %s.\n", 232 str_error(ret)); 233 #undef CHECK_RET_RETURN 287 rc = hc_init_memory(instance); 288 if (rc != EOK) { 289 usb_log_error("Failed to create OHCI memory structures: %s.\n", 290 str_error(rc)); 291 return rc; 292 } 234 293 235 294 fibril_mutex_initialize(&instance->guard);
Note:
See TracChangeset
for help on using the changeset viewer.