Author: mjmartin Date: Tue Apr 19 13:57:32 2011 New Revision: 51401
URL: http://svn.reactos.org/svn/reactos?rev=51401&view=rev Log: [USBEHCI_NEW] - hub_controller: Implement Status Change Endpoint for RootHub. Handling the URB can return STATUS_PENDING, as in the new SCE code. Check for this before completing the Irp. Uncomment calls to PortStatus, SetPortFeature, and ClearPortStatus now that they are implemented. - For function receiving a port number check that its not larger than the actual number of ports on the controller.
Modified: branches/usb-bringup/drivers/usb/usbehci_new/hardware.cpp branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp
Modified: branches/usb-bringup/drivers/usb/usbehci_new/hardware.cpp URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_... ============================================================================== --- branches/usb-bringup/drivers/usb/usbehci_new/hardware.cpp [iso-8859-1] (original) +++ branches/usb-bringup/drivers/usb/usbehci_new/hardware.cpp [iso-8859-1] Tue Apr 19 13:57:32 2011 @@ -602,6 +602,9 @@ { ULONG PortStatus;
+ if (PortIndex > m_Capabilities.HCSParams.PortCount) + return STATUS_UNSUCCESSFUL; + PortStatus = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex)); if (PortStatus & EHCI_PRT_SLOWSPEEDLINE) { @@ -640,7 +643,8 @@ return STATUS_SUCCESS; }
-NTSTATUS CUSBHardwareDevice::GetPortStatus( +NTSTATUS +CUSBHardwareDevice::GetPortStatus( ULONG PortId, OUT USHORT *PortStatus, OUT USHORT *PortChange) @@ -648,6 +652,11 @@ ULONG Value; USHORT Status = 0, Change = 0;
+ DPRINT1("CUSBHardwareDevice::GetPortStatus\n"); + + if (PortId > m_Capabilities.HCSParams.PortCount) + return STATUS_UNSUCCESSFUL; + // // Get the value of the Port Status and Control Register // @@ -703,15 +712,27 @@ if (Value & EHCI_PRT_ENABLEDSTATUSCHANGE) Change |= USB_PORT_STATUS_ENABLE;
+ *PortStatus = Status; + *PortChange = Change; + + //HACK: Maybe + if (Status == (USB_PORT_STATUS_HIGH_SPEED | USB_PORT_STATUS_CONNECT | USB_PORT_STATUS_POWER)) + *PortChange = USB_PORT_STATUS_CONNECT;
return STATUS_SUCCESS; }
-NTSTATUS CUSBHardwareDevice::ClearPortStatus( +NTSTATUS +CUSBHardwareDevice::ClearPortStatus( ULONG PortId, ULONG Status) { ULONG Value; + + DPRINT1("CUSBHardwareDevice::ClearPortStatus\n"); + + if (PortId > m_Capabilities.HCSParams.PortCount) + return STATUS_UNSUCCESSFUL;
Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId));
@@ -737,18 +758,26 @@ }
-NTSTATUS CUSBHardwareDevice::SetPortFeature( +NTSTATUS +CUSBHardwareDevice::SetPortFeature( ULONG PortId, ULONG Feature) { ULONG Value;
+ DPRINT1("CUSBHardwareDevice::SetPortFeature\n"); + + if (PortId > m_Capabilities.HCSParams.PortCount) + return STATUS_UNSUCCESSFUL; + Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId)); + if (Feature == PORT_ENABLE) { // // FIXME: EHCI Ports can only be disabled via reset // + DPRINT1("PORT_ENABLE not supported for EHCI\n"); }
if (Feature == PORT_RESET) @@ -757,7 +786,6 @@ { DPRINT1("Non HighSpeed device. Releasing Ownership\n"); } - // // Reset and clean enable // @@ -769,17 +797,21 @@ }
if (Feature == PORT_POWER) - DPRINT1("Not implemented\n"); - - return STATUS_SUCCESS; -} - -VOID CUSBHardwareDevice::SetAsyncListRegister(ULONG PhysicalAddress) + DPRINT1("PORT_POWER Not implemented\n"); + + return STATUS_SUCCESS; +} + +VOID +CUSBHardwareDevice::SetAsyncListRegister( + ULONG PhysicalAddress) { EHCI_WRITE_REGISTER_ULONG(EHCI_ASYNCLISTBASE, PhysicalAddress); }
-VOID CUSBHardwareDevice::SetPeriodicListRegister(ULONG PhysicalAddress) +VOID +CUSBHardwareDevice::SetPeriodicListRegister( + ULONG PhysicalAddress) { EHCI_WRITE_REGISTER_ULONG(EHCI_PERIODICLISTBASE, PhysicalAddress); }
Modified: branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_... ============================================================================== --- branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp [iso-8859-1] (original) +++ branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp [iso-8859-1] Tue Apr 19 13:57:32 2011 @@ -90,6 +90,7 @@ RTL_BITMAP m_DeviceAddressBitmap; PULONG m_DeviceAddressBitmapBuffer; LIST_ENTRY m_UsbDeviceList; + PIRP m_PendingSCEIrp; };
typedef struct @@ -692,6 +693,60 @@ IN OUT PIRP Irp, PURB Urb) { + ULONG PortCount, PortId; + USHORT PortStatus, PortChange; + + // + // First check if the request is for the Status Change Endpoint + // + + // + // Is the Request for the root hub + // + if (Urb->UrbHeader.UsbdDeviceHandle==0) + { + // + // There should only be one SCE request pending at a time + // + ASSERT (m_PendingSCEIrp == NULL); + + // + // Get the number of ports and check each one for device connected + // + m_Hardware->GetDeviceDetails(NULL, NULL, &PortCount, NULL); + DPRINT1("SCE Request\n"); + DPRINT1("PortCount %d\n", PortCount); + ((PULONG)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 0; + for (PortId = 0; PortId < PortCount; PortId++) + { + m_Hardware->GetPortStatus(PortId, &PortStatus, &PortChange); + + DPRINT1("Port %d: Status %x, Change %x\n", PortId, PortStatus, PortChange); + + // + // FIXME: Verify that this is correct. + // + if ((PortStatus & USB_PORT_STATUS_CONNECT) && (PortChange & USB_PORT_STATUS_CONNECT)) + { + DPRINT1("Device is connected on port %d\n", PortId); + ((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1 << ((PortId + 1) & 7); + break; + } + } + + // + // If there were changes then return SUCCESS + // + if (((PULONG)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] != 0) + return STATUS_SUCCESS; + + // + // Else pend the IRP, to be completed when a device connects or disconnects. + // + m_PendingSCEIrp = Irp; + IoMarkIrpPending(Irp); + return STATUS_PENDING; + } UNIMPLEMENTED return STATUS_NOT_IMPLEMENTED; } @@ -743,9 +798,8 @@ // // get port status // - //Status = m_Hardware->GetPortStatus(PortId, &PortStatus, &PortChange); - - Status = STATUS_SUCCESS; + Status = m_Hardware->GetPortStatus(PortId, &PortStatus, &PortChange); + if (NT_SUCCESS(Status)) { // @@ -771,10 +825,10 @@ switch (Urb->UrbControlVendorClassRequest.Value) { case C_PORT_CONNECTION: - //Status = m_Hardware->ClearPortStatus(PortId, C_PORT_CONNECTION); + Status = m_Hardware->ClearPortStatus(PortId, C_PORT_CONNECTION); break; case C_PORT_RESET: - //Status= m_Hardware->ClearPortStatus(PortId, C_PORT_RESET); + Status= m_Hardware->ClearPortStatus(PortId, C_PORT_RESET); break; default: DPRINT("Unknown Value for Clear Feature %x \n", Urb->UrbControlVendorClassRequest.Value); @@ -806,7 +860,7 @@ // // set suspend port feature // - Status = STATUS_SUCCESS; //m_Hardware->SetPortFeature(PortId, PORT_SUSPEND); + Status = m_Hardware->SetPortFeature(PortId, PORT_SUSPEND); break; } case PORT_POWER: @@ -814,7 +868,7 @@ // // set power feature on port // - Status = STATUS_SUCCESS; //m_Hardware->SetPortFeature(PortId, PORT_POWER); + Status = m_Hardware->SetPortFeature(PortId, PORT_POWER); break; }
@@ -1232,9 +1286,12 @@ break; } } - - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); + if (Status != STATUS_PENDING) + { + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } + return Status; }
Modified: branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_... ============================================================================== --- branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp [iso-8859-1] (original) +++ branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp [iso-8859-1] Tue Apr 19 13:57:32 2011 @@ -70,6 +70,7 @@ PQUEUE_HEAD m_QueueHead; PQUEUE_TRANSFER_DESCRIPTOR m_TransferDescriptors[3]; PUSB_DEFAULT_PIPE_SETUP_PACKET m_DescriptorPacket; + PHYSICAL_ADDRESS m_DescriptorSetupPacket; };
//---------------------------------------------------------------------------------------- @@ -570,14 +571,15 @@ }
// - // FIXME: where put MDL virtual address? - // - - - // - // link setup packet into buffer - VIRTUAL Address!!! - // - m_TransferDescriptors[0]->BufferPointer[0] = (ULONG)PtrToUlong(m_DescriptorPacket); + // Control Transfers have only one in or out buffer if one at all. Put in the QueueHead the + // same as BulkTransfers. USBQueue will use the Mdl to fill in the BufferPointers + // + QueueHead->Mdl = m_TransferBufferMDL; + + // + // link setup packet into buffer - Physical Address!!! + // + m_TransferDescriptors[0]->BufferPointer[0] = (ULONG)PtrToUlong(m_DescriptorSetupPacket.LowPart);
// // link transfer descriptors to queue head @@ -791,6 +793,7 @@ // copy setup packet // RtlCopyMemory(m_DescriptorPacket, m_SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); + m_DescriptorSetupPacket = PhysicalAddress; }
//