USB drivers

All development related issues welcome

Moderator: Moderator Team

vgal
Posts: 88
Joined: Mon Jan 26, 2015 7:38 am

USB drivers

Post 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" ;)
lastar
Posts: 16
Joined: Sat Mar 24, 2012 1:01 pm

Re: USB drivers

Post 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
vgal
Posts: 88
Joined: Mon Jan 26, 2015 7:38 am

Re: USB drivers

Post 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.
vgal
Posts: 88
Joined: Mon Jan 26, 2015 7:38 am

Re: USB drivers

Post 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!
vgal
Posts: 88
Joined: Mon Jan 26, 2015 7:38 am

Re: USB drivers

Post 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).
vgal
Posts: 88
Joined: Mon Jan 26, 2015 7:38 am

Re: USB drivers

Post by vgal »

Files from Usb_test03_sys.7z for only LiveCd *.iso (NOT for BootCd *.iso) images.
vgal
Posts: 88
Joined: Mon Jan 26, 2015 7:38 am

Re: USB drivers

Post 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).
vgal
Posts: 88
Joined: Mon Jan 26, 2015 7:38 am

Re: USB drivers

Post 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).
curiousone
Posts: 14
Joined: Sat Nov 04, 2006 9:25 pm

Re: USB drivers

Post 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.)
breu35
Posts: 12
Joined: Fri Jan 12, 2018 1:50 am

Re: USB drivers

Post 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/
vgal
Posts: 88
Joined: Mon Jan 26, 2015 7:38 am

Re: USB drivers

Post by vgal »

vgal
Posts: 88
Joined: Mon Jan 26, 2015 7:38 am

Re: USB drivers

Post 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.
tojestzart
Posts: 7
Joined: Fri Dec 08, 2017 1:15 am

Re: USB drivers

Post by tojestzart »

makes sense on virtual machine?
or real hardware? only if its win7 aint doing any downgrade or upgrade
ctasan
Posts: 392
Joined: Mon Feb 24, 2014 7:02 pm
Location: Istanbul, Turkey
Contact:

Re: USB drivers

Post 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.
ReactOS Community Changelogs | Admin of ReactOS Official Twitter Account | Admin of ReactOS Turkish Twitter Account @reactos_tr
vgal
Posts: 88
Joined: Mon Jan 26, 2015 7:38 am

Re: USB drivers

Post 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.
Post Reply

Who is online

Users browsing this forum: No registered users and 11 guests