diff --git a/drivers/usb/usbehci_new/hardware.cpp b/drivers/usb/usbehci_new/hardware.cpp index aa9628433d1..aaf9ef4c8c5 100644 --- a/drivers/usb/usbehci_new/hardware.cpp +++ b/drivers/usb/usbehci_new/hardware.cpp @@ -109,6 +109,7 @@ protected: HD_INIT_CALLBACK* m_SCECallBack; // status change callback routine PVOID m_SCEContext; // status change callback routine context BOOLEAN m_DoorBellRingInProgress; // door bell ring in progress + EHCI_PORT_STATUS m_PortStatus[16]; // port status // set command VOID SetCommandRegister(PEHCI_USBCMD_CONTENT UsbCmd); @@ -681,6 +682,7 @@ CUSBHardwareDevice::ResetPort( DPRINT1("Port did not reset\n"); return STATUS_RETRY; } + return STATUS_SUCCESS; } @@ -690,11 +692,10 @@ CUSBHardwareDevice::GetPortStatus( OUT USHORT *PortStatus, OUT USHORT *PortChange) { +#if 0 ULONG Value; USHORT Status = 0, Change = 0; - DPRINT1("CUSBHardwareDevice::GetPortStatus\n"); - if (PortId > m_Capabilities.HCSParams.PortCount) return STATUS_UNSUCCESSFUL; @@ -755,11 +756,10 @@ CUSBHardwareDevice::GetPortStatus( *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; - +#else + *PortStatus = m_PortStatus[PortId].PortStatus; + *PortChange = m_PortStatus[PortId].PortChange; +#endif return STATUS_SUCCESS; } @@ -784,6 +784,12 @@ CUSBHardwareDevice::ClearPortStatus( Value &= ~EHCI_PRT_RESET; EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId), Value); KeStallExecutionProcessor(100); + + // + // update port status + // + m_PortStatus[PortId].PortChange &= ~USB_PORT_STATUS_RESET; + m_PortStatus[PortId].PortStatus |= USB_PORT_STATUS_ENABLE; } } @@ -793,6 +799,8 @@ CUSBHardwareDevice::ClearPortStatus( Value |= EHCI_PRT_CONNECTSTATUSCHANGE; Value |= EHCI_PRT_ENABLEDSTATUSCHANGE; EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId), Value); + + m_PortStatus[PortId].PortChange &= ~USB_PORT_STATUS_CONNECT; } return STATUS_SUCCESS; @@ -827,14 +835,25 @@ CUSBHardwareDevice::SetPortFeature( { DPRINT1("Non HighSpeed device. Releasing Ownership\n"); } - // - // Reset and clean enable - // - Value |= EHCI_PRT_RESET; - Value &= ~EHCI_PRT_ENABLED; - EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId), Value); - KeStallExecutionProcessor(100); + ResetPort(PortId); + + // + // update cached settings + // + m_PortStatus[PortId].PortChange |= USB_PORT_STATUS_RESET; + m_PortStatus[PortId].PortStatus &= ~USB_PORT_STATUS_ENABLE; + + // + // is there a status change callback + // + if (m_SCECallBack != NULL) + { + // + // issue callback + // + m_SCECallBack(m_SCEContext); + } } if (Feature == PORT_POWER) @@ -1069,16 +1088,29 @@ EhciDefferedRoutine( if (PortStatus & EHCI_PRT_SLOWSPEEDLINE) { - DPRINT1("Non HighSeped device connected. Release ownership\n"); + DPRINT1("Non HighSpeed device connected. Release ownership\n"); This->EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * i), EHCI_PRT_RELEASEOWNERSHIP); continue; } - - // - // FIXME: Is a port reset needed, or does hub driver request this? - // } - This->m_SCECallBack(This->m_SCEContext); + + // + // update port status flags + // + This->m_PortStatus[i].PortStatus |= USB_PORT_STATUS_HIGH_SPEED; + This->m_PortStatus[i].PortStatus |= USB_PORT_STATUS_CONNECT; + This->m_PortStatus[i].PortChange |= USB_PORT_STATUS_CONNECT; + + // + // is there a status change callback + // + if (This->m_SCECallBack != NULL) + { + // + // issue callback + // + This->m_SCECallBack(This->m_SCEContext); + } } else { diff --git a/drivers/usb/usbehci_new/hardware.h b/drivers/usb/usbehci_new/hardware.h index 1c97fb3ddb4..eb8e74d7958 100644 --- a/drivers/usb/usbehci_new/hardware.h +++ b/drivers/usb/usbehci_new/hardware.h @@ -58,6 +58,7 @@ #define EHCI_PRT_POWER 0x1000 #define EHCI_PRT_RELEASEOWNERSHIP 0x2000 +#define EHCI_PORTSC_DATAMASK 0xffffffd1 // // Terminate Pointer used for QueueHeads and Element Transfer Descriptors to mark Pointers as the end // @@ -280,3 +281,10 @@ typedef struct _EHCI_HOST_CONTROLLER KSPIN_LOCK Lock; LPDMA_MEMORY_ALLOCATOR DmaMemAllocator; } EHCI_HOST_CONTROLLER, *PEHCI_HOST_CONTROLLER; + +typedef struct +{ + ULONG PortStatus; + ULONG PortChange; +}EHCI_PORT_STATUS; + diff --git a/drivers/usb/usbehci_new/hub_controller.cpp b/drivers/usb/usbehci_new/hub_controller.cpp index 619097d8cfe..cb6530d9030 100644 --- a/drivers/usb/usbehci_new/hub_controller.cpp +++ b/drivers/usb/usbehci_new/hub_controller.cpp @@ -913,7 +913,7 @@ CHubController::HandleClassOther( // // reset port feature // - Status = m_Hardware->ResetPort(PortId); + Status = m_Hardware->SetPortFeature(PortId, PORT_RESET); PC_ASSERT(Status == STATUS_SUCCESS); break; } @@ -928,9 +928,7 @@ CHubController::HandleClassOther( PC_ASSERT(0); Status = STATUS_INVALID_DEVICE_REQUEST; } - - - return STATUS_SUCCESS; + return Status; } //----------------------------------------------------------------------------------------- @@ -1313,6 +1311,12 @@ CHubController::HandleDeviceControl( Irp->IoStatus.Information = sizeof(ULONG); break; } + case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION: + { + DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION UNIMPLEMENTED\n"); + Status = STATUS_SUCCESS; + break; + } default: { DPRINT1("HandleDeviceControl>Type: IoCtl %x InputBufferLength %lu OutputBufferLength %lu NOT IMPLEMENTED\n",