Changes in uspace/drv/bus/usb/ohci/ohci.c [507c6f3:44c1a48] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/ohci.c
r507c6f3 r44c1a48 33 33 * @brief OHCI driver 34 34 */ 35 36 /* XXX Fix this */37 #define _DDF_DATA_IMPLANT38 39 35 #include <errno.h> 40 36 #include <str_error.h> … … 56 52 } ohci_t; 57 53 58 static inline ohci_t *dev_to_ohci(ddf_dev_t *dev) 59 { 60 return ddf_dev_data_get(dev); 54 static inline ohci_t * dev_to_ohci(ddf_dev_t *dev) 55 { 56 assert(dev); 57 return dev->driver_data; 61 58 } 62 59 /** IRQ handling callback, identifies device … … 78 75 hc_interrupt(&ohci->hc, status); 79 76 } 80 77 /*----------------------------------------------------------------------------*/ 81 78 /** Get USB address assigned to root hub. 82 79 * … … 90 87 91 88 if (address != NULL) { 92 *address = dev_to_ohci( ddf_fun_get_dev(fun))->hc.rh.address;89 *address = dev_to_ohci(fun->dev)->hc.rh.address; 93 90 } 94 91 95 92 return EOK; 96 93 } 97 94 /*----------------------------------------------------------------------------*/ 98 95 /** Gets handle of the respective hc (this device, hc function). 99 96 * … … 106 103 { 107 104 assert(fun); 108 ddf_fun_t *hc_fun = dev_to_ohci( ddf_fun_get_dev(fun))->hc_fun;105 ddf_fun_t *hc_fun = dev_to_ohci(fun->dev)->hc_fun; 109 106 assert(hc_fun); 110 107 111 108 if (handle != NULL) 112 *handle = ddf_fun_get_handle(hc_fun);109 *handle = hc_fun->handle; 113 110 return EOK; 114 111 } 115 112 /*----------------------------------------------------------------------------*/ 116 113 /** Root hub USB interface */ 117 114 static usb_iface_t usb_iface = { … … 119 116 .get_my_address = rh_get_my_address, 120 117 }; 121 118 /*----------------------------------------------------------------------------*/ 122 119 /** Standard USB HC options (HC interface) */ 123 120 static ddf_dev_ops_t hc_ops = { 124 121 .interfaces[USBHC_DEV_IFACE] = &hcd_iface, 125 122 }; 126 123 /*----------------------------------------------------------------------------*/ 127 124 /** Standard USB RH options (RH interface) */ 128 125 static ddf_dev_ops_t rh_ops = { 129 126 .interfaces[USB_DEV_IFACE] = &usb_iface, 130 127 }; 131 128 /*----------------------------------------------------------------------------*/ 132 129 /** Initialize hc and rh ddf structures and their respective drivers. 133 130 * … … 143 140 int device_setup_ohci(ddf_dev_t *device) 144 141 { 145 bool ih_registered = false;146 bool hc_inited = false;147 int rc;148 149 142 if (device == NULL) 150 143 return EBADMEM; … … 156 149 } 157 150 151 #define CHECK_RET_DEST_FREE_RETURN(ret, message...) \ 152 if (ret != EOK) { \ 153 if (instance->hc_fun) { \ 154 instance->hc_fun->driver_data = NULL; \ 155 ddf_fun_destroy(instance->hc_fun); \ 156 } \ 157 if (instance->rh_fun) { \ 158 instance->rh_fun->driver_data = NULL; \ 159 ddf_fun_destroy(instance->rh_fun); \ 160 } \ 161 usb_log_error(message); \ 162 return ret; \ 163 } else (void)0 164 158 165 instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci_hc"); 159 if (instance->hc_fun == NULL) { 160 usb_log_error("Failed to create OHCI HC function: %s.\n", 161 str_error(ENOMEM)); 162 rc = ENOMEM; 163 goto error; 164 } 165 166 ddf_fun_set_ops(instance->hc_fun, &hc_ops); 167 ddf_fun_data_implant(instance->hc_fun, &instance->hc); 166 int ret = instance->hc_fun ? EOK : ENOMEM; 167 CHECK_RET_DEST_FREE_RETURN(ret, 168 "Failed to create OHCI HC function: %s.\n", str_error(ret)); 169 instance->hc_fun->ops = &hc_ops; 170 instance->hc_fun->driver_data = &instance->hc; 168 171 169 172 instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci_rh"); 170 if (instance->rh_fun == NULL) { 171 usb_log_error("Failed to create OHCI RH function: %s.\n", 172 str_error(ENOMEM)); 173 rc = ENOMEM; 174 goto error; 175 } 176 177 ddf_fun_set_ops(instance->rh_fun, &rh_ops); 173 ret = instance->rh_fun ? EOK : ENOMEM; 174 CHECK_RET_DEST_FREE_RETURN(ret, 175 "Failed to create OHCI RH function: %s.\n", str_error(ret)); 176 instance->rh_fun->ops = &rh_ops; 178 177 179 178 uintptr_t reg_base = 0; … … 181 180 int irq = 0; 182 181 183 rc = get_my_registers(device, ®_base, ®_size, &irq); 184 if (rc != EOK) { 185 usb_log_error("Failed to get register memory addresses " 186 "for %" PRIun ": %s.\n", ddf_dev_get_handle(device), 187 str_error(rc)); 188 goto error; 189 } 190 182 ret = get_my_registers(device, ®_base, ®_size, &irq); 183 CHECK_RET_DEST_FREE_RETURN(ret, 184 "Failed to get register memory addresses for %" PRIun ": %s.\n", 185 device->handle, str_error(ret)); 191 186 usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n", 192 187 (void *) reg_base, reg_size, irq); 193 188 194 rc = hc_register_irq_handler(device, reg_base, reg_size, irq, irq_handler); 195 if (rc != EOK) { 196 usb_log_error("Failed to register interrupt handler: %s.\n", 197 str_error(rc)); 198 goto error; 199 } 200 201 ih_registered = true; 189 const size_t ranges_count = hc_irq_pio_range_count(); 190 const size_t cmds_count = hc_irq_cmd_count(); 191 irq_pio_range_t irq_ranges[ranges_count]; 192 irq_cmd_t irq_cmds[cmds_count]; 193 irq_code_t irq_code = { 194 .rangecount = ranges_count, 195 .ranges = irq_ranges, 196 .cmdcount = cmds_count, 197 .cmds = irq_cmds 198 }; 199 200 ret = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds, 201 sizeof(irq_cmds), reg_base, reg_size); 202 CHECK_RET_DEST_FREE_RETURN(ret, 203 "Failed to generate IRQ code: %s.\n", str_error(ret)); 204 205 206 /* Register handler to avoid interrupt lockup */ 207 ret = register_interrupt_handler(device, irq, irq_handler, &irq_code); 208 CHECK_RET_DEST_FREE_RETURN(ret, 209 "Failed to register interrupt handler: %s.\n", str_error(ret)); 202 210 203 211 /* Try to enable interrupts */ 204 212 bool interrupts = false; 205 r c= enable_interrupts(device);206 if (r c!= EOK) {213 ret = enable_interrupts(device); 214 if (ret != EOK) { 207 215 usb_log_warning("Failed to enable interrupts: %s." 208 " Falling back to polling\n", str_error(r c));216 " Falling back to polling\n", str_error(ret)); 209 217 /* We don't need that handler */ 210 218 unregister_interrupt_handler(device, irq); 211 ih_registered = false;212 219 } else { 213 220 usb_log_debug("Hw interrupts enabled.\n"); … … 215 222 } 216 223 217 rc = hc_init(&instance->hc, reg_base, reg_size, interrupts); 218 if (rc != EOK) { 219 usb_log_error("Failed to init ohci_hcd: %s.\n", str_error(rc)); 220 goto error; 221 } 222 223 hc_inited = true; 224 225 rc = ddf_fun_bind(instance->hc_fun); 226 if (rc != EOK) { 227 usb_log_error("Failed to bind OHCI device function: %s.\n", 228 str_error(rc)); 229 goto error; 230 } 231 232 rc = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY); 233 if (rc != EOK) { 234 usb_log_error("Failed to add OHCI to HC category: %s.\n", 235 str_error(rc)); 236 goto error; 237 } 238 239 rc = hc_register_hub(&instance->hc, instance->rh_fun); 240 if (rc != EOK) { 241 usb_log_error("Failed to register OHCI root hub: %s.\n", 242 str_error(rc)); 243 goto error; 244 } 245 246 return EOK; 247 248 error: 249 if (hc_inited) 250 hc_fini(&instance->hc); 251 if (ih_registered) 252 unregister_interrupt_handler(device, irq); 253 if (instance->hc_fun != NULL) 254 ddf_fun_destroy(instance->hc_fun); 255 if (instance->rh_fun != NULL) 256 ddf_fun_destroy(instance->rh_fun); 257 return rc; 224 ret = hc_init(&instance->hc, reg_base, reg_size, interrupts); 225 CHECK_RET_DEST_FREE_RETURN(ret, 226 "Failed to init ohci_hcd: %s.\n", str_error(ret)); 227 228 #define CHECK_RET_FINI_RETURN(ret, message...) \ 229 if (ret != EOK) { \ 230 hc_fini(&instance->hc); \ 231 unregister_interrupt_handler(device, irq); \ 232 CHECK_RET_DEST_FREE_RETURN(ret, message); \ 233 } else (void)0 234 235 236 ret = ddf_fun_bind(instance->hc_fun); 237 CHECK_RET_FINI_RETURN(ret, 238 "Failed to bind OHCI device function: %s.\n", str_error(ret)); 239 240 ret = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY); 241 CHECK_RET_FINI_RETURN(ret, 242 "Failed to add OHCI to HC class: %s.\n", str_error(ret)); 243 244 ret = hc_register_hub(&instance->hc, instance->rh_fun); 245 CHECK_RET_FINI_RETURN(ret, 246 "Failed to register OHCI root hub: %s.\n", str_error(ret)); 247 return ret; 248 249 #undef CHECK_RET_FINI_RETURN 258 250 } 259 251 /**
Note:
See TracChangeset
for help on using the changeset viewer.