Ticket #8085: usbOHCIStartupV2.diff
File usbOHCIStartupV2.diff, 3.2 KB (added by , 12 years ago) |
---|
-
src/add-ons/kernel/busses/usb/ohci.cpp
diff --git a/src/add-ons/kernel/busses/usb/ohci.cpp b/src/add-ons/kernel/busses/usb/ohci.cpp index c9f2c1a..7123b3b 100644
a b OHCI::OHCI(pci_info *info, Stack *stack) 204 204 fInterruptEndpoints[0]->next_physical_endpoint 205 205 = fDummyIsochronous->physical_address; 206 206 207 // Disable all interrupts before handoff/reset208 _WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTERRUPTS);209 210 207 // Determine in what context we are running (Kindly copied from FreeBSD) 211 208 uint32 control = _ReadReg(OHCI_CONTROL); 212 if (control & OHCI_INTERRUPT_ROUTING) { 209 if ((control & OHCI_INTERRUPT_ROUTING) != 0) { 210 // SMM in control, ask for control of USB 213 211 TRACE_ALWAYS("smm is in control of the host controller\n"); 214 212 uint32 status = _ReadReg(OHCI_COMMAND_STATUS); 215 213 _WriteReg(OHCI_COMMAND_STATUS, status | OHCI_OWNERSHIP_CHANGE_REQUEST); … … OHCI::OHCI(pci_info *info, Stack *stack) 218 216 control = _ReadReg(OHCI_CONTROL); 219 217 } 220 218 219 // Disable all interrupts to prevent interrupt storm 220 _WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTERRUPTS); 221 221 222 if ((control & OHCI_INTERRUPT_ROUTING) != 0) { 222 TRACE_ERROR("smm does not respond. resetting...\n"); 223 TRACE_ERROR("smm is not responding. Resetting...\n"); 224 // Last resort 223 225 _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET); 224 226 snooze(USB_DELAY_BUS_RESET); 225 } else 227 } else { 226 228 TRACE_ALWAYS("ownership change successful\n"); 229 } 227 230 } else { 228 TRACE("cold started\n"); 229 snooze(USB_DELAY_BUS_RESET); 231 // SMM *not* in control, resume or reset USB bus 232 233 // Disable all interrupts to prevent interrupt storm 234 _WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTERRUPTS); 235 236 control = _ReadReg(OHCI_CONTROL) & OHCI_HC_FUNCTIONAL_STATE_MASK; 237 if ((control & OHCI_HC_FUNCTIONAL_STATE_RESET) == 0) { 238 TRACE("no smm, BIOS active. Attempting resume...\n"); 239 if ((control & OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL) == 0) { 240 _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESUME); 241 for (uint32 i = 0; i < 100 242 && !(control & OHCI_HC_FUNCTIONAL_STATE_RESUME); i++) { 243 snooze(1000); 244 control = _ReadReg(OHCI_CONTROL) 245 & OHCI_HC_FUNCTIONAL_STATE_MASK; 246 } 247 if ((control & OHCI_HC_FUNCTIONAL_STATE_RESUME) == 0) 248 TRACE_ALWAYS("failed to resume controller\n"); 249 } else { 250 TRACE_ALWAYS("bus not reset, and not operational?\n"); 251 } 252 } else { 253 TRACE("no smm, no BIOS. Attempting reset...\n"); 254 255 _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET); 256 snooze(USB_DELAY_BUS_RESET); 257 for (uint32 i = 0; i < 100 258 && !(control & OHCI_HC_FUNCTIONAL_STATE_RESET); i++) { 259 snooze(1000); 260 control = _ReadReg(OHCI_CONTROL) 261 & OHCI_HC_FUNCTIONAL_STATE_MASK; 262 } 263 if ((control & OHCI_HC_FUNCTIONAL_STATE_RESET) == 0) 264 TRACE_ALWAYS("failed to reset controller\n"); 265 } 230 266 } 231 267 268 #if 0 232 269 // This reset should not be necessary according to the OHCI spec, but 233 270 // without it some controllers do not start. 234 271 _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET); 235 272 snooze(USB_DELAY_BUS_RESET); 273 #endif 236 274 237 275 // We now own the host controller and the bus has been reset 238 276 uint32 frameInterval = _ReadReg(OHCI_FRAME_INTERVAL);