Changeset 4254 in vbox
- Timestamp:
- Aug 21, 2007 4:34:55 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Serial/DrvHostSerial.cpp
r4241 r4254 1 /** $Id: $ */ 1 2 /** @file 2 * 3 * VBox stream I/O devices: 4 * Host serial driver 3 * VBox stream I/O devices: Host serial driver 5 4 * 6 5 * Contributed by: Alexander Eichner … … 133 132 { 134 133 PDRVHOSTSERIAL pData = PDMICHAR_2_DRVHOSTSERIAL(pInterface); 135 const char *pBuffer = (const char*)pvBuf;134 const uint8_t *pbBuffer = (const uint8_t *)pvBuf; 136 135 137 136 LogFlow(("%s: pvBuf=%#p cbWrite=%d\n", __FUNCTION__, pvBuf, cbWrite)); … … 141 140 uint32_t idx = pData->iSendQueueHead; 142 141 143 pData->aSendQueue[idx] = p Buffer[i];142 pData->aSendQueue[idx] = pbBuffer[i]; 144 143 idx = (idx + 1) & CHAR_MAX_SEND_QUEUE_MASK; 145 144 … … 162 161 163 162 LogFlow(("%s: Bps=%u chParity=%c cDataBits=%u cStopBits=%u\n", __FUNCTION__, Bps, chParity, cDataBits, cStopBits)); 164 163 165 164 #ifdef RT_OS_LINUX 166 165 termiosSetup = (struct termios *)RTMemTmpAllocZ(sizeof(struct termios)); 167 166 168 167 /* Enable receiver */ 169 168 termiosSetup->c_cflag |= (CLOCAL | CREAD); … … 346 345 break; 347 346 } 348 347 349 348 switch (cStopBits) { 350 349 case 1: … … 376 375 * Send thread loop. 377 376 * 378 * @returns 0 on success.377 * @returns VINF_SUCCESS. 379 378 * @param ThreadSelf Thread handle to this thread. 380 379 * @param pvUser User argument. … … 384 383 PDRVHOSTSERIAL pData = (PDRVHOSTSERIAL)pvUser; 385 384 386 for(;;)385 while (!pData->fShutdown) 387 386 { 388 387 int rc = RTSemEventWait(pData->SendSem, RT_INDEFINITE_WAIT); … … 393 392 * Write the character to the host device. 394 393 */ 395 if (!pData->fShutdown) 394 while ( !pData->fShutdown 395 && pData->iSendQueueTail != pData->iSendQueueHead) 396 396 { 397 while (pData->iSendQueueTail != pData->iSendQueueHead) 397 unsigned cbProcessed = 1; 398 399 rc = RTFileWrite(pData->DeviceFile, &pData->aSendQueue[pData->iSendQueueTail], cbProcessed, NULL); 400 if (VBOX_SUCCESS(rc)) 398 401 { 399 size_t cbProcessed = 1; 400 401 rc = RTFileWrite(pData->DeviceFile, &pData->aSendQueue[pData->iSendQueueTail], cbProcessed, NULL); 402 if (VBOX_SUCCESS(rc)) 403 { 404 Assert(cbProcessed); 405 pData->iSendQueueTail++; 406 pData->iSendQueueTail &= CHAR_MAX_SEND_QUEUE_MASK; 407 } 408 else if (VBOX_FAILURE(rc)) 409 { 410 LogFlow(("Write failed with %Vrc; skipping\n", rc)); 411 break; 412 } 402 Assert(cbProcessed); 403 pData->iSendQueueTail++; 404 pData->iSendQueueTail &= CHAR_MAX_SEND_QUEUE_MASK; 405 } 406 else if (VBOX_FAILURE(rc)) 407 { 408 LogFlow(("Write failed with %Vrc; skipping\n", rc)); 409 break; 413 410 } 414 411 } 415 else 416 break; 417 } 418 419 pData->SendThread = NIL_RTTHREAD; 412 } 420 413 421 414 return VINF_SUCCESS; … … 428 421 * Receive thread loop. 429 422 * 430 * @returns 0 on success. 423 * This thread pushes data from the host serial device up the driver 424 * chain toward the serial device. 425 * 426 * @returns VINF_SUCCESS. 431 427 * @param ThreadSelf Thread handle to this thread. 432 428 * @param pvUser User argument. … … 435 431 { 436 432 PDRVHOSTSERIAL pData = (PDRVHOSTSERIAL)pvUser; 437 char aBuffer[256], *pBuffer; 438 unsigned cbRemaining, cbProcessed, cbRead; 439 int rc; 440 441 cbRemaining = 0; 442 pBuffer = aBuffer; 433 uint8_t abBuffer[256]; 434 uint8_t *pbBuffer = NULL; 435 size_t cbRemaining = 0; /* start by reading host data */ 436 int rc = VINF_SUCCESS; 437 443 438 while (!pData->fShutdown) 444 439 { 445 440 if (!cbRemaining) 446 441 { 447 /* Get block of data fromserial device. */448 cbRemaining = sizeof(aBuffer);449 rc = RTFileRead(pData->DeviceFile, a Buffer, cbRemaining, &cbRead);442 /* Get a block of data from the host serial device. */ 443 unsigned cbRead; 444 rc = RTFileRead(pData->DeviceFile, abBuffer, sizeof(abBuffer), &cbRead); 450 445 if (VBOX_FAILURE(rc)) 451 446 { 452 Log Flow(("Read failed with %Vrc\n", rc));447 LogRel(("Host Serial Driver: Read failed with %Vrc, terminating the worker thread.\n", rc)); 453 448 break; 454 } else {455 cbRemaining = cbRead;456 449 } 457 pBuffer = aBuffer; 450 cbRemaining = cbRead; 451 pbBuffer = abBuffer; 458 452 } 459 453 else 460 454 { 461 /* Send data to guest. */462 cbProcessed = cbRemaining;463 rc = pData->pDrvCharPort->pfnNotifyRead(pData->pDrvCharPort, p Buffer, &cbProcessed);455 /* Send data to the guest. */ 456 size_t cbProcessed = cbRemaining; 457 rc = pData->pDrvCharPort->pfnNotifyRead(pData->pDrvCharPort, pbBuffer, &cbProcessed); 464 458 if (VBOX_SUCCESS(rc)) 465 459 { 466 Assert(cbProcessed); 467 p Buffer += cbProcessed;460 Assert(cbProcessed); Assert(cbProcessed <= cbRemaining); 461 pbBuffer += cbProcessed; 468 462 cbRemaining -= cbProcessed; 469 463 STAM_COUNTER_ADD(&pData->StatBytesRead, cbProcessed); … … 477 471 else 478 472 { 479 Log Flow(("NotifyRead failed with %Vrc\n", rc));473 LogRel(("Host Serial Driver: NotifyRead failed with %Vrc, terminating the worker thread.\n", rc)); 480 474 break; 481 475 } 482 476 } 483 477 } 484 485 pData->ReceiveThread = NIL_RTTHREAD;486 478 487 479 return VINF_SUCCESS; … … 512 504 */ 513 505 pData->ReceiveThread = NIL_RTTHREAD; 506 pData->SendThread = NIL_RTTHREAD; 514 507 pData->fShutdown = false; 515 508 /* IBase. */ … … 553 546 default: 554 547 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, 555 N_("Failed to open host device '%s'"), 548 N_("Failed to open host device '%s'"), 556 549 pData->pszDevicePath); 557 550 } … … 565 558 COMMTIMEOUTS comTimeout; 566 559 567 comTimeout.ReadIntervalTimeout = MAXDWORD; 560 comTimeout.ReadIntervalTimeout = MAXDWORD; 568 561 comTimeout.ReadTotalTimeoutMultiplier = 0; 569 562 comTimeout.ReadTotalTimeoutConstant = 0; … … 591 584 if (VBOX_FAILURE(rc)) 592 585 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("HostSerial#%d cannot create send thread"), pDrvIns->iInstance); 593 594 586 587 595 588 PDMDrvHlpSTAMRegisterF(pDrvIns, &pData->StatBytesWritten, STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_BYTES, "Nr of bytes written", "/Devices/HostSerial%d/Written", pDrvIns->iInstance); 596 589 PDMDrvHlpSTAMRegisterF(pDrvIns, &pData->StatBytesRead, STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_BYTES, "Nr of bytes read", "/Devices/HostSerial%d/Read", pDrvIns->iInstance); … … 614 607 LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance)); 615 608 616 pData->fShutdown = true;617 if (pData->ReceiveThread )609 ASMAtomicXchgBool(&pData->fShutdown, true); 610 if (pData->ReceiveThread != NIL_RTTHREAD) 618 611 { 619 RTThreadWait(pData->ReceiveThread, 1000, NULL); 620 if (pData->ReceiveThread != NIL_RTTHREAD) 621 LogRel(("HostSerial%d: receive thread did not terminate\n", pDrvIns->iInstance)); 612 int rc = RTThreadWait(pData->ReceiveThread, 15000, NULL); 613 if (RT_FAILURE(rc)) 614 LogRel(("HostSerial%d: receive thread did not terminate (rc=%Rrc)\n", pDrvIns->iInstance, rc)); 615 pData->ReceiveThread = NIL_RTTHREAD; 622 616 } 623 617 … … 629 623 pData->SendSem = NIL_RTSEMEVENT; 630 624 631 if (pData->SendThread )625 if (pData->SendThread != NIL_RTTHREAD) 632 626 { 633 RTThreadWait(pData->SendThread, 1000, NULL); 634 if (pData->SendThread != NIL_RTTHREAD) 635 LogRel(("HostSerial%d: send thread did not terminate\n", pDrvIns->iInstance)); 627 int rc = RTThreadWait(pData->SendThread, 15000, NULL); 628 if (RT_FAILURE(rc)) 629 LogRel(("HostSerial%d: send thread did not terminate (rc=%Rrc)\n", pDrvIns->iInstance, rc)); 630 pData->SendThread = NIL_RTTHREAD; 636 631 } 637 632 }
Note:
See TracChangeset
for help on using the changeset viewer.