?? isp1161hc.cpp
字號:
}
}
else
{
//sPTD
psPTDData = (PUSHORT)&sPTDReDump[index];
for (i = 0; i< sizeof(SPhilipsTransferDescriptor)/sizeof(USHORT); i++)
{
*(psPTDData + i) = READ_PORT_USHORT((PUSHORT)m_regBase);
STRONGARM_DELAY(10);
}
//Data
if ( pCurGTd->paCurBuffer)
{
pData = (PUSHORT)m_pobMem->PaToVa(pCurGTd->paCurBuffer);
//In odd case, we add one more byte.
for (i = 0; i< (dwBufferLen + 1)/sizeof(USHORT); i++)
{
*(pData + i) = READ_PORT_USHORT((PUSHORT)m_regBase);
STRONGARM_DELAY(10);
}
/*=====================================================================/
Read alignment (4 bytes) data out from ATL buffer
/======================================================================*/
if (index < m_TdsPutToATLIndex -1)
{
if (dwBufferLen %4)
{
DWORD dwPayLoad = 4 - dwBufferLen % 4;
for (i=0; i< (dwPayLoad)/sizeof(USHORT); i++)
{
READ_PORT_USHORT((PUSHORT)m_regBase);
STRONGARM_DELAY(10);
}
}
}
}
}
/*=====================================================================/
Analyze the PTD read out
/======================================================================*/
if ((sPTDReDump[index].bfActive == 1) && (pEndpt->endptType != gcEndptTypeInterrupt))
{
/*=====================================================================/
OK, now, we will redump the PTD again, and jump out of this routine
that means, 1) we don't set m_ATLBeingReadOut to FALSE, So, in next
frame, the service List routine will not be called to refresh
the TD array. 2). We don't put the TD to the done queue
/======================================================================*/
DEBUGMSG(ISP1161DBG, (TEXT("PHCD:: bfActive ---- 1\r\n")));
m_bsPTDReDump[index] = TRUE;
sPTDReDump[index].bCompletionCode = 0;
m_bReDump = TRUE;
/*===================================================
This is presumed as NAK. What we need to do is to
clear the error counter
====================================================*/
pCurGTd->bfErrorCount = 0;
continue;
}
//Old codes, For interrupt, this is an NAK. means this PTD will not be tried, if it will be retired.
if ((sPTDReDump[index].bfActive == 1) && (pEndpt->endptType == gcEndptTypeInterrupt))
{
sPTDReDump[index].bfActive = 0;
pCurGTd->bfErrorCount = 0;
continue;
}
//New codes, For interrupt, this is an NAK. means this PTD will not be tried, if it will be retired.
/*
if (pEndpt->endptType == gcEndptTypeInterrupt)
{
// sPTDReDump[index].bfActive = 0;
if (sPTDReDump[index].bActualBytes == 0)
{
//pEndpt->fPhcdToggleBit = sPTDReDump[index].bfToggle;
if (sPTDReDump[index].bfToggle)
pEndpt->fPhcdToggleBit = 0;
else
pEndpt->fPhcdToggleBit = 1;
//pEndpt->fPhcdToggleBit = sPTDReDump[index].bfToggle;
//This is presumed as NAK. What we need to do is to clear the error counter
pCurGTd->bfErrorCount = 0;
continue;
}
}
*/
/*=====================================================================/
(Sepc 6.4.4.5) Status Completion part.
1) Completion code write back
2) Update CurrentBufferPoint
/======================================================================*/
/*=====================================================================/
1) Completion code write back
/======================================================================*/
/*=================================================================
Refer to USB spec page 172 packet error and 1161 spec 7.6 PTD
==================================================================*/
if( (sPTDReDump[index].bCompletionCode == 0x1) ||
(sPTDReDump[index].bCompletionCode == 0x3) ||
(sPTDReDump[index].bCompletionCode == 0x4) ||
(sPTDReDump[index].bCompletionCode == 0x5) ||
(sPTDReDump[index].bCompletionCode == 0x6) ||
(sPTDReDump[index].bCompletionCode == 0x7))
{
RETAILMSG(0, (TEXT("PHCD:: PTD CC error: %d, EpNum %d, count: %d\r\n"),
sPTDReDump[index].bCompletionCode, pEndpt->endptArrayNum,
pCurGTd->bfErrorCount));
pCurGTd->bfErrorCount++;
/*
if ( pEndpt->endptType == gcEndptTypeInterrupt)
{
if (pCurGTd->bfErrorCount < 3)
{
continue;
}
}
else if ( pEndpt->endptType == gcEndptTypeControl)
{
if (pCurGTd->bfErrorCount < 3)
{
sPTDReDump[index].bfActive = 1;
sPTDReDump[index].bCompletionCode = 0;
m_bsPTDReDump[index] = TRUE;
m_bReDump = TRUE;
continue;
}
}
*/
continue;
}
else
{
/* ================================================
No error has happened, clear the error counter
=================================================*/
pCurGTd->bfErrorCount = 0;
}
pCurGTd->bfConditionCode = sPTDReDump[index].bCompletionCode;
// if( (sPTDReDump[index].bCompletionCode == 0x9) && (pCurGTd->bfShortPacketOk == 1))
if (sPTDReDump[index].bCompletionCode == 0x9)
{
pCurGTd->bfConditionCode = 0;
}
//Some devices may return more data than you request. don't treat them as error
if (sPTDReDump[index].bCompletionCode == 0x8)
{
pCurGTd->bfConditionCode = 0;
RETAILMSG(1, (TEXT("PHCD:: PTD completion error: %d, EpNum %d\r\n"),
sPTDReDump[index].bCompletionCode, pEndpt->endptArrayNum));
}
if (sPTDReDump[index].bCompletionCode)
RETAILMSG(1, (TEXT("PHCD:: PTD completion error: %d, EpNum %d\r\n"),
sPTDReDump[index].bCompletionCode, pEndpt->endptArrayNum));
/*=====================================================================/
2) Update CurrentBufferPoint
/======================================================================*/
pCurGTd->paCurBuffer = pCurGTd->paCurBuffer + sPTDReDump[index].bActualBytes;
/*=====================================================================/
(Sepc 6.4.4.6) Transfer Desciptor Retirement
(1), put to the done queue
(2), update Endpoints TD, put the next in the first place
(3), DataToggleCarry bit
/======================================================================*/
/*=====================================================================/
(3), DataToggleCarry bit.
/======================================================================*/
if ( (sPTDReDump[index].bCompletionCode & gcPTDCompletionCodemask) == 0)
{
pEndpt->fPhcdToggleBit = sPTDReDump[index].bfToggle;
}
/*=====================================================================/
(2), update Endpoints TD, put the next in the first place
/======================================================================*/
pEndptDesc->paTdQueueHead = pCurGTd->paNextTd;
DEBUGMSG(ISPEP,
(TEXT("PHCD:: TD 0x%08X is put to the TdQueueHead\r\n"),
pCurGTd->paNextTd));
/*=====================================================================/
(1), put to the done queue
/======================================================================*/
ULONG paDoneHead;
paDoneHead = READ_REGISTER_ULONG(HcDoneHead(m_regBase));
pCurGTd->paNextTd = paDoneHead;
WRITE_REGISTER_ULONG(HcDoneHead(m_regBase), paCurGTd);
*pInterrupts |= gcHcInterruptStatusWDHmask;
DEBUGMSG(ISP1161DBG,
(TEXT("PHCD: PTD(s) %u TD 0x%08X is passed to donehead\r\n"),
m_TdsPutToATLIndex, paCurGTd));
} //End of For Loop, which read out the TD that has been processed by HC
/*======================================================================/
After reading out ATL buffer, we save the PTD that should be redumped
to m_TdsRePutToATL array. And now we dump them again to ATL.
Note, this should be put outside of the for loop.
/======================================================================*/
if (m_bReDump)
{
return;
}
/*=====================================================================/
Reset m_TdsPutToATLIndex to 0. So the next time, When goes into
ServiceTransferDescriptor to prepare ATLList, the TD "paCur" will
be put at the begining at the array m_TDsPutToATL[]
Set m_ATLBeingReadOut to FALSE. means I have read them out. Cause
when SOF comes, it will only call SeviceList, when this is FALSE.
/======================================================================*/
m_TdsPutToATLIndex = 0;
m_ATLBeingReadOut = FALSE;
}
VOID CPhcd::ReDumpPtd()
{
DEBUGMSG(ISP1161DBG,
(TEXT("PHCD:: ReDumpPtd called, %d\r\n"), m_TdsPutToATLIndex));
SGeneralTransferDescriptor* pCurGTd;
ULONG paCurGTd;
/*======================================================================/
Remove the PTDs that don't need to be dumped again. Remove the item
in sPTDReDump array, if the corrosponding item in m_bsPTDReDump array
is FALSE.
This is added on 22, Nov. This also means sPTDReDump[index].bfActive = 0
can be removed. m_bsPTDReDump is FALSE means this PTD needs not to be tried.
/=======================================================================*/
UINT i=0;
while( i < m_TdsPutToATLIndex )
{
if ( m_bsPTDReDump[i] == FALSE )
{
if ( i == (m_TdsPutToATLIndex -1))
m_TdsPutToATLIndex--;
else
{
for ( UINT j=i; j< (m_TdsPutToATLIndex - 1); j++)
{
m_TdsPutToATL[j] = m_TdsPutToATL[j+1];
sPTDReDump[j] = sPTDReDump[j+1];
m_bsPTDReDump[j] = m_bsPTDReDump[j+1];
}
m_TdsPutToATLIndex--;
}
}
else
i++;
}
/*========================================================/
Depending on OHCD spec page 101 to calcuate length.
Calcuate data length of each TD and m_ATLTransferLen
/========================================================*/
m_ATLTransferLen = 0;
for (UINT index =0; index < m_TdsPutToATLIndex; index++)
{
paCurGTd = m_TdsPutToATL[index];
pCurGTd = (SGeneralTransferDescriptor*)m_pobMem->PaToVa(paCurGTd);
SDevice *pDev;
SEndpoint *pEndpt;
SEndpointDescriptor *pEndptDesc;
EnterCriticalSection(&m_csDeviceListLock);
pDev = m_ppDevices[pCurGTd->bfAddr];
LeaveCriticalSection(&m_csDeviceListLock);
ASSERT(pDev);
EnterCriticalSection(&pDev->csAccessingEndpointArray);
pEndpt = pDev->ppEndpts[pCurGTd->bfEndptArrayNum];
LeaveCriticalSection(&pDev->csAccessingEndpointArray);
ASSERT(pEndpt);
pEndptDesc = pEndpt->pEd;
USHORT dwBufferLen;
if (pCurGTd->paCurBuffer == 0)
{
dwBufferLen = 0;
}
else
{
USHORT uspaBufferEnd = (USHORT)(pCurGTd->paBufferEnd & 0xFFF);
USHORT uspaCurBuffer = (USHORT)(pCurGTd->paCurBuffer & 0xFFF);
// dwBufferLen = (USHORT)((pCurGTd->paBufferEnd & 0xFFF) - (pCurGTd->paCurBuffer & 0xFFF));
dwBufferLen = uspaBufferEnd - uspaCurBuffer;
if ( (pCurGTd->paBufferEnd & 0xFFFFF000) != (pCurGTd->paCurBuffer & 0xFFFFF000))
dwBufferLen += 4096;
dwBufferLen += 1;
/*===================================================================/
Alignment of 4 bytes, If there are more than 1 PTD in ATL buffer,
the next should be alignment in 4 bytes
====================================================================*/
if (index < m_TdsPutToATLIndex -1)
{
if (dwBufferLen %4)
{
USHORT dwPayLoad = 4 - dwBufferLen % 4;
m_ATLTransferLen += dwPayLoad;
}
}
}
m_ATLTransferLen += dwBufferLen + sizeof(SPhilipsTransferDescriptor);
}
//Transfer counter
WRITE_REGISTER_USHORT(HcWRTransCounter(m_regBase), m_ATLTransferLen);
WRITE_PORT_USHORT((PUSHORT)(m_regBase+2), 0xc1);
for ( index = 0; index < m_TdsPutToATLIndex ; index++)
{
paCurGTd = m_TdsPutToATL[index];
pCurGTd = (SGeneralTransferDescriptor*)m_pobMem->PaToVa(paCurGTd);
SDevice *pDev;
SEndpoint *pEndpt;
SEndpointDescriptor *pEndptDesc;
EnterCriticalSection(&m_csDeviceListLock);
pDev = m_ppDevices[pCurGTd->bfAddr];
LeaveCriticalSection(&m_csDeviceListLock);
ASSERT(pDev);
EnterCriticalSection(&pDev->csAccessingEndpointArray);
pEndpt = pDev->ppEndpts[pCurGTd->bfEndptArrayNum];
LeaveCriticalSection(&pDev->csAccessingEndpointArray);
ASSERT(pEndpt);
pEndptDesc = pEndpt->pEd;
//Depending on OHCD spec page 101 to calcuate length.
USHORT dwBufferLen;
//Calcuate the data length of each TD
if (pCurGTd->paCurBuffer == 0)
{
dwBufferLen = 0;
}
else
{
dwBufferLen = (USHORT)((pCurGTd->paBufferEnd & 0xFFF) - (pCurGTd->paCurBuffer & 0xFFF));
if ( (pCurGTd->paBufferEnd & 0xFFFFF000) != (pCurGTd->paCurBuffer & 0xFFFFF000))
dwBufferLen += 4096;
dwBufferLen += 1;
}
/*=====================================================================/
Write PTD and data to ATL buffer
/======================================================================*/
if (index == m_TdsPutToATLIndex -1)
sPTDReDump[index].bfLastTd = 1;
else
sPTDReDump[index].bfLastTd = 0;
PUSHORT psPTDData;
PUSHORT pData;
psPTDData = (PUSHORT)&sPTDReDump[index];
for (UINT i = 0; i< sizeof(SPhilipsTransferDescriptor)/sizeof(USHORT); i++)
WRITE_PORT_USHORT((PUSHORT)m_regBase, *(psPTDData+i));
if ( pCurGTd->paCurBuffer)
{
pData = (PUSHORT)m_pobMem->PaToVa(pCurGTd->paCurBuffer);
// dwBufferLen += 1, In odd case, we add one more byte.
for (i=0; i< (dwBufferLen + 1)/sizeof(USHORT); i++)
{
WRITE_PORT_USHORT((PUSHORT)m_regBase, *(pData + i));
}
/*=====================================================================/
Send PayLoad data to ATL buffer
/======================================================================*/
if (index < m_TdsPutToATLIndex -1)
{
if (dwBufferLen %4)
{
DWORD dwPayLoad = 4 - dwBufferLen % 4;
for (i=0; i< (dwPayLoad)/sizeof(USHORT); i++)
{
WRITE_PORT_USHORT((PUSHORT)m_regBase, 0);
}
}
}
}
DEBUGMSG(ISP1161DBG,
(TEXT("PHCD::PTD(s) %d, TD 0x%08X -> [%d], bufferLen %u, ATL Len: %d, EdptType %d, CurBuffer 0x%08X\r\n"),
m_TdsPutToATLIndex, paCurGTd, index, dwBufferLen, m_ATLTransferLen, pEndpt->endptType, pCurGTd->paCurBuffer));
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -