Page 1 of 2

USB drivers

Posted: Mon Nov 09, 2015 2:26 am
by vgal
JIRA issue: Opening files from USB drive causes the debug log to be spammed
As it was clarified at the analysis, it not simply spam. Probably it is a bug.

Function CUSBRequest:: InitDescriptor() (reactos\drivers\usb\usbehci\usb_request.cpp) prepares descriptors (use physical address). Function MmGetPhysicalAddress(), used for this purpose, failed when switch threads. One of decisions of this problem - to use physical addresses instead of the virtual. At once structure MDL is followed by the list of pages of physical memory. It can be used in the present state of affairs.

As experiment, I added one function (the incorporated copy functions BuildControlTransferQueueHead, BuildTransferDescriptorChain and InitDescriptor) in which refused from MmGetPhysicalAddress.
This function is caused only when Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL ! = 0 (InitializeWithIrp ()).
If Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL == 0 former function BuildBulkInterruptTransferQueueHead is caused.

Added function - BuildBulkInterruptTransferDataQueueHead ()

Code: Select all

NTSTATUS
CUSBRequest::BuildBulkInterruptTransferDataQueueHead(PQUEUE_HEAD * OutHead)
{
  NTSTATUS                    Status;
  PQUEUE_HEAD                 QueueHead;
  PQUEUE_TRANSFER_DESCRIPTOR  FirstDescriptor = NULL;
  PQUEUE_TRANSFER_DESCRIPTOR  LastDescriptor = NULL;
  PQUEUE_TRANSFER_DESCRIPTOR  CurrentDescriptor;
  ULONG                       TransferSize;
  ULONG                       TransferBufferOffset = 0;
  ULONG                       MaxPacketSize = 0;
  ULONG                       MaxTransferLength;
  UCHAR                       DataToggle;
  PHYSICAL_ADDRESS            Address;
  ULONG_PTR                   PfnArray;
  ULONG                       PageNumber;

  ULONG                       MAX_TRANSFER; // const?


  DPRINT("BuildBulkInterruptTransferDataQueueHead\n");

  MAX_TRANSFER = 1 * PAGE_SIZE;                                                       // FIXME. Use 4 * PAGE_SIZE at max for each new request

  Status = CreateQueueHead(&QueueHead);                                               // Allocate the queue head

  DPRINT1("QueueHead - %p, Addr - %x, CurrentThread - %p, CurrentIrql - %x\n", QueueHead, QueueHead->PhysicalAddr, PsGetCurrentThread(), KeGetCurrentIrql());

  if ( !NT_SUCCESS(Status) )  return STATUS_INSUFFICIENT_RESOURCES;                   // failed to allocate queue heads

  // sanity checks
  PC_ASSERT(QueueHead);
  PC_ASSERT(m_TransferBufferLength);
  PC_ASSERT(m_EndpointDescriptor);

  MaxTransferLength = min(MAX_TRANSFER, m_TransferBufferLength - m_TransferBufferLengthCompleted);

  if ( m_EndpointDescriptor )                                                         // is there an endpoint descriptor
    MaxPacketSize = m_EndpointDescriptor->EndPointDescriptor.wMaxPacketSize;          // use endpoint packet size

  if ( MaxPacketSize )
    TransferSize = min(MaxTransferLength - TransferBufferOffset, MaxPacketSize);      // transfer size is minimum available buffer or endpoint size
  else
    TransferSize = MaxTransferLength - TransferBufferOffset;                          // use available buffer

  ASSERT(TransferSize);                                                               // sanity check


  // build bulk transfer descriptor chain

  do
  {
    Status = CreateDescriptor(&CurrentDescriptor);                                    // allocate transfer descriptor

    if ( !NT_SUCCESS(Status) )  return STATUS_INSUFFICIENT_RESOURCES;                 // failed to allocate transfer descriptor

    PfnArray = (ULONG_PTR)MmGetMdlPfnArray(m_TransferBufferMDL);

    if ( m_TransferBufferLength >= PAGE_SIZE )                                        // if transfer size >= 4096 (1 and more pages)
    {
      PageNumber = (m_TransferBufferLengthCompleted >> PAGE_SHIFT) & 0x0000001F;      // 0x3F for 0x40000 (0x1F for 0x10000)
      DPRINT("PageNumber - %x\n", PageNumber);

      if ( *(PULONG)((PULONG)PfnArray + PageNumber) > 1 )
      {
        if ( (PageNumber == 0)  &&  (m_TransferBufferMDL->ByteOffset > 0) )
          Address.LowPart = ((*(PULONG)PfnArray) << PAGE_SHIFT) + m_TransferBufferMDL->ByteOffset;
        else
          Address.LowPart = ((*(PULONG)((PULONG)PfnArray + PageNumber)) << PAGE_SHIFT);
      }
      else
      {
        DPRINT1("PhysAdr < 0x1000\n"); //??
      }
    }
    else                                                                              // if transfer size < 4096 (< 1 page)
    {
      if ( m_TransferBufferMDL->ByteOffset > 0 )
        Address.LowPart = ((*(PULONG)PfnArray) << PAGE_SHIFT) + m_TransferBufferMDL->ByteOffset;
      else
        Address.LowPart = ((*(PULONG)PfnArray) << PAGE_SHIFT);
    }

    if ( Address.LowPart == 0 )
    {
      DumpQueueHead(QueueHead);
      return STATUS_UNSUCCESSFUL;  // Status = STATUS_UNSUCCESSFUL;
    }
  
    // init transfer descriptor
    CurrentDescriptor->Token.Bits.PIDCode              = InternalGetPidDirection();
    CurrentDescriptor->Token.Bits.TotalBytesToTransfer = 0;
    CurrentDescriptor->Token.Bits.DataToggle           = DataToggle = m_EndpointDescriptor->DataToggle;

    // use physical address
    CurrentDescriptor->BufferPointer[0]                = Address.LowPart + TransferBufferOffset;
    CurrentDescriptor->ExtendedBufferPointer[0]        = 0;                                       // Address.HighPart;

    DPRINT1("CurrentDescriptor->BufferPointer[0] - %p\n", CurrentDescriptor->BufferPointer[0]);
  
    // increment transfer bytes
    CurrentDescriptor->Token.Bits.TotalBytesToTransfer += TransferSize;
    CurrentDescriptor->TotalBytesToTransfer            += TransferSize;

    TransferBufferOffset                               += TransferSize;                           // adjust offset

    InsertTailList(&QueueHead->TransferDescriptorListHead, &CurrentDescriptor->DescriptorEntry);  // insert into queue head

    if ( LastDescriptor )
    {
      // link to current descriptor
      LastDescriptor->NextPointer = CurrentDescriptor->PhysicalAddr;
      LastDescriptor              = CurrentDescriptor;
    }
    else
    {
      LastDescriptor = FirstDescriptor = CurrentDescriptor;                                       // first descriptor in chain
    }

    DataToggle = !DataToggle;                                                                     // flip data toggle

    if ( MaxTransferLength == TransferBufferOffset )  break;                                      // end reached

  } while ( TRUE );

  LastDescriptor = CurrentDescriptor;                                                            // store last descriptor

  m_EndpointDescriptor->DataToggle  = DataToggle;                                                // save data toggle
  m_TransferBufferLengthCompleted  += TransferBufferOffset;                                      // move to next offset

  // init queue head
  QueueHead->EndPointCharacteristics.DeviceAddress        = GetDeviceAddress();
  QueueHead->EndPointCharacteristics.EndPointNumber       = m_EndpointDescriptor->EndPointDescriptor.bEndpointAddress & 0x0F;
  QueueHead->EndPointCharacteristics.MaximumPacketLength  = m_EndpointDescriptor->EndPointDescriptor.wMaxPacketSize;

  QueueHead->NextPointer          = FirstDescriptor->PhysicalAddr;
  QueueHead->CurrentLinkPointer   = FirstDescriptor->PhysicalAddr;
  QueueHead->AlternateNextPointer = TERMINATE_POINTER;

  ASSERT(QueueHead->EndPointCharacteristics.DeviceAddress);
  ASSERT(QueueHead->EndPointCharacteristics.EndPointNumber);
  ASSERT(QueueHead->EndPointCharacteristics.MaximumPacketLength);
  ASSERT(QueueHead->NextPointer);

  LastDescriptor->Token.Bits.InterruptOnComplete = TRUE;    // interrupt on last descriptor

  *OutHead = QueueHead;                                     // store result
  //DumpQueueHead(QueueHead);                               // dump status

  return STATUS_SUCCESS;                                    // done
}
After that "spam" of your flash card can be demanded reformat .

