Ticket #8085: usbOHCIStartupV1.diff
File usbOHCIStartupV1.diff, 3.1 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..c61f631 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) 219 217 } 220 218 221 219 if ((control & OHCI_INTERRUPT_ROUTING) != 0) { 222 TRACE_ERROR("smm does not respond. resetting...\n"); 220 TRACE_ERROR("smm is not responding. Resetting...\n"); 221 // Last resort 223 222 _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET); 224 223 snooze(USB_DELAY_BUS_RESET); 225 } else 224 } else { 226 225 TRACE_ALWAYS("ownership change successful\n"); 226 // Disable all interrupts 227 _WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTERRUPTS); 228 } 227 229 } else { 228 TRACE("cold started\n"); 229 snooze(USB_DELAY_BUS_RESET); 230 // SMM *not* in control, resume or reset USB bus 231 // Disable all interrupts 232 _WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTERRUPTS); 233 control = _ReadReg(OHCI_CONTROL) & OHCI_HC_FUNCTIONAL_STATE_MASK; 234 if ((control & OHCI_HC_FUNCTIONAL_STATE_RESET) == 0) { 235 TRACE("no smm, BIOS active. Attempting resume...\n"); 236 if ((control & OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL) == 0) { 237 _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESUME); 238 for (uint32 i = 0; i < 100 239 && !(control & OHCI_HC_FUNCTIONAL_STATE_RESUME); i++) { 240 snooze(1000); 241 control = _ReadReg(OHCI_CONTROL) 242 & OHCI_HC_FUNCTIONAL_STATE_MASK; 243 } 244 if ((control & OHCI_HC_FUNCTIONAL_STATE_RESUME) == 0) 245 TRACE_ALWAYS("failed to resume controller\n"); 246 } else { 247 TRACE_ALWAYS("bus not reset, and not operational?\n"); 248 } 249 } else { 250 TRACE("no smm, no BIOS. Attempting reset...\n"); 251 252 _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET); 253 snooze(USB_DELAY_BUS_RESET); 254 for (uint32 i = 0; i < 100 255 && !(control & OHCI_HC_FUNCTIONAL_STATE_RESET); i++) { 256 snooze(1000); 257 control = _ReadReg(OHCI_CONTROL) 258 & OHCI_HC_FUNCTIONAL_STATE_MASK; 259 } 260 if ((control & OHCI_HC_FUNCTIONAL_STATE_RESET) == 0) 261 TRACE_ALWAYS("failed to reset controller\n"); 262 } 230 263 } 231 264 265 #if 0 232 266 // This reset should not be necessary according to the OHCI spec, but 233 267 // without it some controllers do not start. 234 268 _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET); 235 269 snooze(USB_DELAY_BUS_RESET); 270 #endif 236 271 237 272 // We now own the host controller and the bus has been reset 238 273 uint32 frameInterval = _ReadReg(OHCI_FRAME_INTERVAL);