Changes in uspace/drv/bus/usb/ehci/res.c [d3dd96e:99e8fb7b] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ehci/res.c
rd3dd96e r99e8fb7b 43 43 #include <usb/debug.h> 44 44 #include <device/hw_res_parsed.h> 45 #include < device/pci.h>45 #include <pci_dev_iface.h> 46 46 47 47 #include "res.h" 48 #include "ehci_regs.h" 48 49 #define HCC_PARAMS_OFFSET 0x8 50 #define HCC_PARAMS_EECP_MASK 0xff 51 #define HCC_PARAMS_EECP_OFFSET 8 52 53 #define CMD_OFFSET 0x0 54 #define STS_OFFSET 0x4 55 #define INT_OFFSET 0x8 56 #define CFG_OFFSET 0x40 57 58 #define USBCMD_RUN 1 59 #define USBSTS_HALTED (1 << 12) 49 60 50 61 #define USBLEGSUP_OFFSET 0 … … 55 66 #define DEFAULT_WAIT 1000 56 67 #define WAIT_STEP 10 68 69 70 /** Get address of registers and IRQ for given device. 71 * 72 * @param[in] dev Device asking for the addresses. 73 * @param[out] mem_regs_p Pointer to the register range. 74 * @param[out] irq_no IRQ assigned to the device. 75 * @return Error code. 76 */ 77 int get_my_registers(ddf_dev_t *dev, 78 addr_range_t *mem_regs_p, int *irq_no) 79 { 80 assert(dev); 81 82 async_sess_t *parent_sess = devman_parent_device_connect( 83 EXCHANGE_SERIALIZE, ddf_dev_get_handle(dev), IPC_FLAG_BLOCKING); 84 if (!parent_sess) 85 return ENOMEM; 86 87 hw_res_list_parsed_t hw_res; 88 hw_res_list_parsed_init(&hw_res); 89 const int ret = hw_res_get_list_parsed(parent_sess, &hw_res, 0); 90 async_hangup(parent_sess); 91 if (ret != EOK) { 92 return ret; 93 } 94 95 if (hw_res.irqs.count != 1 || hw_res.mem_ranges.count != 1) { 96 hw_res_list_parsed_clean(&hw_res); 97 return ENOENT; 98 } 99 100 if (mem_regs_p) 101 *mem_regs_p = hw_res.mem_ranges.ranges[0]; 102 if (irq_no) 103 *irq_no = hw_res.irqs.irqs[0]; 104 105 hw_res_list_parsed_clean(&hw_res); 106 return EOK; 107 } 108 109 /** Calls the PCI driver with a request to enable interrupts 110 * 111 * @param[in] device Device asking for interrupts 112 * @return Error code. 113 */ 114 int enable_interrupts(ddf_dev_t *device) 115 { 116 async_sess_t *parent_sess = devman_parent_device_connect( 117 EXCHANGE_SERIALIZE, ddf_dev_get_handle(device), IPC_FLAG_BLOCKING); 118 if (!parent_sess) 119 return ENOMEM; 120 121 const bool enabled = hw_res_enable_interrupt(parent_sess); 122 async_hangup(parent_sess); 123 124 return enabled ? EOK : EIO; 125 } 57 126 58 127 /** Implements BIOS hands-off routine as described in EHCI spec … … 73 142 return ENOMEM; 74 143 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 144 /* Read the first EEC. i.e. Legacy Support register */ 83 145 uint32_t usblegsup; 84 int r et= pci_config_space_read_32(parent_sess,146 int rc = pci_config_space_read_32(parent_sess, 85 147 eecp + USBLEGSUP_OFFSET, &usblegsup); 86 CHECK_RET_HANGUP_RETURN(ret, 87 "Failed to read USBLEGSUP: %s.\n", str_error(ret)); 148 if (rc != EOK) { 149 usb_log_error("Failed to read USBLEGSUP: %s.\n", 150 str_error(rc)); 151 goto error; 152 } 153 88 154 usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup); 89 155 … … 91 157 * byte. (OS Control semaphore)*/ 92 158 usb_log_debug("Requesting OS control.\n"); 93 r et= pci_config_space_write_8(parent_sess,159 rc = pci_config_space_write_8(parent_sess, 94 160 eecp + USBLEGSUP_OFFSET + 3, 1); 95 CHECK_RET_HANGUP_RETURN(ret, "Failed to request OS EHCI control: %s.\n", 96 str_error(ret)); 161 if (rc != EOK) { 162 usb_log_error("Failed to request OS EHCI control: %s.\n", 163 str_error(rc)); 164 goto error; 165 } 97 166 98 167 size_t wait = 0; 99 168 /* Wait for BIOS to release control. */ 100 r et= pci_config_space_read_32(169 rc = pci_config_space_read_32( 101 170 parent_sess, eecp + USBLEGSUP_OFFSET, &usblegsup); 171 if (rc != EOK) { 172 usb_log_error("Failed reading PCI config space: %s.\n", 173 str_error(rc)); 174 goto error; 175 } 176 102 177 while ((wait < DEFAULT_WAIT) && (usblegsup & USBLEGSUP_BIOS_CONTROL)) { 103 178 async_usleep(WAIT_STEP); 104 r et= pci_config_space_read_32(parent_sess,179 rc = pci_config_space_read_32(parent_sess, 105 180 eecp + USBLEGSUP_OFFSET, &usblegsup); 181 if (rc != EOK) { 182 usb_log_error("Failed reading PCI config space: %s.\n", 183 str_error(rc)); 184 goto error; 185 } 106 186 wait += WAIT_STEP; 107 187 } … … 116 196 usb_log_warning( "BIOS failed to release control after " 117 197 "%zu usecs, force it.\n", wait); 118 r et= pci_config_space_write_32(parent_sess,198 rc = pci_config_space_write_32(parent_sess, 119 199 eecp + USBLEGSUP_OFFSET, USBLEGSUP_OS_CONTROL); 120 CHECK_RET_HANGUP_RETURN(ret, "Failed to force OS control: " 121 "%s.\n", str_error(ret)); 200 if (rc != EOK) { 201 usb_log_error("Failed to force OS control: " 202 "%s.\n", str_error(rc)); 203 goto error; 204 } 205 122 206 /* 123 207 * Check capability type here, value of 01h identifies the capability … … 129 213 /* Read the second EEC Legacy Support and Control register */ 130 214 uint32_t usblegctlsts; 131 r et= pci_config_space_read_32(parent_sess,215 rc = pci_config_space_read_32(parent_sess, 132 216 eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts); 133 CHECK_RET_HANGUP_RETURN(ret, "Failed to get USBLEGCTLSTS: %s.\n", 134 str_error(ret)); 217 if (rc != EOK) { 218 usb_log_error("Failed to get USBLEGCTLSTS: %s.\n", 219 str_error(rc)); 220 goto error; 221 } 222 135 223 usb_log_debug("USBLEGCTLSTS: %" PRIx32 ".\n", usblegctlsts); 136 224 /* … … 139 227 * interfering. NOTE: Three upper bits are WC 140 228 */ 141 r et= pci_config_space_write_32(parent_sess,229 rc = pci_config_space_write_32(parent_sess, 142 230 eecp + USBLEGCTLSTS_OFFSET, 0xe0000000); 143 CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) zero USBLEGCTLSTS.\n", ret); 231 if (rc != EOK) { 232 usb_log_error("Failed(%d) zero USBLEGCTLSTS.\n", rc); 233 goto error; 234 } 235 144 236 udelay(10); 145 r et= pci_config_space_read_32(parent_sess,237 rc = pci_config_space_read_32(parent_sess, 146 238 eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts); 147 CHECK_RET_HANGUP_RETURN(ret, "Failed to get USBLEGCTLSTS 2: %s.\n", 148 str_error(ret)); 239 if (rc != EOK) { 240 usb_log_error("Failed to get USBLEGCTLSTS 2: %s.\n", 241 str_error(rc)); 242 goto error; 243 } 244 149 245 usb_log_debug("Zeroed USBLEGCTLSTS: %" PRIx32 ".\n", 150 246 usblegctlsts); … … 152 248 153 249 /* Read again Legacy Support register */ 154 r et= pci_config_space_read_32(parent_sess,250 rc = pci_config_space_read_32(parent_sess, 155 251 eecp + USBLEGSUP_OFFSET, &usblegsup); 156 CHECK_RET_HANGUP_RETURN(ret, "Failed to read USBLEGSUP: %s.\n", 157 str_error(ret)); 252 if (rc != EOK) { 253 usb_log_error("Failed to read USBLEGSUP: %s.\n", 254 str_error(rc)); 255 goto error; 256 } 257 158 258 usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup); 159 259 async_hangup(parent_sess); 160 260 return EOK; 161 #undef CHECK_RET_HANGUP_RETURN 261 error: 262 async_hangup(parent_sess); 263 return rc; 162 264 } 163 265 … … 169 271 /* Map EHCI registers */ 170 272 void *regs = NULL; 171 int r et= pio_enable_range(reg_range, ®s);172 if (r et!= EOK) {273 int rc = pio_enable_range(reg_range, ®s); 274 if (rc != EOK) { 173 275 usb_log_error("Failed to map registers %p: %s.\n", 174 RNGABSPTR(*reg_range), str_error(r et));175 return r et;276 RNGABSPTR(*reg_range), str_error(rc)); 277 return rc; 176 278 } 177 279 178 280 usb_log_debug2("Registers mapped at: %p.\n", regs); 179 281 180 ehci_caps_regs_t *ehci_caps = regs; 181 182 const uint32_t hcc_params = EHCI_RD(ehci_caps->hccparams); 282 const uint32_t hcc_params = 283 *(uint32_t*)(regs + HCC_PARAMS_OFFSET); 183 284 usb_log_debug("Value of hcc params register: %x.\n", hcc_params); 184 285 … … 186 287 * position of EEC registers (points to PCI config space) */ 187 288 const uint32_t eecp = 188 (hcc_params >> EHCI_CAPS_HCC_EECP_SHIFT) & EHCI_CAPS_HCC_EECP_MASK;289 (hcc_params >> HCC_PARAMS_EECP_OFFSET) & HCC_PARAMS_EECP_MASK; 189 290 usb_log_debug("Value of EECP: %x.\n", eecp); 190 291 191 r et= disable_extended_caps(device, eecp);192 if (r et!= EOK) {292 rc = disable_extended_caps(device, eecp); 293 if (rc != EOK) { 193 294 usb_log_error("Failed to disable extended capabilities: %s.\n", 194 str_error(ret)); 195 return ret; 196 } 197 295 str_error(rc)); 296 return rc; 297 } 198 298 199 299 /* … … 202 302 203 303 /* Get size of capability registers in memory space. */ 204 const unsigned operation_offset = EHCI_RD8(ehci_caps->caplength);304 const unsigned operation_offset = *(uint8_t*)regs; 205 305 usb_log_debug("USBCMD offset: %d.\n", operation_offset); 206 306 207 ehci_regs_t *ehci_regs = regs + operation_offset; 208 209 usb_log_debug("USBCMD value: %x.\n", EHCI_RD(ehci_regs->usbcmd)); 210 if (EHCI_RD(ehci_regs->usbcmd) & USB_CMD_RUN_FLAG) { 211 EHCI_WR(ehci_regs->usbintr, 0); /* disable all interrupts */ 212 EHCI_WR(ehci_regs->usbsts, 0x3f); /* ack all interrupts */ 213 EHCI_WR(ehci_regs->configflag, 0); /* release RH ports */ 214 EHCI_WR(ehci_regs->usbcmd, 0); 307 /* Zero USBCMD register. */ 308 volatile uint32_t *usbcmd = 309 (uint32_t*)((uint8_t*)regs + operation_offset + CMD_OFFSET); 310 volatile uint32_t *usbsts = 311 (uint32_t*)((uint8_t*)regs + operation_offset + STS_OFFSET); 312 volatile uint32_t *usbconf = 313 (uint32_t*)((uint8_t*)regs + operation_offset + CFG_OFFSET); 314 volatile uint32_t *usbint = 315 (uint32_t*)((uint8_t*)regs + operation_offset + INT_OFFSET); 316 usb_log_debug("USBCMD value: %x.\n", *usbcmd); 317 if (*usbcmd & USBCMD_RUN) { 318 *usbsts = 0x3f; /* ack all interrupts */ 319 *usbint = 0; /* disable all interrupts */ 320 *usbconf = 0; /* release control of RH ports */ 321 322 *usbcmd = 0; 215 323 /* Wait until hc is halted */ 216 while (( EHCI_RD(ehci_regs->usbsts) & USB_STS_HC_HALTED_FLAG) == 0);324 while ((*usbsts & USBSTS_HALTED) == 0); 217 325 usb_log_info("EHCI turned off.\n"); 218 326 } else { … … 224 332 "\t USBINT(%p): %x(0x0 = no interrupts).\n" 225 333 "\t CONFIG(%p): %x(0x0 = ports controlled by companion hc).\n", 226 &ehci_regs->usbcmd, EHCI_RD(ehci_regs->usbcmd), 227 &ehci_regs->usbsts, EHCI_RD(ehci_regs->usbsts), 228 &ehci_regs->usbintr, EHCI_RD(ehci_regs->usbintr), 229 &ehci_regs->configflag, EHCI_RD(ehci_regs->configflag)); 230 231 return ret; 334 usbcmd, *usbcmd, usbsts, *usbsts, usbint, *usbint, usbconf,*usbconf); 335 336 return rc; 232 337 } 233 338
Note:
See TracChangeset
for help on using the changeset viewer.