Author: janderwald Date: Wed Feb 22 14:11:23 2012 New Revision: 55806
URL: http://svn.reactos.org/svn/reactos?rev=55806&view=rev Log: [USBUHCI] - Write the configure bit - Clear connection change and port suspend bit when set after controller initialization - Queue work item after the reset port is complete - Disable port before reseting it - Wait time for reset is 50ms, not 25ms - Clear reset change bit when clearing reset feature - Implement enabling port feature
Modified: trunk/reactos/drivers/usb/usbuhci/hardware.cpp trunk/reactos/drivers/usb/usbuhci/hardware.h trunk/reactos/drivers/usb/usbuhci/usb_request.cpp trunk/reactos/drivers/usb/usbuhci/usbuhci.h
Modified: trunk/reactos/drivers/usb/usbuhci/hardware.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbuhci/hardwar... ============================================================================== --- trunk/reactos/drivers/usb/usbuhci/hardware.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/usb/usbuhci/hardware.cpp [iso-8859-1] Wed Feb 22 14:11:23 2012 @@ -289,7 +289,7 @@ // Store Resource base // m_Base = (PULONG)ResourceDescriptor->u.Port.Start.LowPart; //FIXME - DPRINT1("UHCI Base %p\n", m_Base); + DPRINT1("UHCI Base %p Length %x\n", m_Base, ResourceDescriptor->u.Port.Length); break; } } @@ -499,6 +499,9 @@ } }
+ DPRINT1("[USBUHCI] USBCMD: %x USBSTS %x\n", ReadRegister16(UHCI_USBCMD), ReadRegister16(UHCI_USBSTS)); + + if ((Status & UHCI_USBSTS_HCHALT)) { // @@ -509,9 +512,31 @@ return STATUS_UNSUCCESSFUL; }
+ // + // Set the configure bit + // + WriteRegister16(UHCI_USBCMD, ReadRegister16(UHCI_USBCMD) | UHCI_USBCMD_CF); + + for(Index = 0; Index < 2; Index++) + { + // + // get port status + // + Status = ReadRegister16(UHCI_PORTSC1 + Index * 2); + + // + // clear connection change and port suspend + // + WriteRegister16(UHCI_PORTSC1 + Index * 2, Status & ~(UHCI_PORTSC_STATCHA | UHCI_PORTSC_SUSPEND)); + } + DPRINT1("[USBUHCI] Controller Started\n"); DPRINT1("[USBUHCI] Controller Status %x\n", ReadRegister16(UHCI_USBSTS)); + DPRINT1("[USBUHCI] Controller Cmd Status %x\n", ReadRegister16(UHCI_USBCMD)); + DPRINT1("[USBUHCI] Controller Interrupt Status %x\n", ReadRegister16(UHCI_USBINTR)); DPRINT1("[USBUHCI] Controller Frame %x\n", ReadRegister16(UHCI_FRNUM)); + DPRINT1("[USBUHCI] Controller Port Status 0 %x\n", ReadRegister16(UHCI_PORTSC1)); + DPRINT1("[USBUHCI] Controller Port Status 1 %x\n", ReadRegister16(UHCI_PORTSC1 + 2));
// // done @@ -533,12 +558,15 @@ // WRITE_PORT_USHORT((PUSHORT)((ULONG)m_Base + UHCI_USBCMD), UHCI_USBCMD_GRESET);
+ KeStallExecutionProcessor(100); + // // clear command register // WRITE_PORT_USHORT((PUSHORT)((ULONG)m_Base + UHCI_USBCMD), 0);
- KeStallExecutionProcessor(1000); + KeStallExecutionProcessor(10); +
// // restore start of modify register @@ -558,6 +586,12 @@ DPRINT1("[USBUHCI] InitializeController\n");
// + // now disable all interrupts + // + WriteRegister16(UHCI_USBINTR, 0); + + + // // UHCI has two ports // m_NumberOfPorts = 2; @@ -580,10 +614,6 @@
DPRINT1("[USBUHCI] Acquired ownership\n");
- // - // now disable all interrupts - // - WriteRegister16(UHCI_USBINTR, 0);
// // perform global reset @@ -682,14 +712,15 @@ // // init stray descriptor // - m_StrayDescriptor->PhysicalAddress = m_StrayDescriptorPhysicalAddress; + m_StrayDescriptor->PhysicalAddress = m_StrayDescriptorPhysicalAddress.LowPart; m_StrayDescriptor->LinkPhysical = TD_TERMINATE; m_StrayDescriptor->Token = TD_TOKEN_NULL_DATA | (0x7f << TD_TOKEN_DEVADDR_SHIFT) | TD_TOKEN_IN;
+ // // link to last queue head // - m_QueueHead[4]->LinkPhysical = m_StrayDescriptor->PhysicalAddress.LowPart; + m_QueueHead[4]->LinkPhysical = m_StrayDescriptor->PhysicalAddress; m_QueueHead[4]->NextLogicalDescriptor = m_StrayDescriptor;
@@ -805,6 +836,17 @@ Status = ReadRegister16(Port);
// + // Before port reset, disable the port + // + WriteRegister16(Port, ReadRegister16(Port) & ~UHCI_PORTSC_ENABLED); + while(ReadRegister16(Port) & UHCI_PORTSC_ENABLED) + { + DPRINT1("Port %x Status %x\n", PortIndex, ReadRegister16(Port)); + KeStallExecutionProcessor(5); + } + + + // // remove unwanted bits // Status &= UHCI_PORTSC_DATAMASK; @@ -817,7 +859,7 @@ // // now wait a bit // - KeStallExecutionProcessor(25); + KeStallExecutionProcessor(50);
// // re-read status @@ -832,12 +874,17 @@ // // clear reset port // - WriteRegister16(Port, Status & ~UHCI_PORTSC_RESET); + WriteRegister16(Port, (Status & ~UHCI_PORTSC_RESET)); + + // + // set enabled bit + // + WriteRegister16(Port, ReadRegister16(Port) | UHCI_PORTSC_ENABLED);
// // now wait a bit // - KeStallExecutionProcessor(25); + KeStallExecutionProcessor(10);
for (Index = 0; Index < 10; Index++) { @@ -854,7 +901,7 @@ // // enable port // - WriteRegister16(Port, Status | UHCI_PORTSC_ENABLED); + WriteRegister16(Port, Status);
// // wait a bit @@ -891,6 +938,16 @@
m_PortResetChange |= (1 << PortIndex); DPRINT1("[USBOHCI] Port Index %x Status after reset %x\n", PortIndex, ReadRegister16(Port)); + + if (Status & UHCI_PORTSC_CURSTAT) + { + // + // queue work item + // + DPRINT1("Queueing work item\n"); + ExQueueWorkItem(&m_StatusChangeWorkItem, DelayedWorkQueue); + } + return STATUS_SUCCESS; }
@@ -1003,7 +1060,7 @@ // // UHCI is not supporting port reset register bit // - m_PortResetChange &= (1 << PortId); + m_PortResetChange &= ~(1 << PortId); } else if (Feature == C_PORT_CONNECTION) { @@ -1029,6 +1086,8 @@ ULONG PortId, ULONG Feature) { + ULONG PortRegister; + DPRINT1("[UHCI] SetPortFeature PortId %x Feature %x\n", PortId, Feature);
// @@ -1043,12 +1102,21 @@ return STATUS_INVALID_PARAMETER; }
+ PortRegister = UHCI_PORTSC1 + PortId * 2; + if (Feature == PORT_RESET) { // // reset port // return ResetPort(PortId); + } + else if (Feature == PORT_ENABLE) + { + // + // reset port + // + WriteRegister16(PortRegister, ReadRegister16(PortRegister) | UHCI_PORTSC_ENABLED); } else if (Feature == PORT_POWER) { @@ -1107,12 +1175,12 @@ // get context // This = (CUSBHardwareDevice*) ServiceContext; - DPRINT("InterruptServiceRoutine\n");
// // read register // Status = This->ReadRegister16(UHCI_USBSTS); + DPRINT("InterruptServiceRoutine %x\n", Status);
// // check if the interrupt signaled are from us
Modified: trunk/reactos/drivers/usb/usbuhci/hardware.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbuhci/hardwar... ============================================================================== --- trunk/reactos/drivers/usb/usbuhci/hardware.h [iso-8859-1] (original) +++ trunk/reactos/drivers/usb/usbuhci/hardware.h [iso-8859-1] Wed Feb 22 14:11:23 2012 @@ -92,7 +92,7 @@ ULONG BufferPhysical; // pointer to the buffer
// Software part - PHYSICAL_ADDRESS PhysicalAddress; // Physical address of this descriptor + ULONG PhysicalAddress; // Physical address of this descriptor PVOID NextLogicalDescriptor; ULONG BufferSize; // Size of the buffer PVOID BufferLogical; // Logical pointer to the buffer
Modified: trunk/reactos/drivers/usb/usbuhci/usb_request.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbuhci/usb_req... ============================================================================== --- trunk/reactos/drivers/usb/usbuhci/usb_request.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/usb/usbuhci/usb_request.cpp [iso-8859-1] Wed Feb 22 14:11:23 2012 @@ -718,7 +718,7 @@ // // init descriptor // - Descriptor->PhysicalAddress = Address; + Descriptor->PhysicalAddress = Address.LowPart; Descriptor->Status = TD_STATUS_ACTIVE;
if (InternalGetTransferType() == USB_ENDPOINT_TYPE_ISOCHRONOUS) @@ -829,7 +829,7 @@ // // FIXME FIXME FIXME FIXME FIXME // - MaxPacketSize = 64; + MaxPacketSize = 1280;
do { @@ -872,7 +872,7 @@ // // link descriptor // - LastDescriptor->LinkPhysical = CurrentDescriptor->PhysicalAddress.LowPart | TD_DEPTH_FIRST; + LastDescriptor->LinkPhysical = CurrentDescriptor->PhysicalAddress | TD_DEPTH_FIRST; LastDescriptor->NextLogicalDescriptor = (PVOID)CurrentDescriptor; }
@@ -1095,13 +1095,13 @@ // // link setup descriptor to first data descriptor // - SetupDescriptor->LinkPhysical = FirstDescriptor->PhysicalAddress.LowPart | TD_DEPTH_FIRST; + SetupDescriptor->LinkPhysical = FirstDescriptor->PhysicalAddress | TD_DEPTH_FIRST; SetupDescriptor->NextLogicalDescriptor = (PVOID)FirstDescriptor;
// // link last data descriptor to status descriptor // - LastDescriptor->LinkPhysical = StatusDescriptor->PhysicalAddress.LowPart | TD_DEPTH_FIRST; + LastDescriptor->LinkPhysical = StatusDescriptor->PhysicalAddress | TD_DEPTH_FIRST; LastDescriptor->NextLogicalDescriptor = (PVOID)StatusDescriptor; } else @@ -1109,7 +1109,7 @@ // // directly link setup to status descriptor // - SetupDescriptor->LinkPhysical = StatusDescriptor->PhysicalAddress.LowPart | TD_DEPTH_FIRST; + SetupDescriptor->LinkPhysical = StatusDescriptor->PhysicalAddress | TD_DEPTH_FIRST; SetupDescriptor->NextLogicalDescriptor = (PVOID)StatusDescriptor; }
@@ -1117,7 +1117,7 @@ // link queue head with setup descriptor // QueueHead->NextElementDescriptor = (PVOID)SetupDescriptor; - QueueHead->ElementPhysical = SetupDescriptor->PhysicalAddress.LowPart; + QueueHead->ElementPhysical = SetupDescriptor->PhysicalAddress;
// // store result
Modified: trunk/reactos/drivers/usb/usbuhci/usbuhci.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbuhci/usbuhci... ============================================================================== --- trunk/reactos/drivers/usb/usbuhci/usbuhci.h [iso-8859-1] (original) +++ trunk/reactos/drivers/usb/usbuhci/usbuhci.h [iso-8859-1] Wed Feb 22 14:11:23 2012 @@ -2,7 +2,7 @@ #define USBOHCI_H__
#include <ntddk.h> -#define NDEBUG +#define YDEBUG #include <debug.h> #include <hubbusif.h> #include <usbbusif.h>