Changeset 615abda in mainline for uspace/drv/bus/usb/ehci/res.c
- Timestamp:
- 2014-01-19T01:34:03Z (10 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4ee5272
- Parents:
- c9e954c
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ehci/res.c
rc9e954c r615abda 62 62 * @return Error code. 63 63 */ 64 static int disable_extended_caps( ddf_dev_t *device, unsigned eecp)64 static int disable_extended_caps(async_sess_t *parent_sess, unsigned eecp) 65 65 { 66 66 /* nothing to do */ … … 68 68 return EOK; 69 69 70 async_sess_t *parent_sess = devman_parent_device_connect(71 EXCHANGE_SERIALIZE, ddf_dev_get_handle(device), IPC_FLAG_BLOCKING);72 if (!parent_sess)73 return ENOMEM;74 75 #define CHECK_RET_HANGUP_RETURN(ret, message...) \76 if (ret != EOK) { \77 usb_log_error(message); \78 async_hangup(parent_sess); \79 return ret; \80 } else (void)081 82 70 /* Read the first EEC. i.e. Legacy Support register */ 83 71 uint32_t usblegsup; 84 72 int ret = pci_config_space_read_32(parent_sess, 85 73 eecp + USBLEGSUP_OFFSET, &usblegsup); 86 CHECK_RET_HANGUP_RETURN(ret, 87 "Failed to read USBLEGSUP: %s.\n", str_error(ret)); 74 if (ret != EOK) { 75 usb_log_error("Failed to read USBLEGSUP: %s.\n", str_error(ret)); 76 return ret; 77 } 88 78 usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup); 89 79 … … 93 83 ret = pci_config_space_write_8(parent_sess, 94 84 eecp + USBLEGSUP_OFFSET + 3, 1); 95 CHECK_RET_HANGUP_RETURN(ret, "Failed to request OS EHCI control: %s.\n", 96 str_error(ret)); 85 if (ret != EOK) { 86 usb_log_error("Failed to request OS EHCI control: %s.\n", 87 str_error(ret)); 88 return ret; 89 } 97 90 98 91 size_t wait = 0; … … 110 103 if ((usblegsup & USBLEGSUP_BIOS_CONTROL) == 0) { 111 104 usb_log_info("BIOS released control after %zu usec.\n", wait); 112 async_hangup(parent_sess);113 105 return EOK; 114 106 } … … 119 111 ret = pci_config_space_write_32(parent_sess, 120 112 eecp + USBLEGSUP_OFFSET, USBLEGSUP_OS_CONTROL); 121 CHECK_RET_HANGUP_RETURN(ret, "Failed to force OS control: " 122 "%s.\n", str_error(ret)); 113 if (ret != EOK) { 114 usb_log_error("Failed to force OS control: %s.\n", 115 str_error(ret)); 116 return ret; 117 } 118 123 119 /* 124 120 * Check capability type here, value of 01h identifies the capability … … 132 128 ret = pci_config_space_read_32(parent_sess, 133 129 eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts); 134 CHECK_RET_HANGUP_RETURN(ret, "Failed to get USBLEGCTLSTS: %s.\n", 135 str_error(ret)); 130 if (ret != EOK) { 131 usb_log_error("Failed to get USBLEGCTLSTS: %s.\n", 132 str_error(ret)); 133 return ret; 134 } 136 135 usb_log_debug("USBLEGCTLSTS: %" PRIx32 ".\n", usblegctlsts); 137 136 /* … … 142 141 ret = pci_config_space_write_32(parent_sess, 143 142 eecp + USBLEGCTLSTS_OFFSET, 0xe0000000); 144 CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) zero USBLEGCTLSTS.\n", ret); 143 if (ret != EOK) { 144 usb_log_error("Failed to zero USBLEGCTLSTS: %s\n", 145 str_error(ret)); 146 return ret; 147 } 148 145 149 udelay(10); 150 /* read again to amke sure it's zeroed */ 146 151 ret = pci_config_space_read_32(parent_sess, 147 152 eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts); 148 CHECK_RET_HANGUP_RETURN(ret, "Failed to get USBLEGCTLSTS 2: %s.\n", 149 str_error(ret)); 153 if (ret != EOK) { 154 usb_log_error("Failed to get USBLEGCTLSTS 2: %s.\n", 155 str_error(ret)); 156 return ret; 157 } 150 158 usb_log_debug("Zeroed USBLEGCTLSTS: %" PRIx32 ".\n", 151 159 usblegctlsts); … … 155 163 ret = pci_config_space_read_32(parent_sess, 156 164 eecp + USBLEGSUP_OFFSET, &usblegsup); 157 CHECK_RET_HANGUP_RETURN(ret, "Failed to read USBLEGSUP: %s.\n", 158 str_error(ret)); 165 if (ret != EOK) { 166 usb_log_error("Failed to read USBLEGSUP: %s.\n", 167 str_error(ret)); 168 return ret; 169 } 159 170 usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup); 160 async_hangup(parent_sess); 161 return EOK; 162 #undef CHECK_RET_HANGUP_RETURN 171 return ret; 163 172 } 164 173 165 int disable_legacy(ddf_dev_t *device , addr_range_t *reg_range)174 int disable_legacy(ddf_dev_t *device) 166 175 { 167 176 assert(device); 177 178 async_sess_t *parent_sess = devman_parent_device_connect( 179 EXCHANGE_SERIALIZE, ddf_dev_get_handle(device), IPC_FLAG_BLOCKING); 180 if (!parent_sess) 181 return ENOMEM; 182 168 183 usb_log_debug("Disabling EHCI legacy support.\n"); 184 185 hw_res_list_parsed_t res; 186 hw_res_list_parsed_init(&res); 187 int ret = hw_res_get_list_parsed(parent_sess, &res, 0); 188 if (ret != EOK) { 189 usb_log_error("Failed to get resource list: %s\n", 190 str_error(ret)); 191 goto clean; 192 } 193 194 if (res.mem_ranges.count < 1) { 195 usb_log_error("Incorrect mem range count: %zu", 196 res.mem_ranges.count); 197 ret = EINVAL; 198 goto clean; 199 } 169 200 170 201 /* Map EHCI registers */ 171 202 void *regs = NULL; 172 int ret = pio_enable_range(reg_range, ®s);203 ret = pio_enable_range(&res.mem_ranges.ranges[0], ®s); 173 204 if (ret != EOK) { 174 205 usb_log_error("Failed to map registers %p: %s.\n", 175 RNGABSPTR( *reg_range), str_error(ret));176 return ret;206 RNGABSPTR(res.mem_ranges.ranges[0]), str_error(ret)); 207 goto clean; 177 208 } 178 209 … … 190 221 usb_log_debug("Value of EECP: %x.\n", eecp); 191 222 192 ret = disable_extended_caps( device, eecp);223 ret = disable_extended_caps(parent_sess, eecp); 193 224 if (ret != EOK) { 194 225 usb_log_error("Failed to disable extended capabilities: %s.\n", 195 226 str_error(ret)); 196 return ret; 197 } 198 199 200 /* 201 * TURN OFF EHCI FOR NOW, DRIVER WILL REINITIALIZE IT IF NEEDED 202 */ 203 204 /* Get size of capability registers in memory space. */ 205 const unsigned operation_offset = EHCI_RD8(ehci_caps->caplength); 206 usb_log_debug("USBCMD offset: %d.\n", operation_offset); 207 208 ehci_regs_t *ehci_regs = regs + operation_offset; 209 210 usb_log_debug("USBCMD value: %x.\n", EHCI_RD(ehci_regs->usbcmd)); 211 if (EHCI_RD(ehci_regs->usbcmd) & USB_CMD_RUN_FLAG) { 212 EHCI_WR(ehci_regs->usbintr, 0); /* disable all interrupts */ 213 EHCI_WR(ehci_regs->usbsts, 0x3f); /* ack all interrupts */ 214 EHCI_WR(ehci_regs->configflag, 0); /* release RH ports */ 215 EHCI_WR(ehci_regs->usbcmd, 0); 216 /* Wait until hc is halted */ 217 while ((EHCI_RD(ehci_regs->usbsts) & USB_STS_HC_HALTED_FLAG) == 0); 218 usb_log_info("EHCI turned off.\n"); 219 } else { 220 usb_log_info("EHCI was not running.\n"); 221 } 222 usb_log_debug("Registers: \n" 223 "\t USBCMD(%p): %x(0x00080000 = at least 1ms between interrupts)\n" 224 "\t USBSTS(%p): %x(0x00001000 = HC halted)\n" 225 "\t USBINT(%p): %x(0x0 = no interrupts).\n" 226 "\t CONFIG(%p): %x(0x0 = ports controlled by companion hc).\n", 227 &ehci_regs->usbcmd, EHCI_RD(ehci_regs->usbcmd), 228 &ehci_regs->usbsts, EHCI_RD(ehci_regs->usbsts), 229 &ehci_regs->usbintr, EHCI_RD(ehci_regs->usbintr), 230 &ehci_regs->configflag, EHCI_RD(ehci_regs->configflag)); 231 227 goto clean; 228 } 229 clean: 230 //TODO unmap registers 231 hw_res_list_parsed_clean(&res); 232 async_hangup(parent_sess); 232 233 return ret; 233 234 }
Note:
See TracChangeset
for help on using the changeset viewer.