Changeset 26e7d6d in mainline for uspace/drv/bus/usb/ohci/ohci.c
- Timestamp:
- 2011-09-19T16:31:00Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a347a11
- Parents:
- 3842a955 (diff), 086290d (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 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/ohci.c
r3842a955 r26e7d6d 42 42 43 43 #include "ohci.h" 44 #include "iface.h"45 44 #include "pci.h" 46 45 #include "hc.h" 47 #include "root_hub.h"48 46 49 47 typedef struct ohci { … … 52 50 53 51 hc_t hc; 54 rh_t rh;55 52 } ohci_t; 56 53 … … 58 55 { 59 56 assert(dev); 60 assert(dev->driver_data);61 57 return dev->driver_data; 62 58 } 63 64 59 /** IRQ handling callback, identifies device 65 60 * … … 70 65 static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call) 71 66 { 72 hc_t *hc = &dev_to_ohci(dev)->hc; 73 assert(hc); 67 assert(dev); 68 69 ohci_t *ohci = dev_to_ohci(dev); 70 if (!ohci) { 71 usb_log_warning("Interrupt on device that is not ready.\n"); 72 return; 73 } 74 74 const uint16_t status = IPC_GET_ARG1(*call); 75 hc_interrupt( hc, status);75 hc_interrupt(&ohci->hc, status); 76 76 } 77 77 /*----------------------------------------------------------------------------*/ … … 86 86 { 87 87 assert(fun); 88 usb_device_keeper_t *manager = &dev_to_ohci(fun->dev)->hc.manager; 89 90 usb_address_t addr = usb_device_keeper_find(manager, handle); 88 usb_device_manager_t *manager = 89 &dev_to_ohci(fun->dev)->hc.generic.dev_manager; 90 91 const usb_address_t addr = usb_device_manager_find(manager, handle); 91 92 if (addr < 0) { 92 93 return addr; … … 126 127 /** Standard USB HC options (HC interface) */ 127 128 static ddf_dev_ops_t hc_ops = { 128 .interfaces[USBHC_DEV_IFACE] = &hc _iface, /* see iface.h/c */129 .interfaces[USBHC_DEV_IFACE] = &hcd_iface, 129 130 }; 130 131 /*----------------------------------------------------------------------------*/ … … 147 148 int device_setup_ohci(ddf_dev_t *device) 148 149 { 150 assert(device); 151 149 152 ohci_t *instance = malloc(sizeof(ohci_t)); 150 153 if (instance == NULL) { … … 152 155 return ENOMEM; 153 156 } 157 instance->rh_fun = NULL; 158 instance->hc_fun = NULL; 154 159 155 160 #define CHECK_RET_DEST_FREE_RETURN(ret, message...) \ 156 161 if (ret != EOK) { \ 157 162 if (instance->hc_fun) { \ 158 instance->hc_fun->ops = NULL; \159 instance->hc_fun->driver_data = NULL; \160 163 ddf_fun_destroy(instance->hc_fun); \ 161 164 } \ 162 165 if (instance->rh_fun) { \ 163 instance->rh_fun->ops = NULL; \164 instance->rh_fun->driver_data = NULL; \165 166 ddf_fun_destroy(instance->rh_fun); \ 166 167 } \ … … 170 171 } else (void)0 171 172 172 instance->rh_fun = NULL;173 173 instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci_hc"); 174 174 int ret = instance->hc_fun ? EOK : ENOMEM; 175 CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create OHCI HC function.\n"); 175 CHECK_RET_DEST_FREE_RETURN(ret, 176 "Failed to create OHCI HC function: %s.\n", str_error(ret)); 176 177 instance->hc_fun->ops = &hc_ops; 177 178 instance->hc_fun->driver_data = &instance->hc; … … 179 180 instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci_rh"); 180 181 ret = instance->rh_fun ? EOK : ENOMEM; 181 CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create OHCI RH function.\n"); 182 CHECK_RET_DEST_FREE_RETURN(ret, 183 "Failed to create OHCI RH function: %s.\n", str_error(ret)); 182 184 instance->rh_fun->ops = &rh_ops; 183 185 … … 188 190 ret = pci_get_my_registers(device, ®_base, ®_size, &irq); 189 191 CHECK_RET_DEST_FREE_RETURN(ret, 190 "Failed to get memory addresses for %" PRIun ": %s.\n",192 "Failed to get register memory addresses for %" PRIun ": %s.\n", 191 193 device->handle, str_error(ret)); 192 194 usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n", 193 195 (void *) reg_base, reg_size, irq); 194 196 197 const size_t cmd_count = hc_irq_cmd_count(); 198 irq_cmd_t irq_cmds[cmd_count]; 199 irq_code_t irq_code = { .cmdcount = cmd_count, .cmds = irq_cmds }; 200 201 ret = 202 hc_get_irq_commands(irq_cmds, sizeof(irq_cmds), reg_base, reg_size); 203 CHECK_RET_DEST_FREE_RETURN(ret, 204 "Failed to generate IRQ commands: %s.\n", str_error(ret)); 205 206 207 /* Register handler to avoid interrupt lockup */ 208 ret = register_interrupt_handler(device, irq, irq_handler, &irq_code); 209 CHECK_RET_DEST_FREE_RETURN(ret, 210 "Failed to register interrupt handler: %s.\n", str_error(ret)); 211 212 /* Try to enable interrupts */ 195 213 bool interrupts = false; 196 #ifdef CONFIG_USBHC_NO_INTERRUPTS197 usb_log_warning("Interrupts disabled in OS config, "198 "falling back to polling.\n");199 #else200 214 ret = pci_enable_interrupts(device); 201 215 if (ret != EOK) { 202 usb_log_warning("Failed to enable interrupts: %s. \n",203 str_error(ret));204 usb_log_info("HW interrupts not available, "205 "falling back to polling.\n");216 usb_log_warning("Failed to enable interrupts: %s." 217 " Falling back to polling\n", str_error(ret)); 218 /* We don't need that handler */ 219 unregister_interrupt_handler(device, irq); 206 220 } else { 207 221 usb_log_debug("Hw interrupts enabled.\n"); 208 222 interrupts = true; 209 223 } 210 #endif211 224 212 225 ret = hc_init(&instance->hc, reg_base, reg_size, interrupts); 213 CHECK_RET_DEST_FREE_RETURN(ret, "Failed(%d) to init ohci_hcd.\n", ret); 226 CHECK_RET_DEST_FREE_RETURN(ret, 227 "Failed to init ohci_hcd: %s.\n", str_error(ret)); 228 229 device->driver_data = instance; 214 230 215 231 #define CHECK_RET_FINI_RETURN(ret, message...) \ 216 232 if (ret != EOK) { \ 217 233 hc_fini(&instance->hc); \ 234 unregister_interrupt_handler(device, irq); \ 218 235 CHECK_RET_DEST_FREE_RETURN(ret, message); \ 219 236 } else (void)0 220 237 221 /* It does no harm if we register this on polling */222 ret = register_interrupt_handler(device, irq, irq_handler,223 &instance->hc.interrupt_code);224 CHECK_RET_FINI_RETURN(ret,225 "Failed(%d) to register interrupt handler.\n", ret);226 238 227 239 ret = ddf_fun_bind(instance->hc_fun); 228 240 CHECK_RET_FINI_RETURN(ret, 229 "Failed(%d) to bind OHCI device function: %s.\n", 230 ret, str_error(ret)); 231 232 ret = ddf_fun_add_to_class(instance->hc_fun, USB_HC_DDF_CLASS_NAME); 241 "Failed to bind OHCI device function: %s.\n", str_error(ret)); 242 243 ret = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY); 233 244 CHECK_RET_FINI_RETURN(ret, 234 245 "Failed to add OHCI to HC class: %s.\n", str_error(ret)); 235 246 236 device->driver_data = instance; 237 238 hc_start_hw(&instance->hc); 239 hc_register_hub(&instance->hc, instance->rh_fun); 240 return EOK; 241 242 #undef CHECK_RET_DEST_FUN_RETURN 247 ret = hc_register_hub(&instance->hc, instance->rh_fun); 248 CHECK_RET_FINI_RETURN(ret, 249 "Failed to register OHCI root hub: %s.\n", str_error(ret)); 250 return ret; 251 243 252 #undef CHECK_RET_FINI_RETURN 244 253 }
Note:
See TracChangeset
for help on using the changeset viewer.