I seem now is relieved of "spam" ;)

Re: USB drivers

Posted: Sun Nov 15, 2015 10:28 am
by lastar
Hi vgal . Maybe we should see how it's done in an open Usb driver Apple ? http://opensource.apple.com/tarballs/IO ... 4.2.tar.gz

http://opensource.apple.com/tarballs/IOUSBFamily/

in addressing errors in Usb here https://jira.reactos.org/browse/CORE-9224

Re: USB drivers

Posted: Wed Nov 25, 2015 10:13 pm
by vgal
Test for boot RoS from flash on real PC. USB 1.1, UHCI driver only. EHCI driver "disabled". OHCI not tested.

My USB patches in one file:
http://vga.16mb.com/download/USB/Test00/Usb-Test.patch

Changed *.c files
http://vga.16mb.com/download/USB/Test00 ... st00_c.zip

Drivers: usbhub.sys, usbstor.sys, usbuhci.sys, usbehci.sys:
http://vga.16mb.com/download/USB/Test00 ... t00_sys.7z

Test ISO: livecd_69997_usb_test00.iso (split - maximum size of one file is restricted to 9.54 MB on server)
http://vga.16mb.com/download/USB/Test00 ... .part1.rar
http://vga.16mb.com/download/USB/Test00 ... .part2.rar
http://vga.16mb.com/download/USB/Test00 ... .part3.rar
http://vga.16mb.com/download/USB/Test00 ... .part4.rar

