Changeset 3f03199 in mainline for uspace/drv/bus/usb/ohci
- Timestamp:
- 2013-09-15T06:33:53Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9348862
- Parents:
- dd7078c (diff), 1c0cef0 (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. - Location:
- uspace/drv/bus/usb/ohci
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/hc.c
rdd7078c r3f03199 109 109 * @param[out] cmds Commands buffer. 110 110 * @param[in] cmds_size Size of the commands buffer (bytes). 111 * @param[in] regs Physical address of device's registers. 112 * @param[in] reg_size Size of the register area (bytes). 111 * @param[in] regs Device's register range. 113 112 * 114 113 * @return Error code. … … 116 115 int 117 116 hc_get_irq_code(irq_pio_range_t ranges[], size_t ranges_size, irq_cmd_t cmds[], 118 size_t cmds_size, uintptr_t regs, size_t reg_size)117 size_t cmds_size, addr_range_t *regs) 119 118 { 120 119 if ((ranges_size < sizeof(ohci_pio_ranges)) || 121 120 (cmds_size < sizeof(ohci_irq_commands)) || 122 ( reg_size< sizeof(ohci_regs_t)))121 (RNGSZ(*regs) < sizeof(ohci_regs_t))) 123 122 return EOVERFLOW; 124 123 125 124 memcpy(ranges, ohci_pio_ranges, sizeof(ohci_pio_ranges)); 126 ranges[0].base = regs;125 ranges[0].base = RNGABS(*regs); 127 126 128 127 memcpy(cmds, ohci_irq_commands, sizeof(ohci_irq_commands)); 129 ohci_regs_t *registers = (ohci_regs_t *) regs;128 ohci_regs_t *registers = (ohci_regs_t *) RNGABSPTR(*regs); 130 129 cmds[0].addr = (void *) ®isters->interrupt_status; 131 130 cmds[3].addr = (void *) ®isters->interrupt_status; … … 135 134 } 136 135 136 /** Register interrupt handler. 137 * 138 * @param[in] device Host controller DDF device 139 * @param[in] regs Register range 140 * @param[in] irq Interrupt number 141 * @paran[in] handler Interrupt handler 142 * 143 * @return EOK on success or negative error code 144 */ 145 int hc_register_irq_handler(ddf_dev_t *device, addr_range_t *regs, int irq, 146 interrupt_handler_t handler) 147 { 148 int rc; 149 150 irq_pio_range_t irq_ranges[hc_irq_pio_range_count()]; 151 irq_cmd_t irq_cmds[hc_irq_cmd_count()]; 152 153 irq_code_t irq_code = { 154 .rangecount = hc_irq_pio_range_count(), 155 .ranges = irq_ranges, 156 .cmdcount = hc_irq_cmd_count(), 157 .cmds = irq_cmds 158 }; 159 160 rc = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds, 161 sizeof(irq_cmds), regs); 162 if (rc != EOK) { 163 usb_log_error("Failed to generate IRQ code: %s.\n", 164 str_error(rc)); 165 return rc; 166 } 167 168 /* Register handler to avoid interrupt lockup */ 169 rc = register_interrupt_handler(device, irq, handler, &irq_code); 170 if (rc != EOK) { 171 usb_log_error("Failed to register interrupt handler: %s.\n", 172 str_error(rc)); 173 return rc; 174 } 175 176 return EOK; 177 } 178 137 179 /** Initialize OHCI hc driver structure 138 180 * 139 181 * @param[in] instance Memory place for the structure. 140 * @param[in] regs Address of the memory mapped I/O registers. 141 * @param[in] reg_size Size of the memory mapped area. 182 * @param[in] regs Device's I/O registers range. 142 183 * @param[in] interrupts True if w interrupts should be used 143 184 * @return Error code 144 185 */ 145 int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts) 146 { 147 assert(instance); 148 149 int ret = 150 pio_enable((void*)regs, reg_size, (void**)&instance->registers); 186 int hc_init(hc_t *instance, addr_range_t *regs, bool interrupts) 187 { 188 assert(instance); 189 190 int ret = pio_enable_range(regs, (void **) &instance->registers); 151 191 if (ret != EOK) { 152 usb_log_error("Failed to enable access to device regss: %s.\n",192 usb_log_error("Failed to gain access to device registers: %s.\n", 153 193 str_error(ret)); 154 194 return ret; -
uspace/drv/bus/usb/ohci/hc.h
rdd7078c r3f03199 39 39 #include <adt/list.h> 40 40 #include <ddi.h> 41 #include <ddf/interrupt.h> 41 42 42 43 #include <usb/usb.h> … … 73 74 size_t hc_irq_pio_range_count(void); 74 75 size_t hc_irq_cmd_count(void); 75 int hc_get_irq_code(irq_pio_range_t [], size_t, irq_cmd_t [], size_t, uintptr_t, 76 size_t); 76 int hc_get_irq_code(irq_pio_range_t [], size_t, irq_cmd_t [], size_t, 77 addr_range_t *); 78 int hc_register_irq_handler(ddf_dev_t *, addr_range_t *, int, 79 interrupt_handler_t); 77 80 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun); 78 int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts);81 int hc_init(hc_t *instance, addr_range_t *regs, bool interrupts); 79 82 80 83 /** Safely dispose host controller internal structures -
uspace/drv/bus/usb/ohci/ohci.c
rdd7078c r3f03199 80 80 int device_setup_ohci(ddf_dev_t *device) 81 81 { 82 #define CHECK_RET_RETURN(ret, message...) \83 if (ret != EOK) { \84 usb_log_error(message); \85 return ret; \86 }87 82 88 uintptr_t reg_base = 0; 89 size_t reg_size = 0; 83 addr_range_t regs; 90 84 int irq = 0; 91 85 92 int ret = get_my_registers(device, ®_base, ®_size, &irq); 93 CHECK_RET_RETURN(ret, "Failed to get register memory addresses for %" 94 PRIun ": %s.\n", ddf_dev_get_handle(device), str_error(ret)); 86 int ret = get_my_registers(device, ®s, &irq); 87 if (ret != EOK) { 88 usb_log_error("Failed to get register memory addresses " 89 "for %" PRIun ": %s.\n", ddf_dev_get_handle(device), 90 str_error(ret)); 91 return ret; 92 } 95 93 96 94 usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n", 97 (void *) reg_base, reg_size, irq);95 RNGABSPTR(regs), RNGSZ(regs), irq); 98 96 99 const size_t ranges_count = hc_irq_pio_range_count(); 100 const size_t cmds_count = hc_irq_cmd_count(); 101 irq_pio_range_t irq_ranges[ranges_count]; 102 irq_cmd_t irq_cmds[cmds_count]; 103 irq_code_t irq_code = { 104 .rangecount = ranges_count, 105 .ranges = irq_ranges, 106 .cmdcount = cmds_count, 107 .cmds = irq_cmds 108 }; 97 /* Initialize generic HCD driver */ 98 ret = hcd_ddf_setup_hc(device, USB_SPEED_FULL, 99 BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11); 100 if (ret != EOK) { 101 usb_log_error("Failedd to setup generic hcd: %s.", 102 str_error(ret)); 103 return ret; 104 } 109 105 110 ret = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds, 111 sizeof(irq_cmds), reg_base, reg_size); 112 CHECK_RET_RETURN(ret, "Failed to gen IRQ code: %s.\n", str_error(ret)); 113 114 /* Register handler to avoid interrupt lockup */ 115 ret = register_interrupt_handler(device, irq, irq_handler, &irq_code); 116 CHECK_RET_RETURN(ret, 117 "Failed to register irq handler: %s.\n", str_error(ret)); 106 ret = hc_register_irq_handler(device, ®s, irq, irq_handler); 107 if (ret != EOK) { 108 usb_log_error("Failed to register interrupt handler: %s.\n", 109 str_error(ret)); 110 hcd_ddf_clean_hc(device); 111 return ret; 112 } 118 113 119 114 /* Try to enable interrupts */ … … 130 125 } 131 126 132 /* Initialize generic HCD driver */ 133 ret = hcd_ddf_setup_hc(device, USB_SPEED_FULL, 134 BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11); 135 if (ret != EOK) { 127 128 hc_t *hc_impl = malloc(sizeof(hc_t)); 129 if (!hc_impl) { 130 usb_log_error("Failed to allocate driver structure.\n"); 131 hcd_ddf_clean_hc(device); 136 132 unregister_interrupt_handler(device, irq); 137 133 return ret; 138 134 } 139 135 140 // TODO: Undo hcd_setup_device141 #define CHECK_RET_CLEAN_RETURN(ret, message...) \142 if (ret != EOK) { \143 unregister_interrupt_handler(device, irq); \144 CHECK_RET_RETURN(ret, message); \145 } else (void)0146 147 hc_t *hc_impl = malloc(sizeof(hc_t));148 ret = hc_impl ? EOK : ENOMEM;149 CHECK_RET_CLEAN_RETURN(ret, "Failed to allocate driver structure.\n");150 151 136 /* Initialize OHCI HC */ 152 ret = hc_init(hc_impl, reg_base, reg_size, interrupts); 153 CHECK_RET_CLEAN_RETURN(ret, "Failed to init hc: %s.\n", str_error(ret)); 137 ret = hc_init(hc_impl, ®s, interrupts); 138 if (ret != EOK) { 139 usb_log_error("Failed to init hc: %s.\n", str_error(ret)); 140 hcd_ddf_clean_hc(device); 141 unregister_interrupt_handler(device, irq); 142 return ret; 143 } 154 144 155 145 /* Connect OHCI to generic HCD */ … … 159 149 /* HC should be running OK. We can add root hub */ 160 150 ret = hcd_ddf_setup_root_hub(device); 161 CHECK_RET_CLEAN_RETURN(ret, 162 "Failed to register OHCI root hub: %s.\n", str_error(ret)); 151 if (ret != EOK) { 152 usb_log_error("Failed to registter OHCI root hub: %s.\n", 153 str_error(ret)); 154 hcd_ddf_clean_hc(device); 155 unregister_interrupt_handler(device, irq); 156 return ret; 157 } 163 158 164 159 return ret; -
uspace/drv/bus/usb/ohci/res.c
rdd7078c r3f03199 48 48 * 49 49 * @param[in] dev Device asking for the addresses. 50 * @param[out] mem_reg_address Base address of the memory range. 51 * @param[out] mem_reg_size Size of the memory range. 50 * @param[out] p_regs Pointer to register range. 52 51 * @param[out] irq_no IRQ assigned to the device. 53 52 * @return Error code. 54 53 */ 55 int get_my_registers(ddf_dev_t *dev, 56 uintptr_t *mem_reg_address, size_t *mem_reg_size, int *irq_no) 54 int get_my_registers(ddf_dev_t *dev, addr_range_t *p_regs, int *irq_no) 57 55 { 58 56 assert(dev); … … 66 64 hw_res_list_parsed_t hw_res; 67 65 hw_res_list_parsed_init(&hw_res); 68 const int ret = hw_res_get_list_parsed(parent_sess, &hw_res, 0);66 const int ret = hw_res_get_list_parsed(parent_sess, &hw_res, 0); 69 67 async_hangup(parent_sess); 70 68 if (ret != EOK) { … … 78 76 } 79 77 80 if (mem_reg_address) 81 *mem_reg_address = hw_res.mem_ranges.ranges[0].address; 82 if (mem_reg_size) 83 *mem_reg_size = hw_res.mem_ranges.ranges[0].size; 78 if (p_regs) 79 *p_regs = hw_res.mem_ranges.ranges[0]; 84 80 if (irq_no) 85 81 *irq_no = hw_res.irqs.irqs[0]; -
uspace/drv/bus/usb/ohci/res.h
rdd7078c r3f03199 36 36 37 37 #include <ddf/driver.h> 38 #include <device/hw_res_parsed.h> 38 39 39 int get_my_registers(ddf_dev_t *, uintptr_t *, size_t *, int *);40 int get_my_registers(ddf_dev_t *, addr_range_t *, int *); 40 41 int enable_interrupts(ddf_dev_t *); 41 42
Note:
See TracChangeset
for help on using the changeset viewer.
