Ok, the problem with the buffer overrun has been fixed :) Is a dirty? solution:
// --------------------------------------------------------------
// TxDataAvailable_Impl()
// TX data ready to read from m_txqbmd segment
void IMPL(VSPSerialPort, TxDataAvailable)
{
IOReturn ret;
uint8_t* buffer;
uint64_t address;
uint32_t size;
bool needReset = false;
VSPLog(LOG_PREFIX, "----------------------------------\n");
VSPLog(LOG_PREFIX, "TxDataAvailable called.\n");
// Lock to ensure thread safety
VSPAquireLock(ivars);
// Reset first
ivars->m_txIsComplete = false;
// We working...
ivars->m_hwStatus.cts = false;
ivars->m_hwStatus.dsr = false;
// Show me indexes be fore manipulate
VSPLog(LOG_PREFIX, "TxDataAvailable: [IOSPI-TX 1] txPI: %d, txCI: %d, txqoffset: %d, txqlogsz: %d",
ivars->m_spi->txPI, ivars->m_spi->txCI, ivars->m_spi->txqoffset, ivars->m_spi->txqlogsz);
// skip if nothing to do
if (!ivars->m_spi->txPI) {
VSPLog(LOG_PREFIX, "TxDataAvailable: spi->txPI is zero, skip\n");
goto finish;
}
// Get address of new TX data position
address = ivars->m_txseg.address + ivars->m_spi->txCI;
buffer = reinterpret_cast<uint8_t*>(address);
// Calculate available data in TX buffer
size = ivars->m_spi->txPI - ivars->m_spi->txCI;
#ifdef DEBUG // !! Debug ....
VSPLog(LOG_PREFIX, "TxDataAvailable: dump buffer=0x%llx len=%u\n", (uint64_t) buffer, size);
for (uint64_t i = 0; i < size; i++) {
VSPLog(LOG_PREFIX, "TxDataAvailable: buffer[%02lld]=0x%02x %c\n", i, buffer[i], buffer[i]);
}
#endif
// Loopback TX data by async response event
if ((ret = this->enqueueResponse(buffer, size)) != kIOReturnSuccess) {
VSPLog(LOG_PREFIX, "TxDataAvailable: Unable to enqueue response. code=%d\n", ret);
goto finish;
}
// TX -> RX echo done
ivars->m_txIsComplete = true;
// We reserve 1K size from the capacity from t_txqbmd. This protects
// against a buffer overflow.
if ((ivars->m_spi->txPI + 1024) >= (ivars->m_txseg.length - 1024)) {
ivars->m_spi->txPI = 0;
ivars->m_spi->txCI = 0;
}
// Reset TX consumer index to end of received block. This increases the
// offset for the m_txqbmd buffer. Finally the DEXT crash if to protection.
// Reset values like txPI = 0 and txCI = 0 after some transmissions.
else {
ivars->m_spi->txCI = ivars->m_spi->txPI;
}
// Show me indexes be fore manipulation
VSPLog(LOG_PREFIX, "TxDataAvailable: [IOSPI-TX 2] txPI: %d, txCI: %d, txqoffset: %d, txqlogsz: %d",
ivars->m_spi->txPI, ivars->m_spi->txCI, ivars->m_spi->txqoffset, ivars->m_spi->txqlogsz);
// reset memory
memset(buffer, 0, size);
VSPLog(LOG_PREFIX, "TxDataAvailable complete.\n");
finish:
VSPUnlock(ivars);
}