I use Rufus-1.4.12 for write .iso on flash stick.

Re: USB drivers

Posted: Thu Dec 10, 2015 10:35 pm
by vgal
Test for boot RoS from flash on real PC. USB 2.0, EHCI driver only. UHCI and OHCI drivers "disabled".

Changed *.c files
http://vga.16mb.com/download/USB/Test02 ... st02_c.zip

Drivers, hal and kernel:
http://vga.16mb.com/download/USB/Test02 ... t02_sys.7z

"Disabled" and "enabled" versions drivers in dirs.

EHCI driver for VirtualBox:
http://vga.16mb.com/download/USB/Test02 ... for_VB.zip

This is alpha-drivers! :)

Only one USB device should be, without other devices. And if boot ok, your should correct Power-off RoS. (Save registry).
Good luck!

Re: USB drivers

Posted: Thu Dec 24, 2015 10:06 pm
by vgal
Test for boot RoS from flash on real PC. USB 2.0 and USB 1.1.

Drivers, and system files:
http://vga.16mb.com/download/USB/Test03 ... t03_sys.7z

Mice and keyboards work not always and not all. I tried different type of connections - before loading of OS and after loading. It is also possible to try different combinations of ports.

If boot ok, your should correct Power-off RoS. (Save registry on Flash).

Re: USB drivers

Posted: Wed Dec 30, 2015 7:17 pm
by vgal
Files from Usb_test03_sys.7z for only LiveCd *.iso (NOT for BootCd *.iso) images.

Re: USB drivers

Posted: Thu Dec 31, 2015 2:12 am
by vgal
Test for boot RoS from flash (LiveUSB). Now can load non-debug boot mode.
Drivers, and system files: http://vga.16mb.com/download/USB/Test05 ... t05_sys.7z

Files from archive for LiveCd *.iso (NOT for BootCd *.iso) images. Mice and keyboards work not always and not all. I tried different type of connections - before loading of OS and after loading. It is also possible to try different combinations of ports. Minimal debug info.
If boot ok, your should correct Power-off RoS. (Save registry on Flash).

Re: USB drivers

Posted: Tue Jan 05, 2016 2:30 am
by vgal
Test for boot RoS from flash (LiveUSB). USB 2.0 (EHCI) speed Read/Write up.
Drivers, and system files: http://vga.16mb.com/download/USB/Test06 ... t06_sys.7z

Files from archive for LiveCd *.iso (NOT for BootCd *.iso) images. Minimal debug info.
If boot ok, your should correct Shutdown RoS. (for Save registry on Flash).

Re: USB drivers

Posted: Wed Jan 18, 2017 12:36 pm
by curiousone
The server (vga.16mb.com) hosting those links seems down, not sure if thats temporary or not.

Are these changes available elsewhere for review?

(Yes I know thread is old, but appears vgal is still around.)

Re: USB drivers

Posted: Thu Jan 18, 2018 2:10 pm
by breu35
I did not understand if this is exactly it, but Vgal recently did a compilation of the react. And in my notebook are working well all USB.

http://vgal.ru.com/reactos-0-4-7-new-usb/

Re: USB drivers

Posted: Fri Feb 09, 2018 6:32 am
by vgal

Re: USB drivers

Posted: Fri Feb 09, 2018 6:59 am
by vgal
Help is needed!
Need tests on the hardware, check the operation of new USB drivers in Windows XP \ 2003. To do this, you need to boot into SafeMode (F8) and copy the "usbport.sys" and "usbhub.sys" files (from USB stick) in the "%SystemRoot%\system32\drivers\" folder (usually c:\WINDOWS\system32\drivers\). Then reboot in normal mode and check the connection/disconnect (several times) of various usb devices from flash drives, mice and keyboards.
usb-VS-20180208.zip (115Kb)
Please remember that there are risks, because these are drivers that are under development.
After the test is over, just delete these drivers and reboot - the native drivers will be restored.

Re: USB drivers

Posted: Tue Feb 13, 2018 4:13 am
by tojestzart
makes sense on virtual machine?
or real hardware? only if its win7 aint doing any downgrade or upgrade

Re: USB drivers

Posted: Tue Feb 13, 2018 5:14 am
by ctasan
tojestzart wrote:makes sense on virtual machine?
or real hardware? only if its win7 aint doing any downgrade or upgrade
No, he's calling for tests on real hardware.

Re: USB drivers

Posted: Tue Feb 13, 2018 2:00 pm
by vgal
On the HW is always preferable, but in the virtual machine, you can also check devices. Any tests are welcome and the more they are there, the more objective the look.