VirtualBox

Changeset 93914 in vbox for trunk/include


Ignore:
Timestamp:
Feb 24, 2022 12:20:43 PM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
150140
Message:

Devices/USB: Convert the HCI emulations to call into the roothub using the devices port instead of using the VUSBIDEVICE interface directly. This will avoid races when devices will get detached unexpectedly while being in use. Also move the device re-attach logic after a saved state operation down to the roothub in order to avoid code duplication, bugref:10196

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vusb.h

    r93115 r93914  
    564564
    565565
    566 
    567 /**
    568  * VBox USB port bitmap.
    569  *
    570  * Bit 0 == Port 0, ... , Bit 127 == Port 127.
    571  */
    572 typedef struct VUSBPORTBITMAP
    573 {
    574     /** 128 bits */
    575     char ach[16];
    576 } VUSBPORTBITMAP;
    577 /** Pointer to a VBox USB port bitmap. */
    578 typedef VUSBPORTBITMAP *PVUSBPORTBITMAP;
    579 
    580 #ifndef RDESKTOP
    581 
    582 /**
    583  * The VUSB RootHub port interface provided by the HCI (down).
    584  * Pair with VUSBIROOTCONNECTOR
    585  */
    586 typedef struct VUSBIROOTHUBPORT
    587 {
    588     /**
    589      * Get the number of available ports in the hub.
    590      *
    591      * @returns The number of ports available.
    592      * @param   pInterface      Pointer to this structure.
    593      * @param   pAvailable      Bitmap indicating the available ports. Set bit == available port.
    594      */
    595     DECLR3CALLBACKMEMBER(unsigned, pfnGetAvailablePorts,(PVUSBIROOTHUBPORT pInterface, PVUSBPORTBITMAP pAvailable));
    596 
    597     /**
    598      * Gets the supported USB versions.
    599      *
    600      * @returns The mask of supported USB versions.
    601      * @param   pInterface      Pointer to this structure.
    602      */
    603     DECLR3CALLBACKMEMBER(uint32_t, pfnGetUSBVersions,(PVUSBIROOTHUBPORT pInterface));
    604 
    605     /**
    606      * A device is being attached to a port in the roothub.
    607      *
    608      * @param   pInterface      Pointer to this structure.
    609      * @param   pDev            Pointer to the device being attached.
    610      * @param   uPort           The port number assigned to the device.
    611      */
    612     DECLR3CALLBACKMEMBER(int, pfnAttach,(PVUSBIROOTHUBPORT pInterface, PVUSBIDEVICE pDev, unsigned uPort));
    613 
    614     /**
    615      * A device is being detached from a port in the roothub.
    616      *
    617      * @param   pInterface      Pointer to this structure.
    618      * @param   pDev            Pointer to the device being detached.
    619      * @param   uPort           The port number assigned to the device.
    620      */
    621     DECLR3CALLBACKMEMBER(void, pfnDetach,(PVUSBIROOTHUBPORT pInterface, PVUSBIDEVICE pDev, unsigned uPort));
    622 
    623     /**
    624      * Reset the root hub.
    625      *
    626      * @returns VBox status code.
    627      * @param   pInterface      Pointer to this structure.
    628      * @param   pResetOnLinux   Whether or not to do real reset on linux.
    629      */
    630     DECLR3CALLBACKMEMBER(int, pfnReset,(PVUSBIROOTHUBPORT pInterface, bool fResetOnLinux));
    631 
    632     /**
    633      * Transfer completion callback routine.
    634      *
    635      * VUSB will call this when a transfer have been completed
    636      * in a one or another way.
    637      *
    638      * @param   pInterface      Pointer to this structure.
    639      * @param   pUrb            Pointer to the URB in question.
    640      */
    641     DECLR3CALLBACKMEMBER(void, pfnXferCompletion,(PVUSBIROOTHUBPORT pInterface, PVUSBURB urb));
    642 
    643     /**
    644      * Handle transfer errors.
    645      *
    646      * VUSB calls this when a transfer attempt failed. This function will respond
    647      * indicating whether to retry or complete the URB with failure.
    648      *
    649      * @returns Retry indicator.
    650      * @param   pInterface      Pointer to this structure.
    651      * @param   pUrb            Pointer to the URB in question.
    652      */
    653     DECLR3CALLBACKMEMBER(bool, pfnXferError,(PVUSBIROOTHUBPORT pInterface, PVUSBURB pUrb));
    654 
    655     /**
    656      * Processes a new frame if periodic frame processing is enabled.
    657      *
    658      * @returns Flag whether there was activity which influences the frame rate.
    659      * @param   pInterface      Pointer to this structure.
    660      * @param   u32FrameNo      The frame number.
    661      */
    662     DECLR3CALLBACKMEMBER(bool, pfnStartFrame, (PVUSBIROOTHUBPORT pInterface, uint32_t u32FrameNo));
    663 
    664     /**
    665      * Informs the callee about a change in the frame rate due to too many idle cycles or
    666      * when seeing activity after some idle time.
    667      *
    668      * @returns nothing.
    669      * @param   pInterface      Pointer to this structure.
    670      * @param   u32FrameRate    The new frame rate.
    671      */
    672     DECLR3CALLBACKMEMBER(void, pfnFrameRateChanged, (PVUSBIROOTHUBPORT pInterface, uint32_t u32FrameRate));
    673 
    674     /** Alignment dummy. */
    675     RTR3PTR Alignment;
    676 
    677 } VUSBIROOTHUBPORT;
    678 /** VUSBIROOTHUBPORT interface ID. */
    679 # define VUSBIROOTHUBPORT_IID                   "6571aece-6c33-4714-a8ac-9508a3b8b429"
    680 
    681 /** Pointer to a VUSB RootHub connector interface. */
    682 typedef struct VUSBIROOTHUBCONNECTOR *PVUSBIROOTHUBCONNECTOR;
    683 /**
    684  * The VUSB RootHub connector interface provided by the VBox USB RootHub driver
    685  * (up).
    686  * Pair with VUSBIROOTHUBPORT.
    687  */
    688 typedef struct VUSBIROOTHUBCONNECTOR
    689 {
    690     /**
    691      * Sets the URB parameters for the caller.
    692      *
    693      * @returns VBox status code.
    694      * @param   pInterface  Pointer to this struct.
    695      * @param   cbHci       Size of the data private to the HCI for each URB when allocated.
    696      * @param   cbHciTd     Size of one transfer descriptor. The number of transfer descriptors
    697      *                      is given VUSBIROOTHUBCONNECTOR::pfnNewUrb for each URB to calculate the
    698      *                      final amount of memory required for the TDs.
    699      *
    700      * @note This must be called before starting to allocate any URB or otherwise there will be no
    701      *       data available for the HCI.
    702      */
    703     DECLR3CALLBACKMEMBER(int, pfnSetUrbParams, (PVUSBIROOTHUBCONNECTOR pInterface, size_t cbHci, size_t cbHciTd));
    704 
    705     /**
    706      * Allocates a new URB for a transfer.
    707      *
    708      * Either submit using pfnSubmitUrb or free using VUSBUrbFree().
    709      *
    710      * @returns Pointer to a new URB.
    711      * @returns NULL on failure - try again later.
    712      *          This will not fail if the device wasn't found. We'll fail it
    713      *          at submit time, since that makes the usage of this api simpler.
    714      * @param   pInterface  Pointer to this struct.
    715      * @param   DstAddress  The destination address of the URB.
    716      * @param   pDev        Optional device pointer the URB is for.
    717      * @param   enmType     Type of the URB.
    718      * @param   enmDir      Data transfer direction.
    719      * @param   cbData      The amount of data space required.
    720      * @param   cTds        The amount of TD space.
    721      * @param   pszTag      Custom URB tag assigned by the caller, only for
    722      *                      logged builds and optional.
    723      *
    724      * @note pDev should be NULL in most cases. The only useful case is for USB3 where
    725      *       it is required for the SET_ADDRESS request because USB3 uses unicast traffic.
    726      */
    727     DECLR3CALLBACKMEMBER(PVUSBURB, pfnNewUrb,(PVUSBIROOTHUBCONNECTOR pInterface, uint8_t DstAddress, PVUSBIDEVICE pDev,
    728                                               VUSBXFERTYPE enmType, VUSBDIRECTION enmDir, uint32_t cbData, uint32_t cTds, const char *pszTag));
    729 
    730     /**
    731      * Free an URB not submitted yet.
    732      *
    733      * @returns VBox status code.
    734      * @param   pInterface  Pointer to this struct.
    735      * @param   pUrb        Pointer to the URB to free returned by VUSBIROOTHUBCONNECTOR::pfnNewUrb.
    736      */
    737     DECLR3CALLBACKMEMBER(int, pfnFreeUrb, (PVUSBIROOTHUBCONNECTOR pInterface, PVUSBURB pUrb));
    738 
    739     /**
    740      * Submits a URB for transfer.
    741      * The transfer will do asynchronously if possible.
    742      *
    743      * @returns VBox status code.
    744      * @param   pInterface  Pointer to this struct.
    745      * @param   pUrb        Pointer to the URB returned by pfnNewUrb.
    746      *                      The URB will be freed in case of failure.
    747      * @param   pLed        Pointer to USB Status LED
    748      */
    749     DECLR3CALLBACKMEMBER(int, pfnSubmitUrb,(PVUSBIROOTHUBCONNECTOR pInterface, PVUSBURB pUrb, struct PDMLED *pLed));
    750 
    751     /**
    752      * Call to service asynchronous URB completions in a polling fashion.
    753      *
    754      * Reaped URBs will be finished by calling the completion callback,
    755      * thus there is no return code or input or anything from this function
    756      * except for potential state changes elsewhere.
    757      *
    758      * @returns VINF_SUCCESS if no URBs are pending upon return.
    759      * @returns VERR_TIMEOUT if one or more URBs are still in flight upon returning.
    760      * @returns Other VBox status code.
    761      *
    762      * @param   pInterface  Pointer to this struct.
    763      * @param   pDevice     Pointer to a USB device.
    764      * @param   cMillies    Number of milliseconds to poll for completion.
    765      */
    766     DECLR3CALLBACKMEMBER(void, pfnReapAsyncUrbs,(PVUSBIROOTHUBCONNECTOR pInterface, PVUSBIDEVICE pDevice, RTMSINTERVAL cMillies));
    767 
    768     /**
    769      * Cancels and completes - with CRC failure - all URBs queued on an endpoint.
    770      * This is done in response to guest URB cancellation.
    771      *
    772      * @returns VBox status code.
    773      * @param   pInterface  Pointer to this struct.
    774      * @param   pUrb        Pointer to a previously submitted URB.
    775      */
    776     DECLR3CALLBACKMEMBER(int, pfnCancelUrbsEp,(PVUSBIROOTHUBCONNECTOR pInterface, PVUSBURB pUrb));
    777 
    778     /**
    779      * Cancels and completes - with CRC failure - all in-flight async URBs.
    780      * This is typically done before saving a state.
    781      *
    782      * @param   pInterface  Pointer to this struct.
    783      */
    784     DECLR3CALLBACKMEMBER(void, pfnCancelAllUrbs,(PVUSBIROOTHUBCONNECTOR pInterface));
    785 
    786     /**
    787      * Cancels and completes - with CRC failure - all URBs queued on an endpoint.
    788      * This is done in response to a guest endpoint/pipe abort.
    789      *
    790      * @returns VBox status code.
    791      * @param   pInterface  Pointer to this struct.
    792      * @param   pDevice     Pointer to a USB device.
    793      * @param   EndPt       Endpoint number.
    794      * @param   enmDir      Endpoint direction.
    795      */
    796     DECLR3CALLBACKMEMBER(int, pfnAbortEp,(PVUSBIROOTHUBCONNECTOR pInterface, PVUSBIDEVICE pDevice, int EndPt, VUSBDIRECTION enmDir));
    797 
    798     /**
    799      * Attach the device to the root hub.
    800      * The device must not be attached to any hub for this call to succeed.
    801      *
    802      * @returns VBox status code.
    803      * @param   pInterface  Pointer to this struct.
    804      * @param   pDevice     Pointer to the device (interface) to attach.
    805      */
    806     DECLR3CALLBACKMEMBER(int, pfnAttachDevice,(PVUSBIROOTHUBCONNECTOR pInterface, PVUSBIDEVICE pDevice));
    807 
    808     /**
    809      * Detach the device from the root hub.
    810      * The device must already be attached for this call to succeed.
    811      *
    812      * @returns VBox status code.
    813      * @param   pInterface  Pointer to this struct.
    814      * @param   pDevice     Pointer to the device (interface) to detach.
    815      */
    816     DECLR3CALLBACKMEMBER(int, pfnDetachDevice,(PVUSBIROOTHUBCONNECTOR pInterface, PVUSBIDEVICE pDevice));
    817 
    818     /**
    819      * Sets periodic frame processing.
    820      *
    821      * @returns VBox status code.
    822      * @param   pInterface  Pointer to this struct.
    823      * @param   uFrameRate  The target frame rate in Hertz, 0 disables periodic frame processing.
    824      *                      The real frame rate might be lower if there is no activity for a certain period or
    825      *                      higher if there is a need for catching up with where the guest expects the device to be.
    826      */
    827     DECLR3CALLBACKMEMBER(int, pfnSetPeriodicFrameProcessing, (PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uFrameRate));
    828 
    829     /**
    830      * Returns the current frame rate for the periodic frame processing.
    831      *
    832      * @returns Frame rate for periodic frame processing.
    833      * @retval  0 if disabled.
    834      * @param   pInterface  Pointer to this struct.
    835      */
    836     DECLR3CALLBACKMEMBER(uint32_t, pfnGetPeriodicFrameRate, (PVUSBIROOTHUBCONNECTOR pInterface));
    837 
    838     /**
    839      * Updates the internally stored isochronous scheduling frame for a given
    840      * endpoint and returns the delta between the current and previous frame.
    841      *
    842      * @returns Delta between currently and previously scheduled frame.
    843      * @retval  0 if no previous frame was set.
    844      * @param   pInterface  Pointer to this struct.
    845      * @param   pDevice     Pointer to a USB device.
    846      * @param   EndPt       Endpoint number.
    847      * @param   enmDir      Endpoint direction.
    848      * @param   uNewFrameID The frame ID of a new transfer.
    849      * @param   uBits       The number of significant bits in frame ID.
    850      */
    851     DECLR3CALLBACKMEMBER(uint32_t, pfnUpdateIsocFrameDelta, (PVUSBIROOTHUBCONNECTOR pInterface, PVUSBIDEVICE pDevice,
    852                                                              int EndPt, VUSBDIRECTION enmDir, uint16_t uNewFrameID, uint8_t uBits));
    853 
    854     /** Alignment dummy. */
    855     RTR3PTR Alignment;
    856 
    857 } VUSBIROOTHUBCONNECTOR;
    858 AssertCompileSizeAlignment(VUSBIROOTHUBCONNECTOR, 8);
    859 /** VUSBIROOTHUBCONNECTOR interface ID. */
    860 # define VUSBIROOTHUBCONNECTOR_IID              "662d7822-b9c6-43b5-88b6-5d59f0106e46"
    861 
    862 
    863 # ifdef IN_RING3
    864 /** @copydoc VUSBIROOTHUBCONNECTOR::pfnSetUrbParams */
    865 DECLINLINE(int) VUSBIRhSetUrbParams(PVUSBIROOTHUBCONNECTOR pInterface, size_t cbHci, size_t cbHciTd)
    866 {
    867     return pInterface->pfnSetUrbParams(pInterface, cbHci, cbHciTd);
    868 }
    869 
    870 /** @copydoc VUSBIROOTHUBCONNECTOR::pfnNewUrb */
    871 DECLINLINE(PVUSBURB) VUSBIRhNewUrb(PVUSBIROOTHUBCONNECTOR pInterface, uint8_t DstAddress, PVUSBIDEVICE pDev,
    872                                    VUSBXFERTYPE enmType, VUSBDIRECTION enmDir, uint32_t cbData, uint32_t cTds, const char *pszTag)
    873 {
    874     return pInterface->pfnNewUrb(pInterface, DstAddress, pDev, enmType, enmDir, cbData, cTds, pszTag);
    875 }
    876 
    877 /** @copydoc VUSBIROOTHUBCONNECTOR::pfnFreeUrb */
    878 DECLINLINE(int) VUSBIRhFreeUrb(PVUSBIROOTHUBCONNECTOR pInterface, PVUSBURB pUrb)
    879 {
    880     return pInterface->pfnFreeUrb(pInterface, pUrb);
    881 }
    882 
    883 /** @copydoc VUSBIROOTHUBCONNECTOR::pfnSubmitUrb */
    884 DECLINLINE(int) VUSBIRhSubmitUrb(PVUSBIROOTHUBCONNECTOR pInterface, PVUSBURB pUrb, struct PDMLED *pLed)
    885 {
    886     return pInterface->pfnSubmitUrb(pInterface, pUrb, pLed);
    887 }
    888 
    889 /** @copydoc VUSBIROOTHUBCONNECTOR::pfnReapAsyncUrbs */
    890 DECLINLINE(void) VUSBIRhReapAsyncUrbs(PVUSBIROOTHUBCONNECTOR pInterface, PVUSBIDEVICE pDevice, RTMSINTERVAL cMillies)
    891 {
    892     pInterface->pfnReapAsyncUrbs(pInterface, pDevice, cMillies);
    893 }
    894 
    895 /** @copydoc VUSBIROOTHUBCONNECTOR::pfnCancelAllUrbs */
    896 DECLINLINE(void) VUSBIRhCancelAllUrbs(PVUSBIROOTHUBCONNECTOR pInterface)
    897 {
    898     pInterface->pfnCancelAllUrbs(pInterface);
    899 }
    900 
    901 /** @copydoc VUSBIROOTHUBCONNECTOR::pfnAttachDevice */
    902 DECLINLINE(int) VUSBIRhAttachDevice(PVUSBIROOTHUBCONNECTOR pInterface, PVUSBIDEVICE pDevice)
    903 {
    904     return pInterface->pfnAttachDevice(pInterface, pDevice);
    905 }
    906 
    907 /** @copydoc VUSBIROOTHUBCONNECTOR::pfnDetachDevice */
    908 DECLINLINE(int) VUSBIRhDetachDevice(PVUSBIROOTHUBCONNECTOR pInterface, PVUSBIDEVICE pDevice)
    909 {
    910     return pInterface->pfnDetachDevice(pInterface, pDevice);
    911 }
    912 
    913 /** @copydoc VUSBIROOTHUBCONNECTOR::pfnSetPeriodicFrameProcessing */
    914 DECLINLINE(int) VUSBIRhSetPeriodicFrameProcessing(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uFrameRate)
    915 {
    916     return pInterface->pfnSetPeriodicFrameProcessing(pInterface, uFrameRate);
    917 }
    918 
    919 /** @copydoc VUSBIROOTHUBCONNECTOR::pfnGetPeriodicFrameRate */
    920 DECLINLINE(uint32_t) VUSBIRhGetPeriodicFrameRate(PVUSBIROOTHUBCONNECTOR pInterface)
    921 {
    922     return pInterface->pfnGetPeriodicFrameRate(pInterface);
    923 }
    924 # endif /* IN_RING3 */
    925 
    926 #endif /* ! RDESKTOP */
    927 
    928 
    929566/**
    930567 * VUSB device reset completion callback function.
     
    932569 *
    933570 * @param   pDevice Pointer to the virtual USB device core.
     571 * @param   uPort   The port of the device which completed the reset.
    934572 * @param   rc      The VBox status code of the reset operation.
    935573 * @param   pvUser  User specific argument.
     
    937575 * @thread  The reset thread or EMT.
    938576 */
    939 typedef DECLCALLBACKTYPE(void, FNVUSBRESETDONE,(PVUSBIDEVICE pDevice, int rc, void *pvUser));
     577typedef DECLCALLBACKTYPE(void, FNVUSBRESETDONE,(PVUSBIDEVICE pDevice, uint32_t uPort, int rc, void *pvUser));
    940578/** Pointer to a device reset completion callback function (FNUSBRESETDONE). */
    941579typedef FNVUSBRESETDONE *PFNVUSBRESETDONE;
     580
    942581
    943582/**
     
    965604    VUSB_DEVICE_STATE_32BIT_HACK = 0x7fffffff
    966605} VUSBDEVICESTATE;
     606
     607
     608/** Maximum number of USB devices supported. */
     609#define VUSB_DEVICES_MAX            128
     610/** An invalid device port. */
     611#define VUSB_DEVICE_PORT_INVALID    UINT32_MAX
     612
     613/**
     614 * VBox USB port bitmap.
     615 *
     616 * Bit 0 == Port 0, ... , Bit 127 == Port 127.
     617 */
     618typedef struct VUSBPORTBITMAP
     619{
     620    /** 128 bits */
     621    char ach[VUSB_DEVICES_MAX / 8];
     622} VUSBPORTBITMAP;
     623/** Pointer to a VBox USB port bitmap. */
     624typedef VUSBPORTBITMAP *PVUSBPORTBITMAP;
     625AssertCompile(sizeof(VUSBPORTBITMAP) * 8 >= VUSB_DEVICES_MAX);
     626
     627#ifndef RDESKTOP
     628
     629/**
     630 * The VUSB RootHub port interface provided by the HCI (down).
     631 * Pair with VUSBIROOTCONNECTOR
     632 */
     633typedef struct VUSBIROOTHUBPORT
     634{
     635    /**
     636     * Get the number of available ports in the hub.
     637     *
     638     * @returns The number of ports available.
     639     * @param   pInterface      Pointer to this structure.
     640     * @param   pAvailable      Bitmap indicating the available ports. Set bit == available port.
     641     */
     642    DECLR3CALLBACKMEMBER(unsigned, pfnGetAvailablePorts,(PVUSBIROOTHUBPORT pInterface, PVUSBPORTBITMAP pAvailable));
     643
     644    /**
     645     * Gets the supported USB versions.
     646     *
     647     * @returns The mask of supported USB versions.
     648     * @param   pInterface      Pointer to this structure.
     649     */
     650    DECLR3CALLBACKMEMBER(uint32_t, pfnGetUSBVersions,(PVUSBIROOTHUBPORT pInterface));
     651
     652    /**
     653     * A device is being attached to a port in the roothub.
     654     *
     655     * @param   pInterface      Pointer to this structure.
     656     * @param   uPort           The port number assigned to the device.
     657     * @param   enmSpeed        The speed of the device being attached.
     658     */
     659    DECLR3CALLBACKMEMBER(int, pfnAttach,(PVUSBIROOTHUBPORT pInterface, uint32_t uPort, VUSBSPEED enmSpeed));
     660
     661    /**
     662     * A device is being detached from a port in the roothub.
     663     *
     664     * @param   pInterface      Pointer to this structure.
     665     * @param   uPort           The port number assigned to the device.
     666     */
     667    DECLR3CALLBACKMEMBER(void, pfnDetach,(PVUSBIROOTHUBPORT pInterface, uint32_t uPort));
     668
     669    /**
     670     * Reset the root hub.
     671     *
     672     * @returns VBox status code.
     673     * @param   pInterface      Pointer to this structure.
     674     * @param   fResetOnLinux   Whether or not to do real reset on linux.
     675     */
     676    DECLR3CALLBACKMEMBER(int, pfnReset,(PVUSBIROOTHUBPORT pInterface, bool fResetOnLinux));
     677
     678    /**
     679     * Transfer completion callback routine.
     680     *
     681     * VUSB will call this when a transfer have been completed
     682     * in a one or another way.
     683     *
     684     * @param   pInterface      Pointer to this structure.
     685     * @param   pUrb            Pointer to the URB in question.
     686     */
     687    DECLR3CALLBACKMEMBER(void, pfnXferCompletion,(PVUSBIROOTHUBPORT pInterface, PVUSBURB pUrb));
     688
     689    /**
     690     * Handle transfer errors.
     691     *
     692     * VUSB calls this when a transfer attempt failed. This function will respond
     693     * indicating whether to retry or complete the URB with failure.
     694     *
     695     * @returns Retry indicator.
     696     * @param   pInterface      Pointer to this structure.
     697     * @param   pUrb            Pointer to the URB in question.
     698     */
     699    DECLR3CALLBACKMEMBER(bool, pfnXferError,(PVUSBIROOTHUBPORT pInterface, PVUSBURB pUrb));
     700
     701    /**
     702     * Processes a new frame if periodic frame processing is enabled.
     703     *
     704     * @returns Flag whether there was activity which influences the frame rate.
     705     * @param   pInterface      Pointer to this structure.
     706     * @param   u32FrameNo      The frame number.
     707     */
     708    DECLR3CALLBACKMEMBER(bool, pfnStartFrame, (PVUSBIROOTHUBPORT pInterface, uint32_t u32FrameNo));
     709
     710    /**
     711     * Informs the callee about a change in the frame rate due to too many idle cycles or
     712     * when seeing activity after some idle time.
     713     *
     714     * @returns nothing.
     715     * @param   pInterface      Pointer to this structure.
     716     * @param   u32FrameRate    The new frame rate.
     717     */
     718    DECLR3CALLBACKMEMBER(void, pfnFrameRateChanged, (PVUSBIROOTHUBPORT pInterface, uint32_t u32FrameRate));
     719
     720    /** Alignment dummy. */
     721    RTR3PTR Alignment;
     722
     723} VUSBIROOTHUBPORT;
     724/** VUSBIROOTHUBPORT interface ID. */
     725# define VUSBIROOTHUBPORT_IID                   "2ece01c2-4dbf-4bd5-96ca-09fc14164cd4"
     726
     727/** Pointer to a VUSB RootHub connector interface. */
     728typedef struct VUSBIROOTHUBCONNECTOR *PVUSBIROOTHUBCONNECTOR;
     729/**
     730 * The VUSB RootHub connector interface provided by the VBox USB RootHub driver
     731 * (up).
     732 * Pair with VUSBIROOTHUBPORT.
     733 */
     734typedef struct VUSBIROOTHUBCONNECTOR
     735{
     736    /**
     737     * Sets the URB parameters for the caller.
     738     *
     739     * @returns VBox status code.
     740     * @param   pInterface  Pointer to this struct.
     741     * @param   cbHci       Size of the data private to the HCI for each URB when allocated.
     742     * @param   cbHciTd     Size of one transfer descriptor. The number of transfer descriptors
     743     *                      is given VUSBIROOTHUBCONNECTOR::pfnNewUrb for each URB to calculate the
     744     *                      final amount of memory required for the TDs.
     745     *
     746     * @note This must be called before starting to allocate any URB or otherwise there will be no
     747     *       data available for the HCI.
     748     */
     749    DECLR3CALLBACKMEMBER(int, pfnSetUrbParams, (PVUSBIROOTHUBCONNECTOR pInterface, size_t cbHci, size_t cbHciTd));
     750
     751    /**
     752     * Resets the roothub.
     753     *
     754     * @returns VBox status code.
     755     * @param   pInterface      Pointer to this struct.
     756     * @param   fResetOnLinux   Whether or not to do real reset on linux.
     757     */
     758    DECLR3CALLBACKMEMBER(int, pfnReset, (PVUSBIROOTHUBCONNECTOR pInterface, bool fResetOnLinux));
     759
     760    /**
     761     * Powers on the roothub.
     762     *
     763     * @returns VBox status code.
     764     * @param   pInterface  Pointer to this struct.
     765     */
     766    DECLR3CALLBACKMEMBER(int, pfnPowerOn, (PVUSBIROOTHUBCONNECTOR pInterface));
     767
     768    /**
     769     * Power off the roothub.
     770     *
     771     * @returns VBox status code.
     772     * @param   pInterface  Pointer to this struct.
     773     */
     774    DECLR3CALLBACKMEMBER(int, pfnPowerOff, (PVUSBIROOTHUBCONNECTOR pInterface));
     775
     776    /**
     777     * Allocates a new URB for a transfer.
     778     *
     779     * Either submit using pfnSubmitUrb or free using VUSBUrbFree().
     780     *
     781     * @returns Pointer to a new URB.
     782     * @returns NULL on failure - try again later.
     783     *          This will not fail if the device wasn't found. We'll fail it
     784     *          at submit time, since that makes the usage of this api simpler.
     785     * @param   pInterface  Pointer to this struct.
     786     * @param   DstAddress  The destination address of the URB.
     787     * @param   uPort       Optional port of the device the URB is for, use VUSB_DEVICE_PORT_INVALID to indicate to use the destination address.
     788     * @param   enmType     Type of the URB.
     789     * @param   enmDir      Data transfer direction.
     790     * @param   cbData      The amount of data space required.
     791     * @param   cTds        The amount of TD space.
     792     * @param   pszTag      Custom URB tag assigned by the caller, only for
     793     *                      logged builds and optional.
     794     *
     795     * @note pDev should be NULL in most cases. The only useful case is for USB3 where
     796     *       it is required for the SET_ADDRESS request because USB3 uses unicast traffic.
     797     */
     798    DECLR3CALLBACKMEMBER(PVUSBURB, pfnNewUrb,(PVUSBIROOTHUBCONNECTOR pInterface, uint8_t DstAddress, uint32_t uPort,
     799                                              VUSBXFERTYPE enmType, VUSBDIRECTION enmDir, uint32_t cbData, uint32_t cTds, const char *pszTag));
     800
     801    /**
     802     * Free an URB not submitted yet.
     803     *
     804     * @returns VBox status code.
     805     * @param   pInterface  Pointer to this struct.
     806     * @param   pUrb        Pointer to the URB to free returned by VUSBIROOTHUBCONNECTOR::pfnNewUrb.
     807     */
     808    DECLR3CALLBACKMEMBER(int, pfnFreeUrb, (PVUSBIROOTHUBCONNECTOR pInterface, PVUSBURB pUrb));
     809
     810    /**
     811     * Submits a URB for transfer.
     812     * The transfer will do asynchronously if possible.
     813     *
     814     * @returns VBox status code.
     815     * @param   pInterface  Pointer to this struct.
     816     * @param   pUrb        Pointer to the URB returned by pfnNewUrb.
     817     *                      The URB will be freed in case of failure.
     818     * @param   pLed        Pointer to USB Status LED
     819     */
     820    DECLR3CALLBACKMEMBER(int, pfnSubmitUrb,(PVUSBIROOTHUBCONNECTOR pInterface, PVUSBURB pUrb, struct PDMLED *pLed));
     821
     822    /**
     823     * Call to service asynchronous URB completions in a polling fashion.
     824     *
     825     * Reaped URBs will be finished by calling the completion callback,
     826     * thus there is no return code or input or anything from this function
     827     * except for potential state changes elsewhere.
     828     *
     829     * @returns VINF_SUCCESS if no URBs are pending upon return.
     830     * @returns VERR_TIMEOUT if one or more URBs are still in flight upon returning.
     831     * @returns Other VBox status code.
     832     *
     833     * @param   pInterface  Pointer to this struct.
     834     * @param   uPort       Port of the device to reap URBs on.
     835     * @param   cMillies    Number of milliseconds to poll for completion.
     836     */
     837    DECLR3CALLBACKMEMBER(void, pfnReapAsyncUrbs,(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort, RTMSINTERVAL cMillies));
     838
     839    /**
     840     * Cancels and completes - with CRC failure - all URBs queued on an endpoint.
     841     * This is done in response to guest URB cancellation.
     842     *
     843     * @returns VBox status code.
     844     * @param   pInterface  Pointer to this struct.
     845     * @param   pUrb        Pointer to a previously submitted URB.
     846     */
     847    DECLR3CALLBACKMEMBER(int, pfnCancelUrbsEp,(PVUSBIROOTHUBCONNECTOR pInterface, PVUSBURB pUrb));
     848
     849    /**
     850     * Cancels and completes - with CRC failure - all in-flight async URBs.
     851     * This is typically done before saving a state.
     852     *
     853     * @param   pInterface  Pointer to this struct.
     854     */
     855    DECLR3CALLBACKMEMBER(void, pfnCancelAllUrbs,(PVUSBIROOTHUBCONNECTOR pInterface));
     856
     857    /**
     858     * Cancels and completes - with CRC failure - all URBs queued on an endpoint.
     859     * This is done in response to a guest endpoint/pipe abort.
     860     *
     861     * @returns VBox status code.
     862     * @param   pInterface  Pointer to this struct.
     863     * @param   uPort       Port of the device.
     864     * @param   EndPt       Endpoint number.
     865     * @param   enmDir      Endpoint direction.
     866     */
     867    DECLR3CALLBACKMEMBER(int, pfnAbortEp,(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort, int EndPt, VUSBDIRECTION enmDir));
     868
     869    /**
     870     * Attach the device to the root hub.
     871     * The device must not be attached to any hub for this call to succeed.
     872     *
     873     * @returns VBox status code.
     874     * @param   pInterface  Pointer to this struct.
     875     * @param   uPort       Port of the device to attach.
     876     */
     877    DECLR3CALLBACKMEMBER(int, pfnAttachDevice,(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort));
     878
     879    /**
     880     * Detach the device from the root hub.
     881     * The device must already be attached for this call to succeed.
     882     *
     883     * @returns VBox status code.
     884     * @param   pInterface  Pointer to this struct.
     885     * @param   uPort       Port of the device to detach.
     886     */
     887    DECLR3CALLBACKMEMBER(int, pfnDetachDevice,(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort));
     888
     889    /**
     890     * Sets periodic frame processing.
     891     *
     892     * @returns VBox status code.
     893     * @param   pInterface  Pointer to this struct.
     894     * @param   uFrameRate  The target frame rate in Hertz, 0 disables periodic frame processing.
     895     *                      The real frame rate might be lower if there is no activity for a certain period or
     896     *                      higher if there is a need for catching up with where the guest expects the device to be.
     897     */
     898    DECLR3CALLBACKMEMBER(int, pfnSetPeriodicFrameProcessing, (PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uFrameRate));
     899
     900    /**
     901     * Returns the current frame rate for the periodic frame processing.
     902     *
     903     * @returns Frame rate for periodic frame processing.
     904     * @retval  0 if disabled.
     905     * @param   pInterface  Pointer to this struct.
     906     */
     907    DECLR3CALLBACKMEMBER(uint32_t, pfnGetPeriodicFrameRate, (PVUSBIROOTHUBCONNECTOR pInterface));
     908
     909    /**
     910     * Updates the internally stored isochronous scheduling frame for a given
     911     * endpoint and returns the delta between the current and previous frame.
     912     *
     913     * @returns Delta between currently and previously scheduled frame.
     914     * @retval  0 if no previous frame was set.
     915     * @param   pInterface  Pointer to this struct.
     916     * @param   uPort       Port of the device.
     917     * @param   EndPt       Endpoint number.
     918     * @param   enmDir      Endpoint direction.
     919     * @param   uNewFrameID The frame ID of a new transfer.
     920     * @param   uBits       The number of significant bits in frame ID.
     921     */
     922    DECLR3CALLBACKMEMBER(uint32_t, pfnUpdateIsocFrameDelta, (PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort,
     923                                                             int EndPt, VUSBDIRECTION enmDir, uint16_t uNewFrameID, uint8_t uBits));
     924
     925    /**
     926     * Resets the device.
     927     *
     928     * Since a device reset shall take at least 10ms from the guest point of view,
     929     * it must be performed asynchronously. We create a thread which performs this
     930     * operation and ensures it will take at least 10ms.
     931     *
     932     * At times - like init - a synchronous reset is required, this can be done
     933     * by passing NULL for pfnDone.
     934     *
     935     * -- internal stuff, move it --
     936     * While the device is being reset it is in the VUSB_DEVICE_STATE_RESET state.
     937     * On completion it will be in the VUSB_DEVICE_STATE_DEFAULT state if successful,
     938     * or in the VUSB_DEVICE_STATE_DETACHED state if the rest failed.
     939     * -- internal stuff, move it --
     940     *
     941     * @returns VBox status code.
     942     * @param   pInterface      Pointer to this struct.
     943     * @param   uPort           Port of the device to reset.
     944     * @param   fResetOnLinux   Set if we can permit a real reset and a potential logical
     945     *                          device reconnect on linux hosts.
     946     * @param   pfnDone         Pointer to the completion routine. If NULL a synchronous
     947     *                          reset  is performed not respecting the 10ms.
     948     * @param   pvUser          User argument to the completion routine.
     949     * @param   pVM             The cross context VM structure.  Required if pfnDone
     950     *                          is not NULL.
     951     */
     952    DECLR3CALLBACKMEMBER(int, pfnDevReset,(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort, bool fResetOnLinux,
     953                                           PFNVUSBRESETDONE pfnDone, void *pvUser, PVM pVM));
     954
     955    /**
     956     * Powers on the device.
     957     *
     958     * @returns VBox status code.
     959     * @param   pInterface      Pointer to this struct.
     960     * @param   uPort           Port of the device to power on.
     961     */
     962    DECLR3CALLBACKMEMBER(int, pfnDevPowerOn,(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort));
     963
     964    /**
     965     * Powers off the device.
     966     *
     967     * @returns VBox status code.
     968     * @param   pInterface      Pointer to this struct.
     969     * @param   uPort           Port of the device to power off.
     970     */
     971    DECLR3CALLBACKMEMBER(int, pfnDevPowerOff,(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort));
     972
     973    /**
     974     * Get the state of the device.
     975     *
     976     * @returns Device state.
     977     * @param   pInterface      Pointer to this struct.
     978     * @param   uPort           Port of the device to get the state for.
     979     */
     980    DECLR3CALLBACKMEMBER(VUSBDEVICESTATE, pfnDevGetState,(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort));
     981
     982    /**
     983     * Returns whether the device implements the saved state handlers
     984     * and doesn't need to get detached.
     985     *
     986     * @returns true if the device supports saving the state, false otherwise.
     987     * @param   pInterface      Pointer to this struct.
     988     * @param   uPort           Port of the device to query saved state support for.
     989     */
     990    DECLR3CALLBACKMEMBER(bool, pfnDevIsSavedStateSupported,(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort));
     991
     992    /**
     993     * Get the speed the device is operating at.
     994     *
     995     * @returns Device state.
     996     * @param   pInterface      Pointer to this struct.
     997     * @param   uPort           Port of the device to query the speed for.
     998     */
     999    DECLR3CALLBACKMEMBER(VUSBSPEED, pfnDevGetSpeed,(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort));
     1000
     1001} VUSBIROOTHUBCONNECTOR;
     1002AssertCompileSizeAlignment(VUSBIROOTHUBCONNECTOR, 8);
     1003/** VUSBIROOTHUBCONNECTOR interface ID. */
     1004# define VUSBIROOTHUBCONNECTOR_IID              "662d7822-b9c6-43b5-88b6-5d59f0106e46"
     1005
     1006
     1007# ifdef IN_RING3
     1008/** @copydoc VUSBIROOTHUBCONNECTOR::pfnSetUrbParams */
     1009DECLINLINE(int) VUSBIRhSetUrbParams(PVUSBIROOTHUBCONNECTOR pInterface, size_t cbHci, size_t cbHciTd)
     1010{
     1011    return pInterface->pfnSetUrbParams(pInterface, cbHci, cbHciTd);
     1012}
     1013
     1014/** @copydoc VUSBIROOTHUBCONNECTOR::pfnNewUrb */
     1015DECLINLINE(PVUSBURB) VUSBIRhNewUrb(PVUSBIROOTHUBCONNECTOR pInterface, uint8_t DstAddress, uint32_t uPort,
     1016                                   VUSBXFERTYPE enmType, VUSBDIRECTION enmDir, uint32_t cbData, uint32_t cTds, const char *pszTag)
     1017{
     1018    return pInterface->pfnNewUrb(pInterface, DstAddress, uPort, enmType, enmDir, cbData, cTds, pszTag);
     1019}
     1020
     1021/** @copydoc VUSBIROOTHUBCONNECTOR::pfnFreeUrb */
     1022DECLINLINE(int) VUSBIRhFreeUrb(PVUSBIROOTHUBCONNECTOR pInterface, PVUSBURB pUrb)
     1023{
     1024    return pInterface->pfnFreeUrb(pInterface, pUrb);
     1025}
     1026
     1027/** @copydoc VUSBIROOTHUBCONNECTOR::pfnSubmitUrb */
     1028DECLINLINE(int) VUSBIRhSubmitUrb(PVUSBIROOTHUBCONNECTOR pInterface, PVUSBURB pUrb, struct PDMLED *pLed)
     1029{
     1030    return pInterface->pfnSubmitUrb(pInterface, pUrb, pLed);
     1031}
     1032
     1033/** @copydoc VUSBIROOTHUBCONNECTOR::pfnReapAsyncUrbs */
     1034DECLINLINE(void) VUSBIRhReapAsyncUrbs(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort, RTMSINTERVAL cMillies)
     1035{
     1036    pInterface->pfnReapAsyncUrbs(pInterface, uPort, cMillies);
     1037}
     1038
     1039/** @copydoc VUSBIROOTHUBCONNECTOR::pfnCancelAllUrbs */
     1040DECLINLINE(void) VUSBIRhCancelAllUrbs(PVUSBIROOTHUBCONNECTOR pInterface)
     1041{
     1042    pInterface->pfnCancelAllUrbs(pInterface);
     1043}
     1044
     1045/** @copydoc VUSBIROOTHUBCONNECTOR::pfnAttachDevice */
     1046DECLINLINE(int) VUSBIRhAttachDevice(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort)
     1047{
     1048    return pInterface->pfnAttachDevice(pInterface, uPort);
     1049}
     1050
     1051/** @copydoc VUSBIROOTHUBCONNECTOR::pfnDetachDevice */
     1052DECLINLINE(int) VUSBIRhDetachDevice(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort)
     1053{
     1054    return pInterface->pfnDetachDevice(pInterface, uPort);
     1055}
     1056
     1057/** @copydoc VUSBIROOTHUBCONNECTOR::pfnSetPeriodicFrameProcessing */
     1058DECLINLINE(int) VUSBIRhSetPeriodicFrameProcessing(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uFrameRate)
     1059{
     1060    return pInterface->pfnSetPeriodicFrameProcessing(pInterface, uFrameRate);
     1061}
     1062
     1063/** @copydoc VUSBIROOTHUBCONNECTOR::pfnGetPeriodicFrameRate */
     1064DECLINLINE(uint32_t) VUSBIRhGetPeriodicFrameRate(PVUSBIROOTHUBCONNECTOR pInterface)
     1065{
     1066    return pInterface->pfnGetPeriodicFrameRate(pInterface);
     1067}
     1068
     1069/** @copydoc VUSBIROOTHUBCONNECTOR::pfnDevReset */
     1070DECLINLINE(int) VUSBIRhDevReset(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort, bool fResetOnLinux,
     1071                                PFNVUSBRESETDONE pfnDone, void *pvUser, PVM pVM)
     1072{
     1073    return pInterface->pfnDevReset(pInterface, uPort, fResetOnLinux, pfnDone, pvUser, pVM);
     1074}
     1075
     1076/** @copydoc VUSBIROOTHUBCONNECTOR::pfnDevPowerOn */
     1077DECLINLINE(int) VUSBIRhDevPowerOn(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort)
     1078{
     1079    return pInterface->pfnDevPowerOn(pInterface, uPort);
     1080}
     1081
     1082/** @copydoc VUSBIROOTHUBCONNECTOR::pfnDevPowerOff */
     1083DECLINLINE(int) VUSBIRhDevPowerOff(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort)
     1084{
     1085    return pInterface->pfnDevPowerOff(pInterface, uPort);
     1086}
     1087
     1088/** @copydoc VUSBIROOTHUBCONNECTOR::pfnDevGetState */
     1089DECLINLINE(VUSBDEVICESTATE) VUSBIRhDevGetState(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort)
     1090{
     1091    return pInterface->pfnDevGetState(pInterface, uPort);
     1092}
     1093
     1094/** @copydoc VUSBIROOTHUBCONNECTOR::pfnDevGetState */
     1095DECLINLINE(bool) VUSBIRhDevIsSavedStateSupported(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort)
     1096{
     1097    return pInterface->pfnDevIsSavedStateSupported(pInterface, uPort);
     1098}
     1099
     1100/** @copydoc VUSBIROOTHUBCONNECTOR::pfnDevGetSpeed */
     1101DECLINLINE(VUSBSPEED) VUSBIRhDevGetSpeed(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort)
     1102{
     1103    return pInterface->pfnDevGetSpeed(pInterface, uPort);
     1104}
     1105# endif /* IN_RING3 */
     1106
     1107#endif /* ! RDESKTOP */
     1108
    9671109
    9681110#ifndef RDESKTOP
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette