Changeset cffa14e6 in mainline for uspace/drv/bus/usb/ohci/hc.c
- Timestamp:
- 2013-07-24T17:27:56Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- db71e2a
- Parents:
- c442f63
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/hc.c
rc442f63 rcffa14e6 35 35 36 36 #include <errno.h> 37 #include <stdbool.h>38 37 #include <str_error.h> 39 38 #include <adt/list.h> … … 84 83 }; 85 84 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 96 85 static void hc_gain_control(hc_t *instance); 97 86 static void hc_start(hc_t *instance); … … 100 89 static int interrupt_emulator(hc_t *instance); 101 90 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 } 102 107 103 108 /** Generate IRQ code. … … 132 137 } 133 138 134 /** Register interrupt handler.135 *136 * @param[in] device Host controller DDF device137 * @param[in] reg_base Register range base138 * @param[in] reg_size Register range size139 * @param[in] irq Interrupt number140 * @paran[in] handler Interrupt handler141 *142 * @return EOK on success or negative error code143 */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_cmds157 };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 178 139 /** Announce OHCI root hub to the DDF 179 140 * … … 184 145 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun) 185 146 { 186 bool addr_reqd = false;187 bool ep_added = false;188 bool fun_bound = false;189 int rc;190 191 147 assert(instance); 192 148 assert(hub_fun); … … 194 150 /* Try to get address 1 for root hub. */ 195 151 instance->rh.address = 1; 196 rc= usb_device_manager_request_address(152 int ret = usb_device_manager_request_address( 197 153 &instance->generic.dev_manager, &instance->rh.address, false, 198 154 USB_SPEED_FULL); 199 if (r c!= EOK) {155 if (ret != EOK) { 200 156 usb_log_error("Failed to get OHCI root hub address: %s\n", 201 str_error(rc)); 202 goto error; 203 } 204 205 addr_reqd = true; 206 207 rc = usb_endpoint_manager_add_ep( 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( 208 173 &instance->generic.ep_manager, instance->rh.address, 0, 209 174 USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64, 210 175 0, NULL, NULL); 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, 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, 236 189 instance->rh.address, ddf_fun_get_handle(hub_fun)); 237 if (r c != EOK) {190 if (ret != EOK) 238 191 usb_log_warning("Failed to bind root hub address: %s.\n", 239 str_error(rc)); 240 } 192 str_error(ret)); 241 193 242 194 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; 195 #undef CHECK_RET_RELEASE 256 196 } 257 197 … … 268 208 assert(instance); 269 209 270 int rc = 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 = 271 217 pio_enable((void*)regs, reg_size, (void**)&instance->registers); 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 } 218 CHECK_RET_RETURN(ret, 219 "Failed to gain access to device registers: %s.\n", str_error(ret)); 277 220 278 221 list_initialize(&instance->pending_batches); … … 285 228 instance->generic.ep_remove_hook = ohci_endpoint_fini; 286 229 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 } 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 293 234 294 235 fibril_mutex_initialize(&instance->guard);
Note:
See TracChangeset
for help on using the changeset viewer.