Changes in uspace/drv/bus/usb/ohci/hc.c [f83666c:6340a6ff] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/hc.c
rf83666c r6340a6ff 35 35 36 36 #include <errno.h> 37 #include <stdbool.h>38 37 #include <str_error.h> 39 38 #include <adt/list.h> … … 42 41 #include <usb/debug.h> 43 42 #include <usb/usb.h> 44 #include <usb/ddfiface.h>45 43 46 44 #include "hc.h" … … 84 82 }; 85 83 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 84 static void hc_gain_control(hc_t *instance); 97 85 static void hc_start(hc_t *instance); … … 99 87 static int hc_init_memory(hc_t *instance); 100 88 static int interrupt_emulator(hc_t *instance); 101 static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch); 89 90 /** Get number of PIO ranges used in IRQ code. 91 * @return Number of ranges. 92 */ 93 size_t hc_irq_pio_range_count(void) 94 { 95 return sizeof(ohci_pio_ranges) / sizeof(irq_pio_range_t); 96 } 97 98 /** Get number of commands used in IRQ code. 99 * @return Number of commands. 100 */ 101 size_t hc_irq_cmd_count(void) 102 { 103 return sizeof(ohci_irq_commands) / sizeof(irq_cmd_t); 104 } 102 105 103 106 /** Generate IRQ code. … … 132 135 } 133 136 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 /** Announce OHCI root hub to the DDF179 *180 * @param[in] instance OHCI driver intance181 * @param[in] hub_fun DDF fuction representing OHCI root hub182 * @return Error code183 */184 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun)185 {186 bool addr_reqd = false;187 bool ep_added = false;188 bool fun_bound = false;189 int rc;190 191 assert(instance);192 assert(hub_fun);193 194 /* Try to get address 1 for root hub. */195 instance->rh.address = 1;196 rc = usb_device_manager_request_address(197 &instance->generic.dev_manager, &instance->rh.address, false,198 USB_SPEED_FULL);199 if (rc != EOK) {200 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(208 &instance->generic.ep_manager, instance->rh.address, 0,209 USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64,210 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,236 instance->rh.address, ddf_fun_get_handle(hub_fun));237 if (rc != EOK) {238 usb_log_warning("Failed to bind root hub address: %s.\n",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;256 }257 258 137 /** Initialize OHCI hc driver structure 259 138 * … … 268 147 assert(instance); 269 148 270 int r c=149 int ret = 271 150 pio_enable((void*)regs, reg_size, (void**)&instance->registers); 272 if (r c!= EOK) {273 usb_log_error("Failed to gain access to device registers: %s.\n",274 str_error(r c));275 return r c;151 if (ret != EOK) { 152 usb_log_error("Failed to enable access to device regss: %s.\n", 153 str_error(ret)); 154 return ret; 276 155 } 277 156 278 157 list_initialize(&instance->pending_batches); 279 280 hcd_init(&instance->generic, USB_SPEED_FULL, 281 BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11); 282 instance->generic.private_data = instance; 283 instance->generic.schedule = hc_schedule; 284 instance->generic.ep_add_hook = ohci_endpoint_init; 285 instance->generic.ep_remove_hook = ohci_endpoint_fini; 286 287 rc = hc_init_memory(instance); 288 if (rc != EOK) { 158 fibril_mutex_initialize(&instance->guard); 159 160 ret = hc_init_memory(instance); 161 if (ret != EOK) { 289 162 usb_log_error("Failed to create OHCI memory structures: %s.\n", 290 str_error(rc)); 291 return rc; 292 } 293 294 fibril_mutex_initialize(&instance->guard); 163 str_error(ret)); 164 return ret; 165 } 295 166 296 167 hc_gain_control(instance); … … 302 173 } 303 174 304 rh_init(&instance->rh, instance->registers);175 ohci_rh_init(&instance->rh, instance->registers, "ohci rh"); 305 176 hc_start(instance); 306 177 … … 389 260 390 261 /* Check for root hub communication */ 391 if (batch->ep->address == instance->rh.address) {262 if (batch->ep->address == ohci_rh_get_address(&instance->rh)) { 392 263 usb_log_debug("OHCI root hub request.\n"); 393 rh_request(&instance->rh, batch); 394 return EOK; 264 return ohci_rh_schedule(&instance->rh, batch); 395 265 } 396 266 ohci_transfer_batch_t *ohci_batch = ohci_transfer_batch_get(batch); … … 431 301 usb_log_debug2("OHCI(%p) interrupt: %x.\n", instance, status); 432 302 if (status & I_RHSC) 433 rh_interrupt(&instance->rh);303 ohci_rh_interrupt(&instance->rh); 434 304 435 305 if (status & I_WDH) { … … 629 499 do { \ 630 500 const char *name = usb_str_transfer_type(type); \ 631 int ret = endpoint_list_init(&instance->lists[type], name); \501 const int ret = endpoint_list_init(&instance->lists[type], name); \ 632 502 if (ret != EOK) { \ 633 503 usb_log_error("Failed to setup %s endpoint list: %s.\n", \
Note:
See TracChangeset
for help on using the changeset viewer.