?? isp1161hc.cpp
字號:
ULONG paDoneHead;
paDoneHead = READ_REGISTER_ULONG(HcDoneHead(m_regBase));
pCurITd->paNextTd = paDoneHead;
WRITE_REGISTER_ULONG(HcDoneHead(m_regBase), paCurITd);
while( pEndptDesc->paTdQueueHead != pEndptDesc->paTdQueueTail)
{
//Put the next to TdQueueHead
paCurITd = pEndptDesc->paTdQueueHead;
pCurITd = (SIsochTransferDescriptor*)m_pobMem->PaToVa(paCurITd);
pEndptDesc->paTdQueueHead = pCurITd->paNextTd;
//Put itself to DoneHead
ULONG paDoneHead;
paDoneHead = READ_REGISTER_ULONG(HcDoneHead(m_regBase));
pCurITd->paNextTd = paDoneHead;
WRITE_REGISTER_ULONG(HcDoneHead(m_regBase), paCurITd);
}
*pInterrupts |= gcHcInterruptStatusWDHmask;
//Everything over, set them to 0
m_TdsPutToITLFirstIndex = 0;
m_TdsPutToITLSecondIndex = 0;
return;
}
/*=====================================================================/
(1), put to the done queue
/======================================================================*/
ULONG paDoneHead;
paDoneHead = READ_REGISTER_ULONG(HcDoneHead(m_regBase));
pCurITd->paNextTd = paDoneHead;
WRITE_REGISTER_ULONG(HcDoneHead(m_regBase), paCurITd);
*pInterrupts |= gcHcInterruptStatusWDHmask;
RETAILMSG(0, (TEXT("PHCD: PTD(s), TD 0x%08X is passed to donehead, FrameNumber %08X\r\n"),
paCurITd, uFrameNumber));
} //End of For Loop, which read out the TD that has been processed by HC
//After throwing back the TD to donequeue
*p_TdsPutToITLIndex = 0;
}
void CPhcd::ServiceATLTransferDescriptor()
{
ULONG paCurGTd;
SGeneralTransferDescriptor* pCurGTd;
DEBUGMSG(ISP1161DBG, (TEXT("+PHCD::ServiceTransferDescriptor\r\n")));
//Set Length, transfer counter
m_ATLTransferLen = 0;
for(UINT i=0; i< sizeof(m_bsPTDReDump)/sizeof(BOOL); i++)
m_bsPTDReDump[i] = FALSE;
/*========================================================/
Depending on OHCD spec page 101 to calcuate length.
Calcuate data length of each TD and m_ATLTransferLen
/========================================================*/
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);
}
/*=====================================================================/
Prepare Transfer counter
/=====================================================================*/
//Transfer counter
WRITE_REGISTER_USHORT(HcWRTransCounter(m_regBase), m_ATLTransferLen);
/*=====================================================================/
Go through the array and push them one by one to ATL
/=====================================================================*/
WRITE_PORT_USHORT((PUSHORT)(m_regBase+2), 0xc1);
STRONGARM_DELAY(10);
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, m_ATLTransferLen
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;
}
//ExecuteUSBTransanction
UCHAR dwEndpointType = pEndpt->endptType;
SPhilipsTransferDescriptor sPTD;
sPTD.bActualBytes = 0;
/*=====================================================================/
The following code is to calcuate the data toggling. For control
pipe, I am clear, the code is right.
As for Bulk transfer, cause ISP1161 can toggle itself. So, just
set the toggle bit to 0.
/======================================================================*/
{
if (dwEndpointType == gcEndptTypeControl)
{
if (pCurGTd->bfDataToggle & 0x2)
{
sPTD.bfToggle = pCurGTd->bfDataToggle & 0x1;
m_DataToggleBit = 1;
}
else
{
sPTD.bfToggle = m_DataToggleBit;
if (m_DataToggleBit == 0)
m_DataToggleBit = 1;
else
m_DataToggleBit = 0;
}
}
else
{
sPTD.bfToggle = pEndpt->fPhcdToggleBit;
}
}
sPTD.bfActive = 1; //Start the transfer
sPTD.bCompletionCode = 0;
sPTD.bMaxPacketSize = pEndptDesc->bfMaxPacketSize; //Lost the MSB
sPTD.bfSpeed = pEndptDesc->bfIsLowSpeed;
// sPTD.bfLastTd = pCurGTd->bfLastTd;
if (index == m_TdsPutToATLIndex -1)
sPTD.bfLastTd = 1;
else
sPTD.bfLastTd = 0;
sPTD.bEndpointNumber = pEndptDesc->bfEndpointNumber;
sPTD.bTotalBytes = dwBufferLen;
sPTD.bfPID = pCurGTd->bfPID;
if (dwEndpointType == gcEndptTypeInterrupt)
sPTD.bTokenOnce = 1;
else
sPTD.bTokenOnce = 0;
sPTD.bfAddr = pCurGTd->bfAddr;
sPTD.bFormat = pEndptDesc->bfIsIsochronous;
sPTD.bUnused1 = 0;
sPTD.bUnused2 = 0;
sPTD.bUnused3 = 0;
/*=====================================================================/
Send the PTD and the data inside TD to ATL
/======================================================================*/
UINT i;
PUSHORT pData;
PUSHORT psPTDData;
//PTD structure
psPTDData = (PUSHORT)(&sPTD);
for (i = 0; i< sizeof(SPhilipsTransferDescriptor)/sizeof(USHORT); i++)
{
WRITE_PORT_USHORT((PUSHORT)m_regBase, *(psPTDData+i));
STRONGARM_DELAY(10);
}
//Data in the TD
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));
//Zouying, This should be removed to reach 14 packets for bulk
STRONGARM_DELAY(10);
}
/*=====================================================================/
Send Alignment (4 bytes) data to ATL buffer
/======================================================================*/
if (index < m_TdsPutToATLIndex -1)
{
if (dwBufferLen %4)
{
DWORD dwPayLoad = 4 - dwBufferLen % 4;
DEBUGMSG(ISP1161DBG, (TEXT("PHCD:: Payload data is written, %u, atl Len %u\r\n"),
dwPayLoad, m_ATLTransferLen));
for (i=0; i< dwPayLoad/sizeof(USHORT); i++)
{
WRITE_PORT_USHORT((PUSHORT)m_regBase, 0);
STRONGARM_DELAY(10);
}
}
}
}
DEBUGMSG(ISP1161DBG,
(TEXT("PHCD::PTD(s)%d,TD 0x%08X->[%d],bufLen %u,EP %d,CurBuf 0x%08X\r\n"),
m_TdsPutToATLIndex, paCurGTd, index, dwBufferLen, pEndpt->endptType, pCurGTd->paCurBuffer));
}//End of For loop
/*=====================================================================/
Set m_ATLBeingReadOut to TRUE. When the next interrupt comes,
even though we expect it to be ATLInt, which means the ATL we have
just input is finished, so the IspTDTransferComplete will be called
to read it out and put to the done queue.
But it is still possible, that the next interrupt coming in is
SOF interrupt, our program will happily go to ServieList and find
other TDs and put them to ATL buffer, even though the existing ATL
buffer is not read out.
/======================================================================*/
m_ATLBeingReadOut = TRUE;
DEBUGMSG(ISP1161DBG, (TEXT("-PHCD::ServiceTransferDescriptor\r\n")));
}
VOID CPhcd::IspTDTransferComplete(PULONG pInterrupts)
{
DEBUGMSG(ISP1161DBG, (TEXT("PHCD:: A TD is transferred completely\r\n")));
SGeneralTransferDescriptor* pCurGTd;
ULONG paCurGTd;
UINT i = 0;
/*=====================================================================/
The TDs we have just put are finished, we will go through the
m_TdsPutToATL array to check whether this item needs to be dumped
again.
/======================================================================*/
if ( m_TdsPutToATLIndex != 1)
{
//Transfer counter
WRITE_REGISTER_USHORT(HcWRTransCounter(m_regBase), m_ATLTransferLen);
//Read ATL command
WRITE_PORT_USHORT((PUSHORT)(m_regBase+2), 0x41);
STRONGARM_DELAY(10);
}
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);
pEndptDesc = pEndpt->pEd;
/*=====================================================================/
Calcuate the data length of each TD
/=====================================================================*/
USHORT dwBufferLen;
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;
}
/*=====================================================================/
Read PTD and Data out from ATL buffer
If there is only one PTD and the PID direction is out (either SETUP
or OUT), we need to read out the PTD only. This can dramastically
increase the BULK out performance, if there is only one PTD. In
this case, we reset the transfer count.
/======================================================================*/
PUSHORT pData;
PUSHORT psPTDData;
if ( m_TdsPutToATLIndex == 1)
{
if ( pCurGTd->bfPID == 0x00 || pCurGTd->bfPID == 0x01)
{
//Transfer counter
WRITE_REGISTER_USHORT(HcWRTransCounter(m_regBase),
sizeof(SPhilipsTransferDescriptor));
//Read ATL command
WRITE_PORT_USHORT((PUSHORT)(m_regBase+2), 0x41);
STRONGARM_DELAY(10);
//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);
}
}
else
{
//Transfer counter
WRITE_REGISTER_USHORT(HcWRTransCounter(m_regBase),
sizeof(SPhilipsTransferDescriptor) + dwBufferLen);
//Read ATL command
WRITE_PORT_USHORT((PUSHORT)(m_regBase+2), 0x41);
STRONGARM_DELAY(10);
//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);
}
/*
RETAILMSG(1, (TEXT("PHCD:****************************\r\n")));
//Display the data
for (i = 0; i< (dwBufferLen + 1)/sizeof(USHORT); i++)
{
RETAILMSG(1, (TEXT(" 0x%04X\r\n"), *(pData + i)));
}
*/
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -