Changeset dbbba51c in mainline
- Timestamp:
- 2012-03-15T22:46:18Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 14f8fd4
- Parents:
- 68e48db
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ehci/res.c
r68e48db rdbbba51c 128 128 } 129 129 /*----------------------------------------------------------------------------*/ 130 /** Implements BIOS handoff routine as decribed in EHCI spec 131 * 132 * @param[in] device Device asking for interrupts 130 /** Implements BIOS hands-off routine as described in EHCI spec 131 * 132 * @param device EHCI device 133 * @param eecp Value of EHCI Extended Capabilities pointer. 133 134 * @return Error code. 134 135 */ 135 int disable_legacy(const ddf_dev_t *device, uintptr_t reg_base, size_t reg_size)136 static int disable_extended_caps(const ddf_dev_t *device, unsigned eecp) 136 137 { 137 assert(device); 138 /* nothing to do */ 139 if (eecp == 0) 140 return EOK; 141 138 142 async_sess_t *parent_sess = devman_parent_device_connect( 139 143 EXCHANGE_SERIALIZE, device->handle, IPC_FLAG_BLOCKING); … … 141 145 return ENOMEM; 142 146 143 #define CHECK_RET_ RETURN(ret, message...) \147 #define CHECK_RET_HANGUP_RETURN(ret, message...) \ 144 148 if (ret != EOK) { \ 145 149 usb_log_error(message); \ … … 148 152 } else (void)0 149 153 154 /* Read the first EEC. i.e. Legacy Support register */ 155 uint32_t usblegsup; 156 int ret = pci_config_space_read_32(parent_sess, 157 eecp + USBLEGSUP_OFFSET, &usblegsup); 158 CHECK_RET_HANGUP_RETURN(ret, 159 "Failed to read USBLEGSUP: %s.\n", str_error(ret)); 160 usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup); 161 162 /* Request control from firmware/BIOS by writing 1 to highest 163 * byte. (OS Control semaphore)*/ 164 usb_log_debug("Requesting OS control.\n"); 165 ret = pci_config_space_write_8(parent_sess, 166 eecp + USBLEGSUP_OFFSET + 3, 1); 167 CHECK_RET_HANGUP_RETURN(ret, "Failed to request OS EHCI control: %s.\n", 168 str_error(ret)); 169 170 size_t wait = 0; 171 /* Wait for BIOS to release control. */ 172 ret = pci_config_space_read_32( 173 parent_sess, eecp + USBLEGSUP_OFFSET, &usblegsup); 174 while ((wait < DEFAULT_WAIT) && (usblegsup & USBLEGSUP_BIOS_CONTROL)) { 175 async_usleep(WAIT_STEP); 176 ret = pci_config_space_read_32(parent_sess, 177 eecp + USBLEGSUP_OFFSET, &usblegsup); 178 wait += WAIT_STEP; 179 } 180 181 if ((usblegsup & USBLEGSUP_BIOS_CONTROL) == 0) { 182 usb_log_info("BIOS released control after %zu usec.\n", wait); 183 async_hangup(parent_sess); 184 return EOK; 185 } 186 187 /* BIOS failed to hand over control, this should not happen. */ 188 usb_log_warning( "BIOS failed to release control after " 189 "%zu usecs, force it.\n", wait); 190 ret = pci_config_space_write_32(parent_sess, 191 eecp + USBLEGSUP_OFFSET, USBLEGSUP_OS_CONTROL); 192 CHECK_RET_HANGUP_RETURN(ret, "Failed to force OS control: " 193 "%s.\n", str_error(ret)); 194 /* 195 * Check capability type here, value of 01h identifies the capability 196 * as Legacy Support. This extended capability requires one additional 197 * 32-bit register for control/status information and this register is 198 * located at offset EECP+04h 199 */ 200 if ((usblegsup & 0xff) == 1) { 201 /* Read the second EEC Legacy Support and Control register */ 202 uint32_t usblegctlsts; 203 ret = pci_config_space_read_32(parent_sess, 204 eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts); 205 CHECK_RET_HANGUP_RETURN(ret, "Failed to get USBLEGCTLSTS: %s.\n", 206 str_error(ret)); 207 usb_log_debug("USBLEGCTLSTS: %" PRIx32 ".\n", usblegctlsts); 208 /* 209 * Zero SMI enables in legacy control register. 210 * It should prevent pre-OS code from 211 * interfering. NOTE: Three upper bits are WC 212 */ 213 ret = pci_config_space_write_32(parent_sess, 214 eecp + USBLEGCTLSTS_OFFSET, 0xe0000000); 215 CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) zero USBLEGCTLSTS.\n", ret); 216 udelay(10); 217 ret = pci_config_space_read_32(parent_sess, 218 eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts); 219 CHECK_RET_HANGUP_RETURN(ret, "Failed to get USBLEGCTLSTS 2: %s.\n", 220 str_error(ret)); 221 usb_log_debug("Zeroed USBLEGCTLSTS: %" PRIx32 ".\n", 222 usblegctlsts); 223 } 224 225 /* Read again Legacy Support register */ 226 ret = pci_config_space_read_32(parent_sess, 227 eecp + USBLEGSUP_OFFSET, &usblegsup); 228 CHECK_RET_HANGUP_RETURN(ret, "Failed to read USBLEGSUP: %s.\n", 229 str_error(ret)); 230 usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup); 231 async_hangup(parent_sess); 232 return EOK; 233 #undef CHECK_RET_HANGUP_RETURN 234 } 235 236 int disable_legacy(const ddf_dev_t *device, uintptr_t reg_base, size_t reg_size) 237 { 238 assert(device); 239 240 #define CHECK_RET_RETURN(ret, message...) \ 241 if (ret != EOK) { \ 242 usb_log_error(message); \ 243 return ret; \ 244 } else (void)0 245 150 246 /* Map EHCI registers */ 151 247 void *regs = NULL; … … 164 260 usb_log_debug("Value of EECP: %x.\n", eecp); 165 261 166 /* Read the first EEC. i.e. Legacy Support register */ 167 uint32_t usblegsup; 168 ret = pci_config_space_read_32(parent_sess, 169 eecp + USBLEGSUP_OFFSET, &usblegsup); 170 CHECK_RET_RETURN(ret, "Failed to read USBLEGSUP: %s.\n", str_error(ret)); 171 usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup); 172 173 /* Request control from firmware/BIOS, by writing 1 to highest byte. 174 * (OS Control semaphore)*/ 175 usb_log_debug("Requesting OS control.\n"); 176 ret = pci_config_space_write_8(parent_sess, 177 eecp + USBLEGSUP_OFFSET + 3, 1); 178 CHECK_RET_RETURN(ret, "Failed to request OS EHCI control: %s.\n", 262 ret = disable_extended_caps(device, eecp); 263 CHECK_RET_RETURN(ret, "Failed to disable extended capabilities: %s.\n", 179 264 str_error(ret)); 180 265 181 size_t wait = 0;182 /* Wait for BIOS to release control. */183 ret = pci_config_space_read_32(parent_sess,184 eecp + USBLEGSUP_OFFSET, &usblegsup);185 while ((wait < DEFAULT_WAIT) && (usblegsup & USBLEGSUP_BIOS_CONTROL)) {186 async_usleep(WAIT_STEP);187 ret = pci_config_space_read_32(parent_sess,188 eecp + USBLEGSUP_OFFSET, &usblegsup);189 wait += WAIT_STEP;190 }191 192 193 if ((usblegsup & USBLEGSUP_BIOS_CONTROL) == 0) {194 usb_log_info("BIOS released control after %zu usec.\n", wait);195 } else {196 /* BIOS failed to hand over control, this should not happen. */197 usb_log_warning( "BIOS failed to release control after "198 "%zu usecs, force it.\n", wait);199 ret = pci_config_space_write_32(parent_sess,200 eecp + USBLEGSUP_OFFSET, USBLEGSUP_OS_CONTROL);201 CHECK_RET_RETURN(ret, "Failed to force OS control: %s.\n",202 str_error(ret));203 /* Check capability type here, A value of 01h204 * identifies the capability as Legacy Support.205 * This extended capability requires one206 * additional 32-bit register for control/status information,207 * and this register is located at offset EECP+04h208 * */209 if ((usblegsup & 0xff) == 1) {210 /* Read the second EEC211 * Legacy Support and Control register */212 uint32_t usblegctlsts;213 ret = pci_config_space_read_32(parent_sess,214 eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts);215 CHECK_RET_RETURN(ret,216 "Failed to get USBLEGCTLSTS: %s.\n", str_error(ret));217 usb_log_debug("USBLEGCTLSTS: %" PRIx32 ".\n",218 usblegctlsts);219 /* Zero SMI enables in legacy control register.220 * It should prevent pre-OS code from interfering.221 * Three upper bits are WC */222 ret = pci_config_space_write_32(parent_sess,223 eecp + USBLEGCTLSTS_OFFSET, 0xe0000000);224 CHECK_RET_RETURN(ret,225 "Failed(%d) zero USBLEGCTLSTS.\n", ret);226 udelay(10);227 ret = pci_config_space_read_32(parent_sess,228 eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts);229 CHECK_RET_RETURN(ret,230 "Failed to get USBLEGCTLSTS 2: %s.\n",231 str_error(ret));232 usb_log_debug("Zeroed USBLEGCTLSTS: %" PRIx32 ".\n",233 usblegctlsts);234 }235 }236 237 238 /* Read again Legacy Support register */239 ret = pci_config_space_read_32(parent_sess,240 eecp + USBLEGSUP_OFFSET, &usblegsup);241 CHECK_RET_RETURN(ret, "Failed to read USBLEGSUP: %s.\n", str_error(ret));242 usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup);243 244 async_hangup(parent_sess);245 266 #undef CHECK_RET_RETURN 246 267
Note:
See TracChangeset
for help on using the changeset viewer.