1. 08 5月, 2015 1 次提交
  2. 03 3月, 2015 1 次提交
    • L
      xhci: generate a Transfer Event for each Transfer TRB with the IOC bit set · aa685789
      Laszlo Ersek 提交于
      At the moment, when the XHCI driver in edk2
      (MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf) runs on QEMU, with the options
      
        -device nec-usb-xhci -device usb-kbd
      
      it crashes with:
      
        ASSERT MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c(1759):
        TrsRing != ((void*) 0)
      
      The crash hits in the following edk2 call sequence (all files under
      MdeModulePkg/Bus/):
      
      UsbEnumerateNewDev()                         [Usb/UsbBusDxe/UsbEnumer.c]
        UsbBuildDescTable()                        [Usb/UsbBusDxe/UsbDesc.c]
          UsbGetDevDesc()                          [Usb/UsbBusDxe/UsbDesc.c]
            UsbCtrlGetDesc(USB_REQ_GET_DESCRIPTOR) [Usb/UsbBusDxe/UsbDesc.c]
              UsbCtrlRequest()                     [Usb/UsbBusDxe/UsbDesc.c]
                UsbHcControlTransfer()             [Usb/UsbBusDxe/UsbUtility.c]
                  XhcControlTransfer()             [Pci/XhciDxe/Xhci.c]
                    XhcCreateUrb()                 [Pci/XhciDxe/XhciSched.c]
                      XhcCreateTransferTrb()       [Pci/XhciDxe/XhciSched.c]
                    XhcExecTransfer()              [Pci/XhciDxe/XhciSched.c]
                      XhcCheckUrbResult()          [Pci/XhciDxe/XhciSched.c]
                        //
                        // look for TRB_TYPE_DATA_STAGE event [1]
                        //
                    //
                    // Store a copy of the device descriptor, as the hub device
                    // needs this info to configure endpoint. [2]
                    //
        UsbSetConfig()                             [Usb/UsbBusDxe/UsbDesc.c]
          UsbCtrlRequest(USB_REQ_SET_CONFIG)       [Usb/UsbBusDxe/UsbDesc.c]
            UsbHcControlTransfer()                 [Usb/UsbBusDxe/UsbUtility.c]
              XhcControlTransfer()                 [Pci/XhciDxe/Xhci.c]
                XhcSetConfigCmd()                  [Pci/XhciDxe/XhciSched.c]
                  XhcInitializeEndpointContext()   [Pci/XhciDxe/XhciSched.c]
                    //
                    // allocate transfer ring for the endpoint [3]
                    //
      
      USBKeyboardDriverBindingStart()              [Usb/UsbKbDxe/EfiKey.c]
        UsbIoAsyncInterruptTransfer()              [Usb/UsbBusDxe/UsbBus.c]
          UsbHcAsyncInterruptTransfer()            [Usb/UsbBusDxe/UsbUtility.c]
            XhcAsyncInterruptTransfer()            [Pci/XhciDxe/Xhci.c]
              XhcCreateUrb()                       [Pci/XhciDxe/Xhci.c]
                XhcCreateTransferTrb()             [Pci/XhciDxe/XhciSched.c]
                  XhcSyncTrsRing()                 [Pci/XhciDxe/XhciSched.c]
                    ASSERT (TrsRing != NULL) [4]
      
      UsbEnumerateNewDev() in the USB bus driver issues a GET_DESCRIPTOR
      request, in order to determine the number of configurations that the
      endpoint supports. The requests consists of three stages (three TRBs),
      setup, data, and status. The length of the response is determined in [1],
      namely from the transfer event that the host controller generates in
      response to the request's middle stage (ie. the data stage).
      
      If the length of the answer is correct (a full GET_DESCRIPTOR request
      takes 18 bytes), then the XHCI driver that underlies the USB bus driver
      "snoops" (caches) the descriptor data for later [2].
      
      Later, the USB bus driver sends a SET_CONFIG request. The underlying XHCI
      driver allocates a transfer ring for the endpoint, relying on the data
      snooped and cached in step [2].
      
      Finally, the USB keyboard driver submits an asynchronous interrupt
      transfer to manage the keyboard. As part of this it asserts [4] that the
      ring has been allocated in step [3].
      
      And this ASSERT() fires. The root cause can be found in the way QEMU
      handles the initial GET_DESCRIPTOR request.
      
      Again, that request consists of three stages (TRBs, Transfer Request
      Blocks), "setup", "data", and "status". The XhcCreateTransferTrb()
      function sets the IOC ("Interrupt on Completion") flag in each of these
      TRBs.
      
      According to the XHCI specification, the host controller shall generate a
      Transfer Event in response to *each* individual TRB of the request that
      had the IOC flag set. This means that QEMU should queue three events:
      setup, data, and status, for edk2's XHCI driver.
      
      However, QEMU only generates two events:
      - one for the setup (ie. 1st) stage,
      - another for the status (ie. 3rd) stage.
      
      No event is generated for the middle (ie. data) stage. The loop in QEMU's
      xhci_xfer_report() function runs three times, but due to the "reported"
      variable, only the first and the last TRBs elicit events, the middle (data
      stage) results in no event queued.
      
      As a consequence:
      - When handling the GET_DESCRIPTOR request, XhcCheckUrbResult() in [1]
        does not update the response length from zero.
      
      - XhcControlTransfer() thinks that the response is invalid (it has zero
        length payload instead of 18 bytes), hence [2] is not reached; the
        device descriptor is not stashed for later, and the number of possible
        configurations is left at zero.
      
      - When handling the SET_CONFIG request, (NumConfigurations == 0) from
        above prevents the allocation of the endpoint's transfer ring.
      
      - When the keyboard driver tries to use the endpoint, the ASSERT() blows
        up.
      
      The solution is to correct the emulation in QEMU, and to generate a
      transfer event whenever IOC is set in a TRB.
      
      The patch replaces
      
        !reported && (IOC || foo)    == !reported && IOC ||
                                        !reported && foo
      
      with
      
        IOC || (!reported && foo)    == IOC ||
                                        !reported && foo
      
      which only changes how
      
        reported && IOC
      
      is handled. (Namely, it now generates an event.)
      
      Tested with edk2 built for "qemu-system-aarch64 -M virt" (ie.
      "ArmVirtualizationQemu.dsc", aka "AAVMF"), and guest Linux.
      Signed-off-by: NLaszlo Ersek <lersek@redhat.com>
      Signed-off-by: NGerd Hoffmann <kraxel@redhat.com>
      aa685789
  3. 26 2月, 2015 1 次提交
  4. 26 1月, 2015 1 次提交
  5. 11 11月, 2014 1 次提交
  6. 28 10月, 2014 1 次提交
  7. 15 10月, 2014 1 次提交
  8. 23 9月, 2014 1 次提交
  9. 10 9月, 2014 1 次提交
    • D
      xhci PCIe endpoint migration compatibility fix · e6043e92
      Dr. David Alan Gilbert 提交于
      Add back the PCIe config capabilities on XHCI cards in non-PCIe slots,
      but only for machine types before 2.1.
      
      This fixes a migration incompatibility in the XHCI PCI devices
      caused by:
         058fdcf5 - xhci: add endpoint cap on express bus only
      
      Note that in fixing it for compatibility with older QEMUs, it breaks
      compatibility with existing QEMU 2.1's on older machine types.
      
      The status before this patch was (if it used an XHCI adapter):
         machine type | source qemu
           any           pre-2.1     - FAIL
           any           2.1...      - PASS
      
      With this patch:
         machine type | source qemu
           any           pre-2.1    - PASS
           pre-2.1       2.1...     - FAIL
           2.1           2.1...     - PASS
      
      A test to trigger it is to add '-device nec-usb-xhci,id=xhci,addr=0x12'
      to the command line.
      
      Cc: qemu-stable@nongnu.org
      Signed-off-by: NDr. David Alan Gilbert <dgilbert@redhat.com>
      Acked-by: NMichael S. Tsirkin <mst@redhat.com>
      Signed-off-by: NGerd Hoffmann <kraxel@redhat.com>
      e6043e92
  10. 29 8月, 2014 5 次提交
  11. 23 7月, 2014 1 次提交
    • L
      vmstate_xhci_event: fix unterminated field list · 3afca1d6
      Laszlo Ersek 提交于
      "vmstate_xhci_event" was introduced in commit 37352df3 ("xhci: add live
      migration support"), and first released in v1.6.0. The field list in this
      VMSD is not terminated with the VMSTATE_END_OF_LIST() macro.
      
      During normal use (ie. migration), the issue is practically invisible,
      because the "vmstate_xhci_event" object (with the unterminated field list)
      is only ever referenced -- via "vmstate_xhci_intr" -- if xhci_er_full()
      returns true, for the "ev_buffer" test. Since that field_exists() check
      (apparently) almost always returns false, we almost never traverse
      "vmstate_xhci_event" during migration, which hides the bug.
      
      However, Amit's vmstate checker forces recursion into this VMSD as well,
      and the lack of VMSTATE_END_OF_LIST() breaks the field list terminator
      check (field->name != NULL) in dump_vmstate_vmsd(). The result is
      undefined behavior, which in my case translates to infinite recursion
      (because the loop happens to overflow into "vmstate_xhci_intr", which then
      links back to "vmstate_xhci_event").
      
      Add the missing terminator.
      Signed-off-by: NLaszlo Ersek <lersek@redhat.com>
      Reviewed-by: NAmit Shah <amit.shah@redhat.com>
      Reviewed-by: NPaolo Bonzini <pbonzini@redhat.com>
      Cc: qemu-stable@nongnu.org
      Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
      3afca1d6
  12. 02 6月, 2014 2 次提交
  13. 26 5月, 2014 3 次提交
  14. 18 2月, 2014 5 次提交
  15. 10 2月, 2014 1 次提交
  16. 26 11月, 2013 3 次提交
    • H
      xhci: Call usb_device_alloc/free_streams · 72391da5
      Hans de Goede 提交于
      Note this code is not as KISS as I would like, the reason for this is that
      the Linux kernel interface wants streams on eps belonging to one interface
      to be allocated in one call. Things will also work if we do this one ep at a
      time (as long as all eps support the same amount of streams), but lets stick
      to the kernel API.
      Signed-off-by: NHans de Goede <hdegoede@redhat.com>
      Signed-off-by: NGerd Hoffmann <kraxel@redhat.com>
      72391da5
    • G
      xhci: add support for suspend/resume · f1f8bc21
      Gerd Hoffmann 提交于
      The OS can ask the xhci controller to save and restore its
      internal state, which is used by the OS when the system is
      suspended and resumed.
      
      This patch handles writes to the save + restore bits in the
      command register.  Only thing it does is updating the
      restore error bit in the status register to signal an error
      on restore.  The guest OS should do a full reinitialization
      after resume then.
      
      This is the minimal patch which gets S3 going with xhci.
      Implementing full save/restore support is TBD.
      
      https://bugzilla.redhat.com/show_bug.cgi?id=1012365Signed-off-by: NGerd Hoffmann <kraxel@redhat.com>
      f1f8bc21
    • H
      xhci: Add a few missing checks for disconnected devices · de9de157
      Hans de Goede 提交于
      One of the reworks of qemu's usb core made changes to usb-port's disconnect
      handling. Now ports with a device will always have a non 0 dev member, but
      if the device is not attached (which is possible with usb redirection),
      dev->attached will be 0.
      
      So supplement all checks for dev to also check dev->attached, and add an
      extra check in a path where a device check was completely missing.
      
      This fixes various crashes (asserts triggering) I've been seeing when xhci
      attached usb devices get disconnected at the wrong time.
      Signed-off-by: NHans de Goede <hdegoede@redhat.com>
      Signed-off-by: NGerd Hoffmann <kraxel@redhat.com>
      de9de157
  17. 22 10月, 2013 4 次提交
  18. 14 10月, 2013 1 次提交
  19. 19 9月, 2013 4 次提交
  20. 02 9月, 2013 2 次提交