From 6c35ffefb55cccde710f5606aa112ae2a4a06c17 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Mon, 13 Feb 2012 13:39:20 +0000 Subject: [PATCH] [USBOHCI] - Set endpoint direction indicator for control transfers - Mask Version bits when printing out version - Implement function for dumping endpoint descriptor - Implement retrieving pid direction from setup packet - Flip the pid direction for the status descriptor when data is transferred - Return packet size 8 when using the control pipe - OHCI control transfer hang is gone - OHCI control should now work and attached HID devices finish initialization svn path=/trunk/; revision=55574 --- reactos/drivers/usb/usbohci/hardware.cpp | 2 +- reactos/drivers/usb/usbohci/hardware.h | 3 +- reactos/drivers/usb/usbohci/usb_queue.cpp | 2 +- reactos/drivers/usb/usbohci/usb_request.cpp | 182 +++++++++++--------- 4 files changed, 103 insertions(+), 86 deletions(-) diff --git a/reactos/drivers/usb/usbohci/hardware.cpp b/reactos/drivers/usb/usbohci/hardware.cpp index 87eb79f554f..4bf6ccf6b49 100644 --- a/reactos/drivers/usb/usbohci/hardware.cpp +++ b/reactos/drivers/usb/usbohci/hardware.cpp @@ -329,7 +329,7 @@ CUSBHardwareDevice::PnpStart( // Version = READ_REGISTER_ULONG((PULONG)((ULONG_PTR)ResourceBase + OHCI_REVISION_OFFSET)); - DPRINT("Version %x\n", Version); + DPRINT("Version %x\n", Version & 0xFFFF); // // Store Resource base diff --git a/reactos/drivers/usb/usbohci/hardware.h b/reactos/drivers/usb/usbohci/hardware.h index e88c0941bbc..ec9a3cdc674 100644 --- a/reactos/drivers/usb/usbohci/hardware.h +++ b/reactos/drivers/usb/usbohci/hardware.h @@ -241,7 +241,8 @@ typedef struct _OHCI_ENDPOINT_DESCRIPTOR #define OHCI_ENDPOINT_GENERAL_FORMAT 0x00000000 #define OHCI_ENDPOINT_ISOCHRONOUS_FORMAT 0x00008000 #define OHCI_ENDPOINT_HEAD_MASK 0xfffffffc -#define OHCI_ENDPOINT_HALTED 0x00000001 +#define OHCI_ENDPOINT_HALTED 0x00000001 +#define OHCI_ENDPOINT_DIRECTION_DESCRIPTOR 0x00000000 // // Maximum port count set by OHCI // diff --git a/reactos/drivers/usb/usbohci/usb_queue.cpp b/reactos/drivers/usb/usbohci/usb_queue.cpp index 2132bec89ca..a5a79c21c50 100644 --- a/reactos/drivers/usb/usbohci/usb_queue.cpp +++ b/reactos/drivers/usb/usbohci/usb_queue.cpp @@ -285,7 +285,7 @@ CUSBQueue::AddUSBRequest( m_Hardware->GetCurrentFrameNumber(&FrameNumber); DPRINT("Hardware 1ms %p Iso %p\n",m_InterruptEndpoints[0], m_IsoHeadEndpointDescriptor); - ASSERT(m_InterruptEndpoints[0]->NextPhysicalEndpoint == m_IsoHeadEndpointDescriptor->PhysicalAddress.LowPart); + ASSERT(m_InterruptEndpoints[0]->NextPhysicalEndpoint == m_IsoHeadEndpointDescriptor->PhysicalAddress.LowPart); PrintEndpointList(m_IsoHeadEndpointDescriptor); } diff --git a/reactos/drivers/usb/usbohci/usb_request.cpp b/reactos/drivers/usb/usbohci/usb_request.cpp index b667554068f..2ebc80f2510 100644 --- a/reactos/drivers/usb/usbohci/usb_request.cpp +++ b/reactos/drivers/usb/usbohci/usb_request.cpp @@ -48,7 +48,6 @@ public: virtual VOID FreeEndpointDescriptor(struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor); virtual UCHAR GetInterval(); - // local functions ULONG InternalGetTransferType(); UCHAR InternalGetPidDirection(); @@ -65,6 +64,7 @@ public: UCHAR GetEndpointAddress(); USHORT GetMaxPacketSize(); VOID CheckError(struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor); + VOID DumpEndpointDescriptor(struct _OHCI_ENDPOINT_DESCRIPTOR *Descriptor); // constructor / destructor @@ -460,9 +460,10 @@ CUSBRequest::GetMaxPacketSize() if (!m_EndpointDescriptor) { // - // control request + // FIXME: use DeviceDescriptor.bMaxPacketSize0 + // control pipe request // - return 0; + return 8; } ASSERT(m_Irp); @@ -541,16 +542,23 @@ CUSBRequest::InternalGetTransferType() UCHAR CUSBRequest::InternalGetPidDirection() { - ASSERT(m_Irp); - ASSERT(m_EndpointDescriptor); - - // - // end point is defined in the low byte of bEndpointAddress - // - return (m_EndpointDescriptor->bEndpointAddress & USB_ENDPOINT_DIRECTION_MASK) >> 7; + if (m_EndpointDescriptor) + { + // + // end point direction is highest bit in bEndpointAddress + // + return (m_EndpointDescriptor->bEndpointAddress & USB_ENDPOINT_DIRECTION_MASK) >> 7; + } + else + { + // + // request arrives on the control pipe, extract direction from setup packet + // + ASSERT(m_SetupPacket); + return (m_SetupPacket->bmRequestType.B >> 7); + } } - //---------------------------------------------------------------------------------------- UCHAR CUSBRequest::GetDeviceAddress() @@ -983,7 +991,13 @@ CUSBRequest::AllocateEndpointDescriptor( // Descriptor->Flags |= OHCI_ENDPOINT_DIRECTION_IN; } - + } + else + { + // + // get it from transfer descriptor + // + Descriptor->Flags |= OHCI_ENDPOINT_DIRECTION_DESCRIPTOR; } // @@ -1230,6 +1244,35 @@ CUSBRequest::BuildBulkInterruptEndpoint( return STATUS_SUCCESS; } +VOID +CUSBRequest::DumpEndpointDescriptor( + POHCI_ENDPOINT_DESCRIPTOR Descriptor) +{ + ULONG Count = 0; + POHCI_GENERAL_TD GeneralDescriptor; + + DPRINT1("EndpointDescriptor %p Addr %x\n", Descriptor, Descriptor->PhysicalAddress.LowPart); + DPRINT1("EndpointDescriptor HeadPhysicalDescriptor %x HeadLogicalDescriptor %p\n", Descriptor->HeadPhysicalDescriptor, Descriptor->HeadLogicalDescriptor); + DPRINT1("EndpointDescriptor TailPhysicalDescriptor %x\n", Descriptor->TailPhysicalDescriptor); + DPRINT1("EndpointDescriptor NextDescriptor %x\n", Descriptor->NextDescriptor); + DPRINT1("EndpointDescriptor NextPhysicalEndpoint %x\n", Descriptor->NextPhysicalEndpoint); + DPRINT1("EndpointDescriptor Flags %x\n", Descriptor->Flags); + + + GeneralDescriptor = (POHCI_GENERAL_TD)Descriptor->HeadLogicalDescriptor; + while(GeneralDescriptor) + { + DPRINT1("Descriptor %d Address %p Addr %x\n", Count, GeneralDescriptor, GeneralDescriptor->PhysicalAddress); + DPRINT1("Descriptor %d BufferLogical %p BufferPhysical %x\n", Count, GeneralDescriptor->BufferLogical, GeneralDescriptor->BufferPhysical); + DPRINT1("Descriptor %d BufferSize %d\n", Count, GeneralDescriptor->BufferSize); + DPRINT1("Descriptor %d LastPhysicalByteAddress %x\n", Count, GeneralDescriptor->LastPhysicalByteAddress); + DPRINT1("Descriptor %d Flags %x\n", Count, GeneralDescriptor->Flags); + DPRINT1("Descriptor %d NextLogicalDescriptor %p NextPhysicalDescriptor %x\n", Count, GeneralDescriptor->NextLogicalDescriptor, GeneralDescriptor->NextPhysicalDescriptor); + + Count++; + GeneralDescriptor = (POHCI_GENERAL_TD)GeneralDescriptor->NextLogicalDescriptor; + } +} NTSTATUS CUSBRequest::BuildControlTransferDescriptor( @@ -1293,6 +1336,31 @@ CUSBRequest::BuildControlTransferDescriptor( return Status; } + // + // initialize setup descriptor + // + SetupDescriptor->Flags = OHCI_TD_BUFFER_ROUNDING | OHCI_TD_DIRECTION_PID_SETUP | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) | OHCI_TD_TOGGLE_0 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE); + + // + // initialize status descriptor + // + StatusDescriptor->Flags = OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) | OHCI_TD_TOGGLE_1 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE); + + if (m_SetupPacket) + { + // + // copy setup packet + // + RtlCopyMemory(SetupDescriptor->BufferLogical, m_SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); + } + else + { + // + // generate setup packet from urb + // + ASSERT(FALSE); + } + if (m_TransferBufferLength) { // @@ -1312,7 +1380,6 @@ CUSBRequest::BuildControlTransferDescriptor( m_DmaManager->Release(EndpointDescriptor, sizeof(OHCI_ENDPOINT_DESCRIPTOR)); FreeDescriptor(SetupDescriptor); FreeDescriptor(StatusDescriptor); - FreeDescriptor(LastDescriptor); return Status; } @@ -1321,30 +1388,10 @@ CUSBRequest::BuildControlTransferDescriptor( // DataDescriptor->Flags = OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE) | OHCI_TD_TOGGLE_CARRY | OHCI_TD_TOGGLE_1; - if (m_EndpointDescriptor) - { - if (USB_ENDPOINT_DIRECTION_OUT(m_EndpointDescriptor->bEndpointAddress)) - { - // - // direction out - // - DataDescriptor->Flags |= OHCI_TD_DIRECTION_PID_OUT; - } - else - { - // - // direction in - // - DataDescriptor->Flags |= OHCI_TD_DIRECTION_PID_IN; - } - } - else - { - // - // no end point address provided - assume its an in direction - // - DataDescriptor->Flags |= OHCI_TD_DIRECTION_PID_IN; - } + // + // setup pid direction + // + DataDescriptor->Flags |= InternalGetPidDirection() == TRUE ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT; // // use short packets @@ -1355,53 +1402,13 @@ CUSBRequest::BuildControlTransferDescriptor( // store physical address of buffer // DataDescriptor->BufferPhysical = MmGetPhysicalAddress(MmGetMdlVirtualAddress(m_TransferBufferMDL)).LowPart; - DataDescriptor->LastPhysicalByteAddress = DataDescriptor->BufferPhysical + m_TransferBufferLength - 1; - } + DataDescriptor->LastPhysicalByteAddress = DataDescriptor->BufferPhysical + m_TransferBufferLength - 1; - // - // initialize setup descriptor - // - SetupDescriptor->Flags = OHCI_TD_BUFFER_ROUNDING | OHCI_TD_DIRECTION_PID_SETUP | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) | OHCI_TD_TOGGLE_0 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE); + // + // flip status pid direction + // + StatusDescriptor->Flags |= InternalGetPidDirection() == TRUE ? OHCI_TD_DIRECTION_PID_OUT : OHCI_TD_DIRECTION_PID_IN; - if (m_SetupPacket) - { - // - // copy setup packet - // - RtlCopyMemory(SetupDescriptor->BufferLogical, m_SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); - } - else - { - // - // generate setup packet from urb - // - ASSERT(FALSE); - } - - // - // initialize status descriptor - // - StatusDescriptor->Flags = OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) | OHCI_TD_TOGGLE_1 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE); - if (m_TransferBufferLength == 0) - { - // - // input direction is flipped for the status descriptor - // - StatusDescriptor->Flags |= OHCI_TD_DIRECTION_PID_IN; - } - else - { - // - // output direction is flipped for the status descriptor - // - StatusDescriptor->Flags |= OHCI_TD_DIRECTION_PID_OUT; - } - - // - // now link the descriptors - // - if (m_TransferBufferLength) - { // // link setup descriptor to data descriptor // @@ -1423,12 +1430,16 @@ CUSBRequest::BuildControlTransferDescriptor( } else { + // + // status descriptor is always in + // + StatusDescriptor->Flags |= OHCI_TD_DIRECTION_PID_IN; + // // link setup descriptor to status descriptor // SetupDescriptor->NextPhysicalDescriptor = StatusDescriptor->PhysicalAddress.LowPart; SetupDescriptor->NextLogicalDescriptor = StatusDescriptor; - // // link status descriptor to last descriptor // @@ -1448,6 +1459,11 @@ CUSBRequest::BuildControlTransferDescriptor( // *OutEndpointDescriptor = EndpointDescriptor; + // + // dump descriptor + // + //DumpEndpointDescriptor(EndpointDescriptor); + // // done //