VirtualBox

Changeset 90993 in vbox


Ignore:
Timestamp:
Aug 30, 2021 10:39:02 AM (3 years ago)
Author:
vboxsync
Message:

UsbMouse: Reworked URB processing to make it simpler and more uniform. Now lines up with UsbKbd.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Input/UsbMouse.cpp

    r82968 r90993  
    300300    uint16_t    y;
    301301} USBHIDMT_REPORT_POINTER;
     302
     303typedef union USBHIDALL_REPORT
     304{
     305    USBHIDM_REPORT          m;
     306    USBHIDT_REPORT          t;
     307    USBHIDMT_REPORT         mt;
     308    USBHIDMT_REPORT_POINTER mp;
     309} USBHIDALL_REPORT, *PUSBHIDALL_REPORT;
     310
    302311#pragma pack()
    303312
     
    11351144
    11361145/**
    1137  * Completes the URB with a OK state.
    1138  */
    1139 static int usbHidCompleteOk(PUSBHID pThis, PVUSBURB pUrb, size_t cbData)
    1140 {
    1141     LogRelFlow(("usbHidCompleteOk/#%u: pUrb=%p:%s cbData=%#zx\n",
    1142                 pThis->pUsbIns->iInstance, pUrb, pUrb->pszDesc, cbData));
     1146 * Completes the URB after device successfully processed it. Optionally copies data
     1147 * into the URB. May still generate an error if the URB is not big enough.
     1148 */
     1149static int usbHidCompleteOk(PUSBHID pThis, PVUSBURB pUrb, const void *pSrc, size_t cbSrc)
     1150{
     1151    Log(("usbHidCompleteOk/#%u: pUrb=%p:%s (cbData=%#x) cbSrc=%#zx\n", pThis->pUsbIns->iInstance, pUrb, pUrb->pszDesc, pUrb->cbData, cbSrc));
    11431152
    11441153    pUrb->enmStatus = VUSBSTATUS_OK;
    1145     pUrb->cbData    = (uint32_t)cbData;
     1154    size_t  cbCopy  = 0;
     1155    size_t  cbSetup = 0;
     1156
     1157    if (pSrc)   /* Can be NULL if not copying anything. */
     1158    {
     1159        Assert(cbSrc);
     1160        uint8_t *pDst = pUrb->abData;
     1161
     1162        /* Returned data is written after the setup message in control URBs. */
     1163        if (pUrb->enmType == VUSBXFERTYPE_MSG)
     1164            cbSetup = sizeof(VUSBSETUP);
     1165
     1166        Assert(pUrb->cbData >= cbSetup);    /* Only triggers if URB is corrupted. */
     1167
     1168        if (pUrb->cbData > cbSetup)
     1169        {
     1170            /* There is at least one byte of room in the URB. */
     1171            cbCopy = RT_MIN(pUrb->cbData - cbSetup, cbSrc);
     1172            memcpy(pDst + cbSetup, pSrc, cbCopy);
     1173            pUrb->cbData = (uint32_t)(cbCopy + cbSetup);
     1174            Log(("Copied %zu bytes to pUrb->abData[%zu], source had %zu bytes\n", cbCopy, cbSetup, cbSrc));
     1175        }
     1176
     1177        /* Need to check length differences. If cbSrc is less than what
     1178         * the URB has space for, it'll be resolved as a short packet. But
     1179         * if cbSrc is bigger, there is a real problem and the host needs
     1180         * to see an overrun/babble error.
     1181         */
     1182        if (RT_UNLIKELY(cbSrc > cbCopy))
     1183            pUrb->enmStatus = VUSBSTATUS_DATA_OVERRUN;
     1184    }
     1185    else
     1186        Assert(cbSrc == 0); /* Make up your mind, caller! */
    11461187
    11471188    usbHidLinkDone(pThis, pUrb);
     
    11931234
    11941235    if (pUrb)
    1195         return usbHidCompleteOk(pThis, pUrb, 0);
     1236        return usbHidCompleteOk(pThis, pUrb, NULL, 0);
    11961237    return VINF_SUCCESS;
    11971238}
     
    13411382
    13421383    /* Report current state. */
    1343     USBHIDMT_REPORT *p = (USBHIDMT_REPORT *)&pUrb->abData[0];
     1384    USBHIDMT_REPORT r;
     1385    USBHIDMT_REPORT *p = &r;
    13441386    RT_ZERO(*p);
    13451387
     
    13991441
    14001442    LogRel3(("usbHid: reporting touch contact:\n%.*Rhxd\n", sizeof(USBHIDMT_REPORT), p));
    1401     return usbHidCompleteOk(pThis, pUrb, sizeof(USBHIDMT_REPORT));
     1443    return usbHidCompleteOk(pThis, pUrb, p, sizeof(USBHIDMT_REPORT));
    14021444}
    14031445
     
    14191461    if (pUrb)
    14201462    {
    1421         PUSBHIDTM_REPORT    pReport = (PUSBHIDTM_REPORT)&pUrb->abData[0];
     1463        USBHIDTM_REPORT     report;
     1464        PUSBHIDTM_REPORT    pReport = &report;
    14221465        size_t              cbCopy;
    14231466
    14241467        cbCopy = usbHidFillReport(pReport, &pThis->PtrDelta, pThis->enmMode);
    14251468        pThis->fHasPendingChanges = false;
    1426         return usbHidCompleteOk(pThis, pUrb, cbCopy);
     1469        return usbHidCompleteOk(pThis, pUrb, pReport, cbCopy);
    14271470    }
    14281471    else
     
    17641807            AssertFailed();
    17651808            LogRelFlow(("usbHidHandleIntrDevToHost: Entering STATUS\n"));
    1766             return usbHidCompleteOk(pThis, pUrb, 0);
     1809            return usbHidCompleteOk(pThis, pUrb, NULL, 0);
    17671810        }
    17681811
     
    17751818            LogRelFlow(("usbHidHandleIntrDevToHost: Entering READY\n"));
    17761819            pThis->enmState = USBHIDREQSTATE_READY;
    1777             return usbHidCompleteOk(pThis, pUrb, 0);
     1820            return usbHidCompleteOk(pThis, pUrb, NULL, 0);
    17781821        }
    17791822
     
    18041847#define SET_PROTOCOL 0x0B
    18051848
    1806 static uint8_t const g_abQASampleBlob[256] =
    1807 {
     1849static uint8_t const g_abQASampleBlob[256 + 1] =
     1850{
     1851    REPORTID_TOUCH_QABLOB,  /* Report Id. */
    18081852    0xfc, 0x28, 0xfe, 0x84, 0x40, 0xcb, 0x9a, 0x87,
    18091853    0x0d, 0xbe, 0x57, 0x3c, 0xb6, 0x70, 0x09, 0x88,
     
    18671911            if (pSetup->bRequest == GET_REPORT)
    18681912            {
    1869                 uint32_t cbData = 0; /* 0 means that the report is unsupported. */
     1913                uint8_t     abData[sizeof(USBHIDALL_REPORT)];
     1914                uint8_t     *pData = (uint8_t *)&abData;
     1915                uint32_t    cbData = 0; /* 0 means that the report is unsupported. */
    18701916
    18711917                if (u8ReportType == 1 && u8ReportID == REPORTID_TOUCH_POINTER)
    18721918                {
    1873                     USBHIDMT_REPORT_POINTER *p = (USBHIDMT_REPORT_POINTER *)&pUrb->abData[sizeof(VUSBSETUP)];
     1919                    USBHIDMT_REPORT_POINTER *p = (USBHIDMT_REPORT_POINTER *)&abData;
    18741920                    /* The actual state should be reported here. */
    18751921                    p->idReport = REPORTID_TOUCH_POINTER;
     
    18811927                else if (u8ReportType == 1 && u8ReportID == REPORTID_TOUCH_EVENT)
    18821928                {
    1883                     USBHIDMT_REPORT *p = (USBHIDMT_REPORT *)&pUrb->abData[sizeof(VUSBSETUP)];
     1929                    USBHIDMT_REPORT *p = (USBHIDMT_REPORT *)&abData;
    18841930                    /* The actual state should be reported here. */
    18851931                    RT_ZERO(*p);
     
    18891935                else if (u8ReportType == 3 && u8ReportID == REPORTID_TOUCH_MAX_COUNT)
    18901936                {
    1891                     pUrb->abData[sizeof(VUSBSETUP) + 0] = REPORTID_TOUCH_MAX_COUNT;
    1892                     pUrb->abData[sizeof(VUSBSETUP) + 1] = MT_CONTACT_MAX_COUNT; /* Contact count maximum. */
    1893                     pUrb->abData[sizeof(VUSBSETUP) + 2] = 0;  /* Device identifier */
     1937                    abData[0] = REPORTID_TOUCH_MAX_COUNT;
     1938                    abData[1] = MT_CONTACT_MAX_COUNT;  /* Contact count maximum. */
     1939                    abData[2] = 0;                      /* Device identifier */
    18941940                    cbData = 3;
    18951941                }
    18961942                else if (u8ReportType == 3 && u8ReportID == REPORTID_TOUCH_QABLOB)
    18971943                {
    1898                     pUrb->abData[sizeof(VUSBSETUP) + 0] = REPORTID_TOUCH_QABLOB;  /* Report Id. */
    1899                     memcpy(&pUrb->abData[sizeof(VUSBSETUP) + 1],
    1900                            g_abQASampleBlob, sizeof(g_abQASampleBlob));
    1901                     cbData = sizeof(g_abQASampleBlob) + 1;
     1944                    pData  = (uint8_t *)&g_abQASampleBlob;
     1945                    cbData = sizeof(g_abQASampleBlob);
    19021946                }
    19031947                else if (u8ReportType == 3 && u8ReportID == REPORTID_TOUCH_DEVCONFIG)
    19041948                {
    1905                     pUrb->abData[sizeof(VUSBSETUP) + 0] = REPORTID_TOUCH_DEVCONFIG;
    1906                     pUrb->abData[sizeof(VUSBSETUP) + 1] = 2;  /* Device mode:
    1907                                                                * "HID touch device supporting contact
    1908                                                                * identifier and contact count maximum."
    1909                                                                */
    1910                     pUrb->abData[sizeof(VUSBSETUP) + 2] = 0;  /* Device identifier */
     1949                    abData[0] = REPORTID_TOUCH_DEVCONFIG;
     1950                    abData[1] = 2;  /* Device mode:
     1951                                     * "HID touch device supporting contact
     1952                                     * identifier and contact count maximum."
     1953                                     */
     1954                    abData[2] = 0;  /* Device identifier */
    19111955                    cbData = 3;
    19121956                }
     
    19141958                if (cbData > 0)
    19151959                {
    1916                     rc = usbHidCompleteOk(pThis, pUrb, sizeof(VUSBSETUP) + cbData);
     1960                    rc = usbHidCompleteOk(pThis, pUrb, pData, cbData);
    19171961                }
    19181962                else
     
    19241968            {
    19251969                /* SET_REPORT */
    1926                 rc = usbHidCompleteOk(pThis, pUrb, pUrb->cbData);
     1970                rc = usbHidCompleteOk(pThis, pUrb, NULL, 0);
    19271971            }
    19281972        } break;
     
    20012045                                }
    20022046                                /* Returned data is written after the setup message. */
    2003                                 cbCopy = pUrb->cbData - sizeof(*pSetup);
    2004                                 cbCopy = RT_MIN(cbCopy, cbDesc);
     2047                                cbCopy = RT_MIN(pSetup->wValue, cbDesc);
    20052048                                LogRelFlow(("usbHidMouse: GET_DESCRIPTOR DT_IF_HID_DESCRIPTOR wValue=%#x wIndex=%#x cbCopy=%#x\n",
    20062049                                            pSetup->wValue, pSetup->wIndex,
    20072050                                            cbCopy));
    2008                                 memcpy(&pUrb->abData[sizeof(*pSetup)], pDesc, cbCopy);
    2009                                 return usbHidCompleteOk(pThis, pUrb, cbCopy + sizeof(*pSetup));
     2051                                return usbHidCompleteOk(pThis, pUrb, pDesc, cbCopy);
    20102052                            }
    20112053
     
    20322074                                }
    20332075                                /* Returned data is written after the setup message. */
    2034                                 cbCopy = pUrb->cbData - sizeof(*pSetup);
    2035                                 cbCopy = RT_MIN(cbCopy, cbDesc);
     2076                                cbCopy = RT_MIN(pSetup->wLength, cbDesc);
    20362077                                LogRelFlow(("usbHid: GET_DESCRIPTOR DT_IF_HID_REPORT wValue=%#x wIndex=%#x cbCopy=%#x\n",
    20372078                                            pSetup->wValue, pSetup->wIndex,
    20382079                                            cbCopy));
    2039                                 memcpy(&pUrb->abData[sizeof(*pSetup)], pDesc, cbCopy);
    2040                                 return usbHidCompleteOk(pThis, pUrb, cbCopy + sizeof(*pSetup));
     2080                                return usbHidCompleteOk(pThis, pUrb, pDesc, cbCopy);
    20412081                            }
    20422082
     
    20752115                        LogRelFlow(("usbHid: GET_STATUS (device)\n"));
    20762116                        wRet = 0;   /* Not self-powered, no remote wakeup. */
    2077                         memcpy(&pUrb->abData[sizeof(*pSetup)], &wRet, sizeof(wRet));
    2078                         return usbHidCompleteOk(pThis, pUrb, sizeof(wRet) + sizeof(*pSetup));
     2117                        return usbHidCompleteOk(pThis, pUrb, &wRet, sizeof(wRet));
    20792118                    }
    20802119
     
    20832122                        if (pSetup->wIndex == 0)
    20842123                        {
    2085                             memcpy(&pUrb->abData[sizeof(*pSetup)], &wRet, sizeof(wRet));
    2086                             return usbHidCompleteOk(pThis, pUrb, sizeof(wRet) + sizeof(*pSetup));
     2124                            return usbHidCompleteOk(pThis, pUrb, &wRet, sizeof(wRet));
    20872125                        }
    20882126                        LogRelFlow(("usbHid: GET_STATUS (interface) invalid, wIndex=%#x\n", pSetup->wIndex));
     
    20952133                        {
    20962134                            wRet = pThis->aEps[pSetup->wIndex].fHalted ? 1 : 0;
    2097                             memcpy(&pUrb->abData[sizeof(*pSetup)], &wRet, sizeof(wRet));
    2098                             return usbHidCompleteOk(pThis, pUrb, sizeof(wRet) + sizeof(*pSetup));
     2135                            return usbHidCompleteOk(pThis, pUrb, &wRet, sizeof(wRet));
    20992136                        }
    21002137                        LogRelFlow(("usbHid: GET_STATUS (endpoint) invalid, wIndex=%#x\n", pSetup->wIndex));
Note: See TracChangeset for help on using the changeset viewer.

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