Index: drivers/usb/usbehci/hardware.cpp =================================================================== --- drivers/usb/usbehci/hardware.cpp (revision 69930) +++ drivers/usb/usbehci/hardware.cpp (working copy) @@ -476,7 +476,7 @@ // // Initialize the UsbQueue now that we have an AdapterObject. // - Status = m_UsbQueue->Initialize(PUSBHARDWAREDEVICE(this), m_Adapter, m_MemoryManager, &m_Lock); + Status = m_UsbQueue->Initialize(PUSBHARDWAREDEVICE(this), m_Adapter, m_MemoryManager, 0, 0, &m_Lock); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to Initialize the UsbQueue\n"); Index: drivers/usb/usbehci/usb_queue.cpp =================================================================== --- drivers/usb/usbehci/usb_queue.cpp (revision 69930) +++ drivers/usb/usbehci/usb_queue.cpp (working copy) @@ -121,6 +121,8 @@ IN PUSBHARDWAREDEVICE Hardware, IN PDMA_ADAPTER AdapterObject, IN PDMAMEMORYMANAGER MemManager, + IN PVOID DoubleBuffer, + IN ULONG DoublePhysBuffer, IN OPTIONAL PKSPIN_LOCK Lock) { NTSTATUS Status = STATUS_SUCCESS; Index: drivers/usb/usbehci/usb_request.cpp =================================================================== --- drivers/usb/usbehci/usb_request.cpp (revision 69930) +++ drivers/usb/usbehci/usb_request.cpp (working copy) @@ -147,6 +147,12 @@ return STATUS_UNSUCCESSFUL; } +VOID +CUSBRequest::GetDoubleBuffer(PVOID DoubleBuffer, ULONG DoublePhysBuffer) +{ + ASSERT(TRUE); +} + //---------------------------------------------------------------------------------------- NTSTATUS STDMETHODCALLTYPE Index: drivers/usb/usbohci/hardware.cpp =================================================================== --- drivers/usb/usbohci/hardware.cpp (revision 69930) +++ drivers/usb/usbohci/hardware.cpp (working copy) @@ -105,6 +105,9 @@ volatile LONG m_StatusChangeWorkItemStatus; // work item active status ULONG m_SyncFramePhysAddr; // periodic frame list physical address ULONG m_IntervalValue; // periodic interval value + + PVOID m_DoubleBuffer; + ULONG m_DoublePhysBuffer; }; //================================================================================================= @@ -234,6 +237,7 @@ PVOID ResourceBase; NTSTATUS Status; ULONG Version; + PHYSICAL_ADDRESS HighestAddress = {{0xFFFFFFFF, 0}}; DPRINT("CUSBHardwareDevice::PnpStart\n"); for(Index = 0; Index < TranslatedResources->List[0].PartialResourceList.Count; Index++) @@ -322,6 +326,26 @@ DeviceDescription.MaximumLength = MAXULONG; // + // create doublebuffer for transfers (CUSBRequest::InitializeWithIrp()) + // + + //FIXME: relation <- (usbstor\disk.c:USBSTOR_HandleQueryProperty()) AdapterDescriptor->MaximumPhysicalPages = 25; //FIXME compute some sane value + m_DoubleBuffer = MmAllocateContiguousMemory(0x18000, HighestAddress); + + if ( !m_DoubleBuffer ) + { + DPRINT1("PnpStart: Not created DoubleBuffer!\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + return Status; + } + + RtlZeroMemory((PVOID)m_DoubleBuffer, 0x18000); //need ? + + m_DoublePhysBuffer = MmGetPhysicalAddress(m_DoubleBuffer).LowPart; + + DPRINT("PnpStart: m_DoubleBuffer - %p, Len - 0x18000, PhysicalAddress - %p\n", m_DoubleBuffer, m_DoublePhysBuffer); + + // // get dma adapter // m_Adapter = IoGetDmaAdapter(m_PhysicalDeviceObject, &DeviceDescription, &m_MapRegisters); @@ -370,7 +394,7 @@ // // Initialize the UsbQueue now that we have an AdapterObject. // - Status = m_UsbQueue->Initialize(this, m_Adapter, m_MemoryManager, NULL); + Status = m_UsbQueue->Initialize(this, m_Adapter, m_MemoryManager, m_DoubleBuffer, m_DoublePhysBuffer, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to Initialize the UsbQueue\n"); Index: drivers/usb/usbohci/usb_queue.cpp =================================================================== --- drivers/usb/usbohci/usb_queue.cpp (revision 69930) +++ drivers/usb/usbohci/usb_queue.cpp (working copy) @@ -66,6 +66,9 @@ POHCI_ENDPOINT_DESCRIPTOR m_IsoHeadEndpointDescriptor; // isochronous head descriptor POHCI_ENDPOINT_DESCRIPTOR * m_InterruptEndpoints; LIST_ENTRY m_PendingRequestList; // pending request list + + PVOID m_DoubleBuffer; + ULONG m_DoublePhysBuffer; }; //================================================================================================= @@ -93,6 +96,8 @@ IN PUSBHARDWAREDEVICE Hardware, IN PDMA_ADAPTER AdapterObject, IN PDMAMEMORYMANAGER MemManager, + IN PVOID DoubleBuffer, + IN ULONG DoublePhysBuffer, IN OPTIONAL PKSPIN_LOCK Lock) { if (!Hardware) @@ -109,6 +114,17 @@ ASSERT(m_Hardware); // + // store buffer + // + DPRINT("Initialize: DoubleBuffer - %p, Len - 0x18000, DoublePhysBuffer - %p\n", DoubleBuffer, DoublePhysBuffer); + + m_DoubleBuffer = DoubleBuffer; + ASSERT(m_DoubleBuffer); + + m_DoublePhysBuffer = DoublePhysBuffer; + ASSERT(m_DoublePhysBuffer); + + // // get bulk endpoint descriptor // m_Hardware->GetBulkHeadEndpointDescriptor(&m_BulkHeadEndpointDescriptor); @@ -356,7 +372,7 @@ NTSTATUS Status; *OutRequest = NULL; - Status = InternalCreateUSBRequest(&UsbRequest); + Status = InternalCreateUSBRequest(&UsbRequest, m_DoubleBuffer, m_DoublePhysBuffer); if (NT_SUCCESS(Status)) { Index: drivers/usb/usbohci/usb_request.cpp =================================================================== --- drivers/usb/usbohci/usb_request.cpp (revision 69930) +++ drivers/usb/usbohci/usb_request.cpp (working copy) @@ -47,6 +47,7 @@ NTSTATUS BuildSetupPacketFromURB(); NTSTATUS BuildControlTransferDescriptor(POHCI_ENDPOINT_DESCRIPTOR * OutEndpointDescriptor); NTSTATUS BuildBulkInterruptEndpoint(POHCI_ENDPOINT_DESCRIPTOR * OutEndpointDescriptor); + NTSTATUS BuildBulkInterruptDataEndpoint(POHCI_ENDPOINT_DESCRIPTOR * OutEndpointDescriptor); NTSTATUS BuildIsochronousEndpoint(POHCI_ENDPOINT_DESCRIPTOR * OutEndpointDescriptor); NTSTATUS CreateGeneralTransferDescriptor(POHCI_GENERAL_TD* OutDescriptor, ULONG BufferSize); VOID FreeDescriptor(POHCI_GENERAL_TD Descriptor); @@ -143,6 +144,21 @@ // base buffer // PVOID m_Base; + + // + // true if request have MDL + // + BOOLEAN m_RequestWithMdl; + + // + // array physical addresses for MmGetPhysicalAddress() + // + //FIXME: relation <- (usbstor\disk.c:USBSTOR_HandleQueryProperty()) AdapterDescriptor->MaximumPhysicalPages = 25; //FIXME compute some sane value + PHYSICAL_ADDRESS m_PhysicalAddressArray[25]; + + PVOID m_DoubleBuffer; + ULONG m_DoublePhysBuffer; + }; //---------------------------------------------------------------------------------------- @@ -155,6 +171,13 @@ return STATUS_UNSUCCESSFUL; } +VOID +CUSBRequest::GetDoubleBuffer(PVOID DoubleBuffer, ULONG DoublePhysBuffer) +{ + m_DoubleBuffer = DoubleBuffer; + m_DoublePhysBuffer = DoublePhysBuffer; +} + //---------------------------------------------------------------------------------------- NTSTATUS STDMETHODCALLTYPE @@ -362,6 +385,8 @@ // // Create one using TransferBuffer // + m_RequestWithMdl = FALSE; + DPRINT("Creating Mdl from Urb Buffer %p Length %lu\n", m_Urb->UrbBulkOrInterruptTransfer.TransferBuffer, m_Urb->UrbBulkOrInterruptTransfer.TransferBufferLength); m_TransferBufferMDL = IoAllocateMdl(m_Urb->UrbBulkOrInterruptTransfer.TransferBuffer, m_Urb->UrbBulkOrInterruptTransfer.TransferBufferLength, @@ -389,7 +414,92 @@ } else { + ULONG ix = 0; + m_TransferBufferMDL = m_Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL; + m_RequestWithMdl = TRUE; + + if (m_Urb->UrbBulkOrInterruptTransfer.TransferFlags & USBD_TRANSFER_DIRECTION_IN) + { + DPRINT("InitializeWithIrp: USBD_TRANSFER_DIRECTION_IN\n"); + } + else + { + DPRINT("InitializeWithIrp: USBD_TRANSFER_DIRECTION_OUT\n"); + RtlCopyMemory((PVOID)((ULONG_PTR)m_DoubleBuffer + m_TransferBufferMDL->ByteOffset), + (PVOID)((ULONG_PTR)m_TransferBufferMDL->StartVa + m_TransferBufferMDL->ByteOffset), + m_Urb->UrbBulkOrInterruptTransfer.TransferBufferLength); + } + + //DPRINT("InitializeWithIrp: Irp - %p, Irp->MdlAddress - %p\n", Irp, Irp->MdlAddress); + //DPRINT("InitializeWithIrp: Urb TransferFlags - %x\n", m_Urb->UrbBulkOrInterruptTransfer.TransferFlags); + DPRINT("InitializeWithIrp: Urb TransferBufferLength - %x\n", m_Urb->UrbBulkOrInterruptTransfer.TransferBufferLength); + //DPRINT("InitializeWithIrp: Urb TransferBuffer - %p\n", m_Urb->UrbBulkOrInterruptTransfer.TransferBuffer); + DPRINT("InitializeWithIrp: Urb TransferBufferMDL - %p\n", m_Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL); + + //DPRINT("InitializeWithIrp: TransferBufferMDL->Next - %p\n", m_TransferBufferMDL->Next); + //DPRINT("InitializeWithIrp: TransferBufferMDL->Size - %x\n", m_TransferBufferMDL->Size); + //DPRINT("InitializeWithIrp: TransferBufferMDL->MdlFlags - %x\n", m_TransferBufferMDL->MdlFlags); + //DPRINT("InitializeWithIrp: TransferBufferMDL->Process - %p\n", m_TransferBufferMDL->Process); + DPRINT("InitializeWithIrp: TransferBufferMDL->MappedSystemVa - %p\n", m_TransferBufferMDL->MappedSystemVa); + //DPRINT("InitializeWithIrp: TransferBufferMDL->StartVa - %p\n", m_TransferBufferMDL->StartVa); + DPRINT("InitializeWithIrp: TransferBufferMDL->ByteCount - %x\n", m_TransferBufferMDL->ByteCount); + DPRINT("InitializeWithIrp: TransferBufferMDL->ByteOffset - %x\n", m_TransferBufferMDL->ByteOffset); + + //m_BufferPhysicalAddress = (MmGetPhysicalAddress(m_DoubleBuffer)); + + DPRINT("InitializeWithIrp: m_DoubleBuffer - %p, m_DoublePhysBuffer - %p\n", m_DoubleBuffer, m_DoublePhysBuffer); + + if (m_Urb->UrbBulkOrInterruptTransfer.TransferBufferLength > 0x1000) + { + ULONG jx = 0; + + if ( m_Urb->UrbBulkOrInterruptTransfer.TransferBufferLength - + (m_Urb->UrbBulkOrInterruptTransfer.TransferBufferLength >> 12) > 0 ) + { + m_PhysicalAddressArray[0].LowPart = m_DoublePhysBuffer; + m_PhysicalAddressArray[0].HighPart = 0; + + jx++; + + DPRINT("InitializeWithIrp: TransferBufferLength - %x, m_PhysicalAddressArray[%d].LowPart - %p\n", + m_Urb->UrbBulkOrInterruptTransfer.TransferBufferLength, 0, m_PhysicalAddressArray[0].LowPart); + } + + for (ix = 0; ix < (m_Urb->UrbBulkOrInterruptTransfer.TransferBufferLength >> 12); ix++) + { + m_PhysicalAddressArray[ix + jx].LowPart = m_DoublePhysBuffer + ((ix + jx) * 0x1000); + m_PhysicalAddressArray[ix + jx].HighPart = 0; + + DPRINT("InitializeWithIrp: TransferBufferLength - %x, m_PhysicalAddressArray[%d].LowPart - %p\n", + m_Urb->UrbBulkOrInterruptTransfer.TransferBufferLength, ix + jx, m_PhysicalAddressArray[ix + jx].LowPart); + } + } + else + { + if ((0x1000 - m_TransferBufferMDL->ByteOffset) >= m_Urb->UrbBulkOrInterruptTransfer.TransferBufferLength) + { + m_PhysicalAddressArray[ix].LowPart = m_DoublePhysBuffer; + m_PhysicalAddressArray[ix].HighPart = 0; + + DPRINT("InitializeWithIrp: TransferBufferLength - %x, m_PhysicalAddressArray[%d].LowPart - %p\n", + m_Urb->UrbBulkOrInterruptTransfer.TransferBufferLength, ix, m_PhysicalAddressArray[ix].LowPart); + } + else + { + m_PhysicalAddressArray[ix].LowPart = m_DoublePhysBuffer; + m_PhysicalAddressArray[ix].HighPart = 0; + + DPRINT("InitializeWithIrp: TransferBufferLength - %x, m_PhysicalAddressArray[%d].LowPart - %p\n", + m_Urb->UrbBulkOrInterruptTransfer.TransferBufferLength, ix, m_PhysicalAddressArray[ix].LowPart); + + m_PhysicalAddressArray[ix + 1].LowPart = m_DoublePhysBuffer + 0x1000; + m_PhysicalAddressArray[ix + 1].HighPart = 0; + + DPRINT("InitializeWithIrp: TransferBufferLength - %x, m_PhysicalAddressArray[%d].LowPart - %p\n", + m_Urb->UrbBulkOrInterruptTransfer.TransferBufferLength, ix + 1, m_PhysicalAddressArray[ix + 1].LowPart); + } + } } // @@ -1338,6 +1448,169 @@ return STATUS_SUCCESS; } +NTSTATUS +CUSBRequest::BuildBulkInterruptDataEndpoint( + POHCI_ENDPOINT_DESCRIPTOR * OutEndpointDescriptor) +{ + NTSTATUS Status; + POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor; + POHCI_GENERAL_TD FirstDescriptor = NULL; + POHCI_GENERAL_TD LastDescriptor = NULL; + POHCI_GENERAL_TD CurrentDescriptor; + ULONG MaxTransferLength; + ULONG TransferBufferOffset = 0; + ULONG TransferSize; + ULONG MaxPacketSize = 0; + ULONG Direction; + PHYSICAL_ADDRESS Address; + ULONG PageNumber = 0; + + + // sanity check + ASSERT(m_TransferBufferMDL); + ASSERT(m_EndpointDescriptor); + + // allocate endpoint descriptor + Status = AllocateEndpointDescriptor(&EndpointDescriptor); + + // failed to create setup descriptor + if (!NT_SUCCESS(Status)) + return Status; + + //DPRINT("BuildBulkInterruptDataEndpoint: EndpointDescriptor - %p, CurrentThread - %p\n", EndpointDescriptor, PsGetCurrentThread()); + + ASSERT(m_EndpointDescriptor); + + // use 1 * PAGE_SIZE at max for each new request + MaxTransferLength = min(1 * PAGE_SIZE, m_TransferBufferLength - m_TransferBufferLengthCompleted); + + // for now use one page as maximum size + MaxPacketSize = PAGE_SIZE; + + // transfer size is minimum available buffer or endpoint size + if (MaxPacketSize) + TransferSize = min(MaxTransferLength - TransferBufferOffset, MaxPacketSize); + else // use available buffer + TransferSize = MaxTransferLength - TransferBufferOffset; + + do + { + // allocate transfer descriptor + Status = CreateGeneralTransferDescriptor(&CurrentDescriptor, 0); + + // failed to allocate transfer descriptor + if (!NT_SUCCESS(Status)) + return STATUS_INSUFFICIENT_RESOURCES; + + if (InternalGetPidDirection()) + Direction = OHCI_TD_DIRECTION_PID_IN; // input direction + else + Direction = OHCI_TD_DIRECTION_PID_OUT; // output direction + + // initialize descriptor + CurrentDescriptor->Flags = Direction | + OHCI_TD_BUFFER_ROUNDING | + OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) | + OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE) | + OHCI_TD_TOGGLE_CARRY; + + // + // store physical address of buffer + // + + // if transfer size >= 4096 (1 and more pages) + if (m_TransferBufferLength >= PAGE_SIZE) + { + PageNumber = (m_TransferBufferLengthCompleted >> PAGE_SHIFT) & 0x0000001F; + + //DPRINT("PageNumber - %x\n", PageNumber); + + if ( (PageNumber == 0) && (m_TransferBufferMDL->ByteOffset > 0) ) + Address.LowPart = m_PhysicalAddressArray[0].LowPart + m_TransferBufferMDL->ByteOffset; + else + Address.LowPart = m_PhysicalAddressArray[PageNumber].LowPart; + + //DPRINT("BuildBulkInterruptDataEndpoint: m_TransferBufferLength - %x, m_PhysicalAddressArray[%d].LowPart - %p\n", + // m_Urb->UrbBulkOrInterruptTransfer.TransferBufferLength, PageNumber, m_PhysicalAddressArray[PageNumber].LowPart); + } + else + { + // FIXME ??? + ASSERT((0x1000 - m_TransferBufferMDL->ByteOffset) >= m_Urb->UrbBulkOrInterruptTransfer.TransferBufferLength); + + // if transfer size < 4096 (< 1 page) + Address.LowPart = m_PhysicalAddressArray[0].LowPart + m_TransferBufferMDL->ByteOffset; + + //DPRINT("BuildBulkInterruptDataEndpoint: m_TransferBufferLength - %x, m_PhysicalAddressArray[%d].LowPart - %p\n", + // m_Urb->UrbBulkOrInterruptTransfer.TransferBufferLength, PageNumber, m_PhysicalAddressArray[PageNumber].LowPart); + } + + if (Address.LowPart == 0) + { + // error + return STATUS_UNSUCCESSFUL; + } + + CurrentDescriptor->BufferPhysical = Address.LowPart; + CurrentDescriptor->LastPhysicalByteAddress = CurrentDescriptor->BufferPhysical + TransferSize - 1; + + DPRINT("BuildBulkInterruptDataEndpoint: CurrentDescriptor->BufferPhysical - %p, TransferSize %x\n", CurrentDescriptor->BufferPhysical, TransferSize); + //DPRINT("CurrentDescriptor %p Addr %x TransferSize %lu\n", CurrentDescriptor, CurrentDescriptor->PhysicalAddress.LowPart, TransferSize); + + // adjust offset + TransferBufferOffset += TransferSize; + + // is there a previous descriptor + if (LastDescriptor ) + { + // link descriptors + LastDescriptor->NextLogicalDescriptor = (PVOID)CurrentDescriptor; + LastDescriptor->NextPhysicalDescriptor = CurrentDescriptor->PhysicalAddress.LowPart; + } + else + { + // it is the first descriptor + FirstDescriptor = CurrentDescriptor; + } + + //DPRINT("BuildBulkInterruptDataEndpoint: MaxTransferLength - %p, TransferBufferOffset - %x\n", MaxTransferLength, TransferBufferOffset); + + // end reached + if (MaxTransferLength == TransferBufferOffset) + break; + + } while (TRUE); + + // store last descriptor + LastDescriptor = CurrentDescriptor; + + // move to next offset + m_TransferBufferLengthCompleted += TransferBufferOffset; + + // first descriptor has no carry bit + FirstDescriptor->Flags &= ~OHCI_TD_TOGGLE_CARRY; + + // apply data toggle + FirstDescriptor->Flags |= (m_EndpointDescriptor->DataToggle ? OHCI_TD_TOGGLE_1 : OHCI_TD_TOGGLE_0); + + // clear interrupt mask for last transfer descriptor + LastDescriptor->Flags &= ~OHCI_TD_INTERRUPT_MASK; + + // fire interrupt as soon transfer is finished + LastDescriptor->Flags |= OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE); + + // now link descriptor to endpoint + EndpointDescriptor->HeadPhysicalDescriptor = FirstDescriptor->PhysicalAddress.LowPart; + EndpointDescriptor->TailPhysicalDescriptor = (FirstDescriptor == LastDescriptor ? 0 : LastDescriptor->PhysicalAddress.LowPart); + EndpointDescriptor->HeadLogicalDescriptor = FirstDescriptor; + + //DumpEndpointDescriptor(EndpointDescriptor); // dump descriptor list + + *OutEndpointDescriptor = EndpointDescriptor; // store result + + return STATUS_SUCCESS; // done +} + VOID CUSBRequest::DumpEndpointDescriptor( POHCI_ENDPOINT_DESCRIPTOR Descriptor) @@ -1588,9 +1861,27 @@ Status = BuildControlTransferDescriptor((POHCI_ENDPOINT_DESCRIPTOR*)OutDescriptor); break; case USB_ENDPOINT_TYPE_BULK: + if (m_RequestWithMdl) + { + Status = BuildBulkInterruptDataEndpoint(OutDescriptor); + } + else + { + Status = BuildBulkInterruptEndpoint(OutDescriptor); + } + break; + case USB_ENDPOINT_TYPE_INTERRUPT: - Status = BuildBulkInterruptEndpoint(OutDescriptor); + if (m_RequestWithMdl) + { + Status = BuildBulkInterruptDataEndpoint(OutDescriptor); + } + else + { + Status = BuildBulkInterruptEndpoint(OutDescriptor); + } break; + case USB_ENDPOINT_TYPE_ISOCHRONOUS: Status = BuildIsochronousEndpoint((POHCI_ENDPOINT_DESCRIPTOR*)OutDescriptor); break; @@ -1933,7 +2224,40 @@ // IoFreeMdl(m_TransferBufferMDL); } + else + { + if (m_Urb->UrbBulkOrInterruptTransfer.TransferFlags & USBD_TRANSFER_DIRECTION_IN) + { + DPRINT("InitializeWithIrp: USBD_TRANSFER_DIRECTION_IN\n"); + //DPRINT1("InitializeWithIrp: Irp - %p, Irp->MdlAddress - %p\n", Irp, Irp->MdlAddress); + //DPRINT1("InitializeWithIrp: Urb TransferFlags - %x\n", m_Urb->UrbBulkOrInterruptTransfer.TransferFlags); + DPRINT("InitializeWithIrp: Urb TransferBufferLength - %x\n", m_Urb->UrbBulkOrInterruptTransfer.TransferBufferLength); + //DPRINT1("InitializeWithIrp: Urb TransferBuffer - %p\n", m_Urb->UrbBulkOrInterruptTransfer.TransferBuffer); + DPRINT("InitializeWithIrp: Urb TransferBufferMDL - %p\n", m_Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL); + + ////DPRINT1("InitializeWithIrp: TransferBufferMDL->Next - %p\n", m_TransferBufferMDL->Next); + ////DPRINT1("InitializeWithIrp: TransferBufferMDL->Size - %x\n", m_TransferBufferMDL->Size); + ////DPRINT1("InitializeWithIrp: TransferBufferMDL->MdlFlags - %x\n", m_TransferBufferMDL->MdlFlags); + ////DPRINT1("InitializeWithIrp: TransferBufferMDL->Process - %p\n", m_TransferBufferMDL->Process); + DPRINT("InitializeWithIrp: TransferBufferMDL->MappedSystemVa - %p\n", m_TransferBufferMDL->MappedSystemVa); + ////DPRINT1("InitializeWithIrp: TransferBufferMDL->StartVa - %p\n", m_TransferBufferMDL->StartVa); + DPRINT("InitializeWithIrp: TransferBufferMDL->ByteCount - %x\n", m_TransferBufferMDL->ByteCount); + DPRINT("InitializeWithIrp: TransferBufferMDL->ByteOffset - %x\n", m_TransferBufferMDL->ByteOffset); + + RtlCopyMemory((PVOID)((ULONG_PTR)m_TransferBufferMDL->StartVa + m_TransferBufferMDL->ByteOffset), + (PVOID)((ULONG_PTR)m_DoubleBuffer + m_TransferBufferMDL->ByteOffset), + m_Urb->UrbBulkOrInterruptTransfer.TransferBufferLength); + } + else + { + DPRINT("InitializeWithIrp: USBD_TRANSFER_DIRECTION_OUT\n"); + //RtlCopyMemory((PVOID)((ULONG_PTR)m_DoubleBuffer + m_TransferBufferMDL->ByteOffset), + // (PVOID)((ULONG_PTR)m_TransferBufferMDL->StartVa + m_TransferBufferMDL->ByteOffset), + // m_Urb->UrbBulkOrInterruptTransfer.TransferBufferLength); + } + } + // // FIXME calculate length // @@ -1957,7 +2281,7 @@ NTSTATUS NTAPI InternalCreateUSBRequest( - PUSBREQUEST *OutRequest) + PUSBREQUEST *OutRequest, PVOID DoubleBuffer, ULONG DoublePhysBuffer) { PUSBREQUEST This; @@ -1983,6 +2307,8 @@ // *OutRequest = (PUSBREQUEST)This; + This->GetDoubleBuffer(DoubleBuffer, DoublePhysBuffer); + // // done // Index: drivers/usb/usbohci/usbohci.h =================================================================== --- drivers/usb/usbohci/usbohci.h (revision 69930) +++ drivers/usb/usbohci/usbohci.h (working copy) @@ -48,7 +48,7 @@ // // usb_request.cpp // -NTSTATUS NTAPI InternalCreateUSBRequest(PUSBREQUEST *OutRequest); +NTSTATUS NTAPI InternalCreateUSBRequest(PUSBREQUEST *OutRequest, PVOID m_DoubleBuffer, ULONG m_DoublePhysBuffer); } #endif /* USBOHCI_H__ */ Index: drivers/usb/usbuhci/hardware.cpp =================================================================== --- drivers/usb/usbuhci/hardware.cpp (revision 69930) +++ drivers/usb/usbuhci/hardware.cpp (working copy) @@ -370,7 +370,7 @@ // // Initialize the UsbQueue now that we have an AdapterObject. // - Status = m_UsbQueue->Initialize(PUSBHARDWAREDEVICE(this), m_Adapter, m_MemoryManager, NULL); + Status = m_UsbQueue->Initialize(PUSBHARDWAREDEVICE(this), m_Adapter, m_MemoryManager, 0, 0, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to Initialize the UsbQueue\n"); Index: drivers/usb/usbuhci/usb_queue.cpp =================================================================== --- drivers/usb/usbuhci/usb_queue.cpp (revision 69930) +++ drivers/usb/usbuhci/usb_queue.cpp (working copy) @@ -82,6 +82,8 @@ IN PUSBHARDWAREDEVICE Hardware, IN PDMA_ADAPTER AdapterObject, IN PDMAMEMORYMANAGER MemManager, + IN PVOID DoubleBuffer, + IN ULONG OhciPhysBuffer, IN OPTIONAL PKSPIN_LOCK Lock) { Index: drivers/usb/usbuhci/usb_request.cpp =================================================================== --- drivers/usb/usbuhci/usb_request.cpp (revision 69930) +++ drivers/usb/usbuhci/usb_request.cpp (working copy) @@ -145,6 +145,12 @@ return STATUS_UNSUCCESSFUL; } +VOID +CUSBRequest::GetDoubleBuffer(PVOID DoubleBuffer, ULONG DoublePhysBuffer) +{ + ASSERT(TRUE); +} + //---------------------------------------------------------------------------------------- NTSTATUS CUSBRequest::InitializeWithSetupPacket( Index: lib/drivers/libusb/common_interfaces.h =================================================================== --- lib/drivers/libusb/common_interfaces.h (revision 69930) +++ lib/drivers/libusb/common_interfaces.h (working copy) @@ -326,6 +326,10 @@ \ STDMETHOD_(ULONG, GetTransferType)( THIS) PURE; \ \ + STDMETHOD_(VOID, GetDoubleBuffer)( THIS_ \ + IN PVOID DoubleBuffer, \ + IN ULONG DoublePhysBuffer) PURE; \ + \ STDMETHOD_(VOID, GetResultStatus)( THIS_ \ OUT OPTIONAL NTSTATUS * NtStatusCode, \ OUT OPTIONAL PULONG UrbStatusCode) PURE; @@ -348,6 +352,10 @@ \ STDMETHODIMP_(ULONG) GetTransferType(VOID); \ \ + STDMETHODIMP_(VOID) GetDoubleBuffer( \ + IN PVOID DoubleBuffer, \ + IN ULONG DoublePhysBuffer); \ + \ STDMETHODIMP_(VOID) GetResultStatus( \ OUT OPTIONAL NTSTATUS * NtStatusCode, \ OUT OPTIONAL PULONG UrbStatusCode); @@ -373,6 +381,8 @@ IN PUSBHARDWAREDEVICE Hardware, \ IN PDMA_ADAPTER AdapterObject, \ IN PDMAMEMORYMANAGER MemManager, \ + IN PVOID DoubleBuffer, \ + IN ULONG DoublePhysBuffer, \ IN OPTIONAL PKSPIN_LOCK Lock) PURE; \ \ STDMETHOD_(NTSTATUS, AddUSBRequest)( THIS_ \ @@ -390,6 +400,8 @@ IN PUSBHARDWAREDEVICE Hardware, \ IN PDMA_ADAPTER AdapterObject, \ IN PDMAMEMORYMANAGER MemManager, \ + IN PVOID DoubleBuffer, \ + IN ULONG DoublePhysBuffer, \ IN OPTIONAL PKSPIN_LOCK Lock); \ \ STDMETHODIMP_(NTSTATUS) AddUSBRequest( \