protected UHCI_qTD_Struct *CreateQTD_IO(UHCI_QueueHead_Struct *uQH, uint *next, byte direction, bool toggle, ushort tokenBytes, byte device, byte endpoint, uint packetSize) { #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Create qTD IO"); BasicConsole.DelayOutput(5); #endif UHCI_qTD_Struct *td = AllocQTD(next); UHCI_qTD.SetPacketID(td, direction); if (tokenBytes != 0) { UHCI_qTD.SetMaxLength(td, (ushort)((tokenBytes - 1u) & 0x7FFu)); } else { UHCI_qTD.SetMaxLength(td, 0x7FF); } UHCI_qTD.SetDataToggle(td, toggle); UHCI_qTD.SetC_ERR(td, 0x3); UHCI_qTD.SetDeviceAddress(td, device); UHCI_qTD.SetEndpoint(td, endpoint); AllocQTDbuffer(td); uQH->q_last = td; return(td); }
protected UHCI_qTD_Struct *CreateQTD_SETUP(UHCI_QueueHead_Struct *uQH, uint *next, bool toggle, ushort tokenBytes, byte type, byte req, byte hiVal, byte loVal, ushort i, ushort length, byte device, byte endpoint, uint packetSize) { #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Create qTD SETUP"); BasicConsole.DelayOutput(5); #endif UHCI_qTD_Struct *td = AllocQTD(next); UHCI_qTD.SetPacketID(td, UHCI_Consts.TD_SETUP); UHCI_qTD.SetDataToggle(td, toggle); UHCI_qTD.SetDeviceAddress(td, device); UHCI_qTD.SetEndpoint(td, endpoint); UHCI_qTD.SetMaxLength(td, (ushort)(tokenBytes - 1)); UHCI_qTD.SetC_ERR(td, 0x3); //TODO: *buffer = USBRequest *request = (USBRequest *)(AllocQTDbuffer(td)); request->type = type; request->request = req; request->valueHi = hiVal; request->valueLo = loVal; request->index = i; request->length = length; uQH->q_last = td; return(td); }
protected void CreateQH(UHCI_QueueHead_Struct *head, uint horizPtr, UHCI_qTD_Struct *firstTD) { #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Create QH"); BasicConsole.DelayOutput(5); #endif head->next = (UHCI_QueueHead_Struct *)UHCI_Consts.BIT_T; // (paging_getPhysAddr((void*)horizPtr) & 0xFFFFFFF0) | BIT_QH; if (firstTD == null) { head->transfer = (UHCI_qTD_Struct *)UHCI_Consts.BIT_T; } else { head->transfer = (UHCI_qTD_Struct *)((uint)VirtMemManager.GetPhysicalAddress(firstTD) & 0xFFFFFFF0); head->q_first = firstTD; } }
protected void ResetHC() { #if UHCI_TRACE BasicConsole.WriteLine("UHCI: ResetHC"); BasicConsole.DelayOutput(5); #endif //Processes.Scheduler.Disable(); // http://www.lowlevel.eu/wiki/Universal_Host_Controller_Interface#Informationen_vom_PCI-Treiber_holen ushort legacySupport = pciDevice.ReadRegister16(UHCI_Consts.PCI_LEGACY_SUPPORT); pciDevice.WriteRegister16(UHCI_Consts.PCI_LEGACY_SUPPORT, UHCI_Consts.PCI_LEGACY_SUPPORT_STATUS); // resets support status bits in Legacy support register USBCMD.Write_UInt16(UHCI_Consts.CMD_GRESET); Hardware.Devices.Timer.Default.Wait(50); USBCMD.Write_UInt16(0); RootPortCount = (byte)(pciDevice.BaseAddresses[4].Size() / 2); #if UHCI_TRACE BasicConsole.WriteLine(((FOS_System.String)"UHCI: RootPortCount=") + RootPortCount); #endif for (byte i = 2; i < RootPortCount; i++) { if ((PORTSC1.Read_UInt16((ushort)(i * 2)) & UHCI_Consts.PORT_VALID) == 0 || (PORTSC1.Read_UInt16((ushort)(i * 2)) == 0xFFFF)) { RootPortCount = i; break; } } #if UHCI_TRACE BasicConsole.WriteLine(((FOS_System.String)"UHCI: RootPortCount=") + RootPortCount); #endif if (RootPortCount > UHCI_Consts.PORTMAX) { RootPortCount = UHCI_Consts.PORTMAX; } #if UHCI_TRACE BasicConsole.WriteLine(((FOS_System.String)"UHCI: RootPortCount=") + RootPortCount); BasicConsole.DelayOutput(1); #endif RootPorts.Empty(); for (byte i = 0; i < RootPortCount; i++) { RootPorts.Add(new HCPort() { portNum = i }); } #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Checking HC state: Get USBCMD..."); BasicConsole.DelayOutput(1); #endif ushort usbcmd = USBCMD.Read_UInt16(); #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Checking HC state: Check..."); BasicConsole.DelayOutput(1); #endif if ((legacySupport & ~(UHCI_Consts.PCI_LEGACY_SUPPORT_STATUS | UHCI_Consts.PCI_LEGACY_SUPPORT_NO_CHG | UHCI_Consts.PCI_LEGACY_SUPPORT_PIRQ)) != 0 || (usbcmd & UHCI_Consts.CMD_RS) != 0 || (usbcmd & UHCI_Consts.CMD_CF) != 0 || (usbcmd & UHCI_Consts.CMD_EGSM) == 0 || (USBINTR.Read_UInt16() & UHCI_Consts.INT_MASK) != 0) { #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Checking HC state: Do reset..."); BasicConsole.DelayOutput(1); #endif USBSTS.Write_UInt16(UHCI_Consts.STS_MASK); Hardware.Devices.Timer.Default.Wait(1); USBCMD.Write_UInt16(UHCI_Consts.CMD_HCRESET); byte timeout = 50; while ((USBCMD.Read_UInt16() & UHCI_Consts.CMD_HCRESET) != 0) { if (timeout == 0) { #if UHCI_TRACE BasicConsole.WriteLine("UHCI: HC Reset timed out!"); BasicConsole.DelayOutput(1); #endif break; } Hardware.Devices.Timer.Default.Wait(10); timeout--; } #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Checking HC state: Turning off interrupts and HC..."); BasicConsole.DelayOutput(1); #endif USBINTR.Write_UInt16(0); // switch off all interrupts USBCMD.Write_UInt16(0); // switch off the host controller #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Checking HC state: Disabling ports..."); BasicConsole.DelayOutput(1); #endif for (byte i = 0; i < RootPortCount; i++) // switch off the valid root ports { PORTSC1.Write_UInt16(0, (ushort)(i * 2)); } } // TODO: mutex for frame list #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Creating queue head..."); BasicConsole.DelayOutput(1); #endif UHCI_QueueHead_Struct* qh = (UHCI_QueueHead_Struct*)FOS_System.Heap.AllocZeroedAPB((uint)sizeof(UHCI_QueueHead_Struct), 32, "UHCI : ResetHC"); qh->next = (UHCI_QueueHead_Struct*)UHCI_Consts.BIT_T; qh->transfer = (UHCI_qTD_Struct*)UHCI_Consts.BIT_T; qh->q_first = null; qh->q_last = null; qhPointer = qh; #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Setting up frame list entries..."); BasicConsole.DelayOutput(1); #endif for (ushort i = 0; i < 1024; i++) { FrameList[i] = UHCI_Consts.BIT_T; } #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Setting SOFMOD..."); BasicConsole.DelayOutput(1); #endif // define each millisecond one frame, provide physical address of frame list, and start at frame 0 SOFMOD.Write_Byte(0x40); // SOF cycle time: 12000. For a 12 MHz SOF counter clock input, this produces a 1 ms Frame period. #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Setting frame base addr and frame num..."); BasicConsole.DelayOutput(1); #endif FRBASEADD.Write_UInt32((uint)VirtMemManager.GetPhysicalAddress(FrameList)); FRNUM.Write_UInt16(0); #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Setting PCI PIRQ..."); BasicConsole.DelayOutput(1); #endif // set PIRQ pciDevice.WriteRegister16(UHCI_Consts.PCI_LEGACY_SUPPORT, UHCI_Consts.PCI_LEGACY_SUPPORT_PIRQ); #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Starting HC..."); BasicConsole.DelayOutput(1); #endif // start host controller and mark it configured with a 64-byte max packet USBSTS.Write_UInt16(UHCI_Consts.STS_MASK); USBINTR.Write_UInt16(UHCI_Consts.INT_MASK); // switch on all interrupts USBCMD.Write_UInt16((ushort)(UHCI_Consts.CMD_RS | UHCI_Consts.CMD_CF | UHCI_Consts.CMD_MAXP)); #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Reset CSC ports..."); BasicConsole.DelayOutput(1); #endif for (byte i = 0; i < RootPortCount; i++) // reset the CSC of the valid root ports { PORTSC1.Write_UInt16(UHCI_Consts.PORT_CS_CHANGE, (ushort)(i * 2)); } #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Forcing global resume..."); BasicConsole.DelayOutput(1); #endif USBSTS.Write_UInt16(UHCI_Consts.STS_MASK); #if UHCI_TRACE BasicConsole.WriteLine(" - STS MASK set"); #endif USBCMD.Write_UInt16((ushort)(UHCI_Consts.CMD_RS | UHCI_Consts.CMD_CF | UHCI_Consts.CMD_MAXP | UHCI_Consts.CMD_FGR)); #if UHCI_TRACE BasicConsole.WriteLine(" - FGR issued"); #endif Hardware.Devices.Timer.Default.Wait(20); USBCMD.Write_UInt16((ushort)(UHCI_Consts.CMD_RS | UHCI_Consts.CMD_CF | UHCI_Consts.CMD_MAXP)); #if UHCI_TRACE BasicConsole.WriteLine(" - FGR cleared"); BasicConsole.DelayOutput(1); #endif Hardware.Devices.Timer.Default.Wait(100); #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Getting run state..."); BasicConsole.DelayOutput(1); #endif run = (USBCMD.Read_UInt16() & UHCI_Consts.CMD_RS) != 0; if (!run) { BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine("UHCI: Run/Stop not set!"); BasicConsole.SetTextColour(BasicConsole.default_colour); BasicConsole.DelayOutput(5); } else { if ((USBSTS.Read_UInt16() & UHCI_Consts.STS_HCHALTED) == 0) { Status = HCIStatus.Active; EnablePorts(); // attaches the ports } else { BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine("UHCI: HC Halted!"); BasicConsole.SetTextColour(BasicConsole.default_colour); BasicConsole.DelayOutput(5); } } }
protected void ResetHC() { #if UHCI_TRACE BasicConsole.WriteLine("UHCI: ResetHC"); BasicConsole.DelayOutput(5); #endif //Processes.Scheduler.Disable(); // http://www.lowlevel.eu/wiki/Universal_Host_Controller_Interface#Informationen_vom_PCI-Treiber_holen ushort legacySupport = pciDevice.ReadRegister16(UHCI_Consts.PCI_LEGACY_SUPPORT); pciDevice.WriteRegister16(UHCI_Consts.PCI_LEGACY_SUPPORT, UHCI_Consts.PCI_LEGACY_SUPPORT_STATUS); // resets support status bits in Legacy support register USBCMD.Write_UInt16(UHCI_Consts.CMD_GRESET); Hardware.Devices.Timer.Default.Wait(50); USBCMD.Write_UInt16(0); RootPortCount = (byte)(pciDevice.BaseAddresses[4].Size() / 2); #if UHCI_TRACE BasicConsole.WriteLine(((FOS_System.String) "UHCI: RootPortCount=") + RootPortCount); #endif for (byte i = 2; i < RootPortCount; i++) { if ((PORTSC1.Read_UInt16((ushort)(i * 2)) & UHCI_Consts.PORT_VALID) == 0 || (PORTSC1.Read_UInt16((ushort)(i * 2)) == 0xFFFF)) { RootPortCount = i; break; } } #if UHCI_TRACE BasicConsole.WriteLine(((FOS_System.String) "UHCI: RootPortCount=") + RootPortCount); #endif if (RootPortCount > UHCI_Consts.PORTMAX) { RootPortCount = UHCI_Consts.PORTMAX; } #if UHCI_TRACE BasicConsole.WriteLine(((FOS_System.String) "UHCI: RootPortCount=") + RootPortCount); BasicConsole.DelayOutput(1); #endif RootPorts.Empty(); for (byte i = 0; i < RootPortCount; i++) { RootPorts.Add(new HCPort() { portNum = i }); } #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Checking HC state: Get USBCMD..."); BasicConsole.DelayOutput(1); #endif ushort usbcmd = USBCMD.Read_UInt16(); #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Checking HC state: Check..."); BasicConsole.DelayOutput(1); #endif if ((legacySupport & ~(UHCI_Consts.PCI_LEGACY_SUPPORT_STATUS | UHCI_Consts.PCI_LEGACY_SUPPORT_NO_CHG | UHCI_Consts.PCI_LEGACY_SUPPORT_PIRQ)) != 0 || (usbcmd & UHCI_Consts.CMD_RS) != 0 || (usbcmd & UHCI_Consts.CMD_CF) != 0 || (usbcmd & UHCI_Consts.CMD_EGSM) == 0 || (USBINTR.Read_UInt16() & UHCI_Consts.INT_MASK) != 0) { #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Checking HC state: Do reset..."); BasicConsole.DelayOutput(1); #endif USBSTS.Write_UInt16(UHCI_Consts.STS_MASK); Hardware.Devices.Timer.Default.Wait(1); USBCMD.Write_UInt16(UHCI_Consts.CMD_HCRESET); byte timeout = 50; while ((USBCMD.Read_UInt16() & UHCI_Consts.CMD_HCRESET) != 0) { if (timeout == 0) { #if UHCI_TRACE BasicConsole.WriteLine("UHCI: HC Reset timed out!"); BasicConsole.DelayOutput(1); #endif break; } Hardware.Devices.Timer.Default.Wait(10); timeout--; } #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Checking HC state: Turning off interrupts and HC..."); BasicConsole.DelayOutput(1); #endif USBINTR.Write_UInt16(0); // switch off all interrupts USBCMD.Write_UInt16(0); // switch off the host controller #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Checking HC state: Disabling ports..."); BasicConsole.DelayOutput(1); #endif for (byte i = 0; i < RootPortCount; i++) // switch off the valid root ports { PORTSC1.Write_UInt16(0, (ushort)(i * 2)); } } // TODO: mutex for frame list #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Creating queue head..."); BasicConsole.DelayOutput(1); #endif UHCI_QueueHead_Struct *qh = (UHCI_QueueHead_Struct *)FOS_System.Heap.AllocZeroedAPB((uint)sizeof(UHCI_QueueHead_Struct), 32, "UHCI : ResetHC"); qh->next = (UHCI_QueueHead_Struct *)UHCI_Consts.BIT_T; qh->transfer = (UHCI_qTD_Struct *)UHCI_Consts.BIT_T; qh->q_first = null; qh->q_last = null; qhPointer = qh; #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Setting up frame list entries..."); BasicConsole.DelayOutput(1); #endif for (ushort i = 0; i < 1024; i++) { FrameList[i] = UHCI_Consts.BIT_T; } #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Setting SOFMOD..."); BasicConsole.DelayOutput(1); #endif // define each millisecond one frame, provide physical address of frame list, and start at frame 0 SOFMOD.Write_Byte(0x40); // SOF cycle time: 12000. For a 12 MHz SOF counter clock input, this produces a 1 ms Frame period. #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Setting frame base addr and frame num..."); BasicConsole.DelayOutput(1); #endif FRBASEADD.Write_UInt32((uint)VirtMemManager.GetPhysicalAddress(FrameList)); FRNUM.Write_UInt16(0); #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Setting PCI PIRQ..."); BasicConsole.DelayOutput(1); #endif // set PIRQ pciDevice.WriteRegister16(UHCI_Consts.PCI_LEGACY_SUPPORT, UHCI_Consts.PCI_LEGACY_SUPPORT_PIRQ); #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Starting HC..."); BasicConsole.DelayOutput(1); #endif // start host controller and mark it configured with a 64-byte max packet USBSTS.Write_UInt16(UHCI_Consts.STS_MASK); USBINTR.Write_UInt16(UHCI_Consts.INT_MASK); // switch on all interrupts USBCMD.Write_UInt16((ushort)(UHCI_Consts.CMD_RS | UHCI_Consts.CMD_CF | UHCI_Consts.CMD_MAXP)); #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Reset CSC ports..."); BasicConsole.DelayOutput(1); #endif for (byte i = 0; i < RootPortCount; i++) // reset the CSC of the valid root ports { PORTSC1.Write_UInt16(UHCI_Consts.PORT_CS_CHANGE, (ushort)(i * 2)); } #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Forcing global resume..."); BasicConsole.DelayOutput(1); #endif USBSTS.Write_UInt16(UHCI_Consts.STS_MASK); #if UHCI_TRACE BasicConsole.WriteLine(" - STS MASK set"); #endif USBCMD.Write_UInt16((ushort)(UHCI_Consts.CMD_RS | UHCI_Consts.CMD_CF | UHCI_Consts.CMD_MAXP | UHCI_Consts.CMD_FGR)); #if UHCI_TRACE BasicConsole.WriteLine(" - FGR issued"); #endif Hardware.Devices.Timer.Default.Wait(20); USBCMD.Write_UInt16((ushort)(UHCI_Consts.CMD_RS | UHCI_Consts.CMD_CF | UHCI_Consts.CMD_MAXP)); #if UHCI_TRACE BasicConsole.WriteLine(" - FGR cleared"); BasicConsole.DelayOutput(1); #endif Hardware.Devices.Timer.Default.Wait(100); #if UHCI_TRACE BasicConsole.WriteLine("UHCI: Getting run state..."); BasicConsole.DelayOutput(1); #endif run = (USBCMD.Read_UInt16() & UHCI_Consts.CMD_RS) != 0; if (!run) { BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine("UHCI: Run/Stop not set!"); BasicConsole.SetTextColour(BasicConsole.default_colour); BasicConsole.DelayOutput(5); } else { if ((USBSTS.Read_UInt16() & UHCI_Consts.STS_HCHALTED) == 0) { Status = HCIStatus.Active; EnablePorts(); // attaches the ports } else { BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine("UHCI: HC Halted!"); BasicConsole.SetTextColour(BasicConsole.default_colour); BasicConsole.DelayOutput(5); } } }