Changes in uspace/drv/bus/usb/ohci/hc.c [7de1988c:56fd7cf] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/hc.c
r7de1988c r56fd7cf 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); … … 101 90 static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch); 102 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 103 108 /** Generate IRQ code. 104 109 * @param[out] ranges PIO ranges buffer. … … 106 111 * @param[out] cmds Commands buffer. 107 112 * @param[in] cmds_size Size of the commands buffer (bytes). 108 * @param[in] regs Device's register range. 113 * @param[in] regs Physical address of device's registers. 114 * @param[in] reg_size Size of the register area (bytes). 109 115 * 110 116 * @return Error code. … … 112 118 int 113 119 hc_get_irq_code(irq_pio_range_t ranges[], size_t ranges_size, irq_cmd_t cmds[], 114 size_t cmds_size, addr_range_t *regs)120 size_t cmds_size, uintptr_t regs, size_t reg_size) 115 121 { 116 122 if ((ranges_size < sizeof(ohci_pio_ranges)) || 117 123 (cmds_size < sizeof(ohci_irq_commands)) || 118 ( RNGSZ(*regs)< sizeof(ohci_regs_t)))124 (reg_size < sizeof(ohci_regs_t))) 119 125 return EOVERFLOW; 120 126 121 127 memcpy(ranges, ohci_pio_ranges, sizeof(ohci_pio_ranges)); 122 ranges[0].base = RNGABS(*regs);128 ranges[0].base = regs; 123 129 124 130 memcpy(cmds, ohci_irq_commands, sizeof(ohci_irq_commands)); 125 ohci_regs_t *registers = (ohci_regs_t *) RNGABSPTR(*regs);131 ohci_regs_t *registers = (ohci_regs_t *) regs; 126 132 cmds[0].addr = (void *) ®isters->interrupt_status; 127 133 cmds[3].addr = (void *) ®isters->interrupt_status; … … 131 137 } 132 138 133 /** Register interrupt handler.134 *135 * @param[in] device Host controller DDF device136 * @param[in] regs Register range137 * @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, addr_range_t *regs, int irq,143 interrupt_handler_t handler)144 {145 int rc;146 147 irq_pio_range_t irq_ranges[hc_irq_pio_range_count];148 irq_cmd_t irq_cmds[hc_irq_cmd_count];149 150 irq_code_t irq_code = {151 .rangecount = hc_irq_pio_range_count,152 .ranges = irq_ranges,153 .cmdcount = hc_irq_cmd_count,154 .cmds = irq_cmds155 };156 157 rc = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds,158 sizeof(irq_cmds), regs);159 if (rc != EOK) {160 usb_log_error("Failed to generate IRQ code: %s.\n",161 str_error(rc));162 return rc;163 }164 165 /* Register handler to avoid interrupt lockup */166 rc = register_interrupt_handler(device, irq, handler, &irq_code);167 if (rc != EOK) {168 usb_log_error("Failed to register interrupt handler: %s.\n",169 str_error(rc));170 return rc;171 }172 173 return EOK;174 }175 176 139 /** Announce OHCI root hub to the DDF 177 140 * … … 182 145 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun) 183 146 { 184 bool addr_reqd = false;185 bool ep_added = false;186 bool fun_bound = false;187 int rc;188 189 147 assert(instance); 190 148 assert(hub_fun); … … 192 150 /* Try to get address 1 for root hub. */ 193 151 instance->rh.address = 1; 194 rc= usb_device_manager_request_address(152 int ret = usb_device_manager_request_address( 195 153 &instance->generic.dev_manager, &instance->rh.address, false, 196 154 USB_SPEED_FULL); 197 if (r c!= EOK) {155 if (ret != EOK) { 198 156 usb_log_error("Failed to get OHCI root hub address: %s\n", 199 str_error(rc)); 200 goto error; 201 } 202 203 addr_reqd = true; 204 205 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( 206 173 &instance->generic.ep_manager, instance->rh.address, 0, 207 174 USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64, 208 175 0, NULL, NULL); 209 if (rc != EOK) { 210 usb_log_error("Failed to register root hub control endpoint: %s.\n", 211 str_error(rc)); 212 goto error; 213 } 214 215 ep_added = true; 216 217 rc = ddf_fun_add_match_id(hub_fun, "usb&class=hub", 100); 218 if (rc != EOK) { 219 usb_log_error("Failed to add root hub match-id: %s.\n", 220 str_error(rc)); 221 goto error; 222 } 223 224 rc = ddf_fun_bind(hub_fun); 225 if (rc != EOK) { 226 usb_log_error("Failed to bind root hub function: %s.\n", 227 str_error(rc)); 228 goto error; 229 } 230 231 fun_bound = true; 232 233 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, 234 189 instance->rh.address, ddf_fun_get_handle(hub_fun)); 235 if (r c != EOK) {190 if (ret != EOK) 236 191 usb_log_warning("Failed to bind root hub address: %s.\n", 237 str_error(rc)); 238 } 192 str_error(ret)); 239 193 240 194 return EOK; 241 error: 242 if (fun_bound) 243 ddf_fun_unbind(hub_fun); 244 if (ep_added) { 245 usb_endpoint_manager_remove_ep( 246 &instance->generic.ep_manager, instance->rh.address, 0, 247 USB_DIRECTION_BOTH, NULL, NULL); 248 } 249 if (addr_reqd) { 250 usb_device_manager_release_address( 251 &instance->generic.dev_manager, instance->rh.address); 252 } 253 return rc; 195 #undef CHECK_RET_RELEASE 254 196 } 255 197 … … 257 199 * 258 200 * @param[in] instance Memory place for the structure. 259 * @param[in] regs Device's I/O registers range. 201 * @param[in] regs Address of the memory mapped I/O registers. 202 * @param[in] reg_size Size of the memory mapped area. 260 203 * @param[in] interrupts True if w interrupts should be used 261 204 * @return Error code 262 205 */ 263 int hc_init(hc_t *instance, addr_range_t *regs, bool interrupts) 264 { 265 assert(instance); 266 267 int rc = pio_enable_range(regs, (void **) &instance->registers); 268 if (rc != EOK) { 269 usb_log_error("Failed to gain access to device registers: %s.\n", 270 str_error(rc)); 271 return rc; 272 } 206 int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts) 207 { 208 assert(instance); 209 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 = 217 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)); 273 220 274 221 list_initialize(&instance->pending_batches); … … 281 228 instance->generic.ep_remove_hook = ohci_endpoint_fini; 282 229 283 rc = hc_init_memory(instance); 284 if (rc != EOK) { 285 usb_log_error("Failed to create OHCI memory structures: %s.\n", 286 str_error(rc)); 287 return rc; 288 } 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 289 234 290 235 fibril_mutex_initialize(&instance->guard); … … 657 602 assert(instance); 658 603 659 memset(&instance->rh, 0, sizeof(instance->rh));604 bzero(&instance->rh, sizeof(instance->rh)); 660 605 /* Init queues */ 661 606 const int ret = hc_init_transfer_lists(instance);
Note:
See TracChangeset
for help on using the changeset viewer.