Changeset 27890 in vbox for trunk/src/VBox/Devices/Input
- Timestamp:
- Mar 31, 2010 12:57:26 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Input/UsbKbd.cpp
r27838 r27890 128 128 PPDMUSBINS pUsbIns; 129 129 /** Critical section protecting the device state. */ 130 RTCRITSECT CritSect;130 RTCRITSECT csLock; 131 131 132 132 /** The current configuration. … … 162 162 /** If no URB since last key press */ 163 163 bool fNoUrbSinceLastPress; 164 /* If device has pending changes */ 165 bool fHasPendingChanges; 164 166 /* Keys released since last URB */ 165 167 uint8_t aReleasedKeys[6]; … … 356 358 0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19, 357 359 0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55, 358 0xe2, 0x2c, 0x3 2, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,360 0xe2, 0x2c, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 359 361 0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f, 360 362 0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59, … … 438 440 *******************************************************************************/ 439 441 442 /* Everything happens in R3 */ 443 /** 444 * Lock device state mutex. 445 */ 446 DECLINLINE(int) usbKbdLock(PUSBHID pThis) 447 { 448 return RTCritSectEnter(&pThis->csLock); 449 } 450 451 /** 452 * Unlock device state mutex. 453 */ 454 DECLINLINE(void) usbKbdUnlock(PUSBHID pThis) 455 { 456 RTCritSectLeave(&pThis->csLock); 457 } 458 440 459 /** 441 460 * Initializes an URB queue. … … 448 467 pQueue->ppTail = &pQueue->pHead; 449 468 } 450 451 452 469 453 470 /** … … 608 625 memset(&pThis->Report, 0, sizeof(pThis->Report)); 609 626 pThis->fNoUrbSinceLastPress = false; 610 memset(&pThis->aReleasedKeys, 0, sizeof(pThis->aReleasedKeys)); 627 pThis->fHasPendingChanges = false; 628 memset(&pThis->aReleasedKeys[0], 0, sizeof(pThis->aReleasedKeys)); 611 629 612 630 for (unsigned i = 0; i < RT_ELEMENTS(pThis->aEps); i++) … … 634 652 { 635 653 unsigned i; 636 654 637 655 for (i = 0; i < RT_ELEMENTS(pThis->Report.aKeys); ++i) 638 656 { 639 657 if (pThis->Report.aKeys[i] == u8HidCode) 640 658 { 659 /* Remove key down. */ 641 660 pThis->Report.aKeys[i] = 0; 642 break; /* Remove key down. */643 661 } 644 662 } 645 663 664 #if 0 646 665 if (i == RT_ELEMENTS(pThis->Report.aKeys)) 647 666 { 648 // AssertMsgFailed(("Key is up but was never down!?")); 649 } 650 } 667 Log(("Key 0x%x is up but was never down!?", u8HidCode)); 668 } 669 #endif 670 } 671 672 static void usbHidCommitReportReleased(PUSBHID pThis) 673 { 674 unsigned i; 675 for (i=0; i < RT_ELEMENTS(pThis->aReleasedKeys); ++i) 676 { 677 if (pThis->aReleasedKeys[i] != 0) 678 { 679 usbHidUpdateReportReleased(pThis, pThis->aReleasedKeys[i]); 680 pThis->aReleasedKeys[i] = 0; 681 } 682 } 683 } 684 685 #ifdef DEBUG 686 #define HEX_DIGIT(x) (((x) < 0xa) ? ((x) + '0') : ((x) - 0xa + 'a')) 687 static void usbHidComputePressed(PUSBHIDK_REPORT pReport, char* pszBuf, unsigned uBufLen) 688 { 689 unsigned i, uBufPos = 0; 690 for (i=0; i < RT_ELEMENTS(pReport->aKeys); ++i) 691 { 692 uint8_t uCode = pReport->aKeys[i]; 693 if (uCode != 0) 694 { 695 if (uBufPos + 4 >= uBufLen) 696 break; 697 pszBuf[uBufPos++] = HEX_DIGIT(uCode >> 4); 698 pszBuf[uBufPos++] = HEX_DIGIT(uCode & 0xf); 699 pszBuf[uBufPos++] = ' '; 700 } 701 } 702 pszBuf[uBufPos++] = '\0'; 703 } 704 #undef HEX_DIGIT 705 #endif 651 706 652 707 /** … … 662 717 unsigned i; 663 718 719 #ifdef DEBUG 720 char szActiveBuf[128]; 721 usbHidComputePressed(pReport, szActiveBuf, sizeof szActiveBuf); 722 Log2(("Sending report with pressed keys: %s\n", szActiveBuf)); 723 #endif 664 724 cbCopy = sizeof(*pReport); 665 725 memcpy(&pUrb->abData[0], pReport, cbCopy); 666 726 pThis->fNoUrbSinceLastPress = false; 667 for (i=0; i < RT_ELEMENTS(pThis->aReleasedKeys); ++i) 668 { 669 if (pThis->aReleasedKeys[i] != 0) 670 { 671 usbHidUpdateReportReleased(pThis, pThis->aReleasedKeys[i]); 672 pThis->aReleasedKeys[i] = 0; 673 } 674 } 727 pThis->fHasPendingChanges = false; 728 usbHidCommitReportReleased(pThis); 729 #ifdef DEBUG 730 usbHidComputePressed(pReport, szActiveBuf, sizeof szActiveBuf); 731 Log2(("New state: %s\n", szActiveBuf)); 732 #endif 675 733 // LogRel(("Sent report: %x : %x %x, size %d\n", pReport->ShiftState, pReport->aKeys[0], pReport->aKeys[1], cbCopy)); 676 734 return usbHidCompleteOk(pThis, pUrb, cbCopy); … … 678 736 else 679 737 { 680 Log(("No available URB for USB kbd\n")); 738 Log2(("No available URB for USB kbd\n")); 739 pThis->fHasPendingChanges = true; 681 740 } 682 741 return VINF_EOF; … … 705 764 PUSBHID pThis = RT_FROM_MEMBER(pInterface, USBHID, Lun0.IPort); 706 765 PUSBHIDK_REPORT pReport = &pThis->Report; 707 uint32_t u32Usage ;766 uint32_t u32Usage = 0; 708 767 uint8_t u8HidCode; 709 768 int fKeyDown; 710 769 unsigned i; 711 770 712 // int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY); 713 // AssertReleaseRC(rc); 771 usbKbdLock(pThis); 714 772 715 773 pThis->XlatState = ScancodeToHidUsage(pThis->XlatState, u8KeyCode, &u32Usage); … … 721 779 u8HidCode = u32Usage & 0xFF; 722 780 781 Log(("key %s: 0x%x->0x%x\n", 782 fKeyDown ? "down" : "up", u8KeyCode, u8HidCode)); 783 723 784 if (fKeyDown) 724 785 { 786 bool fAlready = false; 725 787 for (i = 0; i < RT_ELEMENTS(pReport->aKeys); ++i) 726 788 { 727 789 if (pReport->aKeys[i] == u8HidCode) 728 break; /* Skip repeat events. */729 if (pReport->aKeys[i] == 0)730 790 { 731 pReport->aKeys[i] = u8HidCode; /* Report key down. */ 732 break; 791 /* Skip repeat events. */ 792 fAlready = true; 793 break; 733 794 } 734 795 } 735 796 736 pThis->fNoUrbSinceLastPress = true; 737 738 if (i == RT_ELEMENTS(pReport->aKeys)) 797 if (!fAlready) 739 798 { 740 /* We ran out of room. Report error. */ 741 Log(("no more room in usbHidKeyboardPutEvent\n")); 742 // @todo!! 799 for (i = 0; i < RT_ELEMENTS(pReport->aKeys); ++i) 800 { 801 if (pReport->aKeys[i] == 0) 802 { 803 pReport->aKeys[i] = u8HidCode; /* Report key down. */ 804 break; 805 } 806 } 807 808 pThis->fNoUrbSinceLastPress = true; 809 810 if (i == RT_ELEMENTS(pReport->aKeys)) 811 { 812 /* We ran out of room. Report error. */ 813 Log(("no more room in usbHidKeyboardPutEvent\n")); 814 // @todo!! 815 } 743 816 } 744 817 } 745 818 else 746 819 { 747 /* We have to avoid coalescing key presses and releases, so put all releases somewhere else */ 820 /* 821 * We have to avoid coalescing key presses and releases, 822 * so put all releases somewhere else if press wasn't seen 823 * by the guest. 824 */ 748 825 if (pThis->fNoUrbSinceLastPress) 749 { 826 { 750 827 for (i = 0; i < RT_ELEMENTS(pThis->aReleasedKeys); ++i) 751 828 { 829 if (pThis->aReleasedKeys[i] == u8HidCode) 830 break; 831 752 832 if (pThis->aReleasedKeys[i] == 0) 753 833 { … … 765 845 } 766 846 767 // PDMCritSectLeave(&pThis->CritSect); 847 usbKbdUnlock(pThis); 848 768 849 return VINF_SUCCESS; 769 850 } … … 775 856 { 776 857 PUSBHID pThis = PDMINS_2_DATA(pUsbIns, PUSBHID); 777 LogFlow(("usbHidUrbReap/#%u: cMillies=%u\n", pUsbIns->iInstance, cMillies));778 779 RTCritSectEnter(&pThis->CritSect);858 //LogFlow(("usbHidUrbReap/#%u: cMillies=%u\n", pUsbIns->iInstance, cMillies)); 859 860 usbKbdLock(pThis); 780 861 781 862 PVUSBURB pUrb = usbHidQueueRemoveHead(&pThis->DoneQueue); … … 784 865 /* Wait */ 785 866 pThis->fHaveDoneQueueWaiter = true; 786 RTCritSectLeave(&pThis->CritSect);867 usbKbdUnlock(pThis); 787 868 788 869 RTSemEventWait(pThis->hEvtDoneQueue, cMillies); 789 870 790 RTCritSectEnter(&pThis->CritSect);871 usbKbdLock(pThis); 791 872 pThis->fHaveDoneQueueWaiter = false; 792 873 … … 794 875 } 795 876 796 RTCritSectLeave(&pThis->CritSect);877 usbKbdUnlock(pThis); 797 878 798 879 if (pUrb) … … 809 890 PUSBHID pThis = PDMINS_2_DATA(pUsbIns, PUSBHID); 810 891 LogFlow(("usbHidUrbCancel/#%u: pUrb=%p:%s\n", pUsbIns->iInstance, pUrb, pUrb->pszDesc)); 811 RTCritSectEnter(&pThis->CritSect);892 usbKbdLock(pThis); 812 893 813 894 /* … … 817 898 usbHidLinkDone(pThis, pUrb); 818 899 819 RTCritSectLeave(&pThis->CritSect);900 usbKbdUnlock(pThis); 820 901 return VINF_SUCCESS; 821 902 } … … 864 945 usbHidQueueAddTail(&pThis->ToHostQueue, pUrb); 865 946 /* If device was not set idle, sent the current report right away. */ 866 if (pThis->bIdle != 0 )947 if (pThis->bIdle != 0 || pThis->fHasPendingChanges) 867 948 usbHidSendReport(pThis); 868 949 LogFlow(("usbHidHandleIntrDevToHost: Sent report via %p:%s\n", pUrb, pUrb->pszDesc)); … … 1063 1144 PUSBHID pThis = PDMINS_2_DATA(pUsbIns, PUSBHID); 1064 1145 LogFlow(("usbHidQueue/#%u: pUrb=%p:%s EndPt=%#x\n", pUsbIns->iInstance, pUrb, pUrb->pszDesc, pUrb->EndPt)); 1065 RTCritSectEnter(&pThis->CritSect);1146 usbKbdLock(pThis); 1066 1147 1067 1148 /* … … 1087 1168 } 1088 1169 1089 RTCritSectLeave(&pThis->CritSect);1170 usbKbdUnlock(pThis); 1090 1171 return rc; 1091 1172 } … … 1102 1183 if ((uEndpoint & ~0x80) < RT_ELEMENTS(pThis->aEps)) 1103 1184 { 1104 RTCritSectEnter(&pThis->CritSect);1185 usbKbdLock(pThis); 1105 1186 pThis->aEps[(uEndpoint & ~0x80)].fHalted = false; 1106 RTCritSectLeave(&pThis->CritSect);1187 usbKbdUnlock(pThis); 1107 1188 } 1108 1189 … … 1131 1212 LogFlow(("usbHidUsbSetConfiguration/#%u: bConfigurationValue=%u\n", pUsbIns->iInstance, bConfigurationValue)); 1132 1213 Assert(bConfigurationValue == 1); 1133 RTCritSectEnter(&pThis->CritSect);1214 usbKbdLock(pThis); 1134 1215 1135 1216 /* … … 1140 1221 pThis->bConfigurationValue = bConfigurationValue; 1141 1222 1142 RTCritSectLeave(&pThis->CritSect);1223 usbKbdUnlock(pThis); 1143 1224 return VINF_SUCCESS; 1144 1225 } … … 1163 1244 PUSBHID pThis = PDMINS_2_DATA(pUsbIns, PUSBHID); 1164 1245 LogFlow(("usbHidUsbReset/#%u:\n", pUsbIns->iInstance)); 1165 RTCritSectEnter(&pThis->CritSect);1246 usbKbdLock(pThis); 1166 1247 1167 1248 int rc = usbHidResetWorker(pThis, NULL, false /*fSetConfig*/); 1168 1249 1169 RTCritSectLeave(&pThis->CritSect);1250 usbKbdUnlock(pThis); 1170 1251 return rc; 1171 1252 } … … 1180 1261 LogFlow(("usbHidDestruct/#%u:\n", pUsbIns->iInstance)); 1181 1262 1182 if (RTCritSectIsInitialized(&pThis->CritSect)) 1183 { 1184 RTCritSectEnter(&pThis->CritSect); 1185 RTCritSectLeave(&pThis->CritSect); 1186 RTCritSectDelete(&pThis->CritSect); 1263 if (RTCritSectIsInitialized(&pThis->csLock)) 1264 { 1265 /* Let whoever runs in this critical section complete */ 1266 usbKbdLock(pThis); 1267 usbKbdUnlock(pThis); 1268 RTCritSectDelete(&pThis->csLock); 1187 1269 } 1188 1270 … … 1213 1295 usbHidQueueInit(&pThis->DoneQueue); 1214 1296 1215 int rc = RTCritSectInit(&pThis-> CritSect);1297 int rc = RTCritSectInit(&pThis->csLock); 1216 1298 AssertRCReturn(rc, rc); 1217 1299
Note:
See TracChangeset
for help on using the changeset viewer.